@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
@@ -0,0 +1,113 @@
1
+ import { BOT_LOCK_UP, depositMaturity } from "../dao.js";
2
+ import { fillsWhole } from "../order/fill.js";
3
+ import { ckbFromUdt, ICKB_DEPOSIT_CAP } from "../udt.js";
4
+ import { ceilDiv, compareBigInt } from "../utils/utils.js";
5
+ /**
6
+ * Assumed turn duration: the bot's turns start ten minutes apart.
7
+ * This is a modeling interval, not a bound on the runtime; see sdk/docs/pool_maturity_estimates.md.
8
+ */
9
+ export const BOT_TURN_MS = 10n * 60n * 1000n;
10
+ /**
11
+ * The estimated fill time of an order on the book or about to be placed, zero when it is
12
+ * already fulfilled. `takenDeposits` are the pool deposits the same plan withdraws
13
+ * directly, which cannot fill its order leg too. Dual-ratio orders never reach here: the
14
+ * scan drops them.
15
+ */
16
+ export function maturity(o, system, takenDeposits = []) {
17
+ const { info, amounts, self } = maturityOrderParts(o);
18
+ const isCkb2Udt = info.isCkb2Udt();
19
+ const amount = isCkb2Udt ? amounts.ckbValue : amounts.udtValue;
20
+ if (amount === 0n) {
21
+ return 0n;
22
+ }
23
+ return isCkb2Udt
24
+ ? ckbToIckbOrderMaturity(info, amount, system, self)
25
+ : ickbToCkbOrderMaturity(info, amount, system, takenDeposits, self);
26
+ }
27
+ /** The order's terms, and its own out point when it is already on the book. */
28
+ function maturityOrderParts(o) {
29
+ if ("info" in o) {
30
+ return { ...o, self: undefined };
31
+ }
32
+ return {
33
+ info: o.data.info,
34
+ amounts: { ckbValue: o.ckbUnoccupied, udtValue: o.udtValue },
35
+ self: o.cell.outPoint,
36
+ };
37
+ }
38
+ /**
39
+ * A buyer waits for the bot to mint: the bot mints one cap-sized deposit per turn once its
40
+ * iCKB inventory is spent, and the inventory is unknown here, so the wait is one turn plus
41
+ * one per whole cap of positive net CKB demand (this request and buyers priced at least
42
+ * as well, less the iCKB sellers bring in). The model does not measure the bot's funds.
43
+ */
44
+ function ckbToIckbOrderMaturity(info, amount, system, self) {
45
+ // An equal price counts as ahead: the bot fills ties in an order of its own choosing.
46
+ const buyersAhead = fillableOrders(system, true, self)
47
+ .filter((group) => group.order.data.info.ckbToUdt.compare(info.ckbToUdt) <= 0)
48
+ .reduce((ckb, group) => ckb + group.order.ckbUnoccupied, 0n);
49
+ const sellers = fillableOrders(system, false, self).reduce((udt, group) => udt + group.udtValue, 0n);
50
+ const demand = amount + buyersAhead - ckbFromUdt(sellers, system.exchangeRatio);
51
+ const capCkb = ckbFromUdt(ICKB_DEPOSIT_CAP, system.exchangeRatio);
52
+ const turns = demand > 0n ? 1n + demand / capCkb : 1n;
53
+ return system.tip.timestamp + BOT_TURN_MS * turns;
54
+ }
55
+ /**
56
+ * A seller waits for CKB: one deposit's worth of assumed working capital, zeroed when
57
+ * another fillable seller has sat beyond the threshold, plus dated pool supply. Return
58
+ * the first date covering demand, plus a turn. Insufficient supply falls back to the last
59
+ * date; this can understate an above-par ask's wait for further DAO growth.
60
+ */
61
+ function ickbToCkbOrderMaturity(info, amount, system, takenDeposits, self) {
62
+ const sellers = fillableOrders(system, false, self);
63
+ const sellersAhead = sellers
64
+ .filter((group) => info.udtToCkb.compare(group.order.data.info.udtToCkb) <= 0)
65
+ .reduce((udt, group) => udt + group.udtValue, 0n);
66
+ // The CKB an order has already received belongs to its earlier fills; what it still
67
+ // needs is the remaining iCKB at its price.
68
+ const needed = ceilDiv(amount * info.udtToCkb.udtScale, info.udtToCkb.ckbScale) +
69
+ ckbFromUdt(sellersAhead, system.exchangeRatio);
70
+ const taken = new Set(takenDeposits.map((deposit) => deposit.cell.outPoint.toHex()));
71
+ const steps = [
72
+ {
73
+ ckbValue: sellers.some((group) => sits(group, system))
74
+ ? 0n
75
+ : ckbFromUdt(ICKB_DEPOSIT_CAP, system.exchangeRatio),
76
+ at: system.tip.timestamp,
77
+ },
78
+ // A claim the bot can no longer request in time rolls a cycle: the bot's rule, not the
79
+ // caller's, since the bot is the one making the requests.
80
+ ...system.poolDeposits
81
+ .filter((deposit) => !taken.has(deposit.cell.outPoint.toHex()))
82
+ .map((deposit) => ({
83
+ ckbValue: deposit.ckbValue,
84
+ at: depositMaturity(deposit.claimEpoch, system.tip, BOT_LOCK_UP).maturity.toUnix(system.tip),
85
+ }))
86
+ .toSorted((left, right) => compareBigInt(left.at, right.at)),
87
+ ];
88
+ let supply = 0n;
89
+ let at = system.tip.timestamp;
90
+ for (const step of steps) {
91
+ supply += step.ckbValue;
92
+ at = step.at;
93
+ if (supply >= needed) {
94
+ break;
95
+ }
96
+ }
97
+ return at + BOT_TURN_MS;
98
+ }
99
+ /** The book orders the bot would take whole in the given direction, this one aside. */
100
+ function fillableOrders(system, isCkb2Udt, self) {
101
+ return system.orderPool.filter((group) => (self === undefined || !group.order.cell.outPoint.eq(self)) &&
102
+ fillsWhole(group, isCkb2Udt, system.exchangeRatio, system.feeRate));
103
+ }
104
+ /**
105
+ * Whether the order has been on the book for more than an eighth of an epoch in blocks,
106
+ * about three ten-minute turns: the bot has seen it and left it. A turn alone left no
107
+ * margin, since an order placed just after a turn waits a turn to be seen, and a failed
108
+ * turn adds the restart delay.
109
+ */
110
+ function sits(group, { tip }) {
111
+ return tip.number - group.blockNumber > tip.epoch.denominator / 8n;
112
+ }
113
+ //# sourceMappingURL=maturity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maturity.js","sourceRoot":"","sources":["../../src/conversion/maturity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type IckbDepositCell } from "../logic.js";
2
+ import type { CkbToIckbConversionPlan, ConversionTransactionOptions, IckbToCkbConversionPlan } from "./types.js";
3
+ /**
4
+ * Plans every deposit count from the most the amount covers down to zero, skipping
5
+ * unrepresentable remainders. Cap-sized deposits plus an order for the rest is the cheapest
6
+ * shape at every amount: a deposit's 82 CKB of occupied capacity goes to its withdrawer
7
+ * (0.082% at the cap, 8.2% at the contract's 1,000 CKB minimum), the excess above the cap
8
+ * is discounted 10%, and an order costs 0.01% at any size; the cap's CKB value grows with
9
+ * the DAO rate, so the order stays cheaper until the cap is worth 820,000 CKB.
10
+ */
11
+ export declare function ckbToIckbConversionPlans(options: ConversionTransactionOptions): CkbToIckbConversionPlan[];
12
+ /**
13
+ * Plans every prefix of the greedy ready-deposit selection, longest first, the remainder as
14
+ * an order: direct withdrawals are free and their claim date certain, an order pays a fee
15
+ * and waits for the bot, so the completion walk takes the most direct plan it can fund.
16
+ * The prefix shape keeps ring classification frozen: a prefix of surplus deposits stays
17
+ * surplus with the same anchors pinned.
18
+ */
19
+ export declare function ickbToCkbConversionPlans(options: ConversionTransactionOptions, poolDeposits: readonly IckbDepositCell[]): IckbToCkbConversionPlan[];
20
+ //# sourceMappingURL=plans.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../../src/conversion/plans.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AASlE,OAAO,KAAK,EACV,uBAAuB,EAEvB,4BAA4B,EAC5B,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAWpB;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,4BAA4B,GACpC,uBAAuB,EAAE,CAgB3B;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,4BAA4B,EACrC,YAAY,EAAE,SAAS,eAAe,EAAE,GACvC,uBAAuB,EAAE,CAc3B"}
@@ -0,0 +1,106 @@
1
+ import { ccc } from "@ckb-ccc/core";
2
+ import { DAO_OUTPUT_LIMIT } from "../dao.js";
3
+ import { readyDeposits } from "../logic.js";
4
+ import { ICKB_DEPOSIT_CAP, ckbFromUdt } from "../udt.js";
5
+ import { DEFAULT_ORDER_FEE, DEFAULT_ORDER_FEE_BASE, estimateConversionOrder, estimateIckbToCkbOrder, } from "./estimate.js";
6
+ import { sumUdt } from "./projection.js";
7
+ import { fitWithdrawalDeposits, ringSurplusDepositFilter, sortByClaim, } from "./withdrawal_ring.js";
8
+ // The planner starts at the most `DAO_OUTPUT_LIMIT` can hold, one change output beside the
9
+ // deposits, and the completion walk steps down from there when change and fees need more room.
10
+ const MAX_PLANNED_DEPOSITS = DAO_OUTPUT_LIMIT - 1;
11
+ /**
12
+ * Plans every deposit count from the most the amount covers down to zero, skipping
13
+ * unrepresentable remainders. Cap-sized deposits plus an order for the rest is the cheapest
14
+ * shape at every amount: a deposit's 82 CKB of occupied capacity goes to its withdrawer
15
+ * (0.082% at the cap, 8.2% at the contract's 1,000 CKB minimum), the excess above the cap
16
+ * is discounted 10%, and an order costs 0.01% at any size; the cap's CKB value grows with
17
+ * the DAO rate, so the order stays cheaper until the cap is worth 820,000 CKB.
18
+ */
19
+ export function ckbToIckbConversionPlans(options) {
20
+ const { amount, context } = options;
21
+ const depositCapacity = ckbFromUdt(ICKB_DEPOSIT_CAP, context.system.exchangeRatio);
22
+ const depositQuotient = depositCapacity === 0n ? 0n : amount / depositCapacity;
23
+ const maxDeposits = depositQuotient > BigInt(MAX_PLANNED_DEPOSITS)
24
+ ? MAX_PLANNED_DEPOSITS
25
+ : Number(depositQuotient);
26
+ const plans = [];
27
+ for (let depositCount = maxDeposits; depositCount >= 0; depositCount -= 1) {
28
+ const plan = ckbToIckbConversionPlan(options, depositCapacity, depositCount);
29
+ if (plan !== undefined) {
30
+ plans.push(plan);
31
+ }
32
+ }
33
+ return plans;
34
+ }
35
+ /**
36
+ * Plans every prefix of the greedy ready-deposit selection, longest first, the remainder as
37
+ * an order: direct withdrawals are free and their claim date certain, an order pays a fee
38
+ * and waits for the bot, so the completion walk takes the most direct plan it can fund.
39
+ * The prefix shape keeps ring classification frozen: a prefix of surplus deposits stays
40
+ * surplus with the same anchors pinned.
41
+ */
42
+ export function ickbToCkbConversionPlans(options, poolDeposits) {
43
+ const { amount, context } = options;
44
+ const { tip, lockUp } = context.system;
45
+ const ready = readyDeposits(poolDeposits, tip, lockUp);
46
+ const isSurplus = ringSurplusDepositFilter(poolDeposits, ready);
47
+ const deposits = fitWithdrawalDeposits(sortByClaim(ready.filter(isSurplus)), amount);
48
+ const plans = [];
49
+ for (let count = deposits.length; count >= 0; count -= 1) {
50
+ const plan = ickbToCkbConversionPlan(options, deposits.slice(0, count));
51
+ if (plan !== undefined) {
52
+ plans.push(plan);
53
+ }
54
+ }
55
+ return plans;
56
+ }
57
+ function ckbToIckbConversionPlan(options, depositCapacity, depositCount) {
58
+ const { amount, context } = options;
59
+ const remainder = amount - depositCapacity * BigInt(depositCount);
60
+ let estimatedMaturity = context.estimatedMaturity;
61
+ let order;
62
+ if (remainder > 0n) {
63
+ const amounts = { ckbValue: remainder, udtValue: 0n };
64
+ const estimate = estimateConversionOrder(true, amounts, context.system, {
65
+ fee: DEFAULT_ORDER_FEE,
66
+ feeBase: DEFAULT_ORDER_FEE_BASE,
67
+ });
68
+ if (estimate?.maturity === undefined) {
69
+ return undefined;
70
+ }
71
+ estimatedMaturity = ccc.numMax(estimatedMaturity, estimate.maturity);
72
+ order = { amounts, estimate };
73
+ }
74
+ return {
75
+ depositCapacity,
76
+ depositCount,
77
+ estimatedMaturity,
78
+ ...(order === undefined ? {} : { order }),
79
+ };
80
+ }
81
+ function ickbToCkbConversionPlan(options, selectedDeposits) {
82
+ const { amount, context } = options;
83
+ let estimatedMaturity = context.estimatedMaturity;
84
+ // Selected deposits are ready, so their sampled claim is their date.
85
+ for (const deposit of selectedDeposits) {
86
+ estimatedMaturity = ccc.numMax(estimatedMaturity, deposit.claimEpoch.toUnix(context.system.tip));
87
+ }
88
+ const remainder = amount - sumUdt(selectedDeposits);
89
+ let order;
90
+ if (remainder > 0n) {
91
+ const amounts = { ckbValue: 0n, udtValue: remainder };
92
+ // The deposits this plan withdraws directly cannot fill its order leg too.
93
+ const estimate = estimateIckbToCkbOrder(amounts, context.system, selectedDeposits);
94
+ if (estimate === undefined) {
95
+ return undefined;
96
+ }
97
+ estimatedMaturity = ccc.numMax(estimatedMaturity, estimate.maturity);
98
+ order = { amounts, estimate };
99
+ }
100
+ return {
101
+ estimatedMaturity,
102
+ ...(order === undefined ? {} : { order }),
103
+ selectedDeposits,
104
+ };
105
+ }
106
+ //# sourceMappingURL=plans.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plans.js","sourceRoot":"","sources":["../../src/conversion/plans.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { OrderGroup } from "../order/cells.js";
2
+ import type { AccountAvailabilityProjection, AccountState, ConversionTransactionContextProjection, SystemState } from "./types.js";
3
+ /**
4
+ * Builds the conversion planner context from account state and the caller's own orders,
5
+ * split by what it will melt: fulfilled orders, buys the bot's whole-fill rule refuses,
6
+ * and orders past the age cutoff are collected and budgeted as account value; the rest
7
+ * stay on the book. DAO growth can make a waiting sell profitable later, so a sell waits
8
+ * for the age cutoff even when the bot would not fill it today.
9
+ */
10
+ export declare function projectConversionTransactionContext(system: SystemState, account: AccountState, orders: readonly OrderGroup[]): ConversionTransactionContextProjection;
11
+ /**
12
+ * Splits wallet-owned CKB and iCKB into immediately available and pending value.
13
+ */
14
+ export declare function projectAccountAvailability(account: AccountState, { available: availableOrders, pending: pendingOrders, }: {
15
+ available: OrderGroup[];
16
+ pending: OrderGroup[];
17
+ }): AccountAvailabilityProjection;
18
+ export declare function sumUdt(items: ReadonlyArray<{
19
+ udtValue: bigint;
20
+ }>): bigint;
21
+ //# sourceMappingURL=projection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../../src/conversion/projection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,OAAO,KAAK,EACV,6BAA6B,EAC7B,YAAY,EACZ,sCAAsC,EACtC,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,SAAS,UAAU,EAAE,GAC5B,sCAAsC,CA4BxC;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,YAAY,EACrB,EACE,SAAS,EAAE,eAAe,EAC1B,OAAO,EAAE,aAAa,GACvB,EAAE;IAAE,SAAS,EAAE,UAAU,EAAE,CAAC;IAAC,OAAO,EAAE,UAAU,EAAE,CAAA;CAAE,GACpD,6BAA6B,CAmC/B;AA2BD,wBAAgB,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,CAEzE"}
@@ -0,0 +1,94 @@
1
+ import { ccc } from "@ckb-ccc/core";
2
+ import { DAO_HEADER_INDEX_LIMIT } from "../dao.js";
3
+ import { isRefused, isStale } from "../order/fill.js";
4
+ import { maturity } from "./maturity.js";
5
+ /**
6
+ * Builds the conversion planner context from account state and the caller's own orders,
7
+ * split by what it will melt: fulfilled orders, buys the bot's whole-fill rule refuses,
8
+ * and orders past the age cutoff are collected and budgeted as account value; the rest
9
+ * stay on the book. DAO growth can make a waiting sell profitable later, so a sell waits
10
+ * for the age cutoff even when the bot would not fill it today.
11
+ */
12
+ export function projectConversionTransactionContext(system, account, orders) {
13
+ const collectable = (group) => group.order.isFulfilled() || isRefused(group, system) || isStale(group, system.tip);
14
+ const projection = projectAccountAvailability(account, {
15
+ available: orders.filter(collectable),
16
+ pending: orders.filter((group) => !collectable(group)),
17
+ });
18
+ const estimatedMaturity = ccc.numMax(system.tip.timestamp, ...projection.pendingWithdrawals.map((group) => group.owned.maturity.toUnix(system.tip)), ...projection.pendingOrders.map((group) => maturity(group.order, system)));
19
+ return {
20
+ projection,
21
+ context: {
22
+ system,
23
+ receipts: account.receipts,
24
+ readyWithdrawals: projection.readyWithdrawals,
25
+ availableOrders: projection.availableOrders,
26
+ cells: [...account.capacityCells, ...account.nativeUdtCells],
27
+ ckbAvailable: projection.ckbAvailable,
28
+ ickbAvailable: projection.ickbAvailable,
29
+ estimatedMaturity,
30
+ },
31
+ };
32
+ }
33
+ /**
34
+ * Splits wallet-owned CKB and iCKB into immediately available and pending value.
35
+ */
36
+ export function projectAccountAvailability(account, { available: availableOrders, pending: pendingOrders, }) {
37
+ const { readyWithdrawals, pendingWithdrawals } = splitWithdrawals(account.withdrawalGroups);
38
+ // An iCKB cell's capacity is the owner's CKB too: completion spends it like a plain cell.
39
+ const ckbNative = sumValues([...account.capacityCells, ...account.nativeUdtCells], (cell) => cell.cellOutput.capacity);
40
+ const ickbNative = sumValues(account.nativeUdtCells, (cell) => ccc.udtBalanceFrom(cell.outputData));
41
+ const ckbAvailable = ckbNative +
42
+ sumCkb(account.receipts) +
43
+ sumCkb(readyWithdrawals) +
44
+ sumCkb(availableOrders);
45
+ const ickbAvailable = ickbNative + sumUdt(account.receipts) + sumUdt(availableOrders);
46
+ const ckbPending = sumCkb(pendingWithdrawals) + sumCkb(pendingOrders);
47
+ const ickbPending = sumUdt(pendingOrders);
48
+ return {
49
+ ckbNative,
50
+ ickbNative,
51
+ ckbAvailable,
52
+ ickbAvailable,
53
+ ckbPending,
54
+ ickbPending,
55
+ ckbBalance: ckbAvailable + ckbPending,
56
+ ickbBalance: ickbAvailable + ickbPending,
57
+ readyWithdrawals,
58
+ pendingWithdrawals,
59
+ availableOrders,
60
+ pendingOrders,
61
+ };
62
+ }
63
+ /**
64
+ * `ready` is the batch one transaction can complete: the deployed DAO script addresses a
65
+ * withdrawal's deposit header only below `DAO_HEADER_INDEX_LIMIT`, and the builder puts
66
+ * those headers first, so matured withdrawals past that count wait a turn.
67
+ */
68
+ function splitWithdrawals(withdrawalGroups) {
69
+ const readyWithdrawals = [];
70
+ const pendingWithdrawals = [];
71
+ for (const group of withdrawalGroups) {
72
+ if (group.owned.isReady && readyWithdrawals.length < DAO_HEADER_INDEX_LIMIT) {
73
+ readyWithdrawals.push(group);
74
+ }
75
+ else {
76
+ pendingWithdrawals.push(group);
77
+ }
78
+ }
79
+ return { readyWithdrawals, pendingWithdrawals };
80
+ }
81
+ function sumCkb(items) {
82
+ return sumValues(items, (item) => item.ckbValue);
83
+ }
84
+ export function sumUdt(items) {
85
+ return sumValues(items, (item) => item.udtValue);
86
+ }
87
+ function sumValues(items, project) {
88
+ let total = 0n;
89
+ for (const item of items) {
90
+ total += project(item);
91
+ }
92
+ return total;
93
+ }
94
+ //# sourceMappingURL=projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection.js","sourceRoot":"","sources":["../../src/conversion/projection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,264 @@
1
+ import type { ccc } from "@ckb-ccc/core";
2
+ import type { BroadcastDeadline, LockUpPolicy } from "../dao.js";
3
+ import type { IckbDepositCell, LogicManager, ReceiptCell } from "../logic.js";
4
+ import type { OrderCell, OrderGroup } from "../order/cells.js";
5
+ import type { Info } from "../order/info.js";
6
+ import type { OrderManager } from "../order/order.js";
7
+ import type { Ratio } from "../order/ratio.js";
8
+ import type { OwnedOwnerManager, WithdrawalGroup } from "../owned_owner.js";
9
+ import type { IckbUdt, ProtocolCell } from "../udt.js";
10
+ import type { ValueComponents } from "../utils/utils.js";
11
+ /**
12
+ * Direction requested by a conversion transaction.
13
+ */
14
+ export type ConversionDirection = "ckb-to-ickb" | "ickb-to-ckb";
15
+ /**
16
+ * Snapshot used to plan one wallet conversion transaction.
17
+ */
18
+ export interface ConversionTransactionContext {
19
+ /** Public system state sampled for conversion planning. */
20
+ system: SystemState;
21
+ /** User receipt cells available for deposit completion. */
22
+ receipts: ReceiptCell[];
23
+ /** User withdrawal groups ready to complete. */
24
+ readyWithdrawals: WithdrawalGroup[];
25
+ /** Order groups available for collection or budgeting as account value. */
26
+ availableOrders: OrderGroup[];
27
+ /** The wallet's liquid cells, plain CKB and iCKB, that completion funds from and sweeps. */
28
+ cells: ccc.Cell[];
29
+ /** Projected CKB available to the wallet after pending state is considered. */
30
+ ckbAvailable: bigint;
31
+ /** Projected iCKB available to the wallet after pending state is considered. */
32
+ ickbAvailable: bigint;
33
+ /**
34
+ * The latest date at which everything the wallet has converting, plus this request, is
35
+ * collectable; an amount of zero is the collection itself.
36
+ */
37
+ estimatedMaturity: bigint;
38
+ }
39
+ /**
40
+ * Inputs and policy limits for building one conversion transaction.
41
+ */
42
+ export interface ConversionTransactionOptions {
43
+ /** Conversion direction to build. */
44
+ direction: ConversionDirection;
45
+ /** Requested input amount in the source asset. */
46
+ amount: bigint;
47
+ /**
48
+ * Lock that owns every cell the transaction creates for the user, the conversion outputs
49
+ * and the change; the signer's recommended lock by default. Completion sweeps the liquid
50
+ * cells along within its input limit, so a foreign lock redirects those funds too.
51
+ */
52
+ lock?: ccc.Script;
53
+ /** Signer whose committed cells fund the completed transaction. */
54
+ signer: ccc.Signer;
55
+ /** Sampled state used to plan this conversion. */
56
+ context: ConversionTransactionContext;
57
+ }
58
+ /**
59
+ * Reason a conversion transaction could not be built without throwing.
60
+ */
61
+ export type ConversionTransactionFailureReason = "amount-negative" | "insufficient-ckb" | "insufficient-ickb" | "amount-too-small" | "nothing-to-do";
62
+ /**
63
+ * A dust iCKB-to-CKB order: too small for the default fee to clear the estimate threshold,
64
+ * so it pays the smallest fee that does. For callers to surface in UI or logs.
65
+ */
66
+ export interface ConversionNotice {
67
+ /** iCKB input amount that triggered the notice. */
68
+ inputIckb: bigint;
69
+ /** CKB output estimate for the noticed path. */
70
+ outputCkb: bigint;
71
+ /** CKB incentive associated with the noticed path. */
72
+ incentiveCkb: bigint;
73
+ }
74
+ /** Composition category selected for a built conversion. */
75
+ export type ConversionKind = "direct" | "order" | "direct-plus-order" | "collect-only";
76
+ /**
77
+ * Result of attempting to build a conversion transaction.
78
+ */
79
+ export type ConversionTransactionResult = {
80
+ ok: true;
81
+ /** Completed transaction, funded from the signer's committed cells. Callers own signing and send. */
82
+ tx: ccc.Transaction;
83
+ /** Estimated maturity timestamp for the conversion result. */
84
+ estimatedMaturity: bigint;
85
+ /** Composition of the selected conversion path. */
86
+ conversionKind: ConversionKind;
87
+ /** Optional notice about the selected path. */
88
+ conversionNotice?: ConversionNotice;
89
+ /**
90
+ * True when every liquid cell of the context is an input. False when the input limit
91
+ * left some behind: a move to another lock then needs another transaction.
92
+ */
93
+ isSweepComplete: boolean;
94
+ /**
95
+ * The epoch the transaction must be broadcast before for its withdrawal requests to
96
+ * claim at their sampled dates (`system.lockUp`); absent when it requests none.
97
+ */
98
+ broadcastBefore?: BroadcastDeadline;
99
+ } | {
100
+ ok: false;
101
+ reason: "amount-too-small";
102
+ /** Best available maturity estimate from the input context. */
103
+ estimatedMaturity: bigint;
104
+ /**
105
+ * The smallest amount this direction accepts at the current fee rate, in the
106
+ * request's unit (CKB shannons or iCKB), so a caller can name it.
107
+ */
108
+ minimum: bigint;
109
+ } | {
110
+ ok: false;
111
+ /** Machine-readable failure reason. */
112
+ reason: Exclude<ConversionTransactionFailureReason, "amount-too-small">;
113
+ /** Best available maturity estimate from the input context. */
114
+ estimatedMaturity: bigint;
115
+ };
116
+ /**
117
+ * Options for completing a partial iCKB transaction before signing and sending.
118
+ */
119
+ export interface CompleteIckbTransactionOptions {
120
+ /** Signer that prepares the transaction; its recommended lock owns the change by default. */
121
+ signer: ccc.Signer;
122
+ /** Lock that owns the change, iCKB and plain, when not the signer's recommended lock. */
123
+ lock?: ccc.Script;
124
+ /** Fee rate passed to CCC fee completion. */
125
+ feeRate: ccc.Num;
126
+ /** The signer's known liquid cells, plain CKB and iCKB, from the account state already read. */
127
+ cells: ccc.Cell[];
128
+ /**
129
+ * The receipts and iCKB deposits the transaction may spend, valued by the state read;
130
+ * any superset works, since only the spent ones are summed.
131
+ */
132
+ protocolCells: readonly ProtocolCell[];
133
+ /**
134
+ * The header the plan was priced at, the state read's `system.tip`, named as a header
135
+ * dep: the chain refuses a transaction whose deps are off the main chain, so a header a
136
+ * node invented, whose DAO rate set the exchange ratio, cannot price an accepted
137
+ * transaction.
138
+ */
139
+ tip: ccc.ClientBlockHeader;
140
+ }
141
+ /**
142
+ * Quote details for one order-based conversion path.
143
+ */
144
+ export interface ConversionOrderEstimate {
145
+ /** Output amount after applying the order ratio and fee. */
146
+ convertedAmount: ccc.FixedPoint;
147
+ /** CKB fee component embedded in the order conversion. */
148
+ ckbFee: ccc.FixedPoint;
149
+ /** Order info that should be encoded into a created order. */
150
+ info: Info;
151
+ /** Estimated maturity timestamp, or `undefined` when it cannot be estimated. */
152
+ maturity: ccc.Num | undefined;
153
+ /** A non-fatal notice about the path this estimate took, for the caller to surface. */
154
+ notice?: ConversionNotice;
155
+ }
156
+ /**
157
+ * Input accepted by maturity estimation, either a live order cell or raw order data plus values.
158
+ */
159
+ export type MaturityOrderInput = OrderCell | {
160
+ info: Info;
161
+ amounts: ValueComponents;
162
+ };
163
+ /**
164
+ * Raw wallet-owned cells and grouped iCKB state sampled from L1.
165
+ */
166
+ export interface AccountState {
167
+ /** Plain capacity cells owned by the account locks. */
168
+ capacityCells: ccc.Cell[];
169
+ /** Native iCKB xUDT cells owned by the account locks. */
170
+ nativeUdtCells: ccc.Cell[];
171
+ /** Receipt cells owned by the account. */
172
+ receipts: ReceiptCell[];
173
+ /** Withdrawal groups owned by the account. */
174
+ withdrawalGroups: WithdrawalGroup[];
175
+ }
176
+ /**
177
+ * Account balances split into available, pending, and order/withdrawal buckets.
178
+ */
179
+ export interface AccountAvailabilityProjection {
180
+ /**
181
+ * CKB in the account's liquid cells, plain and iCKB alike: what the wallet shows and what
182
+ * the next transaction spends, before the change cells, an order's master cell and the
183
+ * fee it must fund on top.
184
+ */
185
+ ckbNative: bigint;
186
+ /** iCKB in the account's native iCKB cells. */
187
+ ickbNative: bigint;
188
+ /** `ckbNative` plus the CKB the receipts, ready withdrawals and collectable orders return. */
189
+ ckbAvailable: bigint;
190
+ /** `ickbNative` plus the iCKB the receipts and collectable orders return. */
191
+ ickbAvailable: bigint;
192
+ /** CKB pending in withdrawals or orders. */
193
+ ckbPending: bigint;
194
+ /** iCKB pending in withdrawals or orders. */
195
+ ickbPending: bigint;
196
+ /** Total CKB balance including pending positions. */
197
+ ckbBalance: bigint;
198
+ /** Total iCKB balance including pending positions. */
199
+ ickbBalance: bigint;
200
+ /**
201
+ * Matured withdrawal groups one transaction can complete: at most the deposit-header slots
202
+ * the DAO script addresses (`DAO_HEADER_INDEX_LIMIT`), which the deposit headers hold alone.
203
+ */
204
+ readyWithdrawals: WithdrawalGroup[];
205
+ /** Withdrawal groups still waiting for DAO maturity or for a header slot in a later turn. */
206
+ pendingWithdrawals: WithdrawalGroup[];
207
+ /** Order groups available for collection or budgeting as account value. */
208
+ availableOrders: OrderGroup[];
209
+ /** Order groups that are owned but unavailable or unresolved. */
210
+ pendingOrders: OrderGroup[];
211
+ }
212
+ /**
213
+ * Combined projection and transaction-planning context for one sampled account state.
214
+ */
215
+ export interface ConversionTransactionContextProjection {
216
+ /** User-facing availability projection. */
217
+ projection: AccountAvailabilityProjection;
218
+ /** Builder-facing transaction context derived from the same sampled state. */
219
+ context: ConversionTransactionContext;
220
+ }
221
+ /**
222
+ * Public sampled system state used for quotes, maturity, and conversion planning.
223
+ */
224
+ export interface SystemState {
225
+ /** The fee rate for transactions. */
226
+ feeRate: ccc.Num;
227
+ /** The sampled tip's parent, this L1 scan's anchor. It may be stale after scans complete. */
228
+ tip: ccc.ClientBlockHeader;
229
+ /** The exchange ratio between CKB and UDT. */
230
+ exchangeRatio: Ratio;
231
+ /** Every order past par on the book, the wallet's own included: what the bot can fill. */
232
+ orderPool: OrderGroup[];
233
+ /** Every iCKB pool deposit with its claim epoch at this tip: the CKB supply. */
234
+ poolDeposits: IckbDepositCell[];
235
+ /** The caller's withdrawal timing rules, which every builder and the sender follow. */
236
+ lockUp: LockUpPolicy;
237
+ }
238
+ /** Manager set that builds one iCKB SDK instance. */
239
+ export interface SdkManagers {
240
+ /** iCKB xUDT manager with receipt and DAO deposit aware completion. */
241
+ ickbUdt: IckbUdt;
242
+ /** Owned-owner manager for withdrawal request and claim cells. */
243
+ ownedOwner: OwnedOwnerManager;
244
+ /** iCKB Logic manager for deposits and receipts. */
245
+ ickbLogic: LogicManager;
246
+ /** Limit order manager. */
247
+ order: OrderManager;
248
+ }
249
+ export interface ConversionOrder {
250
+ amounts: ValueComponents;
251
+ estimate: ConversionOrderEstimate;
252
+ }
253
+ export interface CkbToIckbConversionPlan {
254
+ depositCapacity: bigint;
255
+ depositCount: number;
256
+ estimatedMaturity: bigint;
257
+ order?: ConversionOrder;
258
+ }
259
+ export interface IckbToCkbConversionPlan {
260
+ estimatedMaturity: bigint;
261
+ order?: ConversionOrder;
262
+ selectedDeposits: IckbDepositCell[];
263
+ }
264
+ //# sourceMappingURL=types.d.ts.map