@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/dist/logic.js ADDED
@@ -0,0 +1,173 @@
1
+ import { ccc } from "@ckb-ccc/core";
2
+ import { assertDaoOutputLimit, DAO_DEPOSIT_DATA, DaoOutputLimitError, depositMaturity, isDaoDeposit, pushHeaderDep, } from "./dao.js";
3
+ import { decodeReceiptData, encodeReceiptData, IckbUdt, ickbValue, receiptDataBytes, } from "./udt.js";
4
+ import { findCells, headersByNumber, } from "./utils/utils.js";
5
+ const maxDepositQuantity = 63;
6
+ // Receipts must carry enough capacity for phase 2 when the wallet has no other
7
+ // CKB: one iCKB xUDT cell, one plain capacity cell, and the fee reserve.
8
+ const phase2TxFeeReserve = ccc.One;
9
+ /**
10
+ * Manages logic related to deposits and receipts in the blockchain.
11
+ */
12
+ export class LogicManager {
13
+ /** The iCKB Logic script used as receipt type and DAO deposit lock. */
14
+ script;
15
+ /** Cell dependencies required to execute the iCKB Logic script. */
16
+ cellDeps;
17
+ /** The Nervos DAO script the deposits carry, with its cell deps. */
18
+ dao;
19
+ /** Creates the manager for one iCKB Logic deployment over one DAO deployment. */
20
+ constructor(script, cellDeps, dao) {
21
+ this.script = script;
22
+ this.cellDeps = cellDeps;
23
+ this.dao = dao;
24
+ }
25
+ /** Whether the cell is an iCKB receipt: typed by the logic script with a decodable prefix. */
26
+ isReceipt(cell) {
27
+ return (cell.cellOutput.type?.eq(this.script) === true &&
28
+ ccc.bytesFrom(cell.outputData).length >= receiptDataBytes);
29
+ }
30
+ /** Whether the cell is a DAO deposit locked by the logic script. */
31
+ isDeposit(cell) {
32
+ return isDaoDeposit(cell, this.dao.script) && cell.cellOutput.lock.eq(this.script);
33
+ }
34
+ /**
35
+ * Adds `depositQuantity` DAO deposits of `depositCapacity` locked by the logic script,
36
+ * then the receipt that mints their iCKB in phase 2, locked by `lock`.
37
+ *
38
+ * @remarks Completion (`IckbSdk.completeTransaction`) adds the dep group that also
39
+ * resolves the xUDT script.
40
+ */
41
+ deposit(txLike, depositQuantity, depositCapacity, lock) {
42
+ // A zero quantity would mint a receipt for no deposits, which iCKB Logic refuses on chain.
43
+ if (!Number.isSafeInteger(depositQuantity) || depositQuantity <= 0) {
44
+ throw new TypeError("iCKB deposit quantity must be a positive safe integer");
45
+ }
46
+ const tx = ccc.Transaction.from(txLike);
47
+ if (depositQuantity > maxDepositQuantity) {
48
+ // The completion walk steps a plan down on this error.
49
+ throw new DaoOutputLimitError(tx.outputs.length + depositQuantity + 1);
50
+ }
51
+ const depositCell = ccc.Cell.from({
52
+ previousOutput: { txHash: `0x${"00".repeat(32)}`, index: 0 },
53
+ cellOutput: { capacity: depositCapacity, lock: this.script, type: this.dao.script },
54
+ outputData: DAO_DEPOSIT_DATA,
55
+ });
56
+ const depositAmount = depositCell.capacityFree;
57
+ if (depositAmount < ccc.fixedPointFrom(1000)) {
58
+ throw new Error("iCKB deposit minimum is 1000 CKB free capacity (1082 CKB total capacity)");
59
+ }
60
+ if (depositAmount > ccc.fixedPointFrom(1000000)) {
61
+ throw new Error("iCKB deposit maximum is 1000000 CKB free capacity (1000082 CKB total capacity)");
62
+ }
63
+ tx.addCellDeps(this.cellDeps);
64
+ tx.addCellDeps(this.dao.cellDeps);
65
+ for (let i = 0; i < depositQuantity; i += 1) {
66
+ tx.addOutput(depositCell.cellOutput, depositCell.outputData);
67
+ }
68
+ // Receipts track the deposit's free capacity, not the full DAO cell capacity.
69
+ tx.addOutput({ capacity: receiptPhase2Capacity(lock), lock, type: this.script }, encodeReceiptData({ depositQuantity: BigInt(depositQuantity), depositAmount }));
70
+ assertDaoOutputLimit(tx, this.dao.script);
71
+ return tx;
72
+ }
73
+ /**
74
+ * Adds receipt inputs and their deposit header deps for iCKB deposit completion.
75
+ *
76
+ * @remarks This prepares the phase-2 inputs; the iCKB they mint is completed by
77
+ * `IckbSdk.completeTransaction`.
78
+ */
79
+ completeDeposit(txLike, receipts) {
80
+ const tx = ccc.Transaction.from(txLike);
81
+ if (receipts.length === 0) {
82
+ return tx;
83
+ }
84
+ for (const receipt of receipts) {
85
+ const outPoint = receipt.cell.outPoint.toHex();
86
+ if (!this.isReceipt(receipt.cell)) {
87
+ throw new Error(`Receipt ${outPoint} is not an iCKB receipt for this logic script`);
88
+ }
89
+ }
90
+ tx.addCellDeps(this.cellDeps);
91
+ for (const receipt of receipts) {
92
+ pushHeaderDep(tx, receipt.header.hash);
93
+ tx.addInput(receipt.cell);
94
+ }
95
+ return tx;
96
+ }
97
+ /**
98
+ * The receipts among `cells`, valued at their deposit headers, each header read once.
99
+ */
100
+ async receiptsFrom(client, cells) {
101
+ const receipts = cells.filter(({ cell }) => this.isReceipt(cell));
102
+ const headers = await headersByNumber(client, receipts.map(({ blockNumber }) => blockNumber));
103
+ return receipts.map(({ cell, blockNumber }) =>
104
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- every receipt's block was read above.
105
+ receiptCell(cell, headers.get(blockNumber)));
106
+ }
107
+ /**
108
+ * Every live iCKB deposit, valued at its deposit header, with its claim epoch at the tip;
109
+ * each deposit block's header is read once.
110
+ */
111
+ async findDeposits(client, tip) {
112
+ const cells = (await findCells(client, {
113
+ script: this.script,
114
+ scriptType: "lock",
115
+ filter: {
116
+ script: this.dao.script,
117
+ outputData: DAO_DEPOSIT_DATA,
118
+ outputDataSearchMode: "exact",
119
+ },
120
+ scriptSearchMode: "exact",
121
+ withData: true,
122
+ })).filter(({ cell }) => this.isDeposit(cell));
123
+ const headers = await headersByNumber(client, cells.map(({ blockNumber }) => blockNumber));
124
+ return cells.map(({ cell, blockNumber }) =>
125
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- every deposit's block was read above.
126
+ ickbDepositCell(cell, headers.get(blockNumber), tip));
127
+ }
128
+ }
129
+ /** Values a DAO deposit cell at its deposit header and samples its claim epoch at the tip. */
130
+ function ickbDepositCell(cell, header, tip) {
131
+ const interests = ccc.calcDaoProfit(cell.capacityFree, header, tip);
132
+ return {
133
+ cell,
134
+ header,
135
+ claimEpoch: ccc.calcDaoClaimEpoch(header, tip),
136
+ ckbValue: cell.cellOutput.capacity + interests,
137
+ udtValue: ickbValue(cell.capacityFree, header),
138
+ };
139
+ }
140
+ /** The deposits a withdrawal request made now may claim at their sampled dates under the policy. */
141
+ export function readyDeposits(deposits, tip, policy) {
142
+ return deposits.filter((deposit) => depositMaturity(deposit.claimEpoch, tip, policy).isReady);
143
+ }
144
+ /** Decodes a receipt cell and values it at its deposit header. */
145
+ export function receiptCell(cell, header) {
146
+ let receipt;
147
+ try {
148
+ receipt = decodeReceiptData(cell.outputData);
149
+ }
150
+ catch (error) {
151
+ throw new Error(`Invalid iCKB receipt payload at ${cell.outPoint.toHex()}: ${cell.outputData}`, { cause: error });
152
+ }
153
+ return {
154
+ cell,
155
+ header,
156
+ ckbValue: cell.cellOutput.capacity,
157
+ udtValue: ickbValue(receipt.depositAmount, header) * receipt.depositQuantity,
158
+ };
159
+ }
160
+ /**
161
+ * Returns the CKB needed for the two phase-2 outputs created by one receipt.
162
+ *
163
+ * @remarks The value is sized with the actual user lock because lock args affect
164
+ * occupied capacity. It includes one plain output, one xUDT output, and the
165
+ * phase-2 fee reserve.
166
+ */
167
+ export function receiptPhase2Capacity(lock) {
168
+ // Capacity is measured with the actual user lock. Lock args are wallet-specific
169
+ // and can make both phase-2 outputs larger than protocol-only examples.
170
+ const plainCellCapacity = BigInt(8 + lock.occupiedSize) * ccc.One;
171
+ return plainCellCapacity + IckbUdt.minimumXudtCellCapacity(lock) + phase2TxFeeReserve;
172
+ }
173
+ //# sourceMappingURL=logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logic.js","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,168 @@
1
+ import type { ccc } from "@ckb-ccc/core";
2
+ import type { ValueComponents } from "../utils/utils.js";
3
+ import { OrderData } from "./order_data.js";
4
+ /**
5
+ * Represents a parsed order cell on the blockchain.
6
+ *
7
+ * Implements `ValueComponents` to expose the cell's raw data and its
8
+ * value breakdown (CKB and UDT).
9
+ */
10
+ export declare class OrderCell implements ValueComponents {
11
+ /** Raw live cell that carries the order lock and UDT type. */
12
+ readonly cell: ccc.Cell;
13
+ /** Decoded order payload from `cell.outputData`. */
14
+ readonly data: OrderData;
15
+ /** CKB capacity available for matching after occupied capacity is reserved. */
16
+ readonly ckbUnoccupied: ccc.FixedPoint;
17
+ /** Absolute total order value in the order's comparison units. */
18
+ readonly absTotal: ccc.Num;
19
+ /** Absolute matched progress in the order's comparison units. */
20
+ readonly absProgress: ccc.Num;
21
+ constructor({ cell, data, ckbUnoccupied, absTotal, absProgress, }: {
22
+ cell: ccc.Cell;
23
+ data: OrderData;
24
+ ckbUnoccupied: ccc.FixedPoint;
25
+ absTotal: ccc.Num;
26
+ absProgress: ccc.Num;
27
+ });
28
+ /**
29
+ * Gets the order CKB amount.
30
+ *
31
+ * @returns The CKB amount as a `ccc.FixedPoint`.
32
+ */
33
+ get ckbValue(): ccc.FixedPoint;
34
+ /**
35
+ * Gets the order UDT amount.
36
+ *
37
+ * @returns The UDT amount as a `ccc.FixedPoint`.
38
+ */
39
+ get udtValue(): ccc.FixedPoint;
40
+ /**
41
+ * Attempts to parse an OrderCell from a raw cell.
42
+ *
43
+ * Returns `undefined` if parsing or validation fails.
44
+ *
45
+ * @param cell - The raw chain cell to convert.
46
+ * @returns An `OrderCell` instance or `undefined`.
47
+ */
48
+ static tryFrom(cell: ccc.Cell): OrderCell | undefined;
49
+ /**
50
+ * Parses and validates a raw cell as OrderCell.
51
+ *
52
+ * Throws if the cell is invalid or data validation fails.
53
+ *
54
+ * @param cell - The raw chain cell to convert.
55
+ * @returns A new `OrderCell` instance.
56
+ * @throws When decoding or validation fails.
57
+ */
58
+ static mustFrom(cell: ccc.Cell): OrderCell;
59
+ /**
60
+ * Checks whether the CKB-to-UDT side is enabled and has nonzero inventory.
61
+ *
62
+ * @remarks Executable-match checks for fee, minimum output, and ratio bounds happen during matching.
63
+ */
64
+ isCkb2UdtMatchable(): boolean;
65
+ /**
66
+ * Checks whether the UDT-to-CKB side is enabled and has nonzero inventory.
67
+ *
68
+ * @remarks Executable-match checks for fee, minimum output, and ratio bounds happen during matching.
69
+ */
70
+ isUdt2CkbMatchable(): boolean;
71
+ /** Returns true when either side is enabled and has nonzero inventory. */
72
+ isMatchable(): boolean;
73
+ /**
74
+ * Checks if the order is fulfilled.
75
+ *
76
+ * @returns True if the order is fulfilled (not matchable), otherwise false.
77
+ */
78
+ isFulfilled(): boolean;
79
+ /**
80
+ * Retrieves the master out point of the order.
81
+ * @returns The master out point associated with the order.
82
+ */
83
+ getMaster(): ccc.OutPoint;
84
+ /**
85
+ * Whether `descendant` can be this origin order's live continuation.
86
+ *
87
+ * @remarks
88
+ * This confusion-attack guard requires the same order script, UDT type,
89
+ * master, and info, while forbidding lower total value or lower progress.
90
+ * See {@link https://github.com/ickb/whitepaper/issues/19}.
91
+ */
92
+ isValid(descendant: OrderCell): boolean;
93
+ /**
94
+ * Resolves the best valid descendant order.
95
+ *
96
+ * @remarks
97
+ * The genuine mint origin is the immutable validation baseline. Resolution
98
+ * prefers greater progress and then greater total value; candidate identity is
99
+ * irrelevant. Equal-score non-mint candidates are ambiguous, while the mint
100
+ * origin wins an equal-score tie when it is still live.
101
+ */
102
+ resolve(descendants: OrderCell[]): OrderCell | undefined;
103
+ }
104
+ /**
105
+ * Represents a master cell
106
+ */
107
+ export declare class MasterCell {
108
+ /** Raw live master cell that anchors an order group. */
109
+ readonly cell: ccc.Cell;
110
+ /**
111
+ * Creates an instance of MasterCell.
112
+ * @param cell - The ccc.Cell instance to be wrapped by the MasterCell.
113
+ */
114
+ constructor(cell: ccc.Cell);
115
+ /** Whether this master anchors `order`: its type is the order script and the order names it. */
116
+ anchors(order: OrderCell): boolean;
117
+ }
118
+ /**
119
+ * Represents a group of orders associated with a master cell.
120
+ */
121
+ export declare class OrderGroup implements ValueComponents {
122
+ /** Master cell that authorizes and anchors the current order. */
123
+ readonly master: MasterCell;
124
+ /** Current resolved order cell. */
125
+ readonly order: OrderCell;
126
+ /** Origin order used to validate descendant progress and identity. */
127
+ readonly origin: OrderCell;
128
+ /** The block that committed the origin and its master: how long the order has been on the book. */
129
+ readonly blockNumber: ccc.Num;
130
+ /**
131
+ * Creates an instance of OrderGroup.
132
+ * @param master - The master cell associated with the order group.
133
+ * @param order - The order within the group.
134
+ * @param origin - The original order associated with the group.
135
+ * @param blockNumber - The block that committed the origin and its master.
136
+ */
137
+ constructor(master: MasterCell, order: OrderCell, origin: OrderCell, blockNumber: ccc.Num);
138
+ /**
139
+ * Gets the CKB value of the group.
140
+ *
141
+ * @returns The total CKB amount as a `ccc.FixedPoint`, which is the sum of the CKB values of the order cell and the master cell.
142
+ */
143
+ get ckbValue(): ccc.FixedPoint;
144
+ /**
145
+ * Gets the UDT value of the group.
146
+ *
147
+ * @returns The UDT amount as a `ccc.FixedPoint`, derived from the order cell.
148
+ */
149
+ get udtValue(): ccc.FixedPoint;
150
+ /**
151
+ * Tries to create an OrderGroup from the provided parameters.
152
+ * @param master - The master cell.
153
+ * @param order - The order within the group.
154
+ * @param origin - The original order.
155
+ * @returns An OrderGroup instance or undefined if creation fails.
156
+ */
157
+ static tryFrom(master: MasterCell, order: OrderCell, origin: OrderCell, blockNumber: ccc.Num): OrderGroup | undefined;
158
+ /** Whether the master anchors both orders and the order continues its origin. */
159
+ isValid(): boolean;
160
+ /**
161
+ * Checks if the specified lock is the owner of the master cell.
162
+ *
163
+ * @param locks - The locks to check ownership against.
164
+ * @returns True if the lock is the owner, otherwise false.
165
+ */
166
+ isOwner(...locks: ccc.Script[]): boolean;
167
+ }
168
+ //# sourceMappingURL=cells.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cells.d.ts","sourceRoot":"","sources":["../../src/order/cells.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,309 @@
1
+ import { OrderData } from "./order_data.js";
2
+ /**
3
+ * Represents a parsed order cell on the blockchain.
4
+ *
5
+ * Implements `ValueComponents` to expose the cell's raw data and its
6
+ * value breakdown (CKB and UDT).
7
+ */
8
+ export class OrderCell {
9
+ /** Raw live cell that carries the order lock and UDT type. */
10
+ cell;
11
+ /** Decoded order payload from `cell.outputData`. */
12
+ data;
13
+ /** CKB capacity available for matching after occupied capacity is reserved. */
14
+ ckbUnoccupied;
15
+ /** Absolute total order value in the order's comparison units. */
16
+ absTotal;
17
+ /** Absolute matched progress in the order's comparison units. */
18
+ absProgress;
19
+ constructor({ cell, data, ckbUnoccupied, absTotal, absProgress, }) {
20
+ this.cell = cell;
21
+ this.data = data;
22
+ this.ckbUnoccupied = ckbUnoccupied;
23
+ this.absTotal = absTotal;
24
+ this.absProgress = absProgress;
25
+ }
26
+ /**
27
+ * Gets the order CKB amount.
28
+ *
29
+ * @returns The CKB amount as a `ccc.FixedPoint`.
30
+ */
31
+ get ckbValue() {
32
+ return this.cell.cellOutput.capacity;
33
+ }
34
+ /**
35
+ * Gets the order UDT amount.
36
+ *
37
+ * @returns The UDT amount as a `ccc.FixedPoint`.
38
+ */
39
+ get udtValue() {
40
+ return this.data.udtValue;
41
+ }
42
+ /**
43
+ * Attempts to parse an OrderCell from a raw cell.
44
+ *
45
+ * Returns `undefined` if parsing or validation fails.
46
+ *
47
+ * @param cell - The raw chain cell to convert.
48
+ * @returns An `OrderCell` instance or `undefined`.
49
+ */
50
+ static tryFrom(cell) {
51
+ try {
52
+ return OrderCell.mustFrom(cell);
53
+ }
54
+ catch {
55
+ return undefined;
56
+ }
57
+ }
58
+ /**
59
+ * Parses and validates a raw cell as OrderCell.
60
+ *
61
+ * Throws if the cell is invalid or data validation fails.
62
+ *
63
+ * @param cell - The raw chain cell to convert.
64
+ * @returns A new `OrderCell` instance.
65
+ * @throws When decoding or validation fails.
66
+ */
67
+ static mustFrom(cell) {
68
+ let data;
69
+ try {
70
+ data = OrderData.decode(cell.outputData);
71
+ data.validate();
72
+ }
73
+ catch (error) {
74
+ throw new Error(`Invalid order payload at ${cell.outPoint.toHex()}`, {
75
+ cause: error,
76
+ });
77
+ }
78
+ const udtValue = data.udtValue;
79
+ const ckbUnoccupied = cell.capacityFree;
80
+ const { ckbToUdt, udtToCkb } = data.info;
81
+ const isCkb2Udt = data.info.isCkb2Udt();
82
+ const isUdt2Ckb = data.info.isUdt2Ckb();
83
+ const isDualRatio = isCkb2Udt && isUdt2Ckb;
84
+ // Compute total values in base units
85
+ const ckb2UdtValue = isCkb2Udt
86
+ ? ckbUnoccupied * ckbToUdt.ckbScale + udtValue * ckbToUdt.udtScale
87
+ : 0n;
88
+ const udt2CkbValue = isUdt2Ckb
89
+ ? ckbUnoccupied * udtToCkb.ckbScale + udtValue * udtToCkb.udtScale
90
+ : 0n;
91
+ const absTotal = absoluteOrderTotal(ckb2UdtValue, udt2CkbValue, data.info);
92
+ // What the order already holds of its output side; a dual-ratio order is complete.
93
+ let absProgress = ckbUnoccupied * udtToCkb.ckbScale;
94
+ if (isDualRatio) {
95
+ absProgress = absTotal;
96
+ }
97
+ else if (isCkb2Udt) {
98
+ absProgress = udtValue * ckbToUdt.udtScale;
99
+ }
100
+ return new OrderCell({ cell, data, ckbUnoccupied, absTotal, absProgress });
101
+ }
102
+ /**
103
+ * Checks whether the CKB-to-UDT side is enabled and has nonzero inventory.
104
+ *
105
+ * @remarks Executable-match checks for fee, minimum output, and ratio bounds happen during matching.
106
+ */
107
+ isCkb2UdtMatchable() {
108
+ return this.data.info.isCkb2Udt() && this.ckbUnoccupied > 0n;
109
+ }
110
+ /**
111
+ * Checks whether the UDT-to-CKB side is enabled and has nonzero inventory.
112
+ *
113
+ * @remarks Executable-match checks for fee, minimum output, and ratio bounds happen during matching.
114
+ */
115
+ isUdt2CkbMatchable() {
116
+ return this.data.info.isUdt2Ckb() && this.data.udtValue > 0n;
117
+ }
118
+ /** Returns true when either side is enabled and has nonzero inventory. */
119
+ isMatchable() {
120
+ return this.isCkb2UdtMatchable() || this.isUdt2CkbMatchable();
121
+ }
122
+ /**
123
+ * Checks if the order is fulfilled.
124
+ *
125
+ * @returns True if the order is fulfilled (not matchable), otherwise false.
126
+ */
127
+ isFulfilled() {
128
+ return !this.isMatchable();
129
+ }
130
+ /**
131
+ * Retrieves the master out point of the order.
132
+ * @returns The master out point associated with the order.
133
+ */
134
+ getMaster() {
135
+ return this.data.getMaster(this.cell.outPoint);
136
+ }
137
+ /**
138
+ * Whether `descendant` can be this origin order's live continuation.
139
+ *
140
+ * @remarks
141
+ * This confusion-attack guard requires the same order script, UDT type,
142
+ * master, and info, while forbidding lower total value or lower progress.
143
+ * See {@link https://github.com/ickb/whitepaper/issues/19}.
144
+ */
145
+ isValid(descendant) {
146
+ const udt = this.cell.cellOutput.type;
147
+ return (this.data.isMint() &&
148
+ this.cell.cellOutput.lock.eq(descendant.cell.cellOutput.lock) &&
149
+ udt !== undefined &&
150
+ descendant.cell.cellOutput.type?.eq(udt) === true &&
151
+ descendant.getMaster().eq(this.getMaster()) &&
152
+ this.data.info.eq(descendant.data.info) &&
153
+ this.absTotal <= descendant.absTotal &&
154
+ this.absProgress <= descendant.absProgress);
155
+ }
156
+ /**
157
+ * Resolves the best valid descendant order.
158
+ *
159
+ * @remarks
160
+ * The genuine mint origin is the immutable validation baseline. Resolution
161
+ * prefers greater progress and then greater total value; candidate identity is
162
+ * irrelevant. Equal-score non-mint candidates are ambiguous, while the mint
163
+ * origin wins an equal-score tie when it is still live.
164
+ */
165
+ resolve(descendants) {
166
+ let resolution;
167
+ for (const descendant of descendants) {
168
+ if (!this.isValid(descendant)) {
169
+ continue;
170
+ }
171
+ resolution = betterOrderResolution(resolution, descendant);
172
+ }
173
+ if (resolution?.isAmbiguous === true) {
174
+ return undefined;
175
+ }
176
+ return resolution?.order;
177
+ }
178
+ }
179
+ function absoluteOrderTotal(ckb2UdtValue, udt2CkbValue, info) {
180
+ if (ckb2UdtValue === 0n) {
181
+ return udt2CkbValue;
182
+ }
183
+ if (udt2CkbValue === 0n) {
184
+ return ckb2UdtValue;
185
+ }
186
+ const { ckbToUdt, udtToCkb } = info;
187
+ return ((ckb2UdtValue * udtToCkb.ckbScale * udtToCkb.udtScale +
188
+ udt2CkbValue * ckbToUdt.ckbScale * ckbToUdt.udtScale) >>
189
+ 1n);
190
+ }
191
+ function betterOrderResolution(current, candidate) {
192
+ if (current === undefined || compareOrderScore(current.order, candidate) < 0) {
193
+ return { isAmbiguous: false, order: candidate };
194
+ }
195
+ if (compareOrderScore(current.order, candidate) > 0) {
196
+ return current;
197
+ }
198
+ if (current.order.cell.outPoint.eq(candidate.cell.outPoint)) {
199
+ return current;
200
+ }
201
+ if (candidate.data.isMint() && !current.order.data.isMint()) {
202
+ return { isAmbiguous: false, order: candidate };
203
+ }
204
+ if (!candidate.data.isMint() && current.order.data.isMint()) {
205
+ return current;
206
+ }
207
+ return { ...current, isAmbiguous: true };
208
+ }
209
+ function compareOrderScore(left, right) {
210
+ if (left.absProgress !== right.absProgress) {
211
+ return left.absProgress < right.absProgress ? -1 : 1;
212
+ }
213
+ if (left.absTotal !== right.absTotal) {
214
+ return left.absTotal < right.absTotal ? -1 : 1;
215
+ }
216
+ return 0;
217
+ }
218
+ /**
219
+ * Represents a master cell
220
+ */
221
+ export class MasterCell {
222
+ /** Raw live master cell that anchors an order group. */
223
+ cell;
224
+ /**
225
+ * Creates an instance of MasterCell.
226
+ * @param cell - The ccc.Cell instance to be wrapped by the MasterCell.
227
+ */
228
+ constructor(cell) {
229
+ this.cell = cell;
230
+ }
231
+ /** Whether this master anchors `order`: its type is the order script and the order names it. */
232
+ anchors(order) {
233
+ return (this.cell.cellOutput.type?.eq(order.cell.cellOutput.lock) === true &&
234
+ order.getMaster().eq(this.cell.outPoint));
235
+ }
236
+ }
237
+ /**
238
+ * Represents a group of orders associated with a master cell.
239
+ */
240
+ export class OrderGroup {
241
+ /** Master cell that authorizes and anchors the current order. */
242
+ master;
243
+ /** Current resolved order cell. */
244
+ order;
245
+ /** Origin order used to validate descendant progress and identity. */
246
+ origin;
247
+ /** The block that committed the origin and its master: how long the order has been on the book. */
248
+ blockNumber;
249
+ /**
250
+ * Creates an instance of OrderGroup.
251
+ * @param master - The master cell associated with the order group.
252
+ * @param order - The order within the group.
253
+ * @param origin - The original order associated with the group.
254
+ * @param blockNumber - The block that committed the origin and its master.
255
+ */
256
+ constructor(master, order, origin, blockNumber) {
257
+ this.master = master;
258
+ this.order = order;
259
+ this.origin = origin;
260
+ this.blockNumber = blockNumber;
261
+ }
262
+ /**
263
+ * Gets the CKB value of the group.
264
+ *
265
+ * @returns The total CKB amount as a `ccc.FixedPoint`, which is the sum of the CKB values of the order cell and the master cell.
266
+ */
267
+ get ckbValue() {
268
+ return this.order.cell.cellOutput.capacity + this.master.cell.cellOutput.capacity;
269
+ }
270
+ /**
271
+ * Gets the UDT value of the group.
272
+ *
273
+ * @returns The UDT amount as a `ccc.FixedPoint`, derived from the order cell.
274
+ */
275
+ get udtValue() {
276
+ return this.order.data.udtValue;
277
+ }
278
+ /**
279
+ * Tries to create an OrderGroup from the provided parameters.
280
+ * @param master - The master cell.
281
+ * @param order - The order within the group.
282
+ * @param origin - The original order.
283
+ * @returns An OrderGroup instance or undefined if creation fails.
284
+ */
285
+ static tryFrom(master, order, origin, blockNumber) {
286
+ const og = new OrderGroup(master, order, origin, blockNumber);
287
+ if (og.isValid()) {
288
+ return og;
289
+ }
290
+ return undefined;
291
+ }
292
+ /** Whether the master anchors both orders and the order continues its origin. */
293
+ isValid() {
294
+ return (this.master.anchors(this.origin) &&
295
+ this.master.anchors(this.order) &&
296
+ this.origin.isValid(this.order));
297
+ }
298
+ /**
299
+ * Checks if the specified lock is the owner of the master cell.
300
+ *
301
+ * @param locks - The locks to check ownership against.
302
+ * @returns True if the lock is the owner, otherwise false.
303
+ */
304
+ isOwner(...locks) {
305
+ const lock = this.master.cell.cellOutput.lock;
306
+ return locks.some((l) => lock.eq(l));
307
+ }
308
+ }
309
+ //# sourceMappingURL=cells.js.map