@ckb-ccc/core 0.0.9-alpha.1 → 0.0.10-alpha.4

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 (190) hide show
  1. package/dist/ckb/transaction.d.ts +19 -15
  2. package/dist/ckb/transaction.d.ts.map +1 -1
  3. package/dist/ckb/transaction.js +44 -10
  4. package/dist/client/client.d.ts +1 -1
  5. package/dist/client/client.d.ts.map +1 -1
  6. package/dist/client/clientPublicMainnet.advanced.d.ts.map +1 -1
  7. package/dist/client/clientPublicMainnet.advanced.js +30 -2
  8. package/dist/client/clientPublicMainnet.d.ts.map +1 -1
  9. package/dist/client/clientPublicMainnet.js +1 -1
  10. package/dist/client/clientPublicTestnet.advanced.js +3 -3
  11. package/dist/client/clientPublicTestnet.d.ts.map +1 -1
  12. package/dist/client/clientPublicTestnet.js +1 -1
  13. package/dist/client/clientTypes.advanced.d.ts +8 -8
  14. package/dist/client/clientTypes.advanced.d.ts.map +1 -1
  15. package/dist/client/clientTypes.d.ts +2 -2
  16. package/dist/client/clientTypes.d.ts.map +1 -1
  17. package/dist/client/clientTypes.js +2 -2
  18. package/dist/signer/ckb/index.d.ts +3 -0
  19. package/dist/signer/ckb/index.d.ts.map +1 -1
  20. package/dist/signer/ckb/index.js +3 -0
  21. package/dist/signer/ckb/signerCkbPrivateKey.d.ts +12 -0
  22. package/dist/signer/ckb/signerCkbPrivateKey.d.ts.map +1 -0
  23. package/dist/signer/ckb/signerCkbPrivateKey.js +38 -0
  24. package/dist/signer/ckb/signerCkbPublicKey.d.ts +18 -0
  25. package/dist/signer/ckb/signerCkbPublicKey.d.ts.map +1 -0
  26. package/dist/signer/ckb/signerCkbPublicKey.js +44 -0
  27. package/dist/signer/ckb/verifyCkbSecp256k1.d.ts +5 -0
  28. package/dist/signer/ckb/verifyCkbSecp256k1.d.ts.map +1 -0
  29. package/dist/signer/ckb/verifyCkbSecp256k1.js +14 -0
  30. package/dist/signer/evm/signerEvm.d.ts +2 -1
  31. package/dist/signer/evm/signerEvm.d.ts.map +1 -1
  32. package/dist/signer/evm/signerEvmAddressReadonly.d.ts +2 -2
  33. package/dist/signer/evm/signerEvmAddressReadonly.d.ts.map +1 -1
  34. package/dist/signer/signer/index.d.ts +8 -6
  35. package/dist/signer/signer/index.d.ts.map +1 -1
  36. package/dist/signer/signer/index.js +9 -5
  37. package/dist/utils/index.d.ts +18 -9
  38. package/dist/utils/index.d.ts.map +1 -1
  39. package/dist/utils/index.js +2 -2
  40. package/dist.commonjs/address/address.advanced.d.ts +29 -24
  41. package/dist.commonjs/address/address.advanced.js +115 -89
  42. package/dist.commonjs/address/advanced.d.ts +1 -1
  43. package/dist.commonjs/address/advanced.js +30 -14
  44. package/dist.commonjs/address/index.d.ts +51 -44
  45. package/dist.commonjs/address/index.js +84 -65
  46. package/dist.commonjs/advanced.d.ts +1 -1
  47. package/dist.commonjs/advanced.js +47 -22
  48. package/dist.commonjs/advancedBarrel.d.ts +1 -1
  49. package/dist.commonjs/advancedBarrel.js +30 -14
  50. package/dist.commonjs/barrel.d.ts +1 -1
  51. package/dist.commonjs/barrel.js +30 -14
  52. package/dist.commonjs/bytes/advanced.d.ts +11 -2
  53. package/dist.commonjs/bytes/index.d.ts +9 -3
  54. package/dist.commonjs/bytes/index.js +28 -26
  55. package/dist.commonjs/ckb/advanced.d.ts +1 -1
  56. package/dist.commonjs/ckb/advanced.js +47 -22
  57. package/dist.commonjs/ckb/index.d.ts +1 -1
  58. package/dist.commonjs/ckb/index.js +30 -14
  59. package/dist.commonjs/ckb/molecule.advanced/generated.d.ts +420 -260
  60. package/dist.commonjs/ckb/molecule.advanced/generated.js +1536 -1332
  61. package/dist.commonjs/ckb/molecule.advanced/index.d.ts +3 -3
  62. package/dist.commonjs/ckb/molecule.advanced/index.js +34 -18
  63. package/dist.commonjs/ckb/script.advanced.d.ts +1 -1
  64. package/dist.commonjs/ckb/script.advanced.js +12 -9
  65. package/dist.commonjs/ckb/script.d.ts +121 -117
  66. package/dist.commonjs/ckb/script.js +220 -176
  67. package/dist.commonjs/ckb/transaction.advanced.d.ts +1 -1
  68. package/dist.commonjs/ckb/transaction.advanced.js +4 -4
  69. package/dist.commonjs/ckb/transaction.d.ts +806 -718
  70. package/dist.commonjs/ckb/transaction.d.ts.map +1 -1
  71. package/dist.commonjs/ckb/transaction.js +1425 -1158
  72. package/dist.commonjs/client/advanced.d.ts +1 -1
  73. package/dist.commonjs/client/advanced.js +30 -14
  74. package/dist.commonjs/client/client.advanced.d.ts +23 -6
  75. package/dist.commonjs/client/client.advanced.js +89 -61
  76. package/dist.commonjs/client/client.d.ts +114 -54
  77. package/dist.commonjs/client/client.d.ts.map +1 -1
  78. package/dist.commonjs/client/client.js +215 -182
  79. package/dist.commonjs/client/clientPublicMainnet.advanced.d.ts +8 -4
  80. package/dist.commonjs/client/clientPublicMainnet.advanced.d.ts.map +1 -1
  81. package/dist.commonjs/client/clientPublicMainnet.advanced.js +215 -161
  82. package/dist.commonjs/client/clientPublicMainnet.d.ts +8 -6
  83. package/dist.commonjs/client/clientPublicMainnet.d.ts.map +1 -1
  84. package/dist.commonjs/client/clientPublicMainnet.js +17 -15
  85. package/dist.commonjs/client/clientPublicTestnet.advanced.d.ts +6 -3
  86. package/dist.commonjs/client/clientPublicTestnet.advanced.js +227 -199
  87. package/dist.commonjs/client/clientPublicTestnet.d.ts +8 -6
  88. package/dist.commonjs/client/clientPublicTestnet.d.ts.map +1 -1
  89. package/dist.commonjs/client/clientPublicTestnet.js +13 -13
  90. package/dist.commonjs/client/clientTypes.advanced.d.ts +14 -14
  91. package/dist.commonjs/client/clientTypes.advanced.d.ts.map +1 -1
  92. package/dist.commonjs/client/clientTypes.advanced.js +1 -1
  93. package/dist.commonjs/client/clientTypes.d.ts +52 -27
  94. package/dist.commonjs/client/clientTypes.d.ts.map +1 -1
  95. package/dist.commonjs/client/clientTypes.js +56 -22
  96. package/dist.commonjs/client/index.d.ts +1 -1
  97. package/dist.commonjs/client/index.js +30 -14
  98. package/dist.commonjs/client/jsonRpc/advanced.d.ts +1 -1
  99. package/dist.commonjs/client/jsonRpc/advanced.js +30 -14
  100. package/dist.commonjs/client/jsonRpc/index.d.ts +94 -75
  101. package/dist.commonjs/client/jsonRpc/index.js +135 -108
  102. package/dist.commonjs/client/jsonRpc/transformers.d.ts +76 -36
  103. package/dist.commonjs/client/jsonRpc/transformers.js +174 -152
  104. package/dist.commonjs/client/jsonRpc/types.d.ts +38 -38
  105. package/dist.commonjs/fixedPoint/index.d.ts +9 -3
  106. package/dist.commonjs/fixedPoint/index.js +26 -20
  107. package/dist.commonjs/fixedPoint/index.test.d.ts +1 -1
  108. package/dist.commonjs/fixedPoint/index.test.js +42 -36
  109. package/dist.commonjs/hasher/advanced.d.ts +1 -1
  110. package/dist.commonjs/hasher/index.d.ts +40 -37
  111. package/dist.commonjs/hasher/index.js +58 -48
  112. package/dist.commonjs/hex/index.d.ts +1 -1
  113. package/dist.commonjs/hex/index.js +1 -1
  114. package/dist.commonjs/index.d.ts +1 -1
  115. package/dist.commonjs/index.js +47 -22
  116. package/dist.commonjs/num/index.d.ts +1 -1
  117. package/dist.commonjs/num/index.js +39 -27
  118. package/dist.commonjs/signer/btc/index.d.ts +1 -1
  119. package/dist.commonjs/signer/btc/index.js +30 -14
  120. package/dist.commonjs/signer/btc/signerBtc.d.ts +47 -47
  121. package/dist.commonjs/signer/btc/signerBtc.js +89 -66
  122. package/dist.commonjs/signer/btc/signerBtcPublicKeyReadonly.d.ts +45 -45
  123. package/dist.commonjs/signer/btc/signerBtcPublicKeyReadonly.js +52 -52
  124. package/dist.commonjs/signer/btc/verify.d.ts +6 -2
  125. package/dist.commonjs/signer/btc/verify.js +10 -3
  126. package/dist.commonjs/signer/ckb/index.d.ts +4 -1
  127. package/dist.commonjs/signer/ckb/index.d.ts.map +1 -1
  128. package/dist.commonjs/signer/ckb/index.js +33 -14
  129. package/dist.commonjs/signer/ckb/signerCkbPrivateKey.d.ts +12 -0
  130. package/dist.commonjs/signer/ckb/signerCkbPrivateKey.d.ts.map +1 -0
  131. package/dist.commonjs/signer/ckb/signerCkbPrivateKey.js +56 -0
  132. package/dist.commonjs/signer/ckb/signerCkbPublicKey.d.ts +18 -0
  133. package/dist.commonjs/signer/ckb/signerCkbPublicKey.d.ts.map +1 -0
  134. package/dist.commonjs/signer/ckb/signerCkbPublicKey.js +58 -0
  135. package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.d.ts +45 -45
  136. package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.js +56 -56
  137. package/dist.commonjs/signer/ckb/verifyCkbSecp256k1.d.ts +11 -0
  138. package/dist.commonjs/signer/ckb/verifyCkbSecp256k1.d.ts.map +1 -0
  139. package/dist.commonjs/signer/ckb/verifyCkbSecp256k1.js +27 -0
  140. package/dist.commonjs/signer/ckb/verifyJoyId.d.ts +6 -2
  141. package/dist.commonjs/signer/ckb/verifyJoyId.js +11 -8
  142. package/dist.commonjs/signer/dummy/alwaysError.d.ts +4 -4
  143. package/dist.commonjs/signer/dummy/alwaysError.js +7 -7
  144. package/dist.commonjs/signer/dummy/dummy.d.ts +7 -7
  145. package/dist.commonjs/signer/dummy/dummy.js +16 -16
  146. package/dist.commonjs/signer/dummy/index.d.ts +1 -1
  147. package/dist.commonjs/signer/dummy/index.js +30 -14
  148. package/dist.commonjs/signer/dummy/openLink.d.ts +4 -4
  149. package/dist.commonjs/signer/dummy/openLink.js +7 -7
  150. package/dist.commonjs/signer/evm/index.d.ts +1 -1
  151. package/dist.commonjs/signer/evm/index.js +30 -14
  152. package/dist.commonjs/signer/evm/signerEvm.d.ts +43 -38
  153. package/dist.commonjs/signer/evm/signerEvm.d.ts.map +1 -1
  154. package/dist.commonjs/signer/evm/signerEvm.js +105 -70
  155. package/dist.commonjs/signer/evm/signerEvmAddressReadonly.d.ts +38 -38
  156. package/dist.commonjs/signer/evm/signerEvmAddressReadonly.d.ts.map +1 -1
  157. package/dist.commonjs/signer/evm/signerEvmAddressReadonly.js +42 -42
  158. package/dist.commonjs/signer/evm/verify.d.ts +6 -2
  159. package/dist.commonjs/signer/evm/verify.js +7 -2
  160. package/dist.commonjs/signer/index.d.ts +1 -1
  161. package/dist.commonjs/signer/index.js +30 -14
  162. package/dist.commonjs/signer/nostr/index.d.ts +1 -1
  163. package/dist.commonjs/signer/nostr/index.js +30 -14
  164. package/dist.commonjs/signer/nostr/signerNostr.d.ts +57 -57
  165. package/dist.commonjs/signer/nostr/signerNostr.js +100 -71
  166. package/dist.commonjs/signer/nostr/verify.d.ts +9 -3
  167. package/dist.commonjs/signer/nostr/verify.js +50 -39
  168. package/dist.commonjs/signer/signer/index.d.ts +171 -160
  169. package/dist.commonjs/signer/signer/index.d.ts.map +1 -1
  170. package/dist.commonjs/signer/signer/index.js +235 -195
  171. package/dist.commonjs/utils/index.d.ts +56 -14
  172. package/dist.commonjs/utils/index.d.ts.map +1 -1
  173. package/dist.commonjs/utils/index.js +19 -13
  174. package/package.json +2 -2
  175. package/src/ckb/transaction.ts +87 -33
  176. package/src/client/client.ts +1 -1
  177. package/src/client/clientPublicMainnet.advanced.ts +34 -2
  178. package/src/client/clientPublicMainnet.ts +1 -1
  179. package/src/client/clientPublicTestnet.advanced.ts +3 -3
  180. package/src/client/clientPublicTestnet.ts +1 -1
  181. package/src/client/clientTypes.advanced.ts +8 -8
  182. package/src/client/clientTypes.ts +4 -4
  183. package/src/signer/ckb/index.ts +3 -0
  184. package/src/signer/ckb/signerCkbPrivateKey.ts +58 -0
  185. package/src/signer/ckb/signerCkbPublicKey.ts +63 -0
  186. package/src/signer/ckb/verifyCkbSecp256k1.ts +27 -0
  187. package/src/signer/evm/signerEvm.ts +2 -2
  188. package/src/signer/evm/signerEvmAddressReadonly.ts +1 -1
  189. package/src/signer/signer/index.ts +17 -9
  190. package/src/utils/index.ts +24 -12
@@ -2,7 +2,7 @@ import type { TransactionSkeletonType } from "@ckb-lumos/helpers";
2
2
  import { ClientCollectableSearchKeyFilterLike } from "../advancedBarrel";
3
3
  import { Bytes, BytesLike, bytesFrom } from "../bytes";
4
4
  import { CellDepInfoLike, Client, KnownScript } from "../client";
5
- import { Zero, fixedPointFrom } from "../fixedPoint";
5
+ import { Zero, fixedPointFrom, fixedPointToString } from "../fixedPoint";
6
6
  import { Hasher, hashCkb } from "../hasher";
7
7
  import { Hex, HexLike, hexFrom } from "../hex";
8
8
  import {
@@ -210,7 +210,7 @@ export class OutPoint {
210
210
  export type CellOutputLike = {
211
211
  capacity: NumLike;
212
212
  lock: ScriptLike;
213
- type?: ScriptLike;
213
+ type?: ScriptLike | null;
214
214
  };
215
215
  export class CellOutput {
216
216
  /**
@@ -387,9 +387,9 @@ export class Cell {
387
387
 
388
388
  export type CellInputLike = {
389
389
  previousOutput: OutPointLike;
390
- since?: NumLike;
391
- cellOutput?: CellOutputLike;
392
- outputData?: HexLike;
390
+ since?: NumLike | null;
391
+ cellOutput?: CellOutputLike | null;
392
+ outputData?: HexLike | null;
393
393
  };
394
394
  export class CellInput {
395
395
  /**
@@ -659,9 +659,9 @@ export class CellDep {
659
659
  }
660
660
 
661
661
  export type WitnessArgsLike = {
662
- lock?: HexLike;
663
- inputType?: HexLike;
664
- outputType?: HexLike;
662
+ lock?: HexLike | null;
663
+ inputType?: HexLike | null;
664
+ outputType?: HexLike | null;
665
665
  };
666
666
  export class WitnessArgs {
667
667
  /**
@@ -771,14 +771,16 @@ export function udtBalanceFrom(dataLike: BytesLike) {
771
771
  }
772
772
 
773
773
  export type TransactionLike = {
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[];
774
+ version?: NumLike | null;
775
+ cellDeps?: CellDepLike[] | null;
776
+ headerDeps?: HexLike[] | null;
777
+ inputs?: CellInputLike[] | null;
778
+ outputs?:
779
+ | (Omit<CellOutputLike, "capacity"> &
780
+ Partial<Pick<CellOutputLike, "capacity">>)[]
781
+ | null;
782
+ outputsData?: HexLike[] | null;
783
+ witnesses?: HexLike[] | null;
782
784
  };
783
785
  export class Transaction {
784
786
  /**
@@ -899,10 +901,7 @@ export class Transaction {
899
901
  const outputsData = outputs.map((_, i) =>
900
902
  hexFrom(tx.outputsData?.[i] ?? "0x"),
901
903
  );
902
- if (
903
- tx.outputsData !== undefined &&
904
- outputsData.length < tx.outputsData.length
905
- ) {
904
+ if (tx.outputsData != null && outputsData.length < tx.outputsData.length) {
906
905
  outputsData.push(
907
906
  ...tx.outputsData.slice(outputsData.length).map((d) => hexFrom(d)),
908
907
  );
@@ -1418,7 +1417,10 @@ export class Transaction {
1418
1417
  array: Cell[],
1419
1418
  ) => Promise<T | undefined> | T | undefined,
1420
1419
  init: T,
1421
- ): Promise<number> {
1420
+ ): Promise<{
1421
+ addedCount: number;
1422
+ accumulated?: T;
1423
+ }> {
1422
1424
  const scripts = (await from.getAddressObjs()).map(({ script }) => script);
1423
1425
  const collectedCells = [];
1424
1426
  let acc: T = init;
@@ -1453,13 +1455,18 @@ export class Transaction {
1453
1455
  }),
1454
1456
  ),
1455
1457
  );
1456
- return collectedCells.length;
1458
+ return {
1459
+ addedCount: collectedCells.length,
1460
+ };
1457
1461
  }
1458
1462
  acc = next;
1459
1463
  }
1460
1464
  }
1461
1465
 
1462
- throw new Error("Failed to find enough cells for input");
1466
+ return {
1467
+ addedCount: collectedCells.length,
1468
+ accumulated: acc,
1469
+ };
1463
1470
  }
1464
1471
 
1465
1472
  async completeInputsByCapacity(
@@ -1474,7 +1481,7 @@ export class Transaction {
1474
1481
  return 0;
1475
1482
  }
1476
1483
 
1477
- return this.completeInputs(
1484
+ const { addedCount, accumulated } = await this.completeInputs(
1478
1485
  from,
1479
1486
  filter ?? {
1480
1487
  scriptLenRange: [0, 1],
@@ -1482,10 +1489,35 @@ export class Transaction {
1482
1489
  },
1483
1490
  (acc, { cellOutput: { capacity } }) => {
1484
1491
  const sum = acc + capacity;
1485
- return sum > exceptedCapacity ? undefined : sum;
1492
+ return sum >= exceptedCapacity ? undefined : sum;
1486
1493
  },
1487
1494
  inputsCapacity,
1488
1495
  );
1496
+
1497
+ if (accumulated === undefined) {
1498
+ return addedCount;
1499
+ }
1500
+
1501
+ throw new Error(
1502
+ `Insufficient CKB, need ${fixedPointToString(exceptedCapacity - accumulated)} extra CKB`,
1503
+ );
1504
+ }
1505
+
1506
+ async completeInputsAll(
1507
+ from: Signer,
1508
+ filter?: ClientCollectableSearchKeyFilterLike,
1509
+ ): Promise<number> {
1510
+ const { addedCount } = await this.completeInputs(
1511
+ from,
1512
+ filter ?? {
1513
+ scriptLenRange: [0, 1],
1514
+ outputDataLenRange: [0, 1],
1515
+ },
1516
+ (acc, { cellOutput: { capacity } }) => acc + capacity,
1517
+ Zero,
1518
+ );
1519
+
1520
+ return addedCount;
1489
1521
  }
1490
1522
 
1491
1523
  async completeInputsByUdt(from: Signer, type: ScriptLike): Promise<number> {
@@ -1495,7 +1527,7 @@ export class Transaction {
1495
1527
  return 0;
1496
1528
  }
1497
1529
 
1498
- return this.completeInputs(
1530
+ const { addedCount, accumulated } = await this.completeInputs(
1499
1531
  from,
1500
1532
  {
1501
1533
  script: type,
@@ -1504,10 +1536,18 @@ export class Transaction {
1504
1536
  (acc, { outputData }) => {
1505
1537
  const balance = udtBalanceFrom(outputData);
1506
1538
  const sum = acc + balance;
1507
- return sum > exceptedBalance ? undefined : sum;
1539
+ return sum >= exceptedBalance ? undefined : sum;
1508
1540
  },
1509
1541
  inputsBalance,
1510
1542
  );
1543
+
1544
+ if (accumulated === undefined) {
1545
+ return addedCount;
1546
+ }
1547
+
1548
+ throw new Error(
1549
+ `Insufficient coin, need ${exceptedBalance - accumulated} extra coin`,
1550
+ );
1511
1551
  }
1512
1552
 
1513
1553
  estimateFee(feeRate: NumLike): Num {
@@ -1524,17 +1564,31 @@ export class Transaction {
1524
1564
  // Complete all inputs extra infos for cache
1525
1565
  await this.getInputsCapacity(from.client);
1526
1566
 
1527
- let leastFee = this.estimateFee(feeRate);
1567
+ let leastFee = Zero;
1528
1568
  let leastExtraCapacity = Zero;
1529
1569
 
1530
1570
  while (true) {
1531
1571
  const prepared = await from.prepareTransaction(this.clone());
1532
- const collected = await prepared.completeInputsByCapacity(
1533
- from,
1534
- leastFee + leastExtraCapacity,
1535
- filter,
1536
- );
1572
+ const collected = await (async () => {
1573
+ try {
1574
+ return await prepared.completeInputsByCapacity(
1575
+ from,
1576
+ leastFee + leastExtraCapacity,
1577
+ filter,
1578
+ );
1579
+ } catch (err) {
1580
+ if (leastExtraCapacity !== Zero) {
1581
+ throw new Error("Not enough capacity for the change cell");
1582
+ }
1537
1583
 
1584
+ throw err;
1585
+ }
1586
+ })();
1587
+
1588
+ if (leastFee === Zero) {
1589
+ // The initial fee is calculated based on prepared transaction
1590
+ leastFee = prepared.estimateFee(feeRate);
1591
+ }
1538
1592
  const extraCapacity =
1539
1593
  (await prepared.getInputsCapacity(from.client)) -
1540
1594
  prepared.getOutputsCapacity();
@@ -41,7 +41,7 @@ export enum KnownScript {
41
41
 
42
42
  export type CellDepInfoLike = {
43
43
  cellDep: CellDepLike;
44
- type?: ScriptLike;
44
+ type?: ScriptLike | null;
45
45
  };
46
46
 
47
47
  export class CellDepInfo {
@@ -187,6 +187,38 @@ export const MAINNET_SCRIPTS: Record<
187
187
  },
188
188
  ],
189
189
  },
190
- [KnownScript.SingleUseLock]: undefined,
191
- [KnownScript.OutputTypeProxyLock]: undefined,
190
+ [KnownScript.SingleUseLock]: {
191
+ codeHash:
192
+ "0x8290467a512e5b9a6b816469b0edabba1f4ac474e28ffdd604c2a7c76446bbaf",
193
+ hashType: "data1",
194
+ cellDeps: [
195
+ {
196
+ cellDep: {
197
+ outPoint: {
198
+ txHash:
199
+ "0x10d63a996157d32c01078058000052674ca58d15f921bec7f1dcdac2160eb66b",
200
+ index: 4,
201
+ },
202
+ depType: "code",
203
+ },
204
+ },
205
+ ],
206
+ },
207
+ [KnownScript.OutputTypeProxyLock]: {
208
+ codeHash:
209
+ "0x2df53b592db3ae3685b7787adcfef0332a611edb83ca3feca435809964c3aff2",
210
+ hashType: "data1",
211
+ cellDeps: [
212
+ {
213
+ cellDep: {
214
+ outPoint: {
215
+ txHash:
216
+ "0x10d63a996157d32c01078058000052674ca58d15f921bec7f1dcdac2160eb66b",
217
+ index: 2,
218
+ },
219
+ depType: "code",
220
+ },
221
+ },
222
+ ],
223
+ },
192
224
  };
@@ -4,7 +4,7 @@ import { MAINNET_SCRIPTS } from "./clientPublicMainnet.advanced";
4
4
  import { ClientJsonRpc } from "./jsonRpc";
5
5
 
6
6
  export class ClientPublicMainnet extends ClientJsonRpc {
7
- constructor(url = "https://mainnet.ckbapp.dev/", timeout?: number) {
7
+ constructor(url = "https://mainnet.ckb.dev/", timeout?: number) {
8
8
  super(url, timeout);
9
9
  }
10
10
 
@@ -207,7 +207,7 @@ export const TESTNET_SCRIPTS: Record<
207
207
  cellDep: {
208
208
  outPoint: {
209
209
  txHash:
210
- "0x968c326f7a418f07a128f30d9a415251beaa2ec8bd6bbfda65780c94bebb2a85",
210
+ "0xb4f171c9c9caf7401f54a8e56225ae21d95032150a87a4678eac3f66a3137b93",
211
211
  index: 4,
212
212
  },
213
213
  depType: "code",
@@ -217,14 +217,14 @@ export const TESTNET_SCRIPTS: Record<
217
217
  },
218
218
  [KnownScript.OutputTypeProxyLock]: {
219
219
  codeHash:
220
- "0xc0382e4109cff68a4f536441c0266d2e22f2808e61573129c9289ee0e5e5ed43",
220
+ "0x2df53b592db3ae3685b7787adcfef0332a611edb83ca3feca435809964c3aff2",
221
221
  hashType: "data1",
222
222
  cellDeps: [
223
223
  {
224
224
  cellDep: {
225
225
  outPoint: {
226
226
  txHash:
227
- "0x968c326f7a418f07a128f30d9a415251beaa2ec8bd6bbfda65780c94bebb2a85",
227
+ "0xb4f171c9c9caf7401f54a8e56225ae21d95032150a87a4678eac3f66a3137b93",
228
228
  index: 2,
229
229
  },
230
230
  depType: "code",
@@ -4,7 +4,7 @@ import { TESTNET_SCRIPTS } from "./clientPublicTestnet.advanced";
4
4
  import { ClientJsonRpc } from "./jsonRpc";
5
5
 
6
6
  export class ClientPublicTestnet extends ClientJsonRpc {
7
- constructor(url = "https://testnet.ckbapp.dev/", timeout?: number) {
7
+ constructor(url = "https://testnet.ckb.dev/", timeout?: number) {
8
8
  super(url, timeout);
9
9
  }
10
10
 
@@ -10,17 +10,17 @@ export function clientSearchKeyRangeFrom([a, b]: [NumLike, NumLike]): [
10
10
  }
11
11
 
12
12
  export type ClientCollectableSearchKeyFilterLike = {
13
- script?: ScriptLike;
14
- scriptLenRange?: [NumLike, NumLike];
15
- outputData?: HexLike;
16
- outputDataSearchMode?: "prefix" | "exact" | "partial";
17
- outputDataLenRange?: [NumLike, NumLike];
18
- outputCapacityRange?: [NumLike, NumLike];
13
+ script?: ScriptLike | null;
14
+ scriptLenRange?: [NumLike, NumLike] | null;
15
+ outputData?: HexLike | null;
16
+ outputDataSearchMode?: "prefix" | "exact" | "partial" | null;
17
+ outputDataLenRange?: [NumLike, NumLike] | null;
18
+ outputCapacityRange?: [NumLike, NumLike] | null;
19
19
  };
20
20
  export type ClientCollectableSearchKeyLike = {
21
21
  script: ScriptLike;
22
22
  scriptType: "lock" | "type";
23
23
  scriptSearchMode: "prefix" | "exact" | "partial";
24
- filter?: ClientCollectableSearchKeyFilterLike;
25
- withData?: boolean;
24
+ filter?: ClientCollectableSearchKeyFilterLike | null;
25
+ withData?: boolean | null;
26
26
  };
@@ -23,7 +23,7 @@ export type ClientTransactionResponse = {
23
23
 
24
24
  export type ClientIndexerSearchKeyFilterLike =
25
25
  ClientCollectableSearchKeyFilterLike & {
26
- blockRange?: [NumLike, NumLike];
26
+ blockRange?: [NumLike, NumLike] | null;
27
27
  };
28
28
  export class ClientIndexerSearchKeyFilter {
29
29
  constructor(
@@ -43,7 +43,7 @@ export class ClientIndexerSearchKeyFilter {
43
43
  apply(Script.from, filterLike.script),
44
44
  apply(clientSearchKeyRangeFrom, filterLike.scriptLenRange),
45
45
  apply(hexFrom, filterLike.outputData),
46
- filterLike.outputDataSearchMode,
46
+ filterLike.outputDataSearchMode ?? undefined,
47
47
  apply(clientSearchKeyRangeFrom, filterLike.outputDataLenRange),
48
48
  apply(clientSearchKeyRangeFrom, filterLike.outputCapacityRange),
49
49
  apply(clientSearchKeyRangeFrom, filterLike.blockRange),
@@ -52,7 +52,7 @@ export class ClientIndexerSearchKeyFilter {
52
52
  }
53
53
 
54
54
  export type ClientIndexerSearchKeyLike = ClientCollectableSearchKeyLike & {
55
- filter?: ClientIndexerSearchKeyFilterLike;
55
+ filter?: ClientIndexerSearchKeyFilterLike | null;
56
56
  };
57
57
 
58
58
  export class ClientIndexerSearchKey {
@@ -70,7 +70,7 @@ export class ClientIndexerSearchKey {
70
70
  keyLike.scriptType,
71
71
  keyLike.scriptSearchMode,
72
72
  apply(ClientIndexerSearchKeyFilter.from, keyLike.filter),
73
- keyLike.withData,
73
+ keyLike.withData ?? undefined,
74
74
  );
75
75
  }
76
76
  }
@@ -1,2 +1,5 @@
1
+ export * from "./signerCkbPrivateKey";
2
+ export * from "./signerCkbPublicKey";
1
3
  export * from "./signerCkbScriptReadonly";
4
+ export * from "./verifyCkbSecp256k1";
2
5
  export * from "./verifyJoyId";
@@ -0,0 +1,58 @@
1
+ import { secp256k1 } from "@noble/curves/secp256k1";
2
+ import { bytesConcat, bytesFrom, BytesLike } from "../../bytes";
3
+ import { Transaction, TransactionLike, WitnessArgs } from "../../ckb";
4
+ import { Client } from "../../client";
5
+ import { hashCkb } from "../../hasher";
6
+ import { Hex, hexFrom, HexLike } from "../../hex";
7
+ import { numBeToBytes } from "../../num";
8
+ import { SignerCkbPublicKey } from "./signerCkbPublicKey";
9
+
10
+ export class SignerCkbPrivateKey extends SignerCkbPublicKey {
11
+ public readonly privateKey: Hex;
12
+
13
+ constructor(client: Client, privateKey: HexLike) {
14
+ const pk = hexFrom(privateKey);
15
+ if (bytesFrom(pk).length !== 32) {
16
+ throw new Error("Private key must be 32 bytes!");
17
+ }
18
+
19
+ super(client, secp256k1.getPublicKey(bytesFrom(pk), true));
20
+ this.privateKey = pk;
21
+ }
22
+
23
+ async signMessageRaw(message: string | BytesLike): Promise<Hex> {
24
+ const msg = typeof message === "string" ? message : hexFrom(message);
25
+ const buffer = bytesFrom(`Nervos Message:${msg}`, "utf8");
26
+ const hash = hashCkb(buffer);
27
+
28
+ const signature = secp256k1.sign(
29
+ bytesFrom(hash),
30
+ bytesFrom(this.privateKey),
31
+ );
32
+ const { r, s, recovery } = signature;
33
+
34
+ return hexFrom(
35
+ bytesConcat(
36
+ numBeToBytes(r, 32),
37
+ numBeToBytes(s, 32),
38
+ numBeToBytes(recovery, 1),
39
+ ),
40
+ );
41
+ }
42
+
43
+ async signOnlyTransaction(txLike: TransactionLike): Promise<Transaction> {
44
+ const tx = Transaction.from(txLike);
45
+ const { script } = await this.getRecommendedAddressObj();
46
+ const info = await tx.getSignHashInfo(script, this.client);
47
+ if (!info) {
48
+ return tx;
49
+ }
50
+
51
+ const signature = await this.signMessageRaw(info.message);
52
+
53
+ const witness = tx.getWitnessArgsAt(info.position) ?? WitnessArgs.from({});
54
+ witness.lock = signature;
55
+ tx.setWitnessArgsAt(info.position, witness);
56
+ return tx;
57
+ }
58
+ }
@@ -0,0 +1,63 @@
1
+ import { Address } from "../../address";
2
+ import { bytesFrom } from "../../bytes";
3
+ import { Transaction, TransactionLike } from "../../ckb";
4
+ import { Client, KnownScript } from "../../client";
5
+ import { hashCkb } from "../../hasher";
6
+ import { Hex, HexLike, hexFrom } from "../../hex";
7
+ import { Signer, SignerSignType, SignerType } from "../signer";
8
+
9
+ export class SignerCkbPublicKey extends Signer {
10
+ get type(): SignerType {
11
+ return SignerType.CKB;
12
+ }
13
+
14
+ get signType(): SignerSignType {
15
+ return SignerSignType.CkbSecp256k1;
16
+ }
17
+
18
+ public readonly publicKey: Hex;
19
+
20
+ constructor(client: Client, publicKey: HexLike) {
21
+ super(client);
22
+ this.publicKey = hexFrom(publicKey);
23
+
24
+ if (bytesFrom(this.publicKey).length !== 33) {
25
+ throw new Error("Public key must be 33 bytes!");
26
+ }
27
+ }
28
+
29
+ async connect(): Promise<void> {}
30
+
31
+ async isConnected(): Promise<boolean> {
32
+ return true;
33
+ }
34
+
35
+ async getInternalAddress(): Promise<string> {
36
+ return this.getRecommendedAddress();
37
+ }
38
+
39
+ async getIdentity(): Promise<string> {
40
+ return this.publicKey;
41
+ }
42
+
43
+ async getAddressObjs(): Promise<Address[]> {
44
+ return [
45
+ await Address.fromKnownScript(
46
+ this.client,
47
+ KnownScript.Secp256k1Blake160,
48
+ bytesFrom(hashCkb(this.publicKey)).slice(0, 20),
49
+ ),
50
+ ];
51
+ }
52
+
53
+ async prepareTransaction(txLike: TransactionLike): Promise<Transaction> {
54
+ const tx = Transaction.from(txLike);
55
+ const { script } = await this.getRecommendedAddressObj();
56
+ await tx.addCellDepsOfKnownScripts(
57
+ this.client,
58
+ KnownScript.Secp256k1Blake160,
59
+ );
60
+ await tx.prepareSighashAllWitness(script, 65, this.client);
61
+ return tx;
62
+ }
63
+ }
@@ -0,0 +1,27 @@
1
+ import { secp256k1 } from "@noble/curves/secp256k1";
2
+ import { BytesLike, bytesFrom } from "../../bytes";
3
+ import { hashCkb } from "../../hasher";
4
+ import { Hex, hexFrom } from "../../hex";
5
+ import { numFrom } from "../../num";
6
+
7
+ export function messageHashCkbSecp256k1(message: string | BytesLike): Hex {
8
+ const msg = typeof message === "string" ? message : hexFrom(message);
9
+ const buffer = bytesFrom(`Nervos Message:${msg}`, "utf8");
10
+ return hashCkb(buffer);
11
+ }
12
+
13
+ export function verifyMessageCkbSecp256k1(
14
+ message: string | BytesLike,
15
+ signature: string,
16
+ publicKey: string,
17
+ ): boolean {
18
+ const signatureBytes = bytesFrom(signature);
19
+ return secp256k1.verify(
20
+ new secp256k1.Signature(
21
+ numFrom(signatureBytes.slice(0, 32)),
22
+ numFrom(signatureBytes.slice(32, 64)),
23
+ ).addRecoveryBit(Number(numFrom(signatureBytes.slice(64, 65)))),
24
+ bytesFrom(messageHashCkbSecp256k1(message)),
25
+ bytesFrom(publicKey),
26
+ );
27
+ }
@@ -2,7 +2,7 @@ import { Address } from "../../address";
2
2
  import { BytesLike, bytesConcat, bytesFrom } from "../../bytes";
3
3
  import { Script, Transaction, TransactionLike, WitnessArgs } from "../../ckb";
4
4
  import { KnownScript } from "../../client";
5
- import { hexFrom } from "../../hex";
5
+ import { Hex, hexFrom } from "../../hex";
6
6
  import { numToBytes } from "../../num";
7
7
  import { reduceAsync } from "../../utils";
8
8
  import { Signer, SignerSignType, SignerType } from "../signer";
@@ -25,7 +25,7 @@ export abstract class SignerEvm extends Signer {
25
25
  *
26
26
  * @returns A promise that resolves to a string representing the EVM account.
27
27
  */
28
- abstract getEvmAccount(): Promise<string>;
28
+ abstract getEvmAccount(): Promise<Hex>;
29
29
 
30
30
  /**
31
31
  * Gets the internal address, which is the EVM account in this case.
@@ -53,7 +53,7 @@ export class SignerEvmAddressReadonly extends SignerEvm {
53
53
  * const account = await signer.getEvmAccount(); // Outputs the EVM account
54
54
  * ```
55
55
  */
56
- async getEvmAccount(): Promise<string> {
56
+ async getEvmAccount(): Promise<Hex> {
57
57
  return this.address;
58
58
  }
59
59
  }
@@ -5,6 +5,7 @@ import { Client } from "../../client";
5
5
  import { Hex } from "../../hex";
6
6
  import { Num } from "../../num";
7
7
  import { verifyMessageBtcEcdsa } from "../btc";
8
+ import { verifyMessageCkbSecp256k1 } from "../ckb/verifyCkbSecp256k1";
8
9
  import { verifyMessageJoyId } from "../ckb/verifyJoyId";
9
10
  import { verifyMessageEvmPersonal } from "../evm/verify";
10
11
  import { verifyMessageNostrEvent } from "../nostr/verify";
@@ -15,6 +16,7 @@ export enum SignerSignType {
15
16
  EvmPersonal = "EvmPersonal",
16
17
  JoyId = "JoyId",
17
18
  NostrEvent = "NostrEvent",
19
+ CkbSecp256k1 = "CkbSecp256k1",
18
20
  }
19
21
 
20
22
  /**
@@ -116,20 +118,17 @@ export abstract class Signer {
116
118
  signature.signature,
117
119
  signature.identity,
118
120
  );
121
+ case SignerSignType.CkbSecp256k1:
122
+ return verifyMessageCkbSecp256k1(
123
+ message,
124
+ signature.signature,
125
+ signature.identity,
126
+ );
119
127
  case SignerSignType.Unknown:
120
128
  throw new Error("Unknown signer sign type");
121
129
  }
122
130
  }
123
131
 
124
- /**
125
- * Replace the current client.
126
- * returns false if the new client is invalid for this signer.
127
- */
128
- async replaceClient(client: Client): Promise<boolean> {
129
- this.client_ = client;
130
- return true;
131
- }
132
-
133
132
  /**
134
133
  * Connects to the signer.
135
134
  *
@@ -137,6 +136,15 @@ export abstract class Signer {
137
136
  */
138
137
  abstract connect(): Promise<void>;
139
138
 
139
+ /**
140
+ * Register a listener to be called when this signer is replaced.
141
+ *
142
+ * @returns A function for unregister
143
+ */
144
+ onReplaced(_: () => void): () => void {
145
+ return () => {};
146
+ }
147
+
140
148
  /**
141
149
  * Disconnects to the signer.
142
150
  *