-
Notifications
You must be signed in to change notification settings - Fork 55
/
MoveInstantaneousReward.ts
221 lines (186 loc) · 7.62 KB
/
MoveInstantaneousReward.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
import * as Cardano from '../../../Cardano';
import { CborReader, CborReaderState, CborWriter } from '../../CBOR';
import { CertificateKind } from '../CertificateKind';
import { HexBlob, InvalidArgumentError, InvalidStateError } from '@cardano-sdk/util';
import { MoveInstantaneousRewardToOtherPot } from './MoveInstantaneousRewardToOtherPot';
import { MoveInstantaneousRewardToStakeCreds } from './MoveInstantaneousRewardToStakeCreds';
const EMBEDDED_GROUP_SIZE = 2;
/**
* Certificate used to facilitate an instantaneous transfer of rewards within the system.
*
* Typically, rewards in Cardano are accumulated and distributed through a carefully designed
* process aligned with the staking and delegation mechanics. However, certain situations may
* require a more immediate or specialized handling of rewards, and that's where this type of
* certificate comes into play.
*
* The MoveInstantaneousReward certificate allows for immediate redistribution of rewards
* within pots, or to a specified se of stake addresses.
*/
export class MoveInstantaneousReward {
#toOtherPot: MoveInstantaneousRewardToOtherPot | undefined;
#toStakeCreds: MoveInstantaneousRewardToStakeCreds | undefined;
#kind: Cardano.MirCertificateKind;
#originalBytes: HexBlob | undefined = undefined;
/**
* Serializes a MoveInstantaneousReward into CBOR format.
*
* @returns The MoveInstantaneousReward in CBOR format.
*/
toCbor(): HexBlob {
if (this.#originalBytes) return this.#originalBytes;
let cbor;
switch (this.#kind) {
case Cardano.MirCertificateKind.ToOtherPot:
cbor = this.#toOtherPot!.toCbor();
break;
case Cardano.MirCertificateKind.ToStakeCreds:
cbor = this.#toStakeCreds!.toCbor();
break;
default:
throw new InvalidStateError(`Unexpected kind value: ${this.#kind}`);
}
// CDDL
// move_instantaneous_rewards_cert = (6, move_instantaneous_reward)
const writer = new CborWriter();
writer.writeStartArray(EMBEDDED_GROUP_SIZE);
writer.writeInt(CertificateKind.MoveInstantaneousRewards);
writer.writeEncodedValue(Buffer.from(cbor, 'hex'));
return writer.encodeAsHex();
}
/**
* Deserializes the MoveInstantaneousReward from a CBOR byte array.
*
* @param cbor The CBOR encoded MoveInstantaneousReward object.
* @returns The new MoveInstantaneousReward instance.
*/
static fromCbor(cbor: HexBlob): MoveInstantaneousReward {
const reader = new CborReader(cbor);
let elementsCount = reader.readStartArray();
if (elementsCount !== EMBEDDED_GROUP_SIZE)
throw new InvalidArgumentError('cbor', `Expected elements size ${EMBEDDED_GROUP_SIZE}, but got ${elementsCount}`);
const kind = Number(reader.readInt());
if (kind !== CertificateKind.MoveInstantaneousRewards)
throw new InvalidArgumentError(
'cbor',
`Expected certificate kind ${CertificateKind.MoveInstantaneousRewards}, but got ${kind}`
);
const embeddedCbor = HexBlob.fromBytes(reader.readEncodedValue());
const embeddedCborReader = new CborReader(embeddedCbor);
elementsCount = embeddedCborReader.readStartArray();
if (elementsCount !== EMBEDDED_GROUP_SIZE)
throw new InvalidArgumentError('cbor', `Expected elements size ${EMBEDDED_GROUP_SIZE}, but got ${elementsCount}`);
const cert = new MoveInstantaneousReward();
// Skip pot.
embeddedCborReader.readInt();
if (embeddedCborReader.peekState() === CborReaderState.UnsignedInteger) {
cert.#toOtherPot = MoveInstantaneousRewardToOtherPot.fromCbor(embeddedCbor);
cert.#kind = Cardano.MirCertificateKind.ToOtherPot;
} else if (
embeddedCborReader.peekState() === CborReaderState.StartArray ||
embeddedCborReader.peekState() === CborReaderState.StartMap
) {
cert.#toStakeCreds = MoveInstantaneousRewardToStakeCreds.fromCbor(embeddedCbor);
cert.#kind = Cardano.MirCertificateKind.ToStakeCreds;
} else {
throw new InvalidArgumentError('cbor', 'Invalid CBOR string');
}
cert.#originalBytes = cbor;
return cert;
}
/**
* Creates a Core MirCertificate object from the current MoveInstantaneousReward object.
*
* @returns The Core MirCertificate object.
*/
toCore(): Cardano.MirCertificate {
let core;
switch (this.#kind) {
case Cardano.MirCertificateKind.ToOtherPot:
core = this.#toOtherPot!.toCore();
break;
case Cardano.MirCertificateKind.ToStakeCreds:
core = this.#toStakeCreds!.toCore();
break;
default:
throw new InvalidStateError(`Unexpected kind value: ${this.#kind}`);
}
return core;
}
/**
* Creates a MoveInstantaneousReward object from the given Core MirCertificate object.
*
* @param cert The core MirCertificate object.
*/
static fromCore(cert: Cardano.MirCertificate): MoveInstantaneousReward {
const mirCert = new MoveInstantaneousReward();
switch (cert.kind) {
case Cardano.MirCertificateKind.ToOtherPot:
mirCert.#toOtherPot = MoveInstantaneousRewardToOtherPot.fromCore(cert);
mirCert.#kind = Cardano.MirCertificateKind.ToOtherPot;
break;
case Cardano.MirCertificateKind.ToStakeCreds:
mirCert.#toStakeCreds = MoveInstantaneousRewardToStakeCreds.fromCore(cert);
mirCert.#kind = Cardano.MirCertificateKind.ToStakeCreds;
break;
default:
throw new InvalidStateError(`Unexpected kind value: ${cert.kind}`);
}
return mirCert;
}
/**
* Creates a move instantaneous rewards certificate that transfers finds
* to the other accounting pot.
*
* @param mirCert The MoveInstantaneousRewardToOtherPot certificate.
*/
static newToOtherPot(mirCert: MoveInstantaneousRewardToOtherPot): MoveInstantaneousReward {
const cert = new MoveInstantaneousReward();
cert.#toOtherPot = mirCert;
cert.#kind = Cardano.MirCertificateKind.ToOtherPot;
return cert;
}
/**
* Creates a move instantaneous rewards certificate that transfers funds
* to the given set of reward accounts.
*
* @param mirCert The MoveInstantaneousRewardToStakeCreds certificate.
*/
static newToStakeCreds(mirCert: MoveInstantaneousRewardToStakeCreds): MoveInstantaneousReward {
const cert = new MoveInstantaneousReward();
cert.#toStakeCreds = mirCert;
cert.#kind = Cardano.MirCertificateKind.ToStakeCreds;
return cert;
}
/**
* The kind of MoveInstantaneousReward certificate.
*
* - Reserve Pot: This pot is filled with a predefined amount of ADA at the
* launch of the network. It's used to fund various initiatives, and some of
* he funds are transferred to the reward pot to pay for staking rewards.
*
* - Treasury Pot: The treasury holds funds that can be used for various purposes,
* such as funding development and community initiatives. It's filled by taking
* a portion of the transaction fees and other specified sources.
*
* @returns The MoveInstantaneousReward kind.
*/
kind(): Cardano.MirCertificateKind {
return this.#kind;
}
/**
* Gets a MoveInstantaneousRewardToOtherPot from a MoveInstantaneousReward instance.
*
* @returns a MoveInstantaneousRewardToOtherPot if the MoveInstantaneousReward can be down cast, otherwise, undefined.
*/
asToOtherPot(): MoveInstantaneousRewardToOtherPot | undefined {
return this.#toOtherPot;
}
/**
* Gets a MoveInstantaneousRewardToStakeCreds from a MoveInstantaneousReward instance.
*
* @returns a MoveInstantaneousRewardToStakeCreds if the MoveInstantaneousReward can be down cast, otherwise, undefined.
*/
asToStakeCreds(): MoveInstantaneousRewardToStakeCreds | undefined {
return this.#toStakeCreds;
}
}