@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
@@ -30,281 +30,319 @@ const confirmation_1 = require("./confirmation");
30
30
  const response_builder_1 = require("./response-builder");
31
31
  const push_chain_tx_1 = require("./push-chain-tx");
32
32
  const svm_helpers_1 = require("./svm-helpers");
33
+ const svm_1 = require("./pc20/svm");
33
34
  const helpers_2 = require("./helpers");
34
35
  const response_builder_2 = require("./response-builder");
35
36
  const formatters_1 = require("../../formatters");
36
- function executeFundsOnly(ctx, execute, eventBuffer, getResponseCallbacks) {
37
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
38
- const transformFn = (tx, buf = []) => (0, response_builder_2.transformToUniversalTxResponse)(ctx, tx, buf, getResponseCallbacks());
39
- const chain = ctx.universalSigner.account.chain;
40
- const { vm } = chain_1.CHAIN_INFO[chain];
41
- if (!helpers_1.SUPPORTED_GATEWAY_CHAINS.includes(chain)) {
42
- throw new Error(`Funds bridging is not supported on chain ${chain}. Supported chains: ${helpers_1.SUPPORTED_GATEWAY_CHAINS.join(', ')}`);
37
+ async function executeFundsOnly(ctx, execute, eventBuffer, getResponseCallbacks) {
38
+ const transformFn = (tx, buf = []) => (0, response_builder_2.transformToUniversalTxResponse)(ctx, tx, buf, getResponseCallbacks());
39
+ const chain = ctx.universalSigner.account.chain;
40
+ const { vm } = chain_1.CHAIN_INFO[chain];
41
+ if (!helpers_1.SUPPORTED_GATEWAY_CHAINS.includes(chain)) {
42
+ throw new Error(`Funds bridging is not supported on chain ${chain}. Supported chains: ${helpers_1.SUPPORTED_GATEWAY_CHAINS.join(', ')}`);
43
+ }
44
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_101, chain, ctx.universalSigner.account.address);
45
+ const { defaultRPC, lockerContract } = chain_1.CHAIN_INFO[chain];
46
+ const rpcUrls = ctx.rpcUrls[chain] || defaultRPC;
47
+ // Resolve token: default to native token based on VM
48
+ if (!execute.funds.token) {
49
+ const available = tokens_1.MOVEABLE_TOKENS[chain] || [];
50
+ const preferredSymbol = vm === enums_1.VM.EVM ? 'ETH' : vm === enums_1.VM.SVM ? 'SOL' : undefined;
51
+ const nativeToken = preferredSymbol
52
+ ? available.find((t) => t.symbol === preferredSymbol)
53
+ : undefined;
54
+ if (!nativeToken) {
55
+ throw new Error('Native token not configured for this chain');
43
56
  }
44
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_101, chain, ctx.universalSigner.account.address);
45
- const { defaultRPC, lockerContract } = chain_1.CHAIN_INFO[chain];
46
- const rpcUrls = ctx.rpcUrls[chain] || defaultRPC;
47
- // Resolve token: default to native token based on VM
48
- if (!execute.funds.token) {
49
- const available = tokens_1.MOVEABLE_TOKENS[chain] || [];
50
- const preferredSymbol = vm === enums_1.VM.EVM ? 'ETH' : vm === enums_1.VM.SVM ? 'SOL' : undefined;
51
- const nativeToken = preferredSymbol
52
- ? available.find((t) => t.symbol === preferredSymbol)
53
- : undefined;
54
- if (!nativeToken) {
55
- throw new Error('Native token not configured for this chain');
56
- }
57
- execute.funds.token = nativeToken;
58
- }
59
- const amount = execute.funds.amount;
60
- const symbol = execute.funds.token.symbol;
61
- const bridgeAmount = amount;
62
- if (vm === enums_1.VM.EVM) {
63
- return executeFundsOnlyEvm(ctx, execute, eventBuffer, transformFn, chain, rpcUrls, lockerContract, bridgeAmount, symbol);
64
- }
65
- else {
66
- return executeFundsOnlySvm(ctx, execute, eventBuffer, transformFn, chain, rpcUrls, bridgeAmount, symbol);
67
- }
68
- });
57
+ execute.funds.token = nativeToken;
58
+ }
59
+ const amount = execute.funds.amount;
60
+ const symbol = execute.funds.token.symbol;
61
+ const bridgeAmount = amount;
62
+ if (vm === enums_1.VM.EVM) {
63
+ return executeFundsOnlyEvm(ctx, execute, eventBuffer, transformFn, chain, rpcUrls, lockerContract, bridgeAmount, symbol);
64
+ }
65
+ else {
66
+ return executeFundsOnlySvm(ctx, execute, eventBuffer, transformFn, chain, rpcUrls, bridgeAmount, symbol);
67
+ }
69
68
  }
70
69
  // ============================================================================
71
70
  // EVM funds-only path
72
71
  // ============================================================================
73
- function executeFundsOnlyEvm(ctx, execute, eventBuffer, transformFn, chain, rpcUrls, lockerContract, bridgeAmount, symbol) {
74
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
75
- var _a, _b, _c;
76
- const evmClient = (0, context_1.getOriginEvmClient)(ctx);
77
- const gatewayAddress = lockerContract;
78
- const tokenAddr = execute.funds.token.address;
79
- const isNative = execute.funds.token.mechanism === 'native';
80
- // Skip getCode if accountStatusCache already confirmed deployment
81
- let nonce;
82
- let deployed;
83
- const deployedHint = (_b = (_a = ctx.accountStatusCache) === null || _a === void 0 ? void 0 : _a.uea) === null || _b === void 0 ? void 0 : _b.deployed;
84
- if (deployedHint) {
85
- deployed = true;
86
- nonce = yield (0, uea_manager_1.getUEANonce)(ctx, (0, uea_manager_1.computeUEAOffchain)(ctx));
72
+ async function executeFundsOnlyEvm(ctx, execute, eventBuffer, transformFn, chain, rpcUrls, lockerContract, bridgeAmount, symbol) {
73
+ const evmClient = (0, context_1.getOriginEvmClient)(ctx);
74
+ const gatewayAddress = lockerContract;
75
+ const tokenAddr = execute.funds.token.address;
76
+ const isNative = execute.funds.token.mechanism === 'native';
77
+ // Skip getCode if accountStatusCache already confirmed deployment
78
+ let nonce;
79
+ let deployed;
80
+ const deployedHint = ctx.accountStatusCache?.uea?.deployed;
81
+ if (deployedHint) {
82
+ deployed = true;
83
+ nonce = await (0, uea_manager_1.getUEANonce)(ctx, (0, uea_manager_1.computeUEAOffchain)(ctx));
84
+ }
85
+ else {
86
+ const status = await (0, uea_manager_1.getUeaStatusAndNonce)(ctx);
87
+ nonce = status.nonce;
88
+ deployed = status.deployed;
89
+ }
90
+ const { payload: universalPayload, req } = await (0, payload_builder_1.buildGatewayPayloadAndGas)(ctx, execute, nonce, 'sendFunds', bridgeAmount);
91
+ const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
92
+ (0, context_2.printLog)(ctx, 'sendFunds — buildGatewayPayloadAndGas result: ' + JSON.stringify({
93
+ recipient: execute.to, ueaAddress,
94
+ isSelfBridge: execute.to.toLowerCase() === ueaAddress.toLowerCase(),
95
+ bridgeAmount: bridgeAmount.toString(), isNative, tokenAddr,
96
+ nonce: nonce.toString(), deployed,
97
+ }, (_, v) => typeof v === 'bigint' ? v.toString() : v, 2));
98
+ const ueaBalanceForGas = await ctx.pushClient.getBalance(ueaAddress);
99
+ const gasEstimate = execute.gasLimit || BigInt(1e7);
100
+ const gasPrice = await ctx.pushClient.getGasPrice();
101
+ const requiredGasFee = gasEstimate * gasPrice;
102
+ const requiredFunds = requiredGasFee + (execute.value ?? BigInt(0));
103
+ let nativeAmount = await (0, gas_calculator_1.calculateNativeAmountForDeposit)(ctx, chain, requiredFunds, ueaBalanceForGas,
104
+ // Defer the 103-03-04 ("Prepaid Deposit Estimated") hook — we emit the full
105
+ // 103-03 sizing sequence below, after 103-01/103-02 (UEA resolution), to
106
+ // match the funds-payload path ordering.
107
+ { emitDepositEstimated: false });
108
+ // For EVM fee-locking, fixed-rate PC→USD sizing can underfund when the
109
+ // live WPC/native pool prices PC above the SDK's fallback price. Size the
110
+ // native deposit against the same Push Chain pool used by the gateway.
111
+ if (chain_1.CHAIN_INFO[chain].vm === enums_1.VM.EVM && requiredFunds > ueaBalanceForGas) {
112
+ const deficit = requiredFunds - ueaBalanceForGas;
113
+ const targetWpc = (deficit * BigInt(12)) / BigInt(10);
114
+ const originPrc20 = (0, helpers_1.getNativePRC20ForChain)(chain, ctx.pushNetwork);
115
+ const poolNativeAmount = await (0, gas_calculator_1.estimateNativeForDesiredDeposit)(ctx, targetWpc, originPrc20);
116
+ if (poolNativeAmount > nativeAmount) {
117
+ (0, context_2.printLog)(ctx, `sendFunds — pool-based deposit sizing overrides fixed-rate estimate: fixedNative=${nativeAmount.toString()}, ` +
118
+ `poolNative=${poolNativeAmount.toString()}, requiredFunds=${requiredFunds.toString()}, ` +
119
+ `ueaBalance=${ueaBalanceForGas.toString()}`);
120
+ nativeAmount = poolNativeAmount;
87
121
  }
88
- else {
89
- const status = yield (0, uea_manager_1.getUeaStatusAndNonce)(ctx);
90
- nonce = status.nonce;
91
- deployed = status.deployed;
92
- }
93
- const { payload: universalPayload, req } = yield (0, payload_builder_1.buildGatewayPayloadAndGas)(ctx, execute, nonce, 'sendFunds', bridgeAmount);
94
- const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
95
- (0, context_2.printLog)(ctx, 'sendFunds — buildGatewayPayloadAndGas result: ' + JSON.stringify({
96
- recipient: execute.to, ueaAddress,
97
- isSelfBridge: execute.to.toLowerCase() === ueaAddress.toLowerCase(),
98
- bridgeAmount: bridgeAmount.toString(), isNative, tokenAddr,
99
- nonce: nonce.toString(), deployed,
122
+ }
123
+ (0, context_2.printLog)(ctx, `sendFunds — nativeAmount: ${nativeAmount.toString()}, ueaBalanceForGas: ${ueaBalanceForGas.toString()}, ` +
124
+ `requiredFunds: ${requiredFunds.toString()}`);
125
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_01);
126
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_02, ueaAddress, deployed);
127
+ (0, context_2.printLog)(ctx, `UEA resolved: ${ueaAddress}, deployed: ${deployed}`);
128
+ // SDK 5.2 R1 deposit-sizing progress (parent + Case A/B/C + terminal),
129
+ // emitted here — after UEA resolution — to match the funds-payload path's
130
+ // ordering. The terminal 103-03-04 hook was suppressed inside
131
+ // calculateNativeAmountForDeposit above so it lands in this position instead
132
+ // of before 103-01/103-02. Purely cosmetic: a pool/price read failure here
133
+ // must never block the bridge, so we fall back to the terminal hook alone.
134
+ try {
135
+ const r1Sizing = await (0, gas_usd_sizer_1.sizeR1PushGas)(ctx, {
136
+ pushGasFeeWei: requiredGasFee,
137
+ originChain: chain,
138
+ });
139
+ const nativeTokenUsdPrice = await new price_fetch_1.PriceFetch(ctx.rpcUrls).getPrice(chain);
140
+ const nativeDecimals = chain_1.CHAIN_INFO[chain].vm === enums_1.VM.SVM ? 9 : 18;
141
+ const oneNativeUnit = utils_1.Utils.helpers.parseUnits('1', nativeDecimals);
142
+ const plannedPCDeposit = nativeTokenUsdPrice === BigInt(0)
143
+ ? BigInt(0)
144
+ : (r1Sizing.paddedDepositUsd * oneNativeUnit +
145
+ (nativeTokenUsdPrice - BigInt(1))) /
146
+ nativeTokenUsdPrice +
147
+ BigInt(1);
148
+ const extraDepositPC = plannedPCDeposit > requiredGasFee
149
+ ? plannedPCDeposit - requiredGasFee
150
+ : BigInt(0);
151
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03, chain, r1Sizing.paddedDepositUsd);
152
+ const r1SizingHookId = {
153
+ A: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_01,
154
+ B: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_02,
155
+ C: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_03,
156
+ }[r1Sizing.category];
157
+ (0, context_2.fireProgressHook)(ctx, r1SizingHookId, chain, requiredGasFee, extraDepositPC, r1Sizing.paddedDepositUsd);
158
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_04, nativeAmount, r1Sizing.paddedDepositUsd, chain);
159
+ }
160
+ catch {
161
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_04, nativeAmount, BigInt(0), chain);
162
+ }
163
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_01, execute.funds.amount, execute.funds.token.decimals, symbol);
164
+ // Approve gateway to pull tokens if ERC-20.
165
+ //
166
+ // A PC20 wrapper is deliberately NOT approved. The gateway's configured
167
+ // PC20Factory burns it directly via `burnFrom(sourceAsset, caller, amount)`,
168
+ // so an allowance here would be granted and never used — a pointless
169
+ // approval tx and a standing allowance on the user's wrapper balance.
170
+ if (execute.funds.token.mechanism === 'approve') {
171
+ await (0, gas_calculator_1.ensureErc20Allowance)(ctx, evmClient, tokenAddr, gatewayAddress, execute.funds.amount);
172
+ }
173
+ else if (execute.funds.token.mechanism === 'permit2') {
174
+ throw new Error('Permit2 is not supported yet');
175
+ }
176
+ let txHash;
177
+ try {
178
+ (0, context_2.printLog)(ctx, (execute.to.toLowerCase() === ueaAddress.toLowerCase() ? 'FUNDS ONLY SELF' : 'FUNDS ONLY OTHER') +
179
+ ' — gateway call payload: ' + JSON.stringify({
180
+ gatewayAddress, functionName: 'sendUniversalTx', req,
181
+ value: (isNative ? nativeAmount + bridgeAmount : nativeAmount).toString(),
182
+ isNative, bridgeAmount: bridgeAmount.toString(), nativeAmount: nativeAmount.toString(),
100
183
  }, (_, v) => typeof v === 'bigint' ? v.toString() : v, 2));
101
- const ueaBalanceForGas = yield ctx.pushClient.getBalance(ueaAddress);
102
- const gasEstimate = execute.gasLimit || BigInt(1e7);
103
- const gasPrice = yield ctx.pushClient.getGasPrice();
104
- const requiredGasFee = gasEstimate * gasPrice;
105
- const requiredFunds = requiredGasFee + ((_c = execute.value) !== null && _c !== void 0 ? _c : BigInt(0));
106
- let nativeAmount = yield (0, gas_calculator_1.calculateNativeAmountForDeposit)(ctx, chain, requiredFunds, ueaBalanceForGas,
107
- // Defer the 103-03-04 ("Prepaid Deposit Estimated") hook — we emit the full
108
- // 103-03 sizing sequence below, after 103-01/103-02 (UEA resolution), to
109
- // match the funds-payload path ordering.
110
- { emitDepositEstimated: false });
111
- // For EVM fee-locking, fixed-rate PC→USD sizing can underfund when the
112
- // live WPC/native pool prices PC above the SDK's fallback price. Size the
113
- // native deposit against the same Push Chain pool used by the gateway.
114
- if (chain_1.CHAIN_INFO[chain].vm === enums_1.VM.EVM && requiredFunds > ueaBalanceForGas) {
115
- const deficit = requiredFunds - ueaBalanceForGas;
116
- const targetWpc = (deficit * BigInt(12)) / BigInt(10);
117
- const originPrc20 = (0, helpers_1.getNativePRC20ForChain)(chain, ctx.pushNetwork);
118
- const poolNativeAmount = yield (0, gas_calculator_1.estimateNativeForDesiredDeposit)(ctx, targetWpc, originPrc20);
119
- if (poolNativeAmount > nativeAmount) {
120
- (0, context_2.printLog)(ctx, `sendFunds — pool-based deposit sizing overrides fixed-rate estimate: fixedNative=${nativeAmount.toString()}, ` +
121
- `poolNative=${poolNativeAmount.toString()}, requiredFunds=${requiredFunds.toString()}, ` +
122
- `ueaBalance=${ueaBalanceForGas.toString()}`);
123
- nativeAmount = poolNativeAmount;
124
- }
125
- }
126
- (0, context_2.printLog)(ctx, `sendFunds — nativeAmount: ${nativeAmount.toString()}, ueaBalanceForGas: ${ueaBalanceForGas.toString()}, ` +
127
- `requiredFunds: ${requiredFunds.toString()}`);
128
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_01);
129
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_02, ueaAddress, deployed);
130
- (0, context_2.printLog)(ctx, `UEA resolved: ${ueaAddress}, deployed: ${deployed}`);
131
- // SDK 5.2 R1 deposit-sizing progress (parent + Case A/B/C + terminal),
132
- // emitted here — after UEA resolution — to match the funds-payload path's
133
- // ordering. The terminal 103-03-04 hook was suppressed inside
134
- // calculateNativeAmountForDeposit above so it lands in this position instead
135
- // of before 103-01/103-02. Purely cosmetic: a pool/price read failure here
136
- // must never block the bridge, so we fall back to the terminal hook alone.
137
- try {
138
- const r1Sizing = yield (0, gas_usd_sizer_1.sizeR1PushGas)(ctx, {
139
- pushGasFeeWei: requiredGasFee,
140
- originChain: chain,
141
- });
142
- const nativeTokenUsdPrice = yield new price_fetch_1.PriceFetch(ctx.rpcUrls).getPrice(chain);
143
- const nativeDecimals = chain_1.CHAIN_INFO[chain].vm === enums_1.VM.SVM ? 9 : 18;
144
- const oneNativeUnit = utils_1.Utils.helpers.parseUnits('1', nativeDecimals);
145
- const plannedPCDeposit = nativeTokenUsdPrice === BigInt(0)
146
- ? BigInt(0)
147
- : (r1Sizing.paddedDepositUsd * oneNativeUnit +
148
- (nativeTokenUsdPrice - BigInt(1))) /
149
- nativeTokenUsdPrice +
150
- BigInt(1);
151
- const extraDepositPC = plannedPCDeposit > requiredGasFee
152
- ? plannedPCDeposit - requiredGasFee
153
- : BigInt(0);
154
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03, chain, r1Sizing.paddedDepositUsd);
155
- const r1SizingHookId = {
156
- A: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_01,
157
- B: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_02,
158
- C: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_03,
159
- }[r1Sizing.category];
160
- (0, context_2.fireProgressHook)(ctx, r1SizingHookId, chain, requiredGasFee, extraDepositPC, r1Sizing.paddedDepositUsd);
161
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_04, nativeAmount, r1Sizing.paddedDepositUsd, chain);
162
- }
163
- catch (_d) {
164
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_04, nativeAmount, BigInt(0), chain);
165
- }
166
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_01, execute.funds.amount, execute.funds.token.decimals, symbol);
167
- // Approve gateway to pull tokens if ERC-20
168
- if (execute.funds.token.mechanism === 'approve') {
169
- yield (0, gas_calculator_1.ensureErc20Allowance)(ctx, evmClient, tokenAddr, gatewayAddress, execute.funds.amount);
170
- }
171
- else if (execute.funds.token.mechanism === 'permit2') {
172
- throw new Error('Permit2 is not supported yet');
173
- }
174
- let txHash;
175
- try {
176
- (0, context_2.printLog)(ctx, (execute.to.toLowerCase() === ueaAddress.toLowerCase() ? 'FUNDS ONLY SELF' : 'FUNDS ONLY OTHER') +
177
- ' — gateway call payload: ' + JSON.stringify({
178
- gatewayAddress, functionName: 'sendUniversalTx', req,
179
- value: (isNative ? nativeAmount + bridgeAmount : nativeAmount).toString(),
180
- isNative, bridgeAmount: bridgeAmount.toString(), nativeAmount: nativeAmount.toString(),
181
- }, (_, v) => typeof v === 'bigint' ? v.toString() : v, 2));
182
- txHash = yield (0, gateway_client_1.sendGatewayTxWithFallback)(ctx, evmClient, gatewayAddress, req, ctx.universalSigner, isNative ? nativeAmount + bridgeAmount : nativeAmount);
183
- }
184
- catch (err) {
184
+ txHash = await (0, gateway_client_1.sendGatewayTxWithFallback)(ctx, evmClient, gatewayAddress, req, ctx.universalSigner, isNative ? nativeAmount + bridgeAmount : nativeAmount);
185
+ }
186
+ catch (err) {
187
+ const errMsg = (0, formatters_1.normalizePublicErrorMessage)(err);
188
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_04, errMsg);
189
+ ctx._routeTerminalEmitted = true;
190
+ throw new Error(errMsg);
191
+ }
192
+ const originTx = await (0, helpers_2.fetchOriginChainTransactionForProgress)(ctx, chain, txHash, txHash);
193
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_02, txHash, bridgeAmount, execute.funds.token.decimals, symbol, originTx);
194
+ await (0, confirmation_1.waitForEvmConfirmationsWithCountdown)(ctx, evmClient, txHash, chain_1.CHAIN_INFO[chain].confirmations, chain_1.CHAIN_INFO[chain].timeout);
195
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_04, txHash);
196
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_05);
197
+ (0, context_2.printLog)(ctx, 'sendFunds — querying Push Chain status: ' + JSON.stringify({
198
+ txHash, evmGatewayMethod: execute.to === ueaAddress ? 'sendFunds' : 'sendTxWithFunds',
199
+ }));
200
+ let response;
201
+ try {
202
+ const pushChainUniversalTx = await (0, response_builder_1.queryUniversalTxStatusFromGatewayTx)(ctx, evmClient, gatewayAddress, txHash, execute.to === ueaAddress ? 'sendFunds' : 'sendTxWithFunds', execute._pc20?.direction === 'import');
203
+ // extractPcTxAndTransform fires 199-02 itself on pcTx FAILED; only emit
204
+ // for non-typed failures (RPC lookup error, timeout).
205
+ response = await (0, push_chain_tx_1.extractPcTxAndTransform)(ctx, pushChainUniversalTx, txHash, eventBuffer, 'sendFunds', transformFn);
206
+ }
207
+ catch (err) {
208
+ if (!(err instanceof push_chain_tx_1.PushChainExecutionError)) {
185
209
  const errMsg = (0, formatters_1.normalizePublicErrorMessage)(err);
186
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_04, errMsg);
187
- ctx._routeTerminalEmitted = true;
188
- throw new Error(errMsg);
189
- }
190
- const originTx = yield (0, helpers_2.fetchOriginChainTransactionForProgress)(ctx, chain, txHash, txHash);
191
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_02, txHash, bridgeAmount, execute.funds.token.decimals, symbol, originTx);
192
- yield (0, confirmation_1.waitForEvmConfirmationsWithCountdown)(ctx, evmClient, txHash, chain_1.CHAIN_INFO[chain].confirmations, chain_1.CHAIN_INFO[chain].timeout);
193
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_04, txHash);
194
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_05);
195
- (0, context_2.printLog)(ctx, 'sendFunds — querying Push Chain status: ' + JSON.stringify({
196
- txHash, evmGatewayMethod: execute.to === ueaAddress ? 'sendFunds' : 'sendTxWithFunds',
197
- }));
198
- let response;
199
- try {
200
- const pushChainUniversalTx = yield (0, response_builder_1.queryUniversalTxStatusFromGatewayTx)(ctx, evmClient, gatewayAddress, txHash, execute.to === ueaAddress ? 'sendFunds' : 'sendTxWithFunds');
201
- // extractPcTxAndTransform fires 199-02 itself on pcTx FAILED; only emit
202
- // for non-typed failures (RPC lookup error, timeout).
203
- response = yield (0, push_chain_tx_1.extractPcTxAndTransform)(ctx, pushChainUniversalTx, txHash, eventBuffer, 'sendFunds', transformFn);
204
- }
205
- catch (err) {
206
- if (!(err instanceof push_chain_tx_1.PushChainExecutionError)) {
207
- const errMsg = (0, formatters_1.normalizePublicErrorMessage)(err);
208
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_02, errMsg);
209
- throw new push_chain_tx_1.PushChainExecutionError(errMsg, { gatewayTxHash: txHash });
210
- }
211
- throw err;
210
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_02, errMsg);
211
+ throw new push_chain_tx_1.PushChainExecutionError(errMsg, { gatewayTxHash: txHash });
212
212
  }
213
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_06, bridgeAmount, execute.funds.token.decimals, symbol);
214
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_107);
215
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_01, [response]);
216
- return response;
217
- });
213
+ throw err;
214
+ }
215
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_06, bridgeAmount, execute.funds.token.decimals, symbol);
216
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_107);
217
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_01, [response]);
218
+ return response;
218
219
  }
219
220
  // ============================================================================
220
221
  // SVM funds-only path
221
222
  // ============================================================================
222
- function executeFundsOnlySvm(ctx, execute, eventBuffer, transformFn, chain, rpcUrls, bridgeAmount, symbol) {
223
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
224
- const svmClient = new svm_client_1.SvmClient({ rpcUrls });
225
- const programId = new web3_js_1.PublicKey(universalGatewayV0_json_1.default.address);
226
- const [configPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('config')], programId);
227
- const [vaultPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('vault')], programId);
228
- const { feeVaultPda, protocolFeeLamports } = yield (0, svm_helpers_1.getSvmProtocolFee)(svmClient, programId);
229
- const [rateLimitConfigPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('rate_limit_config')], programId);
230
- const userPk = new web3_js_1.PublicKey(ctx.universalSigner.account.address);
231
- const priceUpdatePk = new web3_js_1.PublicKey(chain_1.SVM_PYTH_PRICE_FEED);
232
- if (execute.payGasWith !== undefined) {
233
- throw new Error('Pay-with token is not supported on Solana');
234
- }
235
- const recipientEvm20 = Array.from(Buffer.from(execute.to.slice(2).padStart(40, '0'), 'hex').subarray(0, 20));
236
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_01);
237
- const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
238
- const { nonce, deployed } = yield (0, uea_manager_1.getUeaStatusAndNonce)(ctx);
239
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_02, ueaAddress, deployed);
240
- let txSignature;
241
- if (execute.funds.token.mechanism === 'native') {
242
- const [tokenRateLimitPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('rate_limit'), web3_js_1.PublicKey.default.toBuffer()], programId);
243
- const reqNative = (0, svm_helpers_1.buildSvmUniversalTxRequest)({
244
- recipient: recipientEvm20, token: web3_js_1.PublicKey.default, amount: bridgeAmount,
245
- payload: '0x', revertRecipient: userPk, signatureData: '0x',
246
- });
247
- txSignature = yield svmClient.writeContract({
248
- abi: universalGatewayV0_json_1.default, address: programId.toBase58(), functionName: 'sendUniversalTx',
249
- args: [reqNative, bridgeAmount + protocolFeeLamports], signer: ctx.universalSigner,
250
- accounts: {
251
- config: configPda, vault: vaultPda, feeVault: feeVaultPda,
252
- userTokenAccount: vaultPda, gatewayTokenAccount: vaultPda, user: userPk,
253
- priceUpdate: priceUpdatePk, rateLimitConfig: rateLimitConfigPda,
254
- tokenRateLimit: tokenRateLimitPda,
255
- tokenProgram: new web3_js_1.PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'),
256
- systemProgram: web3_js_1.SystemProgram.programId,
257
- },
258
- });
259
- }
260
- else if (execute.funds.token.mechanism === 'approve') {
261
- const mintPk = new web3_js_1.PublicKey(execute.funds.token.address);
262
- const TOKEN_PROGRAM_ID = new web3_js_1.PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
263
- const ASSOCIATED_TOKEN_PROGRAM_ID = new web3_js_1.PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
264
- const userAta = web3_js_1.PublicKey.findProgramAddressSync([userPk.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mintPk.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID)[0];
265
- const vaultAta = web3_js_1.PublicKey.findProgramAddressSync([vaultPda.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mintPk.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID)[0];
266
- const [tokenRateLimitPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('rate_limit'), mintPk.toBuffer()], programId);
267
- const reqSpl = (0, svm_helpers_1.buildSvmUniversalTxRequest)({
268
- recipient: recipientEvm20, token: mintPk, amount: bridgeAmount,
269
- payload: '0x', revertRecipient: userPk, signatureData: '0x',
270
- });
271
- txSignature = yield svmClient.writeContract({
272
- abi: universalGatewayV0_json_1.default, address: programId.toBase58(), functionName: 'sendUniversalTx',
273
- args: [reqSpl, protocolFeeLamports], signer: ctx.universalSigner,
274
- accounts: {
275
- config: configPda, vault: vaultPda, feeVault: feeVaultPda,
276
- userTokenAccount: userAta, gatewayTokenAccount: vaultAta, user: userPk,
277
- tokenProgram: TOKEN_PROGRAM_ID, priceUpdate: priceUpdatePk,
278
- rateLimitConfig: rateLimitConfigPda, tokenRateLimit: tokenRateLimitPda,
279
- systemProgram: web3_js_1.SystemProgram.programId,
280
- },
281
- });
282
- }
283
- else {
284
- throw new Error('Unsupported token mechanism on Solana');
285
- }
286
- const originTx = yield (0, helpers_2.fetchOriginChainTransactionForProgress)(ctx, chain, '0x', txSignature);
287
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_02, txSignature, bridgeAmount, execute.funds.token.decimals, symbol, originTx);
288
- yield (0, confirmation_1.waitForSvmConfirmationsWithCountdown)(ctx, svmClient, txSignature, chain_1.CHAIN_INFO[chain].confirmations, chain_1.CHAIN_INFO[chain].timeout);
289
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_04, txSignature);
290
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_05);
291
- let response;
292
- try {
293
- const pushChainUniversalTx = yield (0, response_builder_1.queryUniversalTxStatusFromGatewayTx)(ctx, undefined, undefined, txSignature, 'sendFunds');
294
- response = yield (0, push_chain_tx_1.extractPcTxAndTransform)(ctx, pushChainUniversalTx, txSignature, eventBuffer, 'sendFunds (SVM)', transformFn);
295
- }
296
- catch (err) {
297
- if (!(err instanceof push_chain_tx_1.PushChainExecutionError)) {
298
- const errMsg = (0, formatters_1.normalizePublicErrorMessage)(err);
299
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_02, errMsg);
300
- throw new push_chain_tx_1.PushChainExecutionError(errMsg, { gatewayTxHash: txSignature });
301
- }
302
- throw err;
223
+ async function executeFundsOnlySvm(ctx, execute, eventBuffer, transformFn, chain, rpcUrls, bridgeAmount, symbol) {
224
+ const svmClient = new svm_client_1.SvmClient({ rpcUrls });
225
+ const programId = new web3_js_1.PublicKey(universalGatewayV0_json_1.default.address);
226
+ const [configPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('config')], programId);
227
+ const [vaultPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('vault')], programId);
228
+ const { feeVaultPda, protocolFeeLamports } = await (0, svm_helpers_1.getSvmProtocolFee)(svmClient, programId);
229
+ const [rateLimitConfigPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('rate_limit_config')], programId);
230
+ const userPk = new web3_js_1.PublicKey(ctx.universalSigner.account.address);
231
+ const priceUpdatePk = new web3_js_1.PublicKey(chain_1.SVM_PYTH_PRICE_FEED);
232
+ if (execute.payGasWith !== undefined) {
233
+ throw new Error('Pay-with token is not supported on Solana');
234
+ }
235
+ const recipientEvm20 = Array.from(Buffer.from(execute.to.slice(2).padStart(40, '0'), 'hex').subarray(0, 20));
236
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_01);
237
+ const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
238
+ const { nonce, deployed } = await (0, uea_manager_1.getUeaStatusAndNonce)(ctx);
239
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_02, ueaAddress, deployed);
240
+ let txSignature;
241
+ if (execute.funds.token.mechanism === 'native') {
242
+ const [tokenRateLimitPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('rate_limit'), web3_js_1.PublicKey.default.toBuffer()], programId);
243
+ const reqNative = (0, svm_helpers_1.buildSvmUniversalTxRequest)({
244
+ recipient: recipientEvm20, token: web3_js_1.PublicKey.default, amount: bridgeAmount,
245
+ payload: '0x', revertRecipient: userPk, signatureData: '0x',
246
+ });
247
+ txSignature = await svmClient.writeContract({
248
+ abi: universalGatewayV0_json_1.default, address: programId.toBase58(), functionName: 'sendUniversalTx',
249
+ args: [reqNative, bridgeAmount + protocolFeeLamports], signer: ctx.universalSigner,
250
+ accounts: {
251
+ config: configPda, vault: vaultPda, feeVault: feeVaultPda,
252
+ userTokenAccount: vaultPda, gatewayTokenAccount: vaultPda, user: userPk,
253
+ priceUpdate: priceUpdatePk, rateLimitConfig: rateLimitConfigPda,
254
+ tokenRateLimit: tokenRateLimitPda,
255
+ tokenProgram: new web3_js_1.PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'),
256
+ systemProgram: web3_js_1.SystemProgram.programId,
257
+ },
258
+ });
259
+ }
260
+ else if (execute.funds.token.mechanism === 'approve') {
261
+ const mintPk = new web3_js_1.PublicKey(execute.funds.token.address);
262
+ const TOKEN_PROGRAM_ID = new web3_js_1.PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
263
+ const ASSOCIATED_TOKEN_PROGRAM_ID = new web3_js_1.PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
264
+ const userAta = web3_js_1.PublicKey.findProgramAddressSync([userPk.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mintPk.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID)[0];
265
+ const vaultAta = web3_js_1.PublicKey.findProgramAddressSync([vaultPda.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mintPk.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID)[0];
266
+ const [tokenRateLimitPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('rate_limit'), mintPk.toBuffer()], programId);
267
+ const reqSpl = (0, svm_helpers_1.buildSvmUniversalTxRequest)({
268
+ recipient: recipientEvm20, token: mintPk, amount: bridgeAmount,
269
+ payload: '0x', revertRecipient: userPk, signatureData: '0x',
270
+ });
271
+ txSignature = await svmClient.writeContract({
272
+ abi: universalGatewayV0_json_1.default, address: programId.toBase58(), functionName: 'sendUniversalTx',
273
+ args: [reqSpl, protocolFeeLamports], signer: ctx.universalSigner,
274
+ accounts: {
275
+ config: configPda, vault: vaultPda, feeVault: feeVaultPda,
276
+ userTokenAccount: userAta, gatewayTokenAccount: vaultAta, user: userPk,
277
+ tokenProgram: TOKEN_PROGRAM_ID, priceUpdate: priceUpdatePk,
278
+ rateLimitConfig: rateLimitConfigPda, tokenRateLimit: tokenRateLimitPda,
279
+ systemProgram: web3_js_1.SystemProgram.programId,
280
+ },
281
+ });
282
+ }
283
+ else if (execute.funds.token.mechanism === 'pc20-burn') {
284
+ // NOTE: currently unreachable from sendTransaction — the orchestrator
285
+ // routes SVM PC20 imports through the funds+payload path (svm-bridge),
286
+ // because a pure burn's empty payload gets the PC20 selector prepended by
287
+ // the gateway and classified FUNDS_AND_PAYLOAD, which the chain's inbound
288
+ // decode bricks on with no revert (the selector-only "0x" guard bug).
289
+ // Kept correct as the pure-burn shape for when that chain fix ships.
290
+ //
291
+ // PC20 wrapper burn — route_pc20_universal_tx (deposit.rs). Differs from
292
+ // the SPL escrow route in four program-enforced ways: the recipient must
293
+ // be the nonzero Push recipient (the chain unlocks directly to it), the
294
+ // gateway token account must be ABSENT (burn, not escrow),
295
+ // remaining_accounts must be exactly [pc20_state ro, pc20_mint w], and
296
+ // token_rate_limit is null — a pure burn consumes no per-token rate limit,
297
+ // and this call sends exactly the inbound fee, so there is no post-fee
298
+ // native excess to route as a (rate-limited) FUNDS leg. The gateway
299
+ // prepends the PC20 selector itself — the SDK must not.
300
+ const mintPk = new web3_js_1.PublicKey(execute.funds.token.address);
301
+ const TOKEN_PROGRAM_ID = new web3_js_1.PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
302
+ const ASSOCIATED_TOKEN_PROGRAM_ID = new web3_js_1.PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
303
+ const userAta = web3_js_1.PublicKey.findProgramAddressSync([userPk.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mintPk.toBuffer()], ASSOCIATED_TOKEN_PROGRAM_ID)[0];
304
+ const { remainingAccounts } = (0, svm_1.buildPC20BurnAccounts)({ programId, mint: mintPk });
305
+ const reqBurn = (0, svm_helpers_1.buildSvmUniversalTxRequest)({
306
+ recipient: recipientEvm20, token: mintPk, amount: bridgeAmount,
307
+ payload: '0x', revertRecipient: userPk, signatureData: '0x',
308
+ });
309
+ txSignature = await svmClient.writeContract({
310
+ abi: universalGatewayV0_json_1.default, address: programId.toBase58(), functionName: 'sendUniversalTx',
311
+ args: [reqBurn, protocolFeeLamports], signer: ctx.universalSigner,
312
+ accounts: {
313
+ config: configPda, vault: vaultPda, feeVault: feeVaultPda,
314
+ userTokenAccount: userAta, gatewayTokenAccount: null, user: userPk,
315
+ tokenProgram: TOKEN_PROGRAM_ID, priceUpdate: priceUpdatePk,
316
+ rateLimitConfig: rateLimitConfigPda, tokenRateLimit: null,
317
+ systemProgram: web3_js_1.SystemProgram.programId,
318
+ },
319
+ remainingAccounts,
320
+ });
321
+ }
322
+ else {
323
+ throw new Error('Unsupported token mechanism on Solana');
324
+ }
325
+ const originTx = await (0, helpers_2.fetchOriginChainTransactionForProgress)(ctx, chain, '0x', txSignature);
326
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_02, txSignature, bridgeAmount, execute.funds.token.decimals, symbol, originTx);
327
+ await (0, confirmation_1.waitForSvmConfirmationsWithCountdown)(ctx, svmClient, txSignature, chain_1.CHAIN_INFO[chain].confirmations, chain_1.CHAIN_INFO[chain].timeout);
328
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_04, txSignature);
329
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_05);
330
+ let response;
331
+ try {
332
+ const pushChainUniversalTx = await (0, response_builder_1.queryUniversalTxStatusFromGatewayTx)(ctx, undefined, undefined, txSignature, 'sendFunds', execute._pc20?.direction === 'import');
333
+ response = await (0, push_chain_tx_1.extractPcTxAndTransform)(ctx, pushChainUniversalTx, txSignature, eventBuffer, 'sendFunds (SVM)', transformFn);
334
+ }
335
+ catch (err) {
336
+ if (!(err instanceof push_chain_tx_1.PushChainExecutionError)) {
337
+ const errMsg = (0, formatters_1.normalizePublicErrorMessage)(err);
338
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_02, errMsg);
339
+ throw new push_chain_tx_1.PushChainExecutionError(errMsg, { gatewayTxHash: txSignature });
303
340
  }
304
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_06, bridgeAmount, execute.funds.token.decimals, symbol);
305
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_107);
306
- (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_01, [response]);
307
- return response;
308
- });
341
+ throw err;
342
+ }
343
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_06, bridgeAmount, execute.funds.token.decimals, symbol);
344
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_107);
345
+ (0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_01, [response]);
346
+ return response;
309
347
  }
310
348
  //# sourceMappingURL=execute-funds-only.js.map
@@ -5,7 +5,7 @@
5
5
  * for both EVM and SVM origin chains.
6
6
  */
7
7
  import { ProgressEvent } from '../../progress-hook/progress-hook.types';
8
- import type { ExecuteParams, UniversalTxResponse } from '../orchestrator.types';
8
+ import type { LegacyExecuteParams, UniversalTxResponse } from '../orchestrator.types';
9
9
  import type { OrchestratorContext } from './context';
10
10
  import { type ResponseBuilderCallbacks } from './response-builder';
11
- export declare function executeFundsWithPayload(ctx: OrchestratorContext, execute: ExecuteParams, eventBuffer: ProgressEvent[], getResponseCallbacks: () => ResponseBuilderCallbacks): Promise<UniversalTxResponse>;
11
+ export declare function executeFundsWithPayload(ctx: OrchestratorContext, execute: LegacyExecuteParams, eventBuffer: ProgressEvent[], getResponseCallbacks: () => ResponseBuilderCallbacks): Promise<UniversalTxResponse>;