@ckb-ccc/core 0.0.5-alpha.8 → 0.0.7-alpha.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.
Files changed (265) 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 +215 -27
  10. package/dist/ckb/transaction.d.ts.map +1 -1
  11. package/dist/ckb/transaction.js +472 -32
  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 +50 -13
  19. package/dist/client/client.d.ts.map +1 -1
  20. package/dist/client/client.js +145 -15
  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 +103 -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 +9 -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 +155 -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 +6 -3
  53. package/dist/signer/btc/signerBtcPublicKeyReadonly.d.ts +0 -6
  54. package/dist/signer/btc/signerBtcPublicKeyReadonly.d.ts.map +1 -1
  55. package/dist/signer/btc/signerBtcPublicKeyReadonly.js +0 -8
  56. package/dist/signer/btc/verify.d.ts.map +1 -1
  57. package/dist/signer/btc/verify.js +5 -2
  58. package/dist/signer/ckb/signerCkbScriptReadonly.d.ts +0 -6
  59. package/dist/signer/ckb/signerCkbScriptReadonly.d.ts.map +1 -1
  60. package/dist/signer/ckb/signerCkbScriptReadonly.js +0 -8
  61. package/dist/signer/dummy/alwaysError.d.ts +0 -1
  62. package/dist/signer/dummy/alwaysError.d.ts.map +1 -1
  63. package/dist/signer/dummy/alwaysError.js +0 -3
  64. package/dist/signer/dummy/openLink.d.ts +0 -1
  65. package/dist/signer/dummy/openLink.d.ts.map +1 -1
  66. package/dist/signer/dummy/openLink.js +0 -3
  67. package/dist/signer/evm/signerEvm.d.ts.map +1 -1
  68. package/dist/signer/evm/signerEvm.js +7 -5
  69. package/dist/signer/evm/signerEvmAddressReadonly.d.ts +0 -6
  70. package/dist/signer/evm/signerEvmAddressReadonly.d.ts.map +1 -1
  71. package/dist/signer/evm/signerEvmAddressReadonly.js +0 -8
  72. package/dist/signer/index.d.ts +1 -0
  73. package/dist/signer/index.d.ts.map +1 -1
  74. package/dist/signer/index.js +1 -0
  75. package/dist/signer/nostr/index.d.ts +2 -0
  76. package/dist/signer/nostr/index.d.ts.map +1 -0
  77. package/dist/signer/nostr/index.js +1 -0
  78. package/dist/signer/nostr/signerNostr.d.ts +66 -0
  79. package/dist/signer/nostr/signerNostr.d.ts.map +1 -0
  80. package/dist/signer/nostr/signerNostr.js +85 -0
  81. package/dist/signer/nostr/verify.d.ts +5 -0
  82. package/dist/signer/nostr/verify.d.ts.map +1 -0
  83. package/dist/signer/nostr/verify.js +48 -0
  84. package/dist/signer/signer/index.d.ts +7 -12
  85. package/dist/signer/signer/index.d.ts.map +1 -1
  86. package/dist/signer/signer/index.js +11 -4
  87. package/dist/utils/index.d.ts +59 -0
  88. package/dist/utils/index.d.ts.map +1 -1
  89. package/dist/utils/index.js +17 -0
  90. package/dist.commonjs/address/address.advanced.d.ts +29 -24
  91. package/dist.commonjs/address/address.advanced.d.ts.map +1 -1
  92. package/dist.commonjs/address/address.advanced.js +115 -92
  93. package/dist.commonjs/address/advanced.d.ts +1 -1
  94. package/dist.commonjs/address/advanced.js +30 -14
  95. package/dist.commonjs/address/index.d.ts +51 -44
  96. package/dist.commonjs/address/index.d.ts.map +1 -1
  97. package/dist.commonjs/address/index.js +84 -68
  98. package/dist.commonjs/advanced.d.ts +1 -1
  99. package/dist.commonjs/advanced.js +47 -22
  100. package/dist.commonjs/advancedBarrel.d.ts +1 -1
  101. package/dist.commonjs/advancedBarrel.js +30 -14
  102. package/dist.commonjs/barrel.d.ts +1 -1
  103. package/dist.commonjs/barrel.js +30 -14
  104. package/dist.commonjs/bytes/advanced.d.ts +11 -2
  105. package/dist.commonjs/bytes/index.d.ts +9 -3
  106. package/dist.commonjs/bytes/index.js +28 -26
  107. package/dist.commonjs/ckb/advanced.d.ts +1 -1
  108. package/dist.commonjs/ckb/advanced.js +47 -22
  109. package/dist.commonjs/ckb/index.d.ts +1 -1
  110. package/dist.commonjs/ckb/index.js +30 -14
  111. package/dist.commonjs/ckb/molecule.advanced/generated.d.ts +420 -260
  112. package/dist.commonjs/ckb/molecule.advanced/generated.js +1536 -1332
  113. package/dist.commonjs/ckb/molecule.advanced/index.d.ts +3 -3
  114. package/dist.commonjs/ckb/molecule.advanced/index.js +34 -18
  115. package/dist.commonjs/ckb/script.advanced.d.ts +1 -1
  116. package/dist.commonjs/ckb/script.advanced.js +12 -9
  117. package/dist.commonjs/ckb/script.d.ts +123 -77
  118. package/dist.commonjs/ckb/script.d.ts.map +1 -1
  119. package/dist.commonjs/ckb/script.js +221 -126
  120. package/dist.commonjs/ckb/transaction.advanced.d.ts +1 -1
  121. package/dist.commonjs/ckb/transaction.advanced.js +4 -4
  122. package/dist.commonjs/ckb/transaction.d.ts +796 -533
  123. package/dist.commonjs/ckb/transaction.d.ts.map +1 -1
  124. package/dist.commonjs/ckb/transaction.js +1372 -702
  125. package/dist.commonjs/client/advanced.d.ts +3 -1
  126. package/dist.commonjs/client/advanced.d.ts.map +1 -1
  127. package/dist.commonjs/client/advanced.js +32 -14
  128. package/dist.commonjs/client/client.advanced.d.ts +27 -0
  129. package/dist.commonjs/client/client.advanced.d.ts.map +1 -0
  130. package/dist.commonjs/client/client.advanced.js +116 -0
  131. package/dist.commonjs/client/client.d.ts +118 -21
  132. package/dist.commonjs/client/client.d.ts.map +1 -1
  133. package/dist.commonjs/client/client.js +219 -55
  134. package/dist.commonjs/client/clientPublicMainnet.advanced.d.ts +9 -3
  135. package/dist.commonjs/client/clientPublicMainnet.advanced.d.ts.map +1 -1
  136. package/dist.commonjs/client/clientPublicMainnet.advanced.js +144 -24
  137. package/dist.commonjs/client/clientPublicMainnet.d.ts +9 -5
  138. package/dist.commonjs/client/clientPublicMainnet.d.ts.map +1 -1
  139. package/dist.commonjs/client/clientPublicMainnet.js +18 -8
  140. package/dist.commonjs/client/clientPublicTestnet.advanced.d.ts +8 -3
  141. package/dist.commonjs/client/clientPublicTestnet.advanced.d.ts.map +1 -1
  142. package/dist.commonjs/client/clientPublicTestnet.advanced.js +204 -24
  143. package/dist.commonjs/client/clientPublicTestnet.d.ts +9 -5
  144. package/dist.commonjs/client/clientPublicTestnet.d.ts.map +1 -1
  145. package/dist.commonjs/client/clientPublicTestnet.js +14 -9
  146. package/dist.commonjs/client/clientTypes.advanced.d.ts +23 -0
  147. package/dist.commonjs/client/clientTypes.advanced.d.ts.map +1 -0
  148. package/dist.commonjs/client/clientTypes.advanced.js +8 -0
  149. package/dist.commonjs/client/clientTypes.d.ts +57 -46
  150. package/dist.commonjs/client/clientTypes.d.ts.map +1 -1
  151. package/dist.commonjs/client/clientTypes.js +60 -22
  152. package/dist.commonjs/client/index.d.ts +1 -1
  153. package/dist.commonjs/client/index.js +30 -14
  154. package/dist.commonjs/client/jsonRpc/advanced.d.ts +1 -1
  155. package/dist.commonjs/client/jsonRpc/advanced.js +30 -14
  156. package/dist.commonjs/client/jsonRpc/index.d.ts +94 -75
  157. package/dist.commonjs/client/jsonRpc/index.d.ts.map +1 -1
  158. package/dist.commonjs/client/jsonRpc/index.js +135 -108
  159. package/dist.commonjs/client/jsonRpc/transformers.d.ts +76 -38
  160. package/dist.commonjs/client/jsonRpc/transformers.d.ts.map +1 -1
  161. package/dist.commonjs/client/jsonRpc/transformers.js +174 -150
  162. package/dist.commonjs/client/jsonRpc/types.d.ts +38 -38
  163. package/dist.commonjs/fixedPoint/index.d.ts +9 -3
  164. package/dist.commonjs/fixedPoint/index.js +26 -20
  165. package/dist.commonjs/fixedPoint/index.test.d.ts +1 -1
  166. package/dist.commonjs/fixedPoint/index.test.js +42 -36
  167. package/dist.commonjs/hasher/advanced.d.ts +1 -1
  168. package/dist.commonjs/hasher/index.d.ts +37 -37
  169. package/dist.commonjs/hasher/index.d.ts.map +1 -1
  170. package/dist.commonjs/hasher/index.js +55 -46
  171. package/dist.commonjs/hex/index.d.ts +1 -1
  172. package/dist.commonjs/hex/index.js +1 -1
  173. package/dist.commonjs/index.d.ts +1 -1
  174. package/dist.commonjs/index.js +47 -22
  175. package/dist.commonjs/num/index.d.ts +13 -1
  176. package/dist.commonjs/num/index.d.ts.map +1 -1
  177. package/dist.commonjs/num/index.js +53 -19
  178. package/dist.commonjs/signer/btc/index.d.ts +1 -1
  179. package/dist.commonjs/signer/btc/index.js +30 -14
  180. package/dist.commonjs/signer/btc/signerBtc.d.ts +47 -47
  181. package/dist.commonjs/signer/btc/signerBtc.d.ts.map +1 -1
  182. package/dist.commonjs/signer/btc/signerBtc.js +89 -63
  183. package/dist.commonjs/signer/btc/signerBtcPublicKeyReadonly.d.ts +45 -51
  184. package/dist.commonjs/signer/btc/signerBtcPublicKeyReadonly.d.ts.map +1 -1
  185. package/dist.commonjs/signer/btc/signerBtcPublicKeyReadonly.js +52 -60
  186. package/dist.commonjs/signer/btc/verify.d.ts +6 -2
  187. package/dist.commonjs/signer/btc/verify.d.ts.map +1 -1
  188. package/dist.commonjs/signer/btc/verify.js +13 -3
  189. package/dist.commonjs/signer/ckb/index.d.ts +1 -1
  190. package/dist.commonjs/signer/ckb/index.js +30 -14
  191. package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.d.ts +45 -51
  192. package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.d.ts.map +1 -1
  193. package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.js +56 -64
  194. package/dist.commonjs/signer/ckb/verifyJoyId.d.ts +6 -2
  195. package/dist.commonjs/signer/ckb/verifyJoyId.js +11 -8
  196. package/dist.commonjs/signer/dummy/alwaysError.d.ts +4 -5
  197. package/dist.commonjs/signer/dummy/alwaysError.d.ts.map +1 -1
  198. package/dist.commonjs/signer/dummy/alwaysError.js +7 -10
  199. package/dist.commonjs/signer/dummy/dummy.d.ts +7 -7
  200. package/dist.commonjs/signer/dummy/dummy.js +16 -16
  201. package/dist.commonjs/signer/dummy/index.d.ts +1 -1
  202. package/dist.commonjs/signer/dummy/index.js +30 -14
  203. package/dist.commonjs/signer/dummy/openLink.d.ts +4 -5
  204. package/dist.commonjs/signer/dummy/openLink.d.ts.map +1 -1
  205. package/dist.commonjs/signer/dummy/openLink.js +7 -10
  206. package/dist.commonjs/signer/evm/index.d.ts +1 -1
  207. package/dist.commonjs/signer/evm/index.js +30 -14
  208. package/dist.commonjs/signer/evm/signerEvm.d.ts +42 -38
  209. package/dist.commonjs/signer/evm/signerEvm.d.ts.map +1 -1
  210. package/dist.commonjs/signer/evm/signerEvm.js +106 -69
  211. package/dist.commonjs/signer/evm/signerEvmAddressReadonly.d.ts +37 -43
  212. package/dist.commonjs/signer/evm/signerEvmAddressReadonly.d.ts.map +1 -1
  213. package/dist.commonjs/signer/evm/signerEvmAddressReadonly.js +42 -50
  214. package/dist.commonjs/signer/evm/verify.d.ts +6 -2
  215. package/dist.commonjs/signer/evm/verify.js +7 -2
  216. package/dist.commonjs/signer/index.d.ts +2 -1
  217. package/dist.commonjs/signer/index.d.ts.map +1 -1
  218. package/dist.commonjs/signer/index.js +31 -14
  219. package/dist.commonjs/signer/nostr/index.d.ts +2 -0
  220. package/dist.commonjs/signer/nostr/index.d.ts.map +1 -0
  221. package/dist.commonjs/signer/nostr/index.js +33 -0
  222. package/dist.commonjs/signer/nostr/signerNostr.d.ts +66 -0
  223. package/dist.commonjs/signer/nostr/signerNostr.d.ts.map +1 -0
  224. package/dist.commonjs/signer/nostr/signerNostr.js +118 -0
  225. package/dist.commonjs/signer/nostr/verify.d.ts +11 -0
  226. package/dist.commonjs/signer/nostr/verify.d.ts.map +1 -0
  227. package/dist.commonjs/signer/nostr/verify.js +64 -0
  228. package/dist.commonjs/signer/signer/index.d.ts +156 -155
  229. package/dist.commonjs/signer/signer/index.d.ts.map +1 -1
  230. package/dist.commonjs/signer/signer/index.js +209 -175
  231. package/dist.commonjs/utils/index.d.ts +95 -6
  232. package/dist.commonjs/utils/index.d.ts.map +1 -1
  233. package/dist.commonjs/utils/index.js +30 -6
  234. package/package.json +4 -3
  235. package/src/address/address.advanced.ts +2 -5
  236. package/src/address/index.ts +2 -5
  237. package/src/ckb/script.ts +62 -2
  238. package/src/ckb/transaction.ts +678 -58
  239. package/src/client/advanced.ts +2 -0
  240. package/src/client/client.advanced.ts +134 -0
  241. package/src/client/client.ts +236 -25
  242. package/src/client/clientPublicMainnet.advanced.ts +117 -2
  243. package/src/client/clientPublicMainnet.ts +14 -3
  244. package/src/client/clientPublicTestnet.advanced.ts +176 -2
  245. package/src/client/clientPublicTestnet.ts +9 -3
  246. package/src/client/clientTypes.advanced.ts +26 -0
  247. package/src/client/clientTypes.ts +41 -43
  248. package/src/client/jsonRpc/index.ts +4 -4
  249. package/src/client/jsonRpc/transformers.ts +13 -11
  250. package/src/hasher/index.ts +4 -2
  251. package/src/num/index.ts +22 -0
  252. package/src/signer/btc/signerBtc.ts +6 -8
  253. package/src/signer/btc/signerBtcPublicKeyReadonly.ts +0 -9
  254. package/src/signer/btc/verify.ts +6 -3
  255. package/src/signer/ckb/signerCkbScriptReadonly.ts +0 -9
  256. package/src/signer/dummy/alwaysError.ts +0 -4
  257. package/src/signer/dummy/openLink.ts +0 -4
  258. package/src/signer/evm/signerEvm.ts +11 -11
  259. package/src/signer/evm/signerEvmAddressReadonly.ts +0 -9
  260. package/src/signer/index.ts +1 -0
  261. package/src/signer/nostr/index.ts +1 -0
  262. package/src/signer/nostr/signerNostr.ts +135 -0
  263. package/src/signer/nostr/verify.ts +63 -0
  264. package/src/signer/signer/index.ts +15 -11
  265. package/src/utils/index.ts +108 -0
@@ -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,27 +458,24 @@ 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
- * if (!cellInput.cellOutput) {
388
- * await cellInput.completeExtraInfos();
389
- * }
464
+ * await cellInput.completeExtraInfos();
390
465
  * ```
391
466
  */
392
-
393
- async completeExtraInfos(client: Client): Promise<CellInput> {
394
- if (this.cellOutput && this.outputData && this.blockNumber) {
395
- return this;
467
+ async completeExtraInfos(client: Client): Promise<void> {
468
+ if (this.cellOutput && this.outputData) {
469
+ return;
396
470
  }
397
471
 
398
472
  const cell = await client.getCell(this.previousOutput);
399
- if (cell) {
400
- this.cellOutput = cell.cellOutput;
401
- this.outputData = cell.outputData;
402
- this.blockNumber = cell.blockNumber;
473
+ if (!cell) {
474
+ return;
403
475
  }
404
- return this;
476
+
477
+ this.cellOutput = cell.cellOutput;
478
+ this.outputData = cell.outputData;
405
479
  }
406
480
 
407
481
  /**
@@ -474,6 +548,21 @@ export class CellDep {
474
548
  public depType: DepType,
475
549
  ) {}
476
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
+
477
566
  /**
478
567
  * Creates a CellDep instance from a CellDepLike object.
479
568
  *
@@ -549,6 +638,24 @@ export class CellDep {
549
638
  depTypeFromBytes([view.getDepType()]),
550
639
  );
551
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
+ }
552
659
  }
553
660
 
554
661
  export type WitnessArgsLike = {
@@ -654,14 +761,24 @@ export class WitnessArgs {
654
761
  }
655
762
  }
656
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
+
657
773
  export type TransactionLike = {
658
- version: NumLike;
659
- cellDeps: CellDepLike[];
660
- headerDeps: HexLike[];
661
- inputs: CellInputLike[];
662
- outputs: CellOutputLike[];
663
- outputsData: HexLike[];
664
- 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[];
665
782
  };
666
783
  export class Transaction {
667
784
  /**
@@ -696,11 +813,51 @@ export class Transaction {
696
813
  * const defaultTx = Transaction.default();
697
814
  * ```
698
815
  */
699
-
700
816
  static default(): Transaction {
701
817
  return new Transaction(0n, [], [], [], [], [], []);
702
818
  }
703
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
+
704
861
  /**
705
862
  * Creates a Transaction instance from a TransactionLike object.
706
863
  *
@@ -725,15 +882,37 @@ export class Transaction {
725
882
  if (tx instanceof Transaction) {
726
883
  return tx;
727
884
  }
885
+ const outputs =
886
+ tx.outputs?.map((output, i) => {
887
+ const o = CellOutput.from({
888
+ ...output,
889
+ capacity: output.capacity ?? 0,
890
+ });
891
+ o.capacity = fixedPointFrom(
892
+ o.occupiedSize + (apply(bytesFrom, tx.outputsData?.[i])?.length ?? 0),
893
+ );
894
+ return o;
895
+ }) ?? [];
896
+ const outputsData = outputs.map((_, i) =>
897
+ hexFrom(tx.outputsData?.[i] ?? "0x"),
898
+ );
899
+ if (
900
+ tx.outputsData !== undefined &&
901
+ outputsData.length < tx.outputsData.length
902
+ ) {
903
+ outputsData.push(
904
+ ...tx.outputsData.slice(outputsData.length).map((d) => hexFrom(d)),
905
+ );
906
+ }
728
907
 
729
908
  return new Transaction(
730
- numFrom(tx.version),
731
- tx.cellDeps.map((cellDep) => CellDep.from(cellDep)),
732
- tx.headerDeps.map(hexFrom),
733
- tx.inputs.map((input) => CellInput.from(input)),
734
- tx.outputs.map((output) => CellOutput.from(output)),
735
- tx.outputsData.map(hexFrom),
736
- tx.witnesses.map(hexFrom),
909
+ numFrom(tx.version ?? 0),
910
+ tx.cellDeps?.map((cellDep) => CellDep.from(cellDep)) ?? [],
911
+ tx.headerDeps?.map(hexFrom) ?? [],
912
+ tx.inputs?.map((input) => CellInput.from(input)) ?? [],
913
+ outputs,
914
+ outputsData,
915
+ tx.witnesses?.map(hexFrom) ?? [],
737
916
  );
738
917
  }
739
918
 
@@ -793,7 +972,6 @@ export class Transaction {
793
972
  * const rawTxBytes = transaction.rawToBytes();
794
973
  * ```
795
974
  */
796
-
797
975
  rawToBytes(): Bytes {
798
976
  return bytesFrom(
799
977
  mol.SerializeRawTransaction({
@@ -807,6 +985,32 @@ export class Transaction {
807
985
  );
808
986
  }
809
987
 
988
+ /**
989
+ * Converts the whole transaction data to bytes.
990
+ *
991
+ * @returns A Uint8Array containing the full transaction bytes.
992
+ *
993
+ * @example
994
+ * ```typescript
995
+ * const txBytes = transaction.toBytes();
996
+ * ```
997
+ */
998
+ toBytes(): Bytes {
999
+ return bytesFrom(
1000
+ mol.SerializeTransaction({
1001
+ raw: {
1002
+ version: numToBytes(this.version, 4),
1003
+ cellDeps: this.cellDeps.map((d) => d._toMolData()),
1004
+ headerDeps: this.headerDeps.map((header) => bytesFrom(header)),
1005
+ inputs: this.inputs.map((i) => i._toMolData()),
1006
+ outputs: this.outputs.map((o) => o._toMolData()),
1007
+ outputsData: this.outputsData.map((header) => bytesFrom(header)),
1008
+ },
1009
+ witnesses: this.witnesses.map((witness) => bytesFrom(witness)),
1010
+ }),
1011
+ );
1012
+ }
1013
+
810
1014
  /**
811
1015
  * Calculates the hash of the transaction.
812
1016
  *
@@ -867,11 +1071,11 @@ export class Transaction {
867
1071
  hasher.update(this.hash());
868
1072
 
869
1073
  for (let i = 0; i < this.witnesses.length; i += 1) {
870
- if (this.inputs[i]) {
871
- const input = await this.inputs[i].completeExtraInfos(client);
872
-
1074
+ const input = await this.inputs[i];
1075
+ await input.completeExtraInfos(client);
1076
+ if (input) {
873
1077
  if (!input.cellOutput) {
874
- throw Error("Unable to resolve inputs info");
1078
+ throw new Error("Unable to complete input");
875
1079
  }
876
1080
 
877
1081
  if (!script.eq(input.cellOutput.lock)) {
@@ -919,10 +1123,41 @@ export class Transaction {
919
1123
  const script = Script.from(scriptLike);
920
1124
 
921
1125
  for (let i = 0; i < this.inputs.length; i += 1) {
922
- const input = await this.inputs[i].completeExtraInfos(client);
1126
+ const input = this.inputs[i];
1127
+ await input.completeExtraInfos(client);
1128
+ if (!input.cellOutput) {
1129
+ throw new Error("Unable to complete input");
1130
+ }
1131
+
1132
+ if (script.eq(input.cellOutput.lock)) {
1133
+ return i;
1134
+ }
1135
+ }
1136
+ }
1137
+
1138
+ /**
1139
+ * Find the last occurrence of a input with the specified lock
1140
+ *
1141
+ * @param scriptLike - The script associated with the transaction, represented as a ScriptLike object.
1142
+ * @param client - The client for complete extra infos in the transaction.
1143
+ * @returns A promise that resolves to the prepared transaction
1144
+ *
1145
+ * @example
1146
+ * ```typescript
1147
+ * const index = await tx.findLastInputIndexByLock(scriptLike, client);
1148
+ * ```
1149
+ */
1150
+ async findLastInputIndexByLock(
1151
+ scriptLike: ScriptLike,
1152
+ client: Client,
1153
+ ): Promise<number | undefined> {
1154
+ const script = Script.from(scriptLike);
923
1155
 
1156
+ for (let i = this.inputs.length - 1; i >= 0; i -= 1) {
1157
+ const input = this.inputs[i];
1158
+ await input.completeExtraInfos(client);
924
1159
  if (!input.cellOutput) {
925
- throw Error("Unable to resolve inputs info");
1160
+ throw new Error("Unable to complete input");
926
1161
  }
927
1162
 
928
1163
  if (script.eq(input.cellOutput.lock)) {
@@ -931,6 +1166,125 @@ export class Transaction {
931
1166
  }
932
1167
  }
933
1168
 
1169
+ /**
1170
+ * Add cell deps if they are not existed
1171
+ *
1172
+ * @param cellDepLikes - The cell deps to add
1173
+ *
1174
+ * @example
1175
+ * ```typescript
1176
+ * tx.addCellDeps(cellDep);
1177
+ * ```
1178
+ */
1179
+ addCellDeps(...cellDepsLike: (CellDepLike | CellDepLike[])[]): void {
1180
+ cellDepsLike.flat().forEach((cellDepLike) => {
1181
+ const cellDep = CellDep.from(cellDepLike);
1182
+ if (this.cellDeps.some((c) => c.eq(cellDep))) {
1183
+ return;
1184
+ }
1185
+
1186
+ this.cellDeps.push(cellDep);
1187
+ });
1188
+ }
1189
+
1190
+ /**
1191
+ * Add cell dep from infos if they are not existed
1192
+ *
1193
+ * @param client - A client for searching cell deps
1194
+ * @param cellDepLikes - The cell dep infos to add
1195
+ *
1196
+ * @example
1197
+ * ```typescript
1198
+ * tx.addCellDepInfos(client, cellDepInfos);
1199
+ * ```
1200
+ */
1201
+ async addCellDepInfos(
1202
+ client: Client,
1203
+ ...cellDepInfosLike: (CellDepInfoLike | CellDepInfoLike[])[]
1204
+ ): Promise<void> {
1205
+ this.addCellDeps(await client.getCellDeps(...cellDepInfosLike));
1206
+ }
1207
+
1208
+ /**
1209
+ * Add cell deps from known script
1210
+ *
1211
+ * @param client - The client for searching known script and cell deps
1212
+ * @param scripts - The known scripts to add
1213
+ *
1214
+ * @example
1215
+ * ```typescript
1216
+ * tx.addCellDepsOfKnownScripts(client, KnownScript.OmniLock);
1217
+ * ```
1218
+ */
1219
+ async addCellDepsOfKnownScripts(
1220
+ client: Client,
1221
+ ...scripts: (KnownScript | KnownScript[])[]
1222
+ ): Promise<void> {
1223
+ await Promise.all(
1224
+ scripts
1225
+ .flat()
1226
+ .map(async (script) =>
1227
+ this.addCellDepInfos(
1228
+ client,
1229
+ (await client.getKnownScript(script)).cellDeps,
1230
+ ),
1231
+ ),
1232
+ );
1233
+ }
1234
+
1235
+ /**
1236
+ * Set output data at index.
1237
+ *
1238
+ * @param index - The index of the output data.
1239
+ * @param witness - The data to set.
1240
+ *
1241
+ * @example
1242
+ * ```typescript
1243
+ * await tx.setOutputData(0, "0x00");
1244
+ * ```
1245
+ */
1246
+ setOutputDataAt(index: number, data: HexLike): void {
1247
+ if (this.outputsData.length < index) {
1248
+ this.outputsData.push(
1249
+ ...Array.from(
1250
+ new Array(index - this.outputsData.length),
1251
+ (): Hex => "0x",
1252
+ ),
1253
+ );
1254
+ }
1255
+
1256
+ this.outputsData[index] = hexFrom(data);
1257
+ }
1258
+
1259
+ /**
1260
+ * Add output
1261
+ *
1262
+ * @param output - The cell output to add
1263
+ * @param data - optional output data
1264
+ *
1265
+ * @example
1266
+ * ```typescript
1267
+ * await tx.addOutput(cellOutput, "0xabcd");
1268
+ * ```
1269
+ */
1270
+ addOutput(
1271
+ outputLike: Omit<CellOutputLike, "capacity"> &
1272
+ Partial<Pick<CellOutputLike, "capacity">>,
1273
+ outputData: HexLike = "0x",
1274
+ ): void {
1275
+ const output = CellOutput.from({
1276
+ ...outputLike,
1277
+ capacity: outputLike.capacity ?? 0,
1278
+ });
1279
+ if (output.capacity === Zero) {
1280
+ output.capacity = fixedPointFrom(
1281
+ output.occupiedSize + bytesFrom(outputData).length,
1282
+ );
1283
+ }
1284
+ const i = this.outputs.push(output) - 1;
1285
+ this.setOutputDataAt(i, outputData);
1286
+ }
1287
+
934
1288
  /**
935
1289
  * Get witness at index as WitnessArgs
936
1290
  *
@@ -954,14 +1308,13 @@ export class Transaction {
954
1308
  *
955
1309
  * @param index - The index of the witness.
956
1310
  * @param witness - The WitnessArgs to set.
957
- * @returns The transaction itself.
958
1311
  *
959
1312
  * @example
960
1313
  * ```typescript
961
1314
  * await tx.setWitnessArgsAt(0, witnessArgs);
962
1315
  * ```
963
1316
  */
964
- setWitnessArgsAt(index: number, witness: WitnessArgs): Transaction {
1317
+ setWitnessArgsAt(index: number, witness: WitnessArgs): void {
965
1318
  if (this.witnesses.length < index) {
966
1319
  this.witnesses.push(
967
1320
  ...Array.from(
@@ -972,7 +1325,6 @@ export class Transaction {
972
1325
  }
973
1326
 
974
1327
  this.witnesses[index] = hexFrom(witness.toBytes());
975
- return this;
976
1328
  }
977
1329
 
978
1330
  /**
@@ -992,14 +1344,282 @@ export class Transaction {
992
1344
  scriptLike: ScriptLike,
993
1345
  lockLen: number,
994
1346
  client: Client,
995
- ): Promise<Transaction> {
1347
+ ): Promise<void> {
996
1348
  const position = await this.findInputIndexByLock(scriptLike, client);
997
1349
  if (position === undefined) {
998
- return this;
1350
+ return;
999
1351
  }
1000
1352
 
1001
1353
  const witness = this.getWitnessArgsAt(position) ?? WitnessArgs.from({});
1002
1354
  witness.lock = hexFrom(Array.from(new Array(lockLen), () => 0));
1003
- return this.setWitnessArgsAt(position, witness);
1355
+ this.setWitnessArgsAt(position, witness);
1356
+ }
1357
+
1358
+ async getInputsCapacity(client: Client): Promise<Num> {
1359
+ return reduceAsync(
1360
+ this.inputs,
1361
+ async (acc, input) => {
1362
+ await input.completeExtraInfos(client);
1363
+ if (!input.cellOutput) {
1364
+ throw new Error("Unable to complete input");
1365
+ }
1366
+ return acc + input.cellOutput.capacity;
1367
+ },
1368
+ numFrom(0),
1369
+ );
1370
+ }
1371
+
1372
+ getOutputsCapacity(): Num {
1373
+ return this.outputs.reduce(
1374
+ (acc, { capacity }) => acc + capacity,
1375
+ numFrom(0),
1376
+ );
1377
+ }
1378
+
1379
+ async getInputsUdtBalance(client: Client, type: ScriptLike): Promise<Num> {
1380
+ return reduceAsync(
1381
+ this.inputs,
1382
+ async (acc, input) => {
1383
+ await input.completeExtraInfos(client);
1384
+ if (!input.cellOutput || !input.outputData) {
1385
+ throw new Error("Unable to complete input");
1386
+ }
1387
+ if (!input.cellOutput.type?.eq(type)) {
1388
+ return;
1389
+ }
1390
+
1391
+ return acc + udtBalanceFrom(input.outputData);
1392
+ },
1393
+ numFrom(0),
1394
+ );
1395
+ }
1396
+
1397
+ getOutputsUdtBalance(type: ScriptLike): Num {
1398
+ return this.outputs.reduce((acc, output, i) => {
1399
+ if (!output.type?.eq(type)) {
1400
+ return acc;
1401
+ }
1402
+
1403
+ return acc + udtBalanceFrom(this.outputsData[i]);
1404
+ }, numFrom(0));
1405
+ }
1406
+
1407
+ async completeInputs<T>(
1408
+ from: Signer,
1409
+ filter: ClientCollectableSearchKeyFilterLike,
1410
+ accumulator: (
1411
+ acc: T,
1412
+ v: Cell,
1413
+ i: number,
1414
+ array: Cell[],
1415
+ ) => Promise<T | undefined> | T | undefined,
1416
+ init: T,
1417
+ ): Promise<number> {
1418
+ const scripts = (await from.getAddressObjs()).map(({ script }) => script);
1419
+ const collectedCells = [];
1420
+ let acc: T = init;
1421
+
1422
+ for (const script of scripts) {
1423
+ for await (const cell of from.client.findCellsByCollectableSearchKey({
1424
+ script,
1425
+ scriptType: "lock",
1426
+ filter,
1427
+ scriptSearchMode: "exact",
1428
+ withData: true,
1429
+ })) {
1430
+ if (
1431
+ this.inputs.some(({ previousOutput }) =>
1432
+ previousOutput.eq(cell.outPoint),
1433
+ )
1434
+ ) {
1435
+ continue;
1436
+ }
1437
+ const i = collectedCells.push(cell);
1438
+ const next: T | undefined = await Promise.resolve(
1439
+ accumulator(acc, cell, i - 1, collectedCells),
1440
+ );
1441
+ if (next === undefined) {
1442
+ this.inputs.push(
1443
+ ...collectedCells.map(({ outPoint, outputData, cellOutput }) =>
1444
+ CellInput.from({
1445
+ previousOutput: outPoint,
1446
+ since: 0,
1447
+ outputData,
1448
+ cellOutput,
1449
+ }),
1450
+ ),
1451
+ );
1452
+ return collectedCells.length;
1453
+ }
1454
+ acc = next;
1455
+ }
1456
+ }
1457
+
1458
+ throw new Error("Failed to find enough cells for input");
1459
+ }
1460
+
1461
+ async completeInputsByCapacity(
1462
+ from: Signer,
1463
+ capacityTweak?: NumLike,
1464
+ filter?: ClientCollectableSearchKeyFilterLike,
1465
+ ): Promise<number> {
1466
+ const exceptedCapacity =
1467
+ this.getOutputsCapacity() + numFrom(capacityTweak ?? 0);
1468
+ const inputsCapacity = await this.getInputsCapacity(from.client);
1469
+ if (inputsCapacity >= exceptedCapacity) {
1470
+ return 0;
1471
+ }
1472
+
1473
+ return this.completeInputs(
1474
+ from,
1475
+ filter ?? {
1476
+ scriptLenRange: [0, 1],
1477
+ outputDataLenRange: [0, 1],
1478
+ },
1479
+ (acc, { cellOutput: { capacity } }) => {
1480
+ const sum = acc + capacity;
1481
+ return sum > exceptedCapacity ? undefined : sum;
1482
+ },
1483
+ inputsCapacity,
1484
+ );
1485
+ }
1486
+
1487
+ async completeInputsByUdt(from: Signer, type: ScriptLike): Promise<number> {
1488
+ const exceptedBalance = this.getOutputsUdtBalance(type);
1489
+ const inputsBalance = await this.getInputsUdtBalance(from.client, type);
1490
+ if (inputsBalance >= exceptedBalance) {
1491
+ return 0;
1492
+ }
1493
+
1494
+ return this.completeInputs(
1495
+ from,
1496
+ {
1497
+ script: type,
1498
+ outputDataLenRange: [16, numFrom("0xffffffff")],
1499
+ },
1500
+ (acc, { outputData }) => {
1501
+ const balance = udtBalanceFrom(outputData);
1502
+ const sum = acc + balance;
1503
+ return sum > exceptedBalance ? undefined : sum;
1504
+ },
1505
+ inputsBalance,
1506
+ );
1507
+ }
1508
+
1509
+ estimateFee(feeRate: NumLike): Num {
1510
+ const txSize = this.toBytes().length + 4;
1511
+ return (numFrom(txSize) * numFrom(feeRate) + numFrom(1000)) / numFrom(1000);
1512
+ }
1513
+
1514
+ async completeFee(
1515
+ from: Signer,
1516
+ change: (tx: Transaction, capacity: Num) => Promise<NumLike> | NumLike,
1517
+ feeRate: NumLike,
1518
+ filter?: ClientCollectableSearchKeyFilterLike,
1519
+ ): Promise<[number, boolean]> {
1520
+ // Complete all inputs extra infos for cache
1521
+ await this.getInputsCapacity(from.client);
1522
+
1523
+ let leastFee = this.estimateFee(feeRate);
1524
+ let leastExtraCapacity = Zero;
1525
+
1526
+ while (true) {
1527
+ const prepared = await from.prepareTransaction(this.clone());
1528
+ const collected = await prepared.completeInputsByCapacity(
1529
+ from,
1530
+ leastFee + leastExtraCapacity,
1531
+ filter,
1532
+ );
1533
+
1534
+ const extraCapacity =
1535
+ (await prepared.getInputsCapacity(from.client)) -
1536
+ prepared.getOutputsCapacity();
1537
+ // The extra capacity paid the fee without a change
1538
+ if (extraCapacity === leastFee) {
1539
+ this.copy(prepared);
1540
+ return [collected, false];
1541
+ }
1542
+
1543
+ let changed = prepared.clone();
1544
+ const needed = numFrom(
1545
+ await Promise.resolve(change(changed, extraCapacity - leastFee)),
1546
+ );
1547
+ // No enough extra capacity to create new cells for change
1548
+ if (needed > Zero) {
1549
+ leastExtraCapacity = needed;
1550
+ continue;
1551
+ }
1552
+
1553
+ if (
1554
+ (await changed.getInputsCapacity(from.client)) -
1555
+ changed.getOutputsCapacity() !==
1556
+ leastFee
1557
+ ) {
1558
+ throw new Error(
1559
+ "The change function doesn't use all available capacity",
1560
+ );
1561
+ }
1562
+
1563
+ // New change cells created, update the fee
1564
+ await from.prepareTransaction(changed);
1565
+ const changedFee = changed.estimateFee(feeRate);
1566
+ if (leastFee > changedFee) {
1567
+ throw new Error("The change function removed existed transaction data");
1568
+ }
1569
+ // The fee has been paid
1570
+ if (leastFee === changedFee) {
1571
+ this.copy(changed);
1572
+ return [collected, true];
1573
+ }
1574
+
1575
+ // The fee after changing is more than the original fee
1576
+ leastFee = changedFee;
1577
+ }
1578
+ }
1579
+
1580
+ completeFeeChangeToLock(
1581
+ from: Signer,
1582
+ change: ScriptLike,
1583
+ feeRate: NumLike,
1584
+ filter?: ClientCollectableSearchKeyFilterLike,
1585
+ ): Promise<[number, boolean]> {
1586
+ const script = Script.from(change);
1587
+
1588
+ return this.completeFee(
1589
+ from,
1590
+ (tx, capacity) => {
1591
+ const changeCell = CellOutput.from({ capacity: 0, lock: script });
1592
+ const occupiedCapacity = fixedPointFrom(changeCell.occupiedSize);
1593
+ if (capacity < occupiedCapacity) {
1594
+ return occupiedCapacity;
1595
+ }
1596
+ changeCell.capacity = capacity;
1597
+ tx.addOutput(changeCell);
1598
+ return 0;
1599
+ },
1600
+ feeRate,
1601
+ filter,
1602
+ );
1603
+ }
1604
+
1605
+ completeFeeChangeToOutput(
1606
+ from: Signer,
1607
+ index: NumLike,
1608
+ feeRate: NumLike,
1609
+ filter?: ClientCollectableSearchKeyFilterLike,
1610
+ ): Promise<[number, boolean]> {
1611
+ const change = Number(numFrom(index));
1612
+ if (!this.outputs[change]) {
1613
+ throw new Error("Non-existed output to change");
1614
+ }
1615
+ return this.completeFee(
1616
+ from,
1617
+ (tx, capacity) => {
1618
+ tx.outputs[change].capacity += capacity;
1619
+ return 0;
1620
+ },
1621
+ feeRate,
1622
+ filter,
1623
+ );
1004
1624
  }
1005
1625
  }