@metamask-previews/transaction-controller 56.3.0-preview-e9f8bc88 → 57.0.0-preview-39fa8d37

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 (42) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/dist/TransactionController.cjs +17 -55
  3. package/dist/TransactionController.cjs.map +1 -1
  4. package/dist/TransactionController.d.cts.map +1 -1
  5. package/dist/TransactionController.d.mts.map +1 -1
  6. package/dist/TransactionController.mjs +20 -58
  7. package/dist/TransactionController.mjs.map +1 -1
  8. package/dist/api/simulation-api.cjs.map +1 -1
  9. package/dist/api/simulation-api.d.cts +22 -5
  10. package/dist/api/simulation-api.d.cts.map +1 -1
  11. package/dist/api/simulation-api.d.mts +22 -5
  12. package/dist/api/simulation-api.d.mts.map +1 -1
  13. package/dist/api/simulation-api.mjs.map +1 -1
  14. package/dist/types.cjs.map +1 -1
  15. package/dist/types.d.cts +2 -0
  16. package/dist/types.d.cts.map +1 -1
  17. package/dist/types.d.mts +2 -0
  18. package/dist/types.d.mts.map +1 -1
  19. package/dist/types.mjs.map +1 -1
  20. package/dist/utils/{simulation.cjs → balance-changes.cjs} +103 -112
  21. package/dist/utils/balance-changes.cjs.map +1 -0
  22. package/dist/utils/balance-changes.d.cts +30 -0
  23. package/dist/utils/balance-changes.d.cts.map +1 -0
  24. package/dist/utils/balance-changes.d.mts +30 -0
  25. package/dist/utils/balance-changes.d.mts.map +1 -0
  26. package/dist/utils/{simulation.mjs → balance-changes.mjs} +107 -111
  27. package/dist/utils/balance-changes.mjs.map +1 -0
  28. package/dist/utils/gas-fee-tokens.cjs +123 -0
  29. package/dist/utils/gas-fee-tokens.cjs.map +1 -0
  30. package/dist/utils/gas-fee-tokens.d.cts +22 -0
  31. package/dist/utils/gas-fee-tokens.d.cts.map +1 -0
  32. package/dist/utils/gas-fee-tokens.d.mts +22 -0
  33. package/dist/utils/gas-fee-tokens.d.mts.map +1 -0
  34. package/dist/utils/gas-fee-tokens.mjs +119 -0
  35. package/dist/utils/gas-fee-tokens.mjs.map +1 -0
  36. package/package.json +3 -3
  37. package/dist/utils/simulation.cjs.map +0 -1
  38. package/dist/utils/simulation.d.cts +0 -60
  39. package/dist/utils/simulation.d.cts.map +0 -1
  40. package/dist/utils/simulation.d.mts +0 -60
  41. package/dist/utils/simulation.d.mts.map +0 -1
  42. package/dist/utils/simulation.mjs.map +0 -1
@@ -1,10 +1,14 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getEvents = exports.getSimulationData = exports.SupportedToken = void 0;
6
+ exports.getBalanceChanges = exports.SupportedToken = void 0;
4
7
  const abi_1 = require("@ethersproject/abi");
5
8
  const controller_utils_1 = require("@metamask/controller-utils");
6
9
  const metamask_eth_abis_1 = require("@metamask/metamask-eth-abis");
7
10
  const utils_1 = require("@metamask/utils");
11
+ const bn_js_1 = __importDefault(require("bn.js"));
8
12
  const simulation_api_1 = require("../api/simulation-api.cjs");
9
13
  const constants_1 = require("../constants.cjs");
10
14
  const errors_1 = require("../errors.cjs");
@@ -18,7 +22,7 @@ var SupportedToken;
18
22
  SupportedToken["ERC20_WRAPPED"] = "erc20Wrapped";
19
23
  SupportedToken["ERC721_LEGACY"] = "erc721Legacy";
20
24
  })(SupportedToken || (exports.SupportedToken = SupportedToken = {}));
21
- const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'simulation');
25
+ const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'balance-changes');
22
26
  const SUPPORTED_EVENTS = [
23
27
  'Transfer',
24
28
  'TransferSingle',
@@ -58,102 +62,71 @@ const REVERTED_ERRORS = ['execution reverted', 'insufficient funds for gas'];
58
62
  * @param request.to - The recipient of the transaction.
59
63
  * @param request.value - The value of the transaction.
60
64
  * @param request.data - The data of the transaction.
61
- * @param options - Additional options.
62
- * @param options.blockTime - An optional block time to simulate the transaction at.
63
65
  * @returns The simulation data.
64
66
  */
65
- async function getSimulationData(request, options = {}) {
66
- const { authorizationList, chainId, from, to, value, data } = request;
67
- const { use7702Fees } = options;
68
- log('Getting simulation data', { request, options });
67
+ async function getBalanceChanges(request) {
68
+ log('Request', request);
69
69
  try {
70
70
  const response = await baseRequest({
71
- chainId,
72
- from,
73
- options,
71
+ request,
74
72
  params: {
75
- suggestFees: {
76
- withFeeTransfer: true,
77
- withTransfer: true,
78
- ...(use7702Fees ? { with7702: true } : {}),
79
- },
80
73
  withCallTrace: true,
81
74
  withLogs: true,
82
75
  },
83
- transactions: [
84
- {
85
- authorizationList,
86
- data,
87
- from,
88
- to,
89
- value,
90
- },
91
- ],
92
76
  });
93
77
  const transactionError = response.transactions?.[0]?.error;
94
78
  if (transactionError) {
95
79
  throw new errors_1.SimulationError(transactionError);
96
80
  }
97
- const nativeBalanceChange = getNativeBalanceChange(request.from, response);
81
+ const nativeBalanceChange = getNativeBalanceChange(request, response);
98
82
  const events = getEvents(response);
99
83
  log('Parsed events', events);
100
- const tokenBalanceChanges = await getTokenBalanceChanges(request, events, options);
84
+ const tokenBalanceChanges = await getTokenBalanceChanges(request, events);
101
85
  const simulationData = {
102
86
  nativeBalanceChange,
103
87
  tokenBalanceChanges,
104
88
  };
105
- let gasFeeTokens = [];
106
- try {
107
- gasFeeTokens = getGasFeeTokens(response);
108
- }
109
- catch (error) {
110
- log('Failed to parse gas fee tokens', error, response);
111
- }
112
- return {
113
- gasFeeTokens,
114
- simulationData,
115
- };
89
+ return simulationData;
116
90
  }
117
91
  catch (error) {
118
- log('Failed to get simulation data', error, request);
92
+ log('Failed to get balance changes', error, request);
119
93
  let simulationError = error;
120
94
  if (REVERTED_ERRORS.some((revertErrorMessage) => simulationError.message?.includes(revertErrorMessage))) {
121
95
  simulationError = new errors_1.SimulationRevertedError();
122
96
  }
123
97
  const { code, message } = simulationError;
124
98
  return {
125
- gasFeeTokens: [],
126
- simulationData: {
127
- tokenBalanceChanges: [],
128
- error: {
129
- code,
130
- message,
131
- },
99
+ tokenBalanceChanges: [],
100
+ error: {
101
+ code,
102
+ message,
132
103
  },
133
104
  };
134
105
  }
135
106
  }
136
- exports.getSimulationData = getSimulationData;
107
+ exports.getBalanceChanges = getBalanceChanges;
137
108
  /**
138
109
  * Extract the native balance change from a simulation response.
139
110
  *
140
- * @param userAddress - The user's account address.
141
- * @param response - The simulation response.
142
- * @returns The native balance change or undefined if unchanged.
111
+ * @param request - Simulation request.
112
+ * @param response - Simulation response.
113
+ * @returns Native balance change or undefined if unchanged.
143
114
  */
144
- function getNativeBalanceChange(userAddress, response) {
115
+ function getNativeBalanceChange(request, response) {
145
116
  const transactionResponse = response.transactions[0];
146
117
  /* istanbul ignore next */
147
118
  if (!transactionResponse) {
148
119
  return undefined;
149
120
  }
121
+ const { txParams } = request;
122
+ const userAddress = txParams.from;
150
123
  const { stateDiff } = transactionResponse;
151
124
  const previousBalance = stateDiff?.pre?.[userAddress]?.balance;
152
125
  const newBalance = stateDiff?.post?.[userAddress]?.balance;
153
126
  if (!previousBalance || !newBalance) {
154
127
  return undefined;
155
128
  }
156
- return getSimulationBalanceChange(previousBalance, newBalance);
129
+ return getSimulationBalanceChange(previousBalance, newBalance, transactionResponse.gasCost);
157
130
  }
158
131
  /**
159
132
  * Extract events from a simulation response.
@@ -196,7 +169,6 @@ function getEvents(response) {
196
169
  })
197
170
  .filter((e) => e !== undefined);
198
171
  }
199
- exports.getEvents = getEvents;
200
172
  /**
201
173
  * Normalize event arguments using ABI input definitions.
202
174
  *
@@ -233,30 +205,24 @@ function normalizeEventArgValue(value) {
233
205
  *
234
206
  * @param request - The transaction that was simulated.
235
207
  * @param events - The parsed events.
236
- * @param options - Additional options.
237
- * @param options.blockTime - An optional block time to simulate the transaction at.
238
208
  * @returns An array of token balance changes.
239
209
  */
240
- async function getTokenBalanceChanges(request, events, options) {
241
- const { chainId, from } = request;
210
+ async function getTokenBalanceChanges(request, events) {
211
+ const { txParams } = request;
212
+ const from = txParams.from;
242
213
  const balanceTxs = getTokenBalanceTransactions(request, events);
243
214
  log('Generated balance transactions', [...balanceTxs.after.values()]);
244
- const transactions = [
245
- ...balanceTxs.before.values(),
246
- request,
247
- ...balanceTxs.after.values(),
248
- ];
249
- if (transactions.length === 1) {
215
+ const transactionCount = balanceTxs.before.size + balanceTxs.after.size + 1;
216
+ if (transactionCount === 1) {
250
217
  return [];
251
218
  }
252
219
  const response = await baseRequest({
253
- chainId,
254
- from,
255
- options,
256
- transactions,
220
+ request,
221
+ before: [...balanceTxs.before.values()],
222
+ after: [...balanceTxs.after.values()],
257
223
  });
258
224
  log('Balance simulation response', response);
259
- if (response.transactions.length !== transactions.length) {
225
+ if (response.transactions.length !== transactionCount) {
260
226
  throw new errors_1.SimulationInvalidResponseError();
261
227
  }
262
228
  let prevBalanceTxIndex = 0;
@@ -265,10 +231,10 @@ async function getTokenBalanceChanges(request, events, options) {
265
231
  const previousBalanceCheckSkipped = !balanceTxs.before.get(token);
266
232
  const previousBalance = previousBalanceCheckSkipped
267
233
  ? '0x0'
268
- : getAmountFromBalanceTransactionResult(request.from, token,
234
+ : getAmountFromBalanceTransactionResult(from, token,
269
235
  // eslint-disable-next-line no-plusplus
270
236
  response.transactions[prevBalanceTxIndex++]);
271
- const newBalance = getAmountFromBalanceTransactionResult(request.from, token, response.transactions[index + balanceTxs.before.size + 1]);
237
+ const newBalance = getAmountFromBalanceTransactionResult(from, token, response.transactions[index + balanceTxs.before.size + 1]);
272
238
  const balanceChange = getSimulationBalanceChange(previousBalance, newBalance);
273
239
  if (!balanceChange) {
274
240
  return undefined;
@@ -291,7 +257,8 @@ function getTokenBalanceTransactions(request, events) {
291
257
  const tokenKeys = new Set();
292
258
  const before = new Map();
293
259
  const after = new Map();
294
- const userEvents = events.filter((event) => [event.args.from, event.args.to].includes(request.from));
260
+ const from = request.txParams.from;
261
+ const userEvents = events.filter((event) => [event.args.from, event.args.to].includes(from));
295
262
  log('Filtered user events', userEvents);
296
263
  for (const event of userEvents) {
297
264
  const tokenIds = getEventTokenIds(event);
@@ -308,9 +275,9 @@ function getTokenBalanceTransactions(request, events) {
308
275
  continue;
309
276
  }
310
277
  tokenKeys.add(tokenKey);
311
- const data = getBalanceTransactionData(event.tokenStandard, request.from, tokenId);
278
+ const data = getBalanceTransactionData(event.tokenStandard, from, tokenId);
312
279
  const transaction = {
313
- from: request.from,
280
+ from,
314
281
  to: event.contractAddress,
315
282
  data,
316
283
  };
@@ -466,10 +433,13 @@ function extractLogs(call) {
466
433
  *
467
434
  * @param previousBalance - The previous balance.
468
435
  * @param newBalance - The new balance.
436
+ * @param offset - Optional offset to apply to the new balance.
469
437
  * @returns The balance change data or undefined if unchanged.
470
438
  */
471
- function getSimulationBalanceChange(previousBalance, newBalance) {
472
- const differenceBN = (0, controller_utils_1.hexToBN)(newBalance).sub((0, controller_utils_1.hexToBN)(previousBalance));
439
+ function getSimulationBalanceChange(previousBalance, newBalance, offset = 0) {
440
+ const newBalanceBN = (0, controller_utils_1.hexToBN)(newBalance).add(new bn_js_1.default(offset));
441
+ const previousBalanceBN = (0, controller_utils_1.hexToBN)(previousBalance);
442
+ const differenceBN = newBalanceBN.sub(previousBalanceBN);
473
443
  const isDecrease = differenceBN.isNeg();
474
444
  const difference = (0, controller_utils_1.toHex)(differenceBN.abs());
475
445
  if (differenceBN.isZero()) {
@@ -478,7 +448,7 @@ function getSimulationBalanceChange(previousBalance, newBalance) {
478
448
  }
479
449
  return {
480
450
  previousBalance,
481
- newBalance,
451
+ newBalance: (0, controller_utils_1.toHex)(newBalanceBN),
482
452
  difference,
483
453
  isDecrease,
484
454
  };
@@ -496,61 +466,82 @@ function getContractInterfaces() {
496
466
  return [tokenType, contractInterface];
497
467
  }));
498
468
  }
499
- /**
500
- * Extract gas fee tokens from a simulation response.
501
- *
502
- * @param response - The simulation response.
503
- * @returns An array of gas fee tokens.
504
- */
505
- function getGasFeeTokens(response) {
506
- const feeLevel = response.transactions?.[0]
507
- ?.fees?.[0];
508
- const tokenFees = feeLevel?.tokenFees ?? [];
509
- return tokenFees.map((tokenFee) => ({
510
- amount: tokenFee.balanceNeededToken,
511
- balance: tokenFee.currentBalanceToken,
512
- decimals: tokenFee.token.decimals,
513
- gas: feeLevel.gas,
514
- gasTransfer: tokenFee.transferEstimate,
515
- maxFeePerGas: feeLevel.maxFeePerGas,
516
- maxPriorityFeePerGas: feeLevel.maxPriorityFeePerGas,
517
- rateWei: tokenFee.rateWei,
518
- recipient: tokenFee.feeRecipient,
519
- symbol: tokenFee.token.symbol,
520
- tokenAddress: tokenFee.token.address,
521
- }));
522
- }
523
469
  /**
524
470
  * Base request to simulation API.
525
471
  *
526
- * @param request - The request object.
527
- * @param request.chainId - Chain ID of the transaction.
528
- * @param request.from - Address of the sender.
529
- * @param request.options - Options for the simulation.
530
- * @param request.params - Additional parameters for the request.
531
- * @param request.transactions - Transactions to simulate.
472
+ * @param options - Options bag.
473
+ * @param options.after - Transactions to simulate after user's transaction.
474
+ * @param options.before - Transactions to simulate before user's transaction.
475
+ * @param options.params - Additional parameters for the request.
476
+ * @param options.request - Original request object.
532
477
  * @returns The simulation response.
533
478
  */
534
- async function baseRequest({ chainId, from, options, params, transactions, }) {
535
- const { blockTime, senderCode } = options;
479
+ async function baseRequest({ request, params, before = [], after = [], }) {
480
+ const { blockTime, chainId, ethQuery, txParams } = request;
481
+ const { authorizationList } = txParams;
482
+ const from = txParams.from;
483
+ const authorizationListFinal = authorizationList?.map((authorization) => ({
484
+ address: authorization.address,
485
+ from,
486
+ }));
487
+ const userTransaction = {
488
+ authorizationList: authorizationListFinal,
489
+ data: txParams.data,
490
+ from: txParams.from,
491
+ gas: txParams.gas,
492
+ maxFeePerGas: (txParams.maxFeePerGas ?? txParams.gasPrice),
493
+ maxPriorityFeePerGas: (txParams.maxPriorityFeePerGas ??
494
+ txParams.gasPrice),
495
+ to: txParams.to,
496
+ value: txParams.value,
497
+ };
498
+ const transactions = [...before, userTransaction, ...after];
499
+ const requiredBalanceBN = getRequiredBalance(request);
500
+ const requiredBalanceHex = (0, controller_utils_1.toHex)(requiredBalanceBN);
501
+ log('Required balance', requiredBalanceHex);
502
+ const currentBalanceHex = (await (0, controller_utils_1.query)(ethQuery, 'getBalance', [
503
+ from,
504
+ 'latest',
505
+ ]));
506
+ const currentBalanceBN = (0, controller_utils_1.hexToBN)(currentBalanceHex);
507
+ log('Current balance', currentBalanceHex);
508
+ const isInsufficientBalance = currentBalanceBN.lt(requiredBalanceBN);
536
509
  return await (0, simulation_api_1.simulateTransactions)(chainId, {
537
- transactions,
538
510
  ...params,
511
+ transactions,
512
+ withGas: true,
513
+ withDefaultBlockOverrides: true,
539
514
  ...(blockTime && {
540
515
  blockOverrides: {
541
516
  ...params?.blockOverrides,
542
517
  time: (0, controller_utils_1.toHex)(blockTime),
543
518
  },
544
519
  }),
545
- ...(senderCode && {
520
+ ...(isInsufficientBalance && {
546
521
  overrides: {
547
522
  ...params?.overrides,
548
523
  [from]: {
549
524
  ...params?.overrides?.[from],
550
- code: senderCode,
525
+ balance: requiredBalanceHex,
551
526
  },
552
527
  },
553
528
  }),
554
529
  });
555
530
  }
556
- //# sourceMappingURL=simulation.cjs.map
531
+ /**
532
+ * Calculate the required minimum balance for a transaction.
533
+ *
534
+ * @param request - The transaction request.
535
+ * @returns The minimal balance as a BN.
536
+ */
537
+ function getRequiredBalance(request) {
538
+ const { txParams } = request;
539
+ const gasLimit = (0, controller_utils_1.hexToBN)(txParams.gas ?? '0x0');
540
+ const gasPrice = (0, controller_utils_1.hexToBN)(txParams.maxFeePerGas ?? txParams.gasPrice ?? '0x0');
541
+ const value = (0, controller_utils_1.hexToBN)(txParams.value ?? '0x0');
542
+ const nestedValue = (request.nestedTransactions ?? [])
543
+ .map((tx) => (0, controller_utils_1.hexToBN)(tx.value ?? '0x0'))
544
+ .reduce((acc, val) => acc.add(val), new bn_js_1.default(0));
545
+ return gasLimit.mul(gasPrice).add(value).add(nestedValue);
546
+ }
547
+ //# sourceMappingURL=balance-changes.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance-changes.cjs","sourceRoot":"","sources":["../../src/utils/balance-changes.ts"],"names":[],"mappings":";;;;;;AACA,4CAA+C;AAC/C,iEAAmE;AAEnE,mEAA8E;AAC9E,2CAA+D;AAC/D,kDAAuB;AAEvB,8DAA6D;AAS7D,gDAGsB;AACtB,0CAImB;AACnB,0CAA0C;AAS1C,wCAAmD;AAEnD,IAAY,cAMX;AAND,WAAY,cAAc;IACxB,iCAAe,CAAA;IACf,mCAAiB,CAAA;IACjB,qCAAmB,CAAA;IACnB,gDAA8B,CAAA;IAC9B,gDAA8B,CAAA;AAChC,CAAC,EANW,cAAc,8BAAd,cAAc,QAMzB;AAoBD,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAa,EAAE,iBAAiB,CAAC,CAAC;AAEjE,MAAM,gBAAgB,GAAG;IACvB,UAAU;IACV,gBAAgB;IAChB,eAAe;IACf,SAAS;IACT,YAAY;CACb,CAAC;AAEF,MAAM,oBAAoB,GAAG;IAC3B,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE;QACtB,GAAG,EAAE,4BAAQ;QACb,QAAQ,EAAE,+BAAuB,CAAC,KAAK;KACxC;IACD,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE;QACvB,GAAG,EAAE,6BAAS;QACd,QAAQ,EAAE,+BAAuB,CAAC,MAAM;KACzC;IACD,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE;QACxB,GAAG,EAAE,8BAAU;QACf,QAAQ,EAAE,+BAAuB,CAAC,OAAO;KAC1C;IACD,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE;QAC9B,GAAG,EAAE,wCAA4B;QACjC,QAAQ,EAAE,+BAAuB,CAAC,KAAK;KACxC;IACD,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE;QAC9B,GAAG,EAAE,wCAA4B;QACjC,QAAQ,EAAE,+BAAuB,CAAC,MAAM;KACzC;CACF,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,oBAAoB,EAAE,4BAA4B,CAAC,CAAC;AAI7E;;;;;;;;;;GAUG;AACI,KAAK,UAAU,iBAAiB,CACrC,OAAiC;IAEjC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAExB,IAAI;QACF,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC;YACjC,OAAO;YACP,MAAM,EAAE;gBACN,aAAa,EAAE,IAAI;gBACnB,QAAQ,EAAE,IAAI;aACf;SACF,CAAC,CAAC;QAEH,MAAM,gBAAgB,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;QAE3D,IAAI,gBAAgB,EAAE;YACpB,MAAM,IAAI,wBAAe,CAAC,gBAAgB,CAAC,CAAC;SAC7C;QAED,MAAM,mBAAmB,GAAG,sBAAsB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QAEnC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QAE7B,MAAM,mBAAmB,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAE1E,MAAM,cAAc,GAAG;YACrB,mBAAmB;YACnB,mBAAmB;SACpB,CAAC;QAEF,OAAO,cAAc,CAAC;KACvB;IAAC,OAAO,KAAK,EAAE;QACd,GAAG,CAAC,+BAA+B,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAErD,IAAI,eAAe,GAAG,KAAwB,CAAC;QAE/C,IACE,eAAe,CAAC,IAAI,CAAC,CAAC,kBAAkB,EAAE,EAAE,CAC1C,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CACtD,EACD;YACA,eAAe,GAAG,IAAI,gCAAuB,EAAE,CAAC;SACjD;QAED,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,eAAe,CAAC;QAE1C,OAAO;YACL,mBAAmB,EAAE,EAAE;YACvB,KAAK,EAAE;gBACL,IAAI;gBACJ,OAAO;aACR;SACF,CAAC;KACH;AACH,CAAC;AAxDD,8CAwDC;AAED;;;;;;GAMG;AACH,SAAS,sBAAsB,CAC7B,OAAiC,EACjC,QAA4B;IAE5B,MAAM,mBAAmB,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAErD,0BAA0B;IAC1B,IAAI,CAAC,mBAAmB,EAAE;QACxB,OAAO,SAAS,CAAC;KAClB;IAED,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC7B,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAW,CAAC;IACzC,MAAM,EAAE,SAAS,EAAE,GAAG,mBAAmB,CAAC;IAC1C,MAAM,eAAe,GAAG,SAAS,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/D,MAAM,UAAU,GAAG,SAAS,EAAE,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAE3D,IAAI,CAAC,eAAe,IAAI,CAAC,UAAU,EAAE;QACnC,OAAO,SAAS,CAAC;KAClB;IAED,OAAO,0BAA0B,CAC/B,eAAe,EACf,UAAU,EACV,mBAAmB,CAAC,OAAO,CAC5B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,SAAS,CAAC,QAA4B;IAC7C,0BAA0B;IAC1B,MAAM,IAAI,GAAG,WAAW,CACtB,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,SAAS,IAAK,EAAkC,CAC3E,CAAC;IAEF,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IAE5B,MAAM,UAAU,GAAG,qBAAqB,EAAE,CAAC;IAE3C,OAAO,IAAI;SACR,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;QAClB,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAE/C,IAAI,CAAC,KAAK,EAAE;YACV,GAAG,CAAC,qBAAqB,EAAE,UAAU,CAAC,CAAC;YACvC,OAAO,SAAS,CAAC;SAClB;QAED,0BAA0B;QAC1B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAEpE,wBAAwB;QACxB,IAAI,CAAC,MAAM,EAAE;YACX,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;YAC9C,OAAO,SAAS,CAAC;SAClB;QAED,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;YAC1C,GAAG,CAAC,4BAA4B,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACrD,OAAO,SAAS,CAAC;SAClB;QAED,GAAG,CAAC,wBAAwB,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAEjD,MAAM,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAEpD,OAAO;YACL,eAAe,EAAE,UAAU,CAAC,OAAO;YACnC,aAAa,EAAE,KAAK,CAAC,QAAQ;YAC7B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI;YACJ,GAAG,EAAE,KAAK,CAAC,GAAG;SACf,CAAC;IACJ,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAkB,CAAC;AACrD,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CACzB,IAAY,EACZ,SAA6B;IAE7B,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QACxC,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAE1C,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAErB,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAED;;;;;GAKG;AACH,8DAA8D;AAC9D,SAAS,sBAAsB,CAAC,KAAU;IACxC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACxB,OAAO,KAAK,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;KAC1C;IAED,IAAI,eAAe,GAAG,KAAK,CAAC;IAE5B,eAAe,GAAG,eAAe,CAAC,WAAW,EAAE,EAAE,IAAI,eAAe,CAAC;IACrE,eAAe,GAAG,eAAe,CAAC,WAAW,EAAE,EAAE,IAAI,eAAe,CAAC;IAErE,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,sBAAsB,CACnC,OAAiC,EACjC,MAAqB;IAErB,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC7B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAW,CAAC;IAClC,MAAM,UAAU,GAAG,2BAA2B,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAEhE,GAAG,CAAC,gCAAgC,EAAE,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAEtE,MAAM,gBAAgB,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;IAE5E,IAAI,gBAAgB,KAAK,CAAC,EAAE;QAC1B,OAAO,EAAE,CAAC;KACX;IAED,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC;QACjC,OAAO;QACP,MAAM,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACvC,KAAK,EAAE,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;KACtC,CAAC,CAAC;IAEH,GAAG,CAAC,6BAA6B,EAAE,QAAQ,CAAC,CAAC;IAE7C,IAAI,QAAQ,CAAC,YAAY,CAAC,MAAM,KAAK,gBAAgB,EAAE;QACrD,MAAM,IAAI,uCAA8B,EAAE,CAAC;KAC5C;IAED,IAAI,kBAAkB,GAAG,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAChC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,2BAA2B,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAClE,MAAM,eAAe,GAAG,2BAA2B;YACjD,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,qCAAqC,CACnC,IAAI,EACJ,KAAK;YACL,uCAAuC;YACvC,QAAQ,CAAC,YAAY,CAAC,kBAAkB,EAAE,CAAC,CAC5C,CAAC;QAEN,MAAM,UAAU,GAAG,qCAAqC,CACtD,IAAI,EACJ,KAAK,EACL,QAAQ,CAAC,YAAY,CAAC,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAC1D,CAAC;QAEF,MAAM,aAAa,GAAG,0BAA0B,CAC9C,eAAe,EACf,UAAU,CACX,CAAC;QAEF,IAAI,CAAC,aAAa,EAAE;YAClB,OAAO,SAAS,CAAC;SAClB;QAED,OAAO;YACL,GAAG,KAAK;YACR,GAAG,aAAa;SACjB,CAAC;IACJ,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,SAAS,CAAmC,CAAC;AAChF,CAAC;AAED;;;;;;GAMG;AACH,SAAS,2BAA2B,CAClC,OAAiC,EACjC,MAAqB;IAKrB,MAAM,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;IACzB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;IACxB,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAW,CAAC;IAE1C,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CACzC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAChD,CAAC;IAEF,GAAG,CAAC,sBAAsB,EAAE,UAAU,CAAC,CAAC;IAExC,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE;QAC9B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAEzC,GAAG,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC;QAErC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC9B,MAAM,eAAe,GAAoB;gBACvC,OAAO,EAAE,KAAK,CAAC,eAAe;gBAC9B,QAAQ,EAAE,KAAK,CAAC,aAAa;gBAC7B,EAAE,EAAE,OAAO;aACZ,CAAC;YAEF,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;YAEjD,IAAI,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;gBAC3B,GAAG,CACD,2DAA2D,EAC3D,eAAe,CAChB,CAAC;gBACF,SAAS;aACV;YAED,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAExB,MAAM,IAAI,GAAG,yBAAyB,CACpC,KAAK,CAAC,aAAa,EACnB,IAAI,EACJ,OAAO,CACR,CAAC;YAEF,MAAM,WAAW,GAAiC;gBAChD,IAAI;gBACJ,EAAE,EAAE,KAAK,CAAC,eAAe;gBACzB,IAAI;aACL,CAAC;YAEF,IAAI,qBAAqB,CAAC,KAAK,CAAC,EAAE;gBAChC,KAAK,CAAC,GAAG,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;aACzC;iBAAM;gBACL,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;gBACzC,KAAK,CAAC,GAAG,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;aACzC;SACF;KACF;IAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,SAAS,qBAAqB,CAAC,KAAkB;IAC/C,4EAA4E;IAC5E,iDAAiD;IACjD,OAAO,CACL,KAAK,CAAC,IAAI,KAAK,UAAU;QACzB,KAAK,CAAC,aAAa,KAAK,+BAAuB,CAAC,MAAM;QACtD,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAc,EAAE,EAAE,CAAC,KAAK,CAAC,CAC9C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,KAAkB;IAC1C,IAAI,KAAK,CAAC,aAAa,KAAK,+BAAuB,CAAC,MAAM,EAAE;QAC1D,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAc,CAAC,CAAC;KACpC;IAED,IACE,KAAK,CAAC,aAAa,KAAK,+BAAuB,CAAC,OAAO;QACvD,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAC/B;QACA,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAS,CAAC,CAAC;KAC/B;IAED,IACE,KAAK,CAAC,aAAa,KAAK,+BAAuB,CAAC,OAAO;QACvD,KAAK,CAAC,IAAI,KAAK,eAAe,EAC9B;QACA,OAAO,KAAK,CAAC,IAAI,CAAC,GAAY,CAAC;KAChC;IAED,2DAA2D;IAC3D,OAAO,CAAC,SAAS,CAAC,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,SAAS,oBAAoB,CAC3B,aAAsC;IAEtC,QAAQ,aAAa,EAAE;QACrB,KAAK,+BAAuB,CAAC,MAAM;YACjC,OAAO,IAAI,eAAS,CAAC,6BAAS,CAAC,CAAC;QAClC,KAAK,+BAAuB,CAAC,OAAO;YAClC,OAAO,IAAI,eAAS,CAAC,8BAAU,CAAC,CAAC;QACnC;YACE,OAAO,IAAI,eAAS,CAAC,4BAAQ,CAAC,CAAC;KAClC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,qCAAqC,CAC5C,IAAS,EACT,KAAsB,EACtB,QAAuC;IAEvC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAEtD,IAAI;QACF,IAAI,KAAK,CAAC,QAAQ,KAAK,+BAAuB,CAAC,MAAM,EAAE;YACrD,MAAM,MAAM,GAAG,QAAQ,CAAC,oBAAoB,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YACzE,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACxB,OAAO,KAAK,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;SACnE;QAED,MAAM,MAAM,GAAG,QAAQ,CAAC,oBAAoB,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC3E,OAAO,IAAA,wBAAK,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;KACzB;IAAC,OAAO,KAAK,EAAE;QACd,GAAG,CAAC,sCAAsC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxE,MAAM,IAAI,wBAAe,CACvB,kDACE,KAAK,CAAC,OACR,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CACrB,CAAC;KACH;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,yBAAyB,CAChC,aAAsC,EACtC,IAAS,EACT,OAAa;IAEb,MAAM,QAAQ,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAC;IACrD,QAAQ,aAAa,EAAE;QACrB,KAAK,+BAAuB,CAAC,MAAM;YACjC,OAAO,QAAQ,CAAC,kBAAkB,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAQ,CAAC;QAElE,KAAK,+BAAuB,CAAC,OAAO;YAClC,OAAO,QAAQ,CAAC,kBAAkB,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAQ,CAAC;QAE1E;YACE,OAAO,QAAQ,CAAC,kBAAkB,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAQ,CAAC;KAClE;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,QAAQ,CACf,QAA+B,EAC/B,UAA0C;IAI1C,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAEtD,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE;QACnC,IAAI;YACF,MAAM,iBAAiB,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAc,CAAC;YAC7D,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;YAEtD,OAAO;gBACL,GAAG,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACvC,GAAG;gBACH,QAAQ;aACT,CAAC;YACF,WAAW;YACX,6DAA6D;SAC9D;QAAC,OAAO,CAAC,EAAE;YACV,SAAS;SACV;KACF;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAClB,IAAiC;IAEjC,0BAA0B;IAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IAE7B,0BAA0B;IAC1B,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAErC,OAAO;QACL,GAAG,IAAI;QACP,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE;KACnE,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,0BAA0B,CACjC,eAAoB,EACpB,UAAe,EACf,SAAiB,CAAC;IAElB,MAAM,YAAY,GAAG,IAAA,0BAAO,EAAC,UAAU,CAAC,CAAC,GAAG,CAAC,IAAI,eAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,MAAM,iBAAiB,GAAG,IAAA,0BAAO,EAAC,eAAe,CAAC,CAAC;IACnD,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC;IACxC,MAAM,UAAU,GAAG,IAAA,wBAAK,EAAC,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC;IAE7C,IAAI,YAAY,CAAC,MAAM,EAAE,EAAE;QACzB,GAAG,CAAC,wBAAwB,CAAC,CAAC;QAC9B,OAAO,SAAS,CAAC;KAClB;IAED,OAAO;QACL,eAAe;QACf,UAAU,EAAE,IAAA,wBAAK,EAAC,YAAY,CAAC;QAC/B,UAAU;QACV,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,qBAAqB;IAC5B,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAEtD,OAAO,IAAI,GAAG,CACZ,eAAe,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;QAChC,MAAM,EAAE,GAAG,EAAE,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAChD,MAAM,iBAAiB,GAAG,IAAI,eAAS,CAAC,GAAG,CAAC,CAAC;QAC7C,OAAO,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;IACxC,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,WAAW,CAAC,EACzB,OAAO,EACP,MAAM,EACN,MAAM,GAAG,EAAE,EACX,KAAK,GAAG,EAAE,GAMX;IACC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC3D,MAAM,EAAE,iBAAiB,EAAE,GAAG,QAAQ,CAAC;IACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAW,CAAC;IAElC,MAAM,sBAAsB,GAAG,iBAAiB,EAAE,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QACxE,OAAO,EAAE,aAAa,CAAC,OAAO;QAC9B,IAAI;KACL,CAAC,CAAC,CAAC;IAEJ,MAAM,eAAe,GAAiC;QACpD,iBAAiB,EAAE,sBAAsB;QACzC,IAAI,EAAE,QAAQ,CAAC,IAAW;QAC1B,IAAI,EAAE,QAAQ,CAAC,IAAW;QAC1B,GAAG,EAAE,QAAQ,CAAC,GAAU;QACxB,YAAY,EAAE,CAAC,QAAQ,CAAC,YAAY,IAAI,QAAQ,CAAC,QAAQ,CAAQ;QACjE,oBAAoB,EAAE,CAAC,QAAQ,CAAC,oBAAoB;YAClD,QAAQ,CAAC,QAAQ,CAAQ;QAC3B,EAAE,EAAE,QAAQ,CAAC,EAAS;QACtB,KAAK,EAAE,QAAQ,CAAC,KAAY;KAC7B,CAAC;IAEF,MAAM,YAAY,GAAG,CAAC,GAAG,MAAM,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC,CAAC;IAC5D,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACtD,MAAM,kBAAkB,GAAG,IAAA,wBAAK,EAAC,iBAAiB,CAAC,CAAC;IAEpD,GAAG,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;IAE5C,MAAM,iBAAiB,GAAG,CAAC,MAAM,IAAA,wBAAK,EAAC,QAAQ,EAAE,YAAY,EAAE;QAC7D,IAAI;QACJ,QAAQ;KACT,CAAC,CAAQ,CAAC;IAEX,MAAM,gBAAgB,GAAG,IAAA,0BAAO,EAAC,iBAAiB,CAAC,CAAC;IAEpD,GAAG,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;IAE1C,MAAM,qBAAqB,GAAG,gBAAgB,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC;IAErE,OAAO,MAAM,IAAA,qCAAoB,EAAC,OAAO,EAAE;QACzC,GAAG,MAAM;QACT,YAAY;QACZ,OAAO,EAAE,IAAI;QACb,yBAAyB,EAAE,IAAI;QAC/B,GAAG,CAAC,SAAS,IAAI;YACf,cAAc,EAAE;gBACd,GAAG,MAAM,EAAE,cAAc;gBACzB,IAAI,EAAE,IAAA,wBAAK,EAAC,SAAS,CAAC;aACvB;SACF,CAAC;QACF,GAAG,CAAC,qBAAqB,IAAI;YAC3B,SAAS,EAAE;gBACT,GAAG,MAAM,EAAE,SAAS;gBACpB,CAAC,IAAI,CAAC,EAAE;oBACN,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC,IAAI,CAAC;oBAC5B,OAAO,EAAE,kBAAkB;iBAC5B;aACF;SACF,CAAC;KACH,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,SAAS,kBAAkB,CAAC,OAAiC;IAC3D,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC7B,MAAM,QAAQ,GAAG,IAAA,0BAAO,EAAC,QAAQ,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,IAAA,0BAAO,EAAC,QAAQ,CAAC,YAAY,IAAI,QAAQ,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC;IAC9E,MAAM,KAAK,GAAG,IAAA,0BAAO,EAAC,QAAQ,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC;IAE/C,MAAM,WAAW,GAAG,CAAC,OAAO,CAAC,kBAAkB,IAAI,EAAE,CAAC;SACnD,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAA,0BAAO,EAAC,EAAE,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC;SACvC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,eAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjD,OAAO,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAC5D,CAAC","sourcesContent":["import type { Fragment, LogDescription, Result } from '@ethersproject/abi';\nimport { Interface } from '@ethersproject/abi';\nimport { hexToBN, query, toHex } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport { abiERC20, abiERC721, abiERC1155 } from '@metamask/metamask-eth-abis';\nimport { createModuleLogger, type Hex } from '@metamask/utils';\nimport BN from 'bn.js';\n\nimport { simulateTransactions } from '../api/simulation-api';\nimport type {\n SimulationResponseLog,\n SimulationRequestTransaction,\n SimulationResponse,\n SimulationResponseCallTrace,\n SimulationResponseTransaction,\n SimulationRequest,\n} from '../api/simulation-api';\nimport {\n ABI_SIMULATION_ERC20_WRAPPED,\n ABI_SIMULATION_ERC721_LEGACY,\n} from '../constants';\nimport {\n SimulationError,\n SimulationInvalidResponseError,\n SimulationRevertedError,\n} from '../errors';\nimport { projectLogger } from '../logger';\nimport type {\n SimulationBalanceChange,\n SimulationData,\n SimulationTokenBalanceChange,\n SimulationToken,\n TransactionParams,\n NestedTransactionMetadata,\n} from '../types';\nimport { SimulationTokenStandard } from '../types';\n\nexport enum SupportedToken {\n ERC20 = 'erc20',\n ERC721 = 'erc721',\n ERC1155 = 'erc1155',\n ERC20_WRAPPED = 'erc20Wrapped',\n ERC721_LEGACY = 'erc721Legacy',\n}\n\ntype ABI = Fragment[];\n\nexport type GetBalanceChangesRequest = {\n blockTime?: number;\n chainId: Hex;\n ethQuery: EthQuery;\n nestedTransactions?: NestedTransactionMetadata[];\n txParams: TransactionParams;\n};\n\ntype ParsedEvent = {\n contractAddress: Hex;\n tokenStandard: SimulationTokenStandard;\n name: string;\n args: Record<string, Hex | Hex[]>;\n abi: ABI;\n};\n\nconst log = createModuleLogger(projectLogger, 'balance-changes');\n\nconst SUPPORTED_EVENTS = [\n 'Transfer',\n 'TransferSingle',\n 'TransferBatch',\n 'Deposit',\n 'Withdrawal',\n];\n\nconst SUPPORTED_TOKEN_ABIS = {\n [SupportedToken.ERC20]: {\n abi: abiERC20,\n standard: SimulationTokenStandard.erc20,\n },\n [SupportedToken.ERC721]: {\n abi: abiERC721,\n standard: SimulationTokenStandard.erc721,\n },\n [SupportedToken.ERC1155]: {\n abi: abiERC1155,\n standard: SimulationTokenStandard.erc1155,\n },\n [SupportedToken.ERC20_WRAPPED]: {\n abi: ABI_SIMULATION_ERC20_WRAPPED,\n standard: SimulationTokenStandard.erc20,\n },\n [SupportedToken.ERC721_LEGACY]: {\n abi: ABI_SIMULATION_ERC721_LEGACY,\n standard: SimulationTokenStandard.erc721,\n },\n};\n\nconst REVERTED_ERRORS = ['execution reverted', 'insufficient funds for gas'];\n\ntype BalanceTransactionMap = Map<SimulationToken, SimulationRequestTransaction>;\n\n/**\n * Generate simulation data for a transaction.\n *\n * @param request - The transaction to simulate.\n * @param request.chainId - The chain ID of the transaction.\n * @param request.from - The sender of the transaction.\n * @param request.to - The recipient of the transaction.\n * @param request.value - The value of the transaction.\n * @param request.data - The data of the transaction.\n * @returns The simulation data.\n */\nexport async function getBalanceChanges(\n request: GetBalanceChangesRequest,\n): Promise<SimulationData> {\n log('Request', request);\n\n try {\n const response = await baseRequest({\n request,\n params: {\n withCallTrace: true,\n withLogs: true,\n },\n });\n\n const transactionError = response.transactions?.[0]?.error;\n\n if (transactionError) {\n throw new SimulationError(transactionError);\n }\n\n const nativeBalanceChange = getNativeBalanceChange(request, response);\n const events = getEvents(response);\n\n log('Parsed events', events);\n\n const tokenBalanceChanges = await getTokenBalanceChanges(request, events);\n\n const simulationData = {\n nativeBalanceChange,\n tokenBalanceChanges,\n };\n\n return simulationData;\n } catch (error) {\n log('Failed to get balance changes', error, request);\n\n let simulationError = error as SimulationError;\n\n if (\n REVERTED_ERRORS.some((revertErrorMessage) =>\n simulationError.message?.includes(revertErrorMessage),\n )\n ) {\n simulationError = new SimulationRevertedError();\n }\n\n const { code, message } = simulationError;\n\n return {\n tokenBalanceChanges: [],\n error: {\n code,\n message,\n },\n };\n }\n}\n\n/**\n * Extract the native balance change from a simulation response.\n *\n * @param request - Simulation request.\n * @param response - Simulation response.\n * @returns Native balance change or undefined if unchanged.\n */\nfunction getNativeBalanceChange(\n request: GetBalanceChangesRequest,\n response: SimulationResponse,\n): SimulationBalanceChange | undefined {\n const transactionResponse = response.transactions[0];\n\n /* istanbul ignore next */\n if (!transactionResponse) {\n return undefined;\n }\n\n const { txParams } = request;\n const userAddress = txParams.from as Hex;\n const { stateDiff } = transactionResponse;\n const previousBalance = stateDiff?.pre?.[userAddress]?.balance;\n const newBalance = stateDiff?.post?.[userAddress]?.balance;\n\n if (!previousBalance || !newBalance) {\n return undefined;\n }\n\n return getSimulationBalanceChange(\n previousBalance,\n newBalance,\n transactionResponse.gasCost,\n );\n}\n\n/**\n * Extract events from a simulation response.\n *\n * @param response - The simulation response.\n * @returns The parsed events.\n */\nfunction getEvents(response: SimulationResponse): ParsedEvent[] {\n /* istanbul ignore next */\n const logs = extractLogs(\n response.transactions[0]?.callTrace ?? ({} as SimulationResponseCallTrace),\n );\n\n log('Extracted logs', logs);\n\n const interfaces = getContractInterfaces();\n\n return logs\n .map((currentLog) => {\n const event = parseLog(currentLog, interfaces);\n\n if (!event) {\n log('Failed to parse log', currentLog);\n return undefined;\n }\n\n /* istanbul ignore next */\n const inputs = event.abi.find((e) => e.name === event.name)?.inputs;\n\n /* istanbul ignore if */\n if (!inputs) {\n log('Failed to find inputs for event', event);\n return undefined;\n }\n\n if (!SUPPORTED_EVENTS.includes(event.name)) {\n log('Ignoring unsupported event', event.name, event);\n return undefined;\n }\n\n log('Normalizing event args', event.name, event);\n\n const args = normalizeEventArgs(event.args, inputs);\n\n return {\n contractAddress: currentLog.address,\n tokenStandard: event.standard,\n name: event.name,\n args,\n abi: event.abi,\n };\n })\n .filter((e) => e !== undefined) as ParsedEvent[];\n}\n\n/**\n * Normalize event arguments using ABI input definitions.\n *\n * @param args - The raw event arguments.\n * @param abiInputs - The ABI input definitions.\n * @returns The normalized event arguments.\n */\nfunction normalizeEventArgs(\n args: Result,\n abiInputs: { name: string }[],\n): Record<string, Hex | Hex[]> {\n return args.reduce((result, arg, index) => {\n const name = abiInputs[index].name.replace('_', '');\n const value = normalizeEventArgValue(arg);\n\n result[name] = value;\n\n return result;\n }, {});\n}\n\n/**\n * Normalize an event argument value.\n *\n * @param value - The event argument value.\n * @returns The normalized event argument value.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction normalizeEventArgValue(value: any): any {\n if (Array.isArray(value)) {\n return value.map(normalizeEventArgValue);\n }\n\n let normalizedValue = value;\n\n normalizedValue = normalizedValue.toHexString?.() ?? normalizedValue;\n normalizedValue = normalizedValue.toLowerCase?.() ?? normalizedValue;\n\n return normalizedValue;\n}\n\n/**\n * Generate token balance changes from parsed events.\n *\n * @param request - The transaction that was simulated.\n * @param events - The parsed events.\n * @returns An array of token balance changes.\n */\nasync function getTokenBalanceChanges(\n request: GetBalanceChangesRequest,\n events: ParsedEvent[],\n): Promise<SimulationTokenBalanceChange[]> {\n const { txParams } = request;\n const from = txParams.from as Hex;\n const balanceTxs = getTokenBalanceTransactions(request, events);\n\n log('Generated balance transactions', [...balanceTxs.after.values()]);\n\n const transactionCount = balanceTxs.before.size + balanceTxs.after.size + 1;\n\n if (transactionCount === 1) {\n return [];\n }\n\n const response = await baseRequest({\n request,\n before: [...balanceTxs.before.values()],\n after: [...balanceTxs.after.values()],\n });\n\n log('Balance simulation response', response);\n\n if (response.transactions.length !== transactionCount) {\n throw new SimulationInvalidResponseError();\n }\n\n let prevBalanceTxIndex = 0;\n return [...balanceTxs.after.keys()]\n .map((token, index) => {\n const previousBalanceCheckSkipped = !balanceTxs.before.get(token);\n const previousBalance = previousBalanceCheckSkipped\n ? '0x0'\n : getAmountFromBalanceTransactionResult(\n from,\n token,\n // eslint-disable-next-line no-plusplus\n response.transactions[prevBalanceTxIndex++],\n );\n\n const newBalance = getAmountFromBalanceTransactionResult(\n from,\n token,\n response.transactions[index + balanceTxs.before.size + 1],\n );\n\n const balanceChange = getSimulationBalanceChange(\n previousBalance,\n newBalance,\n );\n\n if (!balanceChange) {\n return undefined;\n }\n\n return {\n ...token,\n ...balanceChange,\n };\n })\n .filter((change) => change !== undefined) as SimulationTokenBalanceChange[];\n}\n\n/**\n * Generate transactions to check token balances.\n *\n * @param request - The transaction that was simulated.\n * @param events - The parsed events.\n * @returns A map of token balance transactions keyed by token.\n */\nfunction getTokenBalanceTransactions(\n request: GetBalanceChangesRequest,\n events: ParsedEvent[],\n): {\n before: BalanceTransactionMap;\n after: BalanceTransactionMap;\n} {\n const tokenKeys = new Set();\n const before = new Map();\n const after = new Map();\n const from = request.txParams.from as Hex;\n\n const userEvents = events.filter((event) =>\n [event.args.from, event.args.to].includes(from),\n );\n\n log('Filtered user events', userEvents);\n\n for (const event of userEvents) {\n const tokenIds = getEventTokenIds(event);\n\n log('Extracted token IDs', tokenIds);\n\n for (const tokenId of tokenIds) {\n const simulationToken: SimulationToken = {\n address: event.contractAddress,\n standard: event.tokenStandard,\n id: tokenId,\n };\n\n const tokenKey = JSON.stringify(simulationToken);\n\n if (tokenKeys.has(tokenKey)) {\n log(\n 'Ignoring additional event with same contract and token ID',\n simulationToken,\n );\n continue;\n }\n\n tokenKeys.add(tokenKey);\n\n const data = getBalanceTransactionData(\n event.tokenStandard,\n from,\n tokenId,\n );\n\n const transaction: SimulationRequestTransaction = {\n from,\n to: event.contractAddress,\n data,\n };\n\n if (skipPriorBalanceCheck(event)) {\n after.set(simulationToken, transaction);\n } else {\n before.set(simulationToken, transaction);\n after.set(simulationToken, transaction);\n }\n }\n }\n\n return { before, after };\n}\n\n/**\n * Check if an event needs to check the previous balance.\n *\n * @param event - The parsed event.\n * @returns True if the prior balance check should be skipped.\n */\nfunction skipPriorBalanceCheck(event: ParsedEvent): boolean {\n // In the case of an NFT mint, we cannot check the NFT owner before the mint\n // as the balance check transaction would revert.\n return (\n event.name === 'Transfer' &&\n event.tokenStandard === SimulationTokenStandard.erc721 &&\n parseInt(event.args.from as string, 16) === 0\n );\n}\n\n/**\n * Extract token IDs from a parsed event.\n *\n * @param event - The parsed event.\n * @returns An array of token IDs.\n */\nfunction getEventTokenIds(event: ParsedEvent): (Hex | undefined)[] {\n if (event.tokenStandard === SimulationTokenStandard.erc721) {\n return [event.args.tokenId as Hex];\n }\n\n if (\n event.tokenStandard === SimulationTokenStandard.erc1155 &&\n event.name === 'TransferSingle'\n ) {\n return [event.args.id as Hex];\n }\n\n if (\n event.tokenStandard === SimulationTokenStandard.erc1155 &&\n event.name === 'TransferBatch'\n ) {\n return event.args.ids as Hex[];\n }\n\n // ERC-20 does not have a token ID so default to undefined.\n return [undefined];\n}\n\n/**\n * Get the interface for a token standard.\n *\n * @param tokenStandard - The token standard.\n * @returns The interface for the token standard.\n */\nfunction getContractInterface(\n tokenStandard: SimulationTokenStandard,\n): Interface {\n switch (tokenStandard) {\n case SimulationTokenStandard.erc721:\n return new Interface(abiERC721);\n case SimulationTokenStandard.erc1155:\n return new Interface(abiERC1155);\n default:\n return new Interface(abiERC20);\n }\n}\n\n/**\n * Extract the value from a balance transaction response using the correct ABI.\n *\n * @param from - The address to check the balance of.\n * @param token - The token to check the balance of.\n * @param response - The balance transaction response.\n * @returns The value of the balance transaction as Hex.\n */\nfunction getAmountFromBalanceTransactionResult(\n from: Hex,\n token: SimulationToken,\n response: SimulationResponseTransaction,\n): Hex {\n const contract = getContractInterface(token.standard);\n\n try {\n if (token.standard === SimulationTokenStandard.erc721) {\n const result = contract.decodeFunctionResult('ownerOf', response.return);\n const owner = result[0];\n return owner.toLowerCase() === from.toLowerCase() ? '0x1' : '0x0';\n }\n\n const result = contract.decodeFunctionResult('balanceOf', response.return);\n return toHex(result[0]);\n } catch (error) {\n log('Failed to decode balance transaction', error, { token, response });\n throw new SimulationError(\n `Failed to decode balance transaction for token ${\n token.address\n }: ${String(error)}`,\n );\n }\n}\n\n/**\n * Generate the balance transaction data for a token.\n *\n * @param tokenStandard - The token standard.\n * @param from - The address to check the balance of.\n * @param tokenId - The token ID to check the balance of.\n * @returns The balance transaction data.\n */\nfunction getBalanceTransactionData(\n tokenStandard: SimulationTokenStandard,\n from: Hex,\n tokenId?: Hex,\n): Hex {\n const contract = getContractInterface(tokenStandard);\n switch (tokenStandard) {\n case SimulationTokenStandard.erc721:\n return contract.encodeFunctionData('ownerOf', [tokenId]) as Hex;\n\n case SimulationTokenStandard.erc1155:\n return contract.encodeFunctionData('balanceOf', [from, tokenId]) as Hex;\n\n default:\n return contract.encodeFunctionData('balanceOf', [from]) as Hex;\n }\n}\n\n/**\n * Parse a raw event log using known ABIs.\n *\n * @param eventLog - The raw event log.\n * @param interfaces - The contract interfaces.\n * @returns The parsed event log or undefined if it could not be parsed.\n */\nfunction parseLog(\n eventLog: SimulationResponseLog,\n interfaces: Map<SupportedToken, Interface>,\n):\n | (LogDescription & { abi: ABI; standard: SimulationTokenStandard })\n | undefined {\n const supportedTokens = Object.values(SupportedToken);\n\n for (const token of supportedTokens) {\n try {\n const contractInterface = interfaces.get(token) as Interface;\n const { abi, standard } = SUPPORTED_TOKEN_ABIS[token];\n\n return {\n ...contractInterface.parseLog(eventLog),\n abi,\n standard,\n };\n // Not used\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n continue;\n }\n }\n\n return undefined;\n}\n\n/**\n * Extract all logs from a call trace tree.\n *\n * @param call - The root call trace.\n * @returns An array of logs.\n */\nfunction extractLogs(\n call: SimulationResponseCallTrace,\n): SimulationResponseLog[] {\n /* istanbul ignore next */\n const logs = call.logs ?? [];\n\n /* istanbul ignore next */\n const nestedCalls = call.calls ?? [];\n\n return [\n ...logs,\n ...nestedCalls.map((nestedCall) => extractLogs(nestedCall)).flat(),\n ];\n}\n\n/**\n * Generate balance change data from previous and new balances.\n *\n * @param previousBalance - The previous balance.\n * @param newBalance - The new balance.\n * @param offset - Optional offset to apply to the new balance.\n * @returns The balance change data or undefined if unchanged.\n */\nfunction getSimulationBalanceChange(\n previousBalance: Hex,\n newBalance: Hex,\n offset: number = 0,\n): SimulationBalanceChange | undefined {\n const newBalanceBN = hexToBN(newBalance).add(new BN(offset));\n const previousBalanceBN = hexToBN(previousBalance);\n const differenceBN = newBalanceBN.sub(previousBalanceBN);\n const isDecrease = differenceBN.isNeg();\n const difference = toHex(differenceBN.abs());\n\n if (differenceBN.isZero()) {\n log('Balance change is zero');\n return undefined;\n }\n\n return {\n previousBalance,\n newBalance: toHex(newBalanceBN),\n difference,\n isDecrease,\n };\n}\n\n/**\n * Get the contract interfaces for all supported tokens.\n *\n * @returns A map of supported tokens to their contract interfaces.\n */\nfunction getContractInterfaces(): Map<SupportedToken, Interface> {\n const supportedTokens = Object.values(SupportedToken);\n\n return new Map(\n supportedTokens.map((tokenType) => {\n const { abi } = SUPPORTED_TOKEN_ABIS[tokenType];\n const contractInterface = new Interface(abi);\n return [tokenType, contractInterface];\n }),\n );\n}\n\n/**\n * Base request to simulation API.\n *\n * @param options - Options bag.\n * @param options.after - Transactions to simulate after user's transaction.\n * @param options.before - Transactions to simulate before user's transaction.\n * @param options.params - Additional parameters for the request.\n * @param options.request - Original request object.\n * @returns The simulation response.\n */\nasync function baseRequest({\n request,\n params,\n before = [],\n after = [],\n}: {\n request: GetBalanceChangesRequest;\n params?: Partial<SimulationRequest>;\n before?: SimulationRequestTransaction[];\n after?: SimulationRequestTransaction[];\n}): Promise<SimulationResponse> {\n const { blockTime, chainId, ethQuery, txParams } = request;\n const { authorizationList } = txParams;\n const from = txParams.from as Hex;\n\n const authorizationListFinal = authorizationList?.map((authorization) => ({\n address: authorization.address,\n from,\n }));\n\n const userTransaction: SimulationRequestTransaction = {\n authorizationList: authorizationListFinal,\n data: txParams.data as Hex,\n from: txParams.from as Hex,\n gas: txParams.gas as Hex,\n maxFeePerGas: (txParams.maxFeePerGas ?? txParams.gasPrice) as Hex,\n maxPriorityFeePerGas: (txParams.maxPriorityFeePerGas ??\n txParams.gasPrice) as Hex,\n to: txParams.to as Hex,\n value: txParams.value as Hex,\n };\n\n const transactions = [...before, userTransaction, ...after];\n const requiredBalanceBN = getRequiredBalance(request);\n const requiredBalanceHex = toHex(requiredBalanceBN);\n\n log('Required balance', requiredBalanceHex);\n\n const currentBalanceHex = (await query(ethQuery, 'getBalance', [\n from,\n 'latest',\n ])) as Hex;\n\n const currentBalanceBN = hexToBN(currentBalanceHex);\n\n log('Current balance', currentBalanceHex);\n\n const isInsufficientBalance = currentBalanceBN.lt(requiredBalanceBN);\n\n return await simulateTransactions(chainId, {\n ...params,\n transactions,\n withGas: true,\n withDefaultBlockOverrides: true,\n ...(blockTime && {\n blockOverrides: {\n ...params?.blockOverrides,\n time: toHex(blockTime),\n },\n }),\n ...(isInsufficientBalance && {\n overrides: {\n ...params?.overrides,\n [from]: {\n ...params?.overrides?.[from],\n balance: requiredBalanceHex,\n },\n },\n }),\n });\n}\n\n/**\n * Calculate the required minimum balance for a transaction.\n *\n * @param request - The transaction request.\n * @returns The minimal balance as a BN.\n */\nfunction getRequiredBalance(request: GetBalanceChangesRequest): BN {\n const { txParams } = request;\n const gasLimit = hexToBN(txParams.gas ?? '0x0');\n const gasPrice = hexToBN(txParams.maxFeePerGas ?? txParams.gasPrice ?? '0x0');\n const value = hexToBN(txParams.value ?? '0x0');\n\n const nestedValue = (request.nestedTransactions ?? [])\n .map((tx) => hexToBN(tx.value ?? '0x0'))\n .reduce((acc, val) => acc.add(val), new BN(0));\n\n return gasLimit.mul(gasPrice).add(value).add(nestedValue);\n}\n"]}
@@ -0,0 +1,30 @@
1
+ import type EthQuery from "@metamask/eth-query";
2
+ import { type Hex } from "@metamask/utils";
3
+ import type { SimulationData, TransactionParams, NestedTransactionMetadata } from "../types.cjs";
4
+ export declare enum SupportedToken {
5
+ ERC20 = "erc20",
6
+ ERC721 = "erc721",
7
+ ERC1155 = "erc1155",
8
+ ERC20_WRAPPED = "erc20Wrapped",
9
+ ERC721_LEGACY = "erc721Legacy"
10
+ }
11
+ export type GetBalanceChangesRequest = {
12
+ blockTime?: number;
13
+ chainId: Hex;
14
+ ethQuery: EthQuery;
15
+ nestedTransactions?: NestedTransactionMetadata[];
16
+ txParams: TransactionParams;
17
+ };
18
+ /**
19
+ * Generate simulation data for a transaction.
20
+ *
21
+ * @param request - The transaction to simulate.
22
+ * @param request.chainId - The chain ID of the transaction.
23
+ * @param request.from - The sender of the transaction.
24
+ * @param request.to - The recipient of the transaction.
25
+ * @param request.value - The value of the transaction.
26
+ * @param request.data - The data of the transaction.
27
+ * @returns The simulation data.
28
+ */
29
+ export declare function getBalanceChanges(request: GetBalanceChangesRequest): Promise<SimulationData>;
30
+ //# sourceMappingURL=balance-changes.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance-changes.d.cts","sourceRoot":"","sources":["../../src/utils/balance-changes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,4BAA4B;AAEhD,OAAO,EAAsB,KAAK,GAAG,EAAE,wBAAwB;AAsB/D,OAAO,KAAK,EAEV,cAAc,EAGd,iBAAiB,EACjB,yBAAyB,EAC1B,qBAAiB;AAGlB,oBAAY,cAAc;IACxB,KAAK,UAAU;IACf,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,aAAa,iBAAiB;IAC9B,aAAa,iBAAiB;CAC/B;AAID,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,GAAG,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,kBAAkB,CAAC,EAAE,yBAAyB,EAAE,CAAC;IACjD,QAAQ,EAAE,iBAAiB,CAAC;CAC7B,CAAC;AA+CF;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,cAAc,CAAC,CAsDzB"}
@@ -0,0 +1,30 @@
1
+ import type EthQuery from "@metamask/eth-query";
2
+ import { type Hex } from "@metamask/utils";
3
+ import type { SimulationData, TransactionParams, NestedTransactionMetadata } from "../types.mjs";
4
+ export declare enum SupportedToken {
5
+ ERC20 = "erc20",
6
+ ERC721 = "erc721",
7
+ ERC1155 = "erc1155",
8
+ ERC20_WRAPPED = "erc20Wrapped",
9
+ ERC721_LEGACY = "erc721Legacy"
10
+ }
11
+ export type GetBalanceChangesRequest = {
12
+ blockTime?: number;
13
+ chainId: Hex;
14
+ ethQuery: EthQuery;
15
+ nestedTransactions?: NestedTransactionMetadata[];
16
+ txParams: TransactionParams;
17
+ };
18
+ /**
19
+ * Generate simulation data for a transaction.
20
+ *
21
+ * @param request - The transaction to simulate.
22
+ * @param request.chainId - The chain ID of the transaction.
23
+ * @param request.from - The sender of the transaction.
24
+ * @param request.to - The recipient of the transaction.
25
+ * @param request.value - The value of the transaction.
26
+ * @param request.data - The data of the transaction.
27
+ * @returns The simulation data.
28
+ */
29
+ export declare function getBalanceChanges(request: GetBalanceChangesRequest): Promise<SimulationData>;
30
+ //# sourceMappingURL=balance-changes.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance-changes.d.mts","sourceRoot":"","sources":["../../src/utils/balance-changes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,4BAA4B;AAEhD,OAAO,EAAsB,KAAK,GAAG,EAAE,wBAAwB;AAsB/D,OAAO,KAAK,EAEV,cAAc,EAGd,iBAAiB,EACjB,yBAAyB,EAC1B,qBAAiB;AAGlB,oBAAY,cAAc;IACxB,KAAK,UAAU;IACf,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,aAAa,iBAAiB;IAC9B,aAAa,iBAAiB;CAC/B;AAID,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,GAAG,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,kBAAkB,CAAC,EAAE,yBAAyB,EAAE,CAAC;IACjD,QAAQ,EAAE,iBAAiB,CAAC;CAC7B,CAAC;AA+CF;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,cAAc,CAAC,CAsDzB"}