@ckb-ccc/core 0.0.6-alpha.0 → 0.0.7-alpha.1
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/dist/address/address.advanced.d.ts.map +1 -1
- package/dist/address/address.advanced.js +2 -5
- package/dist/address/index.d.ts +1 -1
- package/dist/address/index.d.ts.map +1 -1
- package/dist/address/index.js +2 -5
- package/dist/ckb/script.d.ts +43 -1
- package/dist/ckb/script.d.ts.map +1 -1
- package/dist/ckb/script.js +51 -0
- package/dist/ckb/transaction.d.ts +198 -21
- package/dist/ckb/transaction.d.ts.map +1 -1
- package/dist/ckb/transaction.js +440 -21
- package/dist/client/advanced.d.ts +2 -0
- package/dist/client/advanced.d.ts.map +1 -1
- package/dist/client/advanced.js +2 -0
- package/dist/client/client.advanced.d.ts +10 -0
- package/dist/client/client.advanced.d.ts.map +1 -0
- package/dist/client/client.advanced.js +80 -0
- package/dist/client/client.d.ts +44 -8
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +137 -9
- package/dist/client/clientPublicMainnet.advanced.d.ts +4 -2
- package/dist/client/clientPublicMainnet.advanced.d.ts.map +1 -1
- package/dist/client/clientPublicMainnet.advanced.js +102 -0
- package/dist/client/clientPublicMainnet.d.ts +4 -2
- package/dist/client/clientPublicMainnet.d.ts.map +1 -1
- package/dist/client/clientPublicMainnet.js +5 -1
- package/dist/client/clientPublicTestnet.advanced.d.ts +4 -2
- package/dist/client/clientPublicTestnet.advanced.d.ts.map +1 -1
- package/dist/client/clientPublicTestnet.advanced.js +151 -0
- package/dist/client/clientPublicTestnet.d.ts +4 -2
- package/dist/client/clientPublicTestnet.d.ts.map +1 -1
- package/dist/client/clientPublicTestnet.js +6 -1
- package/dist/client/clientTypes.advanced.d.ts +23 -0
- package/dist/client/clientTypes.advanced.d.ts.map +1 -0
- package/dist/client/clientTypes.advanced.js +4 -0
- package/dist/client/clientTypes.d.ts +22 -36
- package/dist/client/clientTypes.d.ts.map +1 -1
- package/dist/client/clientTypes.js +15 -12
- package/dist/client/jsonRpc/index.d.ts +3 -3
- package/dist/client/jsonRpc/index.d.ts.map +1 -1
- package/dist/client/jsonRpc/index.js +3 -3
- package/dist/client/jsonRpc/transformers.d.ts +5 -7
- package/dist/client/jsonRpc/transformers.d.ts.map +1 -1
- package/dist/client/jsonRpc/transformers.js +8 -6
- package/dist/hasher/index.d.ts +1 -1
- package/dist/hasher/index.d.ts.map +1 -1
- package/dist/hasher/index.js +4 -2
- package/dist/num/index.d.ts +12 -0
- package/dist/num/index.d.ts.map +1 -1
- package/dist/num/index.js +21 -0
- package/dist/signer/btc/signerBtc.d.ts.map +1 -1
- package/dist/signer/btc/signerBtc.js +2 -1
- package/dist/signer/evm/signerEvm.d.ts.map +1 -1
- package/dist/signer/evm/signerEvm.js +5 -3
- package/dist/signer/nostr/signerNostr.d.ts.map +1 -1
- package/dist/signer/nostr/signerNostr.js +2 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist.commonjs/address/address.advanced.d.ts +29 -24
- package/dist.commonjs/address/address.advanced.d.ts.map +1 -1
- package/dist.commonjs/address/address.advanced.js +115 -92
- package/dist.commonjs/address/advanced.d.ts +1 -1
- package/dist.commonjs/address/advanced.js +30 -14
- package/dist.commonjs/address/index.d.ts +51 -44
- package/dist.commonjs/address/index.d.ts.map +1 -1
- package/dist.commonjs/address/index.js +84 -68
- package/dist.commonjs/advanced.d.ts +1 -1
- package/dist.commonjs/advanced.js +47 -22
- package/dist.commonjs/advancedBarrel.d.ts +1 -1
- package/dist.commonjs/advancedBarrel.js +30 -14
- package/dist.commonjs/barrel.d.ts +1 -1
- package/dist.commonjs/barrel.js +30 -14
- package/dist.commonjs/bytes/advanced.d.ts +11 -2
- package/dist.commonjs/bytes/index.d.ts +9 -3
- package/dist.commonjs/bytes/index.js +28 -26
- package/dist.commonjs/ckb/advanced.d.ts +1 -1
- package/dist.commonjs/ckb/advanced.js +47 -22
- package/dist.commonjs/ckb/index.d.ts +1 -1
- package/dist.commonjs/ckb/index.js +30 -14
- package/dist.commonjs/ckb/molecule.advanced/generated.d.ts +420 -260
- package/dist.commonjs/ckb/molecule.advanced/generated.js +1536 -1332
- package/dist.commonjs/ckb/molecule.advanced/index.d.ts +3 -3
- package/dist.commonjs/ckb/molecule.advanced/index.js +34 -18
- package/dist.commonjs/ckb/script.advanced.d.ts +1 -1
- package/dist.commonjs/ckb/script.advanced.js +12 -9
- package/dist.commonjs/ckb/script.d.ts +123 -77
- package/dist.commonjs/ckb/script.d.ts.map +1 -1
- package/dist.commonjs/ckb/script.js +221 -126
- package/dist.commonjs/ckb/transaction.advanced.d.ts +1 -1
- package/dist.commonjs/ckb/transaction.advanced.js +4 -4
- package/dist.commonjs/ckb/transaction.d.ts +796 -544
- package/dist.commonjs/ckb/transaction.d.ts.map +1 -1
- package/dist.commonjs/ckb/transaction.js +1373 -725
- package/dist.commonjs/client/advanced.d.ts +3 -1
- package/dist.commonjs/client/advanced.d.ts.map +1 -1
- package/dist.commonjs/client/advanced.js +32 -14
- package/dist.commonjs/client/client.advanced.d.ts +27 -0
- package/dist.commonjs/client/client.advanced.d.ts.map +1 -0
- package/dist.commonjs/client/client.advanced.js +116 -0
- package/dist.commonjs/client/client.d.ts +118 -22
- package/dist.commonjs/client/client.d.ts.map +1 -1
- package/dist.commonjs/client/client.js +218 -56
- package/dist.commonjs/client/clientPublicMainnet.advanced.d.ts +9 -3
- package/dist.commonjs/client/clientPublicMainnet.advanced.d.ts.map +1 -1
- package/dist.commonjs/client/clientPublicMainnet.advanced.js +144 -25
- package/dist.commonjs/client/clientPublicMainnet.d.ts +9 -5
- package/dist.commonjs/client/clientPublicMainnet.d.ts.map +1 -1
- package/dist.commonjs/client/clientPublicMainnet.js +18 -12
- package/dist.commonjs/client/clientPublicTestnet.advanced.d.ts +8 -3
- package/dist.commonjs/client/clientPublicTestnet.advanced.d.ts.map +1 -1
- package/dist.commonjs/client/clientPublicTestnet.advanced.js +204 -28
- package/dist.commonjs/client/clientPublicTestnet.d.ts +9 -5
- package/dist.commonjs/client/clientPublicTestnet.d.ts.map +1 -1
- package/dist.commonjs/client/clientPublicTestnet.js +14 -9
- package/dist.commonjs/client/clientTypes.advanced.d.ts +23 -0
- package/dist.commonjs/client/clientTypes.advanced.d.ts.map +1 -0
- package/dist.commonjs/client/clientTypes.advanced.js +8 -0
- package/dist.commonjs/client/clientTypes.d.ts +57 -46
- package/dist.commonjs/client/clientTypes.d.ts.map +1 -1
- package/dist.commonjs/client/clientTypes.js +60 -22
- package/dist.commonjs/client/index.d.ts +1 -1
- package/dist.commonjs/client/index.js +30 -14
- package/dist.commonjs/client/jsonRpc/advanced.d.ts +1 -1
- package/dist.commonjs/client/jsonRpc/advanced.js +30 -14
- package/dist.commonjs/client/jsonRpc/index.d.ts +94 -75
- package/dist.commonjs/client/jsonRpc/index.d.ts.map +1 -1
- package/dist.commonjs/client/jsonRpc/index.js +135 -108
- package/dist.commonjs/client/jsonRpc/transformers.d.ts +76 -38
- package/dist.commonjs/client/jsonRpc/transformers.d.ts.map +1 -1
- package/dist.commonjs/client/jsonRpc/transformers.js +174 -150
- package/dist.commonjs/client/jsonRpc/types.d.ts +38 -38
- package/dist.commonjs/fixedPoint/index.d.ts +9 -3
- package/dist.commonjs/fixedPoint/index.js +26 -20
- package/dist.commonjs/fixedPoint/index.test.d.ts +1 -1
- package/dist.commonjs/fixedPoint/index.test.js +42 -36
- package/dist.commonjs/hasher/advanced.d.ts +1 -1
- package/dist.commonjs/hasher/index.d.ts +37 -37
- package/dist.commonjs/hasher/index.d.ts.map +1 -1
- package/dist.commonjs/hasher/index.js +55 -46
- package/dist.commonjs/hex/index.d.ts +1 -1
- package/dist.commonjs/hex/index.js +1 -1
- package/dist.commonjs/index.d.ts +1 -1
- package/dist.commonjs/index.js +47 -22
- package/dist.commonjs/num/index.d.ts +13 -1
- package/dist.commonjs/num/index.d.ts.map +1 -1
- package/dist.commonjs/num/index.js +53 -19
- package/dist.commonjs/signer/btc/index.d.ts +1 -1
- package/dist.commonjs/signer/btc/index.js +30 -14
- package/dist.commonjs/signer/btc/signerBtc.d.ts +47 -47
- package/dist.commonjs/signer/btc/signerBtc.d.ts.map +1 -1
- package/dist.commonjs/signer/btc/signerBtc.js +89 -65
- package/dist.commonjs/signer/btc/signerBtcPublicKeyReadonly.d.ts +45 -45
- package/dist.commonjs/signer/btc/signerBtcPublicKeyReadonly.js +52 -52
- package/dist.commonjs/signer/btc/verify.d.ts +6 -2
- package/dist.commonjs/signer/btc/verify.js +10 -3
- package/dist.commonjs/signer/ckb/index.d.ts +1 -1
- package/dist.commonjs/signer/ckb/index.js +30 -14
- package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.d.ts +45 -45
- package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.js +56 -56
- package/dist.commonjs/signer/ckb/verifyJoyId.d.ts +6 -2
- package/dist.commonjs/signer/ckb/verifyJoyId.js +11 -8
- package/dist.commonjs/signer/dummy/alwaysError.d.ts +4 -4
- package/dist.commonjs/signer/dummy/alwaysError.js +7 -7
- package/dist.commonjs/signer/dummy/dummy.d.ts +7 -7
- package/dist.commonjs/signer/dummy/dummy.js +16 -16
- package/dist.commonjs/signer/dummy/index.d.ts +1 -1
- package/dist.commonjs/signer/dummy/index.js +30 -14
- package/dist.commonjs/signer/dummy/openLink.d.ts +4 -4
- package/dist.commonjs/signer/dummy/openLink.js +7 -7
- package/dist.commonjs/signer/evm/index.d.ts +1 -1
- package/dist.commonjs/signer/evm/index.js +30 -14
- package/dist.commonjs/signer/evm/signerEvm.d.ts +42 -38
- package/dist.commonjs/signer/evm/signerEvm.d.ts.map +1 -1
- package/dist.commonjs/signer/evm/signerEvm.js +105 -68
- package/dist.commonjs/signer/evm/signerEvmAddressReadonly.d.ts +37 -37
- package/dist.commonjs/signer/evm/signerEvmAddressReadonly.js +42 -42
- package/dist.commonjs/signer/evm/verify.d.ts +6 -2
- package/dist.commonjs/signer/evm/verify.js +7 -2
- package/dist.commonjs/signer/index.d.ts +1 -1
- package/dist.commonjs/signer/index.js +30 -14
- package/dist.commonjs/signer/nostr/index.d.ts +1 -1
- package/dist.commonjs/signer/nostr/index.js +30 -14
- package/dist.commonjs/signer/nostr/signerNostr.d.ts +57 -57
- package/dist.commonjs/signer/nostr/signerNostr.d.ts.map +1 -1
- package/dist.commonjs/signer/nostr/signerNostr.js +100 -70
- package/dist.commonjs/signer/nostr/verify.d.ts +9 -3
- package/dist.commonjs/signer/nostr/verify.js +50 -39
- package/dist.commonjs/signer/signer/index.d.ts +156 -150
- package/dist.commonjs/signer/signer/index.js +208 -181
- package/dist.commonjs/utils/index.d.ts +38 -8
- package/dist.commonjs/utils/index.d.ts.map +1 -1
- package/dist.commonjs/utils/index.js +18 -12
- package/package.json +2 -2
- package/src/address/address.advanced.ts +2 -5
- package/src/address/index.ts +2 -5
- package/src/ckb/script.ts +62 -2
- package/src/ckb/transaction.ts +637 -46
- package/src/client/advanced.ts +2 -0
- package/src/client/client.advanced.ts +134 -0
- package/src/client/client.ts +225 -16
- package/src/client/clientPublicMainnet.advanced.ts +116 -2
- package/src/client/clientPublicMainnet.ts +8 -3
- package/src/client/clientPublicTestnet.advanced.ts +171 -2
- package/src/client/clientPublicTestnet.ts +9 -3
- package/src/client/clientTypes.advanced.ts +26 -0
- package/src/client/clientTypes.ts +41 -43
- package/src/client/jsonRpc/index.ts +4 -4
- package/src/client/jsonRpc/transformers.ts +13 -11
- package/src/hasher/index.ts +4 -2
- package/src/num/index.ts +22 -0
- package/src/signer/btc/signerBtc.ts +2 -1
- package/src/signer/evm/signerEvm.ts +5 -3
- package/src/signer/nostr/signerNostr.ts +2 -1
- package/src/utils/index.ts +6 -2
package/src/ckb/transaction.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { TransactionSkeletonType } from "@ckb-lumos/helpers";
|
|
2
|
+
import { ClientCollectableSearchKeyFilterLike } from "../advancedBarrel";
|
|
2
3
|
import { Bytes, BytesLike, bytesFrom } from "../bytes";
|
|
3
|
-
import { Client } from "../client";
|
|
4
|
+
import { CellDepInfoLike, Client, KnownScript } from "../client";
|
|
5
|
+
import { Zero, fixedPointFrom } from "../fixedPoint";
|
|
4
6
|
import { Hasher, ckbHash } from "../hasher";
|
|
5
7
|
import { Hex, HexLike, hexFrom } from "../hex";
|
|
6
8
|
import {
|
|
@@ -11,7 +13,8 @@ import {
|
|
|
11
13
|
numToBytes,
|
|
12
14
|
numToHex,
|
|
13
15
|
} from "../num";
|
|
14
|
-
import {
|
|
16
|
+
import { Signer } from "../signer";
|
|
17
|
+
import { apply, reduceAsync } from "../utils";
|
|
15
18
|
import * as mol from "./molecule.advanced";
|
|
16
19
|
import { Script, ScriptLike } from "./script";
|
|
17
20
|
import { DEP_TYPE_TO_NUM, NUM_TO_DEP_TYPE } from "./transaction.advanced";
|
|
@@ -103,6 +106,20 @@ export class OutPoint {
|
|
|
103
106
|
public index: Num,
|
|
104
107
|
) {}
|
|
105
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Clone an OutPoint.
|
|
111
|
+
*
|
|
112
|
+
* @returns A cloned OutPoint instance.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```typescript
|
|
116
|
+
* const outPoint1 = outPoint0.clone();
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
clone(): OutPoint {
|
|
120
|
+
return new OutPoint(this.txHash, this.index);
|
|
121
|
+
}
|
|
122
|
+
|
|
106
123
|
/**
|
|
107
124
|
* Creates an OutPoint instance from an OutPointLike object.
|
|
108
125
|
*
|
|
@@ -114,7 +131,6 @@ export class OutPoint {
|
|
|
114
131
|
* const outPoint = OutPoint.from({ txHash: "0x...", index: 0 });
|
|
115
132
|
* ```
|
|
116
133
|
*/
|
|
117
|
-
|
|
118
134
|
static from(outPoint: OutPointLike): OutPoint {
|
|
119
135
|
if (outPoint instanceof OutPoint) {
|
|
120
136
|
return outPoint;
|
|
@@ -142,11 +158,11 @@ export class OutPoint {
|
|
|
142
158
|
*
|
|
143
159
|
* @example
|
|
144
160
|
* ```typescript
|
|
145
|
-
* const outPointBytes = outPoint.
|
|
161
|
+
* const outPointBytes = outPoint.toBytes();
|
|
146
162
|
* ```
|
|
147
163
|
*/
|
|
148
164
|
|
|
149
|
-
|
|
165
|
+
toBytes(): Bytes {
|
|
150
166
|
return bytesFrom(mol.SerializeOutPoint(this._toMolData()));
|
|
151
167
|
}
|
|
152
168
|
|
|
@@ -173,6 +189,22 @@ export class OutPoint {
|
|
|
173
189
|
numFromBytes(view.getIndex().raw()),
|
|
174
190
|
);
|
|
175
191
|
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Compares the current OutPoint instance with another OutPointLike object for equality.
|
|
195
|
+
*
|
|
196
|
+
* @param val - The OutPointLike object to compare with.
|
|
197
|
+
* @returns True if the out points are equal, otherwise false.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* const isEqual = outPoint.eq(anotherOutPoint);
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
eq(val: OutPointLike): boolean {
|
|
205
|
+
const outPoint = OutPoint.from(val);
|
|
206
|
+
return this.txHash === outPoint.txHash && this.index === outPoint.index;
|
|
207
|
+
}
|
|
176
208
|
}
|
|
177
209
|
|
|
178
210
|
export type CellOutputLike = {
|
|
@@ -195,6 +227,24 @@ export class CellOutput {
|
|
|
195
227
|
public type?: Script,
|
|
196
228
|
) {}
|
|
197
229
|
|
|
230
|
+
get occupiedSize(): number {
|
|
231
|
+
return 8 + this.lock.occupiedSize + (this.type?.occupiedSize ?? 0);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Clone a CellOutput.
|
|
236
|
+
*
|
|
237
|
+
* @returns A cloned CellOutput instance.
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```typescript
|
|
241
|
+
* const cellOutput1 = cellOutput0.clone();
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
clone(): CellOutput {
|
|
245
|
+
return new CellOutput(this.capacity, this.lock.clone(), this.type?.clone());
|
|
246
|
+
}
|
|
247
|
+
|
|
198
248
|
/**
|
|
199
249
|
* Creates a CellOutput instance from a CellOutputLike object.
|
|
200
250
|
*
|
|
@@ -210,7 +260,6 @@ export class CellOutput {
|
|
|
210
260
|
* });
|
|
211
261
|
* ```
|
|
212
262
|
*/
|
|
213
|
-
|
|
214
263
|
static from(cellOutput: CellOutputLike): CellOutput {
|
|
215
264
|
if (cellOutput instanceof CellOutput) {
|
|
216
265
|
return cellOutput;
|
|
@@ -282,7 +331,6 @@ export type CellLike = {
|
|
|
282
331
|
outPoint: OutPointLike;
|
|
283
332
|
cellOutput: CellOutputLike;
|
|
284
333
|
outputData: HexLike;
|
|
285
|
-
blockNumber: NumLike;
|
|
286
334
|
};
|
|
287
335
|
export class Cell {
|
|
288
336
|
/**
|
|
@@ -291,14 +339,12 @@ export class Cell {
|
|
|
291
339
|
* @param outPoint - The output point of the cell.
|
|
292
340
|
* @param cellOutput - The cell output of the cell.
|
|
293
341
|
* @param outputData - The output data of the cell.
|
|
294
|
-
* @param blockNumber - The block number of the cell.
|
|
295
342
|
*/
|
|
296
343
|
|
|
297
344
|
constructor(
|
|
298
345
|
public outPoint: OutPoint,
|
|
299
346
|
public cellOutput: CellOutput,
|
|
300
347
|
public outputData: Hex,
|
|
301
|
-
public blockNumber: Num,
|
|
302
348
|
) {}
|
|
303
349
|
|
|
304
350
|
/**
|
|
@@ -317,17 +363,33 @@ export class Cell {
|
|
|
317
363
|
OutPoint.from(cell.outPoint),
|
|
318
364
|
CellOutput.from(cell.cellOutput),
|
|
319
365
|
hexFrom(cell.outputData),
|
|
320
|
-
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Clone a Cell
|
|
371
|
+
*
|
|
372
|
+
* @returns A cloned Cell instance.
|
|
373
|
+
*
|
|
374
|
+
* @example
|
|
375
|
+
* ```typescript
|
|
376
|
+
* const cell1 = cell0.clone();
|
|
377
|
+
* ```
|
|
378
|
+
*/
|
|
379
|
+
clone(): Cell {
|
|
380
|
+
return new Cell(
|
|
381
|
+
this.outPoint.clone(),
|
|
382
|
+
this.cellOutput.clone(),
|
|
383
|
+
this.outputData,
|
|
321
384
|
);
|
|
322
385
|
}
|
|
323
386
|
}
|
|
324
387
|
|
|
325
388
|
export type CellInputLike = {
|
|
326
389
|
previousOutput: OutPointLike;
|
|
327
|
-
since
|
|
390
|
+
since?: NumLike;
|
|
328
391
|
cellOutput?: CellOutputLike;
|
|
329
392
|
outputData?: HexLike;
|
|
330
|
-
blockNumber?: NumLike;
|
|
331
393
|
};
|
|
332
394
|
export class CellInput {
|
|
333
395
|
/**
|
|
@@ -337,7 +399,6 @@ export class CellInput {
|
|
|
337
399
|
* @param since - The since value of the cell input.
|
|
338
400
|
* @param cellOutput - The optional cell output associated with the cell input.
|
|
339
401
|
* @param outputData - The optional output data associated with the cell input.
|
|
340
|
-
* @param blockNumber - The optional block number associated with the cell input.
|
|
341
402
|
*/
|
|
342
403
|
|
|
343
404
|
constructor(
|
|
@@ -345,9 +406,27 @@ export class CellInput {
|
|
|
345
406
|
public since: Num,
|
|
346
407
|
public cellOutput?: CellOutput,
|
|
347
408
|
public outputData?: Hex,
|
|
348
|
-
public blockNumber?: Num,
|
|
349
409
|
) {}
|
|
350
410
|
|
|
411
|
+
/**
|
|
412
|
+
* Clone a CellInput.
|
|
413
|
+
*
|
|
414
|
+
* @returns A cloned CellInput instance.
|
|
415
|
+
*
|
|
416
|
+
* @example
|
|
417
|
+
* ```typescript
|
|
418
|
+
* const cellInput1 = cellInput0.clone();
|
|
419
|
+
* ```
|
|
420
|
+
*/
|
|
421
|
+
clone(): CellInput {
|
|
422
|
+
return new CellInput(
|
|
423
|
+
this.previousOutput.clone(),
|
|
424
|
+
this.since,
|
|
425
|
+
this.cellOutput?.clone(),
|
|
426
|
+
this.outputData,
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
|
|
351
430
|
/**
|
|
352
431
|
* Creates a CellInput instance from a CellInputLike object.
|
|
353
432
|
*
|
|
@@ -362,7 +441,6 @@ export class CellInput {
|
|
|
362
441
|
* });
|
|
363
442
|
* ```
|
|
364
443
|
*/
|
|
365
|
-
|
|
366
444
|
static from(cellInput: CellInputLike): CellInput {
|
|
367
445
|
if (cellInput instanceof CellInput) {
|
|
368
446
|
return cellInput;
|
|
@@ -370,10 +448,9 @@ export class CellInput {
|
|
|
370
448
|
|
|
371
449
|
return new CellInput(
|
|
372
450
|
OutPoint.from(cellInput.previousOutput),
|
|
373
|
-
numFrom(cellInput.since),
|
|
451
|
+
numFrom(cellInput.since ?? 0),
|
|
374
452
|
apply(CellOutput.from, cellInput.cellOutput),
|
|
375
453
|
apply(hexFrom, cellInput.outputData),
|
|
376
|
-
apply(numFrom, cellInput.blockNumber),
|
|
377
454
|
);
|
|
378
455
|
}
|
|
379
456
|
|
|
@@ -381,15 +458,14 @@ export class CellInput {
|
|
|
381
458
|
* Complete extra infos in the input. Like the output of the out point.
|
|
382
459
|
* The instance will be modified.
|
|
383
460
|
*
|
|
384
|
-
* @returns
|
|
461
|
+
* @returns true if succeed.
|
|
385
462
|
* @example
|
|
386
463
|
* ```typescript
|
|
387
464
|
* await cellInput.completeExtraInfos();
|
|
388
465
|
* ```
|
|
389
466
|
*/
|
|
390
|
-
|
|
391
467
|
async completeExtraInfos(client: Client): Promise<void> {
|
|
392
|
-
if (this.cellOutput && this.outputData
|
|
468
|
+
if (this.cellOutput && this.outputData) {
|
|
393
469
|
return;
|
|
394
470
|
}
|
|
395
471
|
|
|
@@ -400,7 +476,6 @@ export class CellInput {
|
|
|
400
476
|
|
|
401
477
|
this.cellOutput = cell.cellOutput;
|
|
402
478
|
this.outputData = cell.outputData;
|
|
403
|
-
this.blockNumber = cell.blockNumber;
|
|
404
479
|
}
|
|
405
480
|
|
|
406
481
|
/**
|
|
@@ -473,6 +548,21 @@ export class CellDep {
|
|
|
473
548
|
public depType: DepType,
|
|
474
549
|
) {}
|
|
475
550
|
|
|
551
|
+
/**
|
|
552
|
+
* Clone a CellDep.
|
|
553
|
+
*
|
|
554
|
+
* @returns A cloned CellDep instance.
|
|
555
|
+
*
|
|
556
|
+
* @example
|
|
557
|
+
* ```typescript
|
|
558
|
+
* const cellDep1 = cellDep0.clone();
|
|
559
|
+
* ```
|
|
560
|
+
*/
|
|
561
|
+
|
|
562
|
+
clone(): CellDep {
|
|
563
|
+
return new CellDep(this.outPoint.clone(), this.depType);
|
|
564
|
+
}
|
|
565
|
+
|
|
476
566
|
/**
|
|
477
567
|
* Creates a CellDep instance from a CellDepLike object.
|
|
478
568
|
*
|
|
@@ -548,6 +638,24 @@ export class CellDep {
|
|
|
548
638
|
depTypeFromBytes([view.getDepType()]),
|
|
549
639
|
);
|
|
550
640
|
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Compares the current CellDep instance with another CellDepLike object for equality.
|
|
644
|
+
*
|
|
645
|
+
* @param val - The CellDepLike object to compare with.
|
|
646
|
+
* @returns True if the cell deps are equal, otherwise false.
|
|
647
|
+
*
|
|
648
|
+
* @example
|
|
649
|
+
* ```typescript
|
|
650
|
+
* const isEqual = cellDep.eq(anotherCellDep);
|
|
651
|
+
* ```
|
|
652
|
+
*/
|
|
653
|
+
eq(val: CellDepLike): boolean {
|
|
654
|
+
const cellDep = CellDep.from(val);
|
|
655
|
+
return (
|
|
656
|
+
this.outPoint.eq(cellDep.outPoint) && this.depType === cellDep.depType
|
|
657
|
+
);
|
|
658
|
+
}
|
|
551
659
|
}
|
|
552
660
|
|
|
553
661
|
export type WitnessArgsLike = {
|
|
@@ -653,14 +761,24 @@ export class WitnessArgs {
|
|
|
653
761
|
}
|
|
654
762
|
}
|
|
655
763
|
|
|
764
|
+
export function udtBalanceFrom(dataLike: BytesLike) {
|
|
765
|
+
const data = bytesFrom(dataLike).slice(0, 16);
|
|
766
|
+
if (data.length !== 16) {
|
|
767
|
+
throw new Error("Invalid UDT cell data");
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
return numFromBytes(data);
|
|
771
|
+
}
|
|
772
|
+
|
|
656
773
|
export type TransactionLike = {
|
|
657
|
-
version
|
|
658
|
-
cellDeps
|
|
659
|
-
headerDeps
|
|
660
|
-
inputs
|
|
661
|
-
outputs
|
|
662
|
-
|
|
663
|
-
|
|
774
|
+
version?: NumLike;
|
|
775
|
+
cellDeps?: CellDepLike[];
|
|
776
|
+
headerDeps?: HexLike[];
|
|
777
|
+
inputs?: CellInputLike[];
|
|
778
|
+
outputs?: (Omit<CellOutputLike, "capacity"> &
|
|
779
|
+
Partial<Pick<CellOutputLike, "capacity">>)[];
|
|
780
|
+
outputsData?: HexLike[];
|
|
781
|
+
witnesses?: HexLike[];
|
|
664
782
|
};
|
|
665
783
|
export class Transaction {
|
|
666
784
|
/**
|
|
@@ -695,11 +813,51 @@ export class Transaction {
|
|
|
695
813
|
* const defaultTx = Transaction.default();
|
|
696
814
|
* ```
|
|
697
815
|
*/
|
|
698
|
-
|
|
699
816
|
static default(): Transaction {
|
|
700
817
|
return new Transaction(0n, [], [], [], [], [], []);
|
|
701
818
|
}
|
|
702
819
|
|
|
820
|
+
/**
|
|
821
|
+
* Copy every properties from another transaction.
|
|
822
|
+
*
|
|
823
|
+
* @example
|
|
824
|
+
* ```typescript
|
|
825
|
+
* this.copy(Transaction.default());
|
|
826
|
+
* ```
|
|
827
|
+
*/
|
|
828
|
+
copy(txLike: TransactionLike) {
|
|
829
|
+
const tx = Transaction.from(txLike);
|
|
830
|
+
this.version = tx.version;
|
|
831
|
+
this.cellDeps = tx.cellDeps;
|
|
832
|
+
this.headerDeps = tx.headerDeps;
|
|
833
|
+
this.inputs = tx.inputs;
|
|
834
|
+
this.outputs = tx.outputs;
|
|
835
|
+
this.outputsData = tx.outputsData;
|
|
836
|
+
this.witnesses = tx.witnesses;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Clone a Transaction.
|
|
841
|
+
*
|
|
842
|
+
* @returns A cloned instance
|
|
843
|
+
*
|
|
844
|
+
* @example
|
|
845
|
+
* ```typescript
|
|
846
|
+
* const tx1 = tx0.clone();
|
|
847
|
+
* ```
|
|
848
|
+
*/
|
|
849
|
+
clone(): Transaction {
|
|
850
|
+
return new Transaction(
|
|
851
|
+
0n,
|
|
852
|
+
this.cellDeps.map((c) => c.clone()),
|
|
853
|
+
[...this.headerDeps],
|
|
854
|
+
this.inputs.map((i) => i.clone()),
|
|
855
|
+
this.outputs.map((o) => o.clone()),
|
|
856
|
+
[...this.outputsData],
|
|
857
|
+
[...this.witnesses],
|
|
858
|
+
);
|
|
859
|
+
}
|
|
860
|
+
|
|
703
861
|
/**
|
|
704
862
|
* Creates a Transaction instance from a TransactionLike object.
|
|
705
863
|
*
|
|
@@ -724,15 +882,40 @@ export class Transaction {
|
|
|
724
882
|
if (tx instanceof Transaction) {
|
|
725
883
|
return tx;
|
|
726
884
|
}
|
|
885
|
+
const outputs =
|
|
886
|
+
tx.outputs?.map((output, i) => {
|
|
887
|
+
const o = CellOutput.from({
|
|
888
|
+
...output,
|
|
889
|
+
capacity: output.capacity ?? 0,
|
|
890
|
+
});
|
|
891
|
+
if (o.capacity === Zero) {
|
|
892
|
+
o.capacity = fixedPointFrom(
|
|
893
|
+
o.occupiedSize +
|
|
894
|
+
(apply(bytesFrom, tx.outputsData?.[i])?.length ?? 0),
|
|
895
|
+
);
|
|
896
|
+
}
|
|
897
|
+
return o;
|
|
898
|
+
}) ?? [];
|
|
899
|
+
const outputsData = outputs.map((_, i) =>
|
|
900
|
+
hexFrom(tx.outputsData?.[i] ?? "0x"),
|
|
901
|
+
);
|
|
902
|
+
if (
|
|
903
|
+
tx.outputsData !== undefined &&
|
|
904
|
+
outputsData.length < tx.outputsData.length
|
|
905
|
+
) {
|
|
906
|
+
outputsData.push(
|
|
907
|
+
...tx.outputsData.slice(outputsData.length).map((d) => hexFrom(d)),
|
|
908
|
+
);
|
|
909
|
+
}
|
|
727
910
|
|
|
728
911
|
return new Transaction(
|
|
729
|
-
numFrom(tx.version),
|
|
730
|
-
tx.cellDeps
|
|
731
|
-
tx.headerDeps
|
|
732
|
-
tx.inputs
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
tx.witnesses
|
|
912
|
+
numFrom(tx.version ?? 0),
|
|
913
|
+
tx.cellDeps?.map((cellDep) => CellDep.from(cellDep)) ?? [],
|
|
914
|
+
tx.headerDeps?.map(hexFrom) ?? [],
|
|
915
|
+
tx.inputs?.map((input) => CellInput.from(input)) ?? [],
|
|
916
|
+
outputs,
|
|
917
|
+
outputsData,
|
|
918
|
+
tx.witnesses?.map(hexFrom) ?? [],
|
|
736
919
|
);
|
|
737
920
|
}
|
|
738
921
|
|
|
@@ -792,7 +975,6 @@ export class Transaction {
|
|
|
792
975
|
* const rawTxBytes = transaction.rawToBytes();
|
|
793
976
|
* ```
|
|
794
977
|
*/
|
|
795
|
-
|
|
796
978
|
rawToBytes(): Bytes {
|
|
797
979
|
return bytesFrom(
|
|
798
980
|
mol.SerializeRawTransaction({
|
|
@@ -806,6 +988,32 @@ export class Transaction {
|
|
|
806
988
|
);
|
|
807
989
|
}
|
|
808
990
|
|
|
991
|
+
/**
|
|
992
|
+
* Converts the whole transaction data to bytes.
|
|
993
|
+
*
|
|
994
|
+
* @returns A Uint8Array containing the full transaction bytes.
|
|
995
|
+
*
|
|
996
|
+
* @example
|
|
997
|
+
* ```typescript
|
|
998
|
+
* const txBytes = transaction.toBytes();
|
|
999
|
+
* ```
|
|
1000
|
+
*/
|
|
1001
|
+
toBytes(): Bytes {
|
|
1002
|
+
return bytesFrom(
|
|
1003
|
+
mol.SerializeTransaction({
|
|
1004
|
+
raw: {
|
|
1005
|
+
version: numToBytes(this.version, 4),
|
|
1006
|
+
cellDeps: this.cellDeps.map((d) => d._toMolData()),
|
|
1007
|
+
headerDeps: this.headerDeps.map((header) => bytesFrom(header)),
|
|
1008
|
+
inputs: this.inputs.map((i) => i._toMolData()),
|
|
1009
|
+
outputs: this.outputs.map((o) => o._toMolData()),
|
|
1010
|
+
outputsData: this.outputsData.map((header) => bytesFrom(header)),
|
|
1011
|
+
},
|
|
1012
|
+
witnesses: this.witnesses.map((witness) => bytesFrom(witness)),
|
|
1013
|
+
}),
|
|
1014
|
+
);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
809
1017
|
/**
|
|
810
1018
|
* Calculates the hash of the transaction.
|
|
811
1019
|
*
|
|
@@ -866,12 +1074,11 @@ export class Transaction {
|
|
|
866
1074
|
hasher.update(this.hash());
|
|
867
1075
|
|
|
868
1076
|
for (let i = 0; i < this.witnesses.length; i += 1) {
|
|
869
|
-
const input = this.inputs[i];
|
|
1077
|
+
const input = await this.inputs[i];
|
|
1078
|
+
await input.completeExtraInfos(client);
|
|
870
1079
|
if (input) {
|
|
871
|
-
await input.completeExtraInfos(client);
|
|
872
|
-
|
|
873
1080
|
if (!input.cellOutput) {
|
|
874
|
-
throw Error("Unable to
|
|
1081
|
+
throw new Error("Unable to complete input");
|
|
875
1082
|
}
|
|
876
1083
|
|
|
877
1084
|
if (!script.eq(input.cellOutput.lock)) {
|
|
@@ -921,9 +1128,8 @@ export class Transaction {
|
|
|
921
1128
|
for (let i = 0; i < this.inputs.length; i += 1) {
|
|
922
1129
|
const input = this.inputs[i];
|
|
923
1130
|
await input.completeExtraInfos(client);
|
|
924
|
-
|
|
925
1131
|
if (!input.cellOutput) {
|
|
926
|
-
throw Error("Unable to
|
|
1132
|
+
throw new Error("Unable to complete input");
|
|
927
1133
|
}
|
|
928
1134
|
|
|
929
1135
|
if (script.eq(input.cellOutput.lock)) {
|
|
@@ -953,9 +1159,8 @@ export class Transaction {
|
|
|
953
1159
|
for (let i = this.inputs.length - 1; i >= 0; i -= 1) {
|
|
954
1160
|
const input = this.inputs[i];
|
|
955
1161
|
await input.completeExtraInfos(client);
|
|
956
|
-
|
|
957
1162
|
if (!input.cellOutput) {
|
|
958
|
-
throw Error("Unable to
|
|
1163
|
+
throw new Error("Unable to complete input");
|
|
959
1164
|
}
|
|
960
1165
|
|
|
961
1166
|
if (script.eq(input.cellOutput.lock)) {
|
|
@@ -964,6 +1169,125 @@ export class Transaction {
|
|
|
964
1169
|
}
|
|
965
1170
|
}
|
|
966
1171
|
|
|
1172
|
+
/**
|
|
1173
|
+
* Add cell deps if they are not existed
|
|
1174
|
+
*
|
|
1175
|
+
* @param cellDepLikes - The cell deps to add
|
|
1176
|
+
*
|
|
1177
|
+
* @example
|
|
1178
|
+
* ```typescript
|
|
1179
|
+
* tx.addCellDeps(cellDep);
|
|
1180
|
+
* ```
|
|
1181
|
+
*/
|
|
1182
|
+
addCellDeps(...cellDepsLike: (CellDepLike | CellDepLike[])[]): void {
|
|
1183
|
+
cellDepsLike.flat().forEach((cellDepLike) => {
|
|
1184
|
+
const cellDep = CellDep.from(cellDepLike);
|
|
1185
|
+
if (this.cellDeps.some((c) => c.eq(cellDep))) {
|
|
1186
|
+
return;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
this.cellDeps.push(cellDep);
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
/**
|
|
1194
|
+
* Add cell dep from infos if they are not existed
|
|
1195
|
+
*
|
|
1196
|
+
* @param client - A client for searching cell deps
|
|
1197
|
+
* @param cellDepLikes - The cell dep infos to add
|
|
1198
|
+
*
|
|
1199
|
+
* @example
|
|
1200
|
+
* ```typescript
|
|
1201
|
+
* tx.addCellDepInfos(client, cellDepInfos);
|
|
1202
|
+
* ```
|
|
1203
|
+
*/
|
|
1204
|
+
async addCellDepInfos(
|
|
1205
|
+
client: Client,
|
|
1206
|
+
...cellDepInfosLike: (CellDepInfoLike | CellDepInfoLike[])[]
|
|
1207
|
+
): Promise<void> {
|
|
1208
|
+
this.addCellDeps(await client.getCellDeps(...cellDepInfosLike));
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
/**
|
|
1212
|
+
* Add cell deps from known script
|
|
1213
|
+
*
|
|
1214
|
+
* @param client - The client for searching known script and cell deps
|
|
1215
|
+
* @param scripts - The known scripts to add
|
|
1216
|
+
*
|
|
1217
|
+
* @example
|
|
1218
|
+
* ```typescript
|
|
1219
|
+
* tx.addCellDepsOfKnownScripts(client, KnownScript.OmniLock);
|
|
1220
|
+
* ```
|
|
1221
|
+
*/
|
|
1222
|
+
async addCellDepsOfKnownScripts(
|
|
1223
|
+
client: Client,
|
|
1224
|
+
...scripts: (KnownScript | KnownScript[])[]
|
|
1225
|
+
): Promise<void> {
|
|
1226
|
+
await Promise.all(
|
|
1227
|
+
scripts
|
|
1228
|
+
.flat()
|
|
1229
|
+
.map(async (script) =>
|
|
1230
|
+
this.addCellDepInfos(
|
|
1231
|
+
client,
|
|
1232
|
+
(await client.getKnownScript(script)).cellDeps,
|
|
1233
|
+
),
|
|
1234
|
+
),
|
|
1235
|
+
);
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
/**
|
|
1239
|
+
* Set output data at index.
|
|
1240
|
+
*
|
|
1241
|
+
* @param index - The index of the output data.
|
|
1242
|
+
* @param witness - The data to set.
|
|
1243
|
+
*
|
|
1244
|
+
* @example
|
|
1245
|
+
* ```typescript
|
|
1246
|
+
* await tx.setOutputData(0, "0x00");
|
|
1247
|
+
* ```
|
|
1248
|
+
*/
|
|
1249
|
+
setOutputDataAt(index: number, data: HexLike): void {
|
|
1250
|
+
if (this.outputsData.length < index) {
|
|
1251
|
+
this.outputsData.push(
|
|
1252
|
+
...Array.from(
|
|
1253
|
+
new Array(index - this.outputsData.length),
|
|
1254
|
+
(): Hex => "0x",
|
|
1255
|
+
),
|
|
1256
|
+
);
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
this.outputsData[index] = hexFrom(data);
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
/**
|
|
1263
|
+
* Add output
|
|
1264
|
+
*
|
|
1265
|
+
* @param output - The cell output to add
|
|
1266
|
+
* @param data - optional output data
|
|
1267
|
+
*
|
|
1268
|
+
* @example
|
|
1269
|
+
* ```typescript
|
|
1270
|
+
* await tx.addOutput(cellOutput, "0xabcd");
|
|
1271
|
+
* ```
|
|
1272
|
+
*/
|
|
1273
|
+
addOutput(
|
|
1274
|
+
outputLike: Omit<CellOutputLike, "capacity"> &
|
|
1275
|
+
Partial<Pick<CellOutputLike, "capacity">>,
|
|
1276
|
+
outputData: HexLike = "0x",
|
|
1277
|
+
): void {
|
|
1278
|
+
const output = CellOutput.from({
|
|
1279
|
+
...outputLike,
|
|
1280
|
+
capacity: outputLike.capacity ?? 0,
|
|
1281
|
+
});
|
|
1282
|
+
if (output.capacity === Zero) {
|
|
1283
|
+
output.capacity = fixedPointFrom(
|
|
1284
|
+
output.occupiedSize + bytesFrom(outputData).length,
|
|
1285
|
+
);
|
|
1286
|
+
}
|
|
1287
|
+
const i = this.outputs.push(output) - 1;
|
|
1288
|
+
this.setOutputDataAt(i, outputData);
|
|
1289
|
+
}
|
|
1290
|
+
|
|
967
1291
|
/**
|
|
968
1292
|
* Get witness at index as WitnessArgs
|
|
969
1293
|
*
|
|
@@ -987,7 +1311,6 @@ export class Transaction {
|
|
|
987
1311
|
*
|
|
988
1312
|
* @param index - The index of the witness.
|
|
989
1313
|
* @param witness - The WitnessArgs to set.
|
|
990
|
-
* @returns The transaction itself.
|
|
991
1314
|
*
|
|
992
1315
|
* @example
|
|
993
1316
|
* ```typescript
|
|
@@ -1034,4 +1357,272 @@ export class Transaction {
|
|
|
1034
1357
|
witness.lock = hexFrom(Array.from(new Array(lockLen), () => 0));
|
|
1035
1358
|
this.setWitnessArgsAt(position, witness);
|
|
1036
1359
|
}
|
|
1360
|
+
|
|
1361
|
+
async getInputsCapacity(client: Client): Promise<Num> {
|
|
1362
|
+
return reduceAsync(
|
|
1363
|
+
this.inputs,
|
|
1364
|
+
async (acc, input) => {
|
|
1365
|
+
await input.completeExtraInfos(client);
|
|
1366
|
+
if (!input.cellOutput) {
|
|
1367
|
+
throw new Error("Unable to complete input");
|
|
1368
|
+
}
|
|
1369
|
+
return acc + input.cellOutput.capacity;
|
|
1370
|
+
},
|
|
1371
|
+
numFrom(0),
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
getOutputsCapacity(): Num {
|
|
1376
|
+
return this.outputs.reduce(
|
|
1377
|
+
(acc, { capacity }) => acc + capacity,
|
|
1378
|
+
numFrom(0),
|
|
1379
|
+
);
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
async getInputsUdtBalance(client: Client, type: ScriptLike): Promise<Num> {
|
|
1383
|
+
return reduceAsync(
|
|
1384
|
+
this.inputs,
|
|
1385
|
+
async (acc, input) => {
|
|
1386
|
+
await input.completeExtraInfos(client);
|
|
1387
|
+
if (!input.cellOutput || !input.outputData) {
|
|
1388
|
+
throw new Error("Unable to complete input");
|
|
1389
|
+
}
|
|
1390
|
+
if (!input.cellOutput.type?.eq(type)) {
|
|
1391
|
+
return;
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
return acc + udtBalanceFrom(input.outputData);
|
|
1395
|
+
},
|
|
1396
|
+
numFrom(0),
|
|
1397
|
+
);
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
getOutputsUdtBalance(type: ScriptLike): Num {
|
|
1401
|
+
return this.outputs.reduce((acc, output, i) => {
|
|
1402
|
+
if (!output.type?.eq(type)) {
|
|
1403
|
+
return acc;
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
return acc + udtBalanceFrom(this.outputsData[i]);
|
|
1407
|
+
}, numFrom(0));
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
async completeInputs<T>(
|
|
1411
|
+
from: Signer,
|
|
1412
|
+
filter: ClientCollectableSearchKeyFilterLike,
|
|
1413
|
+
accumulator: (
|
|
1414
|
+
acc: T,
|
|
1415
|
+
v: Cell,
|
|
1416
|
+
i: number,
|
|
1417
|
+
array: Cell[],
|
|
1418
|
+
) => Promise<T | undefined> | T | undefined,
|
|
1419
|
+
init: T,
|
|
1420
|
+
): Promise<number> {
|
|
1421
|
+
const scripts = (await from.getAddressObjs()).map(({ script }) => script);
|
|
1422
|
+
const collectedCells = [];
|
|
1423
|
+
let acc: T = init;
|
|
1424
|
+
|
|
1425
|
+
for (const script of scripts) {
|
|
1426
|
+
for await (const cell of from.client.findCellsByCollectableSearchKey({
|
|
1427
|
+
script,
|
|
1428
|
+
scriptType: "lock",
|
|
1429
|
+
filter,
|
|
1430
|
+
scriptSearchMode: "exact",
|
|
1431
|
+
withData: true,
|
|
1432
|
+
})) {
|
|
1433
|
+
if (
|
|
1434
|
+
this.inputs.some(({ previousOutput }) =>
|
|
1435
|
+
previousOutput.eq(cell.outPoint),
|
|
1436
|
+
)
|
|
1437
|
+
) {
|
|
1438
|
+
continue;
|
|
1439
|
+
}
|
|
1440
|
+
const i = collectedCells.push(cell);
|
|
1441
|
+
const next: T | undefined = await Promise.resolve(
|
|
1442
|
+
accumulator(acc, cell, i - 1, collectedCells),
|
|
1443
|
+
);
|
|
1444
|
+
if (next === undefined) {
|
|
1445
|
+
this.inputs.push(
|
|
1446
|
+
...collectedCells.map(({ outPoint, outputData, cellOutput }) =>
|
|
1447
|
+
CellInput.from({
|
|
1448
|
+
previousOutput: outPoint,
|
|
1449
|
+
since: 0,
|
|
1450
|
+
outputData,
|
|
1451
|
+
cellOutput,
|
|
1452
|
+
}),
|
|
1453
|
+
),
|
|
1454
|
+
);
|
|
1455
|
+
return collectedCells.length;
|
|
1456
|
+
}
|
|
1457
|
+
acc = next;
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
throw new Error("Failed to find enough cells for input");
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
async completeInputsByCapacity(
|
|
1465
|
+
from: Signer,
|
|
1466
|
+
capacityTweak?: NumLike,
|
|
1467
|
+
filter?: ClientCollectableSearchKeyFilterLike,
|
|
1468
|
+
): Promise<number> {
|
|
1469
|
+
const exceptedCapacity =
|
|
1470
|
+
this.getOutputsCapacity() + numFrom(capacityTweak ?? 0);
|
|
1471
|
+
const inputsCapacity = await this.getInputsCapacity(from.client);
|
|
1472
|
+
if (inputsCapacity >= exceptedCapacity) {
|
|
1473
|
+
return 0;
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
return this.completeInputs(
|
|
1477
|
+
from,
|
|
1478
|
+
filter ?? {
|
|
1479
|
+
scriptLenRange: [0, 1],
|
|
1480
|
+
outputDataLenRange: [0, 1],
|
|
1481
|
+
},
|
|
1482
|
+
(acc, { cellOutput: { capacity } }) => {
|
|
1483
|
+
const sum = acc + capacity;
|
|
1484
|
+
return sum > exceptedCapacity ? undefined : sum;
|
|
1485
|
+
},
|
|
1486
|
+
inputsCapacity,
|
|
1487
|
+
);
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
async completeInputsByUdt(from: Signer, type: ScriptLike): Promise<number> {
|
|
1491
|
+
const exceptedBalance = this.getOutputsUdtBalance(type);
|
|
1492
|
+
const inputsBalance = await this.getInputsUdtBalance(from.client, type);
|
|
1493
|
+
if (inputsBalance >= exceptedBalance) {
|
|
1494
|
+
return 0;
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
return this.completeInputs(
|
|
1498
|
+
from,
|
|
1499
|
+
{
|
|
1500
|
+
script: type,
|
|
1501
|
+
outputDataLenRange: [16, numFrom("0xffffffff")],
|
|
1502
|
+
},
|
|
1503
|
+
(acc, { outputData }) => {
|
|
1504
|
+
const balance = udtBalanceFrom(outputData);
|
|
1505
|
+
const sum = acc + balance;
|
|
1506
|
+
return sum > exceptedBalance ? undefined : sum;
|
|
1507
|
+
},
|
|
1508
|
+
inputsBalance,
|
|
1509
|
+
);
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
estimateFee(feeRate: NumLike): Num {
|
|
1513
|
+
const txSize = this.toBytes().length + 4;
|
|
1514
|
+
return (numFrom(txSize) * numFrom(feeRate) + numFrom(1000)) / numFrom(1000);
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
async completeFee(
|
|
1518
|
+
from: Signer,
|
|
1519
|
+
change: (tx: Transaction, capacity: Num) => Promise<NumLike> | NumLike,
|
|
1520
|
+
feeRate: NumLike,
|
|
1521
|
+
filter?: ClientCollectableSearchKeyFilterLike,
|
|
1522
|
+
): Promise<[number, boolean]> {
|
|
1523
|
+
// Complete all inputs extra infos for cache
|
|
1524
|
+
await this.getInputsCapacity(from.client);
|
|
1525
|
+
|
|
1526
|
+
let leastFee = this.estimateFee(feeRate);
|
|
1527
|
+
let leastExtraCapacity = Zero;
|
|
1528
|
+
|
|
1529
|
+
while (true) {
|
|
1530
|
+
const prepared = await from.prepareTransaction(this.clone());
|
|
1531
|
+
const collected = await prepared.completeInputsByCapacity(
|
|
1532
|
+
from,
|
|
1533
|
+
leastFee + leastExtraCapacity,
|
|
1534
|
+
filter,
|
|
1535
|
+
);
|
|
1536
|
+
|
|
1537
|
+
const extraCapacity =
|
|
1538
|
+
(await prepared.getInputsCapacity(from.client)) -
|
|
1539
|
+
prepared.getOutputsCapacity();
|
|
1540
|
+
// The extra capacity paid the fee without a change
|
|
1541
|
+
if (extraCapacity === leastFee) {
|
|
1542
|
+
this.copy(prepared);
|
|
1543
|
+
return [collected, false];
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
let changed = prepared.clone();
|
|
1547
|
+
const needed = numFrom(
|
|
1548
|
+
await Promise.resolve(change(changed, extraCapacity - leastFee)),
|
|
1549
|
+
);
|
|
1550
|
+
// No enough extra capacity to create new cells for change
|
|
1551
|
+
if (needed > Zero) {
|
|
1552
|
+
leastExtraCapacity = needed;
|
|
1553
|
+
continue;
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
if (
|
|
1557
|
+
(await changed.getInputsCapacity(from.client)) -
|
|
1558
|
+
changed.getOutputsCapacity() !==
|
|
1559
|
+
leastFee
|
|
1560
|
+
) {
|
|
1561
|
+
throw new Error(
|
|
1562
|
+
"The change function doesn't use all available capacity",
|
|
1563
|
+
);
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
// New change cells created, update the fee
|
|
1567
|
+
await from.prepareTransaction(changed);
|
|
1568
|
+
const changedFee = changed.estimateFee(feeRate);
|
|
1569
|
+
if (leastFee > changedFee) {
|
|
1570
|
+
throw new Error("The change function removed existed transaction data");
|
|
1571
|
+
}
|
|
1572
|
+
// The fee has been paid
|
|
1573
|
+
if (leastFee === changedFee) {
|
|
1574
|
+
this.copy(changed);
|
|
1575
|
+
return [collected, true];
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
// The fee after changing is more than the original fee
|
|
1579
|
+
leastFee = changedFee;
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
completeFeeChangeToLock(
|
|
1584
|
+
from: Signer,
|
|
1585
|
+
change: ScriptLike,
|
|
1586
|
+
feeRate: NumLike,
|
|
1587
|
+
filter?: ClientCollectableSearchKeyFilterLike,
|
|
1588
|
+
): Promise<[number, boolean]> {
|
|
1589
|
+
const script = Script.from(change);
|
|
1590
|
+
|
|
1591
|
+
return this.completeFee(
|
|
1592
|
+
from,
|
|
1593
|
+
(tx, capacity) => {
|
|
1594
|
+
const changeCell = CellOutput.from({ capacity: 0, lock: script });
|
|
1595
|
+
const occupiedCapacity = fixedPointFrom(changeCell.occupiedSize);
|
|
1596
|
+
if (capacity < occupiedCapacity) {
|
|
1597
|
+
return occupiedCapacity;
|
|
1598
|
+
}
|
|
1599
|
+
changeCell.capacity = capacity;
|
|
1600
|
+
tx.addOutput(changeCell);
|
|
1601
|
+
return 0;
|
|
1602
|
+
},
|
|
1603
|
+
feeRate,
|
|
1604
|
+
filter,
|
|
1605
|
+
);
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
completeFeeChangeToOutput(
|
|
1609
|
+
from: Signer,
|
|
1610
|
+
index: NumLike,
|
|
1611
|
+
feeRate: NumLike,
|
|
1612
|
+
filter?: ClientCollectableSearchKeyFilterLike,
|
|
1613
|
+
): Promise<[number, boolean]> {
|
|
1614
|
+
const change = Number(numFrom(index));
|
|
1615
|
+
if (!this.outputs[change]) {
|
|
1616
|
+
throw new Error("Non-existed output to change");
|
|
1617
|
+
}
|
|
1618
|
+
return this.completeFee(
|
|
1619
|
+
from,
|
|
1620
|
+
(tx, capacity) => {
|
|
1621
|
+
tx.outputs[change].capacity += capacity;
|
|
1622
|
+
return 0;
|
|
1623
|
+
},
|
|
1624
|
+
feeRate,
|
|
1625
|
+
filter,
|
|
1626
|
+
);
|
|
1627
|
+
}
|
|
1037
1628
|
}
|