@ickb/sdk 1000.0.81 → 9000.0.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 (157) hide show
  1. package/README.md +81 -32
  2. package/dist/constants.d.ts +13 -22
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/constants.js +80 -76
  5. package/dist/constants.js.map +1 -1
  6. package/dist/conversion/estimate.d.ts +39 -0
  7. package/dist/conversion/estimate.d.ts.map +1 -0
  8. package/dist/conversion/estimate.js +117 -0
  9. package/dist/conversion/estimate.js.map +1 -0
  10. package/dist/conversion/maturity.d.ts +15 -0
  11. package/dist/conversion/maturity.d.ts.map +1 -0
  12. package/dist/conversion/maturity.js +112 -0
  13. package/dist/conversion/maturity.js.map +1 -0
  14. package/dist/conversion/plans.d.ts +20 -0
  15. package/dist/conversion/plans.d.ts.map +1 -0
  16. package/dist/conversion/plans.js +106 -0
  17. package/dist/conversion/plans.js.map +1 -0
  18. package/dist/conversion/projection.d.ts +22 -0
  19. package/dist/conversion/projection.d.ts.map +1 -0
  20. package/dist/conversion/projection.js +91 -0
  21. package/dist/conversion/projection.js.map +1 -0
  22. package/dist/conversion/types.d.ts +252 -0
  23. package/dist/conversion/types.d.ts.map +1 -0
  24. package/dist/conversion/types.js +2 -0
  25. package/dist/conversion/types.js.map +1 -0
  26. package/dist/conversion/withdrawal_ring.d.ts +36 -0
  27. package/dist/conversion/withdrawal_ring.d.ts.map +1 -0
  28. package/dist/conversion/withdrawal_ring.js +87 -0
  29. package/dist/conversion/withdrawal_ring.js.map +1 -0
  30. package/dist/dao.d.ts +86 -0
  31. package/dist/dao.d.ts.map +1 -0
  32. package/dist/dao.js +113 -0
  33. package/dist/dao.js.map +1 -0
  34. package/dist/index.d.ts +51 -3
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +20 -3
  37. package/dist/index.js.map +1 -1
  38. package/dist/logic.d.ts +85 -0
  39. package/dist/logic.d.ts.map +1 -0
  40. package/dist/logic.js +184 -0
  41. package/dist/logic.js.map +1 -0
  42. package/dist/order/cells.d.ts +207 -0
  43. package/dist/order/cells.d.ts.map +1 -0
  44. package/dist/order/cells.js +427 -0
  45. package/dist/order/cells.js.map +1 -0
  46. package/dist/order/conversion.d.ts +43 -0
  47. package/dist/order/conversion.d.ts.map +1 -0
  48. package/dist/order/conversion.js +123 -0
  49. package/dist/order/conversion.js.map +1 -0
  50. package/dist/order/fee.d.ts +9 -0
  51. package/dist/order/fee.d.ts.map +1 -0
  52. package/dist/order/fee.js +24 -0
  53. package/dist/order/fee.js.map +1 -0
  54. package/dist/order/fill.d.ts +36 -0
  55. package/dist/order/fill.d.ts.map +1 -0
  56. package/dist/order/fill.js +53 -0
  57. package/dist/order/fill.js.map +1 -0
  58. package/dist/order/info.d.ts +62 -0
  59. package/dist/order/info.d.ts.map +1 -0
  60. package/dist/order/info.js +99 -0
  61. package/dist/order/info.js.map +1 -0
  62. package/dist/order/master.d.ts +49 -0
  63. package/dist/order/master.d.ts.map +1 -0
  64. package/dist/order/master.js +27 -0
  65. package/dist/order/master.js.map +1 -0
  66. package/dist/order/matcher.d.ts +43 -0
  67. package/dist/order/matcher.d.ts.map +1 -0
  68. package/dist/order/matcher.js +123 -0
  69. package/dist/order/matcher.js.map +1 -0
  70. package/dist/order/order.d.ts +59 -0
  71. package/dist/order/order.d.ts.map +1 -0
  72. package/dist/order/order.js +239 -0
  73. package/dist/order/order.js.map +1 -0
  74. package/dist/order/order_data.d.ts +51 -0
  75. package/dist/order/order_data.d.ts.map +1 -0
  76. package/dist/order/order_data.js +64 -0
  77. package/dist/order/order_data.js.map +1 -0
  78. package/dist/order/ratio.d.ts +42 -0
  79. package/dist/order/ratio.d.ts.map +1 -0
  80. package/dist/order/ratio.js +82 -0
  81. package/dist/order/ratio.js.map +1 -0
  82. package/dist/order/relative.d.ts +43 -0
  83. package/dist/order/relative.d.ts.map +1 -0
  84. package/dist/order/relative.js +54 -0
  85. package/dist/order/relative.js.map +1 -0
  86. package/dist/owned_owner.d.ts +113 -0
  87. package/dist/owned_owner.d.ts.map +1 -0
  88. package/dist/owned_owner.js +280 -0
  89. package/dist/owned_owner.js.map +1 -0
  90. package/dist/sdk.d.ts +71 -42
  91. package/dist/sdk.d.ts.map +1 -1
  92. package/dist/sdk.js +388 -209
  93. package/dist/sdk.js.map +1 -1
  94. package/dist/send/sign_and_send_transaction.d.ts +46 -0
  95. package/dist/send/sign_and_send_transaction.d.ts.map +1 -0
  96. package/dist/send/sign_and_send_transaction.js +101 -0
  97. package/dist/send/sign_and_send_transaction.js.map +1 -0
  98. package/dist/send/wait_transaction.d.ts +41 -0
  99. package/dist/send/wait_transaction.d.ts.map +1 -0
  100. package/dist/send/wait_transaction.js +204 -0
  101. package/dist/send/wait_transaction.js.map +1 -0
  102. package/dist/udt.d.ts +123 -0
  103. package/dist/udt.d.ts.map +1 -0
  104. package/dist/udt.js +244 -0
  105. package/dist/udt.js.map +1 -0
  106. package/dist/utils/chain.d.ts +38 -0
  107. package/dist/utils/chain.d.ts.map +1 -0
  108. package/dist/utils/chain.js +20 -0
  109. package/dist/utils/chain.js.map +1 -0
  110. package/dist/utils/codec.d.ts +19 -0
  111. package/dist/utils/codec.d.ts.map +1 -0
  112. package/dist/utils/codec.js +66 -0
  113. package/dist/utils/codec.js.map +1 -0
  114. package/dist/utils/transaction_header.d.ts +17 -0
  115. package/dist/utils/transaction_header.d.ts.map +1 -0
  116. package/dist/utils/transaction_header.js +44 -0
  117. package/dist/utils/transaction_header.js.map +1 -0
  118. package/dist/utils/utils.d.ts +126 -0
  119. package/dist/utils/utils.d.ts.map +1 -0
  120. package/dist/utils/utils.js +151 -0
  121. package/dist/utils/utils.js.map +1 -0
  122. package/package.json +19 -26
  123. package/src/constants.ts +84 -181
  124. package/src/conversion/estimate.ts +157 -0
  125. package/src/conversion/maturity.ts +159 -0
  126. package/src/conversion/plans.ts +144 -0
  127. package/src/conversion/projection.ts +128 -0
  128. package/src/conversion/types.ts +287 -0
  129. package/src/conversion/withdrawal_ring.ts +126 -0
  130. package/src/dao.ts +172 -0
  131. package/src/index.ts +89 -3
  132. package/src/logic.ts +295 -0
  133. package/src/order/cells.ts +520 -0
  134. package/src/order/conversion.ts +173 -0
  135. package/src/order/fee.ts +30 -0
  136. package/src/order/fill.ts +83 -0
  137. package/src/order/info.ts +178 -0
  138. package/src/order/master.ts +42 -0
  139. package/src/order/matcher.ts +191 -0
  140. package/src/order/order.ts +302 -0
  141. package/src/order/order_data.ts +128 -0
  142. package/src/order/ratio.ts +144 -0
  143. package/src/order/relative.ts +106 -0
  144. package/src/owned_owner.ts +394 -0
  145. package/src/sdk.ts +555 -440
  146. package/src/send/sign_and_send_transaction.ts +120 -0
  147. package/src/send/wait_transaction.ts +271 -0
  148. package/src/udt.ts +317 -0
  149. package/src/utils/chain.ts +43 -0
  150. package/src/utils/codec.ts +74 -0
  151. package/src/utils/transaction_header.ts +66 -0
  152. package/src/utils/utils.ts +237 -0
  153. package/dist/codec.d.ts +0 -3
  154. package/dist/codec.d.ts.map +0 -1
  155. package/dist/codec.js +0 -58
  156. package/dist/codec.js.map +0 -1
  157. package/src/codec.ts +0 -138
package/README.md CHANGED
@@ -1,35 +1,84 @@
1
- # iCKB/SDK
2
-
3
- iCKB SDK built on top of CCC
4
-
5
- ## Dependencies
6
-
7
- ```mermaid
8
- graph TD;
9
- A["@ickb/utils"] --> B["@ckb-ccc/core"];
10
- C["@ickb/dao"] --> A;
11
- C --> B;
12
- D["@ickb/core"] --> A;
13
- D --> C;
14
- E["@ickb/order"] --> A;
15
- E --> B;
16
- F["@ickb/sdk"] --> A;
17
- F --> C;
18
- F --> D;
19
- F --> E;
20
-
21
- click A "https://github.com/ickb/utils" "Go to @ickb/utils"
22
- click B "https://github.com/ckb-devrel/ccc/tree/master/packages/core" "Go to @ckb-ccc/core"
23
- click C "https://github.com/ickb/dao" "Go to @ickb/dao"
24
- click D "https://github.com/ickb/core" "Go to @ickb/core"
25
- click E "https://github.com/ickb/order" "Go to @ickb/order"
26
- click F "https://github.com/ickb/sdk" "Go to @ickb/sdk"
27
- ```
28
-
29
- ## Epoch Semantic Versioning
30
-
31
- This repository follows [Epoch Semantic Versioning](https://antfu.me/posts/epoch-semver). In short ESV aims to provide a more nuanced and effective way to communicate software changes, allowing for better user understanding and smoother upgrades.
1
+ # iCKB SDK
2
+
3
+ `@ickb/sdk` builds iCKB conversions on CCC. Construct it with `IckbSdk.fromChain(chain)`, read account state, build a funded transaction, then sign, send and wait. The public surface follows that workflow and includes the types its signatures need; managers and raw deployment configuration are internal.
4
+
5
+ ## Layout
6
+
7
+ The top-level script modules are `src/udt.ts` (iCKB), `src/logic.ts` (deposits and receipts), `src/owned_owner.ts` (requests and withdrawals) and `src/dao.ts` (shared Nervos DAO rules). The other concerns are:
8
+
9
+ - `src/order/`: UDT limit orders and matching.
10
+ - `src/conversion/`: state projection, estimates, plans, the withdrawal ring and completion.
11
+ - `src/send/`: signing, broadcast and confirmation.
12
+ - `src/utils/`: shared readers and codecs.
13
+
14
+ `src/index.ts` is the only barrel. The package has one runtime dependency, `@ckb-ccc/core`, and no Node built-ins. A separate DAO manager layer had one caller per operation and no raw-DAO consumer, so those operations now live with the iCKB script that uses them. Internal barrels and alternate public entry points would recreate boundaries without another consumer.
15
+
16
+ ## Account state
17
+
18
+ `getL1AccountState(client, locks, lockUp)` reads the account, pool and order book. The caller supplies a `LockUpPolicy`, carried on `system.lockUp`; deposits carry a sampled `claimEpoch`, and readers apply the caller's policy to decide readiness. [`src/dao.ts`](src/dao.ts) defines the wallet and bot presets. A human can leave a wallet popup open, so the wallet's selection and broadcast margins are wider than the bot's.
19
+
20
+ Each account lock is scanned once, unfiltered, then classified by cell kind. The book is also read once: the market sees orders past par, while the account sees its own orders. An older order from the same wallet legitimately queues ahead of its new one. Dual-ratio orders are valid on chain but excluded by the scan because Stack neither places nor handles them; they are not matched, estimated, displayed or collected here.
21
+
22
+ Every cell scan uses the uncached [`findCells`](src/utils/utils.ts) loop with pages of 400, ending on the first short page. There is no aggregate scan budget or page-size option: a large account or book costs a slower read rather than a partial result. A full page whose cursor does not advance throws. The cursor is only a continuation key, not a snapshot; one traversal can return a cell and its successor. Planning must tolerate that rather than assume page coherence.
23
+
24
+ Transaction and header reads are batched before pure decoding. This replaced promise caches and batch-specific reader wrappers; each deposit carries its value instead of being valued again downstream. CCC's speculative broadcast cache is not authority for committed cells. An origin transaction cached without a block number is refreshed, as the comment at the order reader explains.
25
+
26
+ ## Transaction completion
27
+
28
+ `buildConversionTransaction(...)` returns a completed transaction funded from the cells in its state read. It never discovers more inputs while trying candidates. The [root user-lock assumption](../README.md#user-locks) applies to both the wallet's lock and a caller-supplied destination.
29
+
30
+ The SDK tries the most direct plan first and returns the first that completes. Completion is the only authority on affordability: markers, remainder orders, change and fees all affect the answer. Removing one withdrawal can introduce a remainder order costing more capacity than the removed marker, so binary search or a policy-side count bound would be wrong. Typed fundability failures advance the walk; transport, scan, signer and malformed-transaction failures propagate. When every candidate fails, the last fundability failure is thrown.
31
+
32
+ The ready-deposit selection excludes [ring anchors](node/docs/policy.md#rebalancing-and-the-maturity-ring) to preserve the pool's spread of maturities. If every ready deposit is an anchor, only an order plan remains.
33
+
34
+ Direct-first deliberately favors a known claim date and avoiding an order fee over a faster estimated bot fill. A user may therefore receive a direct withdrawal days away even when an order could be filled in minutes. The estimate describes the chosen plan; it does not rank candidates. The greedy maturity-ordered selection also accepts a larger remainder order where an exact best-fit search could withdraw more directly. Capped deposits and the bot's regular deposit sizes reduce that cost without another combinatorial selector.
35
+
36
+ ### Funding and compaction
37
+
38
+ Inputs needed by the outputs go in first, largest first. The completer then sweeps remaining liquid cells until the transaction has 1,000 inputs, about 50 KB. That is a compaction target, not a size bound: funding the outputs can exceed it outright, and fee completion can use cells left after the sweep. An integrator should expect a transaction to spend more of the account than the requested amount alone requires: compaction is deliberate.
39
+
40
+ The sweep limit does not bound the whole transaction. Receipts and collectable orders are added in full, while required funding can exceed that limit. Large collection backlogs can therefore produce an oversized transaction; rebuilding from the same state may repeat the failure. Whole-transaction sizing remains an open design issue.
41
+
42
+ Plain-cell discovery does not filter mining rewards by cellbase maturity. If the scan returns an immature reward, completion can include it and the node rejects the transaction; rebuilding can select it again until it matures. This limitation is accepted: current use cases do not justify reward-specific discovery checks and their complexity.
43
+
44
+ CKB capacity and iCKB quantity stay separate, in bigint. An input's full capacity funds the transaction, but the outputs' occupied capacity, a plain change cell, any order master and the fee still have to be paid. Ordinary change remains a plain cell; existing typed outputs are never repurposed as fee change. A duplicate input is a builder defect detected by completion.
45
+
46
+ CCC prepares the signer and resolves the witness-aware fee; Stack owns the selected cells and output shape. Calling CCC's input collectors would introduce another discovery path with different cache and filtering rules. All candidate plans use the same sampled state.
47
+
48
+ DAO output and deposit-header limits come from the deployed script, not a general consensus output cap. Their constants and reasons live in [`src/dao.ts`](src/dao.ts). Collected withdrawals' deposit headers go first, making the projection's batch of at most 256 matured withdrawals addressable regardless of other headers. The claim-epoch model test compares installed CCC with a pinned transcription of deployed `dao.c`, so a dependency regression fails the gate rather than being hidden behind a local copy.
49
+
50
+ ## Signing and broadcast
51
+
52
+ `signAndSendTransaction(signer, tx, recordTxHash?, broadcastBefore?)` signs locally, then checks the body, fee rate and optional epoch deadline before sending.
53
+
54
+ - Different ordered inputs, outputs or outputs data are rejected. Witnesses, `cellDeps` and `headerDeps` remain signer-owned. The fee ceiling values inputs from the pre-sign transaction.
55
+ - The signed fee rate must not exceed CCC's maximum, which `sendTransactionNoCache` bypasses. There is no operator override that could silently disable this protection.
56
+ - A withdrawal plan carries `broadcastBefore`, the earliest selected claim less the policy's reserve. After signing and the fee check, one fresh tip read rejects an expired plan with `TransactionExpiredError`, without broadcasting. Timing uses epochs because CKB has no transaction expiry and a request committed after its claim can lock the deposit for another cycle.
57
+
58
+ `recordTxHash` receives `signed.hash()` before the send RPC starts. That local hash is authoritative; no hash returned by a node replaces it. Comparing a successful response's hash could only reject after the node had already received the transaction. A duplicate response is accepted only when it names the local hash. Every other send failure is ambiguous and throws `TransactionBroadcastError` carrying `txHash`; callers can observe that hash instead of resending. The client cache is never marked by this helper.
59
+
60
+ ## Confirmation
61
+
62
+ `waitTransaction(client, txHash, { timeout?, interval?, signal? })` observes one already-broadcast transaction for a bounded window and returns it once the node reports commitment, at depth zero. `timeout` defaults to 60,000 ms and covers the whole wait, including in-flight client operations; it must be a non-negative safe integer no larger than a host timer delay. `interval` defaults to 2,000 ms.
63
+
64
+ A client exposing a JSON-RPC requestor is polled with `get_transaction` verbosity 1, including the connector's composition proxy. CCC's typed read hides a rejected transaction with a null body, so raw status is needed to preserve rejection evidence. Body reads use `getTransactionNoCache` and are normalized with `ccc.ClientTransactionResponse.from`; a malformed generic-client response is treated as unconfirmed. The typed path remains for clients without a requestor.
65
+
66
+ A terminal rejection throws `TransactionWaitError` with the hash, status and node reason. Timeout uses CCC's `ErrorClientWaitTransactionTimeout`. Aborting or timing out stops the wait, but CCC transports may still finish their in-flight work; late settlement is handled. Nothing clears or marks the cache here.
67
+
68
+ Callers own what follows a closed window. The actors rebuild from committed state next turn; the app can reopen a window on the same hash without another signature or broadcast. No caller needs positive confirmation depth today; it could be added without replacing this helper. There is no durable signed-byte store, replay graph or pending overlay. Such a store would need reconciliation on every start, while duplicate intent remains an accepted consequence of rebuilding rather than persisting intent.
69
+
70
+ CCC caches sufficiently old headers even across `ClientCacheMemory.clear()`. A consumer that must discard them after a failed transaction gives the client a new cache, as the [interface](../interface/README.md#wallet-session-and-client) does; a deep reorg is possible, so age alone does not make a header immutable.
71
+
72
+ ## Estimates and fees
73
+
74
+ [Pool maturity estimates](docs/pool_maturity_estimates.md) explains the model and its limits. The default order fee lives beside the quote and plan code in [`src/conversion/estimate.ts`](src/conversion/estimate.ts). It buys a window for a bot to fill a buy before DAO growth erodes its incentive; it is not a completion guarantee.
75
+
76
+ ## Versioning and API checks
77
+
78
+ The repository follows [Epoch Semantic Versioning](https://antfu.me/posts/epoch-semver). The [release policy](../README.md#releases) explains this rewrite's starting version.
79
+
80
+ Before this rewritten API is first published, its shape follows actual consumers rather than a committed API report. API Extractor still rejects forgotten exports, so every type reachable from the entry point is importable. A frozen report and release tags would add maintenance without a compatibility promise yet; revisit the report when the new surface has published consumers.
32
81
 
33
82
  ## Licensing
34
83
 
35
- This source code, crafted with care by [Phroi](https://phroi.com/), is freely available on [GitHub](https://github.com/ickb/sdk) and it is released under the [MIT License](./LICENSE).
84
+ This source code, crafted with care by [Phroi](https://phroi.com/), is freely available on [GitHub](https://github.com/ickb/stack/tree/master/sdk) and released under the [MIT License](../LICENSE).
@@ -1,23 +1,14 @@
1
- import { ccc } from "@ckb-ccc/core";
2
- import { IckbUdtManager, LogicManager, OwnedOwnerManager } from "@ickb/core";
3
- import { DaoManager } from "@ickb/dao";
4
- import { OrderManager } from "@ickb/order";
5
- import { CapacityManager, type ScriptDeps } from "@ickb/utils";
6
- export declare function getConfig(d: "mainnet" | "testnet" | {
7
- udt: ScriptDeps;
8
- logic: ScriptDeps;
9
- ownedOwner: ScriptDeps;
10
- order: ScriptDeps;
11
- dao: ScriptDeps;
12
- }, bots?: ccc.ScriptLike[]): {
13
- managers: {
14
- capacity: CapacityManager;
15
- dao: DaoManager;
16
- ickbUdt: IckbUdtManager;
17
- logic: LogicManager;
18
- ownedOwner: OwnedOwnerManager;
19
- order: OrderManager;
20
- };
21
- bots: ccc.Script[];
22
- };
1
+ import type { SdkManagers } from "./conversion/types.js";
2
+ import type { SupportedChain } from "./utils/chain.js";
3
+ /**
4
+ * Plain CKB the bot keeps for its own cells and fees: its sizing line for matches and deposits.
5
+ */
6
+ export declare const CKB_RESERVE: bigint;
7
+ /**
8
+ * The managers of one network's iCKB deployment.
9
+ *
10
+ * @remarks Builders still return partial transactions. `IckbSdk` owns the shared iCKB
11
+ * completion path as `sdk.completeTransaction(...)`, which callers invoke before send.
12
+ */
13
+ export declare function getConfig(chain: SupportedChain): SdkManagers;
23
14
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"../src/","sources":["constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAU,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAgBvE,wBAAgB,SAAS,CACvB,CAAC,EACG,SAAS,GACT,SAAS,GACT;IAEE,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,EAAE,UAAU,CAAC;IAClB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,UAAU,CAAC;IAClB,GAAG,EAAE,UAAU,CAAC;CACjB,EACL,IAAI,GAAE,GAAG,CAAC,UAAU,EAAO,GAC1B;IACD,QAAQ,EAAE;QACR,QAAQ,EAAE,eAAe,CAAC;QAC1B,GAAG,EAAE,UAAU,CAAC;QAChB,OAAO,EAAE,cAAc,CAAC;QACxB,KAAK,EAAE,YAAY,CAAC;QACpB,UAAU,EAAE,iBAAiB,CAAC;QAC9B,KAAK,EAAE,YAAY,CAAC;KACrB,CAAC;IACF,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;CACpB,CAiDA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAqEvD;;GAEG;AACH,eAAO,MAAM,WAAW,QAA2B,CAAC;AAEpD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,WAAW,CAqB5D"}
package/dist/constants.js CHANGED
@@ -1,95 +1,99 @@
1
1
  import { ccc } from "@ckb-ccc/core";
2
- import { IckbUdtManager, LogicManager, OwnedOwnerManager } from "@ickb/core";
3
- import { DaoManager } from "@ickb/dao";
4
- import { OrderManager } from "@ickb/order";
5
- import { CapacityManager, unique } from "@ickb/utils";
6
- export function getConfig(d, bots = []) {
7
- if (d === "mainnet" || d === "testnet") {
8
- bots = bots.concat(d === "mainnet" ? MAINNET_KNOWN_BOTS : TESTNET_KNOWN_BOTS);
9
- const depGroup = d === "mainnet" ? MAINNET_DEP_GROUP : TESTNET_DEP_GROUP;
10
- d = {
11
- udt: from(UDT, depGroup),
12
- logic: from(ICKB_LOGIC, depGroup),
13
- ownedOwner: from(OWNED_OWNER, depGroup),
14
- order: from(ORDER, depGroup),
15
- dao: from(DAO, depGroup),
16
- };
17
- }
18
- const capacity = CapacityManager.withAnyData();
19
- const dao = new DaoManager(d.dao.script, d.dao.cellDeps);
20
- const ickbUdt = new IckbUdtManager(d.udt.script, d.udt.cellDeps, d.logic.script, dao);
21
- const logic = new LogicManager(d.logic.script, d.logic.cellDeps, dao, ickbUdt);
22
- const ownedOwner = new OwnedOwnerManager(d.ownedOwner.script, d.ownedOwner.cellDeps, dao, ickbUdt);
23
- const order = new OrderManager(d.order.script, d.order.cellDeps, ickbUdt);
24
- return {
25
- managers: {
26
- capacity,
27
- dao,
28
- ickbUdt,
29
- logic,
30
- ownedOwner,
31
- order,
32
- },
33
- bots: [...unique(bots.map((b) => ccc.Script.from(b)))],
34
- };
35
- }
36
- function from(script, ...cellDeps) {
37
- return {
38
- script: ccc.Script.from(script),
39
- cellDeps,
40
- };
41
- }
42
- const DAO = {
2
+ import { LogicManager } from "./logic.js";
3
+ import { OrderManager } from "./order/order.js";
4
+ import { OwnedOwnerManager } from "./owned_owner.js";
5
+ import { IckbUdt } from "./udt.js";
6
+ /** Nervos DAO type script. */
7
+ const DAO = ccc.Script.from({
43
8
  codeHash: "0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e",
44
9
  hashType: "type",
45
10
  args: "0x",
46
- };
47
- const UDT = {
11
+ });
12
+ /** Raw xUDT type script; the iCKB args are computed by `IckbUdt.typeScriptFrom`. */
13
+ const UDT = ccc.Script.from({
48
14
  codeHash: "0x50bd8d6680b8b9cf98b73f3c08faf8b2a21914311954118ad6609be6e78a1b95",
49
15
  hashType: "data1",
50
- args: "0xb73b6ab39d79390c6de90a09c96b290c331baf1798ed6f97aed02590929734e800000080",
51
- };
52
- const ICKB_LOGIC = {
16
+ args: "0x",
17
+ });
18
+ /** iCKB Logic script. */
19
+ const ICKB_LOGIC = ccc.Script.from({
53
20
  codeHash: "0x2a8100ab5990fa055ab1b50891702e1e895c7bd1df6322cd725c1a6115873bd3",
54
21
  hashType: "data1",
55
22
  args: "0x",
56
- };
57
- const OWNED_OWNER = {
23
+ });
24
+ /** Owned Owner lock script. */
25
+ const OWNED_OWNER = ccc.Script.from({
58
26
  codeHash: "0xacc79e07d107831feef4c70c9e683dac5644d5993b9cb106dca6e74baa381bd0",
59
27
  hashType: "data1",
60
28
  args: "0x",
61
- };
62
- const ORDER = {
29
+ });
30
+ /** Order lock script. */
31
+ const ORDER = ccc.Script.from({
63
32
  codeHash: "0x49dfb6afee5cc8ac4225aeea8cb8928b150caf3cd92fea33750683c74b13254a",
64
33
  hashType: "data1",
65
34
  args: "0x",
66
- };
67
- const MAINNET_DEP_GROUP = ccc.CellDep.from({
68
- outPoint: {
69
- txHash: "0x621a6f38de3b9f453016780edac3b26bfcbfa3e2ecb47c2da275471a5d3ed165",
70
- index: "0x0",
71
- },
72
- depType: "depGroup",
73
- });
74
- const TESTNET_DEP_GROUP = ccc.CellDep.from({
75
- outPoint: {
76
- txHash: "0xf7ece4fb33d8378344cab11fcd6a4c6f382fd4207ac921cf5821f30712dcd311",
77
- index: "0x0",
78
- },
79
- depType: "depGroup",
80
35
  });
81
- const MAINNET_KNOWN_BOTS = [
82
- {
83
- codeHash: "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
84
- hashType: "type",
85
- args: "0xd096cb29e2f68a85a46bd6bf6cbee6327959ba64",
36
+ /** Each network's code cells, given as direct code deps, and the dep group of the rest. */
37
+ const DEPLOYMENTS = {
38
+ mainnet: {
39
+ udtCode: {
40
+ txHash: "0xc07844ce21b38e4b071dd0e1ee3b0e27afd8d7532491327f39b786343f558ab7",
41
+ index: 0,
42
+ },
43
+ logicCode: {
44
+ txHash: "0xd7309191381f5a8a2904b8a79958a9be2752dbba6871fa193dab6aeb29dc8f44",
45
+ index: 0,
46
+ },
47
+ depGroup: {
48
+ txHash: "0x621a6f38de3b9f453016780edac3b26bfcbfa3e2ecb47c2da275471a5d3ed165",
49
+ index: 0,
50
+ },
86
51
  },
87
- ];
88
- const TESTNET_KNOWN_BOTS = [
89
- {
90
- codeHash: "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
91
- hashType: "type",
92
- args: "0xb4380110f7679ac31cefe4925485645d82bf619f",
52
+ testnet: {
53
+ udtCode: {
54
+ txHash: "0xbf6fb538763efec2a70a6a3dcb7242787087e1030c4e7d86585bc63a9d337f5f",
55
+ index: 0,
56
+ },
57
+ logicCode: {
58
+ txHash: "0x9ac989b3355764f76cdce02c69dedb819fdfbcbda49a7db1a2c9facdfdb9a7fe",
59
+ index: 0,
60
+ },
61
+ depGroup: {
62
+ txHash: "0xf7ece4fb33d8378344cab11fcd6a4c6f382fd4207ac921cf5821f30712dcd311",
63
+ index: 0,
64
+ },
93
65
  },
94
- ];
66
+ };
67
+ /**
68
+ * Plain CKB the bot keeps for its own cells and fees: its sizing line for matches and deposits.
69
+ */
70
+ export const CKB_RESERVE = ccc.fixedPointFrom(1000);
71
+ /**
72
+ * The managers of one network's iCKB deployment.
73
+ *
74
+ * @remarks Builders still return partial transactions. `IckbSdk` owns the shared iCKB
75
+ * completion path as `sdk.completeTransaction(...)`, which callers invoke before send.
76
+ */
77
+ export function getConfig(chain) {
78
+ // The runtime check stands for callers outside TypeScript.
79
+ if (!Object.hasOwn(DEPLOYMENTS, chain)) {
80
+ throw new TypeError("unsupported iCKB network");
81
+ }
82
+ const { udtCode, logicCode, depGroup } = DEPLOYMENTS[chain];
83
+ const cellDeps = [ccc.CellDep.from({ outPoint: depGroup, depType: "depGroup" })];
84
+ const dao = { script: DAO, cellDeps };
85
+ const ickbUdt = new IckbUdt({
86
+ code: udtCode,
87
+ script: IckbUdt.typeScriptFrom(UDT, ICKB_LOGIC),
88
+ logicCode,
89
+ logicScript: ICKB_LOGIC,
90
+ daoScript: DAO,
91
+ });
92
+ return {
93
+ ickbUdt,
94
+ ownedOwner: new OwnedOwnerManager(OWNED_OWNER, cellDeps, dao),
95
+ ickbLogic: new LogicManager(ICKB_LOGIC, cellDeps, dao),
96
+ order: new OrderManager(ORDER, cellDeps, ickbUdt.script),
97
+ };
98
+ }
95
99
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"../src/","sources":["constants.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { IckbDepositCell } from "../logic.js";
2
+ import { type ValueComponents } from "../utils/utils.js";
3
+ import type { ConversionOrderEstimate, SystemState } from "./types.js";
4
+ /**
5
+ * Default order fee: 0.01%. At roughly 2% annual DAO yield this buys about two days of
6
+ * price headroom for a buy, versus hours at 0.001%; actual fillability also depends on
7
+ * mining fees. It leaves time to notice a stalled bot without charging the much larger 0.1%.
8
+ */
9
+ export declare const DEFAULT_ORDER_FEE = 10n;
10
+ /** Default order-fee denominator used by Stack conversion quotes and plans. */
11
+ export declare const DEFAULT_ORDER_FEE_BASE = 100000n;
12
+ /** The quote and its maturity estimate, or `undefined` when no order ratio represents it. */
13
+ export declare function estimateConversionOrder(isCkb2Udt: boolean, amounts: ValueComponents, system: SystemState, { fee, feeBase }: {
14
+ fee: bigint;
15
+ feeBase: bigint;
16
+ }, takenDeposits?: readonly IckbDepositCell[]): ConversionOrderEstimate | undefined;
17
+ /**
18
+ * Returns the CKB fee threshold above which order maturity is worth estimating.
19
+ * This conservative proxy stays separate from partialOrderFee: the quote has no built
20
+ * order whose serialized size could supply that fee yet.
21
+ */
22
+ export declare function estimateMaturityFeeThreshold(system: Pick<SystemState, "feeRate">): bigint;
23
+ /**
24
+ * The smallest request one direction accepts as an order at the current fee rate. A
25
+ * CKB-to-iCKB remainder pays the default order fee, which must cover the maturity threshold
26
+ * of ten mining fees; an iCKB-to-CKB remainder can give its whole CKB value as the dust
27
+ * fee, so its value must exceed the threshold. The extra unit covers the quote's rounding,
28
+ * as the dust search's boundary shows; callers round up further for display.
29
+ */
30
+ export declare function minimumOrderAmount(isCkb2Udt: boolean, system: SystemState): bigint;
31
+ /**
32
+ * The order leg of an iCKB-to-CKB conversion: at the default fee when that fee clears the
33
+ * maturity threshold, else the smallest fee that does (a dust order, noticed). Either way
34
+ * it is dated: a sell order at par is always covered by the pool (see `maturity`).
35
+ */
36
+ export declare function estimateIckbToCkbOrder(amounts: ValueComponents, system: SystemState, takenDeposits: readonly IckbDepositCell[]): (ConversionOrderEstimate & {
37
+ maturity: bigint;
38
+ }) | undefined;
39
+ //# sourceMappingURL=estimate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimate.d.ts","sourceRoot":"","sources":["../../src/conversion/estimate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAKnD,OAAO,EAAW,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAElE,OAAO,KAAK,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEvE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC,+EAA+E;AAC/E,eAAO,MAAM,sBAAsB,UAAU,CAAC;AAE9C,6FAA6F;AAC7F,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,WAAW,EACnB,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAClD,aAAa,GAAE,SAAS,eAAe,EAAO,GAC7C,uBAAuB,GAAG,SAAS,CAerC;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,GACnC,MAAM,CAER;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAOlF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,WAAW,EACnB,aAAa,EAAE,SAAS,eAAe,EAAE,GACxC,CAAC,uBAAuB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,CAyB9D"}
@@ -0,0 +1,117 @@
1
+ import { OrderConversionRepresentabilityError, quoteConversion, } from "../order/conversion.js";
2
+ import { ceilDiv } from "../utils/utils.js";
3
+ import { maturity } from "./maturity.js";
4
+ /**
5
+ * Default order fee: 0.01%. At roughly 2% annual DAO yield this buys about two days of
6
+ * price headroom for a buy, versus hours at 0.001%; actual fillability also depends on
7
+ * mining fees. It leaves time to notice a stalled bot without charging the much larger 0.1%.
8
+ */
9
+ export const DEFAULT_ORDER_FEE = 10n;
10
+ /** Default order-fee denominator used by Stack conversion quotes and plans. */
11
+ export const DEFAULT_ORDER_FEE_BASE = 100000n;
12
+ /** The quote and its maturity estimate, or `undefined` when no order ratio represents it. */
13
+ export function estimateConversionOrder(isCkb2Udt, amounts, system, { fee, feeBase }, takenDeposits = []) {
14
+ let quote;
15
+ try {
16
+ quote = quoteConversion(isCkb2Udt, system.exchangeRatio, amounts, { fee, feeBase });
17
+ }
18
+ catch (error) {
19
+ if (error instanceof OrderConversionRepresentabilityError) {
20
+ return undefined;
21
+ }
22
+ throw error;
23
+ }
24
+ const estimatedMaturity = quote.ckbFee >= estimateMaturityFeeThreshold(system)
25
+ ? maturity({ info: quote.info, amounts }, system, takenDeposits)
26
+ : undefined;
27
+ return { ...quote, maturity: estimatedMaturity };
28
+ }
29
+ /**
30
+ * Returns the CKB fee threshold above which order maturity is worth estimating.
31
+ * This conservative proxy stays separate from partialOrderFee: the quote has no built
32
+ * order whose serialized size could supply that fee yet.
33
+ */
34
+ export function estimateMaturityFeeThreshold(system) {
35
+ return 10n * system.feeRate;
36
+ }
37
+ /**
38
+ * The smallest request one direction accepts as an order at the current fee rate. A
39
+ * CKB-to-iCKB remainder pays the default order fee, which must cover the maturity threshold
40
+ * of ten mining fees; an iCKB-to-CKB remainder can give its whole CKB value as the dust
41
+ * fee, so its value must exceed the threshold. The extra unit covers the quote's rounding,
42
+ * as the dust search's boundary shows; callers round up further for display.
43
+ */
44
+ export function minimumOrderAmount(isCkb2Udt, system) {
45
+ const threshold = estimateMaturityFeeThreshold(system) + 1n;
46
+ if (isCkb2Udt) {
47
+ return ceilDiv(threshold * DEFAULT_ORDER_FEE_BASE, DEFAULT_ORDER_FEE);
48
+ }
49
+ const { ckbScale, udtScale } = system.exchangeRatio;
50
+ return ceilDiv(threshold * ckbScale, udtScale);
51
+ }
52
+ /**
53
+ * The order leg of an iCKB-to-CKB conversion: at the default fee when that fee clears the
54
+ * maturity threshold, else the smallest fee that does (a dust order, noticed). Either way
55
+ * it is dated: a sell order at par is always covered by the pool (see `maturity`).
56
+ */
57
+ export function estimateIckbToCkbOrder(amounts, system, takenDeposits) {
58
+ const base = estimateConversionOrder(false, amounts, system, { fee: DEFAULT_ORDER_FEE, feeBase: DEFAULT_ORDER_FEE_BASE }, takenDeposits);
59
+ if (base?.maturity !== undefined) {
60
+ return { ...base, maturity: base.maturity };
61
+ }
62
+ const dust = estimateDustIckbToCkbOrder(amounts, system);
63
+ if (dust === undefined) {
64
+ return undefined;
65
+ }
66
+ return {
67
+ ...dust,
68
+ maturity: maturity({ info: dust.info, amounts }, system, takenDeposits),
69
+ notice: {
70
+ inputIckb: amounts.udtValue,
71
+ outputCkb: dust.convertedAmount,
72
+ incentiveCkb: positiveFee(dust.ckbFee),
73
+ },
74
+ };
75
+ }
76
+ function estimateDustIckbToCkbOrder(amounts, system) {
77
+ const baseEstimate = estimateConversionOrder(false, amounts, system, {
78
+ fee: 0n,
79
+ feeBase: DEFAULT_ORDER_FEE_BASE,
80
+ });
81
+ if (baseEstimate === undefined) {
82
+ return undefined;
83
+ }
84
+ const targetFee = estimateMaturityFeeThreshold(system);
85
+ const feeBase = baseEstimate.convertedAmount + 1n;
86
+ if (targetFee <= 0n || feeBase <= 1n) {
87
+ return baseEstimate;
88
+ }
89
+ const estimateWithFee = (fee) => estimateConversionOrder(false, amounts, system, { fee, feeBase });
90
+ return lowestFeeEstimateAtThreshold(estimateWithFee, feeBase - 1n, targetFee);
91
+ }
92
+ function lowestFeeEstimateAtThreshold(estimateWithFee, highestFee, targetFee) {
93
+ const highestDiscount = estimateWithFee(highestFee);
94
+ if (highestDiscount === undefined || highestDiscount.ckbFee < targetFee) {
95
+ return undefined;
96
+ }
97
+ let low = 0n;
98
+ let high = highestFee;
99
+ while (low < high) {
100
+ const mid = (low + high) / 2n;
101
+ const estimateAtMid = estimateWithFee(mid);
102
+ if (estimateAtMid === undefined) {
103
+ return undefined;
104
+ }
105
+ if (estimateAtMid.ckbFee >= targetFee) {
106
+ high = mid;
107
+ }
108
+ else {
109
+ low = mid + 1n;
110
+ }
111
+ }
112
+ return estimateWithFee(low);
113
+ }
114
+ function positiveFee(fee) {
115
+ return fee > 0n ? fee : 0n;
116
+ }
117
+ //# sourceMappingURL=estimate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimate.js","sourceRoot":"","sources":["../../src/conversion/estimate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { IckbDepositCell } from "../logic.js";
2
+ import type { MaturityOrderInput, SystemState } from "./types.js";
3
+ /**
4
+ * Assumed turn duration, allowing for restart delay, confirmation and slow reads.
5
+ * This is a modeling interval, not a bound on the runtime; see sdk/docs/pool_maturity_estimates.md.
6
+ */
7
+ export declare const BOT_TURN_MS: bigint;
8
+ /**
9
+ * The estimated fill time of an order on the book or about to be placed, zero when it is
10
+ * already fulfilled. `takenDeposits` are the pool deposits the same plan withdraws
11
+ * directly, which cannot fill its order leg too. Dual-ratio orders never reach here: the
12
+ * scan drops them.
13
+ */
14
+ export declare function maturity(o: MaturityOrderInput, system: SystemState, takenDeposits?: readonly IckbDepositCell[]): bigint;
15
+ //# sourceMappingURL=maturity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maturity.d.ts","sourceRoot":"","sources":["../../src/conversion/maturity.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAMnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,WAAW,QAAoB,CAAC;AAE7C;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,CAAC,EAAE,kBAAkB,EACrB,MAAM,EAAE,WAAW,EACnB,aAAa,GAAE,SAAS,eAAe,EAAO,GAC7C,MAAM,CAWR"}