@ckb-ccc/core 1.9.1 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/dist/ckb/hash.d.ts +18 -0
- package/dist/ckb/hash.d.ts.map +1 -0
- package/dist/ckb/hash.js +19 -0
- package/dist/ckb/index.d.ts +2 -0
- package/dist/ckb/index.d.ts.map +1 -1
- package/dist/ckb/index.js +2 -0
- package/dist/ckb/script.d.ts +12 -0
- package/dist/ckb/script.d.ts.map +1 -1
- package/dist/ckb/script.js +17 -0
- package/dist/ckb/transaction.d.ts +326 -25
- package/dist/ckb/transaction.d.ts.map +1 -1
- package/dist/ckb/transaction.js +354 -79
- package/dist/ckb/transactionErrors.d.ts +15 -0
- package/dist/ckb/transactionErrors.d.ts.map +1 -0
- package/dist/ckb/transactionErrors.js +21 -0
- package/dist/client/cache/cache.d.ts +7 -0
- package/dist/client/cache/cache.d.ts.map +1 -1
- package/dist/client/cache/cache.js +11 -0
- package/dist/client/cache/memory.advanced.d.ts +36 -3
- package/dist/client/cache/memory.advanced.d.ts.map +1 -1
- package/dist/client/cache/memory.advanced.js +53 -25
- package/dist/client/cache/memory.d.ts +10 -1
- package/dist/client/cache/memory.d.ts.map +1 -1
- package/dist/client/cache/memory.js +13 -2
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +6 -9
- package/dist/client/clientTypes.advanced.d.ts +0 -1
- package/dist/client/clientTypes.advanced.d.ts.map +1 -1
- package/dist/client/clientTypes.advanced.js +0 -1
- package/dist/hasher/hasherCkb.d.ts +0 -16
- package/dist/hasher/hasherCkb.d.ts.map +1 -1
- package/dist/hasher/hasherCkb.js +0 -18
- package/dist/molecule/codec.d.ts +30 -10
- package/dist/molecule/codec.d.ts.map +1 -1
- package/dist/molecule/codec.js +46 -13
- package/dist/signer/ckb/signerCkbScriptReadonly.d.ts +18 -6
- package/dist/signer/ckb/signerCkbScriptReadonly.d.ts.map +1 -1
- package/dist/signer/ckb/signerCkbScriptReadonly.js +18 -6
- package/dist/signer/signer/index.d.ts +11 -1
- package/dist/signer/signer/index.d.ts.map +1 -1
- package/dist/signer/signer/index.js +23 -0
- package/dist.commonjs/ckb/hash.d.ts +18 -0
- package/dist.commonjs/ckb/hash.d.ts.map +1 -0
- package/dist.commonjs/ckb/hash.js +22 -0
- package/dist.commonjs/ckb/index.d.ts +2 -0
- package/dist.commonjs/ckb/index.d.ts.map +1 -1
- package/dist.commonjs/ckb/index.js +2 -0
- package/dist.commonjs/ckb/script.d.ts +12 -0
- package/dist.commonjs/ckb/script.d.ts.map +1 -1
- package/dist.commonjs/ckb/script.js +17 -0
- package/dist.commonjs/ckb/transaction.d.ts +326 -25
- package/dist.commonjs/ckb/transaction.d.ts.map +1 -1
- package/dist.commonjs/ckb/transaction.js +353 -78
- package/dist.commonjs/ckb/transactionErrors.d.ts +15 -0
- package/dist.commonjs/ckb/transactionErrors.d.ts.map +1 -0
- package/dist.commonjs/ckb/transactionErrors.js +26 -0
- package/dist.commonjs/client/cache/cache.d.ts +7 -0
- package/dist.commonjs/client/cache/cache.d.ts.map +1 -1
- package/dist.commonjs/client/cache/cache.js +11 -0
- package/dist.commonjs/client/cache/memory.advanced.d.ts +36 -3
- package/dist.commonjs/client/cache/memory.advanced.d.ts.map +1 -1
- package/dist.commonjs/client/cache/memory.advanced.js +54 -26
- package/dist.commonjs/client/cache/memory.d.ts +10 -1
- package/dist.commonjs/client/cache/memory.d.ts.map +1 -1
- package/dist.commonjs/client/cache/memory.js +12 -1
- package/dist.commonjs/client/client.d.ts.map +1 -1
- package/dist.commonjs/client/client.js +5 -8
- package/dist.commonjs/client/clientTypes.advanced.d.ts +0 -1
- package/dist.commonjs/client/clientTypes.advanced.d.ts.map +1 -1
- package/dist.commonjs/client/clientTypes.advanced.js +1 -2
- package/dist.commonjs/hasher/hasherCkb.d.ts +0 -16
- package/dist.commonjs/hasher/hasherCkb.d.ts.map +1 -1
- package/dist.commonjs/hasher/hasherCkb.js +2 -21
- package/dist.commonjs/molecule/codec.d.ts +30 -10
- package/dist.commonjs/molecule/codec.d.ts.map +1 -1
- package/dist.commonjs/molecule/codec.js +46 -13
- package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.d.ts +18 -6
- package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.d.ts.map +1 -1
- package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.js +18 -6
- package/dist.commonjs/signer/signer/index.d.ts +11 -1
- package/dist.commonjs/signer/signer/index.d.ts.map +1 -1
- package/dist.commonjs/signer/signer/index.js +23 -0
- package/package.json +1 -1
- package/prettier.config.mjs +1 -1
- package/src/ckb/hash.ts +28 -0
- package/src/ckb/index.ts +2 -0
- package/src/ckb/script.ts +20 -0
- package/src/ckb/transaction.ts +436 -80
- package/src/ckb/transactionErrors.ts +36 -0
- package/src/client/cache/cache.ts +14 -1
- package/src/client/cache/memory.advanced.ts +57 -30
- package/src/client/cache/memory.ts +18 -1
- package/src/client/client.ts +5 -10
- package/src/client/clientTypes.advanced.ts +0 -1
- package/src/hasher/hasherCkb.ts +0 -26
- package/src/molecule/codec.ts +50 -13
- package/src/signer/ckb/signerCkbScriptReadonly.ts +24 -8
- package/src/signer/signer/index.ts +34 -0
package/src/ckb/transaction.ts
CHANGED
|
@@ -7,11 +7,7 @@ import {
|
|
|
7
7
|
type ClientBlockHeaderLike,
|
|
8
8
|
} from "../client/index.js";
|
|
9
9
|
import { KnownScript } from "../client/knownScript.js";
|
|
10
|
-
import {
|
|
11
|
-
Zero,
|
|
12
|
-
fixedPointFrom,
|
|
13
|
-
fixedPointToString,
|
|
14
|
-
} from "../fixedPoint/index.js";
|
|
10
|
+
import { Zero, fixedPointFrom } from "../fixedPoint/index.js";
|
|
15
11
|
import { Hasher, HasherCkb, hashCkb } from "../hasher/index.js";
|
|
16
12
|
import { Hex, HexLike, hexFrom } from "../hex/index.js";
|
|
17
13
|
import { mol } from "../molecule/index.js";
|
|
@@ -27,6 +23,10 @@ import type { Signer } from "../signer/index.js";
|
|
|
27
23
|
import { apply, reduceAsync } from "../utils/index.js";
|
|
28
24
|
import { Script, ScriptLike, ScriptOpt } from "./script.js";
|
|
29
25
|
import { DEP_TYPE_TO_NUM, NUM_TO_DEP_TYPE } from "./transaction.advanced.js";
|
|
26
|
+
import {
|
|
27
|
+
ErrorTransactionInsufficientCapacity,
|
|
28
|
+
ErrorTransactionInsufficientCoin,
|
|
29
|
+
} from "./transactionErrors.js";
|
|
30
30
|
import type { LumosTransactionSkeletonType } from "./transactionLumos.js";
|
|
31
31
|
|
|
32
32
|
export const DepTypeCodec: mol.Codec<DepTypeLike, DepType> = mol.Codec.from({
|
|
@@ -162,6 +162,36 @@ export class OutPoint extends mol.Entity.Base<OutPointLike, OutPoint>() {
|
|
|
162
162
|
}
|
|
163
163
|
return new OutPoint(hexFrom(outPoint.txHash), numFrom(outPoint.index));
|
|
164
164
|
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Clone a OutPoint.
|
|
168
|
+
*
|
|
169
|
+
* @returns A cloned OutPoint instance.
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```typescript
|
|
173
|
+
* const outPoint1 = outPoint0.clone();
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
clone(): OutPoint {
|
|
177
|
+
return new OutPoint(this.txHash, this.index);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Check if the OutPoint is equal to another OutPoint.
|
|
182
|
+
* @public
|
|
183
|
+
* @param other - The other OutPoint to compare with
|
|
184
|
+
* @returns True if the OutPoints are equal, false otherwise
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* const isEqual = outPoint0.eq(outPoint1);
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
eq(other: OutPointLike): boolean {
|
|
192
|
+
other = OutPoint.from(other);
|
|
193
|
+
return this.txHash === other.txHash && this.index === other.index;
|
|
194
|
+
}
|
|
165
195
|
}
|
|
166
196
|
|
|
167
197
|
/**
|
|
@@ -205,29 +235,72 @@ export class CellOutput extends mol.Entity.Base<CellOutputLike, CellOutput>() {
|
|
|
205
235
|
|
|
206
236
|
/**
|
|
207
237
|
* Creates a CellOutput instance from a CellOutputLike object.
|
|
238
|
+
* This method supports automatic capacity calculation when capacity is 0 or omitted.
|
|
208
239
|
*
|
|
209
240
|
* @param cellOutput - A CellOutputLike object or an instance of CellOutput.
|
|
241
|
+
* Can also be an object without capacity when outputData is provided.
|
|
242
|
+
* @param outputData - Optional output data used for automatic capacity calculation.
|
|
243
|
+
* When provided and capacity is 0, the capacity will be calculated
|
|
244
|
+
* as occupiedSize + outputData.length.
|
|
210
245
|
* @returns A CellOutput instance.
|
|
211
246
|
*
|
|
212
247
|
* @example
|
|
213
248
|
* ```typescript
|
|
214
|
-
*
|
|
249
|
+
* // Basic usage with explicit capacity
|
|
250
|
+
* const cellOutput1 = CellOutput.from({
|
|
215
251
|
* capacity: 1000n,
|
|
216
252
|
* lock: { codeHash: "0x...", hashType: "type", args: "0x..." },
|
|
217
253
|
* type: { codeHash: "0x...", hashType: "type", args: "0x..." }
|
|
218
254
|
* });
|
|
255
|
+
*
|
|
256
|
+
* // Automatic capacity calculation
|
|
257
|
+
* const cellOutput2 = CellOutput.from({
|
|
258
|
+
* lock: { codeHash: "0x...", hashType: "type", args: "0x..." }
|
|
259
|
+
* }, "0x1234"); // Capacity will be calculated automatically
|
|
219
260
|
* ```
|
|
220
261
|
*/
|
|
221
|
-
static from(cellOutput: CellOutputLike): CellOutput
|
|
262
|
+
static from(cellOutput: CellOutputLike, outputData?: HexLike): CellOutput;
|
|
263
|
+
static from(
|
|
264
|
+
cellOutput: Omit<CellOutputLike, "capacity"> &
|
|
265
|
+
Partial<Pick<CellOutputLike, "capacity">>,
|
|
266
|
+
outputData: HexLike,
|
|
267
|
+
): CellOutput;
|
|
268
|
+
static from(
|
|
269
|
+
cellOutput: Omit<CellOutputLike, "capacity"> &
|
|
270
|
+
Partial<Pick<CellOutputLike, "capacity">>,
|
|
271
|
+
outputData?: HexLike,
|
|
272
|
+
): CellOutput {
|
|
222
273
|
if (cellOutput instanceof CellOutput) {
|
|
223
274
|
return cellOutput;
|
|
224
275
|
}
|
|
225
276
|
|
|
226
|
-
|
|
227
|
-
numFrom(cellOutput.capacity),
|
|
277
|
+
const output = new CellOutput(
|
|
278
|
+
numFrom(cellOutput.capacity ?? 0),
|
|
228
279
|
Script.from(cellOutput.lock),
|
|
229
280
|
apply(Script.from, cellOutput.type),
|
|
230
281
|
);
|
|
282
|
+
|
|
283
|
+
if (output.capacity === Zero) {
|
|
284
|
+
output.capacity = fixedPointFrom(
|
|
285
|
+
output.occupiedSize + bytesFrom(outputData ?? "0x").length,
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return output;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Clone a CellOutput.
|
|
294
|
+
*
|
|
295
|
+
* @returns A cloned CellOutput instance.
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* ```typescript
|
|
299
|
+
* const cellOutput1 = cellOutput0.clone();
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
302
|
+
clone(): CellOutput {
|
|
303
|
+
return new CellOutput(this.capacity, this.lock.clone(), this.type?.clone());
|
|
231
304
|
}
|
|
232
305
|
}
|
|
233
306
|
export const CellOutputVec = mol.vector(CellOutput);
|
|
@@ -264,9 +337,37 @@ export class Cell {
|
|
|
264
337
|
|
|
265
338
|
/**
|
|
266
339
|
* Creates a Cell instance from a CellLike object.
|
|
340
|
+
* This method accepts either `outPoint` or `previousOutput` to specify the cell's location,
|
|
341
|
+
* and supports automatic capacity calculation for the cell output.
|
|
267
342
|
*
|
|
268
|
-
* @param cell - A CellLike object or an instance of Cell.
|
|
343
|
+
* @param cell - A CellLike object or an instance of Cell. The object can use either:
|
|
344
|
+
* - `outPoint`: For referencing a cell output
|
|
345
|
+
* - `previousOutput`: For referencing a cell input (alternative name for outPoint)
|
|
346
|
+
* The cellOutput can omit capacity for automatic calculation.
|
|
269
347
|
* @returns A Cell instance.
|
|
348
|
+
*
|
|
349
|
+
* @example
|
|
350
|
+
* ```typescript
|
|
351
|
+
* // Using outPoint with explicit capacity
|
|
352
|
+
* const cell1 = Cell.from({
|
|
353
|
+
* outPoint: { txHash: "0x...", index: 0 },
|
|
354
|
+
* cellOutput: {
|
|
355
|
+
* capacity: 1000n,
|
|
356
|
+
* lock: { codeHash: "0x...", hashType: "type", args: "0x..." }
|
|
357
|
+
* },
|
|
358
|
+
* outputData: "0x"
|
|
359
|
+
* });
|
|
360
|
+
*
|
|
361
|
+
* // Using previousOutput with automatic capacity calculation
|
|
362
|
+
* const cell2 = Cell.from({
|
|
363
|
+
* previousOutput: { txHash: "0x...", index: 0 },
|
|
364
|
+
* cellOutput: {
|
|
365
|
+
* lock: { codeHash: "0x...", hashType: "type", args: "0x..." }
|
|
366
|
+
* // capacity will be calculated automatically
|
|
367
|
+
* },
|
|
368
|
+
* outputData: "0x1234"
|
|
369
|
+
* });
|
|
370
|
+
* ```
|
|
270
371
|
*/
|
|
271
372
|
|
|
272
373
|
static from(cell: CellLike): Cell {
|
|
@@ -276,7 +377,7 @@ export class Cell {
|
|
|
276
377
|
|
|
277
378
|
return new Cell(
|
|
278
379
|
OutPoint.from("outPoint" in cell ? cell.outPoint : cell.previousOutput),
|
|
279
|
-
CellOutput.from(cell.cellOutput),
|
|
380
|
+
CellOutput.from(cell.cellOutput, cell.outputData),
|
|
280
381
|
hexFrom(cell.outputData),
|
|
281
382
|
);
|
|
282
383
|
}
|
|
@@ -700,12 +801,23 @@ export class CellInput extends mol.Entity.Base<CellInputLike, CellInput>() {
|
|
|
700
801
|
return (await this.getCell(client)).getDaoProfit(client);
|
|
701
802
|
}
|
|
702
803
|
|
|
804
|
+
/**
|
|
805
|
+
* Clone a CellInput.
|
|
806
|
+
*
|
|
807
|
+
* @returns A cloned CellInput instance.
|
|
808
|
+
*
|
|
809
|
+
* @example
|
|
810
|
+
* ```typescript
|
|
811
|
+
* const cellInput1 = cellInput0.clone();
|
|
812
|
+
* ```
|
|
813
|
+
*/
|
|
703
814
|
clone(): CellInput {
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
815
|
+
return new CellInput(
|
|
816
|
+
this.previousOutput.clone(),
|
|
817
|
+
this.since,
|
|
818
|
+
this.cellOutput?.clone(),
|
|
819
|
+
this.outputData,
|
|
820
|
+
);
|
|
709
821
|
}
|
|
710
822
|
}
|
|
711
823
|
export const CellInputVec = mol.vector(CellInput);
|
|
@@ -741,21 +853,6 @@ export class CellDep extends mol.Entity.Base<CellDepLike, CellDep>() {
|
|
|
741
853
|
super();
|
|
742
854
|
}
|
|
743
855
|
|
|
744
|
-
/**
|
|
745
|
-
* Clone a CellDep.
|
|
746
|
-
*
|
|
747
|
-
* @returns A cloned CellDep instance.
|
|
748
|
-
*
|
|
749
|
-
* @example
|
|
750
|
-
* ```typescript
|
|
751
|
-
* const cellDep1 = cellDep0.clone();
|
|
752
|
-
* ```
|
|
753
|
-
*/
|
|
754
|
-
|
|
755
|
-
clone(): CellDep {
|
|
756
|
-
return new CellDep(this.outPoint.clone(), this.depType);
|
|
757
|
-
}
|
|
758
|
-
|
|
759
856
|
/**
|
|
760
857
|
* Creates a CellDep instance from a CellDepLike object.
|
|
761
858
|
*
|
|
@@ -781,6 +878,20 @@ export class CellDep extends mol.Entity.Base<CellDepLike, CellDep>() {
|
|
|
781
878
|
depTypeFrom(cellDep.depType),
|
|
782
879
|
);
|
|
783
880
|
}
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* Clone a CellDep.
|
|
884
|
+
*
|
|
885
|
+
* @returns A cloned CellDep instance.
|
|
886
|
+
*
|
|
887
|
+
* @example
|
|
888
|
+
* ```typescript
|
|
889
|
+
* const cellDep1 = cellDep0.clone();
|
|
890
|
+
* ```
|
|
891
|
+
*/
|
|
892
|
+
clone(): CellDep {
|
|
893
|
+
return new CellDep(this.outPoint.clone(), this.depType);
|
|
894
|
+
}
|
|
784
895
|
}
|
|
785
896
|
export const CellDepVec = mol.vector(CellDep);
|
|
786
897
|
|
|
@@ -947,6 +1058,9 @@ export class Transaction extends mol.Entity.Base<
|
|
|
947
1058
|
|
|
948
1059
|
/**
|
|
949
1060
|
* Copy every properties from another transaction.
|
|
1061
|
+
* This method replaces all properties of the current transaction with those from the provided transaction.
|
|
1062
|
+
*
|
|
1063
|
+
* @param txLike - The transaction-like object to copy properties from.
|
|
950
1064
|
*
|
|
951
1065
|
* @example
|
|
952
1066
|
* ```typescript
|
|
@@ -964,6 +1078,55 @@ export class Transaction extends mol.Entity.Base<
|
|
|
964
1078
|
this.witnesses = tx.witnesses;
|
|
965
1079
|
}
|
|
966
1080
|
|
|
1081
|
+
/**
|
|
1082
|
+
* Creates a deep copy of the transaction.
|
|
1083
|
+
* This method creates a new Transaction instance with all nested objects cloned,
|
|
1084
|
+
* ensuring that modifications to the cloned transaction do not affect the original.
|
|
1085
|
+
*
|
|
1086
|
+
* @returns A new Transaction instance that is a deep copy of the current transaction.
|
|
1087
|
+
*
|
|
1088
|
+
* @example
|
|
1089
|
+
* ```typescript
|
|
1090
|
+
* const originalTx = Transaction.from({
|
|
1091
|
+
* version: 0,
|
|
1092
|
+
* inputs: [{ previousOutput: { txHash: "0x...", index: 0 } }],
|
|
1093
|
+
* outputs: [{ capacity: 1000n, lock: lockScript }],
|
|
1094
|
+
* outputsData: ["0x"],
|
|
1095
|
+
* witnesses: ["0x"]
|
|
1096
|
+
* });
|
|
1097
|
+
*
|
|
1098
|
+
* const clonedTx = originalTx.clone();
|
|
1099
|
+
*
|
|
1100
|
+
* // Modifications to clonedTx won't affect originalTx
|
|
1101
|
+
* clonedTx.addOutput({ capacity: 2000n, lock: anotherLockScript });
|
|
1102
|
+
* console.log(originalTx.outputs.length); // Still 1
|
|
1103
|
+
* console.log(clonedTx.outputs.length); // Now 2
|
|
1104
|
+
* ```
|
|
1105
|
+
*
|
|
1106
|
+
* @remarks
|
|
1107
|
+
* The clone operation performs deep copying for:
|
|
1108
|
+
* - Cell dependencies (cellDeps) - each CellDep is cloned
|
|
1109
|
+
* - Inputs - each CellInput is cloned
|
|
1110
|
+
* - Outputs - each CellOutput is cloned
|
|
1111
|
+
*
|
|
1112
|
+
* The following are shallow copied (references to immutable data):
|
|
1113
|
+
* - Header dependencies (headerDeps) - Hex strings are immutable
|
|
1114
|
+
* - Output data (outputsData) - Hex strings are immutable
|
|
1115
|
+
* - Witnesses - Hex strings are immutable
|
|
1116
|
+
* - Version - bigint is immutable
|
|
1117
|
+
*/
|
|
1118
|
+
clone(): Transaction {
|
|
1119
|
+
return new Transaction(
|
|
1120
|
+
this.version,
|
|
1121
|
+
this.cellDeps.map((c) => c.clone()),
|
|
1122
|
+
this.headerDeps.map((h) => h),
|
|
1123
|
+
this.inputs.map((i) => i.clone()),
|
|
1124
|
+
this.outputs.map((o) => o.clone()),
|
|
1125
|
+
this.outputsData.map((o) => o),
|
|
1126
|
+
this.witnesses.map((w) => w),
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
|
|
967
1130
|
/**
|
|
968
1131
|
* Creates a Transaction instance from a TransactionLike object.
|
|
969
1132
|
*
|
|
@@ -989,19 +1152,9 @@ export class Transaction extends mol.Entity.Base<
|
|
|
989
1152
|
return tx;
|
|
990
1153
|
}
|
|
991
1154
|
const outputs =
|
|
992
|
-
tx.outputs?.map((output, i) =>
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
capacity: output.capacity ?? 0,
|
|
996
|
-
});
|
|
997
|
-
if (o.capacity === Zero) {
|
|
998
|
-
o.capacity = fixedPointFrom(
|
|
999
|
-
o.occupiedSize +
|
|
1000
|
-
(apply(bytesFrom, tx.outputsData?.[i])?.length ?? 0),
|
|
1001
|
-
);
|
|
1002
|
-
}
|
|
1003
|
-
return o;
|
|
1004
|
-
}) ?? [];
|
|
1155
|
+
tx.outputs?.map((output, i) =>
|
|
1156
|
+
CellOutput.from(output, tx.outputsData?.[i] ?? []),
|
|
1157
|
+
) ?? [];
|
|
1005
1158
|
const outputsData = outputs.map((_, i) =>
|
|
1006
1159
|
hexFrom(tx.outputsData?.[i] ?? "0x"),
|
|
1007
1160
|
);
|
|
@@ -1229,7 +1382,7 @@ export class Transaction extends mol.Entity.Base<
|
|
|
1229
1382
|
*
|
|
1230
1383
|
* @param scriptLike - The script associated with the transaction, represented as a ScriptLike object.
|
|
1231
1384
|
* @param client - The client for complete extra infos in the transaction.
|
|
1232
|
-
* @returns A promise that resolves to the
|
|
1385
|
+
* @returns A promise that resolves to the found index, or undefined if no matching input is found.
|
|
1233
1386
|
*
|
|
1234
1387
|
* @example
|
|
1235
1388
|
* ```typescript
|
|
@@ -1256,7 +1409,7 @@ export class Transaction extends mol.Entity.Base<
|
|
|
1256
1409
|
*
|
|
1257
1410
|
* @param scriptLike - The script associated with the transaction, represented as a ScriptLike object.
|
|
1258
1411
|
* @param client - The client for complete extra infos in the transaction.
|
|
1259
|
-
* @returns A promise that resolves to the
|
|
1412
|
+
* @returns A promise that resolves to the found index, or undefined if no matching input is found.
|
|
1260
1413
|
*
|
|
1261
1414
|
* @example
|
|
1262
1415
|
* ```typescript
|
|
@@ -1369,14 +1522,14 @@ export class Transaction extends mol.Entity.Base<
|
|
|
1369
1522
|
* Set output data at index.
|
|
1370
1523
|
*
|
|
1371
1524
|
* @param index - The index of the output data.
|
|
1372
|
-
* @param
|
|
1525
|
+
* @param data - The data to set.
|
|
1373
1526
|
*
|
|
1374
1527
|
* @example
|
|
1375
1528
|
* ```typescript
|
|
1376
|
-
*
|
|
1529
|
+
* tx.setOutputDataAt(0, "0x00");
|
|
1377
1530
|
* ```
|
|
1378
1531
|
*/
|
|
1379
|
-
setOutputDataAt(index: number,
|
|
1532
|
+
setOutputDataAt(index: number, data: HexLike): void {
|
|
1380
1533
|
if (this.outputsData.length < index) {
|
|
1381
1534
|
this.outputsData.push(
|
|
1382
1535
|
...Array.from(
|
|
@@ -1386,7 +1539,7 @@ export class Transaction extends mol.Entity.Base<
|
|
|
1386
1539
|
);
|
|
1387
1540
|
}
|
|
1388
1541
|
|
|
1389
|
-
this.outputsData[index] = hexFrom(
|
|
1542
|
+
this.outputsData[index] = hexFrom(data);
|
|
1390
1543
|
}
|
|
1391
1544
|
|
|
1392
1545
|
/**
|
|
@@ -1461,16 +1614,7 @@ export class Transaction extends mol.Entity.Base<
|
|
|
1461
1614
|
Partial<Pick<CellOutputLike, "capacity">>,
|
|
1462
1615
|
outputData: HexLike = "0x",
|
|
1463
1616
|
): number {
|
|
1464
|
-
const
|
|
1465
|
-
...outputLike,
|
|
1466
|
-
capacity: outputLike.capacity ?? 0,
|
|
1467
|
-
});
|
|
1468
|
-
if (output.capacity === Zero) {
|
|
1469
|
-
output.capacity = fixedPointFrom(
|
|
1470
|
-
output.occupiedSize + bytesFrom(outputData).length,
|
|
1471
|
-
);
|
|
1472
|
-
}
|
|
1473
|
-
const len = this.outputs.push(output);
|
|
1617
|
+
const len = this.outputs.push(CellOutput.from(outputLike, outputData));
|
|
1474
1618
|
this.setOutputDataAt(len - 1, outputData);
|
|
1475
1619
|
|
|
1476
1620
|
return len;
|
|
@@ -1697,8 +1841,8 @@ export class Transaction extends mol.Entity.Base<
|
|
|
1697
1841
|
return addedCount;
|
|
1698
1842
|
}
|
|
1699
1843
|
|
|
1700
|
-
throw new
|
|
1701
|
-
|
|
1844
|
+
throw new ErrorTransactionInsufficientCapacity(
|
|
1845
|
+
expectedCapacity - accumulated,
|
|
1702
1846
|
);
|
|
1703
1847
|
}
|
|
1704
1848
|
|
|
@@ -1782,8 +1926,9 @@ export class Transaction extends mol.Entity.Base<
|
|
|
1782
1926
|
return addedCount;
|
|
1783
1927
|
}
|
|
1784
1928
|
|
|
1785
|
-
throw new
|
|
1786
|
-
|
|
1929
|
+
throw new ErrorTransactionInsufficientCoin(
|
|
1930
|
+
expectedBalance - accumulated,
|
|
1931
|
+
type,
|
|
1787
1932
|
);
|
|
1788
1933
|
}
|
|
1789
1934
|
|
|
@@ -1836,12 +1981,54 @@ export class Transaction extends mol.Entity.Base<
|
|
|
1836
1981
|
return (numFrom(txSize) * numFrom(feeRate) + numFrom(999)) / numFrom(1000);
|
|
1837
1982
|
}
|
|
1838
1983
|
|
|
1984
|
+
/**
|
|
1985
|
+
* Completes the transaction fee by adding inputs and handling change outputs.
|
|
1986
|
+
* This method automatically calculates the required fee based on the transaction size and fee rate,
|
|
1987
|
+
* adds necessary inputs to cover the fee, and handles change outputs through the provided change function.
|
|
1988
|
+
*
|
|
1989
|
+
* @param from - The signer to complete inputs from and prepare the transaction.
|
|
1990
|
+
* @param change - A function that handles change capacity. It receives the transaction and excess capacity,
|
|
1991
|
+
* and should return the additional capacity needed (0 if change is handled successfully,
|
|
1992
|
+
* positive number if more capacity is needed for change cell creation).
|
|
1993
|
+
* @param expectedFeeRate - The expected fee rate in shannons per 1000 bytes. If not provided,
|
|
1994
|
+
* it will be fetched from the client.
|
|
1995
|
+
* @param filter - Optional filter for selecting cells when adding inputs.
|
|
1996
|
+
* @param options - Optional configuration object.
|
|
1997
|
+
* @param options.feeRateBlockRange - Block range for fee rate calculation when expectedFeeRate is not provided.
|
|
1998
|
+
* @param options.maxFeeRate - Maximum allowed fee rate.
|
|
1999
|
+
* @param options.shouldAddInputs - Whether to add inputs automatically. Defaults to true.
|
|
2000
|
+
* @returns A promise that resolves to a tuple containing:
|
|
2001
|
+
* - The number of inputs added during the process
|
|
2002
|
+
* - A boolean indicating whether change outputs were created (true) or fee was paid without change (false)
|
|
2003
|
+
*
|
|
2004
|
+
* @throws {ErrorTransactionInsufficientCapacity} When there's not enough capacity to cover the fee.
|
|
2005
|
+
* @throws {Error} When the change function doesn't properly handle the available capacity.
|
|
2006
|
+
*
|
|
2007
|
+
* @example
|
|
2008
|
+
* ```typescript
|
|
2009
|
+
* const [addedInputs, hasChange] = await tx.completeFee(
|
|
2010
|
+
* signer,
|
|
2011
|
+
* (tx, capacity) => {
|
|
2012
|
+
* if (capacity >= 61_00000000n) { // Minimum for a change cell
|
|
2013
|
+
* tx.addOutput({ capacity, lock: changeScript });
|
|
2014
|
+
* return 0;
|
|
2015
|
+
* }
|
|
2016
|
+
* return 61_00000000n; // Need more capacity for change cell
|
|
2017
|
+
* },
|
|
2018
|
+
* 1000n // 1000 shannons per 1000 bytes
|
|
2019
|
+
* );
|
|
2020
|
+
* ```
|
|
2021
|
+
*/
|
|
1839
2022
|
async completeFee(
|
|
1840
2023
|
from: Signer,
|
|
1841
2024
|
change: (tx: Transaction, capacity: Num) => Promise<NumLike> | NumLike,
|
|
1842
2025
|
expectedFeeRate?: NumLike,
|
|
1843
2026
|
filter?: ClientCollectableSearchKeyFilterLike,
|
|
1844
|
-
options?: {
|
|
2027
|
+
options?: {
|
|
2028
|
+
feeRateBlockRange?: NumLike;
|
|
2029
|
+
maxFeeRate?: NumLike;
|
|
2030
|
+
shouldAddInputs?: boolean;
|
|
2031
|
+
},
|
|
1845
2032
|
): Promise<[number, boolean]> {
|
|
1846
2033
|
const feeRate =
|
|
1847
2034
|
expectedFeeRate ??
|
|
@@ -1852,40 +2039,67 @@ export class Transaction extends mol.Entity.Base<
|
|
|
1852
2039
|
|
|
1853
2040
|
let leastFee = Zero;
|
|
1854
2041
|
let leastExtraCapacity = Zero;
|
|
1855
|
-
|
|
2042
|
+
let collected = 0;
|
|
2043
|
+
|
|
2044
|
+
// ===
|
|
2045
|
+
// Usually, for the worst situation, three iterations are needed
|
|
2046
|
+
// 1. First attempt to complete the transaction.
|
|
2047
|
+
// 2. Not enough capacity for the change cell.
|
|
2048
|
+
// 3. Fee increased by the change cell.
|
|
2049
|
+
// ===
|
|
1856
2050
|
while (true) {
|
|
1857
|
-
|
|
1858
|
-
|
|
2051
|
+
collected += await (async () => {
|
|
2052
|
+
if (!(options?.shouldAddInputs ?? true)) {
|
|
2053
|
+
return 0;
|
|
2054
|
+
}
|
|
2055
|
+
|
|
1859
2056
|
try {
|
|
1860
|
-
return await
|
|
2057
|
+
return await this.completeInputsByCapacity(
|
|
1861
2058
|
from,
|
|
1862
2059
|
leastFee + leastExtraCapacity,
|
|
1863
2060
|
filter,
|
|
1864
2061
|
);
|
|
1865
2062
|
} catch (err) {
|
|
1866
|
-
if (
|
|
1867
|
-
|
|
2063
|
+
if (
|
|
2064
|
+
err instanceof ErrorTransactionInsufficientCapacity &&
|
|
2065
|
+
leastExtraCapacity !== Zero
|
|
2066
|
+
) {
|
|
2067
|
+
throw new ErrorTransactionInsufficientCapacity(err.amount, {
|
|
2068
|
+
isForChange: true,
|
|
2069
|
+
});
|
|
1868
2070
|
}
|
|
1869
2071
|
|
|
1870
2072
|
throw err;
|
|
1871
2073
|
}
|
|
1872
2074
|
})();
|
|
1873
2075
|
|
|
1874
|
-
await from.
|
|
2076
|
+
const fee = await this.getFee(from.client);
|
|
2077
|
+
if (fee < leastFee + leastExtraCapacity) {
|
|
2078
|
+
// Not enough capacity are collected, it should only happens when shouldAddInputs is false
|
|
2079
|
+
throw new ErrorTransactionInsufficientCapacity(
|
|
2080
|
+
leastFee + leastExtraCapacity - fee,
|
|
2081
|
+
{ isForChange: leastExtraCapacity !== Zero },
|
|
2082
|
+
);
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2085
|
+
await from.prepareTransaction(this);
|
|
1875
2086
|
if (leastFee === Zero) {
|
|
1876
2087
|
// The initial fee is calculated based on prepared transaction
|
|
1877
|
-
|
|
2088
|
+
// This should only happens during the first iteration
|
|
2089
|
+
leastFee = this.estimateFee(feeRate);
|
|
1878
2090
|
}
|
|
1879
|
-
const fee = await tx.getFee(from.client);
|
|
1880
2091
|
// The extra capacity paid the fee without a change
|
|
2092
|
+
// leastExtraCapacity should be 0 here, otherwise we should failed in the previous check
|
|
2093
|
+
// So this only happens in the first iteration
|
|
1881
2094
|
if (fee === leastFee) {
|
|
1882
|
-
this.copy(tx);
|
|
1883
2095
|
return [collected, false];
|
|
1884
2096
|
}
|
|
1885
2097
|
|
|
2098
|
+
// Invoke the change function on a transaction multiple times may cause problems, so we clone it
|
|
2099
|
+
const tx = this.clone();
|
|
1886
2100
|
const needed = numFrom(await Promise.resolve(change(tx, fee - leastFee)));
|
|
1887
|
-
// No enough extra capacity to create new cells for change
|
|
1888
2101
|
if (needed > Zero) {
|
|
2102
|
+
// No enough extra capacity to create new cells for change, collect inputs again
|
|
1889
2103
|
leastExtraCapacity = needed;
|
|
1890
2104
|
continue;
|
|
1891
2105
|
}
|
|
@@ -1913,11 +2127,48 @@ export class Transaction extends mol.Entity.Base<
|
|
|
1913
2127
|
}
|
|
1914
2128
|
}
|
|
1915
2129
|
|
|
2130
|
+
/**
|
|
2131
|
+
* Completes the transaction fee by adding inputs and creating a change output with the specified lock script.
|
|
2132
|
+
* This is a convenience method that automatically creates a change cell with the provided lock script
|
|
2133
|
+
* when there's excess capacity after paying the transaction fee.
|
|
2134
|
+
*
|
|
2135
|
+
* @param from - The signer to complete inputs from and prepare the transaction.
|
|
2136
|
+
* @param change - The lock script for the change output cell.
|
|
2137
|
+
* @param feeRate - Optional fee rate in shannons per 1000 bytes. If not provided, it will be fetched from the client.
|
|
2138
|
+
* @param filter - Optional filter for selecting cells when adding inputs.
|
|
2139
|
+
* @param options - Optional configuration object.
|
|
2140
|
+
* @param options.feeRateBlockRange - Block range for fee rate calculation when feeRate is not provided.
|
|
2141
|
+
* @param options.maxFeeRate - Maximum allowed fee rate.
|
|
2142
|
+
* @param options.shouldAddInputs - Whether to add inputs automatically. Defaults to true.
|
|
2143
|
+
* @returns A promise that resolves to a tuple containing:
|
|
2144
|
+
* - The number of inputs added during the process
|
|
2145
|
+
* - A boolean indicating whether change outputs were created (true) or fee was paid without change (false)
|
|
2146
|
+
*
|
|
2147
|
+
* @example
|
|
2148
|
+
* ```typescript
|
|
2149
|
+
* const changeScript = Script.from({
|
|
2150
|
+
* codeHash: "0x...",
|
|
2151
|
+
* hashType: "type",
|
|
2152
|
+
* args: "0x..."
|
|
2153
|
+
* });
|
|
2154
|
+
*
|
|
2155
|
+
* const [addedInputs, hasChange] = await tx.completeFeeChangeToLock(
|
|
2156
|
+
* signer,
|
|
2157
|
+
* changeScript,
|
|
2158
|
+
* 1000n // 1000 shannons per 1000 bytes
|
|
2159
|
+
* );
|
|
2160
|
+
* ```
|
|
2161
|
+
*/
|
|
1916
2162
|
completeFeeChangeToLock(
|
|
1917
2163
|
from: Signer,
|
|
1918
2164
|
change: ScriptLike,
|
|
1919
2165
|
feeRate?: NumLike,
|
|
1920
2166
|
filter?: ClientCollectableSearchKeyFilterLike,
|
|
2167
|
+
options?: {
|
|
2168
|
+
feeRateBlockRange?: NumLike;
|
|
2169
|
+
maxFeeRate?: NumLike;
|
|
2170
|
+
shouldAddInputs?: boolean;
|
|
2171
|
+
},
|
|
1921
2172
|
): Promise<[number, boolean]> {
|
|
1922
2173
|
const script = Script.from(change);
|
|
1923
2174
|
|
|
@@ -1935,24 +2186,91 @@ export class Transaction extends mol.Entity.Base<
|
|
|
1935
2186
|
},
|
|
1936
2187
|
feeRate,
|
|
1937
2188
|
filter,
|
|
2189
|
+
options,
|
|
1938
2190
|
);
|
|
1939
2191
|
}
|
|
1940
2192
|
|
|
2193
|
+
/**
|
|
2194
|
+
* Completes the transaction fee using the signer's recommended address for change.
|
|
2195
|
+
* This is a convenience method that automatically uses the signer's recommended
|
|
2196
|
+
* address as the change destination, making it easier to complete transactions
|
|
2197
|
+
* without manually specifying a change address.
|
|
2198
|
+
*
|
|
2199
|
+
* @param from - The signer to complete inputs from and prepare the transaction.
|
|
2200
|
+
* @param feeRate - Optional fee rate in shannons per 1000 bytes. If not provided, it will be fetched from the client.
|
|
2201
|
+
* @param filter - Optional filter for selecting cells when adding inputs.
|
|
2202
|
+
* @param options - Optional configuration object.
|
|
2203
|
+
* @param options.feeRateBlockRange - Block range for fee rate calculation when feeRate is not provided.
|
|
2204
|
+
* @param options.maxFeeRate - Maximum allowed fee rate.
|
|
2205
|
+
* @param options.shouldAddInputs - Whether to add inputs automatically. Defaults to true.
|
|
2206
|
+
* @returns A promise that resolves to a tuple containing:
|
|
2207
|
+
* - The number of inputs added during the process
|
|
2208
|
+
* - A boolean indicating whether change outputs were created (true) or fee was paid without change (false)
|
|
2209
|
+
*
|
|
2210
|
+
* @example
|
|
2211
|
+
* ```typescript
|
|
2212
|
+
* const [addedInputs, hasChange] = await tx.completeFeeBy(
|
|
2213
|
+
* signer,
|
|
2214
|
+
* 1000n // 1000 shannons per 1000 bytes
|
|
2215
|
+
* );
|
|
2216
|
+
*
|
|
2217
|
+
* // Change will automatically go to signer's recommended address
|
|
2218
|
+
* ```
|
|
2219
|
+
*/
|
|
1941
2220
|
async completeFeeBy(
|
|
1942
2221
|
from: Signer,
|
|
1943
2222
|
feeRate?: NumLike,
|
|
1944
2223
|
filter?: ClientCollectableSearchKeyFilterLike,
|
|
2224
|
+
options?: {
|
|
2225
|
+
feeRateBlockRange?: NumLike;
|
|
2226
|
+
maxFeeRate?: NumLike;
|
|
2227
|
+
shouldAddInputs?: boolean;
|
|
2228
|
+
},
|
|
1945
2229
|
): Promise<[number, boolean]> {
|
|
1946
2230
|
const { script } = await from.getRecommendedAddressObj();
|
|
1947
2231
|
|
|
1948
|
-
return this.completeFeeChangeToLock(from, script, feeRate, filter);
|
|
2232
|
+
return this.completeFeeChangeToLock(from, script, feeRate, filter, options);
|
|
1949
2233
|
}
|
|
1950
2234
|
|
|
2235
|
+
/**
|
|
2236
|
+
* Completes the transaction fee by adding excess capacity to an existing output.
|
|
2237
|
+
* Instead of creating a new change output, this method adds any excess capacity
|
|
2238
|
+
* to the specified existing output in the transaction.
|
|
2239
|
+
*
|
|
2240
|
+
* @param from - The signer to complete inputs from and prepare the transaction.
|
|
2241
|
+
* @param index - The index of the existing output to add excess capacity to.
|
|
2242
|
+
* @param feeRate - Optional fee rate in shannons per 1000 bytes. If not provided, it will be fetched from the client.
|
|
2243
|
+
* @param filter - Optional filter for selecting cells when adding inputs.
|
|
2244
|
+
* @param options - Optional configuration object.
|
|
2245
|
+
* @param options.feeRateBlockRange - Block range for fee rate calculation when feeRate is not provided.
|
|
2246
|
+
* @param options.maxFeeRate - Maximum allowed fee rate.
|
|
2247
|
+
* @param options.shouldAddInputs - Whether to add inputs automatically. Defaults to true.
|
|
2248
|
+
* @returns A promise that resolves to a tuple containing:
|
|
2249
|
+
* - The number of inputs added during the process
|
|
2250
|
+
* - A boolean indicating whether change was applied (true) or fee was paid without change (false)
|
|
2251
|
+
*
|
|
2252
|
+
* @throws {Error} When the specified output index doesn't exist.
|
|
2253
|
+
*
|
|
2254
|
+
* @example
|
|
2255
|
+
* ```typescript
|
|
2256
|
+
* // Add excess capacity to the first output (index 0)
|
|
2257
|
+
* const [addedInputs, hasChange] = await tx.completeFeeChangeToOutput(
|
|
2258
|
+
* signer,
|
|
2259
|
+
* 0, // Output index
|
|
2260
|
+
* 1000n // 1000 shannons per 1000 bytes
|
|
2261
|
+
* );
|
|
2262
|
+
* ```
|
|
2263
|
+
*/
|
|
1951
2264
|
completeFeeChangeToOutput(
|
|
1952
2265
|
from: Signer,
|
|
1953
2266
|
index: NumLike,
|
|
1954
2267
|
feeRate?: NumLike,
|
|
1955
2268
|
filter?: ClientCollectableSearchKeyFilterLike,
|
|
2269
|
+
options?: {
|
|
2270
|
+
feeRateBlockRange?: NumLike;
|
|
2271
|
+
maxFeeRate?: NumLike;
|
|
2272
|
+
shouldAddInputs?: boolean;
|
|
2273
|
+
},
|
|
1956
2274
|
): Promise<[number, boolean]> {
|
|
1957
2275
|
const change = Number(numFrom(index));
|
|
1958
2276
|
if (!this.outputs[change]) {
|
|
@@ -1966,12 +2284,32 @@ export class Transaction extends mol.Entity.Base<
|
|
|
1966
2284
|
},
|
|
1967
2285
|
feeRate,
|
|
1968
2286
|
filter,
|
|
2287
|
+
options,
|
|
1969
2288
|
);
|
|
1970
2289
|
}
|
|
1971
2290
|
}
|
|
1972
2291
|
|
|
1973
2292
|
/**
|
|
1974
|
-
* Calculate Nervos DAO profit between two blocks
|
|
2293
|
+
* Calculate Nervos DAO profit between two blocks.
|
|
2294
|
+
* This function computes the profit earned from a Nervos DAO deposit
|
|
2295
|
+
* based on the capacity and the time period between deposit and withdrawal.
|
|
2296
|
+
*
|
|
2297
|
+
* @param profitableCapacity - The capacity that earns profit (total capacity minus occupied capacity).
|
|
2298
|
+
* @param depositHeaderLike - The block header when the DAO deposit was made.
|
|
2299
|
+
* @param withdrawHeaderLike - The block header when the DAO withdrawal is made.
|
|
2300
|
+
* @returns The profit amount in CKB (capacity units).
|
|
2301
|
+
*
|
|
2302
|
+
* @example
|
|
2303
|
+
* ```typescript
|
|
2304
|
+
* const profit = calcDaoProfit(
|
|
2305
|
+
* ccc.fixedPointFrom(100), // 100 CKB profitable capacity
|
|
2306
|
+
* depositHeader,
|
|
2307
|
+
* withdrawHeader
|
|
2308
|
+
* );
|
|
2309
|
+
* console.log(`Profit: ${profit} shannons`);
|
|
2310
|
+
* ```
|
|
2311
|
+
*
|
|
2312
|
+
* @see {@link https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0023-dao-deposit-withdraw/0023-dao-deposit-withdraw.md | Nervos DAO RFC}
|
|
1975
2313
|
*/
|
|
1976
2314
|
export function calcDaoProfit(
|
|
1977
2315
|
profitableCapacity: NumLike,
|
|
@@ -1990,8 +2328,26 @@ export function calcDaoProfit(
|
|
|
1990
2328
|
}
|
|
1991
2329
|
|
|
1992
2330
|
/**
|
|
1993
|
-
* Calculate claimable epoch for Nervos DAO withdrawal
|
|
1994
|
-
*
|
|
2331
|
+
* Calculate claimable epoch for Nervos DAO withdrawal.
|
|
2332
|
+
* This function determines the earliest epoch when a Nervos DAO withdrawal
|
|
2333
|
+
* can be claimed based on the deposit and withdrawal epochs.
|
|
2334
|
+
*
|
|
2335
|
+
* @param depositHeader - The block header when the DAO deposit was made.
|
|
2336
|
+
* @param withdrawHeader - The block header when the DAO withdrawal was initiated.
|
|
2337
|
+
* @returns The epoch when the withdrawal can be claimed, represented as [number, index, length].
|
|
2338
|
+
*
|
|
2339
|
+
* @example
|
|
2340
|
+
* ```typescript
|
|
2341
|
+
* const claimEpoch = calcDaoClaimEpoch(depositHeader, withdrawHeader);
|
|
2342
|
+
* console.log(`Can claim at epoch: ${claimEpoch[0]}, index: ${claimEpoch[1]}, length: ${claimEpoch[2]}`);
|
|
2343
|
+
* ```
|
|
2344
|
+
*
|
|
2345
|
+
* @remarks
|
|
2346
|
+
* The Nervos DAO has a minimum lock period of 180 epochs (~30 days).
|
|
2347
|
+
* This function calculates the exact epoch when the withdrawal becomes claimable
|
|
2348
|
+
* based on the deposit epoch and withdrawal epoch timing.
|
|
2349
|
+
*
|
|
2350
|
+
* @see {@link https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0023-dao-deposit-withdraw/0023-dao-deposit-withdraw.md | Nervos DAO RFC}
|
|
1995
2351
|
*/
|
|
1996
2352
|
export function calcDaoClaimEpoch(
|
|
1997
2353
|
depositHeader: ClientBlockHeaderLike,
|