@ocap/state 1.28.9 → 1.29.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/esm/_virtual/rolldown_runtime.mjs +18 -0
  2. package/esm/contexts/state.d.mts +15 -0
  3. package/esm/contexts/state.mjs +17 -0
  4. package/esm/index.d.mts +20 -0
  5. package/esm/index.mjs +47 -0
  6. package/esm/states/account.d.mts +18 -0
  7. package/esm/states/account.mjs +91 -0
  8. package/esm/states/asset.d.mts +14 -0
  9. package/esm/states/asset.mjs +80 -0
  10. package/esm/states/blacklist.d.mts +36 -0
  11. package/esm/states/blacklist.mjs +71 -0
  12. package/esm/states/chain.d.mts +30 -0
  13. package/esm/states/chain.mjs +52 -0
  14. package/esm/states/delegation.d.mts +11 -0
  15. package/esm/states/delegation.mjs +42 -0
  16. package/esm/states/evidence.d.mts +12 -0
  17. package/esm/states/evidence.mjs +35 -0
  18. package/esm/states/factory.d.mts +12 -0
  19. package/esm/states/factory.mjs +76 -0
  20. package/esm/states/rollup-block.d.mts +13 -0
  21. package/esm/states/rollup-block.mjs +75 -0
  22. package/esm/states/rollup.d.mts +18 -0
  23. package/esm/states/rollup.mjs +215 -0
  24. package/esm/states/stake.d.mts +13 -0
  25. package/esm/states/stake.mjs +89 -0
  26. package/esm/states/token-factory.d.mts +13 -0
  27. package/esm/states/token-factory.mjs +76 -0
  28. package/esm/states/token.d.mts +14 -0
  29. package/esm/states/token.mjs +109 -0
  30. package/esm/states/tx.d.mts +233 -0
  31. package/esm/states/tx.mjs +867 -0
  32. package/esm/util.d.mts +6 -0
  33. package/esm/util.mjs +18 -0
  34. package/lib/_virtual/rolldown_runtime.cjs +43 -0
  35. package/lib/contexts/state.cjs +19 -0
  36. package/lib/contexts/state.d.cts +15 -0
  37. package/lib/index.cjs +121 -0
  38. package/lib/index.d.cts +20 -0
  39. package/lib/states/account.cjs +106 -0
  40. package/lib/states/account.d.cts +18 -0
  41. package/lib/states/asset.cjs +91 -0
  42. package/lib/states/asset.d.cts +14 -0
  43. package/lib/states/blacklist.cjs +74 -0
  44. package/lib/states/blacklist.d.cts +36 -0
  45. package/lib/states/chain.cjs +62 -0
  46. package/lib/states/chain.d.cts +30 -0
  47. package/lib/states/delegation.cjs +50 -0
  48. package/lib/states/delegation.d.cts +11 -0
  49. package/lib/states/evidence.cjs +44 -0
  50. package/lib/states/evidence.d.cts +12 -0
  51. package/lib/states/factory.cjs +85 -0
  52. package/lib/states/factory.d.cts +12 -0
  53. package/lib/states/rollup-block.cjs +85 -0
  54. package/lib/states/rollup-block.d.cts +13 -0
  55. package/lib/states/rollup.cjs +230 -0
  56. package/lib/states/rollup.d.cts +18 -0
  57. package/lib/states/stake.cjs +99 -0
  58. package/lib/states/stake.d.cts +13 -0
  59. package/lib/states/token-factory.cjs +86 -0
  60. package/lib/states/token-factory.d.cts +13 -0
  61. package/lib/states/token.cjs +121 -0
  62. package/lib/states/token.d.cts +14 -0
  63. package/lib/states/tx.cjs +889 -0
  64. package/lib/states/tx.d.cts +233 -0
  65. package/lib/util.cjs +19 -0
  66. package/lib/util.d.cts +6 -0
  67. package/package.json +46 -14
  68. package/lib/contexts/state.js +0 -19
  69. package/lib/index.js +0 -63
  70. package/lib/states/account.js +0 -95
  71. package/lib/states/asset.js +0 -91
  72. package/lib/states/blacklist.js +0 -103
  73. package/lib/states/chain.js +0 -49
  74. package/lib/states/delegation.js +0 -46
  75. package/lib/states/evidence.js +0 -35
  76. package/lib/states/factory.js +0 -92
  77. package/lib/states/rollup-block.js +0 -84
  78. package/lib/states/rollup.js +0 -297
  79. package/lib/states/stake.js +0 -83
  80. package/lib/states/token-factory.js +0 -74
  81. package/lib/states/token.js +0 -124
  82. package/lib/states/tx.js +0 -896
  83. package/lib/util.js +0 -28
@@ -0,0 +1,889 @@
1
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
+ let _arcblock_did = require("@arcblock/did");
3
+ let _ocap_util = require("@ocap/util");
4
+ let _ocap_util_lib_error = require("@ocap/util/lib/error");
5
+ let lodash_pick = require("lodash/pick");
6
+ lodash_pick = require_rolldown_runtime.__toESM(lodash_pick);
7
+ let lodash_get = require("lodash/get");
8
+ lodash_get = require_rolldown_runtime.__toESM(lodash_get);
9
+ let _ocap_message = require("@ocap/message");
10
+ let _ocap_util_lib_get_list_field = require("@ocap/util/lib/get-list-field");
11
+ let _ocap_util_lib_get_related_addr = require("@ocap/util/lib/get-related-addr");
12
+ let lodash_camelCase = require("lodash/camelCase");
13
+ lodash_camelCase = require_rolldown_runtime.__toESM(lodash_camelCase);
14
+ let lodash_groupBy = require("lodash/groupBy");
15
+ lodash_groupBy = require_rolldown_runtime.__toESM(lodash_groupBy);
16
+ let lodash_merge = require("lodash/merge");
17
+ lodash_merge = require_rolldown_runtime.__toESM(lodash_merge);
18
+ let lodash_upperFirst = require("lodash/upperFirst");
19
+ lodash_upperFirst = require_rolldown_runtime.__toESM(lodash_upperFirst);
20
+
21
+ //#region src/states/tx.ts
22
+ var tx_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
23
+ FORGE_TOKEN_HOLDER: () => FORGE_TOKEN_HOLDER,
24
+ attachPaidTxGas: () => attachPaidTxGas,
25
+ create: () => create,
26
+ eachReceipts: () => eachReceipts,
27
+ getTxReceipts: () => getTxReceipts,
28
+ getTxReceiver: () => getTxReceiver,
29
+ getTxSender: () => getTxSender,
30
+ groupReceiptTokenChanges: () => groupReceiptTokenChanges,
31
+ mergeTxReceipts: () => mergeTxReceipts,
32
+ update: () => update,
33
+ verifyTxReceipts: () => verifyTxReceipts
34
+ });
35
+ const ZERO = new _ocap_util.BN(0);
36
+ const { RoleType } = _arcblock_did.types;
37
+ const FORGE_TOKEN_HOLDER = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
38
+ const FORGE_FEE_RECEIVER = "z1EJUBdbPYqMiWHfRZvSAvbYeWcEHB19Xyfc";
39
+ const QLDB_MIGRATION_TIME = /* @__PURE__ */ new Date("2021-05-03T12:46:56.245Z");
40
+ function eachReceipts(receipts, callback) {
41
+ return (receipts || []).map((receipt) => {
42
+ return (receipt.changes || []).map((change) => callback(receipt.address, change));
43
+ }).flat();
44
+ }
45
+ function groupReceiptTokenChanges(receipts) {
46
+ const tokenChanges = {};
47
+ eachReceipts(receipts || [], (address, change) => {
48
+ if ((0, _arcblock_did.toTypeInfo)(change.target).role !== RoleType.ROLE_TOKEN) return;
49
+ if (change.value === "0") return;
50
+ if (!tokenChanges[address]) tokenChanges[address] = {};
51
+ const tokenChange = tokenChanges[address];
52
+ tokenChange[change.target] = new _ocap_util.BN(tokenChange[change.target] || 0).add(new _ocap_util.BN(change.value)).toString();
53
+ });
54
+ return tokenChanges;
55
+ }
56
+ const getTxReceiver = ({ tx, itx, typeUrl }) => {
57
+ switch (typeUrl) {
58
+ case "TransferTx":
59
+ case "ExchangeTx":
60
+ case "TransferV2Tx":
61
+ case "ExchangeV2Tx": return itx.to;
62
+ case "MintAssetTx": return itx.owner;
63
+ case "CreateTokenTx":
64
+ case "CreateAssetTx":
65
+ case "AcquireAssetV2Tx": return tx.delegator || tx.from;
66
+ case "AcquireAssetV3Tx": return itx.owner;
67
+ case "SetupSwapTx": return itx.receiver;
68
+ case "StakeTx": return itx.address;
69
+ default: return "";
70
+ }
71
+ };
72
+ const getTxSender = ({ tx, typeUrl }) => {
73
+ switch (typeUrl) {
74
+ case "TransferTx":
75
+ case "TransferV2Tx":
76
+ case "ExchangeTx":
77
+ case "ExchangeV2Tx":
78
+ case "AcquireAssetV2Tx":
79
+ case "SetupSwapTx":
80
+ case "WithdrawTokenTx":
81
+ case "StakeTx":
82
+ case "ReturnStakeTx":
83
+ case "SlashStakeTx": return tx.from;
84
+ default: return "";
85
+ }
86
+ };
87
+ const getReceiptChange = (receipts, { address, action }) => {
88
+ return receipts.filter((x) => !address || x.address === address).flatMap((x) => x.changes.filter((c) => !action || c.action === action));
89
+ };
90
+ const getTransferReceipts = (tx) => {
91
+ const senderReceipt = {
92
+ address: tx.from,
93
+ changes: []
94
+ };
95
+ const receiverReceipt = {
96
+ address: tx.itxJson.to,
97
+ changes: []
98
+ };
99
+ if (new _ocap_util.BN(tx.itxJson.value).gt(ZERO)) {
100
+ senderReceipt.changes.push({
101
+ target: "",
102
+ action: "transfer",
103
+ value: `-${tx.itxJson.value}`
104
+ });
105
+ receiverReceipt.changes.push({
106
+ target: "",
107
+ action: "transfer",
108
+ value: tx.itxJson.value
109
+ });
110
+ }
111
+ if (Array.isArray(tx.itxJson.tokens)) tx.itxJson.tokens.forEach((x) => {
112
+ senderReceipt.changes.push({
113
+ target: x.address,
114
+ action: "transfer",
115
+ value: `-${x.value}`
116
+ });
117
+ receiverReceipt.changes.push({
118
+ target: x.address,
119
+ action: "transfer",
120
+ value: x.value
121
+ });
122
+ });
123
+ if (Array.isArray(tx.itxJson.assets)) tx.itxJson.assets.forEach((x) => {
124
+ senderReceipt.changes.push({
125
+ target: x,
126
+ action: "transfer",
127
+ value: "-1"
128
+ });
129
+ receiverReceipt.changes.push({
130
+ target: x,
131
+ action: "transfer",
132
+ value: "1"
133
+ });
134
+ });
135
+ return [senderReceipt, receiverReceipt];
136
+ };
137
+ const getReceiptsFromTxInput = (inputs, symbol, action = "transfer") => {
138
+ const receipts = [];
139
+ inputs.forEach((x) => {
140
+ const receipt = {
141
+ address: x.owner,
142
+ changes: []
143
+ };
144
+ (0, _ocap_util_lib_get_list_field.getListField)(x, "tokens").forEach(({ address, value }) => {
145
+ receipt.changes.push({
146
+ target: address,
147
+ action,
148
+ value: `${symbol}${value}`
149
+ });
150
+ });
151
+ (0, _ocap_util_lib_get_list_field.getListField)(x, "assets").forEach((address) => receipt.changes.push({
152
+ target: address,
153
+ action,
154
+ value: `${symbol}1`
155
+ }));
156
+ receipts.push(receipt);
157
+ });
158
+ return receipts;
159
+ };
160
+ const getReceiptsFromContext = (ctx) => {
161
+ if (Array.isArray(ctx.updatedAccounts)) {
162
+ const grouped = (0, lodash_groupBy.default)(ctx.updatedAccounts.filter((x) => x.address && x.delta), "address");
163
+ return Object.keys(grouped).map((k) => ({
164
+ address: k,
165
+ changes: grouped[k].map((x) => ({
166
+ target: x.token,
167
+ action: x.action || "transfer",
168
+ value: x.delta
169
+ }))
170
+ }));
171
+ }
172
+ return [];
173
+ };
174
+ /**
175
+ * Add receipts for tx that have gasPaid but no receipts
176
+ * This is used to handle legacy data that gas receipts were not properly recorded
177
+ */
178
+ const getReceiptsFromGasPaid = (tx, { config, typeUrl }) => {
179
+ const gasReceipt = getReceiptChange(tx.receipts || [], { action: "gas" });
180
+ const gasPaid = new _ocap_util.BN(tx.gasPaid || 0);
181
+ if (gasReceipt.length) return [];
182
+ if (gasPaid.lte(ZERO)) return [];
183
+ const gasPayer = { AccountMigrateTx: tx.itxJson?.address }[typeUrl] || tx.from;
184
+ const gasReceiver = config?.vaults?.txGas?.[0] || FORGE_FEE_RECEIVER;
185
+ if (!gasPayer) return [];
186
+ return [{
187
+ address: gasPayer,
188
+ changes: [{
189
+ target: "",
190
+ action: "gas",
191
+ value: gasPaid.neg().toString()
192
+ }]
193
+ }, {
194
+ address: gasReceiver,
195
+ changes: [{
196
+ target: "",
197
+ action: "gas",
198
+ value: gasPaid.toString()
199
+ }]
200
+ }];
201
+ };
202
+ const getTransferV3Receipts = (tx) => [...getReceiptsFromTxInput(tx.itxJson.inputs || [], "-", "transfer"), ...getReceiptsFromTxInput(tx.itxJson.outputs || [], "", "transfer")];
203
+ const getExchangeReceipts = (tx, ctx) => {
204
+ const { senderState, receiverState } = ctx;
205
+ const { sender, receiver } = tx.itxJson;
206
+ const senderReceipt = {
207
+ address: senderState ? senderState.address : tx.from,
208
+ changes: []
209
+ };
210
+ const receiverReceipt = {
211
+ address: receiverState ? receiverState.address : tx.itxJson.to,
212
+ changes: []
213
+ };
214
+ if (sender && new _ocap_util.BN(sender.value).gt(ZERO)) {
215
+ senderReceipt.changes.push({
216
+ target: "",
217
+ action: "transfer",
218
+ value: `-${sender.value}`
219
+ });
220
+ receiverReceipt.changes.push({
221
+ target: "",
222
+ action: "transfer",
223
+ value: sender.value
224
+ });
225
+ }
226
+ if (receiver && new _ocap_util.BN(receiver.value).gt(ZERO)) {
227
+ receiverReceipt.changes.push({
228
+ target: "",
229
+ action: "transfer",
230
+ value: `-${receiver.value}`
231
+ });
232
+ senderReceipt.changes.push({
233
+ target: "",
234
+ action: "transfer",
235
+ value: receiver.value
236
+ });
237
+ }
238
+ if (Array.isArray(sender?.tokens)) sender.tokens.forEach((x) => {
239
+ senderReceipt.changes.push({
240
+ target: x.address,
241
+ action: "transfer",
242
+ value: `-${x.value}`
243
+ });
244
+ receiverReceipt.changes.push({
245
+ target: x.address,
246
+ action: "transfer",
247
+ value: x.value
248
+ });
249
+ });
250
+ if (Array.isArray(receiver?.tokens)) receiver.tokens.forEach((x) => {
251
+ receiverReceipt.changes.push({
252
+ target: x.address,
253
+ action: "transfer",
254
+ value: `-${x.value}`
255
+ });
256
+ senderReceipt.changes.push({
257
+ target: x.address,
258
+ action: "transfer",
259
+ value: x.value
260
+ });
261
+ });
262
+ if (Array.isArray(sender?.assets)) sender.assets.forEach((x) => {
263
+ senderReceipt.changes.push({
264
+ target: x,
265
+ action: "transfer",
266
+ value: "-1"
267
+ });
268
+ receiverReceipt.changes.push({
269
+ target: x,
270
+ action: "transfer",
271
+ value: "1"
272
+ });
273
+ });
274
+ if (Array.isArray(receiver?.assets)) receiver.assets.forEach((x) => {
275
+ receiverReceipt.changes.push({
276
+ target: x,
277
+ action: "transfer",
278
+ value: "-1"
279
+ });
280
+ senderReceipt.changes.push({
281
+ target: x,
282
+ action: "transfer",
283
+ value: "1"
284
+ });
285
+ });
286
+ return [senderReceipt, receiverReceipt];
287
+ };
288
+ const getCreateAssetReceipts = (tx) => {
289
+ return [{
290
+ address: tx.delegator || tx.from,
291
+ changes: [{
292
+ target: tx.itxJson.address,
293
+ action: "create",
294
+ value: "1"
295
+ }]
296
+ }];
297
+ };
298
+ const getMintAssetReceipts = (tx, ctx) => {
299
+ const { assets = [], address, owner } = tx.itxJson;
300
+ const ownerReceipt = {
301
+ address: ctx.ownerAddress || owner,
302
+ changes: [{
303
+ target: address,
304
+ action: "mint",
305
+ value: "1"
306
+ }]
307
+ };
308
+ assets.map((x) => ownerReceipt.changes.push({
309
+ target: x,
310
+ action: "consume",
311
+ value: "-1"
312
+ }));
313
+ return [ownerReceipt];
314
+ };
315
+ const getAcquireAssetReceipts = (tx, ctx) => {
316
+ const { assets = [], address } = tx.itxJson;
317
+ const ownerReceipt = {
318
+ address: tx.delegator || tx.from,
319
+ changes: [{
320
+ target: address,
321
+ action: "mint",
322
+ value: "1"
323
+ }]
324
+ };
325
+ const senderReceipt = {
326
+ address: tx.from,
327
+ changes: []
328
+ };
329
+ assets.map((x) => senderReceipt.changes.push({
330
+ target: x,
331
+ action: "consume",
332
+ value: "-1"
333
+ }));
334
+ if (ctx.factoryState) {
335
+ const { value, tokens } = ctx.factoryState.input;
336
+ if (new _ocap_util.BN(value).gt(ZERO)) senderReceipt.changes.push({
337
+ target: "",
338
+ action: "consume",
339
+ value: `-${value}`
340
+ });
341
+ tokens.map((x) => senderReceipt.changes.push({
342
+ target: x.address,
343
+ action: "consume",
344
+ value: `-${x.value}`
345
+ }));
346
+ }
347
+ let mergedReceipts = [ownerReceipt, senderReceipt];
348
+ if (ownerReceipt.address === senderReceipt.address) {
349
+ senderReceipt.changes = [...ownerReceipt.changes, ...senderReceipt.changes];
350
+ mergedReceipts = [senderReceipt];
351
+ }
352
+ return [...mergedReceipts];
353
+ };
354
+ const getAcquireAssetV3Receipts = (tx) => {
355
+ const { inputs, owner, address } = tx.itxJson;
356
+ return [{
357
+ address: owner,
358
+ changes: [{
359
+ target: address,
360
+ action: "mint",
361
+ value: "1"
362
+ }]
363
+ }, ...getReceiptsFromTxInput(inputs, "-", "consume")];
364
+ };
365
+ const getStakeReceipts = (tx) => {
366
+ const { inputs, address } = tx.itxJson;
367
+ const tokens = {};
368
+ const assets = [];
369
+ inputs.forEach((input) => {
370
+ input.tokens.forEach((x) => {
371
+ if (typeof tokens[x.address] === "undefined") tokens[x.address] = new _ocap_util.BN(0);
372
+ tokens[x.address] = tokens[x.address].add(new _ocap_util.BN(x.value));
373
+ });
374
+ assets.push(...input.assets);
375
+ });
376
+ const stakeReceipt = {
377
+ address,
378
+ changes: []
379
+ };
380
+ assets.forEach((x) => stakeReceipt.changes.push({
381
+ target: x,
382
+ action: "stake",
383
+ value: "1"
384
+ }));
385
+ Object.keys(tokens).forEach((x) => stakeReceipt.changes.push({
386
+ target: x,
387
+ action: "stake",
388
+ value: tokens[x].toString(10)
389
+ }));
390
+ return [stakeReceipt, ...getReceiptsFromTxInput(inputs, "-", "stake")];
391
+ };
392
+ const getClaimStakeReceipts = (tx, ctx, action) => {
393
+ const { address } = tx.itxJson;
394
+ const { outputs } = ctx;
395
+ const tokens = {};
396
+ const assets = [];
397
+ outputs.forEach((output) => {
398
+ (0, _ocap_util_lib_get_list_field.getListField)(output, "tokens").forEach((x) => {
399
+ if (typeof tokens[x.address] === "undefined") tokens[x.address] = new _ocap_util.BN(0);
400
+ tokens[x.address] = tokens[x.address].add(new _ocap_util.BN(x.value));
401
+ });
402
+ assets.push(...(0, _ocap_util_lib_get_list_field.getListField)(output, "assets"));
403
+ });
404
+ const stakeReceipt = {
405
+ address,
406
+ changes: []
407
+ };
408
+ assets.forEach((x) => stakeReceipt.changes.push({
409
+ target: x,
410
+ action,
411
+ value: "-1"
412
+ }));
413
+ Object.keys(tokens).forEach((x) => stakeReceipt.changes.push({
414
+ target: x,
415
+ action,
416
+ value: `-${tokens[x].toString(10)}`
417
+ }));
418
+ return [stakeReceipt, ...getReceiptsFromTxInput(outputs, "", action)];
419
+ };
420
+ const getCreateTokenReceipts = (tx) => {
421
+ const { initialSupply, address } = tx.itxJson;
422
+ const balance = new _ocap_util.BN(initialSupply).toString();
423
+ return [{
424
+ address: tx.delegator || tx.from,
425
+ changes: [{
426
+ target: address,
427
+ action: "mint",
428
+ value: balance
429
+ }]
430
+ }];
431
+ };
432
+ const getMintTokenReceipts = (tx, ctx) => {
433
+ const { inputChanges, tokenFactoryState } = ctx;
434
+ const { reserveAddress, tokenAddress, owner } = tokenFactoryState;
435
+ const hasFee = new _ocap_util.BN(ctx.reserveFee || "0").gt(ZERO);
436
+ return inputChanges.map((input) => {
437
+ return {
438
+ address: input.address,
439
+ changes: [{
440
+ target: reserveAddress,
441
+ action: "swap",
442
+ value: input.delta
443
+ }]
444
+ };
445
+ }).concat([{
446
+ address: tx.itxJson.receiver,
447
+ changes: [{
448
+ target: tokenAddress,
449
+ action: "mint",
450
+ value: `${tx.itxJson.amount}`
451
+ }]
452
+ }]).concat(hasFee ? [{
453
+ address: owner,
454
+ changes: [{
455
+ target: reserveAddress,
456
+ action: "fee",
457
+ value: `${ctx.reserveFee}`
458
+ }]
459
+ }] : []);
460
+ };
461
+ const getBurnTokenReceipts = (tx, ctx) => {
462
+ const { inputChanges, tokenFactoryState } = ctx;
463
+ const { reserveAddress, tokenAddress, owner } = tokenFactoryState;
464
+ const fee = new _ocap_util.BN(ctx.reserveFee || "0");
465
+ const receiveAmount = new _ocap_util.BN(ctx.reserveAmount || "0").sub(fee);
466
+ return inputChanges.map((input) => {
467
+ return {
468
+ address: input.address,
469
+ changes: [{
470
+ target: tokenAddress,
471
+ action: "burn",
472
+ value: input.delta
473
+ }]
474
+ };
475
+ }).concat(receiveAmount.gt(ZERO) ? [{
476
+ address: tx.itxJson.receiver,
477
+ changes: [{
478
+ target: reserveAddress,
479
+ action: "swap",
480
+ value: receiveAmount.toString()
481
+ }]
482
+ }] : []).concat(fee.gt(ZERO) ? [{
483
+ address: owner,
484
+ changes: [{
485
+ target: reserveAddress,
486
+ action: "fee",
487
+ value: fee.toString()
488
+ }]
489
+ }] : []);
490
+ };
491
+ const getDepositTokenReceipts = (tx) => [{
492
+ address: tx.itxJson.address,
493
+ changes: [{
494
+ target: "",
495
+ action: "mint",
496
+ value: tx.itxJson.value
497
+ }]
498
+ }];
499
+ const getWithdrawFee = (value) => {
500
+ let fee = new _ocap_util.BN(value).abs().mul(new _ocap_util.BN("1")).div(new _ocap_util.BN("1000"));
501
+ fee = _ocap_util.BN.min(fee, new _ocap_util.BN("100000000000000000000"));
502
+ fee = _ocap_util.BN.max(fee, new _ocap_util.BN("1000000000000000000"));
503
+ return fee;
504
+ };
505
+ const getWithdrawTokenReceipts = (tx) => {
506
+ const fee = getWithdrawFee(tx.itxJson.value);
507
+ return [{
508
+ address: tx.from,
509
+ changes: [{
510
+ target: "",
511
+ action: "lock",
512
+ value: `-${tx.itxJson.value}`
513
+ }, {
514
+ target: "",
515
+ action: "fee",
516
+ value: `-${fee.toString()}`
517
+ }]
518
+ }, {
519
+ address: FORGE_TOKEN_HOLDER,
520
+ changes: [{
521
+ target: "",
522
+ action: "lock",
523
+ value: tx.itxJson.value
524
+ }, {
525
+ target: "",
526
+ action: "fee",
527
+ value: fee.toString()
528
+ }]
529
+ }];
530
+ };
531
+ const getRevokeWithdrawReceipts = (tx, ctx) => {
532
+ const { withdrawTx } = ctx;
533
+ if (!withdrawTx?.tx?.from) return [];
534
+ if (withdrawTx.hash !== tx.itxJson.withdraw_tx_hash) return [];
535
+ const account = withdrawTx.tx.from;
536
+ const lockChange = (withdrawTx.receipts?.find((x) => x.address === account))?.changes?.find((x) => x.action === "lock");
537
+ if (!lockChange) return [];
538
+ const value = new _ocap_util.BN(lockChange.value).abs();
539
+ const fee = getWithdrawFee(value.toString());
540
+ const revokeFee = fee.mul(new _ocap_util.BN("5")).div(new _ocap_util.BN("100"));
541
+ return [
542
+ {
543
+ address: account,
544
+ changes: [{
545
+ target: "",
546
+ action: "unlock",
547
+ value: value.toString()
548
+ }, {
549
+ target: "",
550
+ action: "fee",
551
+ value: fee.sub(revokeFee).toString()
552
+ }]
553
+ },
554
+ {
555
+ address: FORGE_TOKEN_HOLDER,
556
+ changes: [{
557
+ target: "",
558
+ action: "unlock",
559
+ value: `-${value.toString()}`
560
+ }, {
561
+ target: "",
562
+ action: "fee",
563
+ value: `-${fee.toString()}`
564
+ }]
565
+ },
566
+ {
567
+ address: FORGE_FEE_RECEIVER,
568
+ changes: [{
569
+ target: "",
570
+ action: "fee",
571
+ value: revokeFee.toString()
572
+ }]
573
+ }
574
+ ];
575
+ };
576
+ const getApproveWithdrawReceipts = (tx, ctx) => {
577
+ const { withdrawTx } = ctx;
578
+ if (!withdrawTx?.tx?.itxJson?.value) return [];
579
+ if (withdrawTx.hash !== tx.itxJson.withdraw_tx_hash) return [];
580
+ const { value } = withdrawTx.tx.itxJson;
581
+ const fee = getWithdrawFee(value);
582
+ return [{
583
+ address: FORGE_TOKEN_HOLDER,
584
+ changes: [{
585
+ target: "",
586
+ action: "burn",
587
+ value: `-${value}`
588
+ }, {
589
+ target: "",
590
+ action: "fee",
591
+ value: `-${fee.toString()}`
592
+ }]
593
+ }, {
594
+ address: FORGE_FEE_RECEIVER,
595
+ changes: [{
596
+ target: "",
597
+ action: "fee",
598
+ value: fee.toString()
599
+ }]
600
+ }];
601
+ };
602
+ const getSetupSwapReceipts = (tx) => [{
603
+ address: tx.from,
604
+ changes: [new _ocap_util.BN(tx.itxJson.value).gt(ZERO) ? {
605
+ target: "",
606
+ action: "swap",
607
+ value: `-${tx.itxJson.value}`
608
+ } : null, ...tx.itxJson.assets.map((x) => ({
609
+ target: x,
610
+ action: "swap",
611
+ value: "-1"
612
+ }))].filter(Boolean)
613
+ }];
614
+ const getRetrieveSwapReceipts = (tx) => [{
615
+ address: tx.from,
616
+ changes: [new _ocap_util.BN(tx.itxJson.value).gt(ZERO) ? {
617
+ target: "",
618
+ action: "swap",
619
+ value: tx.itxJson.value
620
+ } : null, ...tx.itxJson.assets.map((x) => ({
621
+ target: x,
622
+ action: "swap",
623
+ value: "1"
624
+ }))].filter(Boolean)
625
+ }];
626
+ const getMigrateReceipts = (tx, context) => {
627
+ const fromState = context.fromState || context.senderState;
628
+ if (!fromState?.tokens) return [];
629
+ if (!tx.itxJson?.address) return [];
630
+ const changes = Object.entries(fromState.tokens).filter(([, value]) => value && value !== "0").map(([address, value]) => ({
631
+ target: address,
632
+ action: "migrate",
633
+ value
634
+ }));
635
+ return changes.length ? [{
636
+ address: tx.itxJson.address,
637
+ changes
638
+ }] : [];
639
+ };
640
+ const getDeclareReceipts = (tx, ctx) => {
641
+ const txTime = new Date(ctx.time || "");
642
+ if (!tx.itxJson?.issuer) return [];
643
+ if (!ctx.config?.token) return [];
644
+ if (!ctx.time) return [];
645
+ if (txTime >= QLDB_MIGRATION_TIME) return [];
646
+ const gas = (0, _ocap_util.fromTokenToUnit)("0.5", ctx.config.token.decimal || 18);
647
+ return [{
648
+ address: tx.itxJson.issuer,
649
+ changes: [{
650
+ target: ctx.config.token.address || "",
651
+ action: "gas",
652
+ value: `-${gas.toString()}`
653
+ }]
654
+ }, {
655
+ address: FORGE_FEE_RECEIVER,
656
+ changes: [{
657
+ target: ctx.config.token.address || "",
658
+ action: "gas",
659
+ value: gas.toString()
660
+ }]
661
+ }];
662
+ };
663
+ const mergeTxReceipts = (receipts) => {
664
+ const merged = {};
665
+ receipts.forEach((x) => {
666
+ if (merged[x.address] === void 0) merged[x.address] = x;
667
+ else merged[x.address].changes = [...merged[x.address].changes, ...x.changes];
668
+ });
669
+ return Object.values(merged);
670
+ };
671
+ /**
672
+ * Get list of accounts with migration history
673
+ */
674
+ const getAccountMigrationsFromContext = (ctx) => {
675
+ const migrationAddresses = [];
676
+ for (const [key, state] of Object.entries(ctx)) {
677
+ if (key.endsWith("State") && state && typeof state === "object" && "address" in state) migrationAddresses.push((0, _ocap_util_lib_get_related_addr.getRelatedAddresses)(state));
678
+ if (key.endsWith("States") && Array.isArray(state)) state.forEach((x) => {
679
+ if (x && typeof x === "object" && "address" in x) migrationAddresses.push((0, _ocap_util_lib_get_related_addr.getRelatedAddresses)(x));
680
+ });
681
+ }
682
+ return migrationAddresses;
683
+ };
684
+ /**
685
+ * Group receipts by target
686
+ */
687
+ const groupReceiptsByTarget = (receipts) => {
688
+ const targets = {};
689
+ for (const { address, changes } of receipts) for (const { target, value, action } of changes) {
690
+ if (!targets[target]) targets[target] = [];
691
+ targets[target].push({
692
+ address,
693
+ value: new _ocap_util.BN(value),
694
+ action
695
+ });
696
+ }
697
+ return targets;
698
+ };
699
+ /**
700
+ * Verify transaction receipts
701
+ */
702
+ const verifyTxReceipts = (receipts, typeUrl, ctx = {}) => {
703
+ const targets = groupReceiptsByTarget(receipts);
704
+ const accountsWithMigration = getAccountMigrationsFromContext(ctx);
705
+ const skipActionsForType = {
706
+ MintAssetTx: ["mint", "consume"],
707
+ AcquireAssetV2Tx: ["mint", "consume"],
708
+ AcquireAssetV3Tx: ["mint", "consume"],
709
+ CreateAssetTx: ["create"],
710
+ CreateTokenTx: ["mint"],
711
+ CreateRollupBlockTx: ["burn", "mint"],
712
+ AccountMigrateTx: ["migrate"],
713
+ ApproveWithdrawTx: ["burn"],
714
+ SetupSwapTx: ["swap"],
715
+ RevokeSwapTx: ["swap"],
716
+ RetrieveSwapTx: ["swap"],
717
+ MintTokenTx: [
718
+ "swap",
719
+ "mint",
720
+ "fee"
721
+ ],
722
+ BurnTokenTx: [
723
+ "burn",
724
+ "swap",
725
+ "fee"
726
+ ]
727
+ }[typeUrl] || [];
728
+ for (const [target, changes] of Object.entries(targets)) {
729
+ const filteredChanges = changes.filter(({ action }) => {
730
+ if (!skipActionsForType.includes(action)) return true;
731
+ if (action === "consume" && (0, _arcblock_did.toTypeInfo)(target).role !== RoleType.ROLE_ASSET) return true;
732
+ return false;
733
+ });
734
+ const sum = filteredChanges.reduce((prev, current) => prev.add(current.value), new _ocap_util.BN(0));
735
+ if (!sum.eq(ZERO)) throw new _ocap_util_lib_error.CustomError("INVALID_RECEIPTS_VALUE", `Receipts are not zero-sum, target: ${target}, sum: ${sum}`);
736
+ const accountValue = {};
737
+ for (const { address, value, action } of filteredChanges) {
738
+ const accounts = accountsWithMigration.find((x) => x.includes(address)) || [address];
739
+ for (const account of accounts) {
740
+ const key = `${action}-${account}`;
741
+ const existingValue = accountValue[key];
742
+ if (existingValue && (existingValue.gt(ZERO) && value.lt(ZERO) || existingValue.lt(ZERO) && value.gt(ZERO))) throw new _ocap_util_lib_error.CustomError("INVALID_RECEIPTS_ADDRESS", `Duplicate accounts in receipts, target: ${target}, address: ${address}, action: ${action}`);
743
+ accountValue[key] = value;
744
+ }
745
+ }
746
+ }
747
+ return true;
748
+ };
749
+ /**
750
+ * Create transaction receipts, each receipt has following properties:
751
+ *
752
+ * - address: the entity did that changed
753
+ * - changes:
754
+ * - target: the target address that was changed, can be token address, asset address
755
+ * - action: why the target has changed, such as consume, burn and transfer
756
+ * - value: the amount that has changed
757
+ */
758
+ const getTxReceipts = ({ tx, code }, ctx = {}) => {
759
+ const typeUrl = (0, lodash_upperFirst.default)((0, lodash_camelCase.default)(tx?.itxJson?._type || ""));
760
+ if (code !== "OK") {
761
+ const receiptsFromContext = ctx.gasPaid ? getReceiptsFromContext(ctx) : [];
762
+ const receiptsFromGas = getReceiptsFromGasPaid(tx, {
763
+ ...ctx,
764
+ typeUrl
765
+ });
766
+ return receiptsFromContext.concat(receiptsFromGas);
767
+ }
768
+ let receipts = Array.isArray(ctx.receipts) ? ctx.receipts : [];
769
+ if (["TransferTx", "TransferV2Tx"].includes(typeUrl)) receipts = receipts.concat(getTransferReceipts(tx));
770
+ else if (["TransferV3Tx"].includes(typeUrl)) receipts = receipts.concat(getTransferV3Receipts(tx));
771
+ else if (["ExchangeTx", "ExchangeV2Tx"].includes(typeUrl)) receipts = receipts.concat(getExchangeReceipts(tx, ctx));
772
+ else if (["CreateAssetTx"].includes(typeUrl)) receipts = receipts.concat(getCreateAssetReceipts(tx));
773
+ else if (["MintAssetTx"].includes(typeUrl)) receipts = receipts.concat(getMintAssetReceipts(tx, ctx));
774
+ else if (["AcquireAssetV2Tx"].includes(typeUrl)) receipts = receipts.concat(getAcquireAssetReceipts(tx, ctx));
775
+ else if (["AcquireAssetV3Tx"].includes(typeUrl)) receipts = receipts.concat(getAcquireAssetV3Receipts(tx));
776
+ else if (["CreateTokenTx"].includes(typeUrl)) receipts = receipts.concat(getCreateTokenReceipts(tx));
777
+ else if (["MintTokenTx"].includes(typeUrl)) receipts = receipts.concat(getMintTokenReceipts(tx, ctx));
778
+ else if (["BurnTokenTx"].includes(typeUrl)) receipts = receipts.concat(getBurnTokenReceipts(tx, ctx));
779
+ else if (["DepositTokenTx"].includes(typeUrl)) receipts = receipts.concat(getDepositTokenReceipts(tx));
780
+ else if (["WithdrawTokenTx"].includes(typeUrl)) receipts = receipts.concat(getWithdrawTokenReceipts(tx));
781
+ else if (["SetupSwapTx"].includes(typeUrl)) receipts = receipts.concat(getSetupSwapReceipts(tx));
782
+ else if (["RetrieveSwapTx", "RevokeSwapTx"].includes(typeUrl)) receipts = receipts.concat(getRetrieveSwapReceipts(tx));
783
+ else if (["StakeTx"].includes(typeUrl)) receipts = receipts.concat(getStakeReceipts(tx));
784
+ else if (["ClaimStakeTx"].includes(typeUrl)) receipts = receipts.concat(getClaimStakeReceipts(tx, ctx, "claim"));
785
+ else if (["SlashStakeTx"].includes(typeUrl)) receipts = receipts.concat(getClaimStakeReceipts(tx, ctx, "slash"));
786
+ else if (["ReturnStakeTx"].includes(typeUrl)) receipts = receipts.concat(getClaimStakeReceipts(tx, ctx, "stake"));
787
+ else if (["RevokeWithdrawTx"].includes(typeUrl)) receipts = receipts.concat(getRevokeWithdrawReceipts(tx, ctx));
788
+ else if (["ApproveWithdrawTx"].includes(typeUrl)) receipts = receipts.concat(getApproveWithdrawReceipts(tx, ctx));
789
+ else if (["AccountMigrateTx"].includes(typeUrl)) receipts = receipts.concat(getMigrateReceipts(tx, ctx));
790
+ else if (["DeclareTx"].includes(typeUrl)) receipts = receipts.concat(getDeclareReceipts(tx, ctx));
791
+ receipts = receipts.concat(getReceiptsFromContext(ctx));
792
+ receipts = receipts.concat(getReceiptsFromGasPaid(tx, {
793
+ ...ctx,
794
+ typeUrl
795
+ }));
796
+ const merged = mergeTxReceipts(receipts).filter((x) => x.address && Array.isArray(x.changes) && x.changes.length);
797
+ const tokenAddr = (0, lodash_get.default)(ctx, "config.token.address", "");
798
+ if (tokenAddr) merged.forEach((x) => x.changes.forEach((c) => {
799
+ if (c.target === "") c.target = tokenAddr;
800
+ }));
801
+ return merged;
802
+ };
803
+ const create = (context, code = "OK", verifyReceipts = true) => {
804
+ const { txHash, txTime, tx, totalGas, itxExtras = {}, extra = {} } = context;
805
+ const itx = (0, _ocap_message.decodeAny)(tx.itx).value;
806
+ const typeUrl = (0, _ocap_message.fromTypeUrl)(tx.itx.typeUrl);
807
+ const typeName = tx.itx.typeUrl.split(":").pop() || "";
808
+ const itxJson = (0, _ocap_message.formatMessage)(typeUrl, itx);
809
+ const result = {
810
+ code,
811
+ hash: txHash,
812
+ height: 0,
813
+ index: 0,
814
+ time: txTime,
815
+ sender: getTxSender({
816
+ tx,
817
+ itx,
818
+ typeUrl
819
+ }),
820
+ receiver: getTxReceiver({
821
+ tx,
822
+ itx,
823
+ typeUrl
824
+ }),
825
+ type: typeName,
826
+ tx: {
827
+ chainId: tx.chainId,
828
+ delegator: tx.delegator,
829
+ from: tx.from,
830
+ nonce: tx.nonce,
831
+ serviceFee: tx.serviceFee || "0",
832
+ gasFee: (0, _ocap_util.isBN)(totalGas) ? totalGas.toString(10) : "0",
833
+ pk: tx.pk ? (0, _ocap_util.toBase64)(tx.pk) : void 0,
834
+ signature: tx.signature ? (0, _ocap_util.toBase64)(tx.signature) : void 0,
835
+ signatures: (0, _ocap_util_lib_get_list_field.getListField)(tx, "signatures").map((x) => (0, _ocap_message.formatMessage)("Multisig", x)),
836
+ itx: { __typename: typeUrl },
837
+ itxJson: {
838
+ _type: typeUrl,
839
+ encoded_value: tx.itx.value,
840
+ type_url: tx.itx.typeUrl,
841
+ ...itxJson,
842
+ ...itxExtras,
843
+ data: itx.data || null
844
+ },
845
+ extra: extra.txExtra || null
846
+ }
847
+ };
848
+ result.receipts = getTxReceipts(result, context);
849
+ if (code === "OK" && verifyReceipts) try {
850
+ verifyTxReceipts(result.receipts, typeUrl, context);
851
+ result.receiptsVerified = true;
852
+ } catch (err) {
853
+ console.warn(JSON.stringify(result, null));
854
+ console.error("verifyTxReceipts error", err);
855
+ result.receiptsVerified = false;
856
+ }
857
+ attachPaidTxGas(result);
858
+ return result;
859
+ };
860
+ const attachPaidTxGas = (tx) => {
861
+ if (tx.tx.gasPaid) return tx;
862
+ let gasChange = null;
863
+ (tx.receipts || []).forEach((r) => {
864
+ const tmp = r.changes.find((c) => c.action === "gas" && c.value === tx.tx.gasFee);
865
+ if (tmp) gasChange = tmp;
866
+ });
867
+ tx.tx.gasPaid = gasChange ? tx.tx.gasFee : "0";
868
+ return tx;
869
+ };
870
+ const update = (state, updates) => (0, lodash_merge.default)(state, (0, lodash_pick.default)(updates, ["finalized", "tx.itxJson.actualFee"]));
871
+
872
+ //#endregion
873
+ exports.FORGE_TOKEN_HOLDER = FORGE_TOKEN_HOLDER;
874
+ exports.attachPaidTxGas = attachPaidTxGas;
875
+ exports.create = create;
876
+ exports.eachReceipts = eachReceipts;
877
+ exports.getTxReceipts = getTxReceipts;
878
+ exports.getTxReceiver = getTxReceiver;
879
+ exports.getTxSender = getTxSender;
880
+ exports.groupReceiptTokenChanges = groupReceiptTokenChanges;
881
+ exports.mergeTxReceipts = mergeTxReceipts;
882
+ Object.defineProperty(exports, 'tx_exports', {
883
+ enumerable: true,
884
+ get: function () {
885
+ return tx_exports;
886
+ }
887
+ });
888
+ exports.update = update;
889
+ exports.verifyTxReceipts = verifyTxReceipts;