@pushchain/core 6.0.19 → 6.0.21

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 (112) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/package.json +1 -1
  3. package/src/lib/cache/cache.js +2 -0
  4. package/src/lib/constants/abi/index.d.ts +1 -0
  5. package/src/lib/constants/abi/index.js +8 -1
  6. package/src/lib/constants/abi/pc20.evm.d.ts +217 -0
  7. package/src/lib/constants/abi/pc20.evm.js +150 -0
  8. package/src/lib/constants/abi/prc20.evm.d.ts +172 -0
  9. package/src/lib/constants/abi/prc20.evm.js +97 -0
  10. package/src/lib/constants/abi/universalGatewayV0.json +1 -1
  11. package/src/lib/constants/chain.js +38 -8
  12. package/src/lib/constants/selectors.js +2 -2
  13. package/src/lib/constants/tokens.js +4 -3
  14. package/src/lib/formatters.js +16 -6
  15. package/src/lib/generated/uexecutor/v1/query.js +2 -4
  16. package/src/lib/generated/uexecutor/v1/types.d.ts +14 -0
  17. package/src/lib/generated/uexecutor/v1/types.js +90 -47
  18. package/src/lib/generated/uexecutor/v2/query.js +2 -4
  19. package/src/lib/generated/uexecutor/v2/types.d.ts +20 -0
  20. package/src/lib/generated/uexecutor/v2/types.js +49 -33
  21. package/src/lib/generated/v1/tx.js +30 -37
  22. package/src/lib/index.d.ts +4 -1
  23. package/src/lib/index.js +21 -3
  24. package/src/lib/internal/buffer.js +1 -2
  25. package/src/lib/orchestrator/cea-utils.js +73 -83
  26. package/src/lib/orchestrator/internals/account-manager.js +130 -139
  27. package/src/lib/orchestrator/internals/cascade.d.ts +0 -6
  28. package/src/lib/orchestrator/internals/cascade.js +1184 -1059
  29. package/src/lib/orchestrator/internals/confirmation.js +138 -148
  30. package/src/lib/orchestrator/internals/error-decoder.js +1 -1
  31. package/src/lib/orchestrator/internals/errors.js +12 -3
  32. package/src/lib/orchestrator/internals/execute-funds-only.d.ts +2 -2
  33. package/src/lib/orchestrator/internals/execute-funds-only.js +297 -259
  34. package/src/lib/orchestrator/internals/execute-funds-payload.d.ts +2 -2
  35. package/src/lib/orchestrator/internals/execute-funds-payload.js +220 -220
  36. package/src/lib/orchestrator/internals/execute-standard.d.ts +0 -8
  37. package/src/lib/orchestrator/internals/execute-standard.js +339 -342
  38. package/src/lib/orchestrator/internals/gas-calculator.js +497 -520
  39. package/src/lib/orchestrator/internals/gas-usd-sizer.js +101 -110
  40. package/src/lib/orchestrator/internals/gateway-client.js +102 -103
  41. package/src/lib/orchestrator/internals/helpers.js +30 -27
  42. package/src/lib/orchestrator/internals/inbound-tracker.js +234 -238
  43. package/src/lib/orchestrator/internals/outbound-sync.js +463 -452
  44. package/src/lib/orchestrator/internals/outbound-tracker.js +27 -34
  45. package/src/lib/orchestrator/internals/payload-builder.d.ts +2 -2
  46. package/src/lib/orchestrator/internals/payload-builder.js +119 -100
  47. package/src/lib/orchestrator/internals/pc-usd-oracle.js +121 -129
  48. package/src/lib/orchestrator/internals/pc20/address-codec.d.ts +31 -0
  49. package/src/lib/orchestrator/internals/pc20/address-codec.js +124 -0
  50. package/src/lib/orchestrator/internals/pc20/chain-namespace.d.ts +68 -0
  51. package/src/lib/orchestrator/internals/pc20/chain-namespace.js +136 -0
  52. package/src/lib/orchestrator/internals/pc20/errors.d.ts +160 -0
  53. package/src/lib/orchestrator/internals/pc20/errors.js +236 -0
  54. package/src/lib/orchestrator/internals/pc20/export.d.ts +172 -0
  55. package/src/lib/orchestrator/internals/pc20/export.js +412 -0
  56. package/src/lib/orchestrator/internals/pc20/gate.d.ts +67 -0
  57. package/src/lib/orchestrator/internals/pc20/gate.js +184 -0
  58. package/src/lib/orchestrator/internals/pc20/resolver.d.ts +187 -0
  59. package/src/lib/orchestrator/internals/pc20/resolver.js +658 -0
  60. package/src/lib/orchestrator/internals/pc20/svm.d.ts +189 -0
  61. package/src/lib/orchestrator/internals/pc20/svm.js +286 -0
  62. package/src/lib/orchestrator/internals/pc20/tracking.d.ts +46 -0
  63. package/src/lib/orchestrator/internals/pc20/tracking.js +109 -0
  64. package/src/lib/orchestrator/internals/preflight.js +1 -1
  65. package/src/lib/orchestrator/internals/progress-route-hooks.js +2 -2
  66. package/src/lib/orchestrator/internals/push-chain-tx.js +319 -331
  67. package/src/lib/orchestrator/internals/quote.js +90 -94
  68. package/src/lib/orchestrator/internals/rescue.js +76 -79
  69. package/src/lib/orchestrator/internals/response-builder.d.ts +28 -1
  70. package/src/lib/orchestrator/internals/response-builder.js +817 -701
  71. package/src/lib/orchestrator/internals/route-handlers.d.ts +7 -15
  72. package/src/lib/orchestrator/internals/route-handlers.js +1512 -1178
  73. package/src/lib/orchestrator/internals/signing.js +78 -83
  74. package/src/lib/orchestrator/internals/svm-bridge.d.ts +2 -2
  75. package/src/lib/orchestrator/internals/svm-bridge.js +161 -93
  76. package/src/lib/orchestrator/internals/svm-helpers.d.ts +15 -1
  77. package/src/lib/orchestrator/internals/svm-helpers.js +68 -24
  78. package/src/lib/orchestrator/internals/svm-rent.d.ts +19 -1
  79. package/src/lib/orchestrator/internals/svm-rent.js +163 -141
  80. package/src/lib/orchestrator/internals/tx-transformer.js +26 -23
  81. package/src/lib/orchestrator/internals/uea-manager.js +89 -86
  82. package/src/lib/orchestrator/max-pc-for-gas.js +5 -6
  83. package/src/lib/orchestrator/orchestrator.js +217 -200
  84. package/src/lib/orchestrator/orchestrator.types.d.ts +121 -1
  85. package/src/lib/orchestrator/orchestrator.types.js +19 -0
  86. package/src/lib/orchestrator/payload-builders.d.ts +2 -2
  87. package/src/lib/orchestrator/payload-builders.js +26 -24
  88. package/src/lib/orchestrator/route-detector.js +26 -9
  89. package/src/lib/orchestrator/svm-idl/ix-encoder.js +1 -2
  90. package/src/lib/orchestrator/svm-idl/normalize-address.js +2 -2
  91. package/src/lib/orchestrator/svm-idl/resolve.js +1 -2
  92. package/src/lib/price-fetch/price-fetch.js +67 -68
  93. package/src/lib/progress-hook/progress-hook.js +124 -72
  94. package/src/lib/push-chain/push-chain.js +171 -153
  95. package/src/lib/push-client/push-client.js +223 -237
  96. package/src/lib/universal/account/account.js +349 -365
  97. package/src/lib/universal/signer/signer.d.ts +2 -1
  98. package/src/lib/universal/signer/signer.js +315 -299
  99. package/src/lib/universal-tx-detector/auto-detect.js +55 -60
  100. package/src/lib/universal-tx-detector/cascade.js +160 -172
  101. package/src/lib/universal-tx-detector/child-inbounds.js +67 -75
  102. package/src/lib/universal-tx-detector/classify.js +2 -3
  103. package/src/lib/universal-tx-detector/detector-svm.js +139 -147
  104. package/src/lib/universal-tx-detector/detector.js +145 -157
  105. package/src/lib/universal-tx-detector/normalize.js +7 -7
  106. package/src/lib/utils/external-tx-hash.js +1 -2
  107. package/src/lib/utils.d.ts +44 -0
  108. package/src/lib/utils.js +762 -683
  109. package/src/lib/vm-client/evm-client.js +186 -202
  110. package/src/lib/vm-client/svm-client.d.ts +1 -1
  111. package/src/lib/vm-client/svm-client.js +220 -224
  112. package/src/lib/vm-client/vm-client.types.d.ts +14 -2
@@ -4,111 +4,107 @@
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.quoteExactOutput = quoteExactOutput;
7
- const tslib_1 = require("tslib");
8
7
  const viem_1 = require("viem");
9
8
  const chain_1 = require("../../constants/chain");
10
9
  const enums_1 = require("../../constants/enums");
11
10
  const utils_1 = require("../../utils");
12
11
  const evm_client_1 = require("../../vm-client/evm-client");
13
- function quoteExactOutput(ctx_1, amountOut_1, _a) {
14
- return tslib_1.__awaiter(this, arguments, void 0, function* (ctx, amountOut, { from, to, }) {
15
- var _b, _c, _d;
16
- const originChain = ctx.universalSigner.account.chain;
17
- if (originChain !== enums_1.CHAIN.ETHEREUM_MAINNET &&
18
- originChain !== enums_1.CHAIN.ETHEREUM_SEPOLIA) {
19
- throw new Error('Exact-output quoting is only supported on Ethereum Mainnet and Sepolia for now');
12
+ async function quoteExactOutput(ctx, amountOut, { from, to, }) {
13
+ const originChain = ctx.universalSigner.account.chain;
14
+ if (originChain !== enums_1.CHAIN.ETHEREUM_MAINNET &&
15
+ originChain !== enums_1.CHAIN.ETHEREUM_SEPOLIA) {
16
+ throw new Error('Exact-output quoting is only supported on Ethereum Mainnet and Sepolia for now');
17
+ }
18
+ if (!from)
19
+ throw new Error('from token is required');
20
+ if (!to)
21
+ throw new Error('to token is required');
22
+ const rpcUrls = ctx.rpcUrls[originChain] || chain_1.CHAIN_INFO[originChain].defaultRPC;
23
+ const evm = new evm_client_1.EvmClient({ rpcUrls });
24
+ const factoryFromConfig = chain_1.CHAIN_INFO[originChain].dex?.uniV3Factory;
25
+ const quoterFromConfig = chain_1.CHAIN_INFO[originChain].dex?.uniV3QuoterV2;
26
+ if (!factoryFromConfig || !quoterFromConfig) {
27
+ throw new Error('Uniswap V3 addresses not configured for this chain');
28
+ }
29
+ const UNISWAP_V3_FACTORY = factoryFromConfig;
30
+ const UNISWAP_V3_QUOTER_V2 = quoterFromConfig;
31
+ const factoryAbi = (0, viem_1.parseAbi)([
32
+ 'function getPool(address tokenA, address tokenB, uint24 fee) view returns (address)',
33
+ ]);
34
+ const quoterAbi = (0, viem_1.parseAbi)([
35
+ 'function quoteExactOutputSingle((address tokenIn, address tokenOut, uint256 amount, uint24 fee, uint160 sqrtPriceLimitX96) params) returns (uint256 amountIn, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)',
36
+ ]);
37
+ const poolAbi = (0, viem_1.parseAbi)([
38
+ 'function liquidity() view returns (uint128)',
39
+ ]);
40
+ const feeTiers = [100, 500, 3000, 10000];
41
+ let bestAmountIn = null;
42
+ let bestFee = null;
43
+ for (const fee of feeTiers) {
44
+ const poolAddress = await evm.readContract({
45
+ abi: factoryAbi,
46
+ address: UNISWAP_V3_FACTORY,
47
+ functionName: 'getPool',
48
+ args: [from.address, to.address, fee],
49
+ });
50
+ const isZero = !poolAddress ||
51
+ poolAddress.toLowerCase() ===
52
+ '0x0000000000000000000000000000000000000000';
53
+ if (isZero)
54
+ continue;
55
+ try {
56
+ const liquidity = await evm.readContract({
57
+ abi: poolAbi,
58
+ address: poolAddress,
59
+ functionName: 'liquidity',
60
+ args: [],
61
+ });
62
+ if (!liquidity || liquidity === BigInt(0))
63
+ continue;
20
64
  }
21
- if (!from)
22
- throw new Error('from token is required');
23
- if (!to)
24
- throw new Error('to token is required');
25
- const rpcUrls = ctx.rpcUrls[originChain] || chain_1.CHAIN_INFO[originChain].defaultRPC;
26
- const evm = new evm_client_1.EvmClient({ rpcUrls });
27
- const factoryFromConfig = (_b = chain_1.CHAIN_INFO[originChain].dex) === null || _b === void 0 ? void 0 : _b.uniV3Factory;
28
- const quoterFromConfig = (_c = chain_1.CHAIN_INFO[originChain].dex) === null || _c === void 0 ? void 0 : _c.uniV3QuoterV2;
29
- if (!factoryFromConfig || !quoterFromConfig) {
30
- throw new Error('Uniswap V3 addresses not configured for this chain');
65
+ catch {
66
+ continue;
31
67
  }
32
- const UNISWAP_V3_FACTORY = factoryFromConfig;
33
- const UNISWAP_V3_QUOTER_V2 = quoterFromConfig;
34
- const factoryAbi = (0, viem_1.parseAbi)([
35
- 'function getPool(address tokenA, address tokenB, uint24 fee) view returns (address)',
36
- ]);
37
- const quoterAbi = (0, viem_1.parseAbi)([
38
- 'function quoteExactOutputSingle((address tokenIn, address tokenOut, uint256 amount, uint24 fee, uint160 sqrtPriceLimitX96) params) returns (uint256 amountIn, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)',
39
- ]);
40
- const poolAbi = (0, viem_1.parseAbi)([
41
- 'function liquidity() view returns (uint128)',
42
- ]);
43
- const feeTiers = [100, 500, 3000, 10000];
44
- let bestAmountIn = null;
45
- let bestFee = null;
46
- for (const fee of feeTiers) {
47
- const poolAddress = yield evm.readContract({
48
- abi: factoryAbi,
49
- address: UNISWAP_V3_FACTORY,
50
- functionName: 'getPool',
51
- args: [from.address, to.address, fee],
68
+ try {
69
+ const result = await evm.readContract({
70
+ abi: quoterAbi,
71
+ address: UNISWAP_V3_QUOTER_V2,
72
+ functionName: 'quoteExactOutputSingle',
73
+ args: [
74
+ {
75
+ tokenIn: from.address,
76
+ tokenOut: to.address,
77
+ amount: amountOut,
78
+ fee,
79
+ sqrtPriceLimitX96: BigInt(0),
80
+ },
81
+ ],
52
82
  });
53
- const isZero = !poolAddress ||
54
- poolAddress.toLowerCase() ===
55
- '0x0000000000000000000000000000000000000000';
56
- if (isZero)
57
- continue;
58
- try {
59
- const liquidity = yield evm.readContract({
60
- abi: poolAbi,
61
- address: poolAddress,
62
- functionName: 'liquidity',
63
- args: [],
64
- });
65
- if (!liquidity || liquidity === BigInt(0))
66
- continue;
67
- }
68
- catch (_e) {
83
+ const amountIn = result?.[0] ?? BigInt(0);
84
+ if (amountIn === BigInt(0))
69
85
  continue;
70
- }
71
- try {
72
- const result = yield evm.readContract({
73
- abi: quoterAbi,
74
- address: UNISWAP_V3_QUOTER_V2,
75
- functionName: 'quoteExactOutputSingle',
76
- args: [
77
- {
78
- tokenIn: from.address,
79
- tokenOut: to.address,
80
- amount: amountOut,
81
- fee,
82
- sqrtPriceLimitX96: BigInt(0),
83
- },
84
- ],
85
- });
86
- const amountIn = (_d = result === null || result === void 0 ? void 0 : result[0]) !== null && _d !== void 0 ? _d : BigInt(0);
87
- if (amountIn === BigInt(0))
88
- continue;
89
- if (bestAmountIn === null || amountIn < bestAmountIn) {
90
- bestAmountIn = amountIn;
91
- bestFee = fee;
92
- }
93
- }
94
- catch (_f) {
95
- // try next fee
86
+ if (bestAmountIn === null || amountIn < bestAmountIn) {
87
+ bestAmountIn = amountIn;
88
+ bestFee = fee;
96
89
  }
97
90
  }
98
- if (bestAmountIn === null || bestFee === null) {
99
- throw new Error('No direct Uniswap V3 pool found for the given token pair on common fee tiers');
91
+ catch {
92
+ // try next fee
100
93
  }
101
- const amountInBig = BigInt(bestAmountIn);
102
- const amountInHuman = parseFloat(utils_1.Utils.helpers.formatUnits(amountInBig, { decimals: from.decimals }));
103
- const amountOutHuman = parseFloat(utils_1.Utils.helpers.formatUnits(amountOut, { decimals: to.decimals }));
104
- const rate = amountInHuman > 0 ? amountOutHuman / amountInHuman : 0;
105
- return {
106
- amountIn: bestAmountIn.toString(),
107
- amountOut: amountOut.toString(),
108
- rate,
109
- route: [from.symbol, to.symbol],
110
- timestamp: Date.now(),
111
- };
112
- });
94
+ }
95
+ if (bestAmountIn === null || bestFee === null) {
96
+ throw new Error('No direct Uniswap V3 pool found for the given token pair on common fee tiers');
97
+ }
98
+ const amountInBig = BigInt(bestAmountIn);
99
+ const amountInHuman = parseFloat(utils_1.Utils.helpers.formatUnits(amountInBig, { decimals: from.decimals }));
100
+ const amountOutHuman = parseFloat(utils_1.Utils.helpers.formatUnits(amountOut, { decimals: to.decimals }));
101
+ const rate = amountInHuman > 0 ? amountOutHuman / amountInHuman : 0;
102
+ return {
103
+ amountIn: bestAmountIn.toString(),
104
+ amountOut: amountOut.toString(),
105
+ rate,
106
+ route: [from.symbol, to.symbol],
107
+ timestamp: Date.now(),
108
+ };
113
109
  }
114
110
  //# sourceMappingURL=quote.js.map
@@ -7,7 +7,6 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.rescueFunds = rescueFunds;
10
- const tslib_1 = require("tslib");
11
10
  const viem_1 = require("viem");
12
11
  const universalGatewayPC_evm_1 = require("../../constants/abi/universalGatewayPC.evm");
13
12
  const selectors_1 = require("../../constants/selectors");
@@ -29,84 +28,82 @@ const gas_calculator_1 = require("./gas-calculator");
29
28
  * @param executeFn - The Orchestrator.execute() method (avoids circular dep)
30
29
  * @returns Transaction response
31
30
  */
32
- function rescueFunds(ctx, params, executeFn) {
33
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
34
- // Validate universalTxId format (bytes32: 0x + 64 hex chars)
35
- if (!params.universalTxId ||
36
- params.universalTxId.length !== 66 ||
37
- !/^0x[0-9a-fA-F]{64}$/.test(params.universalTxId)) {
38
- throw new Error(`Invalid universalTxId: expected 0x-prefixed bytes32 (66 chars), got "${params.universalTxId}"`);
39
- }
40
- // Validate prc20 is not zero address
41
- if (!params.prc20 ||
42
- params.prc20 === selectors_1.ZERO_ADDRESS) {
43
- throw new Error('prc20 token address cannot be zero address');
44
- }
45
- const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
46
- const gatewayPcAddress = (0, helpers_1.getUniversalGatewayPCAddress)();
47
- (0, context_1.printLog)(ctx, `rescueFunds — universalTxId=${params.universalTxId}, prc20=${params.prc20}, gateway=${gatewayPcAddress}`);
48
- // Pre-fetch UEA status
49
- const [ueaCode, ueaBalance] = yield Promise.all([
50
- ctx.pushClient.publicClient.getCode({ address: ueaAddress }),
51
- ctx.pushClient.getBalance(ueaAddress),
52
- ]);
53
- const isUEADeployed = ueaCode !== undefined;
54
- const ueaNonce = isUEADeployed ? yield (0, uea_manager_1.getUEANonce)(ctx, ueaAddress) : BigInt(0);
55
- // Query rescue gas fee
56
- let nativeValueForGas = BigInt(0);
57
- try {
58
- const result = yield (0, gas_calculator_1.queryRescueGasFee)(ctx, params.prc20, ctx.universalSigner.account.chain);
59
- nativeValueForGas = result.nativeValueForGas;
60
- (0, context_1.printLog)(ctx, `rescueFunds — queried gas fee: gasFee=${result.gasFee.toString()}, gasToken=${result.gasToken}, nativeValueForGas=${nativeValueForGas.toString()}`);
61
- }
62
- catch (err) {
63
- throw new Error(`Failed to query rescue gas fee: ${err}`);
64
- }
65
- // Adjust nativeValueForGas using the same balance-capping pattern as outbound
66
- const EVM_NATIVE_VALUE_TARGET = BigInt(200e18); // 200 UPC
67
- const EVM_GAS_RESERVE = BigInt(3e18); // 3 UPC for tx overhead
68
- const currentBalance = ueaBalance;
69
- let adjustedValue;
70
- if (currentBalance > EVM_NATIVE_VALUE_TARGET + EVM_GAS_RESERVE) {
71
- adjustedValue = EVM_NATIVE_VALUE_TARGET;
72
- }
73
- else if (currentBalance > EVM_GAS_RESERVE) {
74
- adjustedValue = currentBalance - EVM_GAS_RESERVE;
75
- }
76
- else {
77
- adjustedValue = nativeValueForGas;
78
- }
79
- if (adjustedValue !== nativeValueForGas) {
80
- (0, context_1.printLog)(ctx, `rescueFunds — adjusting nativeValueForGas from ${nativeValueForGas.toString()} to ${adjustedValue.toString()} (UEA balance: ${currentBalance.toString()})`);
81
- nativeValueForGas = adjustedValue;
82
- }
83
- // Build single rescue multicall (no PRC-20 approval needed — no burn)
84
- const rescueCallData = (0, viem_1.encodeFunctionData)({
85
- abi: universalGatewayPC_evm_1.UNIVERSAL_GATEWAY_PC,
86
- functionName: 'rescueFundsOnSourceChain',
87
- args: [params.universalTxId, params.prc20],
88
- });
89
- const pushChainMulticalls = [
90
- {
91
- to: gatewayPcAddress,
92
- value: nativeValueForGas,
93
- data: rescueCallData,
94
- },
95
- ];
96
- (0, context_1.printLog)(ctx, `rescueFunds — built rescue multicall, nativeValueForGas=${nativeValueForGas.toString()}`);
97
- const multicallNativeValue = pushChainMulticalls.reduce((sum, mc) => { var _a; return sum + ((_a = mc.value) !== null && _a !== void 0 ? _a : BigInt(0)); }, BigInt(0));
98
- const executeParams = {
99
- to: ueaAddress,
100
- value: multicallNativeValue,
101
- data: pushChainMulticalls,
102
- _ueaStatus: {
103
- isDeployed: isUEADeployed,
104
- nonce: ueaNonce,
105
- balance: ueaBalance,
106
- },
107
- _skipFeeLocking: true,
108
- };
109
- return executeFn(executeParams);
31
+ async function rescueFunds(ctx, params, executeFn) {
32
+ // Validate universalTxId format (bytes32: 0x + 64 hex chars)
33
+ if (!params.universalTxId ||
34
+ params.universalTxId.length !== 66 ||
35
+ !/^0x[0-9a-fA-F]{64}$/.test(params.universalTxId)) {
36
+ throw new Error(`Invalid universalTxId: expected 0x-prefixed bytes32 (66 chars), got "${params.universalTxId}"`);
37
+ }
38
+ // Validate prc20 is not zero address
39
+ if (!params.prc20 ||
40
+ params.prc20 === selectors_1.ZERO_ADDRESS) {
41
+ throw new Error('prc20 token address cannot be zero address');
42
+ }
43
+ const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
44
+ const gatewayPcAddress = (0, helpers_1.getUniversalGatewayPCAddress)();
45
+ (0, context_1.printLog)(ctx, `rescueFunds — universalTxId=${params.universalTxId}, prc20=${params.prc20}, gateway=${gatewayPcAddress}`);
46
+ // Pre-fetch UEA status
47
+ const [ueaCode, ueaBalance] = await Promise.all([
48
+ ctx.pushClient.publicClient.getCode({ address: ueaAddress }),
49
+ ctx.pushClient.getBalance(ueaAddress),
50
+ ]);
51
+ const isUEADeployed = ueaCode !== undefined;
52
+ const ueaNonce = isUEADeployed ? await (0, uea_manager_1.getUEANonce)(ctx, ueaAddress) : BigInt(0);
53
+ // Query rescue gas fee
54
+ let nativeValueForGas = BigInt(0);
55
+ try {
56
+ const result = await (0, gas_calculator_1.queryRescueGasFee)(ctx, params.prc20, ctx.universalSigner.account.chain);
57
+ nativeValueForGas = result.nativeValueForGas;
58
+ (0, context_1.printLog)(ctx, `rescueFunds — queried gas fee: gasFee=${result.gasFee.toString()}, gasToken=${result.gasToken}, nativeValueForGas=${nativeValueForGas.toString()}`);
59
+ }
60
+ catch (err) {
61
+ throw new Error(`Failed to query rescue gas fee: ${err}`);
62
+ }
63
+ // Adjust nativeValueForGas using the same balance-capping pattern as outbound
64
+ const EVM_NATIVE_VALUE_TARGET = BigInt(200e18); // 200 UPC
65
+ const EVM_GAS_RESERVE = BigInt(3e18); // 3 UPC for tx overhead
66
+ const currentBalance = ueaBalance;
67
+ let adjustedValue;
68
+ if (currentBalance > EVM_NATIVE_VALUE_TARGET + EVM_GAS_RESERVE) {
69
+ adjustedValue = EVM_NATIVE_VALUE_TARGET;
70
+ }
71
+ else if (currentBalance > EVM_GAS_RESERVE) {
72
+ adjustedValue = currentBalance - EVM_GAS_RESERVE;
73
+ }
74
+ else {
75
+ adjustedValue = nativeValueForGas;
76
+ }
77
+ if (adjustedValue !== nativeValueForGas) {
78
+ (0, context_1.printLog)(ctx, `rescueFunds — adjusting nativeValueForGas from ${nativeValueForGas.toString()} to ${adjustedValue.toString()} (UEA balance: ${currentBalance.toString()})`);
79
+ nativeValueForGas = adjustedValue;
80
+ }
81
+ // Build single rescue multicall (no PRC-20 approval needed — no burn)
82
+ const rescueCallData = (0, viem_1.encodeFunctionData)({
83
+ abi: universalGatewayPC_evm_1.UNIVERSAL_GATEWAY_PC,
84
+ functionName: 'rescueFundsOnSourceChain',
85
+ args: [params.universalTxId, params.prc20],
110
86
  });
87
+ const pushChainMulticalls = [
88
+ {
89
+ to: gatewayPcAddress,
90
+ value: nativeValueForGas,
91
+ data: rescueCallData,
92
+ },
93
+ ];
94
+ (0, context_1.printLog)(ctx, `rescueFunds — built rescue multicall, nativeValueForGas=${nativeValueForGas.toString()}`);
95
+ const multicallNativeValue = pushChainMulticalls.reduce((sum, mc) => sum + (mc.value ?? BigInt(0)), BigInt(0));
96
+ const executeParams = {
97
+ to: ueaAddress,
98
+ value: multicallNativeValue,
99
+ data: pushChainMulticalls,
100
+ _ueaStatus: {
101
+ isDeployed: isUEADeployed,
102
+ nonce: ueaNonce,
103
+ balance: ueaBalance,
104
+ },
105
+ _skipFeeLocking: true,
106
+ };
107
+ return executeFn(executeParams);
111
108
  }
112
109
  //# sourceMappingURL=rescue.js.map
@@ -28,7 +28,34 @@ export interface ResponseBuilderCallbacks {
28
28
  maxTimeoutMs: number;
29
29
  };
30
30
  }
31
- export declare function queryUniversalTxStatusFromGatewayTx(ctx: OrchestratorContext, evmClient: EvmClient | undefined, gatewayAddress: `0x${string}` | undefined, txHash: string, evmGatewayMethod: 'sendFunds' | 'sendTxWithFunds' | 'sendTxWithGas'): Promise<UniversalTx | undefined>;
31
+ /**
32
+ * Pick the gateway log whose event is the PC20 burn — the leg that carries the
33
+ * user's transfer.
34
+ *
35
+ * A PC20 return with a prepaid gas deposit makes the gateway emit TWO
36
+ * `UniversalTx` events from one user tx: the PC20 burn (payload prefixed with
37
+ * the `PC20` selector) and, second, a plain FUNDS event for the attached
38
+ * native value. Each becomes its own UTX on Push. The default "last gateway
39
+ * log" heuristic therefore selects the *fee-credit* leg, so a failure there
40
+ * (see the known fee-credit bug) is reported as the whole transfer failing —
41
+ * even though the tokens arrived via the first leg.
42
+ *
43
+ * Identification is by payload prefix rather than log order: the selector is
44
+ * what the gateway itself stamps on the PC20 leg, so it stays correct if the
45
+ * emission order ever changes. Returns null when no PC20 leg is present, and
46
+ * the caller keeps its existing behaviour.
47
+ */
48
+ export declare function findPC20GatewayLogIndex(ctx: OrchestratorContext, gatewayLogs: Array<{
49
+ topics?: unknown;
50
+ data?: unknown;
51
+ logIndex?: unknown;
52
+ }>): number | null;
53
+ export declare function queryUniversalTxStatusFromGatewayTx(ctx: OrchestratorContext, evmClient: EvmClient | undefined, gatewayAddress: `0x${string}` | undefined, txHash: string, evmGatewayMethod: 'sendFunds' | 'sendTxWithFunds' | 'sendTxWithGas',
54
+ /**
55
+ * Set for PC20 imports (wrapper burns). Selects the PC20 burn leg rather
56
+ * than the last gateway log — see {@link findPC20GatewayLogIndex}.
57
+ */
58
+ preferPC20Log?: boolean): Promise<UniversalTx | undefined>;
32
59
  /**
33
60
  * Source-hash resolution for trackTransaction.
34
61
  *