@pushchain/core 5.1.16 → 5.1.18
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/package.json +1 -1
- package/src/lib/constants/index.d.ts +1 -1
- package/src/lib/constants/index.js +2 -1
- package/src/lib/constants/selectors.d.ts +8 -0
- package/src/lib/constants/selectors.js +9 -1
- package/src/lib/formatters.d.ts +1 -0
- package/src/lib/formatters.js +32 -0
- package/src/lib/orchestrator/internals/cascade.d.ts +8 -1
- package/src/lib/orchestrator/internals/cascade.js +486 -143
- package/src/lib/orchestrator/internals/error-decoder.d.ts +2 -6
- package/src/lib/orchestrator/internals/error-decoder.js +10 -10
- package/src/lib/orchestrator/internals/errors.d.ts +1 -1
- package/src/lib/orchestrator/internals/errors.js +7 -4
- package/src/lib/orchestrator/internals/execute-standard.js +7 -6
- package/src/lib/orchestrator/internals/gas-calculator.js +78 -11
- package/src/lib/orchestrator/internals/helpers.d.ts +2 -1
- package/src/lib/orchestrator/internals/helpers.js +13 -11
- package/src/lib/orchestrator/internals/outbound-sync.d.ts +1 -0
- package/src/lib/orchestrator/internals/outbound-sync.js +93 -37
- package/src/lib/orchestrator/internals/preflight.d.ts +9 -23
- package/src/lib/orchestrator/internals/preflight.js +22 -48
- package/src/lib/orchestrator/internals/response-builder.js +23 -7
- package/src/lib/orchestrator/internals/route-handlers.js +34 -49
- package/src/lib/orchestrator/internals/tx-transformer.js +2 -1
- package/src/lib/orchestrator/orchestrator.d.ts +7 -1
- package/src/lib/orchestrator/orchestrator.js +40 -2
- package/src/lib/orchestrator/orchestrator.types.d.ts +4 -14
- package/src/lib/progress-hook/progress-hook.js +66 -16
- package/src/lib/progress-hook/progress-hook.types.d.ts +4 -1
- package/src/lib/progress-hook/progress-hook.types.js +8 -0
- package/src/lib/push-chain/push-chain.d.ts +11 -1
- package/src/lib/push-chain/push-chain.js +2 -2
- package/src/lib/universal-tx-detector/cascade.js +14 -4
- package/src/lib/universal-tx-detector/child-inbounds.js +9 -1
- package/src/lib/universal-tx-detector/detector.js +9 -3
- package/src/lib/universal-tx-detector/normalize.d.ts +42 -0
- package/src/lib/universal-tx-detector/normalize.js +127 -0
- package/src/lib/utils/external-tx-hash.d.ts +37 -0
- package/src/lib/utils/external-tx-hash.js +62 -0
|
@@ -23,7 +23,7 @@ import { type PreflightPathTag } from './errors';
|
|
|
23
23
|
export interface RunPreflightOpts {
|
|
24
24
|
ctx: OrchestratorContext;
|
|
25
25
|
ueaAddress: `0x${string}`;
|
|
26
|
-
/** Effective UEA balance in wei
|
|
26
|
+
/** Effective UEA balance in native PC wei (already includes fresh-wallet prediction). */
|
|
27
27
|
ueaBalance: bigint;
|
|
28
28
|
/** Buffered pool quote (pre-clamp) — what the SDK would actually attempt. */
|
|
29
29
|
requiredValue: bigint;
|
|
@@ -36,45 +36,31 @@ export interface RunPreflightOpts {
|
|
|
36
36
|
prc20Balance?: bigint;
|
|
37
37
|
/** Cascade-only: identifies which segment failed. */
|
|
38
38
|
segmentIndex?: number;
|
|
39
|
-
/**
|
|
40
|
-
* Per-call opt-out (`params.options.allowUnderfundedSwap`). When `true`,
|
|
41
|
-
* pre-flight logs the shortfall but does NOT fire 203-04 or throw —
|
|
42
|
-
* caller can fall back to the legacy clamp-and-refund branch.
|
|
43
|
-
*/
|
|
44
|
-
allowUnderfundedSwap?: boolean;
|
|
45
39
|
}
|
|
46
40
|
export type PreflightResult = {
|
|
47
41
|
ok: true;
|
|
48
42
|
/** What `nativeValueForGas` should be (== requiredValue when sufficient). */
|
|
49
43
|
adjustedValue: bigint;
|
|
50
|
-
} | {
|
|
51
|
-
ok: false;
|
|
52
|
-
/** Set when allowUnderfundedSwap=true: the legacy clamped value. */
|
|
53
|
-
legacyClampedValue: bigint;
|
|
54
44
|
};
|
|
55
45
|
/**
|
|
56
46
|
* Pre-flight check. PRC-20 balance is checked before the native check —
|
|
57
47
|
* a missing burn token fails before the gas-balance check, so the user
|
|
58
|
-
* sees the actionable PRC-20 shortfall instead of a stale
|
|
59
|
-
*
|
|
60
|
-
* Returns a result object instead of throwing for the legacy opt-out
|
|
61
|
-
* path. The throw happens here (not in the caller) for the default
|
|
62
|
-
* `allowUnderfundedSwap=false` case so all 6 paths share one throw site.
|
|
48
|
+
* sees the actionable PRC-20 shortfall instead of a stale native PC error.
|
|
63
49
|
*/
|
|
64
50
|
export declare function runPreflight(opts: RunPreflightOpts): PreflightResult;
|
|
65
51
|
/**
|
|
66
52
|
* SVM-only telemetry threshold. Buffered pool quotes above this value
|
|
67
|
-
* fire `SEND-TX-203-05` (single-route)
|
|
68
|
-
* The threshold is for
|
|
69
|
-
*
|
|
70
|
-
* number.
|
|
53
|
+
* fire `SEND-TX-203-05` (R2 single-route), `SEND-TX-303-06` (R3
|
|
54
|
+
* single-route), or `SEND-TX-003-05` (cascade). The threshold is for
|
|
55
|
+
* visibility, not truncation — pre-flight handles drain protection.
|
|
56
|
+
* v2 may add a hard cap once telemetry justifies a number.
|
|
71
57
|
*/
|
|
72
58
|
export declare const SVM_NATIVE_VALUE_WARN_THRESHOLD: bigint;
|
|
73
59
|
/**
|
|
74
60
|
* Fire the SVM warn-threshold hook + log line if the buffered quote
|
|
75
61
|
* exceeds the threshold. Non-blocking; `nativeValueForGas` is not
|
|
76
|
-
* truncated by the caller. The hook ID switches
|
|
77
|
-
*
|
|
78
|
-
*
|
|
62
|
+
* truncated by the caller. The hook ID switches between buckets so
|
|
63
|
+
* each stream stays self-consistent within its convention (R2 → 203,
|
|
64
|
+
* R3 → 303, cascade → 003).
|
|
79
65
|
*/
|
|
80
66
|
export declare function maybeFireSvmWarnThreshold(ctx: OrchestratorContext, bufferedQuote: bigint, gasToken: `0x${string}`, pathTag: PreflightPathTag): void;
|
|
@@ -26,41 +26,29 @@ exports.maybeFireSvmWarnThreshold = maybeFireSvmWarnThreshold;
|
|
|
26
26
|
const context_1 = require("./context");
|
|
27
27
|
const progress_hook_types_1 = require("../../progress-hook/progress-hook.types");
|
|
28
28
|
const errors_1 = require("./errors");
|
|
29
|
-
/**
|
|
30
|
-
* Internal: compute the legacy clamp value (matches the pre-existing
|
|
31
|
-
* branches in route-handlers.ts:643-659 / :968-980 / :1396-1412).
|
|
32
|
-
* Returned only when `allowUnderfundedSwap=true`.
|
|
33
|
-
*/
|
|
34
|
-
function legacyClamp(ueaBalance, requiredValue, gasReserve) {
|
|
35
|
-
if (ueaBalance >= requiredValue + gasReserve)
|
|
36
|
-
return requiredValue;
|
|
37
|
-
if (ueaBalance > gasReserve)
|
|
38
|
-
return ueaBalance - gasReserve;
|
|
39
|
-
if (ueaBalance > BigInt(0))
|
|
40
|
-
return ueaBalance < requiredValue ? ueaBalance : requiredValue;
|
|
41
|
-
return BigInt(0);
|
|
42
|
-
}
|
|
43
29
|
/**
|
|
44
30
|
* Pre-flight check. PRC-20 balance is checked before the native check —
|
|
45
31
|
* a missing burn token fails before the gas-balance check, so the user
|
|
46
|
-
* sees the actionable PRC-20 shortfall instead of a stale
|
|
47
|
-
*
|
|
48
|
-
* Returns a result object instead of throwing for the legacy opt-out
|
|
49
|
-
* path. The throw happens here (not in the caller) for the default
|
|
50
|
-
* `allowUnderfundedSwap=false` case so all 6 paths share one throw site.
|
|
32
|
+
* sees the actionable PRC-20 shortfall instead of a stale native PC error.
|
|
51
33
|
*/
|
|
52
34
|
function runPreflight(opts) {
|
|
53
|
-
const { ctx, ueaAddress, ueaBalance, requiredValue, gasReserve, pathTag, burnToken, burnAmount, prc20Balance, segmentIndex,
|
|
54
|
-
//
|
|
55
|
-
//
|
|
35
|
+
const { ctx, ueaAddress, ueaBalance, requiredValue, gasReserve, pathTag, burnToken, burnAmount, prc20Balance, segmentIndex, } = opts;
|
|
36
|
+
// Each route bucket gets its own preflight IDs so hook streams stay
|
|
37
|
+
// self-consistent within their convention (R2 → 203-xx, R3 → 303-xx,
|
|
38
|
+
// cascade → 003-xx). The three hook formatters share an identical
|
|
56
39
|
// signature, so the runtime branching is just an ID swap at each fire site.
|
|
57
40
|
const isCascade = pathTag === 'CASCADE';
|
|
41
|
+
const isR3 = pathTag === 'R3_EVM' || pathTag === 'R3_SVM';
|
|
58
42
|
const HOOK_PRE_INFO = isCascade
|
|
59
43
|
? progress_hook_types_1.PROGRESS_HOOK.SEND_TX_003_03
|
|
60
|
-
:
|
|
44
|
+
: isR3
|
|
45
|
+
? progress_hook_types_1.PROGRESS_HOOK.SEND_TX_303_04
|
|
46
|
+
: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_203_03;
|
|
61
47
|
const HOOK_PRE_FAIL = isCascade
|
|
62
48
|
? progress_hook_types_1.PROGRESS_HOOK.SEND_TX_003_04
|
|
63
|
-
:
|
|
49
|
+
: isR3
|
|
50
|
+
? progress_hook_types_1.PROGRESS_HOOK.SEND_TX_303_05
|
|
51
|
+
: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_203_04;
|
|
64
52
|
// 1. PRC-20 burn-balance check (skipped when burnAmount = 0 — R3 paths
|
|
65
53
|
// structurally hold zero of the source-chain native PRC-20; see plan §9 #4).
|
|
66
54
|
if (burnAmount && burnAmount > BigInt(0) && burnToken) {
|
|
@@ -69,15 +57,6 @@ function runPreflight(opts) {
|
|
|
69
57
|
(0, context_1.fireProgressHook)(ctx, HOOK_PRE_INFO, burnAmount, onHand, sufficient, ueaAddress, pathTag, { kind: 'PRC20', burnToken, segmentIndex });
|
|
70
58
|
if (!sufficient) {
|
|
71
59
|
const shortfall = burnAmount - onHand;
|
|
72
|
-
if (allowUnderfundedSwap) {
|
|
73
|
-
(0, context_1.printLog)(ctx, `[preflight ${pathTag}] PRC-20 shortfall ${shortfall} of ${burnToken}; ` +
|
|
74
|
-
`allowUnderfundedSwap=true — proceeding with legacy clamp behaviour, ` +
|
|
75
|
-
`swap is expected to revert with InsufficientBalance(0xf4d678b8) on-chain.`);
|
|
76
|
-
return {
|
|
77
|
-
ok: false,
|
|
78
|
-
legacyClampedValue: legacyClamp(ueaBalance, requiredValue, gasReserve),
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
60
|
(0, context_1.fireProgressHook)(ctx, HOOK_PRE_FAIL, burnAmount, onHand, shortfall, ueaAddress, pathTag, { kind: 'PRC20', burnToken, segmentIndex });
|
|
82
61
|
throw new errors_1.InsufficientUEABalanceError({
|
|
83
62
|
required: burnAmount,
|
|
@@ -99,13 +78,6 @@ function runPreflight(opts) {
|
|
|
99
78
|
return { ok: true, adjustedValue: requiredValue };
|
|
100
79
|
}
|
|
101
80
|
const shortfall = totalRequired - ueaBalance;
|
|
102
|
-
if (allowUnderfundedSwap) {
|
|
103
|
-
const clamped = legacyClamp(ueaBalance, requiredValue, gasReserve);
|
|
104
|
-
(0, context_1.printLog)(ctx, `[preflight ${pathTag}] UPC shortfall ${shortfall} wei; ` +
|
|
105
|
-
`allowUnderfundedSwap=true — proceeding with legacy clamped value ${clamped}, ` +
|
|
106
|
-
`swap may revert inside Uniswap with Error("STF") if the clamp under-funds the pool quote.`);
|
|
107
|
-
return { ok: false, legacyClampedValue: clamped };
|
|
108
|
-
}
|
|
109
81
|
(0, context_1.fireProgressHook)(ctx, HOOK_PRE_FAIL, totalRequired, ueaBalance, shortfall, ueaAddress, pathTag, { kind: 'NATIVE', segmentIndex });
|
|
110
82
|
throw new errors_1.InsufficientUEABalanceError({
|
|
111
83
|
required: totalRequired,
|
|
@@ -119,25 +91,27 @@ function runPreflight(opts) {
|
|
|
119
91
|
}
|
|
120
92
|
/**
|
|
121
93
|
* SVM-only telemetry threshold. Buffered pool quotes above this value
|
|
122
|
-
* fire `SEND-TX-203-05` (single-route)
|
|
123
|
-
* The threshold is for
|
|
124
|
-
*
|
|
125
|
-
* number.
|
|
94
|
+
* fire `SEND-TX-203-05` (R2 single-route), `SEND-TX-303-06` (R3
|
|
95
|
+
* single-route), or `SEND-TX-003-05` (cascade). The threshold is for
|
|
96
|
+
* visibility, not truncation — pre-flight handles drain protection.
|
|
97
|
+
* v2 may add a hard cap once telemetry justifies a number.
|
|
126
98
|
*/
|
|
127
99
|
exports.SVM_NATIVE_VALUE_WARN_THRESHOLD = BigInt(5000) * BigInt(1e18);
|
|
128
100
|
/**
|
|
129
101
|
* Fire the SVM warn-threshold hook + log line if the buffered quote
|
|
130
102
|
* exceeds the threshold. Non-blocking; `nativeValueForGas` is not
|
|
131
|
-
* truncated by the caller. The hook ID switches
|
|
132
|
-
*
|
|
133
|
-
*
|
|
103
|
+
* truncated by the caller. The hook ID switches between buckets so
|
|
104
|
+
* each stream stays self-consistent within its convention (R2 → 203,
|
|
105
|
+
* R3 → 303, cascade → 003).
|
|
134
106
|
*/
|
|
135
107
|
function maybeFireSvmWarnThreshold(ctx, bufferedQuote, gasToken, pathTag) {
|
|
136
108
|
if (bufferedQuote <= exports.SVM_NATIVE_VALUE_WARN_THRESHOLD)
|
|
137
109
|
return;
|
|
138
110
|
const HOOK_WARN = pathTag === 'CASCADE'
|
|
139
111
|
? progress_hook_types_1.PROGRESS_HOOK.SEND_TX_003_05
|
|
140
|
-
:
|
|
112
|
+
: pathTag === 'R3_EVM' || pathTag === 'R3_SVM'
|
|
113
|
+
? progress_hook_types_1.PROGRESS_HOOK.SEND_TX_303_06
|
|
114
|
+
: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_203_05;
|
|
141
115
|
(0, context_1.fireProgressHook)(ctx, HOOK_WARN, bufferedQuote, exports.SVM_NATIVE_VALUE_WARN_THRESHOLD, gasToken, pathTag);
|
|
142
116
|
(0, context_1.printLog)(ctx, `[preflight ${pathTag}] SVM warn-threshold tripped: bufferedQuote=${bufferedQuote} > ` +
|
|
143
117
|
`${exports.SVM_NATIVE_VALUE_WARN_THRESHOLD} for gasToken=${gasToken} — pool may be skewed`);
|
|
@@ -536,7 +536,7 @@ function transformToUniversalTxResponse(ctx_1, tx_1) {
|
|
|
536
536
|
accessList: Array.isArray(tx.accessList) ? [...tx.accessList] : [],
|
|
537
537
|
// 6. Utilities
|
|
538
538
|
wait: (waitOptions) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
539
|
-
var _a, _b, _c, _d, _e, _f;
|
|
539
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
540
540
|
// For trackTransaction replays the tx is historical — cosmos already
|
|
541
541
|
// has the full graph indexed, so the 20s/30s initial-wait buffers
|
|
542
542
|
// designed for live sends are pure deadweight. Default them to 0 when
|
|
@@ -605,9 +605,17 @@ function transformToUniversalTxResponse(ctx_1, tx_1) {
|
|
|
605
605
|
timeout: outboundTimeoutMs,
|
|
606
606
|
progressHook: outboundTranslator,
|
|
607
607
|
});
|
|
608
|
-
|
|
609
|
-
//
|
|
610
|
-
|
|
608
|
+
// `outboundDetails.externalTxHash` is the raw `0x`-hex form (kept
|
|
609
|
+
// internally so the R3 inbound tracker below can query Cosmos with
|
|
610
|
+
// it via `waitForInboundPushTx → findChildUtxIdFromExternalTx`).
|
|
611
|
+
// For every USER-FACING surface (progress hook event + receipt) we
|
|
612
|
+
// want the chain-native form so consumers can paste it straight
|
|
613
|
+
// into an explorer / RPC: base58 for SVM, hex for EVM. Build a
|
|
614
|
+
// display copy and use it for both the hook and the receipt.
|
|
615
|
+
const displayExternalTxHash = (_f = (0, helpers_1.toExternalTxHashDisplay)(outboundDetails.destinationChain, outboundDetails.externalTxHash)) !== null && _f !== void 0 ? _f : outboundDetails.externalTxHash;
|
|
616
|
+
const userFacingOutboundDetails = Object.assign(Object.assign({}, outboundDetails), { externalTxHash: displayExternalTxHash });
|
|
617
|
+
emit(hooks.success(userFacingOutboundDetails));
|
|
618
|
+
baseReceipt = Object.assign(Object.assign({}, baseReceipt), { externalTxHash: displayExternalTxHash, externalChain: outboundDetails.destinationChain, externalExplorerUrl: outboundDetails.explorerUrl, externalRecipient: outboundDetails.recipient, externalAmount: outboundDetails.amount, externalAssetAddr: outboundDetails.assetAddr, externalStatus: 'success' });
|
|
611
619
|
// R3 round-trip: poll Push Chain for the inbound tx that the
|
|
612
620
|
// source-chain CEA's sendUniversalTxToUEA call produces. Correlate
|
|
613
621
|
// via the outbound external tx hash → child UTX id → child pcTx.
|
|
@@ -637,7 +645,7 @@ function transformToUniversalTxResponse(ctx_1, tx_1) {
|
|
|
637
645
|
}
|
|
638
646
|
else {
|
|
639
647
|
// status === 'failed' (terminal failure status from chain)
|
|
640
|
-
const failMsg = (
|
|
648
|
+
const failMsg = (_g = inbound.errorMessage) !== null && _g !== void 0 ? _g : 'inbound execution failed on Push Chain';
|
|
641
649
|
emit(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_399_02](failMsg, 'inbound', targetChain));
|
|
642
650
|
baseReceipt = Object.assign(Object.assign({}, baseReceipt), { pushInboundUtxId: inbound.childUtxId, pushInboundTxHash: inbound.pushTxHash || undefined, externalStatus: 'failed', externalError: failMsg });
|
|
643
651
|
}
|
|
@@ -669,8 +677,16 @@ function transformToUniversalTxResponse(ctx_1, tx_1) {
|
|
|
669
677
|
// observed tx hash is carried by OutboundFailedError — expose it
|
|
670
678
|
// as externalTxHash so consumers can link to the explorer.
|
|
671
679
|
const failedExternalTxHash = error instanceof outbound_sync_1.OutboundFailedError ? error.externalTxHash : undefined;
|
|
672
|
-
|
|
673
|
-
|
|
680
|
+
// Normalize to chain-native display form for SVM (base58); EVM hex
|
|
681
|
+
// passes through unchanged. `OutboundFailedError.destinationChain`
|
|
682
|
+
// is a chain namespace string (e.g., 'solana:devnet') — convert to
|
|
683
|
+
// the CHAIN enum via the same helper used in outbound-sync.
|
|
684
|
+
const failedChain = error instanceof outbound_sync_1.OutboundFailedError && error.destinationChain
|
|
685
|
+
? (_h = (0, helpers_1.chainFromNamespace)(error.destinationChain)) !== null && _h !== void 0 ? _h : undefined
|
|
686
|
+
: undefined;
|
|
687
|
+
const failedExternalTxHashDisplay = (_j = (0, helpers_1.toExternalTxHashDisplay)(failedChain, failedExternalTxHash)) !== null && _j !== void 0 ? _j : failedExternalTxHash;
|
|
688
|
+
baseReceipt = Object.assign(Object.assign(Object.assign({}, baseReceipt), { externalStatus: isTimeout ? 'timeout' : 'failed', externalError: errMsg }), (failedExternalTxHashDisplay
|
|
689
|
+
? { externalTxHash: failedExternalTxHashDisplay }
|
|
674
690
|
: {}));
|
|
675
691
|
// Outbound polling timed out or failed — return the annotated
|
|
676
692
|
// receipt without throwing. Push Chain tx succeeded, external
|
|
@@ -281,7 +281,7 @@ function executeMultiChain(ctx, params, executeFn) {
|
|
|
281
281
|
*/
|
|
282
282
|
function executeUoaToCea(ctx, params, executeFn) {
|
|
283
283
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
284
|
-
var _a, _b, _c
|
|
284
|
+
var _a, _b, _c;
|
|
285
285
|
const target = params.to;
|
|
286
286
|
const targetChain = target.chain;
|
|
287
287
|
const targetAddress = target.address;
|
|
@@ -430,12 +430,16 @@ function executeUoaToCea(ctx, params, executeFn) {
|
|
|
430
430
|
}
|
|
431
431
|
}
|
|
432
432
|
}
|
|
433
|
-
//
|
|
433
|
+
// estimateNativeValueForSwap applies the full 2.2x safety buffer
|
|
434
|
+
// internally (pool-slippage cushion + the 10% headroom that used to be
|
|
435
|
+
// multiplied here). Folded into one place so the function's cap branch
|
|
436
|
+
// bounds the final value — the previous outer ×110/100 on top of the
|
|
437
|
+
// inner cap broke preflight whenever the cap fired. Over-send is refunded
|
|
438
|
+
// by the contract.
|
|
434
439
|
let nativeValueForGas = BigInt(0);
|
|
435
440
|
if (universalCoreAddress && gasFee > BigInt(0)) {
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
(0, context_1.printLog)(ctx, `executeUoaToCea — nativeValueForGas: pool-quote=${estimated.toString()}, with 10% buffer=${nativeValueForGas.toString()}`);
|
|
441
|
+
nativeValueForGas = yield (0, gas_calculator_1.estimateNativeValueForSwap)(ctx, universalCoreAddress, gasToken, gasFee, effectiveBalance);
|
|
442
|
+
(0, context_1.printLog)(ctx, `executeUoaToCea — nativeValueForGas=${nativeValueForGas.toString()} (includes 2.2x buffer)`);
|
|
439
443
|
}
|
|
440
444
|
// Hard safety cap so a broken pool price can't drain the UEA.
|
|
441
445
|
if (nativeValueForGas > EVM_NATIVE_VALUE_SAFETY_CAP) {
|
|
@@ -457,8 +461,7 @@ function executeUoaToCea(ctx, params, executeFn) {
|
|
|
457
461
|
args: [ueaAddress],
|
|
458
462
|
});
|
|
459
463
|
}
|
|
460
|
-
|
|
461
|
-
const preflightR2Evm = (0, preflight_1.runPreflight)({
|
|
464
|
+
(0, preflight_1.runPreflight)({
|
|
462
465
|
ctx,
|
|
463
466
|
ueaAddress,
|
|
464
467
|
ueaBalance: effectiveBalance,
|
|
@@ -468,13 +471,8 @@ function executeUoaToCea(ctx, params, executeFn) {
|
|
|
468
471
|
burnToken: prc20Token,
|
|
469
472
|
burnAmount,
|
|
470
473
|
prc20Balance: prc20BalanceR2Evm,
|
|
471
|
-
allowUnderfundedSwap: allowUnderfundedR2Evm,
|
|
472
474
|
});
|
|
473
|
-
|
|
474
|
-
nativeValueForGas = preflightR2Evm.legacyClampedValue;
|
|
475
|
-
(0, context_1.printLog)(ctx, `executeUoaToCea — allowUnderfundedSwap=true; using legacy clamped value ${nativeValueForGas.toString()}`);
|
|
476
|
-
}
|
|
477
|
-
// ok=true → nativeValueForGas already covers required + reserve; no adjust needed.
|
|
475
|
+
// Preflight success means nativeValueForGas already covers required + reserve; no adjust needed.
|
|
478
476
|
// Build outbound multicalls (approve burn + sendUniversalTxOutbound with native value)
|
|
479
477
|
const outboundMulticalls = (0, payload_builders_1.buildOutboundApprovalAndCall)({
|
|
480
478
|
prc20Token,
|
|
@@ -536,7 +534,7 @@ function executeUoaToCea(ctx, params, executeFn) {
|
|
|
536
534
|
*/
|
|
537
535
|
function executeUoaToCeaSvm(ctx, params, target, executeFn) {
|
|
538
536
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
539
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
537
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
540
538
|
const targetChain = target.chain;
|
|
541
539
|
const targetAddress = target.address; // 0x-prefixed, 32 bytes
|
|
542
540
|
const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
|
|
@@ -648,8 +646,10 @@ function executeUoaToCeaSvm(ctx, params, target, executeFn) {
|
|
|
648
646
|
}
|
|
649
647
|
const ueaNonce = (!isUEADeployed || isNativePushEOASvm) ? BigInt(0) : yield (0, uea_manager_1.getUEANonce)(ctx, ueaAddress);
|
|
650
648
|
// R2 does NOT use Case A/B/C gas abstraction (scoped to R1 + R3 only).
|
|
651
|
-
// Size msg.value from the live WPC/gasToken Uniswap V3 pool quote
|
|
652
|
-
//
|
|
649
|
+
// Size msg.value from the live WPC/gasToken Uniswap V3 pool quote. The
|
|
650
|
+
// 2.2x safety buffer is applied inside estimateNativeValueForSwap (was
|
|
651
|
+
// split as inner 2x + outer 10% — combined to keep the cap branch
|
|
652
|
+
// mathematically correct). swapAndBurnGas refunds the excess as PC via
|
|
653
653
|
// refundUnusedGas.
|
|
654
654
|
//
|
|
655
655
|
// SVM pools (WPC/pSOL) are thinner than EVM pools so the pool-quote can
|
|
@@ -664,9 +664,10 @@ function executeUoaToCeaSvm(ctx, params, target, executeFn) {
|
|
|
664
664
|
const SVM_GAS_RESERVE = BigInt(3e18); // 3 UPC for outer-tx gas
|
|
665
665
|
let nativeValueForGas = BigInt(0);
|
|
666
666
|
if (universalCoreAddress && gasFee > BigInt(0)) {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
(0,
|
|
667
|
+
// 2.2x safety buffer is applied inside estimateNativeValueForSwap so
|
|
668
|
+
// the function's balance-cap branch bounds the final value correctly.
|
|
669
|
+
nativeValueForGas = yield (0, gas_calculator_1.estimateNativeValueForSwap)(ctx, universalCoreAddress, gasToken, gasFee, ueaBalance);
|
|
670
|
+
(0, context_1.printLog)(ctx, `executeUoaToCeaSvm — nativeValueForGas=${nativeValueForGas.toString()} (includes 2.2x buffer)`);
|
|
670
671
|
(0, preflight_1.maybeFireSvmWarnThreshold)(ctx, nativeValueForGas, gasToken, 'R2_SVM');
|
|
671
672
|
}
|
|
672
673
|
// Pre-flight: throws InsufficientUEABalanceError when UEA cannot cover
|
|
@@ -688,8 +689,7 @@ function executeUoaToCeaSvm(ctx, params, target, executeFn) {
|
|
|
688
689
|
args: [ueaAddress],
|
|
689
690
|
});
|
|
690
691
|
}
|
|
691
|
-
|
|
692
|
-
const preflightR2Svm = (0, preflight_1.runPreflight)({
|
|
692
|
+
(0, preflight_1.runPreflight)({
|
|
693
693
|
ctx,
|
|
694
694
|
ueaAddress,
|
|
695
695
|
ueaBalance,
|
|
@@ -699,12 +699,7 @@ function executeUoaToCeaSvm(ctx, params, target, executeFn) {
|
|
|
699
699
|
burnToken: prc20Token,
|
|
700
700
|
burnAmount,
|
|
701
701
|
prc20Balance: prc20BalanceR2Svm,
|
|
702
|
-
allowUnderfundedSwap: allowUnderfundedR2Svm,
|
|
703
702
|
});
|
|
704
|
-
if (!preflightR2Svm.ok) {
|
|
705
|
-
nativeValueForGas = preflightR2Svm.legacyClampedValue;
|
|
706
|
-
(0, context_1.printLog)(ctx, `executeUoaToCeaSvm — allowUnderfundedSwap=true; using legacy clamped value ${nativeValueForGas.toString()}`);
|
|
707
|
-
}
|
|
708
703
|
// --- Build Push Chain multicalls (approve + sendUniversalTxOutbound) ---
|
|
709
704
|
// Reuse the same builder as EVM — this part is identical
|
|
710
705
|
const pushChainMulticalls = (0, payload_builders_1.buildOutboundApprovalAndCall)({
|
|
@@ -769,7 +764,7 @@ function executeUoaToCeaSvm(ctx, params, target, executeFn) {
|
|
|
769
764
|
*/
|
|
770
765
|
function executeCeaToPush(ctx, params, executeFn) {
|
|
771
766
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
772
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
767
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
773
768
|
// 1. Validate and extract source chain
|
|
774
769
|
if (!((_a = params.from) === null || _a === void 0 ? void 0 : _a.chain)) {
|
|
775
770
|
throw new Error('Route 3 (CEA -> Push) requires from.chain to specify the source CEA chain');
|
|
@@ -903,8 +898,8 @@ function executeCeaToPush(ctx, params, executeFn) {
|
|
|
903
898
|
// so the inbound will arrive when the UEA nonce is already incremented.
|
|
904
899
|
pushPayload = (0, payload_builders_1.buildInboundUniversalPayload)(multicallPayload, { nonce: ueaNonce + BigInt(1) });
|
|
905
900
|
}
|
|
906
|
-
// Build sendUniversalTxToUEA self-call on CEA
|
|
907
|
-
//
|
|
901
|
+
// Build sendUniversalTxToUEA self-call on CEA. CEA self-calls must always
|
|
902
|
+
// use value=0; native sends spend from the CEA's existing balance.
|
|
908
903
|
// CEA internally calls gateway.sendUniversalTxFromCEA(...)
|
|
909
904
|
// Uses bridgeAmount (= burn amount deposited by Vault)
|
|
910
905
|
const sendUniversalTxCall = (0, payload_builders_1.buildSendUniversalTxToUEA)(ceaAddress, // to: CEA address (self-call)
|
|
@@ -929,13 +924,14 @@ function executeCeaToPush(ctx, params, executeFn) {
|
|
|
929
924
|
// tokens FROM the CEA back to Push Chain, not to round-trip them.
|
|
930
925
|
const prc20Token = (0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork);
|
|
931
926
|
const burnAmount = BigInt(0);
|
|
927
|
+
const outboundGasLimit = (_f = params.gasLimit) !== null && _f !== void 0 ? _f : selectors_1.DEFAULT_CEA_TO_PUSH_GAS_LIMIT;
|
|
932
928
|
(0, context_1.printLog)(ctx, `executeCeaToPush — prc20Token: ${prc20Token}, burnAmount: ${burnAmount.toString()}`);
|
|
933
929
|
// 9. Build outbound request (same structure as Route 2)
|
|
934
930
|
// target = CEA address (for self-execution), value = 0 in payload
|
|
935
931
|
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, // target: CEA address (to=CEA for self-execution)
|
|
936
932
|
prc20Token, // token: native PRC-20 for source chain (for namespace lookup)
|
|
937
933
|
burnAmount, // amount: 0 (payload-only, CEA uses its own balance)
|
|
938
|
-
|
|
934
|
+
outboundGasLimit, ceaPayload, // payload: ABI-encoded CEA multicall
|
|
939
935
|
ueaAddress // revertRecipient: UEA
|
|
940
936
|
);
|
|
941
937
|
(0, context_1.printLog)(ctx, `executeCeaToPush — outbound request: ${JSON.stringify({
|
|
@@ -957,10 +953,9 @@ function executeCeaToPush(ctx, params, executeFn) {
|
|
|
957
953
|
let gasToken = selectors_1.ZERO_ADDRESS;
|
|
958
954
|
let sizingDecisionR3;
|
|
959
955
|
if (prc20Token !== selectors_1.ZERO_ADDRESS) {
|
|
960
|
-
const gasLimit = outboundReq.gasLimit;
|
|
961
956
|
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_302_01, sourceChain);
|
|
962
957
|
try {
|
|
963
|
-
const result = yield (0, gas_calculator_1.queryOutboundGasFee)(ctx, prc20Token,
|
|
958
|
+
const result = yield (0, gas_calculator_1.queryOutboundGasFee)(ctx, prc20Token, outboundGasLimit, sourceChain);
|
|
964
959
|
gasToken = result.gasToken;
|
|
965
960
|
gasFee = result.gasFee;
|
|
966
961
|
protocolFeeR3 = result.protocolFee;
|
|
@@ -1040,20 +1035,14 @@ function executeCeaToPush(ctx, params, executeFn) {
|
|
|
1040
1035
|
// Pre-flight (R3 EVM): no PRC-20 burn check — `burnAmount = 0` makes this
|
|
1041
1036
|
// payload-only (UEA never holds the source-chain PRC-20; see plan §9 #4).
|
|
1042
1037
|
// Native UPC check still applies for the gas swap.
|
|
1043
|
-
|
|
1044
|
-
const preflightR3Evm = (0, preflight_1.runPreflight)({
|
|
1038
|
+
(0, preflight_1.runPreflight)({
|
|
1045
1039
|
ctx,
|
|
1046
1040
|
ueaAddress,
|
|
1047
1041
|
ueaBalance: effectiveBalance,
|
|
1048
1042
|
requiredValue: nativeValueForGas,
|
|
1049
1043
|
gasReserve: OUTBOUND_GAS_RESERVE_R3,
|
|
1050
1044
|
pathTag: 'R3_EVM',
|
|
1051
|
-
allowUnderfundedSwap: allowUnderfundedR3Evm,
|
|
1052
1045
|
});
|
|
1053
|
-
if (!preflightR3Evm.ok) {
|
|
1054
|
-
nativeValueForGas = preflightR3Evm.legacyClampedValue;
|
|
1055
|
-
(0, context_1.printLog)(ctx, `executeCeaToPush — allowUnderfundedSwap=true; using legacy clamped value ${nativeValueForGas.toString()}`);
|
|
1056
|
-
}
|
|
1057
1046
|
// 12. Build Push Chain multicalls (approvals + sendUniversalTxOutbound)
|
|
1058
1047
|
const pushChainMulticalls = (0, payload_builders_1.buildOutboundApprovalAndCall)({
|
|
1059
1048
|
prc20Token,
|
|
@@ -1118,7 +1107,7 @@ function executeCeaToPush(ctx, params, executeFn) {
|
|
|
1118
1107
|
*/
|
|
1119
1108
|
function executeCeaToPushSvm(ctx, params, sourceChain, executeFn) {
|
|
1120
1109
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1121
|
-
var _a, _b, _c, _d
|
|
1110
|
+
var _a, _b, _c, _d;
|
|
1122
1111
|
if (typeof params.to !== 'string') {
|
|
1123
1112
|
throw new Error('Route 3 SVM (CEA -> Push): to must be a Push Chain address (string), not a ChainTarget');
|
|
1124
1113
|
}
|
|
@@ -1266,20 +1255,14 @@ function executeCeaToPushSvm(ctx, params, sourceChain, executeFn) {
|
|
|
1266
1255
|
// Pre-flight (R3 SVM): no PRC-20 burn check — `burnAmount = 1` is a legacy
|
|
1267
1256
|
// precompile-validation shim against a token UEAs structurally don't hold
|
|
1268
1257
|
// (see plan §9 #4 / §10.2 latent-bug ticket). Native UPC check still applies.
|
|
1269
|
-
|
|
1270
|
-
const preflightR3Svm = (0, preflight_1.runPreflight)({
|
|
1258
|
+
(0, preflight_1.runPreflight)({
|
|
1271
1259
|
ctx,
|
|
1272
1260
|
ueaAddress,
|
|
1273
1261
|
ueaBalance: currentBalance,
|
|
1274
1262
|
requiredValue: nativeValueForGas,
|
|
1275
1263
|
gasReserve: OUTBOUND_GAS_RESERVE_R3_SVM,
|
|
1276
1264
|
pathTag: 'R3_SVM',
|
|
1277
|
-
allowUnderfundedSwap: allowUnderfundedR3Svm,
|
|
1278
1265
|
});
|
|
1279
|
-
if (!preflightR3Svm.ok) {
|
|
1280
|
-
nativeValueForGas = preflightR3Svm.legacyClampedValue;
|
|
1281
|
-
(0, context_1.printLog)(ctx, `executeCeaToPushSvm — allowUnderfundedSwap=true; using legacy clamped value ${nativeValueForGas.toString()}`);
|
|
1282
|
-
}
|
|
1283
1266
|
// Build Push Chain multicalls (approvals + sendUniversalTxOutbound)
|
|
1284
1267
|
const pushChainMulticalls = (0, payload_builders_1.buildOutboundApprovalAndCall)({
|
|
1285
1268
|
prc20Token,
|
|
@@ -1559,7 +1542,8 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1559
1542
|
const multicallPayload = (0, payload_builder_1.buildMulticallPayloadData)(ctx, pushDestination, multicallData);
|
|
1560
1543
|
pushPayload = (0, payload_builders_1.buildInboundUniversalPayload)(multicallPayload, { nonce: ueaNonceHop + BigInt(1) });
|
|
1561
1544
|
}
|
|
1562
|
-
// Build sendUniversalTxToUEA self-call on CEA
|
|
1545
|
+
// Build sendUniversalTxToUEA self-call on CEA. CEA self-calls must
|
|
1546
|
+
// always use value=0; native sends spend from the CEA balance.
|
|
1563
1547
|
const sendCall = (0, payload_builders_1.buildSendUniversalTxToUEA)(ceaAddress, tokenAddress, amount, pushPayload, ceaAddress);
|
|
1564
1548
|
ceaMulticalls.push(sendCall);
|
|
1565
1549
|
const ceaPayload = (0, payload_builders_1.buildCeaMulticallPayload)(ceaMulticalls);
|
|
@@ -1567,7 +1551,8 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1567
1551
|
// Route 3: CEA uses its own pre-existing balance — no PRC-20 burn needed.
|
|
1568
1552
|
// burnAmount = 0 makes this a payload-only outbound relay.
|
|
1569
1553
|
const burnAmount = BigInt(0);
|
|
1570
|
-
const
|
|
1554
|
+
const outboundGasLimit = (_l = params.gasLimit) !== null && _l !== void 0 ? _l : selectors_1.DEFAULT_CEA_TO_PUSH_GAS_LIMIT;
|
|
1555
|
+
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, prc20Token, burnAmount, outboundGasLimit, ceaPayload, ueaAddress);
|
|
1571
1556
|
return { payload: ceaPayload, gatewayRequest: outboundReq };
|
|
1572
1557
|
}
|
|
1573
1558
|
default:
|
|
@@ -176,7 +176,8 @@ function reconstructR3(universalTxResponse, universalTxData, isFailed, errorMsg)
|
|
|
176
176
|
events.push(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_303_02](universalTxResponse.from, ceaAddress, sourceChain));
|
|
177
177
|
// R3 pre-flight reconstruction — R3 EVM burnAmount=0, R3 SVM burnAmount=0
|
|
178
178
|
// (post-fix). Only the NATIVE pre-flight check fires; no PRC-20 second hook.
|
|
179
|
-
|
|
179
|
+
// R3 single-route uses 303-04 (R3 bucket); see runPreflight in preflight.ts.
|
|
180
|
+
events.push(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_303_04](BigInt(0), BigInt(0), true, universalTxResponse.from, 'R3_EVM', { kind: 'NATIVE' }));
|
|
180
181
|
events.push(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_304_01]());
|
|
181
182
|
events.push(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_304_02]());
|
|
182
183
|
events.push(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_304_03]());
|
|
@@ -85,9 +85,15 @@ export declare class Orchestrator {
|
|
|
85
85
|
* The cascade composes all hops bottom-to-top into a single Push Chain tx.
|
|
86
86
|
*
|
|
87
87
|
* @param preparedTxs - Array of prepared transactions
|
|
88
|
+
* @param options - Optional per-call options. `progressHook` is additive with
|
|
89
|
+
* the init-time hook from `PushChain.initialize` and receives every
|
|
90
|
+
* `ProgressEvent` emitted during this cascade (pre-flight, broadcast, and
|
|
91
|
+
* tracking). Dedups by reference if it matches the init-time hook.
|
|
88
92
|
* @returns Object with send() method
|
|
89
93
|
*/
|
|
90
|
-
createCascadedBuilder(preparedTxs: PreparedUniversalTx[]
|
|
94
|
+
createCascadedBuilder(preparedTxs: PreparedUniversalTx[], options?: {
|
|
95
|
+
progressHook?: (event: ProgressEvent) => void;
|
|
96
|
+
}): {
|
|
91
97
|
send: () => Promise<CascadedTxResponse>;
|
|
92
98
|
};
|
|
93
99
|
/**
|
|
@@ -30,6 +30,7 @@ class Orchestrator {
|
|
|
30
30
|
return {
|
|
31
31
|
executeFn: this.execute.bind(this),
|
|
32
32
|
waitForOutboundTxFn: (hash, opts) => (0, internals_1.waitForOutboundTx)(this.ctx, hash, opts),
|
|
33
|
+
waitForInboundPushTxFn: (hash, sourceChain, opts) => (0, internals_1.waitForInboundPushTx)(this.ctx, hash, sourceChain, opts),
|
|
33
34
|
waitForAllOutboundTxsFn: (hash, hops, opts) => (0, internals_1.waitForAllOutboundTxsV2)(this.ctx, hash, hops, opts),
|
|
34
35
|
};
|
|
35
36
|
}
|
|
@@ -296,10 +297,47 @@ class Orchestrator {
|
|
|
296
297
|
* The cascade composes all hops bottom-to-top into a single Push Chain tx.
|
|
297
298
|
*
|
|
298
299
|
* @param preparedTxs - Array of prepared transactions
|
|
300
|
+
* @param options - Optional per-call options. `progressHook` is additive with
|
|
301
|
+
* the init-time hook from `PushChain.initialize` and receives every
|
|
302
|
+
* `ProgressEvent` emitted during this cascade (pre-flight, broadcast, and
|
|
303
|
+
* tracking). Dedups by reference if it matches the init-time hook.
|
|
299
304
|
* @returns Object with send() method
|
|
300
305
|
*/
|
|
301
|
-
createCascadedBuilder(preparedTxs) {
|
|
302
|
-
|
|
306
|
+
createCascadedBuilder(preparedTxs, options) {
|
|
307
|
+
const perCallHook = options === null || options === void 0 ? void 0 : options.progressHook;
|
|
308
|
+
if (!perCallHook) {
|
|
309
|
+
return (0, internals_1.createCascadedBuilder)(this.ctx, preparedTxs, this._getCascadeCallbacks());
|
|
310
|
+
}
|
|
311
|
+
// Wrap ctx.progressHook for the synchronous send() phase — captures every
|
|
312
|
+
// fireProgressHook(ctx, ...) call during pre-flight, composeCascade, and
|
|
313
|
+
// the Push Chain broadcast. Restored when send() resolves/rejects so the
|
|
314
|
+
// wrapper doesn't leak across calls.
|
|
315
|
+
//
|
|
316
|
+
// For the asynchronous tracking phase (waitForAll), we pass perCallHook as
|
|
317
|
+
// the cascade builder's `defaultEventHook` — waitForAll falls back to it
|
|
318
|
+
// when callers don't pass their own `eventHook`, and the existing
|
|
319
|
+
// `dispatchCascadeProgressEvent` path delivers events to BOTH that hook
|
|
320
|
+
// and ctx.progressHook (the init-time hook, restored by then) with
|
|
321
|
+
// reference-dedup.
|
|
322
|
+
const innerBuilder = (0, internals_1.createCascadedBuilder)(this.ctx, preparedTxs, this._getCascadeCallbacks(), perCallHook);
|
|
323
|
+
return {
|
|
324
|
+
send: () => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
325
|
+
const originalHook = this.progressHook;
|
|
326
|
+
const wrapped = (event) => {
|
|
327
|
+
if (originalHook && originalHook !== perCallHook) {
|
|
328
|
+
originalHook(event);
|
|
329
|
+
}
|
|
330
|
+
perCallHook(event);
|
|
331
|
+
};
|
|
332
|
+
this.progressHook = wrapped;
|
|
333
|
+
try {
|
|
334
|
+
return yield innerBuilder.send();
|
|
335
|
+
}
|
|
336
|
+
finally {
|
|
337
|
+
this.progressHook = originalHook;
|
|
338
|
+
}
|
|
339
|
+
}),
|
|
340
|
+
};
|
|
303
341
|
}
|
|
304
342
|
/**
|
|
305
343
|
* Queries gas fee for an outbound transaction from the UniversalCore contract.
|
|
@@ -397,20 +397,6 @@ export type UniversalExecuteParams = Omit<ExecuteParams, 'to'> & {
|
|
|
397
397
|
* Only applicable for Route 2 (UOA_TO_CEA) on EVM chains.
|
|
398
398
|
*/
|
|
399
399
|
migration?: boolean;
|
|
400
|
-
/**
|
|
401
|
-
* Per-call SDK behaviour overrides. Reserved for opt-out flags that must
|
|
402
|
-
* not affect the global orchestrator config.
|
|
403
|
-
*/
|
|
404
|
-
options?: {
|
|
405
|
-
/**
|
|
406
|
-
* Restore the legacy clamp-and-refund behaviour for outbound paths whose
|
|
407
|
-
* UEA balance is below the buffered pool quote. Default `false` — the
|
|
408
|
-
* SDK throws `InsufficientUEABalanceError` (see `runPreflight`) and does
|
|
409
|
-
* NOT submit a cosmos tx. Set `true` only when the caller intentionally
|
|
410
|
-
* relies on `swapAndBurnGas` refunds to power through low balances.
|
|
411
|
-
*/
|
|
412
|
-
allowUnderfundedSwap?: boolean;
|
|
413
|
-
};
|
|
414
400
|
};
|
|
415
401
|
/**
|
|
416
402
|
* Account metadata for SVM CPI execution (Solana Gateway pattern).
|
|
@@ -514,6 +500,10 @@ export interface HopDescriptor {
|
|
|
514
500
|
svmPayload?: `0x${string}`;
|
|
515
501
|
/** Whether this hop is a CEA migration (raw MIGRATION_SELECTOR payload) */
|
|
516
502
|
isMigration?: boolean;
|
|
503
|
+
/** Whether this Route 3 hop only seeds native PC into the UEA. @internal */
|
|
504
|
+
nativeSeedOnly?: boolean;
|
|
505
|
+
/** Native PC amount seeded by a value-only Route 3 hop. @internal */
|
|
506
|
+
nativeSeedAmount?: bigint;
|
|
517
507
|
/** SDK 5.2 gas-abstraction sizing decision for this hop. @internal */
|
|
518
508
|
sizing?: import('./internals/gas-usd-sizer').GasSizingDecision;
|
|
519
509
|
}
|