-
Notifications
You must be signed in to change notification settings - Fork 54
/
RewardAddress.ts
126 lines (112 loc) · 3.86 KB
/
RewardAddress.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* eslint-disable no-bitwise */
import { Address, AddressProps, AddressType, Credential, CredentialType } from './Address';
import { Hash28ByteBase16 } from '@cardano-sdk/crypto';
import { InvalidArgumentError } from '@cardano-sdk/util';
import { NetworkId } from '../ChainId';
/**
* A reward address is a cryptographic hash of the public stake key of the address. Reward account addresses are used
* to distribute rewards for participating in the proof-of-stake protocol (either directly or via delegation).
*/
export class RewardAddress {
readonly #type: AddressType;
readonly #networkId: NetworkId;
readonly #paymentPart: Credential;
/**
* Initializes a new instance of the RewardAddress class.
*
* @param props The address properties.
* @private
*/
// eslint-disable-next-line sonarjs/no-identical-functions
private constructor(props: AddressProps) {
this.#networkId = props.networkId!;
this.#paymentPart = props.paymentPart!;
this.#type = props.type;
}
/**
* Creates a new instance of the RewardAddress from its credentials.
*
* @param networkId The Network identifier.
* @param payment The payment credential.
*/
static fromCredentials(networkId: NetworkId, payment: Credential): RewardAddress {
let type = AddressType.RewardKey;
if (payment.type === CredentialType.ScriptHash) type |= 0b0001;
return new RewardAddress({
networkId,
paymentPart: payment,
type
});
}
/**
* Gets the payment credential part of the reward address.
*
* Note: by convention, the key inside reward addresses are NOT considered stake credentials,
* pointer addresses and the chain history is required to resolve its associated credential
*/
getPaymentCredential(): Credential {
return this.#paymentPart;
}
/** Converts from RewardAddress instance to Address. */
// eslint-disable-next-line sonarjs/no-identical-functions
toAddress(): Address {
return new Address({
networkId: this.#networkId,
paymentPart: this.#paymentPart,
type: this.#type
});
}
/**
* Creates a RewardAddress address from an Address instance.
*
* @param addr The address instance to be converted.
* @returns The RewardAddress instance or undefined if Address is not a valid RewardAddress.
*/
static fromAddress(addr: Address): RewardAddress | undefined {
let address;
switch (addr.getProps().type) {
case AddressType.RewardKey:
case AddressType.RewardScript:
address = new RewardAddress(addr.getProps());
break;
default:
}
return address;
}
/**
* Packs the reward address into its raw binary format.
*
* @param props The address properties.
*/
static packParts(props: AddressProps): Buffer {
return Buffer.concat([
Buffer.from([(props.type << 4) | props.networkId!]),
Buffer.from(props.paymentPart!.hash, 'hex')
]);
}
/**
* There are currently 2 types of Stake addresses, summarized below:
*
* - 0110 None StakeKeyHash
* - 0111 None ScriptHash
*
* @param type The address type.
* @param data The serialized address data.
*/
static unpackParts(type: number, data: Uint8Array): Address {
if (data.length !== 29)
throw new InvalidArgumentError('data', 'Enterprise address data length should be 29 bytes long.');
const network = data[0] & 0b0000_1111;
const stakeCredential = Hash28ByteBase16(Buffer.from(data.slice(1, 29)).toString('hex'));
return new Address({
networkId: network,
// Note: by convention, the key inside reward addresses are NOT considered stake credentials,
// pointer addresses and the chain history is required to resolve its associated credential
paymentPart: {
hash: stakeCredential,
type: type === AddressType.RewardScript ? CredentialType.ScriptHash : CredentialType.KeyHash
},
type
});
}
}