@ickb/sdk 1000.0.82 → 9001.0.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 (157) hide show
  1. package/README.md +84 -32
  2. package/dist/constants.d.ts +9 -22
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/constants.js +62 -76
  5. package/dist/constants.js.map +1 -1
  6. package/dist/conversion/estimate.d.ts +33 -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 +113 -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 +21 -0
  19. package/dist/conversion/projection.d.ts.map +1 -0
  20. package/dist/conversion/projection.js +94 -0
  21. package/dist/conversion/projection.js.map +1 -0
  22. package/dist/conversion/types.d.ts +264 -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 +34 -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 +100 -0
  31. package/dist/dao.d.ts.map +1 -0
  32. package/dist/dao.js +125 -0
  33. package/dist/dao.js.map +1 -0
  34. package/dist/index.d.ts +49 -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 +81 -0
  39. package/dist/logic.d.ts.map +1 -0
  40. package/dist/logic.js +173 -0
  41. package/dist/logic.js.map +1 -0
  42. package/dist/order/cells.d.ts +168 -0
  43. package/dist/order/cells.d.ts.map +1 -0
  44. package/dist/order/cells.js +309 -0
  45. package/dist/order/cells.js.map +1 -0
  46. package/dist/order/conversion.d.ts +37 -0
  47. package/dist/order/conversion.d.ts.map +1 -0
  48. package/dist/order/conversion.js +120 -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 +102 -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 +124 -0
  69. package/dist/order/matcher.js.map +1 -0
  70. package/dist/order/order.d.ts +63 -0
  71. package/dist/order/order.d.ts.map +1 -0
  72. package/dist/order/order.js +234 -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 +67 -0
  77. package/dist/order/order_data.js.map +1 -0
  78. package/dist/order/ratio.d.ts +40 -0
  79. package/dist/order/ratio.d.ts.map +1 -0
  80. package/dist/order/ratio.js +74 -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 +57 -0
  85. package/dist/order/relative.js.map +1 -0
  86. package/dist/owned_owner.d.ts +108 -0
  87. package/dist/owned_owner.d.ts.map +1 -0
  88. package/dist/owned_owner.js +260 -0
  89. package/dist/owned_owner.js.map +1 -0
  90. package/dist/sdk.d.ts +113 -41
  91. package/dist/sdk.d.ts.map +1 -1
  92. package/dist/sdk.js +410 -209
  93. package/dist/sdk.js.map +1 -1
  94. package/dist/send/sign_and_send_transaction.d.ts +61 -0
  95. package/dist/send/sign_and_send_transaction.d.ts.map +1 -0
  96. package/dist/send/sign_and_send_transaction.js +201 -0
  97. package/dist/send/sign_and_send_transaction.js.map +1 -0
  98. package/dist/send/wait_transaction.d.ts +42 -0
  99. package/dist/send/wait_transaction.d.ts.map +1 -0
  100. package/dist/send/wait_transaction.js +172 -0
  101. package/dist/send/wait_transaction.js.map +1 -0
  102. package/dist/udt.d.ts +108 -0
  103. package/dist/udt.d.ts.map +1 -0
  104. package/dist/udt.js +180 -0
  105. package/dist/udt.js.map +1 -0
  106. package/dist/utils/chain.d.ts +3 -0
  107. package/dist/utils/chain.d.ts.map +1 -0
  108. package/dist/utils/chain.js +2 -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 +69 -0
  113. package/dist/utils/codec.js.map +1 -0
  114. package/dist/utils/utils.d.ts +99 -0
  115. package/dist/utils/utils.d.ts.map +1 -0
  116. package/dist/utils/utils.js +130 -0
  117. package/dist/utils/utils.js.map +1 -0
  118. package/dist/utils/verified_client.d.ts +19 -0
  119. package/dist/utils/verified_client.d.ts.map +1 -0
  120. package/dist/utils/verified_client.js +92 -0
  121. package/dist/utils/verified_client.js.map +1 -0
  122. package/package.json +19 -26
  123. package/src/constants.ts +65 -181
  124. package/src/conversion/estimate.ts +155 -0
  125. package/src/conversion/maturity.ts +158 -0
  126. package/src/conversion/plans.ts +144 -0
  127. package/src/conversion/projection.ts +136 -0
  128. package/src/conversion/types.ts +302 -0
  129. package/src/conversion/withdrawal_ring.ts +122 -0
  130. package/src/dao.ts +196 -0
  131. package/src/index.ts +89 -3
  132. package/src/logic.ts +283 -0
  133. package/src/order/cells.ts +383 -0
  134. package/src/order/conversion.ts +162 -0
  135. package/src/order/fee.ts +30 -0
  136. package/src/order/fill.ts +83 -0
  137. package/src/order/info.ts +181 -0
  138. package/src/order/master.ts +42 -0
  139. package/src/order/matcher.ts +191 -0
  140. package/src/order/order.ts +288 -0
  141. package/src/order/order_data.ts +131 -0
  142. package/src/order/ratio.ts +127 -0
  143. package/src/order/relative.ts +109 -0
  144. package/src/owned_owner.ts +364 -0
  145. package/src/sdk.ts +542 -440
  146. package/src/send/sign_and_send_transaction.ts +256 -0
  147. package/src/send/wait_transaction.ts +227 -0
  148. package/src/udt.ts +249 -0
  149. package/src/utils/chain.ts +2 -0
  150. package/src/utils/codec.ts +78 -0
  151. package/src/utils/utils.ts +208 -0
  152. package/src/utils/verified_client.ts +136 -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,87 @@
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, maxFeeRate?)` reads the account, pool and order book; `maxFeeRate` caps the node's sampled fee rate through CCC's `getFeeRate` (a cap of zero or less throws `RangeError`), so every consumer of the state (completion, the planned fee, the collect rule, estimates) plans at one rate. 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. It reads the indexer's raw answer through the client's JSON-RPC requestor, because the answer carries each cell's block number and CCC's typed scan drops it: receipts, deposits and withdrawal requests then read their committing header by number, instead of asking the node for each creating transaction's status first. The number is the node's claim either way. The SDK needs a JSON-RPC client for its raw reads (scans, status polls, transaction proofs); the connector's composition proxy forwards the requestor. It keeps no typed fallback for other clients: none exists in CCC, and two code paths per read had to be kept equivalent. Pages stay at 400 because CKB's sample config recommends that `request_limit`, and a node configured with it refuses a larger page rather than truncating it. 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 order is dated by its master's block from the scan: the master is created beside the mint order and never changes until melted, so no status read is needed; its origin transaction is read cache first, a cached body trusted like the scan itself, since the send checks every cell it spends.
25
+
26
+ Every node read in `getL1AccountState` and `signAndSendTransaction` goes through a wrapper the SDK puts on the client it is given, so a consumer passes a plain client and cannot forget. Completion and signing read through the signer's client and `waitTransaction` through the plain one: the send verifies every cell completion valued before signing, witnesses and cell deps are the signer's, and a transaction status has nothing to verify against. The wrapper checks every header against its own hash, a header read by number against the number asked for, and a transaction read by hash against the hash of its body; it serves a cell from that verified body, cache first, re-hashing a cache hit since a consumer's cache need not key bodies by their hash. A header's DAO rate sets the interest a withdrawal collects and the iCKB a deposit is worth. CCC's fee completion values that interest through the signer's client, which the SDK does not wrap, at whatever header the node names; the [send](#signing-and-broadcast) measures the fee from verified values and refuses one above what completion planned. The header beside a transaction or a cell is pinned only to the block the node names for it; the chain values a transaction at the headers it names in its deps, and the [send check](#signing-and-broadcast) refuses an input valued outside them and proves which block committed a withdrawal request. The state read is anchored at the tip's parent, which is bound two ways. Its age against the local clock, the selection margin less the broadcast reserve (five minutes for the bot, thirty for a wallet), catches an honest node that has fallen behind; the bound is on the parent, not the tip, because a fresh tip a node invented can name any old block as its parent. Completion names the parent as a header dep, so a header a node invented prices nothing the chain accepts. The send's deadline check reads the live tip under the same age bound. The bot, the generator and the interface open their clients with `clientCache()`: CCC's default cache keeps 128 blocks and 256 transaction bodies, fewer than a pool's deposits span or a large book's order origins, so every read refetched most of them; the larger cache holds 4096 of each, filling only as far as needed, and a cached header or body is still checked.
27
+
28
+ ## Transaction completion
29
+
30
+ `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.
31
+
32
+ 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.
33
+
34
+ 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.
35
+
36
+ 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.
37
+
38
+ ### Funding and compaction
39
+
40
+ 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.
41
+
42
+ 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.
43
+
44
+ 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.
45
+
46
+ 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. Completion names the header the plan was priced at as the last header dep: a parent a node invented passes the hash checks and, dated fresh, the age bound, and its DAO rate sets the exchange ratio fills and orders are priced at, but the chain refuses a transaction whose header deps are off the main chain. Last, because the deployed dao.c reads one byte of a deposit header's index, so the deposit headers lead. That header is the tip's parent, for one more read: a tip can still lose a one-block race, and a transaction naming it is then refused after signing, as a testnet order was on 2026-10-30. Every fork recorded as an uncle in a day of each chain (257 on mainnet, 77 on testnet, to 2026-10-30) was one block deep, so a header further back would only add staleness. Receipts and deposits being withdrawn count at the iCKB value the state read gave them at their deposit headers, passed in as `protocolCells`, rather than each candidate asking the node again which block created them; a wrong value can only get the transaction refused by iCKB Logic's strict equality, and a protocol input without a value is a builder defect that throws.
47
+
48
+ 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.
49
+
50
+ 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.
51
+
52
+ ## Signing and broadcast
53
+
54
+ `signAndSendTransaction(signer, tx, plannedFee, recordTxHash?, broadcastBefore?)` signs locally, then checks the body, the fee and the optional epoch deadline before sending.
55
+
56
+ - Every input is verified before signing: its creating transaction is read from the client cache, else the node, and accepted only when its hash is the one the `OutPoint` names, so the output at the index is the real cell. A planned cell that differs from it in capacity, lock, type or data is rejected; an input without its cell attached is valued from that output. The default lock signs each input as its `OutPoint` only, so without this a node understating a plain cell's capacity or an iCKB amount would turn the difference into fee or a burn on a transaction that passes every other check. One `get_transaction` per distinct creating transaction not already cached.
57
+ - Different ordered inputs, outputs or outputs data are rejected. Witnesses, `cellDeps` and `headerDeps` remain signer-owned. The fee check values the verified inputs, and a phase-2 DAO input's interest at the deposit and request headers the transaction names in its deps: CCC values that interest from headers it reads afresh, which a node can answer with another real block, while the chain reads the deps, so an input valued at a header outside them is refused. The deps alone bind the request header to some block the transaction names, not to the block that committed the input, so in a withdrawal of several requests a node could swap which named request header values which input, paying the rate drift between the two blocks times the capacity imbalance to the miner. The send therefore asks the node for each request transaction's `get_transaction_proof` against the request header it valued, and refuses unless the Merkle path from the transaction's hash reaches that header's transactions root, which the header's own hash binds. That is one call of a few hundred bytes per request transaction per send, through the client's JSON-RPC requestor, which such a send therefore needs. The proven request header is the real request block, so dao.c's rule that it come after the deposit is left to the chain; a send-side copy of that rule, added before the proof, was dropped. A proven pair never changes, but caching it saved nothing: a request is spent once, and proven again only when a failed send is rebuilt. Rejected: reading the whole block, which proves the same at up to hundreds of kilobytes; a second node, which replaces proof with trust; a planner rule valuing every request at the highest-numbered dep, which closes the swap without a call but splits withdrawals by block; an on-chain script recomputing a digest of the inputs and their headers, whose carrier cell a flow's last transaction leaves behind; and accepting the swap, the earlier choice. Deposits, receipts and their headers need no proof: iCKB Logic settles them with strict equality, so a wrong header gets the transaction refused, and a deposit header is matched by the number in the verified cell data.
58
+ - The fee the chain will take must not exceed `plannedFee`, the fee completion priced: `tx.estimateFee(feeRate)`, which CCC's fee completion meets exactly. Completion valued phase-2 interest at whatever header the node named for the request, and a header that hashes correctly can still be one the chain does not use: a lower rate there shortens the change. Checking only CCC's maximum fee rate let that difference go to the miner, up to about 0.1 CKB per kB of transaction. Amounts are compared rather than rates, so the signed size does not matter. Rejected: re-pricing the completed transaction through a verified client, which reads the same node answer CCC read and so catches only a node changing its answer between two reads. The check also replaces CCC's maximum fee rate, which `sendTransactionNoCache` bypasses: CCC caps the rate `getFeeRate` samples at that maximum, so a fee planned from the state read's rate is within it, unless the caller passes its own `maxFeeRate`, which replaces that ceiling on purpose: the caller's cap is the ceiling, and a cap above CCC's lets a node's sample rise to it. That rate is a node statistic with no proof; the bot caps it with `BOT_MAX_FEE_RATE`, and a wallet shows the resulting fee before the user signs.
59
+ - 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. That tip is not a header dep, so a node can show a fresh tip from before the deadline and let an expired plan through; the cost is that extra cycle, time rather than CKB, which is accepted. Checking the priced header, a dep, plus the local clock's elapsed time would close it at the cost of estimating epochs from time.
60
+
61
+ `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.
62
+
63
+ ## Confirmation
64
+
65
+ `waitTransaction(client, txHash, { timeout?, interval?, signal? })` observes one already-broadcast transaction for a bounded window and resolves 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.
66
+
67
+ The client is polled with `get_transaction` verbosity 1. CCC's typed read hides a rejected transaction with a null body, so raw status is needed to preserve rejection evidence. The body is never read: no caller uses it, and a second answer from the same node would verify nothing.
68
+
69
+ 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.
70
+
71
+ 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.
72
+
73
+ 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.
74
+
75
+ ## Estimates and fees
76
+
77
+ [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.
78
+
79
+ ## Versioning and API checks
80
+
81
+ The repository follows [Epoch Semantic Versioning](https://antfu.me/posts/epoch-semver). The [release policy](../README.md#releases) explains this rewrite's starting version.
82
+
83
+ While the rewritten API has no outside consumers, its shape follows the stack's own rather than a committed API report, and a breaking change takes the next major version. 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
84
 
33
85
  ## Licensing
34
86
 
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).
87
+ 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,10 @@
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
+ * The managers of one network's iCKB deployment.
5
+ *
6
+ * @remarks Builders still return partial transactions. `IckbSdk` owns the shared iCKB
7
+ * completion path as `sdk.completeTransaction(...)`, which callers invoke before send.
8
+ */
9
+ export declare function getConfig(chain: SupportedChain): SdkManagers;
23
10
  //# 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;AAwDvD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,WAAW,CAoB5D"}
package/dist/constants.js CHANGED
@@ -1,95 +1,81 @@
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
+ /**
37
+ * Each network's iCKB dep group: it carries every iCKB script's code cell, xUDT's and
38
+ * iCKB Logic's included, so one group dep resolves them all.
39
+ */
40
+ const DEPLOYMENTS = {
41
+ mainnet: {
42
+ depGroup: {
43
+ txHash: "0x621a6f38de3b9f453016780edac3b26bfcbfa3e2ecb47c2da275471a5d3ed165",
44
+ index: 0,
45
+ },
86
46
  },
87
- ];
88
- const TESTNET_KNOWN_BOTS = [
89
- {
90
- codeHash: "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
91
- hashType: "type",
92
- args: "0xb4380110f7679ac31cefe4925485645d82bf619f",
47
+ testnet: {
48
+ depGroup: {
49
+ txHash: "0xf7ece4fb33d8378344cab11fcd6a4c6f382fd4207ac921cf5821f30712dcd311",
50
+ index: 0,
51
+ },
93
52
  },
94
- ];
53
+ };
54
+ /**
55
+ * The managers of one network's iCKB deployment.
56
+ *
57
+ * @remarks Builders still return partial transactions. `IckbSdk` owns the shared iCKB
58
+ * completion path as `sdk.completeTransaction(...)`, which callers invoke before send.
59
+ */
60
+ export function getConfig(chain) {
61
+ // The runtime check stands for callers outside TypeScript.
62
+ if (!Object.hasOwn(DEPLOYMENTS, chain)) {
63
+ throw new TypeError("unsupported iCKB network");
64
+ }
65
+ const { depGroup } = DEPLOYMENTS[chain];
66
+ const cellDeps = [ccc.CellDep.from({ outPoint: depGroup, depType: "depGroup" })];
67
+ const dao = { script: DAO, cellDeps };
68
+ const ickbUdt = new IckbUdt({
69
+ script: IckbUdt.typeScriptFrom(UDT, ICKB_LOGIC),
70
+ cellDeps,
71
+ logicScript: ICKB_LOGIC,
72
+ daoScript: DAO,
73
+ });
74
+ return {
75
+ ickbUdt,
76
+ ownedOwner: new OwnedOwnerManager(OWNED_OWNER, cellDeps, dao),
77
+ ickbLogic: new LogicManager(ICKB_LOGIC, cellDeps, dao),
78
+ order: new OrderManager(ORDER, cellDeps, ickbUdt.script),
79
+ };
80
+ }
95
81
  //# 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":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGnC,8BAA8B;AAC9B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,QAAQ,EAAE,oEAAoE;IAC9E,QAAQ,EAAE,MAAM;IAChB,IAAI,EAAE,IAAI;CACX,CAAC,CAAC;AAEH,oFAAoF;AACpF,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,QAAQ,EAAE,oEAAoE;IAC9E,QAAQ,EAAE,OAAO;IACjB,IAAI,EAAE,IAAI;CACX,CAAC,CAAC;AAEH,yBAAyB;AACzB,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IACjC,QAAQ,EAAE,oEAAoE;IAC9E,QAAQ,EAAE,OAAO;IACjB,IAAI,EAAE,IAAI;CACX,CAAC,CAAC;AAEH,+BAA+B;AAC/B,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAClC,QAAQ,EAAE,oEAAoE;IAC9E,QAAQ,EAAE,OAAO;IACjB,IAAI,EAAE,IAAI;CACX,CAAC,CAAC;AAEH,yBAAyB;AACzB,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAC5B,QAAQ,EAAE,oEAAoE;IAC9E,QAAQ,EAAE,OAAO;IACjB,IAAI,EAAE,IAAI;CACX,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,WAAW,GAAG;IAClB,OAAO,EAAE;QACP,QAAQ,EAAE;YACR,MAAM,EAAE,oEAAoE;YAC5E,KAAK,EAAE,CAAC;SACT;KACF;IACD,OAAO,EAAE;QACP,QAAQ,EAAE;YACR,MAAM,EAAE,oEAAoE;YAC5E,KAAK,EAAE,CAAC;SACT;KACF;CACO,CAAC;AAEX;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,2DAA2D;IAC3D,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,SAAS,CAAC,0BAA0B,CAAC,CAAC;IAClD,CAAC;IACD,MAAM,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;IACjF,MAAM,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;QAC1B,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC;QAC/C,QAAQ;QACR,WAAW,EAAE,UAAU;QACvB,SAAS,EAAE,GAAG;KACf,CAAC,CAAC;IACH,OAAO;QACL,OAAO;QACP,UAAU,EAAE,IAAI,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,GAAG,CAAC;QAC7D,SAAS,EAAE,IAAI,YAAY,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC;QACtD,KAAK,EAAE,IAAI,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC;KACzD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,33 @@
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
+ * The smallest request one direction accepts as an order at the current fee rate. A
19
+ * CKB-to-iCKB remainder pays the default order fee, which must cover the maturity threshold
20
+ * of ten mining fees; an iCKB-to-CKB remainder can give its whole CKB value as the dust
21
+ * fee, so its value must exceed the threshold. The extra unit covers the quote's rounding,
22
+ * as the dust search's boundary shows; callers round up further for display.
23
+ */
24
+ export declare function minimumOrderAmount(isCkb2Udt: boolean, system: SystemState): bigint;
25
+ /**
26
+ * The order leg of an iCKB-to-CKB conversion: at the default fee when that fee clears the
27
+ * maturity threshold, else the smallest fee that does (a dust order, noticed). Either way
28
+ * it is dated: a sell order at par is always covered by the pool (see `maturity`).
29
+ */
30
+ export declare function estimateIckbToCkbOrder(amounts: ValueComponents, system: SystemState, takenDeposits: readonly IckbDepositCell[]): (ConversionOrderEstimate & {
31
+ maturity: bigint;
32
+ }) | undefined;
33
+ //# 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;AAWD;;;;;;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
+ 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: the bot's turns start ten minutes apart.
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"}