@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.
- package/esm/_virtual/rolldown_runtime.mjs +18 -0
- package/esm/contexts/state.d.mts +15 -0
- package/esm/contexts/state.mjs +17 -0
- package/esm/index.d.mts +20 -0
- package/esm/index.mjs +47 -0
- package/esm/states/account.d.mts +18 -0
- package/esm/states/account.mjs +91 -0
- package/esm/states/asset.d.mts +14 -0
- package/esm/states/asset.mjs +80 -0
- package/esm/states/blacklist.d.mts +36 -0
- package/esm/states/blacklist.mjs +71 -0
- package/esm/states/chain.d.mts +30 -0
- package/esm/states/chain.mjs +52 -0
- package/esm/states/delegation.d.mts +11 -0
- package/esm/states/delegation.mjs +42 -0
- package/esm/states/evidence.d.mts +12 -0
- package/esm/states/evidence.mjs +35 -0
- package/esm/states/factory.d.mts +12 -0
- package/esm/states/factory.mjs +76 -0
- package/esm/states/rollup-block.d.mts +13 -0
- package/esm/states/rollup-block.mjs +75 -0
- package/esm/states/rollup.d.mts +18 -0
- package/esm/states/rollup.mjs +215 -0
- package/esm/states/stake.d.mts +13 -0
- package/esm/states/stake.mjs +89 -0
- package/esm/states/token-factory.d.mts +13 -0
- package/esm/states/token-factory.mjs +76 -0
- package/esm/states/token.d.mts +14 -0
- package/esm/states/token.mjs +109 -0
- package/esm/states/tx.d.mts +233 -0
- package/esm/states/tx.mjs +867 -0
- package/esm/util.d.mts +6 -0
- package/esm/util.mjs +18 -0
- package/lib/_virtual/rolldown_runtime.cjs +43 -0
- package/lib/contexts/state.cjs +19 -0
- package/lib/contexts/state.d.cts +15 -0
- package/lib/index.cjs +121 -0
- package/lib/index.d.cts +20 -0
- package/lib/states/account.cjs +106 -0
- package/lib/states/account.d.cts +18 -0
- package/lib/states/asset.cjs +91 -0
- package/lib/states/asset.d.cts +14 -0
- package/lib/states/blacklist.cjs +74 -0
- package/lib/states/blacklist.d.cts +36 -0
- package/lib/states/chain.cjs +62 -0
- package/lib/states/chain.d.cts +30 -0
- package/lib/states/delegation.cjs +50 -0
- package/lib/states/delegation.d.cts +11 -0
- package/lib/states/evidence.cjs +44 -0
- package/lib/states/evidence.d.cts +12 -0
- package/lib/states/factory.cjs +85 -0
- package/lib/states/factory.d.cts +12 -0
- package/lib/states/rollup-block.cjs +85 -0
- package/lib/states/rollup-block.d.cts +13 -0
- package/lib/states/rollup.cjs +230 -0
- package/lib/states/rollup.d.cts +18 -0
- package/lib/states/stake.cjs +99 -0
- package/lib/states/stake.d.cts +13 -0
- package/lib/states/token-factory.cjs +86 -0
- package/lib/states/token-factory.d.cts +13 -0
- package/lib/states/token.cjs +121 -0
- package/lib/states/token.d.cts +14 -0
- package/lib/states/tx.cjs +889 -0
- package/lib/states/tx.d.cts +233 -0
- package/lib/util.cjs +19 -0
- package/lib/util.d.cts +6 -0
- package/package.json +46 -14
- package/lib/contexts/state.js +0 -19
- package/lib/index.js +0 -63
- package/lib/states/account.js +0 -95
- package/lib/states/asset.js +0 -91
- package/lib/states/blacklist.js +0 -103
- package/lib/states/chain.js +0 -49
- package/lib/states/delegation.js +0 -46
- package/lib/states/evidence.js +0 -35
- package/lib/states/factory.js +0 -92
- package/lib/states/rollup-block.js +0 -84
- package/lib/states/rollup.js +0 -297
- package/lib/states/stake.js +0 -83
- package/lib/states/token-factory.js +0 -74
- package/lib/states/token.js +0 -124
- package/lib/states/tx.js +0 -896
- 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;
|