@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,364 @@
1
+ import { ccc, mol } from "@ckb-ccc/core";
2
+ import {
3
+ assertDaoOutputLimit,
4
+ DAO_HEADER_INDEX_LIMIT,
5
+ DaoHeaderIndexError,
6
+ isDaoWithdrawalRequest,
7
+ pushHeaderDep,
8
+ } from "./dao.ts";
9
+ import type { IckbDepositCell } from "./logic.ts";
10
+ import { ickbValue } from "./udt.ts";
11
+ import { CheckedInt32LE, CheckedUint64LE } from "./utils/codec.ts";
12
+ import {
13
+ headersByNumber,
14
+ type ScannedCell,
15
+ type ScriptDeps,
16
+ type ValueComponents,
17
+ } from "./utils/utils.ts";
18
+
19
+ /**
20
+ * A live Nervos DAO withdrawal request cell, valued at the two headers it spans.
21
+ */
22
+ export interface DaoWithdrawalRequestCell {
23
+ /** The DAO withdrawal request cell. */
24
+ cell: ccc.Cell;
25
+ /** The deposit header and the request's own header. */
26
+ headers: [ccc.ClientBlockHeader, ccc.ClientBlockHeader];
27
+ /** The DAO claim epoch of the request. */
28
+ maturity: ccc.Epoch;
29
+ /** Whether the claim epoch is at or before the tip: the request can be withdrawn. */
30
+ isReady: boolean;
31
+ /** The capacity the withdrawal returns: the cell's plus the interest. */
32
+ ckbValue: ccc.FixedPoint;
33
+ }
34
+
35
+ /** The owner marker payload: where its owned cell sits in their shared transaction. */
36
+ export interface OwnerData {
37
+ /** Signed output-index distance from the owner marker to the owned cell. */
38
+ ownedDistance: ccc.Num;
39
+ }
40
+
41
+ const OwnerDataCodec = mol.struct({
42
+ ownedDistance: CheckedInt32LE,
43
+ });
44
+ // An owner marker's fixed prefix: a signed 32-bit distance.
45
+ const ownerDataBytes = 4;
46
+
47
+ /** Encodes an owner marker payload. */
48
+ export function encodeOwnerData(data: OwnerData): ccc.Bytes {
49
+ return OwnerDataCodec.encode(data);
50
+ }
51
+
52
+ /**
53
+ * Decodes the fixed owner-data prefix and ignores trailing cell payload bytes.
54
+ *
55
+ * @remarks The owner data prefix is 4 bytes after the `0x` marker: a signed little-endian
56
+ * relative output-index distance to the owned cell. Later bytes belong to other protocol
57
+ * data and are intentionally tolerated here.
58
+ */
59
+ export function decodeOwnerData(outputData: ccc.Hex): OwnerData {
60
+ const { ownedDistance } = OwnerDataCodec.decode(
61
+ outputData.slice(0, 2 + 2 * ownerDataBytes),
62
+ );
63
+ return { ownedDistance: ccc.numFrom(ownedDistance) };
64
+ }
65
+
66
+ /**
67
+ * Wraps an owner marker cell that references an owned withdrawal request.
68
+ */
69
+ export class OwnerCell {
70
+ /** The live owner marker cell whose output data points to the owned request. */
71
+ public cell: ccc.Cell;
72
+
73
+ /** Creates an owner marker wrapper for a live cell. */
74
+ constructor(cell: ccc.Cell) {
75
+ this.cell = cell;
76
+ }
77
+
78
+ /**
79
+ * Returns the owned withdrawal request out point referenced by this owner marker.
80
+ *
81
+ * @remarks Owner data stores a signed output-index distance. The owned cell is resolved
82
+ * on the same transaction hash as the owner marker cell.
83
+ */
84
+ public getOwned(): ccc.OutPoint {
85
+ const { txHash, index } = this.cell.outPoint;
86
+ let ownedDistance: ccc.Num;
87
+ try {
88
+ ({ ownedDistance } = decodeOwnerData(this.cell.outputData));
89
+ } catch (error) {
90
+ throw new Error(
91
+ `Invalid owner marker payload at ${this.cell.outPoint.toHex()}: ${this.cell.outputData}`,
92
+ { cause: error },
93
+ );
94
+ }
95
+ const ownedIndex = index + ownedDistance;
96
+ if (ownedIndex < 0n) {
97
+ throw new Error(
98
+ `Owner marker ${this.cell.outPoint.toHex()} points before output 0 with distance ${String(ownedDistance)}`,
99
+ );
100
+ }
101
+ return new ccc.OutPoint(txHash, ownedIndex);
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Pairs an owned DAO withdrawal request with the owner marker cell that points to it.
107
+ */
108
+ export class WithdrawalGroup implements ValueComponents {
109
+ /** The decoded DAO withdrawal request controlled by this owner marker. */
110
+ public owned: DaoWithdrawalRequestCell;
111
+
112
+ /** The owner marker cell that references the owned withdrawal request. */
113
+ public owner: OwnerCell;
114
+
115
+ /** Creates a withdrawal group from a decoded request and its owner marker. */
116
+ constructor(owned: DaoWithdrawalRequestCell, owner: OwnerCell) {
117
+ this.owned = owned;
118
+ this.owner = owner;
119
+ }
120
+
121
+ /** Returns the total CKB capacity in the owned withdrawal and owner marker cells. */
122
+ public get ckbValue(): ccc.FixedPoint {
123
+ return this.owned.ckbValue + this.owner.cell.cellOutput.capacity;
124
+ }
125
+
126
+ /** Returns the iCKB amount represented by the owned withdrawal request. */
127
+ public get udtValue(): ccc.FixedPoint {
128
+ return ickbValue(this.owned.cell.capacityFree, this.owned.headers[0]);
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Builds and finds Owned Owner withdrawal groups for an iCKB deployment.
134
+ */
135
+ export class OwnedOwnerManager implements ScriptDeps {
136
+ /** The Owned Owner script used as owner marker type and withdrawal request lock. */
137
+ public readonly script: ccc.Script;
138
+
139
+ /** Cell dependencies required to execute the Owned Owner script. */
140
+ public readonly cellDeps: ccc.CellDep[];
141
+
142
+ /** The Nervos DAO script the withdrawal requests carry, with its cell deps. */
143
+ public readonly dao: ScriptDeps;
144
+
145
+ /** Creates the manager for one Owned Owner deployment over one DAO deployment. */
146
+ constructor(script: ccc.Script, cellDeps: ccc.CellDep[], dao: ScriptDeps) {
147
+ this.script = script;
148
+ this.cellDeps = cellDeps;
149
+ this.dao = dao;
150
+ }
151
+
152
+ /** Whether the cell is an owner marker for this manager's script. */
153
+ public isOwner(cell: ccc.Cell): boolean {
154
+ if (cell.cellOutput.type?.eq(this.script) !== true || cell.outputData.length < 10) {
155
+ return false;
156
+ }
157
+ try {
158
+ new OwnerCell(cell).getOwned();
159
+ return true;
160
+ } catch {
161
+ return false;
162
+ }
163
+ }
164
+
165
+ /** Whether the cell is a DAO withdrawal request locked by this manager's script. */
166
+ public isOwned(cell: ccc.Cell): boolean {
167
+ return (
168
+ isDaoWithdrawalRequest(cell, this.dao.script) &&
169
+ cell.cellOutput.lock.eq(this.script)
170
+ );
171
+ }
172
+
173
+ /**
174
+ * Spends the deposits into DAO withdrawal requests locked by the Owned Owner script,
175
+ * each followed by an owner marker locked by `lock` that points back at it.
176
+ *
177
+ * @remarks Completion (`IckbSdk.completeTransaction`) adds the dep group that also
178
+ * resolves the xUDT script.
179
+ */
180
+ public requestWithdrawal(
181
+ txLike: ccc.TransactionLike,
182
+ deposits: IckbDepositCell[],
183
+ lock: ccc.Script,
184
+ ): ccc.Transaction {
185
+ const tx = ccc.Transaction.from(txLike);
186
+ if (deposits.length === 0) {
187
+ return tx;
188
+ }
189
+ // The DAO script pairs each request output with the input at the same index.
190
+ if (
191
+ tx.inputs.length !== tx.outputs.length ||
192
+ tx.outputs.length !== tx.outputsData.length
193
+ ) {
194
+ throw new Error("Transaction has different inputs and outputs lengths");
195
+ }
196
+ tx.addCellDeps(this.cellDeps);
197
+ tx.addCellDeps(this.dao.cellDeps);
198
+ const requestStart = tx.outputs.length;
199
+ for (const { cell, header } of deposits) {
200
+ if (cell.cellOutput.lock.args.length !== this.script.args.length) {
201
+ throw new Error("Withdrawal request lock args has different size from deposit");
202
+ }
203
+ pushHeaderDep(tx, header.hash);
204
+ tx.addInput(cell);
205
+ tx.addOutput(
206
+ { capacity: cell.cellOutput.capacity, lock: this.script, type: this.dao.script },
207
+ CheckedUint64LE.encode(header.number),
208
+ );
209
+ }
210
+ for (let index = 0; index < deposits.length; index += 1) {
211
+ tx.addOutput(
212
+ { lock, type: this.script },
213
+ // Negative: owner markers are appended after their withdrawal outputs.
214
+ encodeOwnerData({
215
+ ownedDistance: BigInt(requestStart + index - tx.outputs.length),
216
+ }),
217
+ );
218
+ }
219
+ assertDaoOutputLimit(tx, this.dao.script);
220
+ return tx;
221
+ }
222
+
223
+ /**
224
+ * Spends the owned withdrawal requests and their owner markers, with the DAO header deps,
225
+ * since, and witness each request needs.
226
+ *
227
+ * @remarks The distinct deposit headers are moved to the front of the header deps and
228
+ * the withdrawal headers appended, so a deposit header's index is its rank among the
229
+ * collected withdrawals. Caller must ensure UDT cellDeps are added to the transaction.
230
+ */
231
+ public withdraw(
232
+ txLike: ccc.TransactionLike,
233
+ withdrawalGroups: WithdrawalGroup[],
234
+ ): ccc.Transaction {
235
+ const tx = ccc.Transaction.from(txLike);
236
+ if (withdrawalGroups.length === 0) {
237
+ return tx;
238
+ }
239
+ for (const group of withdrawalGroups) {
240
+ const ownedOutPoint = group.owned.cell.outPoint;
241
+ const linkedOutPoint = group.owner.getOwned();
242
+ if (!linkedOutPoint.eq(ownedOutPoint)) {
243
+ throw new Error(
244
+ `Withdrawal owner ${group.owner.cell.outPoint.toHex()} points to ${linkedOutPoint.toHex()} but group owned cell is ${ownedOutPoint.toHex()}`,
245
+ );
246
+ }
247
+ }
248
+ tx.addCellDeps(this.cellDeps);
249
+ tx.addCellDeps(this.dao.cellDeps);
250
+ // Only this step names a header by index, and the deployed script reads that index as
251
+ // one byte, so the deposit headers go first, ahead of whatever the requests and receipts
252
+ // pushed: the limit then counts these alone. Safe because nothing else in the stack reads
253
+ // a header by position and every built transaction passes here once.
254
+ const depositHashes = [
255
+ ...new Set(withdrawalGroups.map(({ owned }) => owned.headers[0].hash)),
256
+ ];
257
+ tx.headerDeps = [
258
+ ...depositHashes,
259
+ ...tx.headerDeps.filter((hash) => !depositHashes.includes(hash)),
260
+ ];
261
+ for (const { owned } of withdrawalGroups) {
262
+ pushHeaderDep(tx, owned.headers[1].hash);
263
+ }
264
+ for (const { owned } of withdrawalGroups) {
265
+ const headerIndex = tx.headerDeps.indexOf(owned.headers[0].hash);
266
+ // The deployed dao.c reads one byte of the u64 index field (RFC 0023 erratum,
267
+ // nervosnetwork/rfcs pull 456), so index 256 would be read as 0.
268
+ if (headerIndex >= DAO_HEADER_INDEX_LIMIT) {
269
+ throw new DaoHeaderIndexError(headerIndex);
270
+ }
271
+ const inputIndex =
272
+ tx.addInput({
273
+ outPoint: owned.cell.outPoint,
274
+ cellOutput: owned.cell.cellOutput,
275
+ outputData: owned.cell.outputData,
276
+ since: { relative: "absolute", metric: "epoch", value: owned.maturity.toNum() },
277
+ }) - 1;
278
+ const witness = tx.getWitnessArgs(inputIndex) ?? ccc.WitnessArgs.from({});
279
+ if ((witness.inputType ?? "") !== "") {
280
+ throw new Error("Witnesses of withdrawal request already in use");
281
+ }
282
+ witness.inputType = ccc.hexFrom(CheckedUint64LE.encode(headerIndex));
283
+ tx.setWitnessArgs(inputIndex, witness);
284
+ }
285
+ for (const { owner } of withdrawalGroups) {
286
+ tx.addInput(owner.cell);
287
+ }
288
+ assertDaoOutputLimit(tx, this.dao.script);
289
+ return tx;
290
+ }
291
+
292
+ /**
293
+ * The owner markers among `cells` paired with their owned withdrawal requests, which live
294
+ * in the marker's own transaction at the encoded distance, so the marker's block is the
295
+ * request's. Markers whose target is not an owned withdrawal request are skipped. Each
296
+ * header is read once per batch.
297
+ */
298
+ public async withdrawalGroupsFrom(
299
+ client: ccc.Client,
300
+ cells: readonly ScannedCell[],
301
+ tip: ccc.ClientBlockHeader,
302
+ ): Promise<WithdrawalGroup[]> {
303
+ const owners = cells
304
+ .filter(({ cell }) => this.isOwner(cell))
305
+ .map(({ cell, blockNumber }) => ({ owner: new OwnerCell(cell), blockNumber }));
306
+ const ownedCells = await Promise.all(
307
+ owners.map(async ({ owner }) => client.getCell(owner.getOwned())),
308
+ );
309
+ const pairs = owners.flatMap(({ owner, blockNumber }, index) => {
310
+ const owned = ownedCells[index];
311
+ return owned !== undefined && this.isOwned(owned)
312
+ ? [{ owner, owned, blockNumber, depositBlockNumber: depositBlockNumberOf(owned) }]
313
+ : [];
314
+ });
315
+ const headers = await headersByNumber(
316
+ client,
317
+ pairs.flatMap((pair) => [pair.depositBlockNumber, pair.blockNumber]),
318
+ );
319
+ return pairs.map(
320
+ ({ owner, owned, blockNumber, depositBlockNumber }) =>
321
+ new WithdrawalGroup(
322
+ withdrawalRequestCell(
323
+ owned,
324
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- both headers were read above.
325
+ headers.get(depositBlockNumber)!,
326
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- both headers were read above.
327
+ headers.get(blockNumber)!,
328
+ tip,
329
+ ),
330
+ owner,
331
+ ),
332
+ );
333
+ }
334
+ }
335
+
336
+ /** Values a DAO withdrawal request at its two headers and judges it claimable at the tip. */
337
+ export function withdrawalRequestCell(
338
+ cell: ccc.Cell,
339
+ depositHeader: ccc.ClientBlockHeader,
340
+ requestHeader: ccc.ClientBlockHeader,
341
+ tip: ccc.ClientBlockHeader,
342
+ ): DaoWithdrawalRequestCell {
343
+ const interests = ccc.calcDaoProfit(cell.capacityFree, depositHeader, requestHeader);
344
+ const maturity = ccc.calcDaoClaimEpoch(depositHeader, requestHeader);
345
+ return {
346
+ cell,
347
+ headers: [depositHeader, requestHeader],
348
+ maturity,
349
+ isReady: maturity.compare(tip.epoch) <= 0,
350
+ ckbValue: cell.cellOutput.capacity + interests,
351
+ };
352
+ }
353
+
354
+ /** The deposit block number a withdrawal request records in its data. */
355
+ function depositBlockNumberOf(cell: ccc.Cell): ccc.Num {
356
+ try {
357
+ return CheckedUint64LE.decode(cell.outputData);
358
+ } catch (error) {
359
+ throw new Error(
360
+ `Invalid DAO withdrawal request payload at ${cell.outPoint.toHex()}: ${cell.outputData}`,
361
+ { cause: error },
362
+ );
363
+ }
364
+ }