@pushchain/core 5.1.3 → 5.1.4-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/package.json +29 -6
  2. package/src/lib/constants/abi/prc20.evm.d.ts +22 -2
  3. package/src/lib/constants/abi/prc20.evm.js +11 -3
  4. package/src/lib/constants/abi/universalGatewayPC.evm.d.ts +59 -0
  5. package/src/lib/constants/abi/universalGatewayPC.evm.js +26 -0
  6. package/src/lib/constants/chain.d.ts +4 -0
  7. package/src/lib/constants/chain.js +6 -2
  8. package/src/lib/index.d.ts +2 -2
  9. package/src/lib/internal/bs58.d.ts +2 -0
  10. package/src/lib/internal/bs58.js +7 -0
  11. package/src/lib/orchestrator/cea-utils.d.ts +0 -9
  12. package/src/lib/orchestrator/cea-utils.js +15 -4
  13. package/src/lib/orchestrator/internals/account-manager.d.ts +16 -0
  14. package/src/lib/orchestrator/internals/account-manager.js +191 -0
  15. package/src/lib/orchestrator/internals/cascade.d.ts +23 -0
  16. package/src/lib/orchestrator/internals/cascade.js +945 -0
  17. package/src/lib/orchestrator/internals/confirmation.d.ts +9 -0
  18. package/src/lib/orchestrator/internals/confirmation.js +123 -0
  19. package/src/lib/orchestrator/internals/context.d.ts +38 -0
  20. package/src/lib/orchestrator/internals/context.js +49 -0
  21. package/src/lib/orchestrator/internals/execute-funds-only.d.ts +11 -0
  22. package/src/lib/orchestrator/internals/execute-funds-only.js +219 -0
  23. package/src/lib/orchestrator/internals/execute-funds-payload.d.ts +11 -0
  24. package/src/lib/orchestrator/internals/execute-funds-payload.js +222 -0
  25. package/src/lib/orchestrator/internals/execute-standard.d.ts +13 -0
  26. package/src/lib/orchestrator/internals/execute-standard.js +225 -0
  27. package/src/lib/orchestrator/internals/gas-calculator.d.ts +38 -0
  28. package/src/lib/orchestrator/internals/gas-calculator.js +424 -0
  29. package/src/lib/orchestrator/internals/gateway-client.d.ts +24 -0
  30. package/src/lib/orchestrator/internals/gateway-client.js +191 -0
  31. package/src/lib/orchestrator/internals/helpers.d.ts +26 -0
  32. package/src/lib/orchestrator/internals/helpers.js +181 -0
  33. package/src/lib/orchestrator/internals/index.d.ts +24 -0
  34. package/src/lib/orchestrator/internals/index.js +132 -0
  35. package/src/lib/orchestrator/internals/outbound-sync.d.ts +49 -0
  36. package/src/lib/orchestrator/internals/outbound-sync.js +357 -0
  37. package/src/lib/orchestrator/internals/outbound-tracker.d.ts +8 -0
  38. package/src/lib/orchestrator/internals/outbound-tracker.js +64 -0
  39. package/src/lib/orchestrator/internals/payload-builder.d.ts +24 -0
  40. package/src/lib/orchestrator/internals/payload-builder.js +178 -0
  41. package/src/lib/orchestrator/internals/push-chain-tx.d.ts +32 -0
  42. package/src/lib/orchestrator/internals/push-chain-tx.js +207 -0
  43. package/src/lib/orchestrator/internals/quote.d.ts +9 -0
  44. package/src/lib/orchestrator/internals/quote.js +114 -0
  45. package/src/lib/orchestrator/internals/rescue.d.ts +20 -0
  46. package/src/lib/orchestrator/internals/rescue.js +112 -0
  47. package/src/lib/orchestrator/internals/response-builder.d.ts +26 -0
  48. package/src/lib/orchestrator/internals/response-builder.js +504 -0
  49. package/src/lib/orchestrator/internals/route-handlers.d.ts +77 -0
  50. package/src/lib/orchestrator/internals/route-handlers.js +1192 -0
  51. package/src/lib/orchestrator/internals/signing.d.ts +27 -0
  52. package/src/lib/orchestrator/internals/signing.js +258 -0
  53. package/src/lib/orchestrator/internals/svm-bridge.d.ts +21 -0
  54. package/src/lib/orchestrator/internals/svm-bridge.js +122 -0
  55. package/src/lib/orchestrator/internals/svm-helpers.d.ts +35 -0
  56. package/src/lib/orchestrator/internals/svm-helpers.js +143 -0
  57. package/src/lib/orchestrator/internals/tx-transformer.d.ts +12 -0
  58. package/src/lib/orchestrator/internals/tx-transformer.js +120 -0
  59. package/src/lib/orchestrator/internals/uea-manager.d.ts +17 -0
  60. package/src/lib/orchestrator/internals/uea-manager.js +164 -0
  61. package/src/lib/orchestrator/orchestrator.d.ts +33 -431
  62. package/src/lib/orchestrator/orchestrator.js +124 -6125
  63. package/src/lib/orchestrator/orchestrator.types.d.ts +11 -10
  64. package/src/lib/orchestrator/payload-builders.js +34 -8
  65. package/src/lib/price-fetch/price-fetch.js +19 -7
  66. package/src/lib/push-chain/push-chain.d.ts +6 -0
  67. package/src/lib/push-chain/push-chain.js +10 -2
  68. package/src/lib/push-client/push-client.d.ts +3 -0
  69. package/src/lib/push-client/push-client.js +21 -31
  70. package/src/lib/universal/account/account.d.ts +35 -16
  71. package/src/lib/universal/account/account.js +298 -16
  72. package/src/lib/universal/signer/signer.d.ts +2 -3
  73. package/src/lib/universal/signer/signer.js +65 -115
  74. package/src/lib/universal/universal.types.d.ts +41 -0
  75. package/src/lib/utils.d.ts +7 -2
  76. package/src/lib/utils.js +65 -34
  77. package/src/lib/vm-client/evm-client.js +3 -11
  78. package/src/lib/vm-client/svm-client.d.ts +0 -4
  79. package/src/lib/vm-client/svm-client.js +2 -8
  80. package/src/index.js.map +0 -1
  81. package/src/lib/cache/cache.js.map +0 -1
  82. package/src/lib/constants/abi/cea.evm.js.map +0 -1
  83. package/src/lib/constants/abi/ceaFactory.evm.js.map +0 -1
  84. package/src/lib/constants/abi/erc20.evm.js.map +0 -1
  85. package/src/lib/constants/abi/factoryV1.js.map +0 -1
  86. package/src/lib/constants/abi/feeLocker.evm.js.map +0 -1
  87. package/src/lib/constants/abi/index.js.map +0 -1
  88. package/src/lib/constants/abi/prc20.evm.js.map +0 -1
  89. package/src/lib/constants/abi/uea-factory.js.map +0 -1
  90. package/src/lib/constants/abi/uea.evm.js.map +0 -1
  91. package/src/lib/constants/abi/uea.svm.js.map +0 -1
  92. package/src/lib/constants/abi/universalGateway.evm.js.map +0 -1
  93. package/src/lib/constants/abi/universalGatewayPC.evm.js.map +0 -1
  94. package/src/lib/constants/abi/universalGatewayV0.evm.js.map +0 -1
  95. package/src/lib/constants/chain.js.map +0 -1
  96. package/src/lib/constants/enums.js.map +0 -1
  97. package/src/lib/constants/index.js.map +0 -1
  98. package/src/lib/constants/selectors.js.map +0 -1
  99. package/src/lib/constants/tokens.js.map +0 -1
  100. package/src/lib/generated/uexecutor/v1/query.js.map +0 -1
  101. package/src/lib/generated/uexecutor/v1/types.js.map +0 -1
  102. package/src/lib/generated/uexecutor/v2/index.js.map +0 -1
  103. package/src/lib/generated/uexecutor/v2/query.js.map +0 -1
  104. package/src/lib/generated/uexecutor/v2/types.js.map +0 -1
  105. package/src/lib/generated/v1/tx.js.map +0 -1
  106. package/src/lib/index.js.map +0 -1
  107. package/src/lib/internal/buffer.js.map +0 -1
  108. package/src/lib/internal/global-buffer-polyfill.js.map +0 -1
  109. package/src/lib/orchestrator/cea-utils.js.map +0 -1
  110. package/src/lib/orchestrator/orchestrator.js.map +0 -1
  111. package/src/lib/orchestrator/orchestrator.types.js.map +0 -1
  112. package/src/lib/orchestrator/payload-builders.js.map +0 -1
  113. package/src/lib/orchestrator/route-detector.js.map +0 -1
  114. package/src/lib/price-fetch/price-fetch.js.map +0 -1
  115. package/src/lib/progress-hook/progress-hook.js.map +0 -1
  116. package/src/lib/progress-hook/progress-hook.types.js.map +0 -1
  117. package/src/lib/push-chain/helpers/abis.js.map +0 -1
  118. package/src/lib/push-chain/helpers/addresses.js.map +0 -1
  119. package/src/lib/push-chain/push-chain.js.map +0 -1
  120. package/src/lib/push-client/push-client.js.map +0 -1
  121. package/src/lib/push-client/push-client.types.js.map +0 -1
  122. package/src/lib/universal/account/account.js.map +0 -1
  123. package/src/lib/universal/account/index.js.map +0 -1
  124. package/src/lib/universal/signer/index.js.map +0 -1
  125. package/src/lib/universal/signer/signer.js.map +0 -1
  126. package/src/lib/universal/signer/signer.types.js.map +0 -1
  127. package/src/lib/universal/universal.types.js.map +0 -1
  128. package/src/lib/utils.js.map +0 -1
  129. package/src/lib/vm-client/evm-client.js.map +0 -1
  130. package/src/lib/vm-client/svm-client.js.map +0 -1
  131. package/src/lib/vm-client/vm-client.types.js.map +0 -1
@@ -0,0 +1,424 @@
1
+ "use strict";
2
+ /**
3
+ * Gas fee queries, native amount calculations, ERC-20 allowance,
4
+ * and Uniswap V3 quoting — extracted from Orchestrator.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ensureErc20Allowance = ensureErc20Allowance;
8
+ exports.queryOutboundGasFee = queryOutboundGasFee;
9
+ exports.estimateNativeValueForSwap = estimateNativeValueForSwap;
10
+ exports.queryRescueGasFee = queryRescueGasFee;
11
+ exports.calculateNativeAmountForDeposit = calculateNativeAmountForDeposit;
12
+ exports.calculateGasAmountFromAmountOutMinETH = calculateGasAmountFromAmountOutMinETH;
13
+ const tslib_1 = require("tslib");
14
+ const web3_js_1 = require("@solana/web3.js");
15
+ const viem_1 = require("viem");
16
+ const abi_1 = require("../../constants/abi");
17
+ const chain_1 = require("../../constants/chain");
18
+ const enums_1 = require("../../constants/enums");
19
+ const tokens_1 = require("../../constants/tokens");
20
+ const progress_hook_types_1 = require("../../progress-hook/progress-hook.types");
21
+ const price_fetch_1 = require("../../price-fetch/price-fetch");
22
+ const utils_1 = require("../../utils");
23
+ const svm_client_1 = require("../../vm-client/svm-client");
24
+ const context_1 = require("./context");
25
+ const helpers_1 = require("./helpers");
26
+ /** Buffer multiplier for nativeValueForGas. Excess is refunded by swapAndBurnGas to the UEA. */
27
+ const GAS_FEE_BUFFER_MULTIPLIER = BigInt(1000000);
28
+ // Minimal ABIs for Uniswap V3 pool price estimation
29
+ const UNISWAP_V3_POOL_SLOT0_ABI = [
30
+ {
31
+ type: 'function',
32
+ name: 'slot0',
33
+ inputs: [],
34
+ outputs: [
35
+ { name: 'sqrtPriceX96', type: 'uint160', internalType: 'uint160' },
36
+ { name: 'tick', type: 'int24', internalType: 'int24' },
37
+ { name: 'observationIndex', type: 'uint16', internalType: 'uint16' },
38
+ { name: 'observationCardinality', type: 'uint16', internalType: 'uint16' },
39
+ { name: 'observationCardinalityNext', type: 'uint16', internalType: 'uint16' },
40
+ { name: 'feeProtocol', type: 'uint8', internalType: 'uint8' },
41
+ { name: 'unlocked', type: 'bool', internalType: 'bool' },
42
+ ],
43
+ stateMutability: 'view',
44
+ },
45
+ ];
46
+ const UNISWAP_V3_FACTORY_ABI = [
47
+ {
48
+ type: 'function',
49
+ name: 'getPool',
50
+ inputs: [
51
+ { name: 'tokenA', type: 'address', internalType: 'address' },
52
+ { name: 'tokenB', type: 'address', internalType: 'address' },
53
+ { name: 'fee', type: 'uint24', internalType: 'uint24' },
54
+ ],
55
+ outputs: [{ name: 'pool', type: 'address', internalType: 'address' }],
56
+ stateMutability: 'view',
57
+ },
58
+ ];
59
+ const UNIVERSAL_CORE_SWAP_HELPERS_ABI = [
60
+ { type: 'function', name: 'WPC', inputs: [], outputs: [{ name: '', type: 'address', internalType: 'address' }], stateMutability: 'view' },
61
+ { type: 'function', name: 'uniswapV3Factory', inputs: [], outputs: [{ name: '', type: 'address', internalType: 'address' }], stateMutability: 'view' },
62
+ { type: 'function', name: 'defaultFeeTier', inputs: [{ name: '', type: 'address', internalType: 'address' }], outputs: [{ name: '', type: 'uint24', internalType: 'uint24' }], stateMutability: 'view' },
63
+ ];
64
+ const ZERO_ADDR = '0x0000000000000000000000000000000000000000';
65
+ // ============================================================================
66
+ // ERC-20 Allowance
67
+ // ============================================================================
68
+ function ensureErc20Allowance(ctx, evmClient, tokenAddress, spender, requiredAmount) {
69
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
70
+ const chain = ctx.universalSigner.account.chain;
71
+ const owner = ctx.universalSigner.account.address;
72
+ const currentAllowance = yield evmClient.readContract({
73
+ abi: abi_1.ERC20_EVM,
74
+ address: tokenAddress,
75
+ functionName: 'allowance',
76
+ args: [owner, spender],
77
+ });
78
+ if (currentAllowance >= requiredAmount)
79
+ return;
80
+ if (currentAllowance > BigInt(0)) {
81
+ (0, context_1.printLog)(ctx, `Resetting existing allowance from ${currentAllowance.toString()} to 0 for spender ${spender}`);
82
+ const resetTxHash = yield evmClient.writeContract({
83
+ abi: abi_1.ERC20_EVM,
84
+ address: tokenAddress,
85
+ functionName: 'approve',
86
+ args: [spender, BigInt(0)],
87
+ signer: ctx.universalSigner,
88
+ });
89
+ yield evmClient.waitForConfirmations({
90
+ txHash: resetTxHash,
91
+ confirmations: 1,
92
+ timeoutMs: chain_1.CHAIN_INFO[chain].timeout,
93
+ });
94
+ }
95
+ const setTxHash = yield evmClient.writeContract({
96
+ abi: abi_1.ERC20_EVM,
97
+ address: tokenAddress,
98
+ functionName: 'approve',
99
+ args: [spender, requiredAmount],
100
+ signer: ctx.universalSigner,
101
+ });
102
+ yield evmClient.waitForConfirmations({
103
+ txHash: setTxHash,
104
+ confirmations: 1,
105
+ timeoutMs: chain_1.CHAIN_INFO[chain].timeout,
106
+ });
107
+ try {
108
+ const updated = yield evmClient.readContract({
109
+ abi: abi_1.ERC20_EVM,
110
+ address: tokenAddress,
111
+ functionName: 'allowance',
112
+ args: [owner, spender],
113
+ });
114
+ if (updated < requiredAmount) {
115
+ (0, context_1.printLog)(ctx, 'Warning: allowance not updated yet; proceeding');
116
+ }
117
+ }
118
+ catch (_a) {
119
+ // ignore
120
+ }
121
+ });
122
+ }
123
+ // ============================================================================
124
+ // Outbound Gas Fee Query
125
+ // ============================================================================
126
+ function queryOutboundGasFee(ctx, prc20Token, gasLimit) {
127
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
128
+ var _a, _b;
129
+ const gatewayPcAddress = (0, helpers_1.getUniversalGatewayPCAddress)();
130
+ const pushChain = (0, helpers_1.getPushChainForNetwork)(ctx.pushNetwork);
131
+ const rpcUrl = ((_b = (_a = chain_1.CHAIN_INFO[pushChain]) === null || _a === void 0 ? void 0 : _a.defaultRPC) === null || _b === void 0 ? void 0 : _b[0]) || 'unknown';
132
+ (0, context_1.printLog)(ctx, `queryOutboundGasFee — [step 1] inputs: gateway=${gatewayPcAddress}, prc20Token=${prc20Token}, gasLimit=${gasLimit}, rpcUrl=${rpcUrl}`);
133
+ let universalCoreAddress;
134
+ try {
135
+ universalCoreAddress = yield ctx.pushClient.readContract({
136
+ address: gatewayPcAddress,
137
+ abi: abi_1.UNIVERSAL_GATEWAY_PC,
138
+ functionName: 'UNIVERSAL_CORE',
139
+ args: [],
140
+ });
141
+ (0, context_1.printLog)(ctx, `queryOutboundGasFee — [step 2] UNIVERSAL_CORE resolved to: ${universalCoreAddress}`);
142
+ }
143
+ catch (err) {
144
+ (0, context_1.printLog)(ctx, `queryOutboundGasFee — [step 2] FAILED to read UNIVERSAL_CORE: ${err instanceof Error ? err.message : String(err)}`);
145
+ throw err;
146
+ }
147
+ const callData = (0, viem_1.encodeFunctionData)({
148
+ abi: abi_1.UNIVERSAL_CORE_EVM,
149
+ functionName: 'getOutboundTxGasAndFees',
150
+ args: [prc20Token, gasLimit],
151
+ });
152
+ (0, context_1.printLog)(ctx, `queryOutboundGasFee — [step 3] calling getOutboundTxGasAndFees on ${universalCoreAddress}`);
153
+ (0, context_1.printLog)(ctx, `queryOutboundGasFee — [step 3] eth_call: {"method":"eth_call","params":[{"to":"${universalCoreAddress}","data":"${callData}"},"latest"]}`);
154
+ let gasToken;
155
+ let gasFee;
156
+ let protocolFee;
157
+ let gasPrice = BigInt(0);
158
+ try {
159
+ const result = yield ctx.pushClient.readContract({
160
+ address: universalCoreAddress,
161
+ abi: abi_1.UNIVERSAL_CORE_EVM,
162
+ functionName: 'getOutboundTxGasAndFees',
163
+ args: [prc20Token, gasLimit],
164
+ });
165
+ gasToken = result[0];
166
+ gasFee = result[1];
167
+ protocolFee = result[2];
168
+ gasPrice = result[3];
169
+ (0, context_1.printLog)(ctx, `queryOutboundGasFee — [step 4] success: gasToken=${gasToken}, gasFee=${gasFee}, protocolFee=${protocolFee}, gasPrice=${gasPrice}`);
170
+ }
171
+ catch (err) {
172
+ (0, context_1.printLog)(ctx, `queryOutboundGasFee — [step 3] FAILED: ${err instanceof Error ? err.message : String(err)}`);
173
+ throw err;
174
+ }
175
+ const nativeValueForGas = protocolFee + gasFee * GAS_FEE_BUFFER_MULTIPLIER;
176
+ (0, context_1.printLog)(ctx, `queryOutboundGasFee — [step 5] using 1000000x buffer: nativeValueForGas=${nativeValueForGas}`);
177
+ return { gasToken, gasFee, protocolFee, nativeValueForGas, gasPrice, universalCoreAddress };
178
+ });
179
+ }
180
+ // ============================================================================
181
+ // Uniswap V3 Pool Price Estimation
182
+ // ============================================================================
183
+ /**
184
+ * Estimate the native WPC amount needed to swap for `gasFee` of `gasToken`
185
+ * by reading the Uniswap V3 pool price on Push Chain.
186
+ * Returns the estimated amount with a 2x safety buffer (excess is refunded by the contract).
187
+ * Falls back to a percentage of accountBalance if any on-chain query fails.
188
+ */
189
+ function estimateNativeValueForSwap(ctx, universalCoreAddress, gasToken, gasFee, accountBalance) {
190
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
191
+ const SWAP_BUFFER = BigInt(2); // 2x safety buffer; excess is refunded by swapAndBurnGas
192
+ const BALANCE_FALLBACK_DIVISOR = BigInt(10); // 10% of balance as fallback
193
+ const GAS_RESERVE = BigInt(3e18); // 3 UPC reserve for tx overhead
194
+ try {
195
+ // Read WPC, factory, and defaultFeeTier in parallel
196
+ const [wpcAddress, factoryAddress, feeTier] = yield Promise.all([
197
+ ctx.pushClient.readContract({
198
+ address: universalCoreAddress,
199
+ abi: UNIVERSAL_CORE_SWAP_HELPERS_ABI,
200
+ functionName: 'WPC',
201
+ args: [],
202
+ }),
203
+ ctx.pushClient.readContract({
204
+ address: universalCoreAddress,
205
+ abi: UNIVERSAL_CORE_SWAP_HELPERS_ABI,
206
+ functionName: 'uniswapV3Factory',
207
+ args: [],
208
+ }),
209
+ ctx.pushClient.readContract({
210
+ address: universalCoreAddress,
211
+ abi: UNIVERSAL_CORE_SWAP_HELPERS_ABI,
212
+ functionName: 'defaultFeeTier',
213
+ args: [gasToken],
214
+ }),
215
+ ]);
216
+ if (!feeTier) {
217
+ (0, context_1.printLog)(ctx, `estimateNativeValueForSwap — no fee tier for gasToken, using balance fallback`);
218
+ return balanceFallback(accountBalance, BALANCE_FALLBACK_DIVISOR, GAS_RESERVE);
219
+ }
220
+ // Get pool address from factory
221
+ const poolAddress = yield ctx.pushClient.readContract({
222
+ address: factoryAddress,
223
+ abi: UNISWAP_V3_FACTORY_ABI,
224
+ functionName: 'getPool',
225
+ args: [wpcAddress, gasToken, feeTier],
226
+ });
227
+ if (poolAddress === ZERO_ADDR) {
228
+ (0, context_1.printLog)(ctx, `estimateNativeValueForSwap — pool not found, using balance fallback`);
229
+ return balanceFallback(accountBalance, BALANCE_FALLBACK_DIVISOR, GAS_RESERVE);
230
+ }
231
+ // Read slot0 for current price
232
+ const slot0 = yield ctx.pushClient.readContract({
233
+ address: poolAddress,
234
+ abi: UNISWAP_V3_POOL_SLOT0_ABI,
235
+ functionName: 'slot0',
236
+ args: [],
237
+ });
238
+ const sqrtPriceX96 = slot0[0];
239
+ if (!sqrtPriceX96 || sqrtPriceX96 === BigInt(0)) {
240
+ (0, context_1.printLog)(ctx, `estimateNativeValueForSwap — pool not initialized, using balance fallback`);
241
+ return balanceFallback(accountBalance, BALANCE_FALLBACK_DIVISOR, GAS_RESERVE);
242
+ }
243
+ // price (token1/token0 in raw units) = (sqrtPriceX96)² / 2¹⁹²
244
+ const Q192 = BigInt(1) << BigInt(192);
245
+ const priceNum = sqrtPriceX96 * sqrtPriceX96; // sqrtPrice² in Q192
246
+ // Uniswap V3 sorts tokens: token0 < token1 by address
247
+ const isGasTokenToken0 = gasToken.toLowerCase() < wpcAddress.toLowerCase();
248
+ let wpcNeeded;
249
+ if (isGasTokenToken0) {
250
+ // price = WPC_per_gasToken → wpcNeeded = gasFee * price
251
+ wpcNeeded = (gasFee * priceNum) / Q192;
252
+ }
253
+ else {
254
+ // price = gasToken_per_WPC → wpcNeeded = gasFee / price
255
+ wpcNeeded = (gasFee * Q192) / priceNum;
256
+ }
257
+ const result = wpcNeeded * SWAP_BUFFER;
258
+ (0, context_1.printLog)(ctx, `estimateNativeValueForSwap — pool=${poolAddress}, sqrtPriceX96=${sqrtPriceX96}, ` +
259
+ `wpcNeeded=${wpcNeeded}, withBuffer(2x)=${result}`);
260
+ // Cap at (balance - reserve)
261
+ if (accountBalance > result + GAS_RESERVE) {
262
+ return result;
263
+ }
264
+ else if (accountBalance > GAS_RESERVE) {
265
+ return accountBalance - GAS_RESERVE;
266
+ }
267
+ return result; // let caller decide if balance is too low
268
+ }
269
+ catch (err) {
270
+ (0, context_1.printLog)(ctx, `estimateNativeValueForSwap — failed: ${err instanceof Error ? err.message : String(err)}, using balance fallback`);
271
+ return balanceFallback(accountBalance, BALANCE_FALLBACK_DIVISOR, GAS_RESERVE);
272
+ }
273
+ });
274
+ }
275
+ function balanceFallback(balance, divisor, reserve) {
276
+ const fraction = balance / divisor;
277
+ if (balance > fraction + reserve)
278
+ return fraction;
279
+ if (balance > reserve)
280
+ return balance - reserve;
281
+ return fraction;
282
+ }
283
+ // ============================================================================
284
+ // Rescue Gas Fee Query
285
+ // ============================================================================
286
+ function queryRescueGasFee(ctx, prc20Token) {
287
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
288
+ const gatewayPcAddress = (0, helpers_1.getUniversalGatewayPCAddress)();
289
+ (0, context_1.printLog)(ctx, `queryRescueGasFee — inputs: gateway=${gatewayPcAddress}, prc20Token=${prc20Token}`);
290
+ let universalCoreAddress;
291
+ try {
292
+ universalCoreAddress = yield ctx.pushClient.readContract({
293
+ address: gatewayPcAddress,
294
+ abi: abi_1.UNIVERSAL_GATEWAY_PC,
295
+ functionName: 'UNIVERSAL_CORE',
296
+ args: [],
297
+ });
298
+ (0, context_1.printLog)(ctx, `queryRescueGasFee — UNIVERSAL_CORE resolved to: ${universalCoreAddress}`);
299
+ }
300
+ catch (err) {
301
+ (0, context_1.printLog)(ctx, `queryRescueGasFee — FAILED to read UNIVERSAL_CORE: ${err instanceof Error ? err.message : String(err)}`);
302
+ throw err;
303
+ }
304
+ let gasToken;
305
+ let gasFee;
306
+ let rescueGasLimit;
307
+ let gasPrice;
308
+ try {
309
+ const result = yield ctx.pushClient.readContract({
310
+ address: universalCoreAddress,
311
+ abi: abi_1.UNIVERSAL_CORE_EVM,
312
+ functionName: 'getRescueFundsGasLimit',
313
+ args: [prc20Token],
314
+ });
315
+ gasToken = result[0];
316
+ gasFee = result[1];
317
+ rescueGasLimit = result[2];
318
+ gasPrice = result[3];
319
+ (0, context_1.printLog)(ctx, `queryRescueGasFee — success: gasToken=${gasToken}, gasFee=${gasFee}, rescueGasLimit=${rescueGasLimit}, gasPrice=${gasPrice}`);
320
+ }
321
+ catch (err) {
322
+ (0, context_1.printLog)(ctx, `queryRescueGasFee — FAILED: ${err instanceof Error ? err.message : String(err)}`);
323
+ throw err;
324
+ }
325
+ const nativeValueForGas = gasFee * GAS_FEE_BUFFER_MULTIPLIER;
326
+ (0, context_1.printLog)(ctx, `queryRescueGasFee — using 1000000x buffer: nativeValueForGas=${nativeValueForGas}`);
327
+ return { gasToken, gasFee, rescueGasLimit, gasPrice, nativeValueForGas };
328
+ });
329
+ }
330
+ // ============================================================================
331
+ // Native Amount Calculation for Deposit
332
+ // ============================================================================
333
+ function calculateNativeAmountForDeposit(ctx, chain, requiredFunds, ueaBalance) {
334
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
335
+ var _a, _b;
336
+ (0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_02_01);
337
+ const oneUsd = utils_1.Utils.helpers.parseUnits('1', 8);
338
+ const tenUsd = utils_1.Utils.helpers.parseUnits('10', 8);
339
+ const deficit = requiredFunds > ueaBalance ? requiredFunds - ueaBalance : BigInt(0);
340
+ let depositUsd = deficit > BigInt(0) ? ctx.pushClient.pushToUSDC(deficit) : oneUsd;
341
+ if (depositUsd < oneUsd)
342
+ depositUsd = oneUsd;
343
+ if (depositUsd > tenUsd)
344
+ throw new Error('Deposit value exceeds max $10 worth of native token');
345
+ if (chain_1.CHAIN_INFO[chain].vm === enums_1.VM.SVM) {
346
+ const svmClient = new svm_client_1.SvmClient({
347
+ rpcUrls: ctx.rpcUrls[enums_1.CHAIN.SOLANA_DEVNET] ||
348
+ chain_1.CHAIN_INFO[enums_1.CHAIN.SOLANA_DEVNET].defaultRPC,
349
+ });
350
+ const programId = new web3_js_1.PublicKey(abi_1.SVM_GATEWAY_IDL.address);
351
+ const [configPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('config')], programId);
352
+ try {
353
+ const cfg = yield svmClient.readContract({
354
+ abi: abi_1.SVM_GATEWAY_IDL,
355
+ address: abi_1.SVM_GATEWAY_IDL.address,
356
+ functionName: 'config',
357
+ args: [configPda.toBase58()],
358
+ });
359
+ const minField = (_a = cfg.minCapUniversalTxUsd) !== null && _a !== void 0 ? _a : cfg.min_cap_universal_tx_usd;
360
+ const maxField = (_b = cfg.maxCapUniversalTxUsd) !== null && _b !== void 0 ? _b : cfg.max_cap_universal_tx_usd;
361
+ const minCapUsd = BigInt(minField.toString());
362
+ const maxCapUsd = BigInt(maxField.toString());
363
+ if (depositUsd < minCapUsd)
364
+ depositUsd = minCapUsd;
365
+ const withMargin = (minCapUsd * BigInt(12)) / BigInt(10);
366
+ if (depositUsd < withMargin)
367
+ depositUsd = withMargin;
368
+ if (depositUsd > maxCapUsd)
369
+ depositUsd = maxCapUsd;
370
+ }
371
+ catch (_c) {
372
+ // best-effort
373
+ }
374
+ }
375
+ const nativeTokenUsdPrice = yield new price_fetch_1.PriceFetch(ctx.rpcUrls).getPrice(chain);
376
+ const nativeDecimals = chain_1.CHAIN_INFO[chain].vm === enums_1.VM.SVM ? 9 : 18;
377
+ const oneNativeUnit = utils_1.Utils.helpers.parseUnits('1', nativeDecimals);
378
+ let nativeAmount = (depositUsd * oneNativeUnit + (nativeTokenUsdPrice - BigInt(1))) /
379
+ nativeTokenUsdPrice;
380
+ nativeAmount = nativeAmount + BigInt(1);
381
+ (0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_02_02, nativeAmount);
382
+ return nativeAmount;
383
+ });
384
+ }
385
+ // ============================================================================
386
+ // ERC-20 Gas Amount from Exact Output Quote
387
+ // ============================================================================
388
+ function calculateGasAmountFromAmountOutMinETH(ctx, gasTokenAddress, amountOutMinETH, quoteExactOutputFn) {
389
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
390
+ var _a, _b, _c;
391
+ const originChain = ctx.universalSigner.account.chain;
392
+ if (originChain !== enums_1.CHAIN.ETHEREUM_SEPOLIA &&
393
+ originChain !== enums_1.CHAIN.ARBITRUM_SEPOLIA &&
394
+ originChain !== enums_1.CHAIN.BASE_SEPOLIA) {
395
+ throw new Error('Gas payment in ERC-20 is supported only on Ethereum Sepolia, Arbitrum Sepolia, and Base Sepolia for now');
396
+ }
397
+ const WETH = (_a = chain_1.CHAIN_INFO[originChain].dex) === null || _a === void 0 ? void 0 : _a.weth;
398
+ if (!WETH)
399
+ throw new Error('WETH address not configured for this chain');
400
+ let gasAmount;
401
+ if (gasTokenAddress.toLowerCase() === WETH.toLowerCase()) {
402
+ gasAmount = BigInt(amountOutMinETH);
403
+ }
404
+ else {
405
+ const fromList = (_b = tokens_1.PAYABLE_TOKENS[originChain]) !== null && _b !== void 0 ? _b : [];
406
+ const fromToken = fromList.find((t) => (t.address || '').toLowerCase() === gasTokenAddress.toLowerCase());
407
+ const toList = ((_c = tokens_1.MOVEABLE_TOKENS[originChain]) !== null && _c !== void 0 ? _c : []);
408
+ const toToken = toList.find((t) => t.symbol === 'WETH' ||
409
+ (t.address || '').toLowerCase() === (WETH || '').toLowerCase());
410
+ if (!fromToken || !toToken) {
411
+ throw new Error('Token not supported for quoting');
412
+ }
413
+ const targetOut = BigInt(amountOutMinETH);
414
+ const exactOutQuote = yield quoteExactOutputFn(targetOut, {
415
+ from: fromToken,
416
+ to: toToken,
417
+ });
418
+ const requiredIn = BigInt(exactOutQuote.amountIn);
419
+ gasAmount = (requiredIn * BigInt(101)) / BigInt(100);
420
+ }
421
+ return { gasAmount };
422
+ });
423
+ }
424
+ //# sourceMappingURL=gas-calculator.js.map
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Gateway interaction: request conversion, tx sending, and fee locking.
3
+ * All chains use V1 gateway ABI.
4
+ */
5
+ import { CHAIN } from '../../constants/enums';
6
+ import { EvmClient } from '../../vm-client/evm-client';
7
+ import type { UniversalPayload } from '../../generated/v1/tx';
8
+ import type { UniversalTxRequest, UniversalTxRequestV1, UniversalTokenTxRequest, UniversalTokenTxRequestV1 } from '../orchestrator.types';
9
+ import type { UniversalSigner } from '../../universal/universal.types';
10
+ import type { OrchestratorContext } from './context';
11
+ export declare function toGatewayRequestV1(req: UniversalTxRequest): UniversalTxRequestV1;
12
+ export declare function toGatewayTokenRequestV1(req: UniversalTokenTxRequest): UniversalTokenTxRequestV1;
13
+ export declare function sendGatewayTxWithFallback(ctx: OrchestratorContext, evmClient: EvmClient, address: `0x${string}`, req: UniversalTxRequest, signer: UniversalSigner, value: bigint): Promise<`0x${string}`>;
14
+ export declare function sendGatewayTokenTxWithFallback(ctx: OrchestratorContext, evmClient: EvmClient, address: `0x${string}`, req: UniversalTokenTxRequest, signer: UniversalSigner, value?: bigint): Promise<`0x${string}`>;
15
+ export declare function lockFee(ctx: OrchestratorContext, amount: bigint, universalPayload: UniversalPayload, req: UniversalTxRequest): Promise<Uint8Array>;
16
+ /**
17
+ * Creates an EVM client for the origin chain's gateway.
18
+ * Validates that the chain supports gateway operations.
19
+ */
20
+ export declare function getOriginGatewayContext(ctx: OrchestratorContext): {
21
+ chain: CHAIN;
22
+ evmClient?: EvmClient;
23
+ gatewayAddress?: `0x${string}`;
24
+ };
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ /**
3
+ * Gateway interaction: request conversion, tx sending, and fee locking.
4
+ * All chains use V1 gateway ABI.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.toGatewayRequestV1 = toGatewayRequestV1;
8
+ exports.toGatewayTokenRequestV1 = toGatewayTokenRequestV1;
9
+ exports.sendGatewayTxWithFallback = sendGatewayTxWithFallback;
10
+ exports.sendGatewayTokenTxWithFallback = sendGatewayTokenTxWithFallback;
11
+ exports.lockFee = lockFee;
12
+ exports.getOriginGatewayContext = getOriginGatewayContext;
13
+ const tslib_1 = require("tslib");
14
+ const bs58_1 = require("../../internal/bs58");
15
+ const web3_js_1 = require("@solana/web3.js");
16
+ const viem_1 = require("viem");
17
+ const context_1 = require("./context");
18
+ const abi_1 = require("../../constants/abi");
19
+ const chain_1 = require("../../constants/chain");
20
+ const enums_1 = require("../../constants/enums");
21
+ const price_fetch_1 = require("../../price-fetch/price-fetch");
22
+ const utils_1 = require("../../utils");
23
+ const evm_client_1 = require("../../vm-client/evm-client");
24
+ const helpers_1 = require("./helpers");
25
+ const svm_client_1 = require("../../vm-client/svm-client");
26
+ const context_2 = require("./context");
27
+ const svm_helpers_1 = require("./svm-helpers");
28
+ const svm_helpers_2 = require("./svm-helpers");
29
+ // ============================================================================
30
+ // ABI
31
+ // ============================================================================
32
+ const GATEWAY_ABI = abi_1.UNIVERSAL_GATEWAY_V1_SEND;
33
+ // ============================================================================
34
+ // Request Conversion (V0 struct → V1 flat format)
35
+ // ============================================================================
36
+ function toGatewayRequestV1(req) {
37
+ return {
38
+ recipient: req.recipient,
39
+ token: req.token,
40
+ amount: req.amount,
41
+ payload: req.payload,
42
+ revertRecipient: req.revertInstruction.fundRecipient,
43
+ signatureData: req.signatureData,
44
+ };
45
+ }
46
+ function toGatewayTokenRequestV1(req) {
47
+ return {
48
+ recipient: req.recipient,
49
+ token: req.token,
50
+ amount: req.amount,
51
+ gasToken: req.gasToken,
52
+ gasAmount: req.gasAmount,
53
+ payload: req.payload,
54
+ revertRecipient: req.revertInstruction.fundRecipient,
55
+ signatureData: req.signatureData,
56
+ amountOutMinETH: req.amountOutMinETH,
57
+ deadline: req.deadline,
58
+ };
59
+ }
60
+ // ============================================================================
61
+ // Send Gateway Tx (V1 only)
62
+ // ============================================================================
63
+ function sendGatewayTxWithFallback(ctx, evmClient, address, req, signer, value) {
64
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
65
+ return evmClient.writeContract({
66
+ abi: GATEWAY_ABI,
67
+ address,
68
+ functionName: 'sendUniversalTx',
69
+ args: [toGatewayRequestV1(req)],
70
+ signer,
71
+ value,
72
+ });
73
+ });
74
+ }
75
+ function sendGatewayTokenTxWithFallback(ctx, evmClient, address, req, signer, value) {
76
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
77
+ return evmClient.writeContract(Object.assign({ abi: GATEWAY_ABI, address, functionName: 'sendUniversalTx', args: [toGatewayTokenRequestV1(req)], signer }, (value !== undefined && { value })));
78
+ });
79
+ }
80
+ // ============================================================================
81
+ // Fee Locking
82
+ // ============================================================================
83
+ function lockFee(ctx, amount, universalPayload,
84
+ // DEBUG: lockFee entry
85
+ req) {
86
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
87
+ const chain = ctx.universalSigner.account.chain;
88
+ const { lockerContract, vm, defaultRPC } = chain_1.CHAIN_INFO[chain];
89
+ if (!lockerContract) {
90
+ throw new Error(`Locker contract not configured for chain: ${chain}`);
91
+ }
92
+ const rpcUrls = ctx.rpcUrls[chain] || defaultRPC;
93
+ switch (vm) {
94
+ case enums_1.VM.EVM: {
95
+ const evmClient = (0, context_1.getOriginEvmClient)(ctx);
96
+ const nativeTokenUsdPrice = yield new price_fetch_1.PriceFetch(ctx.rpcUrls).getPrice(chain);
97
+ const nativeDecimals = 18;
98
+ const oneUsd = utils_1.Utils.helpers.parseUnits('1', 8);
99
+ const tenUsd = utils_1.Utils.helpers.parseUnits('10', 8);
100
+ let depositUsd = amount < oneUsd ? oneUsd : amount;
101
+ if (depositUsd > tenUsd)
102
+ depositUsd = tenUsd;
103
+ let nativeAmount = (depositUsd * BigInt(Math.pow(10, nativeDecimals)) +
104
+ (nativeTokenUsdPrice - BigInt(1))) /
105
+ nativeTokenUsdPrice;
106
+ nativeAmount = nativeAmount + BigInt(1);
107
+ const txHash = yield sendGatewayTxWithFallback(ctx, evmClient, lockerContract, req, ctx.universalSigner, nativeAmount);
108
+ return (0, viem_1.hexToBytes)(txHash);
109
+ }
110
+ case enums_1.VM.SVM: {
111
+ const [nativeTokenUsdPrice, svmClient] = yield Promise.all([
112
+ new price_fetch_1.PriceFetch(ctx.rpcUrls).getPrice(chain),
113
+ Promise.resolve(new svm_client_1.SvmClient({ rpcUrls })),
114
+ ]);
115
+ const nativeDecimals = 9;
116
+ const oneUsd = utils_1.Utils.helpers.parseUnits('1', 8);
117
+ const tenUsd = utils_1.Utils.helpers.parseUnits('10', 8);
118
+ let depositUsd = amount < oneUsd ? oneUsd : amount;
119
+ if (depositUsd > tenUsd)
120
+ depositUsd = tenUsd;
121
+ let nativeAmount = (depositUsd * BigInt(Math.pow(10, nativeDecimals)) +
122
+ (nativeTokenUsdPrice - BigInt(1))) /
123
+ nativeTokenUsdPrice;
124
+ nativeAmount = nativeAmount + BigInt(1);
125
+ const programId = new web3_js_1.PublicKey(abi_1.SVM_GATEWAY_IDL.address);
126
+ const [configPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('config')], programId);
127
+ const [vaultPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('vault')], programId);
128
+ const [rateLimitConfigPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('rate_limit_config')], programId);
129
+ const [tokenRateLimitPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('rate_limit'), web3_js_1.PublicKey.default.toBuffer()], programId);
130
+ const userPk = new web3_js_1.PublicKey(ctx.universalSigner.account.address);
131
+ const { feeVaultPda, protocolFeeLamports } = yield (0, svm_helpers_2.getSvmProtocolFee)(svmClient, programId);
132
+ const gasReq = (0, svm_helpers_1.buildSvmUniversalTxRequestFromReq)(req, userPk);
133
+ try {
134
+ const txHash = yield svmClient.writeContract({
135
+ abi: abi_1.SVM_GATEWAY_IDL,
136
+ address: programId.toBase58(),
137
+ functionName: 'sendUniversalTx',
138
+ args: [gasReq, nativeAmount + protocolFeeLamports],
139
+ signer: ctx.universalSigner,
140
+ accounts: {
141
+ config: configPda,
142
+ vault: vaultPda,
143
+ feeVault: feeVaultPda,
144
+ userTokenAccount: vaultPda,
145
+ gatewayTokenAccount: vaultPda,
146
+ user: userPk,
147
+ priceUpdate: new web3_js_1.PublicKey(chain_1.SVM_PYTH_PRICE_FEED),
148
+ rateLimitConfig: rateLimitConfigPda,
149
+ tokenRateLimit: tokenRateLimitPda,
150
+ tokenProgram: new web3_js_1.PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'),
151
+ systemProgram: web3_js_1.SystemProgram.programId,
152
+ },
153
+ });
154
+ return new Uint8Array(bs58_1.bs58.decode(txHash));
155
+ }
156
+ catch (error) {
157
+ (0, context_2.printLog)(ctx, `Error sending UniversalTx: ${error instanceof Error ? error.message : String(error)}`);
158
+ throw error;
159
+ }
160
+ }
161
+ default:
162
+ throw new Error(`Unsupported VM type: ${vm}`);
163
+ }
164
+ });
165
+ }
166
+ // ============================================================================
167
+ // Origin Gateway Context
168
+ // ============================================================================
169
+ /**
170
+ * Creates an EVM client for the origin chain's gateway.
171
+ * Validates that the chain supports gateway operations.
172
+ */
173
+ function getOriginGatewayContext(ctx) {
174
+ const chain = ctx.universalSigner.account.chain;
175
+ if (!helpers_1.SUPPORTED_GATEWAY_CHAINS.includes(chain)) {
176
+ throw new Error('Funds + payload bridging is only supported on Ethereum Sepolia, Arbitrum Sepolia, Base Sepolia, BNB Testnet, and Solana Devnet for now');
177
+ }
178
+ if (chain_1.CHAIN_INFO[chain].vm === enums_1.VM.EVM) {
179
+ const { defaultRPC, lockerContract } = chain_1.CHAIN_INFO[chain];
180
+ const rpcUrls = ctx.rpcUrls[chain] || defaultRPC;
181
+ const evmClient = new evm_client_1.EvmClient({ rpcUrls });
182
+ const gatewayAddress = lockerContract;
183
+ if (!gatewayAddress) {
184
+ throw new Error('Universal Gateway address not configured');
185
+ }
186
+ return { chain, evmClient, gatewayAddress };
187
+ }
188
+ // SVM path does not require evmClient/gatewayAddress
189
+ return { chain };
190
+ }
191
+ //# sourceMappingURL=gateway-client.js.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Pure utility functions extracted from Orchestrator.
3
+ *
4
+ * These have minimal dependencies and are used across multiple submodules.
5
+ */
6
+ import { CHAIN, PUSH_NETWORK } from '../../constants/enums';
7
+ import type { ExecuteParams, UniversalExecuteParams } from '../orchestrator.types';
8
+ import type { OrchestratorContext } from './context';
9
+ /** Chains that support gateway operations (multicall, funds bridging, etc.) */
10
+ export declare const SUPPORTED_GATEWAY_CHAINS: CHAIN[];
11
+ export declare function isPushChain(chain: CHAIN): boolean;
12
+ export declare function getPushChainForNetwork(pushNetwork: PUSH_NETWORK): CHAIN;
13
+ export declare function getChainNamespace(chain: CHAIN): string;
14
+ export declare function chainFromNamespace(namespace: string): CHAIN | null;
15
+ export declare function getNativePRC20ForChain(targetChain: CHAIN, pushNetwork: PUSH_NETWORK): `0x${string}`;
16
+ export declare function getUniversalGatewayPCAddress(): `0x${string}`;
17
+ /**
18
+ * Validates that a feeLockTxHash is a well-formed transaction hash.
19
+ * EVM: must be 0x-prefixed 64-hex-char string (66 chars total).
20
+ * SVM (Base58): must be at least 32 chars.
21
+ */
22
+ export declare function validateFeeLockTxHash(feeLockTxHash: string): void;
23
+ export declare function validateMainnetConnection(chain: CHAIN, pushChainId: string): void;
24
+ export declare function bigintReplacer(_key: string, value: any): any;
25
+ export declare function toExecuteParams(params: UniversalExecuteParams): ExecuteParams;
26
+ export declare function fetchOriginChainTransactionForProgress(ctx: OrchestratorContext, chain: CHAIN, txHashHex: string, txHashDisplay: string): Promise<object | undefined>;