@pushchain/core 6.0.20 → 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.
- package/CHANGELOG.md +48 -0
- package/package.json +1 -1
- package/src/lib/cache/cache.js +2 -0
- package/src/lib/constants/abi/index.d.ts +1 -0
- package/src/lib/constants/abi/index.js +8 -1
- package/src/lib/constants/abi/pc20.evm.d.ts +217 -0
- package/src/lib/constants/abi/pc20.evm.js +150 -0
- package/src/lib/constants/abi/prc20.evm.d.ts +172 -0
- package/src/lib/constants/abi/prc20.evm.js +97 -0
- package/src/lib/constants/abi/universalGatewayV0.json +1 -1
- package/src/lib/constants/chain.js +38 -8
- package/src/lib/constants/selectors.js +2 -2
- package/src/lib/constants/tokens.js +4 -3
- package/src/lib/formatters.js +16 -6
- package/src/lib/generated/uexecutor/v1/query.js +2 -4
- package/src/lib/generated/uexecutor/v1/types.d.ts +14 -0
- package/src/lib/generated/uexecutor/v1/types.js +90 -47
- package/src/lib/generated/uexecutor/v2/query.js +2 -4
- package/src/lib/generated/uexecutor/v2/types.d.ts +20 -0
- package/src/lib/generated/uexecutor/v2/types.js +49 -33
- package/src/lib/generated/v1/tx.js +30 -37
- package/src/lib/index.d.ts +3 -0
- package/src/lib/index.js +21 -3
- package/src/lib/internal/buffer.js +1 -2
- package/src/lib/orchestrator/cea-utils.js +73 -83
- package/src/lib/orchestrator/internals/account-manager.js +130 -139
- package/src/lib/orchestrator/internals/cascade.d.ts +0 -6
- package/src/lib/orchestrator/internals/cascade.js +1184 -1059
- package/src/lib/orchestrator/internals/confirmation.js +138 -148
- package/src/lib/orchestrator/internals/error-decoder.js +1 -1
- package/src/lib/orchestrator/internals/errors.js +12 -3
- package/src/lib/orchestrator/internals/execute-funds-only.d.ts +2 -2
- package/src/lib/orchestrator/internals/execute-funds-only.js +297 -259
- package/src/lib/orchestrator/internals/execute-funds-payload.d.ts +2 -2
- package/src/lib/orchestrator/internals/execute-funds-payload.js +220 -220
- package/src/lib/orchestrator/internals/execute-standard.d.ts +0 -8
- package/src/lib/orchestrator/internals/execute-standard.js +339 -342
- package/src/lib/orchestrator/internals/gas-calculator.js +497 -520
- package/src/lib/orchestrator/internals/gas-usd-sizer.js +101 -110
- package/src/lib/orchestrator/internals/gateway-client.js +102 -103
- package/src/lib/orchestrator/internals/helpers.js +30 -27
- package/src/lib/orchestrator/internals/inbound-tracker.js +234 -238
- package/src/lib/orchestrator/internals/outbound-sync.js +463 -452
- package/src/lib/orchestrator/internals/outbound-tracker.js +27 -34
- package/src/lib/orchestrator/internals/payload-builder.d.ts +2 -2
- package/src/lib/orchestrator/internals/payload-builder.js +119 -100
- package/src/lib/orchestrator/internals/pc-usd-oracle.js +121 -129
- package/src/lib/orchestrator/internals/pc20/address-codec.d.ts +31 -0
- package/src/lib/orchestrator/internals/pc20/address-codec.js +124 -0
- package/src/lib/orchestrator/internals/pc20/chain-namespace.d.ts +68 -0
- package/src/lib/orchestrator/internals/pc20/chain-namespace.js +136 -0
- package/src/lib/orchestrator/internals/pc20/errors.d.ts +160 -0
- package/src/lib/orchestrator/internals/pc20/errors.js +236 -0
- package/src/lib/orchestrator/internals/pc20/export.d.ts +172 -0
- package/src/lib/orchestrator/internals/pc20/export.js +412 -0
- package/src/lib/orchestrator/internals/pc20/gate.d.ts +67 -0
- package/src/lib/orchestrator/internals/pc20/gate.js +184 -0
- package/src/lib/orchestrator/internals/pc20/resolver.d.ts +187 -0
- package/src/lib/orchestrator/internals/pc20/resolver.js +658 -0
- package/src/lib/orchestrator/internals/pc20/svm.d.ts +189 -0
- package/src/lib/orchestrator/internals/pc20/svm.js +286 -0
- package/src/lib/orchestrator/internals/pc20/tracking.d.ts +46 -0
- package/src/lib/orchestrator/internals/pc20/tracking.js +109 -0
- package/src/lib/orchestrator/internals/preflight.js +1 -1
- package/src/lib/orchestrator/internals/progress-route-hooks.js +2 -2
- package/src/lib/orchestrator/internals/push-chain-tx.js +319 -329
- package/src/lib/orchestrator/internals/quote.js +90 -94
- package/src/lib/orchestrator/internals/rescue.js +76 -79
- package/src/lib/orchestrator/internals/response-builder.d.ts +28 -1
- package/src/lib/orchestrator/internals/response-builder.js +817 -701
- package/src/lib/orchestrator/internals/route-handlers.d.ts +7 -15
- package/src/lib/orchestrator/internals/route-handlers.js +1512 -1178
- package/src/lib/orchestrator/internals/signing.js +78 -83
- package/src/lib/orchestrator/internals/svm-bridge.d.ts +2 -2
- package/src/lib/orchestrator/internals/svm-bridge.js +161 -93
- package/src/lib/orchestrator/internals/svm-helpers.d.ts +15 -1
- package/src/lib/orchestrator/internals/svm-helpers.js +68 -24
- package/src/lib/orchestrator/internals/svm-rent.d.ts +19 -1
- package/src/lib/orchestrator/internals/svm-rent.js +163 -141
- package/src/lib/orchestrator/internals/tx-transformer.js +26 -23
- package/src/lib/orchestrator/internals/uea-manager.js +89 -86
- package/src/lib/orchestrator/max-pc-for-gas.js +5 -6
- package/src/lib/orchestrator/orchestrator.js +217 -200
- package/src/lib/orchestrator/orchestrator.types.d.ts +121 -1
- package/src/lib/orchestrator/orchestrator.types.js +19 -0
- package/src/lib/orchestrator/payload-builders.d.ts +2 -2
- package/src/lib/orchestrator/payload-builders.js +26 -24
- package/src/lib/orchestrator/route-detector.js +26 -9
- package/src/lib/orchestrator/svm-idl/ix-encoder.js +1 -2
- package/src/lib/orchestrator/svm-idl/normalize-address.js +2 -2
- package/src/lib/orchestrator/svm-idl/resolve.js +1 -2
- package/src/lib/price-fetch/price-fetch.js +67 -68
- package/src/lib/progress-hook/progress-hook.js +124 -72
- package/src/lib/push-chain/push-chain.js +171 -153
- package/src/lib/push-client/push-client.js +223 -237
- package/src/lib/universal/account/account.js +349 -365
- package/src/lib/universal/signer/signer.js +306 -294
- package/src/lib/universal-tx-detector/auto-detect.js +55 -60
- package/src/lib/universal-tx-detector/cascade.js +160 -172
- package/src/lib/universal-tx-detector/child-inbounds.js +67 -75
- package/src/lib/universal-tx-detector/classify.js +2 -3
- package/src/lib/universal-tx-detector/detector-svm.js +139 -147
- package/src/lib/universal-tx-detector/detector.js +145 -157
- package/src/lib/universal-tx-detector/normalize.js +7 -7
- package/src/lib/utils/external-tx-hash.js +1 -2
- package/src/lib/utils.d.ts +44 -0
- package/src/lib/utils.js +762 -683
- package/src/lib/vm-client/evm-client.js +186 -202
- package/src/lib/vm-client/svm-client.d.ts +1 -1
- package/src/lib/vm-client/svm-client.js +220 -224
- package/src/lib/vm-client/vm-client.types.d.ts +14 -2
|
@@ -34,245 +34,245 @@ const signing_1 = require("./signing");
|
|
|
34
34
|
const quote_1 = require("./quote");
|
|
35
35
|
const formatters_1 = require("../../formatters");
|
|
36
36
|
const helpers_1 = require("./helpers");
|
|
37
|
-
function executeFundsWithPayload(ctx, execute, eventBuffer, getResponseCallbacks) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
37
|
+
async function executeFundsWithPayload(ctx, execute, eventBuffer, getResponseCallbacks) {
|
|
38
|
+
const transformFn = (tx, buf = []) => (0, response_builder_1.transformToUniversalTxResponse)(ctx, tx, buf, getResponseCallbacks());
|
|
39
|
+
const { chain, evmClient, gatewayAddress } = (0, gateway_client_1.getOriginGatewayContext)(ctx);
|
|
40
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_101, chain, ctx.universalSigner.account.address);
|
|
41
|
+
// Default token to native ETH if none provided
|
|
42
|
+
if (!execute.funds.token) {
|
|
43
|
+
const available = tokens_1.MOVEABLE_TOKENS[chain] || [];
|
|
44
|
+
const vm = chain_1.CHAIN_INFO[chain].vm;
|
|
45
|
+
const preferredSymbol = vm === enums_1.VM.EVM ? 'ETH' : vm === enums_1.VM.SVM ? 'SOL' : undefined;
|
|
46
|
+
const nativeToken = preferredSymbol
|
|
47
|
+
? available.find((t) => t.symbol === preferredSymbol)
|
|
48
|
+
: undefined;
|
|
49
|
+
if (!nativeToken) {
|
|
50
|
+
throw new Error('Native token not configured for this chain');
|
|
51
|
+
}
|
|
52
|
+
execute.funds.token = nativeToken;
|
|
53
|
+
}
|
|
54
|
+
const mechanism = execute.funds.token.mechanism;
|
|
55
|
+
let nonce;
|
|
56
|
+
let deployed;
|
|
57
|
+
const deployedHint = ctx.accountStatusCache?.uea?.deployed;
|
|
58
|
+
if (deployedHint) {
|
|
59
|
+
deployed = true;
|
|
60
|
+
nonce = await (0, uea_manager_1.getUEANonce)(ctx, (0, uea_manager_1.computeUEAOffchain)(ctx));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
const status = await (0, uea_manager_1.getUeaStatusAndNonce)(ctx);
|
|
64
|
+
nonce = status.nonce;
|
|
65
|
+
deployed = status.deployed;
|
|
66
|
+
}
|
|
67
|
+
const { payload: universalPayload, req } = await (0, payload_builder_1.buildGatewayPayloadAndGas)(ctx, execute, nonce, 'sendTxWithFunds', execute.funds.amount);
|
|
68
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_102_01);
|
|
69
|
+
// Compute required gas funding on Push Chain and current UEA balance
|
|
70
|
+
const gasEstimate = execute.gasLimit || BigInt(1e7);
|
|
71
|
+
const gasPrice = await ctx.pushClient.getGasPrice();
|
|
72
|
+
const requiredGasFee = gasEstimate * gasPrice;
|
|
73
|
+
const payloadValue = execute.value ?? BigInt(0);
|
|
74
|
+
const requiredFunds = requiredGasFee + payloadValue;
|
|
75
|
+
const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
|
|
76
|
+
const ueaBalance = await ctx.pushClient.getBalance(ueaAddress);
|
|
77
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_01);
|
|
78
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_02, ueaAddress, deployed);
|
|
79
|
+
// SDK 5.2 Case A/B/C sizing on the Push-chain gas portion.
|
|
80
|
+
// Floor pad comes from the sizer ($1 for Case A); upper bound now lives in
|
|
81
|
+
// the origin gateway (MAX_CAP_UNIVERSAL_TX_USD) — the SDK no longer caps.
|
|
82
|
+
const r1Sizing = await (0, gas_usd_sizer_1.sizeR1PushGas)(ctx, {
|
|
83
|
+
pushGasFeeWei: requiredGasFee,
|
|
84
|
+
originChain: chain,
|
|
85
|
+
});
|
|
86
|
+
// Convert the sizer's USD result into planned PC native deposit so the
|
|
87
|
+
// sizer progress hook can surface the user-facing `extraDepositPC` =
|
|
88
|
+
// totalPCDeposit - gasRequired. The same conversion is reused below for
|
|
89
|
+
// the final nativeAmount calc (after SVM clamp).
|
|
90
|
+
const nativeTokenUsdPrice = await new price_fetch_1.PriceFetch(ctx.rpcUrls).getPrice(chain);
|
|
91
|
+
const nativeDecimals = chain_1.CHAIN_INFO[chain].vm === enums_1.VM.SVM ? 9 : 18;
|
|
92
|
+
const oneNativeUnit = utils_1.Utils.helpers.parseUnits('1', nativeDecimals);
|
|
93
|
+
const usdToNative = (usd) => {
|
|
94
|
+
if (nativeTokenUsdPrice === BigInt(0))
|
|
95
|
+
return BigInt(0);
|
|
96
|
+
const out = (usd * oneNativeUnit + (nativeTokenUsdPrice - BigInt(1))) / nativeTokenUsdPrice;
|
|
97
|
+
return out + BigInt(1);
|
|
98
|
+
};
|
|
99
|
+
const plannedPCDeposit = usdToNative(r1Sizing.paddedDepositUsd);
|
|
100
|
+
const extraDepositPC = plannedPCDeposit > requiredGasFee ? plannedPCDeposit - requiredGasFee : BigInt(0);
|
|
101
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03, chain, r1Sizing.paddedDepositUsd);
|
|
102
|
+
const r1SizingHookId = {
|
|
103
|
+
A: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_01,
|
|
104
|
+
B: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_02,
|
|
105
|
+
C: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_03,
|
|
106
|
+
}[r1Sizing.category];
|
|
107
|
+
(0, context_1.fireProgressHook)(ctx, r1SizingHookId, chain, requiredGasFee, extraDepositPC, r1Sizing.paddedDepositUsd);
|
|
108
|
+
const deficit = requiredFunds > ueaBalance ? requiredFunds - ueaBalance : BigInt(0);
|
|
109
|
+
let depositUsd = deficit > BigInt(0) ? ctx.pushClient.pushToUSDC(deficit) : BigInt(0);
|
|
110
|
+
// Apply sizer floor: Case A pads to $1, Cases B/C pass-through.
|
|
111
|
+
if (depositUsd < r1Sizing.paddedDepositUsd)
|
|
112
|
+
depositUsd = r1Sizing.paddedDepositUsd;
|
|
113
|
+
// Match funds-only and standard fee-lock sizing: fixed PC→USD conversion can
|
|
114
|
+
// underfund large PC deposits when the live pETH/WPC pool has meaningful
|
|
115
|
+
// slippage. Quote the native amount required for the target WPC output and
|
|
116
|
+
// raise the USD deposit before converting back to source-chain native value.
|
|
117
|
+
if (chain_1.CHAIN_INFO[chain].vm === enums_1.VM.EVM && requiredFunds > ueaBalance) {
|
|
118
|
+
const deficit = requiredFunds - ueaBalance;
|
|
119
|
+
const targetWpc = (deficit * BigInt(12)) / BigInt(10);
|
|
120
|
+
const originPrc20 = (0, helpers_1.getNativePRC20ForChain)(chain, ctx.pushNetwork);
|
|
121
|
+
const poolNativeAmount = await (0, gas_calculator_1.estimateNativeForDesiredDeposit)(ctx, targetWpc, originPrc20);
|
|
122
|
+
if (poolNativeAmount > BigInt(0)) {
|
|
123
|
+
const poolBasedUsd = (poolNativeAmount * nativeTokenUsdPrice) / oneNativeUnit;
|
|
124
|
+
if (poolBasedUsd > depositUsd) {
|
|
125
|
+
(0, context_1.printLog)(ctx, `sendFundsWithPayload — pool-based deposit sizing overrides fixed-rate estimate: ` +
|
|
126
|
+
`fixedUsd=${depositUsd.toString()}, poolBasedUsd=${poolBasedUsd.toString()}, ` +
|
|
127
|
+
`requiredFunds=${requiredFunds.toString()}, ueaBalance=${ueaBalance.toString()}`);
|
|
128
|
+
depositUsd = poolBasedUsd;
|
|
53
129
|
}
|
|
54
|
-
execute.funds.token = nativeToken;
|
|
55
130
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
131
|
+
}
|
|
132
|
+
// If SVM, clamp depositUsd to on-chain Config caps
|
|
133
|
+
if (chain_1.CHAIN_INFO[chain].vm === enums_1.VM.SVM) {
|
|
134
|
+
const svmClient = new svm_client_1.SvmClient({
|
|
135
|
+
rpcUrls: ctx.rpcUrls[enums_1.CHAIN.SOLANA_DEVNET] || chain_1.CHAIN_INFO[enums_1.CHAIN.SOLANA_DEVNET].defaultRPC,
|
|
136
|
+
});
|
|
137
|
+
const programId = new web3_js_1.PublicKey(universalGatewayV0_json_1.default.address);
|
|
138
|
+
const [configPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('config')], programId);
|
|
139
|
+
try {
|
|
140
|
+
const cfg = await svmClient.readContract({
|
|
141
|
+
abi: universalGatewayV0_json_1.default, address: universalGatewayV0_json_1.default.address,
|
|
142
|
+
functionName: 'config', args: [configPda.toBase58()],
|
|
143
|
+
});
|
|
144
|
+
const minCapUsd = BigInt((cfg.minCapUniversalTxUsd ?? cfg.min_cap_universal_tx_usd).toString());
|
|
145
|
+
const maxCapUsd = BigInt((cfg.maxCapUniversalTxUsd ?? cfg.max_cap_universal_tx_usd).toString());
|
|
146
|
+
if (depositUsd < minCapUsd)
|
|
147
|
+
depositUsd = minCapUsd;
|
|
148
|
+
const withMargin = (minCapUsd * BigInt(12)) / BigInt(10);
|
|
149
|
+
if (depositUsd < withMargin)
|
|
150
|
+
depositUsd = withMargin;
|
|
151
|
+
if (depositUsd > maxCapUsd)
|
|
152
|
+
depositUsd = maxCapUsd;
|
|
63
153
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
nonce = status.nonce;
|
|
67
|
-
deployed = status.deployed;
|
|
154
|
+
catch {
|
|
155
|
+
// best-effort
|
|
68
156
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// Floor pad comes from the sizer ($1 for Case A); upper bound now lives in
|
|
83
|
-
// the origin gateway (MAX_CAP_UNIVERSAL_TX_USD) — the SDK no longer caps.
|
|
84
|
-
const r1Sizing = yield (0, gas_usd_sizer_1.sizeR1PushGas)(ctx, {
|
|
85
|
-
pushGasFeeWei: requiredGasFee,
|
|
86
|
-
originChain: chain,
|
|
87
|
-
});
|
|
88
|
-
// Convert the sizer's USD result into planned PC native deposit so the
|
|
89
|
-
// sizer progress hook can surface the user-facing `extraDepositPC` =
|
|
90
|
-
// totalPCDeposit - gasRequired. The same conversion is reused below for
|
|
91
|
-
// the final nativeAmount calc (after SVM clamp).
|
|
92
|
-
const nativeTokenUsdPrice = yield new price_fetch_1.PriceFetch(ctx.rpcUrls).getPrice(chain);
|
|
93
|
-
const nativeDecimals = chain_1.CHAIN_INFO[chain].vm === enums_1.VM.SVM ? 9 : 18;
|
|
94
|
-
const oneNativeUnit = utils_1.Utils.helpers.parseUnits('1', nativeDecimals);
|
|
95
|
-
const usdToNative = (usd) => {
|
|
96
|
-
if (nativeTokenUsdPrice === BigInt(0))
|
|
97
|
-
return BigInt(0);
|
|
98
|
-
const out = (usd * oneNativeUnit + (nativeTokenUsdPrice - BigInt(1))) / nativeTokenUsdPrice;
|
|
99
|
-
return out + BigInt(1);
|
|
100
|
-
};
|
|
101
|
-
const plannedPCDeposit = usdToNative(r1Sizing.paddedDepositUsd);
|
|
102
|
-
const extraDepositPC = plannedPCDeposit > requiredGasFee ? plannedPCDeposit - requiredGasFee : BigInt(0);
|
|
103
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03, chain, r1Sizing.paddedDepositUsd);
|
|
104
|
-
const r1SizingHookId = {
|
|
105
|
-
A: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_01,
|
|
106
|
-
B: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_02,
|
|
107
|
-
C: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_03,
|
|
108
|
-
}[r1Sizing.category];
|
|
109
|
-
(0, context_1.fireProgressHook)(ctx, r1SizingHookId, chain, requiredGasFee, extraDepositPC, r1Sizing.paddedDepositUsd);
|
|
110
|
-
const deficit = requiredFunds > ueaBalance ? requiredFunds - ueaBalance : BigInt(0);
|
|
111
|
-
let depositUsd = deficit > BigInt(0) ? ctx.pushClient.pushToUSDC(deficit) : BigInt(0);
|
|
112
|
-
// Apply sizer floor: Case A pads to $1, Cases B/C pass-through.
|
|
113
|
-
if (depositUsd < r1Sizing.paddedDepositUsd)
|
|
114
|
-
depositUsd = r1Sizing.paddedDepositUsd;
|
|
115
|
-
// Match funds-only and standard fee-lock sizing: fixed PC→USD conversion can
|
|
116
|
-
// underfund large PC deposits when the live pETH/WPC pool has meaningful
|
|
117
|
-
// slippage. Quote the native amount required for the target WPC output and
|
|
118
|
-
// raise the USD deposit before converting back to source-chain native value.
|
|
119
|
-
if (chain_1.CHAIN_INFO[chain].vm === enums_1.VM.EVM && requiredFunds > ueaBalance) {
|
|
120
|
-
const deficit = requiredFunds - ueaBalance;
|
|
121
|
-
const targetWpc = (deficit * BigInt(12)) / BigInt(10);
|
|
122
|
-
const originPrc20 = (0, helpers_1.getNativePRC20ForChain)(chain, ctx.pushNetwork);
|
|
123
|
-
const poolNativeAmount = yield (0, gas_calculator_1.estimateNativeForDesiredDeposit)(ctx, targetWpc, originPrc20);
|
|
124
|
-
if (poolNativeAmount > BigInt(0)) {
|
|
125
|
-
const poolBasedUsd = (poolNativeAmount * nativeTokenUsdPrice) / oneNativeUnit;
|
|
126
|
-
if (poolBasedUsd > depositUsd) {
|
|
127
|
-
(0, context_1.printLog)(ctx, `sendFundsWithPayload — pool-based deposit sizing overrides fixed-rate estimate: ` +
|
|
128
|
-
`fixedUsd=${depositUsd.toString()}, poolBasedUsd=${poolBasedUsd.toString()}, ` +
|
|
129
|
-
`requiredFunds=${requiredFunds.toString()}, ueaBalance=${ueaBalance.toString()}`);
|
|
130
|
-
depositUsd = poolBasedUsd;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
157
|
+
}
|
|
158
|
+
// Final USD(8) -> native conversion reusing the cached price fetched above.
|
|
159
|
+
const nativeAmount = usdToNative(depositUsd);
|
|
160
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_03_04, nativeAmount, depositUsd, chain);
|
|
161
|
+
const bridgeAmount = execute.funds.amount;
|
|
162
|
+
const symbol = execute.funds.token.symbol;
|
|
163
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_01, bridgeAmount, execute.funds.token.decimals, symbol);
|
|
164
|
+
if (chain_1.CHAIN_INFO[ctx.universalSigner.account.chain].vm === enums_1.VM.EVM) {
|
|
165
|
+
const tokenAddr = execute.funds.token.address;
|
|
166
|
+
if (mechanism === 'approve') {
|
|
167
|
+
const evmClientEvm = evmClient;
|
|
168
|
+
const gatewayAddressEvm = gatewayAddress;
|
|
169
|
+
await (0, gas_calculator_1.ensureErc20Allowance)(ctx, evmClientEvm, tokenAddr, gatewayAddressEvm, bridgeAmount);
|
|
133
170
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const svmClient = new svm_client_1.SvmClient({
|
|
137
|
-
rpcUrls: ctx.rpcUrls[enums_1.CHAIN.SOLANA_DEVNET] || chain_1.CHAIN_INFO[enums_1.CHAIN.SOLANA_DEVNET].defaultRPC,
|
|
138
|
-
});
|
|
139
|
-
const programId = new web3_js_1.PublicKey(universalGatewayV0_json_1.default.address);
|
|
140
|
-
const [configPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('config')], programId);
|
|
141
|
-
try {
|
|
142
|
-
const cfg = yield svmClient.readContract({
|
|
143
|
-
abi: universalGatewayV0_json_1.default, address: universalGatewayV0_json_1.default.address,
|
|
144
|
-
functionName: 'config', args: [configPda.toBase58()],
|
|
145
|
-
});
|
|
146
|
-
const minCapUsd = BigInt(((_d = cfg.minCapUniversalTxUsd) !== null && _d !== void 0 ? _d : cfg.min_cap_universal_tx_usd).toString());
|
|
147
|
-
const maxCapUsd = BigInt(((_e = cfg.maxCapUniversalTxUsd) !== null && _e !== void 0 ? _e : cfg.max_cap_universal_tx_usd).toString());
|
|
148
|
-
if (depositUsd < minCapUsd)
|
|
149
|
-
depositUsd = minCapUsd;
|
|
150
|
-
const withMargin = (minCapUsd * BigInt(12)) / BigInt(10);
|
|
151
|
-
if (depositUsd < withMargin)
|
|
152
|
-
depositUsd = withMargin;
|
|
153
|
-
if (depositUsd > maxCapUsd)
|
|
154
|
-
depositUsd = maxCapUsd;
|
|
155
|
-
}
|
|
156
|
-
catch (_m) {
|
|
157
|
-
// best-effort
|
|
158
|
-
}
|
|
171
|
+
else if (mechanism === 'permit2') {
|
|
172
|
+
throw new Error('Permit2 is not supported yet');
|
|
159
173
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const bridgeAmount = execute.funds.amount;
|
|
164
|
-
const symbol = execute.funds.token.symbol;
|
|
165
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_01, bridgeAmount, execute.funds.token.decimals, symbol);
|
|
174
|
+
}
|
|
175
|
+
let txHash;
|
|
176
|
+
try {
|
|
166
177
|
if (chain_1.CHAIN_INFO[ctx.universalSigner.account.chain].vm === enums_1.VM.EVM) {
|
|
167
178
|
const tokenAddr = execute.funds.token.address;
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (chain_1.CHAIN_INFO[ctx.universalSigner.account.chain].vm === enums_1.VM.EVM) {
|
|
180
|
-
const tokenAddr = execute.funds.token.address;
|
|
181
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_01);
|
|
182
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_02);
|
|
183
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_03);
|
|
184
|
-
const evmClientEvm = evmClient;
|
|
185
|
-
const gatewayAddressEvm = gatewayAddress;
|
|
186
|
-
const payloadBytes = (0, signing_1.encodeUniversalPayload)(universalPayload);
|
|
187
|
-
const payWith = execute.payGasWith;
|
|
188
|
-
const gasTokenAddress = (_f = payWith === null || payWith === void 0 ? void 0 : payWith.token) === null || _f === void 0 ? void 0 : _f.address;
|
|
189
|
-
if (gasTokenAddress) {
|
|
190
|
-
if (chain !== enums_1.CHAIN.ETHEREUM_SEPOLIA) {
|
|
191
|
-
throw new Error(`Only ${push_chain_1.PushChain.utils.chains.getChainName(enums_1.CHAIN.ETHEREUM_SEPOLIA)} is supported for paying gas fees with ERC-20 tokens`);
|
|
192
|
-
}
|
|
193
|
-
let amountOutMinETH = (payWith === null || payWith === void 0 ? void 0 : payWith.minAmountOut) !== undefined ? BigInt(payWith.minAmountOut) : nativeAmount;
|
|
194
|
-
const slippageBps = (_g = payWith === null || payWith === void 0 ? void 0 : payWith.slippageBps) !== null && _g !== void 0 ? _g : 100;
|
|
195
|
-
amountOutMinETH = BigInt(push_chain_1.PushChain.utils.conversion.slippageToMinAmount(amountOutMinETH.toString(), { slippageBps }));
|
|
196
|
-
const quoteExactOutputFn = (amountOut, opts) => (0, quote_1.quoteExactOutput)(ctx, amountOut, opts);
|
|
197
|
-
const { gasAmount } = yield (0, gas_calculator_1.calculateGasAmountFromAmountOutMinETH)(ctx, gasTokenAddress, amountOutMinETH, quoteExactOutputFn);
|
|
198
|
-
const deadline = BigInt(0);
|
|
199
|
-
const ownerAddress = ctx.universalSigner.account.address;
|
|
200
|
-
const gasTokenBalance = yield evmClientEvm.getErc20Balance({
|
|
201
|
-
tokenAddress: gasTokenAddress, ownerAddress,
|
|
202
|
-
});
|
|
203
|
-
if (gasTokenBalance < gasAmount) {
|
|
204
|
-
const sym = (_j = (_h = payWith === null || payWith === void 0 ? void 0 : payWith.token) === null || _h === void 0 ? void 0 : _h.symbol) !== null && _j !== void 0 ? _j : 'gas token';
|
|
205
|
-
const decimals = (_l = (_k = payWith === null || payWith === void 0 ? void 0 : payWith.token) === null || _k === void 0 ? void 0 : _k.decimals) !== null && _l !== void 0 ? _l : 18;
|
|
206
|
-
throw new Error(`Insufficient ${sym} balance to cover gas fees: need ${utils_1.Utils.helpers.formatUnits(gasAmount, decimals)}, have ${utils_1.Utils.helpers.formatUnits(gasTokenBalance, decimals)}`);
|
|
207
|
-
}
|
|
208
|
-
yield (0, gas_calculator_1.ensureErc20Allowance)(ctx, evmClientEvm, gasTokenAddress, gatewayAddressEvm, gasAmount);
|
|
209
|
-
const reqToken = Object.assign(Object.assign({}, req), { gasToken: gasTokenAddress, gasAmount, amountOutMinETH, deadline });
|
|
210
|
-
txHash = yield (0, gateway_client_1.sendGatewayTokenTxWithFallback)(ctx, evmClientEvm, gatewayAddressEvm, reqToken, ctx.universalSigner);
|
|
179
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_01);
|
|
180
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_02);
|
|
181
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_03);
|
|
182
|
+
const evmClientEvm = evmClient;
|
|
183
|
+
const gatewayAddressEvm = gatewayAddress;
|
|
184
|
+
const payloadBytes = (0, signing_1.encodeUniversalPayload)(universalPayload);
|
|
185
|
+
const payWith = execute.payGasWith;
|
|
186
|
+
const gasTokenAddress = payWith?.token?.address;
|
|
187
|
+
if (gasTokenAddress) {
|
|
188
|
+
if (chain !== enums_1.CHAIN.ETHEREUM_SEPOLIA) {
|
|
189
|
+
throw new Error(`Only ${push_chain_1.PushChain.utils.chains.getChainName(enums_1.CHAIN.ETHEREUM_SEPOLIA)} is supported for paying gas fees with ERC-20 tokens`);
|
|
211
190
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
191
|
+
let amountOutMinETH = payWith?.minAmountOut !== undefined ? BigInt(payWith.minAmountOut) : nativeAmount;
|
|
192
|
+
const slippageBps = payWith?.slippageBps ?? 100;
|
|
193
|
+
amountOutMinETH = BigInt(push_chain_1.PushChain.utils.conversion.slippageToMinAmount(amountOutMinETH.toString(), { slippageBps }));
|
|
194
|
+
const quoteExactOutputFn = (amountOut, opts) => (0, quote_1.quoteExactOutput)(ctx, amountOut, opts);
|
|
195
|
+
const { gasAmount } = await (0, gas_calculator_1.calculateGasAmountFromAmountOutMinETH)(ctx, gasTokenAddress, amountOutMinETH, quoteExactOutputFn);
|
|
196
|
+
const deadline = BigInt(0);
|
|
197
|
+
const ownerAddress = ctx.universalSigner.account.address;
|
|
198
|
+
const gasTokenBalance = await evmClientEvm.getErc20Balance({
|
|
199
|
+
tokenAddress: gasTokenAddress, ownerAddress,
|
|
200
|
+
});
|
|
201
|
+
if (gasTokenBalance < gasAmount) {
|
|
202
|
+
const sym = payWith?.token?.symbol ?? 'gas token';
|
|
203
|
+
const decimals = payWith?.token?.decimals ?? 18;
|
|
204
|
+
throw new Error(`Insufficient ${sym} balance to cover gas fees: need ${utils_1.Utils.helpers.formatUnits(gasAmount, decimals)}, have ${utils_1.Utils.helpers.formatUnits(gasTokenBalance, decimals)}`);
|
|
216
205
|
}
|
|
206
|
+
await (0, gas_calculator_1.ensureErc20Allowance)(ctx, evmClientEvm, gasTokenAddress, gatewayAddressEvm, gasAmount);
|
|
207
|
+
const reqToken = {
|
|
208
|
+
...req, gasToken: gasTokenAddress, gasAmount, amountOutMinETH, deadline,
|
|
209
|
+
};
|
|
210
|
+
txHash = await (0, gateway_client_1.sendGatewayTokenTxWithFallback)(ctx, evmClientEvm, gatewayAddressEvm, reqToken, ctx.universalSigner);
|
|
217
211
|
}
|
|
218
212
|
else {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
213
|
+
const isNativeToken = mechanism === 'native';
|
|
214
|
+
const totalValue = isNativeToken ? nativeAmount + bridgeAmount : nativeAmount;
|
|
215
|
+
txHash = await (0, gateway_client_1.sendGatewayTxWithFallback)(ctx, evmClientEvm, gatewayAddressEvm, req, ctx.universalSigner, totalValue);
|
|
222
216
|
}
|
|
223
217
|
}
|
|
224
|
-
catch (err) {
|
|
225
|
-
const errMsg = (0, formatters_1.normalizePublicErrorMessage)(err);
|
|
226
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_04, errMsg);
|
|
227
|
-
ctx._routeTerminalEmitted = true;
|
|
228
|
-
throw new Error(errMsg);
|
|
229
|
-
}
|
|
230
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_03);
|
|
231
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_02, txHash, bridgeAmount, execute.funds.token.decimals, symbol);
|
|
232
|
-
// Awaiting confirmations
|
|
233
|
-
const signerChain = ctx.universalSigner.account.chain;
|
|
234
|
-
if (chain_1.CHAIN_INFO[signerChain].vm === enums_1.VM.EVM) {
|
|
235
|
-
yield (0, confirmation_1.waitForEvmConfirmationsWithCountdown)(ctx, evmClient, txHash, chain_1.CHAIN_INFO[signerChain].confirmations, chain_1.CHAIN_INFO[signerChain].timeout);
|
|
236
|
-
}
|
|
237
218
|
else {
|
|
238
|
-
|
|
239
|
-
|
|
219
|
+
txHash = await (0, svm_bridge_1.sendSVMTxWithFunds)(ctx, {
|
|
220
|
+
execute, mechanism, universalPayload, bridgeAmount, nativeAmount, req,
|
|
240
221
|
});
|
|
241
|
-
yield (0, confirmation_1.waitForSvmConfirmationsWithCountdown)(ctx, svmClient, txHash, chain_1.CHAIN_INFO[signerChain].confirmations, chain_1.CHAIN_INFO[signerChain].timeout);
|
|
242
222
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
const errMsg = (0, formatters_1.normalizePublicErrorMessage)(err);
|
|
226
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_04, errMsg);
|
|
227
|
+
ctx._routeTerminalEmitted = true;
|
|
228
|
+
throw new Error(errMsg);
|
|
229
|
+
}
|
|
230
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_03);
|
|
231
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_02, txHash, bridgeAmount, execute.funds.token.decimals, symbol);
|
|
232
|
+
// Awaiting confirmations
|
|
233
|
+
const signerChain = ctx.universalSigner.account.chain;
|
|
234
|
+
if (chain_1.CHAIN_INFO[signerChain].vm === enums_1.VM.EVM) {
|
|
235
|
+
await (0, confirmation_1.waitForEvmConfirmationsWithCountdown)(ctx, evmClient, txHash, chain_1.CHAIN_INFO[signerChain].confirmations, chain_1.CHAIN_INFO[signerChain].timeout);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
const svmClient = new svm_client_1.SvmClient({
|
|
239
|
+
rpcUrls: ctx.rpcUrls[enums_1.CHAIN.SOLANA_DEVNET] || chain_1.CHAIN_INFO[enums_1.CHAIN.SOLANA_DEVNET].defaultRPC,
|
|
240
|
+
});
|
|
241
|
+
await (0, confirmation_1.waitForSvmConfirmationsWithCountdown)(ctx, svmClient, txHash, chain_1.CHAIN_INFO[signerChain].confirmations, chain_1.CHAIN_INFO[signerChain].timeout);
|
|
242
|
+
}
|
|
243
|
+
// Funds Flow: Confirmed on origin
|
|
244
|
+
let feeLockTxHash = txHash;
|
|
245
|
+
if (chain_1.CHAIN_INFO[ctx.universalSigner.account.chain].vm === enums_1.VM.SVM) {
|
|
246
|
+
if (feeLockTxHash && !feeLockTxHash.startsWith('0x')) {
|
|
247
|
+
const decoded = bs58_1.bs58.decode(feeLockTxHash);
|
|
248
|
+
feeLockTxHash = (0, viem_1.bytesToHex)(new Uint8Array(decoded));
|
|
250
249
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
pushChainUniversalTx = yield (0, response_builder_1.queryUniversalTxStatusFromGatewayTx)(ctx, undefined, undefined, txHash, 'sendTxWithFunds');
|
|
261
|
-
}
|
|
262
|
-
response = yield (0, push_chain_tx_1.extractPcTxAndTransform)(ctx, pushChainUniversalTx, txHash, eventBuffer, 'sendTxWithFunds', transformFn);
|
|
250
|
+
}
|
|
251
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_04, txHash);
|
|
252
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_05);
|
|
253
|
+
let response;
|
|
254
|
+
try {
|
|
255
|
+
let pushChainUniversalTx;
|
|
256
|
+
const isPc20Import = execute._pc20?.direction === 'import';
|
|
257
|
+
if (chain_1.CHAIN_INFO[ctx.universalSigner.account.chain].vm === enums_1.VM.EVM) {
|
|
258
|
+
pushChainUniversalTx = await (0, response_builder_1.queryUniversalTxStatusFromGatewayTx)(ctx, evmClient, gatewayAddress, txHash, 'sendTxWithFunds', isPc20Import);
|
|
263
259
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const errMsg = (0, formatters_1.normalizePublicErrorMessage)(err);
|
|
267
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_02, errMsg);
|
|
268
|
-
throw new push_chain_tx_1.PushChainExecutionError(errMsg, { gatewayTxHash: txHash });
|
|
269
|
-
}
|
|
270
|
-
throw err;
|
|
260
|
+
else {
|
|
261
|
+
pushChainUniversalTx = await (0, response_builder_1.queryUniversalTxStatusFromGatewayTx)(ctx, undefined, undefined, txHash, 'sendTxWithFunds', isPc20Import);
|
|
271
262
|
}
|
|
272
|
-
(0,
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
263
|
+
response = await (0, push_chain_tx_1.extractPcTxAndTransform)(ctx, pushChainUniversalTx, txHash, eventBuffer, 'sendTxWithFunds', transformFn);
|
|
264
|
+
}
|
|
265
|
+
catch (err) {
|
|
266
|
+
if (!(err instanceof push_chain_tx_1.PushChainExecutionError)) {
|
|
267
|
+
const errMsg = (0, formatters_1.normalizePublicErrorMessage)(err);
|
|
268
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_02, errMsg);
|
|
269
|
+
throw new push_chain_tx_1.PushChainExecutionError(errMsg, { gatewayTxHash: txHash });
|
|
270
|
+
}
|
|
271
|
+
throw err;
|
|
272
|
+
}
|
|
273
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_106_06, bridgeAmount, execute.funds.token.decimals, symbol);
|
|
274
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_107);
|
|
275
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_01, [response]);
|
|
276
|
+
return response;
|
|
277
277
|
}
|
|
278
278
|
//# sourceMappingURL=execute-funds-payload.js.map
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Standard payload execution flow (no funds) — extracted from Orchestrator.execute().
|
|
3
|
-
*
|
|
4
|
-
* Handles payload-only execution on Push Chain:
|
|
5
|
-
* - Push-to-Push direct transactions
|
|
6
|
-
* - Fee-locking path for undeployed/underfunded UEA
|
|
7
|
-
* - Signed verification path for deployed UEA with funds
|
|
8
|
-
*/
|
|
9
1
|
import { ProgressEvent } from '../../progress-hook/progress-hook.types';
|
|
10
2
|
import type { ExecuteParams, UniversalTxResponse } from '../orchestrator.types';
|
|
11
3
|
import type { OrchestratorContext } from './context';
|