@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.
Files changed (215) hide show
  1. package/dist/address/address.advanced.d.ts.map +1 -1
  2. package/dist/address/address.advanced.js +2 -5
  3. package/dist/address/index.d.ts +1 -1
  4. package/dist/address/index.d.ts.map +1 -1
  5. package/dist/address/index.js +2 -5
  6. package/dist/ckb/script.d.ts +43 -1
  7. package/dist/ckb/script.d.ts.map +1 -1
  8. package/dist/ckb/script.js +51 -0
  9. package/dist/ckb/transaction.d.ts +198 -21
  10. package/dist/ckb/transaction.d.ts.map +1 -1
  11. package/dist/ckb/transaction.js +440 -21
  12. package/dist/client/advanced.d.ts +2 -0
  13. package/dist/client/advanced.d.ts.map +1 -1
  14. package/dist/client/advanced.js +2 -0
  15. package/dist/client/client.advanced.d.ts +10 -0
  16. package/dist/client/client.advanced.d.ts.map +1 -0
  17. package/dist/client/client.advanced.js +80 -0
  18. package/dist/client/client.d.ts +44 -8
  19. package/dist/client/client.d.ts.map +1 -1
  20. package/dist/client/client.js +137 -9
  21. package/dist/client/clientPublicMainnet.advanced.d.ts +4 -2
  22. package/dist/client/clientPublicMainnet.advanced.d.ts.map +1 -1
  23. package/dist/client/clientPublicMainnet.advanced.js +102 -0
  24. package/dist/client/clientPublicMainnet.d.ts +4 -2
  25. package/dist/client/clientPublicMainnet.d.ts.map +1 -1
  26. package/dist/client/clientPublicMainnet.js +5 -1
  27. package/dist/client/clientPublicTestnet.advanced.d.ts +4 -2
  28. package/dist/client/clientPublicTestnet.advanced.d.ts.map +1 -1
  29. package/dist/client/clientPublicTestnet.advanced.js +151 -0
  30. package/dist/client/clientPublicTestnet.d.ts +4 -2
  31. package/dist/client/clientPublicTestnet.d.ts.map +1 -1
  32. package/dist/client/clientPublicTestnet.js +6 -1
  33. package/dist/client/clientTypes.advanced.d.ts +23 -0
  34. package/dist/client/clientTypes.advanced.d.ts.map +1 -0
  35. package/dist/client/clientTypes.advanced.js +4 -0
  36. package/dist/client/clientTypes.d.ts +22 -36
  37. package/dist/client/clientTypes.d.ts.map +1 -1
  38. package/dist/client/clientTypes.js +15 -12
  39. package/dist/client/jsonRpc/index.d.ts +3 -3
  40. package/dist/client/jsonRpc/index.d.ts.map +1 -1
  41. package/dist/client/jsonRpc/index.js +3 -3
  42. package/dist/client/jsonRpc/transformers.d.ts +5 -7
  43. package/dist/client/jsonRpc/transformers.d.ts.map +1 -1
  44. package/dist/client/jsonRpc/transformers.js +8 -6
  45. package/dist/hasher/index.d.ts +1 -1
  46. package/dist/hasher/index.d.ts.map +1 -1
  47. package/dist/hasher/index.js +4 -2
  48. package/dist/num/index.d.ts +12 -0
  49. package/dist/num/index.d.ts.map +1 -1
  50. package/dist/num/index.js +21 -0
  51. package/dist/signer/btc/signerBtc.d.ts.map +1 -1
  52. package/dist/signer/btc/signerBtc.js +2 -1
  53. package/dist/signer/evm/signerEvm.d.ts.map +1 -1
  54. package/dist/signer/evm/signerEvm.js +5 -3
  55. package/dist/signer/nostr/signerNostr.d.ts.map +1 -1
  56. package/dist/signer/nostr/signerNostr.js +2 -1
  57. package/dist/utils/index.d.ts +1 -1
  58. package/dist/utils/index.d.ts.map +1 -1
  59. package/dist/utils/index.js +1 -1
  60. package/dist.commonjs/address/address.advanced.d.ts +29 -24
  61. package/dist.commonjs/address/address.advanced.d.ts.map +1 -1
  62. package/dist.commonjs/address/address.advanced.js +115 -92
  63. package/dist.commonjs/address/advanced.d.ts +1 -1
  64. package/dist.commonjs/address/advanced.js +30 -14
  65. package/dist.commonjs/address/index.d.ts +51 -44
  66. package/dist.commonjs/address/index.d.ts.map +1 -1
  67. package/dist.commonjs/address/index.js +84 -68
  68. package/dist.commonjs/advanced.d.ts +1 -1
  69. package/dist.commonjs/advanced.js +47 -22
  70. package/dist.commonjs/advancedBarrel.d.ts +1 -1
  71. package/dist.commonjs/advancedBarrel.js +30 -14
  72. package/dist.commonjs/barrel.d.ts +1 -1
  73. package/dist.commonjs/barrel.js +30 -14
  74. package/dist.commonjs/bytes/advanced.d.ts +11 -2
  75. package/dist.commonjs/bytes/index.d.ts +9 -3
  76. package/dist.commonjs/bytes/index.js +28 -26
  77. package/dist.commonjs/ckb/advanced.d.ts +1 -1
  78. package/dist.commonjs/ckb/advanced.js +47 -22
  79. package/dist.commonjs/ckb/index.d.ts +1 -1
  80. package/dist.commonjs/ckb/index.js +30 -14
  81. package/dist.commonjs/ckb/molecule.advanced/generated.d.ts +420 -260
  82. package/dist.commonjs/ckb/molecule.advanced/generated.js +1536 -1332
  83. package/dist.commonjs/ckb/molecule.advanced/index.d.ts +3 -3
  84. package/dist.commonjs/ckb/molecule.advanced/index.js +34 -18
  85. package/dist.commonjs/ckb/script.advanced.d.ts +1 -1
  86. package/dist.commonjs/ckb/script.advanced.js +12 -9
  87. package/dist.commonjs/ckb/script.d.ts +123 -77
  88. package/dist.commonjs/ckb/script.d.ts.map +1 -1
  89. package/dist.commonjs/ckb/script.js +221 -126
  90. package/dist.commonjs/ckb/transaction.advanced.d.ts +1 -1
  91. package/dist.commonjs/ckb/transaction.advanced.js +4 -4
  92. package/dist.commonjs/ckb/transaction.d.ts +796 -544
  93. package/dist.commonjs/ckb/transaction.d.ts.map +1 -1
  94. package/dist.commonjs/ckb/transaction.js +1373 -725
  95. package/dist.commonjs/client/advanced.d.ts +3 -1
  96. package/dist.commonjs/client/advanced.d.ts.map +1 -1
  97. package/dist.commonjs/client/advanced.js +32 -14
  98. package/dist.commonjs/client/client.advanced.d.ts +27 -0
  99. package/dist.commonjs/client/client.advanced.d.ts.map +1 -0
  100. package/dist.commonjs/client/client.advanced.js +116 -0
  101. package/dist.commonjs/client/client.d.ts +118 -22
  102. package/dist.commonjs/client/client.d.ts.map +1 -1
  103. package/dist.commonjs/client/client.js +218 -56
  104. package/dist.commonjs/client/clientPublicMainnet.advanced.d.ts +9 -3
  105. package/dist.commonjs/client/clientPublicMainnet.advanced.d.ts.map +1 -1
  106. package/dist.commonjs/client/clientPublicMainnet.advanced.js +144 -25
  107. package/dist.commonjs/client/clientPublicMainnet.d.ts +9 -5
  108. package/dist.commonjs/client/clientPublicMainnet.d.ts.map +1 -1
  109. package/dist.commonjs/client/clientPublicMainnet.js +18 -12
  110. package/dist.commonjs/client/clientPublicTestnet.advanced.d.ts +8 -3
  111. package/dist.commonjs/client/clientPublicTestnet.advanced.d.ts.map +1 -1
  112. package/dist.commonjs/client/clientPublicTestnet.advanced.js +204 -28
  113. package/dist.commonjs/client/clientPublicTestnet.d.ts +9 -5
  114. package/dist.commonjs/client/clientPublicTestnet.d.ts.map +1 -1
  115. package/dist.commonjs/client/clientPublicTestnet.js +14 -9
  116. package/dist.commonjs/client/clientTypes.advanced.d.ts +23 -0
  117. package/dist.commonjs/client/clientTypes.advanced.d.ts.map +1 -0
  118. package/dist.commonjs/client/clientTypes.advanced.js +8 -0
  119. package/dist.commonjs/client/clientTypes.d.ts +57 -46
  120. package/dist.commonjs/client/clientTypes.d.ts.map +1 -1
  121. package/dist.commonjs/client/clientTypes.js +60 -22
  122. package/dist.commonjs/client/index.d.ts +1 -1
  123. package/dist.commonjs/client/index.js +30 -14
  124. package/dist.commonjs/client/jsonRpc/advanced.d.ts +1 -1
  125. package/dist.commonjs/client/jsonRpc/advanced.js +30 -14
  126. package/dist.commonjs/client/jsonRpc/index.d.ts +94 -75
  127. package/dist.commonjs/client/jsonRpc/index.d.ts.map +1 -1
  128. package/dist.commonjs/client/jsonRpc/index.js +135 -108
  129. package/dist.commonjs/client/jsonRpc/transformers.d.ts +76 -38
  130. package/dist.commonjs/client/jsonRpc/transformers.d.ts.map +1 -1
  131. package/dist.commonjs/client/jsonRpc/transformers.js +174 -150
  132. package/dist.commonjs/client/jsonRpc/types.d.ts +38 -38
  133. package/dist.commonjs/fixedPoint/index.d.ts +9 -3
  134. package/dist.commonjs/fixedPoint/index.js +26 -20
  135. package/dist.commonjs/fixedPoint/index.test.d.ts +1 -1
  136. package/dist.commonjs/fixedPoint/index.test.js +42 -36
  137. package/dist.commonjs/hasher/advanced.d.ts +1 -1
  138. package/dist.commonjs/hasher/index.d.ts +37 -37
  139. package/dist.commonjs/hasher/index.d.ts.map +1 -1
  140. package/dist.commonjs/hasher/index.js +55 -46
  141. package/dist.commonjs/hex/index.d.ts +1 -1
  142. package/dist.commonjs/hex/index.js +1 -1
  143. package/dist.commonjs/index.d.ts +1 -1
  144. package/dist.commonjs/index.js +47 -22
  145. package/dist.commonjs/num/index.d.ts +13 -1
  146. package/dist.commonjs/num/index.d.ts.map +1 -1
  147. package/dist.commonjs/num/index.js +53 -19
  148. package/dist.commonjs/signer/btc/index.d.ts +1 -1
  149. package/dist.commonjs/signer/btc/index.js +30 -14
  150. package/dist.commonjs/signer/btc/signerBtc.d.ts +47 -47
  151. package/dist.commonjs/signer/btc/signerBtc.d.ts.map +1 -1
  152. package/dist.commonjs/signer/btc/signerBtc.js +89 -65
  153. package/dist.commonjs/signer/btc/signerBtcPublicKeyReadonly.d.ts +45 -45
  154. package/dist.commonjs/signer/btc/signerBtcPublicKeyReadonly.js +52 -52
  155. package/dist.commonjs/signer/btc/verify.d.ts +6 -2
  156. package/dist.commonjs/signer/btc/verify.js +10 -3
  157. package/dist.commonjs/signer/ckb/index.d.ts +1 -1
  158. package/dist.commonjs/signer/ckb/index.js +30 -14
  159. package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.d.ts +45 -45
  160. package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.js +56 -56
  161. package/dist.commonjs/signer/ckb/verifyJoyId.d.ts +6 -2
  162. package/dist.commonjs/signer/ckb/verifyJoyId.js +11 -8
  163. package/dist.commonjs/signer/dummy/alwaysError.d.ts +4 -4
  164. package/dist.commonjs/signer/dummy/alwaysError.js +7 -7
  165. package/dist.commonjs/signer/dummy/dummy.d.ts +7 -7
  166. package/dist.commonjs/signer/dummy/dummy.js +16 -16
  167. package/dist.commonjs/signer/dummy/index.d.ts +1 -1
  168. package/dist.commonjs/signer/dummy/index.js +30 -14
  169. package/dist.commonjs/signer/dummy/openLink.d.ts +4 -4
  170. package/dist.commonjs/signer/dummy/openLink.js +7 -7
  171. package/dist.commonjs/signer/evm/index.d.ts +1 -1
  172. package/dist.commonjs/signer/evm/index.js +30 -14
  173. package/dist.commonjs/signer/evm/signerEvm.d.ts +42 -38
  174. package/dist.commonjs/signer/evm/signerEvm.d.ts.map +1 -1
  175. package/dist.commonjs/signer/evm/signerEvm.js +105 -68
  176. package/dist.commonjs/signer/evm/signerEvmAddressReadonly.d.ts +37 -37
  177. package/dist.commonjs/signer/evm/signerEvmAddressReadonly.js +42 -42
  178. package/dist.commonjs/signer/evm/verify.d.ts +6 -2
  179. package/dist.commonjs/signer/evm/verify.js +7 -2
  180. package/dist.commonjs/signer/index.d.ts +1 -1
  181. package/dist.commonjs/signer/index.js +30 -14
  182. package/dist.commonjs/signer/nostr/index.d.ts +1 -1
  183. package/dist.commonjs/signer/nostr/index.js +30 -14
  184. package/dist.commonjs/signer/nostr/signerNostr.d.ts +57 -57
  185. package/dist.commonjs/signer/nostr/signerNostr.d.ts.map +1 -1
  186. package/dist.commonjs/signer/nostr/signerNostr.js +100 -70
  187. package/dist.commonjs/signer/nostr/verify.d.ts +9 -3
  188. package/dist.commonjs/signer/nostr/verify.js +50 -39
  189. package/dist.commonjs/signer/signer/index.d.ts +156 -150
  190. package/dist.commonjs/signer/signer/index.js +208 -181
  191. package/dist.commonjs/utils/index.d.ts +38 -8
  192. package/dist.commonjs/utils/index.d.ts.map +1 -1
  193. package/dist.commonjs/utils/index.js +18 -12
  194. package/package.json +2 -2
  195. package/src/address/address.advanced.ts +2 -5
  196. package/src/address/index.ts +2 -5
  197. package/src/ckb/script.ts +62 -2
  198. package/src/ckb/transaction.ts +637 -46
  199. package/src/client/advanced.ts +2 -0
  200. package/src/client/client.advanced.ts +134 -0
  201. package/src/client/client.ts +225 -16
  202. package/src/client/clientPublicMainnet.advanced.ts +116 -2
  203. package/src/client/clientPublicMainnet.ts +8 -3
  204. package/src/client/clientPublicTestnet.advanced.ts +171 -2
  205. package/src/client/clientPublicTestnet.ts +9 -3
  206. package/src/client/clientTypes.advanced.ts +26 -0
  207. package/src/client/clientTypes.ts +41 -43
  208. package/src/client/jsonRpc/index.ts +4 -4
  209. package/src/client/jsonRpc/transformers.ts +13 -11
  210. package/src/hasher/index.ts +4 -2
  211. package/src/num/index.ts +22 -0
  212. package/src/signer/btc/signerBtc.ts +2 -1
  213. package/src/signer/evm/signerEvm.ts +5 -3
  214. package/src/signer/nostr/signerNostr.ts +2 -1
  215. package/src/utils/index.ts +6 -2
@@ -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 { apply } from "../utils";
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.encode();
161
+ * const outPointBytes = outPoint.toBytes();
146
162
  * ```
147
163
  */
148
164
 
149
- encode(): Bytes {
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
- numFrom(cell.blockNumber),
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: NumLike;
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 The completed instance.
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 && this.blockNumber) {
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: NumLike;
658
- cellDeps: CellDepLike[];
659
- headerDeps: HexLike[];
660
- inputs: CellInputLike[];
661
- outputs: CellOutputLike[];
662
- outputsData: HexLike[];
663
- witnesses: HexLike[];
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.map((cellDep) => CellDep.from(cellDep)),
731
- tx.headerDeps.map(hexFrom),
732
- tx.inputs.map((input) => CellInput.from(input)),
733
- tx.outputs.map((output) => CellOutput.from(output)),
734
- tx.outputsData.map(hexFrom),
735
- tx.witnesses.map(hexFrom),
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 resolve inputs info");
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 resolve inputs info");
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 resolve inputs info");
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
  }