@pushchain/core 5.1.5-alpha.0 → 5.1.5
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 +19 -0
- package/package.json +1 -1
- package/src/lib/constants/abi/index.d.ts +2 -0
- package/src/lib/constants/abi/index.js +6 -1
- package/src/lib/constants/abi/uniswap-v3-router.evm.d.ts +58 -0
- package/src/lib/constants/abi/uniswap-v3-router.evm.js +41 -0
- package/src/lib/constants/abi/wpc.evm.d.ts +24 -0
- package/src/lib/constants/abi/wpc.evm.js +27 -0
- package/src/lib/constants/chain.d.ts +1 -0
- package/src/lib/constants/chain.js +8 -6
- package/src/lib/constants/tokens.js +3 -3
- package/src/lib/generated/uexecutor/v2/types.d.ts +14 -0
- package/src/lib/generated/uexecutor/v2/types.js +96 -3
- package/src/lib/orchestrator/internals/cascade.d.ts +1 -1
- package/src/lib/orchestrator/internals/cascade.js +556 -225
- package/src/lib/orchestrator/internals/confirmation.js +60 -15
- package/src/lib/orchestrator/internals/context.d.ts +23 -0
- package/src/lib/orchestrator/internals/context.js +54 -0
- package/src/lib/orchestrator/internals/execute-funds-only.js +47 -21
- package/src/lib/orchestrator/internals/execute-funds-payload.js +53 -31
- package/src/lib/orchestrator/internals/execute-standard.js +137 -26
- package/src/lib/orchestrator/internals/gas-calculator.d.ts +5 -2
- package/src/lib/orchestrator/internals/gas-calculator.js +59 -11
- package/src/lib/orchestrator/internals/gas-usd-sizer.d.ts +53 -0
- package/src/lib/orchestrator/internals/gas-usd-sizer.js +165 -0
- package/src/lib/orchestrator/internals/helpers.js +2 -0
- package/src/lib/orchestrator/internals/inbound-tracker.d.ts +83 -0
- package/src/lib/orchestrator/internals/inbound-tracker.js +322 -0
- package/src/lib/orchestrator/internals/index.d.ts +3 -1
- package/src/lib/orchestrator/internals/index.js +8 -2
- package/src/lib/orchestrator/internals/outbound-sync.d.ts +32 -1
- package/src/lib/orchestrator/internals/outbound-sync.js +154 -17
- package/src/lib/orchestrator/internals/pc-usd-oracle.d.ts +28 -0
- package/src/lib/orchestrator/internals/pc-usd-oracle.js +285 -0
- package/src/lib/orchestrator/internals/progress-route-hooks.d.ts +23 -0
- package/src/lib/orchestrator/internals/progress-route-hooks.js +72 -0
- package/src/lib/orchestrator/internals/push-chain-tx.d.ts +27 -1
- package/src/lib/orchestrator/internals/push-chain-tx.js +111 -15
- package/src/lib/orchestrator/internals/rescue.js +1 -1
- package/src/lib/orchestrator/internals/response-builder.d.ts +5 -0
- package/src/lib/orchestrator/internals/response-builder.js +252 -53
- package/src/lib/orchestrator/internals/route-handlers.js +480 -206
- package/src/lib/orchestrator/internals/tx-transformer.js +293 -35
- package/src/lib/orchestrator/orchestrator.d.ts +7 -1
- package/src/lib/orchestrator/orchestrator.js +108 -56
- package/src/lib/orchestrator/orchestrator.types.d.ts +120 -5
- package/src/lib/orchestrator/payload-builders.d.ts +16 -0
- package/src/lib/orchestrator/payload-builders.js +6 -5
- package/src/lib/orchestrator/route-detector.js +20 -8
- package/src/lib/orchestrator/svm-idl/normalize-address.d.ts +19 -0
- package/src/lib/orchestrator/svm-idl/normalize-address.js +56 -0
- package/src/lib/orchestrator/svm-idl/registry.d.ts +13 -4
- package/src/lib/orchestrator/svm-idl/registry.js +15 -14
- package/src/lib/orchestrator/svm-idl/resolve.js +5 -2
- package/src/lib/progress-hook/progress-hook.d.ts +28 -0
- package/src/lib/progress-hook/progress-hook.js +555 -101
- package/src/lib/progress-hook/progress-hook.types.d.ts +76 -24
- package/src/lib/progress-hook/progress-hook.types.js +74 -29
- package/src/lib/push-client/push-client.d.ts +7 -0
- package/src/lib/push-client/push-client.js +18 -1
- package/src/lib/universal-tx-detector/__tests__/fixtures/builders.d.ts +32 -0
- package/src/lib/universal-tx-detector/__tests__/fixtures/builders.js +65 -0
- package/src/lib/universal-tx-detector/__tests__/fixtures/scenarios.d.ts +72 -0
- package/src/lib/universal-tx-detector/__tests__/fixtures/scenarios.js +669 -0
- package/src/lib/universal-tx-detector/auto-detect.d.ts +37 -0
- package/src/lib/universal-tx-detector/auto-detect.js +112 -0
- package/src/lib/universal-tx-detector/cascade.d.ts +64 -0
- package/src/lib/universal-tx-detector/cascade.js +254 -0
- package/src/lib/universal-tx-detector/child-inbounds.d.ts +58 -0
- package/src/lib/universal-tx-detector/child-inbounds.js +145 -0
- package/src/lib/universal-tx-detector/classify.d.ts +33 -0
- package/src/lib/universal-tx-detector/classify.js +228 -0
- package/src/lib/universal-tx-detector/detector-svm.d.ts +46 -0
- package/src/lib/universal-tx-detector/detector-svm.js +324 -0
- package/src/lib/universal-tx-detector/detector.d.ts +13 -0
- package/src/lib/universal-tx-detector/detector.js +233 -0
- package/src/lib/universal-tx-detector/events.d.ts +765 -0
- package/src/lib/universal-tx-detector/events.js +241 -0
- package/src/lib/universal-tx-detector/index.d.ts +18 -0
- package/src/lib/universal-tx-detector/index.js +36 -0
- package/src/lib/universal-tx-detector/svm-events.d.ts +41 -0
- package/src/lib/universal-tx-detector/svm-events.js +68 -0
- package/src/lib/universal-tx-detector/types.d.ts +100 -0
- package/src/lib/universal-tx-detector/types.js +3 -0
- package/src/lib/utils.d.ts +30 -13
- package/src/lib/utils.js +47 -21
|
@@ -23,6 +23,7 @@ const context_1 = require("./context");
|
|
|
23
23
|
const helpers_1 = require("./helpers");
|
|
24
24
|
const payload_builder_1 = require("./payload-builder");
|
|
25
25
|
const signing_1 = require("./signing");
|
|
26
|
+
const progress_hook_1 = require("../../progress-hook/progress-hook");
|
|
26
27
|
const uea_manager_1 = require("./uea-manager");
|
|
27
28
|
const confirmation_1 = require("./confirmation");
|
|
28
29
|
const gateway_client_1 = require("./gateway-client");
|
|
@@ -31,37 +32,81 @@ const push_chain_tx_1 = require("./push-chain-tx");
|
|
|
31
32
|
const gas_calculator_1 = require("./gas-calculator");
|
|
32
33
|
const helpers_2 = require("./helpers");
|
|
33
34
|
const price_fetch_1 = require("../../price-fetch/price-fetch");
|
|
35
|
+
/**
|
|
36
|
+
* Encode a UniversalPayload for transport over the origin chain's gateway.
|
|
37
|
+
* - EVM origin → ABI encoding (chain decodes via DecodeUniversalPayloadEVM).
|
|
38
|
+
* - SVM origin → Borsh encoding (chain decodes via DecodeUniversalPayloadSolana).
|
|
39
|
+
*
|
|
40
|
+
* The encoded bytes are placed in the Solana gateway's UniversalTx event
|
|
41
|
+
* (or the EVM UniversalGateway's SendUniversalTx event) payload field. Push
|
|
42
|
+
* Chain's uexecutor module decodes from that same field using the source
|
|
43
|
+
* chain's namespace (see push-chain/x/uexecutor/types/decode_payload.go).
|
|
44
|
+
* Using the wrong encoder for SVM origin results in garbage fields — in
|
|
45
|
+
* particular gasLimit=0 — which surfaces as "intrinsic gas too low" when
|
|
46
|
+
* the chain calls executeUniversalTx on the (possibly lazy-deployed) UEA.
|
|
47
|
+
*/
|
|
48
|
+
function encodePayloadForOrigin(ctx, payload) {
|
|
49
|
+
const { vm } = chain_1.CHAIN_INFO[ctx.universalSigner.account.chain];
|
|
50
|
+
if (vm === enums_1.VM.SVM) {
|
|
51
|
+
const buf = (0, signing_1.encodeUniversalPayloadSvm)(payload);
|
|
52
|
+
return ('0x' + buf.toString('hex'));
|
|
53
|
+
}
|
|
54
|
+
return (0, signing_1.encodeUniversalPayload)(payload);
|
|
55
|
+
}
|
|
34
56
|
function executeStandardPayload(ctx, execute, eventBuffer, getResponseCallbacks) {
|
|
35
57
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
36
|
-
var _a, _b;
|
|
58
|
+
var _a, _b, _c;
|
|
37
59
|
const transformFn = (tx, buf = []) => (0, response_builder_1.transformToUniversalTxResponse)(ctx, tx, buf, getResponseCallbacks());
|
|
38
60
|
// Set default value for value if undefined
|
|
39
61
|
if (execute.value === undefined) {
|
|
40
62
|
execute.value = BigInt(0);
|
|
41
63
|
}
|
|
42
64
|
const chain = ctx.universalSigner.account.chain;
|
|
43
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.
|
|
65
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_101, chain, ctx.universalSigner.account.address);
|
|
44
66
|
(0, helpers_1.validateMainnetConnection)(chain, ctx.pushClient.pushChainInfo.chainId);
|
|
67
|
+
// Gas estimation fires for both Push-to-Push and external-origin flows so
|
|
68
|
+
// reconstructProgressEvents (which always emits 102-01/02) and live execute
|
|
69
|
+
// stay in lockstep. For the Push-to-Push shortcut we have no origin-chain
|
|
70
|
+
// gas to estimate; surface the tx gas limit as the "cost" to match what
|
|
71
|
+
// the reconstruction path does (it reads universalTxResponse.gasLimit).
|
|
72
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_102_01);
|
|
45
73
|
// Push to Push Tx
|
|
46
74
|
if ((0, helpers_1.isPushChain)(chain)) {
|
|
47
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.
|
|
48
|
-
|
|
49
|
-
|
|
75
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_102_02, (_a = execute.gasLimit) !== null && _a !== void 0 ? _a : BigInt(21000));
|
|
76
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_107);
|
|
77
|
+
let tx;
|
|
78
|
+
try {
|
|
79
|
+
tx = yield (0, push_chain_tx_1.sendPushTx)(ctx, execute, eventBuffer, transformFn);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
// Push Chain broadcast failed. Wallet rejection surfaces as 104-04;
|
|
83
|
+
// everything else (RPC fail, on-chain revert) as 199-02.
|
|
84
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
85
|
+
const { isUserDecline } = (0, progress_hook_1.classifyDeclineError)(errMsg);
|
|
86
|
+
(0, context_1.fireProgressHook)(ctx, isUserDecline ? progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_04 : progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_02, errMsg);
|
|
87
|
+
// Mark that a terminal-ish error hook has already fired so the
|
|
88
|
+
// outer orchestrator catch doesn't emit a second 199-02 on top.
|
|
89
|
+
ctx._routeTerminalEmitted = true;
|
|
90
|
+
if (!isUserDecline && !(err instanceof push_chain_tx_1.PushChainExecutionError)) {
|
|
91
|
+
throw new push_chain_tx_1.PushChainExecutionError(errMsg);
|
|
92
|
+
}
|
|
93
|
+
throw err;
|
|
94
|
+
}
|
|
95
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_01, [tx]);
|
|
50
96
|
return tx;
|
|
51
97
|
}
|
|
52
98
|
// Fetch Gas details and estimate cost of execution
|
|
53
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_02_01);
|
|
54
99
|
const gasEstimate = execute.gasLimit || BigInt(1e7);
|
|
55
100
|
const gasPrice = yield ctx.pushClient.getGasPrice();
|
|
56
101
|
const requiredGasFee = gasEstimate * gasPrice;
|
|
57
102
|
const requiredFunds = requiredGasFee + execute.value;
|
|
58
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.
|
|
103
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_102_02, requiredFunds);
|
|
59
104
|
// Fetch UEA Details (or use pre-fetched status if available)
|
|
60
105
|
const UEA = (0, uea_manager_1.computeUEAOffchain)(ctx);
|
|
61
106
|
let isUEADeployed;
|
|
62
107
|
let nonce;
|
|
63
108
|
let funds;
|
|
64
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.
|
|
109
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_01);
|
|
65
110
|
if (execute._ueaStatus) {
|
|
66
111
|
isUEADeployed = execute._ueaStatus.isDeployed;
|
|
67
112
|
nonce = execute._ueaStatus.nonce;
|
|
@@ -69,7 +114,7 @@ function executeStandardPayload(ctx, execute, eventBuffer, getResponseCallbacks)
|
|
|
69
114
|
}
|
|
70
115
|
else {
|
|
71
116
|
// Skip getCode if accountStatusCache already confirmed deployment
|
|
72
|
-
const deployedHint = (
|
|
117
|
+
const deployedHint = (_c = (_b = ctx.accountStatusCache) === null || _b === void 0 ? void 0 : _b.uea) === null || _c === void 0 ? void 0 : _c.deployed;
|
|
73
118
|
if (deployedHint) {
|
|
74
119
|
const [balance, ueaNonce] = yield Promise.all([
|
|
75
120
|
ctx.pushClient.getBalance(UEA),
|
|
@@ -89,7 +134,7 @@ function executeStandardPayload(ctx, execute, eventBuffer, getResponseCallbacks)
|
|
|
89
134
|
funds = balance;
|
|
90
135
|
}
|
|
91
136
|
}
|
|
92
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.
|
|
137
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_103_02, UEA, isUEADeployed);
|
|
93
138
|
// Validate and decode feeLockTxHash
|
|
94
139
|
let feeLockTxHash = execute.feeLockTxHash;
|
|
95
140
|
if (feeLockTxHash) {
|
|
@@ -122,7 +167,7 @@ function executeStandardPayload(ctx, execute, eventBuffer, getResponseCallbacks)
|
|
|
122
167
|
}, helpers_1.bigintReplacer));
|
|
123
168
|
req = (0, payload_builder_1.buildUniversalTxRequest)(ctx.universalSigner.account.address, {
|
|
124
169
|
recipient: viem_1.zeroAddress, token: viem_1.zeroAddress, amount: BigInt(0),
|
|
125
|
-
payload: (
|
|
170
|
+
payload: encodePayloadForOrigin(ctx, universalPayloadForReq),
|
|
126
171
|
});
|
|
127
172
|
}
|
|
128
173
|
else {
|
|
@@ -151,7 +196,7 @@ function executeStandardPayload(ctx, execute, eventBuffer, getResponseCallbacks)
|
|
|
151
196
|
}, helpers_1.bigintReplacer));
|
|
152
197
|
req = (0, payload_builder_1.buildUniversalTxRequest)(ctx.universalSigner.account.address, {
|
|
153
198
|
recipient: viem_1.zeroAddress, token: viem_1.zeroAddress, amount: BigInt(0),
|
|
154
|
-
payload: (
|
|
199
|
+
payload: encodePayloadForOrigin(ctx, universalPayloadOther),
|
|
155
200
|
});
|
|
156
201
|
}
|
|
157
202
|
}
|
|
@@ -172,7 +217,7 @@ function executeStandardPayload(ctx, execute, eventBuffer, getResponseCallbacks)
|
|
|
172
217
|
}, helpers_1.bigintReplacer));
|
|
173
218
|
req = (0, payload_builder_1.buildUniversalTxRequest)(ctx.universalSigner.account.address, {
|
|
174
219
|
recipient: viem_1.zeroAddress, token: viem_1.zeroAddress, amount: BigInt(0),
|
|
175
|
-
payload: (
|
|
220
|
+
payload: encodePayloadForOrigin(ctx, universalPayloadSelf),
|
|
176
221
|
});
|
|
177
222
|
}
|
|
178
223
|
}
|
|
@@ -190,10 +235,21 @@ function executeStandardPayload(ctx, execute, eventBuffer, getResponseCallbacks)
|
|
|
190
235
|
let verificationData;
|
|
191
236
|
if (!feeLockingRequired) {
|
|
192
237
|
const ueaVersion = yield (0, uea_manager_1.fetchUEAVersion)(ctx);
|
|
193
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.
|
|
194
|
-
|
|
238
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_02);
|
|
239
|
+
let signature;
|
|
240
|
+
try {
|
|
241
|
+
signature = yield (0, signing_1.signUniversalPayload)(ctx, universalPayload, UEA, ueaVersion);
|
|
242
|
+
}
|
|
243
|
+
catch (err) {
|
|
244
|
+
// Wallet decline, contract revert during sign, or RPC failure — the
|
|
245
|
+
// 104-04 builder's classifyDeclineError heuristic picks the right
|
|
246
|
+
// copy (real decline → "Verification Declined"; else "Signature Failed").
|
|
247
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
248
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_04, errMsg);
|
|
249
|
+
throw err;
|
|
250
|
+
}
|
|
195
251
|
verificationData = (0, viem_1.bytesToHex)(signature);
|
|
196
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.
|
|
252
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_03);
|
|
197
253
|
}
|
|
198
254
|
else {
|
|
199
255
|
// Fee Locking
|
|
@@ -299,7 +355,18 @@ function executeStandardPayload(ctx, execute, eventBuffer, getResponseCallbacks)
|
|
|
299
355
|
(0, context_1.printLog)(ctx, `Fee-lock pre-flight quote failed, proceeding without validation: ${err instanceof Error ? err.message : String(err)}`);
|
|
300
356
|
}
|
|
301
357
|
}
|
|
302
|
-
|
|
358
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_01);
|
|
359
|
+
let feeLockTxHashBytes;
|
|
360
|
+
try {
|
|
361
|
+
feeLockTxHashBytes = yield (0, gateway_client_1.lockFee)(ctx, effectiveLockAmountInUSD, universalPayload, req);
|
|
362
|
+
}
|
|
363
|
+
catch (err) {
|
|
364
|
+
// User declined the fee-lock tx submission or the origin-chain RPC
|
|
365
|
+
// rejected it — classifier picks decline vs generic signature failure.
|
|
366
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
367
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_104_04, errMsg);
|
|
368
|
+
throw err;
|
|
369
|
+
}
|
|
303
370
|
feeLockTxHash = (0, viem_1.bytesToHex)(feeLockTxHashBytes);
|
|
304
371
|
verificationData = (0, viem_1.bytesToHex)(feeLockTxHashBytes);
|
|
305
372
|
const { vm } = chain_1.CHAIN_INFO[chain];
|
|
@@ -307,19 +374,63 @@ function executeStandardPayload(ctx, execute, eventBuffer, getResponseCallbacks)
|
|
|
307
374
|
? bs58_1.bs58.encode(Buffer.from(feeLockTxHashBytes))
|
|
308
375
|
: feeLockTxHash;
|
|
309
376
|
const originTx = yield (0, helpers_1.fetchOriginChainTransactionForProgress)(ctx, chain, feeLockTxHash, feeLockTxHashDisplay);
|
|
310
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.
|
|
377
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_105_01, feeLockTxHashDisplay, originTx);
|
|
311
378
|
yield (0, confirmation_1.waitForLockerFeeConfirmation)(ctx, feeLockTxHashBytes);
|
|
312
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.
|
|
379
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_105_02);
|
|
313
380
|
const { defaultRPC, lockerContract } = chain_1.CHAIN_INFO[chain];
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
381
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_107);
|
|
382
|
+
let response;
|
|
383
|
+
try {
|
|
384
|
+
const pushChainUniversalTx = yield (0, response_builder_1.queryUniversalTxStatusFromGatewayTx)(ctx, new evm_client_1.EvmClient({ rpcUrls: ctx.rpcUrls[chain] || defaultRPC }), lockerContract, feeLockTxHash, 'sendTxWithGas');
|
|
385
|
+
// extractPcTxAndTransform fires 199-02 itself on pcTx FAILED and throws
|
|
386
|
+
// PushChainExecutionError — don't double-emit. Anything else thrown
|
|
387
|
+
// here (gateway-tx lookup failure, RPC error) hasn't emitted 199-02
|
|
388
|
+
// yet, so the catch below surfaces it.
|
|
389
|
+
response = yield (0, push_chain_tx_1.extractPcTxAndTransform)(ctx, pushChainUniversalTx, feeLockTxHash, eventBuffer, 'sendTxWithGas', transformFn);
|
|
390
|
+
}
|
|
391
|
+
catch (err) {
|
|
392
|
+
if (!(err instanceof push_chain_tx_1.PushChainExecutionError)) {
|
|
393
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
394
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_02, errMsg);
|
|
395
|
+
throw new push_chain_tx_1.PushChainExecutionError(errMsg, { gatewayTxHash: feeLockTxHash });
|
|
396
|
+
}
|
|
397
|
+
throw err;
|
|
398
|
+
}
|
|
399
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_01, [response]);
|
|
317
400
|
return response;
|
|
318
401
|
}
|
|
319
|
-
// Non-fee-locking path: Broadcasting Tx to PC via sendUniversalTx
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
(
|
|
402
|
+
// Non-fee-locking path: Broadcasting Tx to PC via sendUniversalTx.
|
|
403
|
+
// Provide a resign callback so sendUniversalTx can recover from the
|
|
404
|
+
// UEA-nonce race: the EIP-712 hash uses the UEA's live storage nonce
|
|
405
|
+
// (not payload.nonce), so if anything advances it between our read and
|
|
406
|
+
// Cosmos inclusion the tx reverts with InvalidEVMSignature(0xc7dbd31d).
|
|
407
|
+
const resignOnSigMismatch = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
408
|
+
const freshNonce = yield (0, uea_manager_1.getUEANonce)(ctx, UEA);
|
|
409
|
+
const freshUeaVersion = yield (0, uea_manager_1.fetchUEAVersion)(ctx);
|
|
410
|
+
const freshPayload = JSON.parse(JSON.stringify(Object.assign(Object.assign({}, universalPayload), { nonce: freshNonce }), helpers_1.bigintReplacer));
|
|
411
|
+
const freshSig = yield (0, signing_1.signUniversalPayload)(ctx, freshPayload, UEA, freshUeaVersion);
|
|
412
|
+
return {
|
|
413
|
+
universalPayload: freshPayload,
|
|
414
|
+
verificationData: (0, viem_1.bytesToHex)(freshSig),
|
|
415
|
+
};
|
|
416
|
+
});
|
|
417
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_107);
|
|
418
|
+
let transactions;
|
|
419
|
+
try {
|
|
420
|
+
transactions = yield (0, push_chain_tx_1.sendUniversalTx)(ctx, isUEADeployed, feeLockTxHash, universalPayload, verificationData, eventBuffer, transformFn, resignOnSigMismatch);
|
|
421
|
+
}
|
|
422
|
+
catch (err) {
|
|
423
|
+
// Push Chain broadcast failed (Cosmos reject, UEA revert, nonce race
|
|
424
|
+
// exhaustion). Surface terminal 199-02 before re-throwing so the stream
|
|
425
|
+
// ends with the spec'd error hook. Typed PushChainExecutionError lets
|
|
426
|
+
// callers classify via instanceof without message sniffing.
|
|
427
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
428
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_02, errMsg);
|
|
429
|
+
if (err instanceof push_chain_tx_1.PushChainExecutionError)
|
|
430
|
+
throw err;
|
|
431
|
+
throw new push_chain_tx_1.PushChainExecutionError(errMsg);
|
|
432
|
+
}
|
|
433
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_199_01, transactions);
|
|
323
434
|
return transactions[transactions.length - 1];
|
|
324
435
|
});
|
|
325
436
|
}
|
|
@@ -6,14 +6,16 @@ import { CHAIN } from '../../constants/enums';
|
|
|
6
6
|
import { ConversionQuote, MoveableToken, PayableToken } from '../../constants/tokens';
|
|
7
7
|
import { EvmClient } from '../../vm-client/evm-client';
|
|
8
8
|
import type { OrchestratorContext } from './context';
|
|
9
|
+
import { type GasSizingDecision } from './gas-usd-sizer';
|
|
9
10
|
export declare function ensureErc20Allowance(ctx: OrchestratorContext, evmClient: EvmClient, tokenAddress: `0x${string}`, spender: `0x${string}`, requiredAmount: bigint): Promise<void>;
|
|
10
|
-
export declare function queryOutboundGasFee(ctx: OrchestratorContext, prc20Token: `0x${string}`, gasLimit: bigint): Promise<{
|
|
11
|
+
export declare function queryOutboundGasFee(ctx: OrchestratorContext, prc20Token: `0x${string}`, gasLimit: bigint, destinationChain?: CHAIN): Promise<{
|
|
11
12
|
gasToken: `0x${string}`;
|
|
12
13
|
gasFee: bigint;
|
|
13
14
|
protocolFee: bigint;
|
|
14
15
|
nativeValueForGas: bigint;
|
|
15
16
|
gasPrice: bigint;
|
|
16
17
|
universalCoreAddress: `0x${string}`;
|
|
18
|
+
sizing?: GasSizingDecision;
|
|
17
19
|
}>;
|
|
18
20
|
/**
|
|
19
21
|
* Estimate the native WPC amount needed to swap for `gasFee` of `gasToken`
|
|
@@ -22,12 +24,13 @@ export declare function queryOutboundGasFee(ctx: OrchestratorContext, prc20Token
|
|
|
22
24
|
* Falls back to a percentage of accountBalance if any on-chain query fails.
|
|
23
25
|
*/
|
|
24
26
|
export declare function estimateNativeValueForSwap(ctx: OrchestratorContext, universalCoreAddress: `0x${string}`, gasToken: `0x${string}`, gasFee: bigint, accountBalance: bigint): Promise<bigint>;
|
|
25
|
-
export declare function queryRescueGasFee(ctx: OrchestratorContext, prc20Token: `0x${string}
|
|
27
|
+
export declare function queryRescueGasFee(ctx: OrchestratorContext, prc20Token: `0x${string}`, destinationChain?: CHAIN): Promise<{
|
|
26
28
|
gasToken: `0x${string}`;
|
|
27
29
|
gasFee: bigint;
|
|
28
30
|
rescueGasLimit: bigint;
|
|
29
31
|
gasPrice: bigint;
|
|
30
32
|
nativeValueForGas: bigint;
|
|
33
|
+
sizing?: GasSizingDecision;
|
|
31
34
|
}>;
|
|
32
35
|
export declare function calculateNativeAmountForDeposit(ctx: OrchestratorContext, chain: CHAIN, requiredFunds: bigint, ueaBalance: bigint): Promise<bigint>;
|
|
33
36
|
export declare function calculateGasAmountFromAmountOutMinETH(ctx: OrchestratorContext, gasTokenAddress: `0x${string}`, amountOutMinETH: bigint | string, quoteExactOutputFn: (amountOut: bigint, opts: {
|
|
@@ -25,7 +25,13 @@ const utils_1 = require("../../utils");
|
|
|
25
25
|
const svm_client_1 = require("../../vm-client/svm-client");
|
|
26
26
|
const context_1 = require("./context");
|
|
27
27
|
const helpers_1 = require("./helpers");
|
|
28
|
-
|
|
28
|
+
const gas_usd_sizer_1 = require("./gas-usd-sizer");
|
|
29
|
+
/**
|
|
30
|
+
* Legacy fallback buffer used ONLY when the caller does not supply a
|
|
31
|
+
* `destinationChain` and the USD sizer cannot be invoked. New code paths
|
|
32
|
+
* should always pass `destinationChain` so gas is sized against the real
|
|
33
|
+
* dollar cost (SDK 5.2). Excess is refunded by swapAndBurnGas to the UEA.
|
|
34
|
+
*/
|
|
29
35
|
const GAS_FEE_BUFFER_MULTIPLIER = BigInt(1000000);
|
|
30
36
|
// Minimal ABIs for Uniswap V3 pool price estimation
|
|
31
37
|
const UNISWAP_V3_POOL_SLOT0_ABI = [
|
|
@@ -125,7 +131,7 @@ function ensureErc20Allowance(ctx, evmClient, tokenAddress, spender, requiredAmo
|
|
|
125
131
|
// ============================================================================
|
|
126
132
|
// Outbound Gas Fee Query
|
|
127
133
|
// ============================================================================
|
|
128
|
-
function queryOutboundGasFee(ctx, prc20Token, gasLimit) {
|
|
134
|
+
function queryOutboundGasFee(ctx, prc20Token, gasLimit, destinationChain) {
|
|
129
135
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
130
136
|
var _a, _b;
|
|
131
137
|
const gatewayPcAddress = (0, helpers_1.getUniversalGatewayPCAddress)();
|
|
@@ -174,9 +180,32 @@ function queryOutboundGasFee(ctx, prc20Token, gasLimit) {
|
|
|
174
180
|
(0, context_1.printLog)(ctx, `queryOutboundGasFee — [step 3] FAILED: ${err instanceof Error ? err.message : String(err)}`);
|
|
175
181
|
throw err;
|
|
176
182
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
183
|
+
let nativeValueForGas;
|
|
184
|
+
let sizing;
|
|
185
|
+
if (destinationChain !== undefined) {
|
|
186
|
+
try {
|
|
187
|
+
sizing = yield (0, gas_usd_sizer_1.sizeOutboundGas)(ctx, {
|
|
188
|
+
gasFee,
|
|
189
|
+
originChain: ctx.universalSigner.account.chain,
|
|
190
|
+
destinationChain,
|
|
191
|
+
});
|
|
192
|
+
// All categories — A, B, and C — return the sizer's calibrated gas leg.
|
|
193
|
+
// R3 consumers additionally bump `nativeValueForGas` by `overflowNativePc`
|
|
194
|
+
// when category === 'C' (see route-handlers.executeCeaToPush).
|
|
195
|
+
nativeValueForGas = sizing.gasLegNativePc + protocolFee;
|
|
196
|
+
(0, context_1.printLog)(ctx, `queryOutboundGasFee — [step 5] sizer: category=${sizing.category}, gasUsd=${sizing.gasUsd}, ` +
|
|
197
|
+
`gasLegNativePc=${sizing.gasLegNativePc}, overflowNativePc=${sizing.overflowNativePc}, nativeValueForGas=${nativeValueForGas}`);
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
(0, context_1.printLog)(ctx, `queryOutboundGasFee — [step 5] sizer failed (${err instanceof Error ? err.message : String(err)}); falling back to 1M buffer`);
|
|
201
|
+
nativeValueForGas = protocolFee + gasFee * GAS_FEE_BUFFER_MULTIPLIER;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
nativeValueForGas = protocolFee + gasFee * GAS_FEE_BUFFER_MULTIPLIER;
|
|
206
|
+
(0, context_1.printLog)(ctx, `queryOutboundGasFee — [step 5] no destinationChain provided; legacy 1M buffer: nativeValueForGas=${nativeValueForGas}`);
|
|
207
|
+
}
|
|
208
|
+
return { gasToken, gasFee, protocolFee, nativeValueForGas, gasPrice, universalCoreAddress, sizing };
|
|
180
209
|
});
|
|
181
210
|
}
|
|
182
211
|
// ============================================================================
|
|
@@ -285,7 +314,7 @@ function balanceFallback(balance, divisor, reserve) {
|
|
|
285
314
|
// ============================================================================
|
|
286
315
|
// Rescue Gas Fee Query
|
|
287
316
|
// ============================================================================
|
|
288
|
-
function queryRescueGasFee(ctx, prc20Token) {
|
|
317
|
+
function queryRescueGasFee(ctx, prc20Token, destinationChain) {
|
|
289
318
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
290
319
|
const gatewayPcAddress = (0, helpers_1.getUniversalGatewayPCAddress)();
|
|
291
320
|
(0, context_1.printLog)(ctx, `queryRescueGasFee — inputs: gateway=${gatewayPcAddress}, prc20Token=${prc20Token}`);
|
|
@@ -324,9 +353,28 @@ function queryRescueGasFee(ctx, prc20Token) {
|
|
|
324
353
|
(0, context_1.printLog)(ctx, `queryRescueGasFee — FAILED: ${err instanceof Error ? err.message : String(err)}`);
|
|
325
354
|
throw err;
|
|
326
355
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
356
|
+
let nativeValueForGas;
|
|
357
|
+
let sizing;
|
|
358
|
+
if (destinationChain !== undefined) {
|
|
359
|
+
try {
|
|
360
|
+
sizing = yield (0, gas_usd_sizer_1.sizeOutboundGas)(ctx, {
|
|
361
|
+
gasFee,
|
|
362
|
+
originChain: ctx.universalSigner.account.chain,
|
|
363
|
+
destinationChain,
|
|
364
|
+
});
|
|
365
|
+
nativeValueForGas = sizing.gasLegNativePc;
|
|
366
|
+
(0, context_1.printLog)(ctx, `queryRescueGasFee — sizer: category=${sizing.category}, gasUsd=${sizing.gasUsd}, nativeValueForGas=${nativeValueForGas}`);
|
|
367
|
+
}
|
|
368
|
+
catch (err) {
|
|
369
|
+
(0, context_1.printLog)(ctx, `queryRescueGasFee — sizer failed (${err instanceof Error ? err.message : String(err)}); falling back to 1M buffer`);
|
|
370
|
+
nativeValueForGas = gasFee * GAS_FEE_BUFFER_MULTIPLIER;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
nativeValueForGas = gasFee * GAS_FEE_BUFFER_MULTIPLIER;
|
|
375
|
+
(0, context_1.printLog)(ctx, `queryRescueGasFee — no destinationChain provided; legacy 1M buffer: nativeValueForGas=${nativeValueForGas}`);
|
|
376
|
+
}
|
|
377
|
+
return { gasToken, gasFee, rescueGasLimit, gasPrice, nativeValueForGas, sizing };
|
|
330
378
|
});
|
|
331
379
|
}
|
|
332
380
|
// ============================================================================
|
|
@@ -335,7 +383,7 @@ function queryRescueGasFee(ctx, prc20Token) {
|
|
|
335
383
|
function calculateNativeAmountForDeposit(ctx, chain, requiredFunds, ueaBalance) {
|
|
336
384
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
337
385
|
var _a, _b;
|
|
338
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.
|
|
386
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_102_01);
|
|
339
387
|
const oneUsd = utils_1.Utils.helpers.parseUnits('1', 8);
|
|
340
388
|
const maxUsd = utils_1.Utils.helpers.parseUnits('1000', 8);
|
|
341
389
|
const deficit = requiredFunds > ueaBalance ? requiredFunds - ueaBalance : BigInt(0);
|
|
@@ -380,7 +428,7 @@ function calculateNativeAmountForDeposit(ctx, chain, requiredFunds, ueaBalance)
|
|
|
380
428
|
let nativeAmount = (depositUsd * oneNativeUnit + (nativeTokenUsdPrice - BigInt(1))) /
|
|
381
429
|
nativeTokenUsdPrice;
|
|
382
430
|
nativeAmount = nativeAmount + BigInt(1);
|
|
383
|
-
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.
|
|
431
|
+
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_102_02, nativeAmount);
|
|
384
432
|
return nativeAmount;
|
|
385
433
|
});
|
|
386
434
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { CHAIN } from '../../constants/enums';
|
|
2
|
+
import type { OrchestratorContext } from './context';
|
|
3
|
+
export type GasSizingCategory = 'A' | 'B' | 'C';
|
|
4
|
+
export interface GasSizingInput {
|
|
5
|
+
/** Raw gasFee from getOutboundTxGasAndFees (in gasToken units, e.g., pETH 18d) */
|
|
6
|
+
gasFee: bigint;
|
|
7
|
+
/** Origin chain the user signed from — picks the PC/USD oracle pool */
|
|
8
|
+
originChain: CHAIN;
|
|
9
|
+
/**
|
|
10
|
+
* Destination chain whose native asset is represented by gasToken on PC.
|
|
11
|
+
* Used to price gasFee in USD via PriceFetch (Chainlink ETH/USD, Pyth SOL/USD).
|
|
12
|
+
*/
|
|
13
|
+
destinationChain: CHAIN;
|
|
14
|
+
}
|
|
15
|
+
export interface GasSizingDecision {
|
|
16
|
+
category: GasSizingCategory;
|
|
17
|
+
/** Native PC to send as msg.value for the sendUniversalTxOutbound leg */
|
|
18
|
+
gasLegNativePc: bigint;
|
|
19
|
+
/** Native PC to bridge as funds alongside (only > 0 when category === 'C') */
|
|
20
|
+
overflowNativePc: bigint;
|
|
21
|
+
/** Diagnostic — raw gas cost in USD (1e8) */
|
|
22
|
+
gasUsd: bigint;
|
|
23
|
+
/** Diagnostic — portion to bridge in USD (1e8) */
|
|
24
|
+
overflowUsd: bigint;
|
|
25
|
+
}
|
|
26
|
+
export declare function sizeOutboundGas(ctx: OrchestratorContext, input: GasSizingInput): Promise<GasSizingDecision>;
|
|
27
|
+
export interface R1SizingInput {
|
|
28
|
+
/** Push-chain gas cost in UPC wei (18 decimals) */
|
|
29
|
+
pushGasFeeWei: bigint;
|
|
30
|
+
/** Origin chain — picks the WPC/USD oracle pool */
|
|
31
|
+
originChain: CHAIN;
|
|
32
|
+
}
|
|
33
|
+
export interface R1SizingDecision {
|
|
34
|
+
category: GasSizingCategory;
|
|
35
|
+
/** Push-gas cost in USD (8 decimals) */
|
|
36
|
+
pushGasUsd: bigint;
|
|
37
|
+
/** USD the SDK should request on the origin gateway (8 decimals) */
|
|
38
|
+
paddedDepositUsd: bigint;
|
|
39
|
+
}
|
|
40
|
+
export declare function sizeR1PushGas(ctx: OrchestratorContext, input: R1SizingInput): Promise<R1SizingDecision>;
|
|
41
|
+
/**
|
|
42
|
+
* Given gasFee (in gasToken units) and destination VM, return gasFee in USD
|
|
43
|
+
* (8 decimals). Exposed for direct use in places that already have the
|
|
44
|
+
* destUsdPrice cached (e.g., rescue flows).
|
|
45
|
+
*/
|
|
46
|
+
export declare function computeGasUsd(ctx: OrchestratorContext, gasFee: bigint, destinationChain: CHAIN): Promise<bigint>;
|
|
47
|
+
/** Test-only export of thresholds. @internal */
|
|
48
|
+
export declare const __THRESHOLDS: {
|
|
49
|
+
ONE_USD_8D: bigint;
|
|
50
|
+
TEN_USD_8D: bigint;
|
|
51
|
+
};
|
|
52
|
+
/** Alias for backward-compat at call sites. */
|
|
53
|
+
export { getPcUsdPrice } from './pc-usd-oracle';
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getPcUsdPrice = exports.__THRESHOLDS = void 0;
|
|
4
|
+
exports.sizeOutboundGas = sizeOutboundGas;
|
|
5
|
+
exports.sizeR1PushGas = sizeR1PushGas;
|
|
6
|
+
exports.computeGasUsd = computeGasUsd;
|
|
7
|
+
const tslib_1 = require("tslib");
|
|
8
|
+
/**
|
|
9
|
+
* Gas sizing for outbound transactions (Routes 2/3/4).
|
|
10
|
+
*
|
|
11
|
+
* Categorizes destination gas cost into three buckets per the SDK 5.2 spec:
|
|
12
|
+
* - A: gasUsd < $1 → floor to $1 worth of native PC
|
|
13
|
+
* - B: $1 ≤ gasUsd ≤ $10 → happy path, use gasFee as sized
|
|
14
|
+
* - C: gasUsd > $10 → split: $10 gas leg + overflow bridged as funds
|
|
15
|
+
*
|
|
16
|
+
* Output amounts are in native PC (nPUSH, 18 decimals) because that's what
|
|
17
|
+
* `sendUniversalTxOutbound` consumes as `msg.value` before swapAndBurnGas
|
|
18
|
+
* swaps it into the destination gas token (pETH, pSOL, …).
|
|
19
|
+
*/
|
|
20
|
+
const viem_1 = require("viem");
|
|
21
|
+
const enums_1 = require("../../constants/enums");
|
|
22
|
+
const chain_1 = require("../../constants/chain");
|
|
23
|
+
const price_fetch_1 = require("../../price-fetch/price-fetch");
|
|
24
|
+
const context_1 = require("./context");
|
|
25
|
+
const pc_usd_oracle_1 = require("./pc-usd-oracle");
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// Thresholds (USD, 8 decimals)
|
|
28
|
+
// ============================================================================
|
|
29
|
+
const ONE_USD_8D = (0, viem_1.parseUnits)('1', 8); // 100_000_000
|
|
30
|
+
const TEN_USD_8D = (0, viem_1.parseUnits)('10', 8); // 1_000_000_000
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// Public API
|
|
33
|
+
// ============================================================================
|
|
34
|
+
function sizeOutboundGas(ctx, input) {
|
|
35
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
const { gasFee, originChain, destinationChain } = input;
|
|
37
|
+
// 1) Price gasFee in USD (8 decimals). gasFee is denominated in the
|
|
38
|
+
// destination native (pETH = ETH value, pSOL = SOL value). The price
|
|
39
|
+
// feed lives on the *origin* side (origin gateway's Chainlink/Pyth),
|
|
40
|
+
// but we reuse the same feed via PriceFetch — the asset being priced
|
|
41
|
+
// is ETH or SOL, not the route.
|
|
42
|
+
const destVm = chain_1.CHAIN_INFO[destinationChain].vm;
|
|
43
|
+
const priceSourceChain = destVm === enums_1.VM.SVM ? enums_1.CHAIN.SOLANA_DEVNET : enums_1.CHAIN.ETHEREUM_SEPOLIA;
|
|
44
|
+
const destDecimals = destVm === enums_1.VM.SVM ? 9 : 18;
|
|
45
|
+
let destUsdPrice;
|
|
46
|
+
try {
|
|
47
|
+
destUsdPrice = yield new price_fetch_1.PriceFetch(ctx.rpcUrls).getPrice(priceSourceChain);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
(0, context_1.printLog)(ctx, `sizeOutboundGas — PriceFetch.getPrice failed (${err instanceof Error ? err.message : String(err)}); treating as Case B passthrough`);
|
|
51
|
+
// Degrade gracefully: assume the raw gasFee is already a sane size and
|
|
52
|
+
// convert 1:1 to native PC. Callers keep their existing fallback logic.
|
|
53
|
+
return passthroughAsCaseB(ctx, gasFee, originChain);
|
|
54
|
+
}
|
|
55
|
+
const oneDestNativeUnit = (0, viem_1.parseUnits)('1', destDecimals);
|
|
56
|
+
const gasUsd = (gasFee * destUsdPrice) / oneDestNativeUnit;
|
|
57
|
+
(0, context_1.printLog)(ctx, `sizeOutboundGas — gasFee=${gasFee.toString()} ${destVm === enums_1.VM.SVM ? 'pSOL' : 'pETH'} (${destDecimals}d), ` +
|
|
58
|
+
`destUsdPrice=${destUsdPrice.toString()} (1e8), gasUsd=${gasUsd.toString()} (1e8)`);
|
|
59
|
+
// 2) Categorize and compute target USD for each leg.
|
|
60
|
+
let category;
|
|
61
|
+
let gasLegUsd;
|
|
62
|
+
let overflowUsd;
|
|
63
|
+
if (gasUsd < ONE_USD_8D) {
|
|
64
|
+
category = 'A';
|
|
65
|
+
gasLegUsd = ONE_USD_8D;
|
|
66
|
+
overflowUsd = BigInt(0);
|
|
67
|
+
}
|
|
68
|
+
else if (gasUsd <= TEN_USD_8D) {
|
|
69
|
+
category = 'B';
|
|
70
|
+
gasLegUsd = gasUsd;
|
|
71
|
+
overflowUsd = BigInt(0);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
category = 'C';
|
|
75
|
+
gasLegUsd = TEN_USD_8D;
|
|
76
|
+
overflowUsd = gasUsd - TEN_USD_8D;
|
|
77
|
+
}
|
|
78
|
+
// 3) Convert USD targets back to native PC via the per-route WPC/stable oracle.
|
|
79
|
+
const gasLegNativePc = yield (0, pc_usd_oracle_1.usdToPc)(ctx, gasLegUsd, originChain);
|
|
80
|
+
const overflowNativePc = overflowUsd > BigInt(0)
|
|
81
|
+
? yield (0, pc_usd_oracle_1.usdToPc)(ctx, overflowUsd, originChain)
|
|
82
|
+
: BigInt(0);
|
|
83
|
+
(0, context_1.printLog)(ctx, `sizeOutboundGas — category=${category}, gasLegUsd=${gasLegUsd.toString()}, ` +
|
|
84
|
+
`overflowUsd=${overflowUsd.toString()}, gasLegNativePc=${gasLegNativePc.toString()}, ` +
|
|
85
|
+
`overflowNativePc=${overflowNativePc.toString()}`);
|
|
86
|
+
return {
|
|
87
|
+
category,
|
|
88
|
+
gasLegNativePc,
|
|
89
|
+
overflowNativePc,
|
|
90
|
+
gasUsd,
|
|
91
|
+
overflowUsd,
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
// ============================================================================
|
|
96
|
+
// Internal helpers
|
|
97
|
+
// ============================================================================
|
|
98
|
+
/**
|
|
99
|
+
* When the USD price feed fails, fall back to a pass-through that keeps the
|
|
100
|
+
* Orchestrator alive: return the raw gasFee as a Case B result, converting
|
|
101
|
+
* through the existing PC/USD oracle (or its hardcoded fallback).
|
|
102
|
+
*/
|
|
103
|
+
function passthroughAsCaseB(ctx, gasFee, originChain) {
|
|
104
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
105
|
+
const oneUsd = ONE_USD_8D;
|
|
106
|
+
const gasLegNativePc = yield (0, pc_usd_oracle_1.usdToPc)(ctx, oneUsd, originChain);
|
|
107
|
+
void gasFee;
|
|
108
|
+
return {
|
|
109
|
+
category: 'B',
|
|
110
|
+
gasLegNativePc,
|
|
111
|
+
overflowNativePc: BigInt(0),
|
|
112
|
+
gasUsd: oneUsd,
|
|
113
|
+
overflowUsd: BigInt(0),
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function sizeR1PushGas(ctx, input) {
|
|
118
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
119
|
+
const { pushGasFeeWei, originChain } = input;
|
|
120
|
+
// 1) Convert pushGasFeeWei (UPC wei, 18d) → USD (8d) via per-route oracle.
|
|
121
|
+
const pcUsdPrice = yield (0, pc_usd_oracle_1.getPcUsdPrice)(ctx, originChain);
|
|
122
|
+
const onePcUnit = (0, viem_1.parseUnits)('1', 18);
|
|
123
|
+
const pushGasUsd = (pushGasFeeWei * pcUsdPrice) / onePcUnit;
|
|
124
|
+
(0, context_1.printLog)(ctx, `sizeR1PushGas — pushGasFeeWei=${pushGasFeeWei.toString()} UPC (18d), ` +
|
|
125
|
+
`pcUsdPrice=${pcUsdPrice.toString()} (1e8), pushGasUsd=${pushGasUsd.toString()} (1e8)`);
|
|
126
|
+
// 2) Bucket.
|
|
127
|
+
let category;
|
|
128
|
+
let paddedDepositUsd;
|
|
129
|
+
if (pushGasUsd < ONE_USD_8D) {
|
|
130
|
+
category = 'A';
|
|
131
|
+
paddedDepositUsd = ONE_USD_8D;
|
|
132
|
+
}
|
|
133
|
+
else if (pushGasUsd <= TEN_USD_8D) {
|
|
134
|
+
category = 'B';
|
|
135
|
+
paddedDepositUsd = pushGasUsd;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
category = 'C';
|
|
139
|
+
paddedDepositUsd = pushGasUsd;
|
|
140
|
+
}
|
|
141
|
+
(0, context_1.printLog)(ctx, `sizeR1PushGas — category=${category}, paddedDepositUsd=${paddedDepositUsd.toString()} (1e8)`);
|
|
142
|
+
return { category, pushGasUsd, paddedDepositUsd };
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Given gasFee (in gasToken units) and destination VM, return gasFee in USD
|
|
147
|
+
* (8 decimals). Exposed for direct use in places that already have the
|
|
148
|
+
* destUsdPrice cached (e.g., rescue flows).
|
|
149
|
+
*/
|
|
150
|
+
function computeGasUsd(ctx, gasFee, destinationChain) {
|
|
151
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
152
|
+
const destVm = chain_1.CHAIN_INFO[destinationChain].vm;
|
|
153
|
+
const priceSourceChain = destVm === enums_1.VM.SVM ? enums_1.CHAIN.SOLANA_DEVNET : enums_1.CHAIN.ETHEREUM_SEPOLIA;
|
|
154
|
+
const destDecimals = destVm === enums_1.VM.SVM ? 9 : 18;
|
|
155
|
+
const destUsdPrice = yield new price_fetch_1.PriceFetch(ctx.rpcUrls).getPrice(priceSourceChain);
|
|
156
|
+
const oneUnit = (0, viem_1.parseUnits)('1', destDecimals);
|
|
157
|
+
return (gasFee * destUsdPrice) / oneUnit;
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/** Test-only export of thresholds. @internal */
|
|
161
|
+
exports.__THRESHOLDS = { ONE_USD_8D, TEN_USD_8D };
|
|
162
|
+
/** Alias for backward-compat at call sites. */
|
|
163
|
+
var pc_usd_oracle_2 = require("./pc-usd-oracle");
|
|
164
|
+
Object.defineProperty(exports, "getPcUsdPrice", { enumerable: true, get: function () { return pc_usd_oracle_2.getPcUsdPrice; } });
|
|
165
|
+
//# sourceMappingURL=gas-usd-sizer.js.map
|
|
@@ -129,6 +129,8 @@ function bigintReplacer(_key, value) {
|
|
|
129
129
|
// Params Conversion
|
|
130
130
|
// ============================================================================
|
|
131
131
|
function toExecuteParams(params) {
|
|
132
|
+
// Post-route-detector, ChainTarget.address has already been normalized to
|
|
133
|
+
// 0x-prefixed hex for SVM targets (see route-detector.ts), so the cast is safe.
|
|
132
134
|
const to = typeof params.to === 'string'
|
|
133
135
|
? params.to
|
|
134
136
|
: params.to.address;
|