@pushchain/core 5.1.18 → 6.0.0
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/abi/cea.evm.d.ts +52 -0
- package/src/lib/constants/abi/cea.evm.js +66 -1
- package/src/lib/constants/abi/prc20.evm.d.ts +117 -11
- package/src/lib/constants/abi/prc20.evm.js +38 -11
- package/src/lib/constants/abi/uea.evm.js +41 -0
- package/src/lib/constants/abi/universalGatewayPC.evm.d.ts +117 -1
- package/src/lib/constants/abi/universalGatewayPC.evm.js +40 -1
- package/src/lib/constants/abi/universalGatewayV0.json +1 -1
- package/src/lib/constants/chain.js +14 -14
- package/src/lib/constants/tokens.js +1 -0
- package/src/lib/formatters.d.ts +6 -0
- package/src/lib/formatters.js +14 -0
- package/src/lib/index.d.ts +2 -0
- package/src/lib/index.js +7 -1
- package/src/lib/orchestrator/internals/cascade.js +139 -81
- package/src/lib/orchestrator/internals/errors.js +1 -1
- package/src/lib/orchestrator/internals/execute-funds-only.js +3 -2
- package/src/lib/orchestrator/internals/execute-funds-payload.js +2 -1
- package/src/lib/orchestrator/internals/execute-standard.js +4 -4
- package/src/lib/orchestrator/internals/gas-calculator.d.ts +1 -0
- package/src/lib/orchestrator/internals/gas-calculator.js +13 -11
- package/src/lib/orchestrator/internals/helpers.js +1 -0
- package/src/lib/orchestrator/internals/inbound-tracker.js +4 -2
- package/src/lib/orchestrator/internals/outbound-sync.js +73 -60
- package/src/lib/orchestrator/internals/pc-usd-oracle.d.ts +1 -1
- package/src/lib/orchestrator/internals/pc-usd-oracle.js +4 -3
- package/src/lib/orchestrator/internals/push-chain-tx.js +5 -1
- package/src/lib/orchestrator/internals/route-handlers.js +155 -185
- package/src/lib/orchestrator/internals/signing.js +7 -2
- package/src/lib/orchestrator/internals/svm-helpers.js +3 -3
- package/src/lib/orchestrator/internals/svm-rent.d.ts +42 -9
- package/src/lib/orchestrator/internals/svm-rent.js +148 -14
- package/src/lib/orchestrator/internals/tx-transformer.js +5 -2
- package/src/lib/orchestrator/max-pc-for-gas.d.ts +60 -0
- package/src/lib/orchestrator/max-pc-for-gas.js +66 -0
- package/src/lib/orchestrator/orchestrator.d.ts +1 -0
- package/src/lib/orchestrator/orchestrator.types.d.ts +31 -9
- package/src/lib/orchestrator/payload-builders.d.ts +7 -6
- package/src/lib/orchestrator/payload-builders.js +18 -6
- package/src/lib/progress-hook/progress-hook.js +26 -18
- package/src/lib/universal-tx-detector/events.d.ts +3 -1
- package/src/lib/universal-tx-detector/events.js +3 -1
- package/src/lib/universal-tx-detector/svm-events.d.ts +1 -1
- package/src/lib/universal-tx-detector/svm-events.js +1 -1
|
@@ -112,6 +112,37 @@ function resolveR2Prc20TokenSvm(params, targetChain, pushNetwork, hasSvmExecute)
|
|
|
112
112
|
}
|
|
113
113
|
return { prc20Token, burnAmount };
|
|
114
114
|
}
|
|
115
|
+
function resolveR3SvmDrain(params, sourceChain, pushNetwork) {
|
|
116
|
+
var _a;
|
|
117
|
+
let drainAmount = BigInt(0);
|
|
118
|
+
let tokenMintHex;
|
|
119
|
+
let prc20Token = (0, helpers_1.getNativePRC20ForChain)(sourceChain, pushNetwork);
|
|
120
|
+
if (((_a = params.funds) === null || _a === void 0 ? void 0 : _a.amount) && params.funds.amount > BigInt(0)) {
|
|
121
|
+
drainAmount = params.funds.amount;
|
|
122
|
+
const token = params.funds.token;
|
|
123
|
+
if ((token === null || token === void 0 ? void 0 : token.mechanism) === 'approve') {
|
|
124
|
+
const mintPk = new web3_js_1.PublicKey(token.address);
|
|
125
|
+
tokenMintHex = ('0x' + Buffer.from(mintPk.toBytes()).toString('hex'));
|
|
126
|
+
prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token).address;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else if (params.value && params.value > BigInt(0)) {
|
|
130
|
+
drainAmount = params.value;
|
|
131
|
+
}
|
|
132
|
+
return { prc20Token, drainAmount, tokenMintHex };
|
|
133
|
+
}
|
|
134
|
+
function buildR3SvmExtraPayload(ctx, params, ueaAddress, sourceChain, inboundNonce) {
|
|
135
|
+
if (!params.data) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
const executeParams = (0, helpers_1.toExecuteParams)(params);
|
|
139
|
+
const multicallCtx = Object.assign(Object.assign({}, ctx), { universalSigner: Object.assign(Object.assign({}, ctx.universalSigner), { account: Object.assign(Object.assign({}, ctx.universalSigner.account), { chain: sourceChain }) }) });
|
|
140
|
+
const multicallPayload = (0, payload_builder_1.buildMulticallPayloadData)(multicallCtx, executeParams.to, (0, payload_builders_1.buildExecuteMulticall)({ execute: executeParams, ueaAddress }));
|
|
141
|
+
const inboundPayload = (0, payload_builders_1.buildInboundUniversalPayload)(multicallPayload, {
|
|
142
|
+
nonce: inboundNonce !== null && inboundNonce !== void 0 ? inboundNonce : BigInt(0),
|
|
143
|
+
});
|
|
144
|
+
return (0, viem_1.hexToBytes)(inboundPayload);
|
|
145
|
+
}
|
|
115
146
|
/**
|
|
116
147
|
* Build the CEA-side multicall payload for a Route 2 EVM outbound. Needs the
|
|
117
148
|
* resolved `ceaAddress` because the native-value self-call branch skips the
|
|
@@ -281,7 +312,7 @@ function executeMultiChain(ctx, params, executeFn) {
|
|
|
281
312
|
*/
|
|
282
313
|
function executeUoaToCea(ctx, params, executeFn) {
|
|
283
314
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
284
|
-
var _a, _b, _c;
|
|
315
|
+
var _a, _b, _c, _d;
|
|
285
316
|
const target = params.to;
|
|
286
317
|
const targetChain = target.chain;
|
|
287
318
|
const targetAddress = target.address;
|
|
@@ -337,6 +368,7 @@ function executeUoaToCea(ctx, params, executeFn) {
|
|
|
337
368
|
// --- 202: Gas estimation (spec-ordered before 203) ---
|
|
338
369
|
let gasFee = BigInt(0);
|
|
339
370
|
let protocolFee = BigInt(0);
|
|
371
|
+
let outboundGasPrice = BigInt(0);
|
|
340
372
|
let gasToken = selectors_1.ZERO_ADDRESS;
|
|
341
373
|
let universalCoreAddress;
|
|
342
374
|
if (prc20Token !== selectors_1.ZERO_ADDRESS) {
|
|
@@ -345,6 +377,7 @@ function executeUoaToCea(ctx, params, executeFn) {
|
|
|
345
377
|
const result = yield (0, gas_calculator_1.queryOutboundGasFee)(ctx, prc20Token, gasLimitForQuery, targetChain);
|
|
346
378
|
gasFee = result.gasFee;
|
|
347
379
|
protocolFee = result.protocolFee;
|
|
380
|
+
outboundGasPrice = result.gasPrice;
|
|
348
381
|
gasToken = result.gasToken;
|
|
349
382
|
universalCoreAddress = result.universalCoreAddress;
|
|
350
383
|
(0, context_1.printLog)(ctx, `executeUoaToCea — queried gas fee: ${gasFee.toString()}, gasToken: ${gasToken}`);
|
|
@@ -376,19 +409,20 @@ function executeUoaToCea(ctx, params, executeFn) {
|
|
|
376
409
|
(0, context_1.printLog)(ctx, `executeUoaToCea — MIGRATION: using raw MIGRATION_SELECTOR payload (${ceaPayload}), native PRC-20 ${prc20Token}`);
|
|
377
410
|
}
|
|
378
411
|
// Build outbound request struct for the gateway
|
|
379
|
-
//
|
|
380
|
-
//
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, gasLimitForQuery, ceaPayload, ueaAddress // revert recipient is the UEA
|
|
386
|
-
);
|
|
412
|
+
// Empty CEA payloads intentionally use zero recipient to park funds in the
|
|
413
|
+
// CEA under the post-audit single-call guard.
|
|
414
|
+
const targetBytes = ceaPayload === '0x'
|
|
415
|
+
? selectors_1.ZERO_ADDRESS
|
|
416
|
+
: ceaAddress;
|
|
417
|
+
(0, payload_builders_1.assertCeaFundsParkingInvariant)(targetBytes, ceaPayload);
|
|
418
|
+
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, gasLimitForQuery, ceaPayload, ueaAddress, // revert recipient is the UEA
|
|
419
|
+
(_d = params.maxPCForGas) !== null && _d !== void 0 ? _d : BigInt(0), outboundGasPrice);
|
|
387
420
|
(0, context_1.printLog)(ctx, `executeUoaToCea — outbound request: ${JSON.stringify({
|
|
388
421
|
target: outboundReq.target,
|
|
389
422
|
token: outboundReq.token,
|
|
390
423
|
amount: outboundReq.amount.toString(),
|
|
391
424
|
gasLimit: outboundReq.gasLimit.toString(),
|
|
425
|
+
maxPCForGas: outboundReq.maxPCForGas.toString(),
|
|
392
426
|
payloadLength: outboundReq.payload.length,
|
|
393
427
|
revertRecipient: outboundReq.revertRecipient,
|
|
394
428
|
}, null, 2)}`);
|
|
@@ -561,44 +595,49 @@ function executeUoaToCeaSvm(ctx, params, target, executeFn) {
|
|
|
561
595
|
// --- 202: Gas estimation (spec-ordered before 203) ---
|
|
562
596
|
let gasFee = BigInt(0);
|
|
563
597
|
let protocolFeeSvm = BigInt(0);
|
|
598
|
+
let outboundGasPriceSvm = BigInt(0);
|
|
564
599
|
let gasToken = selectors_1.ZERO_ADDRESS;
|
|
565
600
|
let universalCoreAddress;
|
|
566
601
|
// Effective gas limit seeded from the user param. When the user omits
|
|
567
|
-
// gasLimit, it'll be derived from the
|
|
568
|
-
//
|
|
602
|
+
// gasLimit, it'll be derived from the gas quote so the on-chain record
|
|
603
|
+
// carries a non-zero compute budget the relay can use.
|
|
569
604
|
let effectiveGasLimit = (_d = params.gasLimit) !== null && _d !== void 0 ? _d : BigInt(0);
|
|
570
|
-
//
|
|
571
|
-
//
|
|
572
|
-
//
|
|
573
|
-
//
|
|
574
|
-
//
|
|
575
|
-
const
|
|
576
|
-
? (
|
|
605
|
+
// SVM finalize budget: the Solana gateway requires gas_fee to cover the
|
|
606
|
+
// relayer signature fee, ExecutedSubTx rent, a compute buffer, and
|
|
607
|
+
// conditionally CEA ATA rent for SPL outbounds. The on-chain quote can be
|
|
608
|
+
// below that floor, so we compare the quoted fee in lamports and re-query
|
|
609
|
+
// with a bumped gasLimit when required.
|
|
610
|
+
const svmFundsToken = burnAmount > BigInt(0)
|
|
611
|
+
? (_e = params.funds) === null || _e === void 0 ? void 0 : _e.token
|
|
577
612
|
: undefined;
|
|
578
|
-
|
|
579
|
-
ctx,
|
|
580
|
-
ueaAddress,
|
|
581
|
-
targetChain,
|
|
582
|
-
splMintBase58,
|
|
583
|
-
burnAmount,
|
|
584
|
-
effectiveGasLimit,
|
|
585
|
-
});
|
|
613
|
+
const splMintBase58 = (svmFundsToken === null || svmFundsToken === void 0 ? void 0 : svmFundsToken.mechanism) === 'approve' ? svmFundsToken.address : undefined;
|
|
586
614
|
if (prc20Token !== selectors_1.ZERO_ADDRESS) {
|
|
587
615
|
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_202_01, targetChain);
|
|
588
616
|
try {
|
|
589
|
-
|
|
617
|
+
let result = yield (0, gas_calculator_1.queryOutboundGasFee)(ctx, prc20Token, effectiveGasLimit, targetChain);
|
|
618
|
+
result = yield (0, svm_rent_1.ensureSvmFinalizeGasBudgetQuote)({
|
|
619
|
+
ctx,
|
|
620
|
+
ueaAddress,
|
|
621
|
+
targetChain,
|
|
622
|
+
prc20Token,
|
|
623
|
+
quote: result,
|
|
624
|
+
splMintBase58,
|
|
625
|
+
burnAmount,
|
|
626
|
+
pathTag: 'executeUoaToCeaSvm',
|
|
627
|
+
});
|
|
590
628
|
gasFee = result.gasFee;
|
|
591
629
|
protocolFeeSvm = result.protocolFee;
|
|
630
|
+
outboundGasPriceSvm = result.gasPrice;
|
|
592
631
|
gasToken = result.gasToken;
|
|
593
632
|
universalCoreAddress = result.universalCoreAddress;
|
|
594
|
-
// When user omits gasLimit (sent as 0), the contract computes fees using
|
|
595
|
-
// baseGasLimitByChainNamespace. But the relay reads the
|
|
596
|
-
//
|
|
597
|
-
//
|
|
598
|
-
|
|
599
|
-
if (!params.gasLimit
|
|
600
|
-
effectiveGasLimit
|
|
601
|
-
|
|
633
|
+
// When user omits gasLimit (sent as 0), the contract computes fees using
|
|
634
|
+
// its internal baseGasLimitByChainNamespace. But the relay reads the
|
|
635
|
+
// stored gasLimit from the outbound record. Store the resolved value from
|
|
636
|
+
// UniversalCore so the relayer has a non-zero SVM budget.
|
|
637
|
+
effectiveGasLimit = result.gasLimitUsed;
|
|
638
|
+
if (!params.gasLimit) {
|
|
639
|
+
(0, context_1.printLog)(ctx, `executeUoaToCeaSvm — resolved effectiveGasLimit: ${effectiveGasLimit} ` +
|
|
640
|
+
`(gasFee=${result.gasFee}, gasPrice=${result.gasPrice})`);
|
|
602
641
|
}
|
|
603
642
|
(0, context_1.printLog)(ctx, `executeUoaToCeaSvm — queried gas fee: ${gasFee.toString()}, gasToken: ${gasToken}`);
|
|
604
643
|
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_202_02, targetChain, protocolFeeSvm, gasFee);
|
|
@@ -614,13 +653,14 @@ function executeUoaToCeaSvm(ctx, params, target, executeFn) {
|
|
|
614
653
|
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_203_02, ueaAddress, targetAddress, targetChain, true);
|
|
615
654
|
// --- Build outbound request ---
|
|
616
655
|
// targetBytes: for execute = program id (resolver output); for withdraw = to.address
|
|
617
|
-
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, effectiveGasLimit, svmPayload, ueaAddress // revert recipient is the UEA
|
|
618
|
-
);
|
|
656
|
+
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, effectiveGasLimit, svmPayload, ueaAddress, // revert recipient is the UEA
|
|
657
|
+
(_f = params.maxPCForGas) !== null && _f !== void 0 ? _f : BigInt(0), outboundGasPriceSvm);
|
|
619
658
|
(0, context_1.printLog)(ctx, `executeUoaToCeaSvm — outbound request: ${JSON.stringify({
|
|
620
659
|
target: outboundReq.target,
|
|
621
660
|
token: outboundReq.token,
|
|
622
661
|
amount: outboundReq.amount.toString(),
|
|
623
662
|
gasLimit: outboundReq.gasLimit.toString(),
|
|
663
|
+
maxPCForGas: outboundReq.maxPCForGas.toString(),
|
|
624
664
|
payloadLength: (outboundReq.payload.length - 2) / 2,
|
|
625
665
|
revertRecipient: outboundReq.revertRecipient,
|
|
626
666
|
}, null, 2)}`);
|
|
@@ -764,7 +804,7 @@ function executeUoaToCeaSvm(ctx, params, target, executeFn) {
|
|
|
764
804
|
*/
|
|
765
805
|
function executeCeaToPush(ctx, params, executeFn) {
|
|
766
806
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
767
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
807
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
768
808
|
// 1. Validate and extract source chain
|
|
769
809
|
if (!((_a = params.from) === null || _a === void 0 ? void 0 : _a.chain)) {
|
|
770
810
|
throw new Error('Route 3 (CEA -> Push) requires from.chain to specify the source CEA chain');
|
|
@@ -801,11 +841,6 @@ function executeCeaToPush(ctx, params, executeFn) {
|
|
|
801
841
|
(0, context_1.printLog)(ctx, `executeCeaToPush — sourceChain: ${sourceChain}, CEA: ${ceaAddress}, deployed: ${ceaDeployed}`);
|
|
802
842
|
// CEA auto-deploys on-chain: Vault.finalizeUniversalTx calls CEAFactory.deployCEA()
|
|
803
843
|
// if CEA doesn't exist yet. No SDK-side blocking needed.
|
|
804
|
-
// 5. Get UniversalGateway address on source chain
|
|
805
|
-
const gatewayAddress = chain_1.UNIVERSAL_GATEWAY_ADDRESSES[sourceChain];
|
|
806
|
-
if (!gatewayAddress) {
|
|
807
|
-
throw new Error(`No UniversalGateway address configured for chain ${sourceChain}`);
|
|
808
|
-
}
|
|
809
844
|
// 6. Build multicall for CEA to execute on source chain (self-calls via sendUniversalTxToUEA)
|
|
810
845
|
const ceaMulticalls = [];
|
|
811
846
|
// Determine token and amount for sendUniversalTxToUEA
|
|
@@ -821,7 +856,7 @@ function executeCeaToPush(ctx, params, executeFn) {
|
|
|
821
856
|
amount = params.funds.amount;
|
|
822
857
|
}
|
|
823
858
|
else {
|
|
824
|
-
// ERC20 token
|
|
859
|
+
// ERC20 token. CEA handles gateway approval internally around sendUniversalTxToUEA.
|
|
825
860
|
tokenAddress = token.address;
|
|
826
861
|
amount = params.funds.amount;
|
|
827
862
|
}
|
|
@@ -838,33 +873,7 @@ function executeCeaToPush(ctx, params, executeFn) {
|
|
|
838
873
|
// query and relay execution, causing sendUniversalTxToUEA to revert with
|
|
839
874
|
// InsufficientBalance. Pre-existing CEA funds remain parked and can be swept separately.
|
|
840
875
|
const bridgeAmount = amount;
|
|
841
|
-
//
|
|
842
|
-
// Keeping bridgeAmount as-is (0) for payload-only to test precompile behavior.
|
|
843
|
-
// For ERC20 tokens, add approve call for the bridge amount
|
|
844
|
-
// (CEA approves gateway to spend the Vault-deposited amount)
|
|
845
|
-
// Reset to 0 first for USDT-style tokens that revert on non-zero to non-zero approve.
|
|
846
|
-
if (tokenAddress !== selectors_1.ZERO_ADDRESS && bridgeAmount > BigInt(0)) {
|
|
847
|
-
const approveZeroData = (0, viem_1.encodeFunctionData)({
|
|
848
|
-
abi: erc20_evm_1.ERC20_EVM,
|
|
849
|
-
functionName: 'approve',
|
|
850
|
-
args: [gatewayAddress, BigInt(0)],
|
|
851
|
-
});
|
|
852
|
-
ceaMulticalls.push({
|
|
853
|
-
to: tokenAddress,
|
|
854
|
-
value: BigInt(0),
|
|
855
|
-
data: approveZeroData,
|
|
856
|
-
});
|
|
857
|
-
const approveData = (0, viem_1.encodeFunctionData)({
|
|
858
|
-
abi: erc20_evm_1.ERC20_EVM,
|
|
859
|
-
functionName: 'approve',
|
|
860
|
-
args: [gatewayAddress, bridgeAmount],
|
|
861
|
-
});
|
|
862
|
-
ceaMulticalls.push({
|
|
863
|
-
to: tokenAddress,
|
|
864
|
-
value: BigInt(0),
|
|
865
|
-
data: approveData,
|
|
866
|
-
});
|
|
867
|
-
}
|
|
876
|
+
// The post-audit CEA allows amount=0 for payload-only sendUniversalTxToUEA.
|
|
868
877
|
// Pre-fetch UEA nonce — needed for the inbound UniversalPayload struct
|
|
869
878
|
// Skip getCode if accountStatusCache already confirmed deployment
|
|
870
879
|
let isUEADeployed;
|
|
@@ -928,17 +937,18 @@ function executeCeaToPush(ctx, params, executeFn) {
|
|
|
928
937
|
(0, context_1.printLog)(ctx, `executeCeaToPush — prc20Token: ${prc20Token}, burnAmount: ${burnAmount.toString()}`);
|
|
929
938
|
// 9. Build outbound request (same structure as Route 2)
|
|
930
939
|
// target = CEA address (for self-execution), value = 0 in payload
|
|
931
|
-
|
|
940
|
+
let outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, // target: CEA address (to=CEA for self-execution)
|
|
932
941
|
prc20Token, // token: native PRC-20 for source chain (for namespace lookup)
|
|
933
942
|
burnAmount, // amount: 0 (payload-only, CEA uses its own balance)
|
|
934
943
|
outboundGasLimit, ceaPayload, // payload: ABI-encoded CEA multicall
|
|
935
|
-
ueaAddress // revertRecipient: UEA
|
|
936
|
-
);
|
|
944
|
+
ueaAddress, // revertRecipient: UEA
|
|
945
|
+
(_g = params.maxPCForGas) !== null && _g !== void 0 ? _g : BigInt(0));
|
|
937
946
|
(0, context_1.printLog)(ctx, `executeCeaToPush — outbound request: ${JSON.stringify({
|
|
938
947
|
target: outboundReq.target,
|
|
939
948
|
token: outboundReq.token,
|
|
940
949
|
amount: outboundReq.amount.toString(),
|
|
941
950
|
gasLimit: outboundReq.gasLimit.toString(),
|
|
951
|
+
maxPCForGas: outboundReq.maxPCForGas.toString(),
|
|
942
952
|
payloadLength: outboundReq.payload.length,
|
|
943
953
|
revertRecipient: outboundReq.revertRecipient,
|
|
944
954
|
}, null, 2)}`);
|
|
@@ -949,6 +959,7 @@ function executeCeaToPush(ctx, params, executeFn) {
|
|
|
949
959
|
// 11. Query gas fees from UniversalCore
|
|
950
960
|
let gasFee = BigInt(0);
|
|
951
961
|
let protocolFeeR3 = BigInt(0);
|
|
962
|
+
let outboundGasPriceR3 = BigInt(0);
|
|
952
963
|
let nativeValueForGas = BigInt(0);
|
|
953
964
|
let gasToken = selectors_1.ZERO_ADDRESS;
|
|
954
965
|
let sizingDecisionR3;
|
|
@@ -958,10 +969,12 @@ function executeCeaToPush(ctx, params, executeFn) {
|
|
|
958
969
|
const result = yield (0, gas_calculator_1.queryOutboundGasFee)(ctx, prc20Token, outboundGasLimit, sourceChain);
|
|
959
970
|
gasToken = result.gasToken;
|
|
960
971
|
gasFee = result.gasFee;
|
|
972
|
+
outboundGasPriceR3 = result.gasPrice;
|
|
961
973
|
protocolFeeR3 = result.protocolFee;
|
|
962
974
|
nativeValueForGas = result.nativeValueForGas;
|
|
963
975
|
sizingDecisionR3 = result.sizing;
|
|
964
|
-
(0,
|
|
976
|
+
outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, prc20Token, burnAmount, outboundGasLimit, ceaPayload, ueaAddress, (_h = params.maxPCForGas) !== null && _h !== void 0 ? _h : BigInt(0), outboundGasPriceR3);
|
|
977
|
+
(0, context_1.printLog)(ctx, `executeCeaToPush — queried gas fee: ${gasFee.toString()}, gasToken: ${gasToken}, nativeValueForGas: ${nativeValueForGas.toString()}, sizing=${(_k = (_j = result.sizing) === null || _j === void 0 ? void 0 : _j.category) !== null && _k !== void 0 ? _k : 'legacy'}`);
|
|
965
978
|
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_302_02, sourceChain, protocolFeeR3, gasFee);
|
|
966
979
|
}
|
|
967
980
|
catch (err) {
|
|
@@ -1107,7 +1120,7 @@ function executeCeaToPush(ctx, params, executeFn) {
|
|
|
1107
1120
|
*/
|
|
1108
1121
|
function executeCeaToPushSvm(ctx, params, sourceChain, executeFn) {
|
|
1109
1122
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1110
|
-
var _a, _b, _c, _d;
|
|
1123
|
+
var _a, _b, _c, _d, _e;
|
|
1111
1124
|
if (typeof params.to !== 'string') {
|
|
1112
1125
|
throw new Error('Route 3 SVM (CEA -> Push): to must be a Push Chain address (string), not a ChainTarget');
|
|
1113
1126
|
}
|
|
@@ -1121,41 +1134,31 @@ function executeCeaToPushSvm(ctx, params, sourceChain, executeFn) {
|
|
|
1121
1134
|
const gatewayProgramHex = ('0x' + Buffer.from(programPk.toBytes()).toString('hex'));
|
|
1122
1135
|
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_301, sourceChain, lockerContract);
|
|
1123
1136
|
(0, context_1.printLog)(ctx, `executeCeaToPushSvm — sourceChain: ${sourceChain}, gateway: ${lockerContract}`);
|
|
1124
|
-
//
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
drainAmount = params.funds.amount;
|
|
1130
|
-
const token = params.funds.token;
|
|
1131
|
-
if (token && token.address) {
|
|
1132
|
-
// Convert SPL mint address to 32-byte hex
|
|
1133
|
-
const mintPk = new web3_js_1.PublicKey(token.address);
|
|
1134
|
-
tokenMintHex = ('0x' + Buffer.from(mintPk.toBytes()).toString('hex'));
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
else if (params.value && params.value > BigInt(0)) {
|
|
1138
|
-
// Native SOL drain
|
|
1139
|
-
drainAmount = params.value;
|
|
1140
|
-
}
|
|
1141
|
-
// Route 3 SVM: ALWAYS use native PRC-20 for chain namespace lookup + gas fees.
|
|
1142
|
-
// CEA uses its own pre-existing balance — no PRC-20 burn needed on Push Chain.
|
|
1143
|
-
const prc20Token = (0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork);
|
|
1144
|
-
// Build the SVM CPI payload (send_universal_tx_to_uea wrapped in execute)
|
|
1145
|
-
// If params.data is provided, pass it as extraPayload for Push Chain execution
|
|
1146
|
-
let extraPayload;
|
|
1147
|
-
if (params.data && typeof params.data === 'string') {
|
|
1148
|
-
extraPayload = (0, viem_1.hexToBytes)(params.data);
|
|
1149
|
-
}
|
|
1137
|
+
// Route 3 SVM: CEA uses its own pre-existing balance — no PRC-20 burn
|
|
1138
|
+
// needed on Push Chain. The outer request token must still match the source
|
|
1139
|
+
// asset so the relayer supplies the same Solana mint that the payload
|
|
1140
|
+
// encodes; otherwise the gateway rejects with InvalidMint.
|
|
1141
|
+
const { prc20Token, drainAmount, tokenMintHex } = resolveR3SvmDrain(params, sourceChain, ctx.pushNetwork);
|
|
1150
1142
|
// Derive CEA PDA as revert recipient: ["push_identity", ueaAddress_20_bytes]
|
|
1151
1143
|
const ueaBytes = Buffer.from(ueaAddress.slice(2), 'hex'); // 20 bytes
|
|
1152
1144
|
const [ceaPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('push_identity'), ueaBytes], programPk);
|
|
1153
1145
|
const ceaPdaHex = ('0x' + Buffer.from(ceaPda.toBytes()).toString('hex'));
|
|
1146
|
+
// Pre-fetch UEA status before payload construction. The inbound
|
|
1147
|
+
// UniversalPayload must use the nonce after this outbound execution, because
|
|
1148
|
+
// the Push-side execute() below consumes one UEA nonce before the Solana
|
|
1149
|
+
// round-trip payload returns.
|
|
1150
|
+
const gatewayPcAddress = (0, helpers_1.getUniversalGatewayPCAddress)();
|
|
1151
|
+
const [ueaCode, ueaBalance] = yield Promise.all([
|
|
1152
|
+
ctx.pushClient.publicClient.getCode({ address: ueaAddress }),
|
|
1153
|
+
ctx.pushClient.getBalance(ueaAddress),
|
|
1154
|
+
]);
|
|
1155
|
+
const isUEADeployed = ueaCode !== undefined;
|
|
1156
|
+
const ueaNonce = isUEADeployed ? yield (0, uea_manager_1.getUEANonce)(ctx, ueaAddress) : BigInt(0);
|
|
1154
1157
|
const svmPayload = (0, payload_builders_1.encodeSvmCeaToUeaPayload)({
|
|
1155
1158
|
gatewayProgramHex,
|
|
1156
1159
|
drainAmount,
|
|
1157
1160
|
tokenMintHex,
|
|
1158
|
-
extraPayload,
|
|
1161
|
+
extraPayload: buildR3SvmExtraPayload(ctx, params, ueaAddress, sourceChain, ueaNonce + BigInt(1)),
|
|
1159
1162
|
revertRecipientHex: ceaPdaHex,
|
|
1160
1163
|
});
|
|
1161
1164
|
(0, context_1.printLog)(ctx, `executeCeaToPushSvm — drainAmount: ${drainAmount.toString()}, payload length: ${(svmPayload.length - 2) / 2} bytes`);
|
|
@@ -1166,33 +1169,42 @@ function executeCeaToPushSvm(ctx, params, sourceChain, executeFn) {
|
|
|
1166
1169
|
// (e.g. pSOL). The UGPC upgrade post-2026-03-19 already accepts amount = 0
|
|
1167
1170
|
// on the cascade path, and the same precompile is used here.
|
|
1168
1171
|
const burnAmount = BigInt(0);
|
|
1172
|
+
let effectiveGasLimit = (_a = params.gasLimit) !== null && _a !== void 0 ? _a : BigInt(0);
|
|
1169
1173
|
// Build outbound request: target = gateway program (self-call)
|
|
1170
|
-
|
|
1171
|
-
(0, context_1.printLog)(ctx, `executeCeaToPushSvm — outbound request: target=${outboundReq.target.slice(0, 20)}..., token=${outboundReq.token}`);
|
|
1172
|
-
// Pre-fetch UEA status early — balance is needed for gas value calculation
|
|
1173
|
-
const gatewayPcAddress = (0, helpers_1.getUniversalGatewayPCAddress)();
|
|
1174
|
-
const [ueaCode, ueaBalance] = yield Promise.all([
|
|
1175
|
-
ctx.pushClient.publicClient.getCode({ address: ueaAddress }),
|
|
1176
|
-
ctx.pushClient.getBalance(ueaAddress),
|
|
1177
|
-
]);
|
|
1178
|
-
const isUEADeployed = ueaCode !== undefined;
|
|
1179
|
-
const ueaNonce = isUEADeployed ? yield (0, uea_manager_1.getUEANonce)(ctx, ueaAddress) : BigInt(0);
|
|
1174
|
+
let outboundReq = (0, payload_builders_1.buildOutboundRequest)(gatewayProgramHex, prc20Token, burnAmount, effectiveGasLimit, svmPayload, ueaAddress, (_b = params.maxPCForGas) !== null && _b !== void 0 ? _b : BigInt(0));
|
|
1175
|
+
(0, context_1.printLog)(ctx, `executeCeaToPushSvm — outbound request: target=${outboundReq.target.slice(0, 20)}..., token=${outboundReq.token}, maxPCForGas=${outboundReq.maxPCForGas}`);
|
|
1180
1176
|
// Query gas fees
|
|
1181
1177
|
let gasFee = BigInt(0);
|
|
1182
1178
|
let protocolFeeR3Svm = BigInt(0);
|
|
1179
|
+
let outboundGasPriceR3Svm = BigInt(0);
|
|
1183
1180
|
let nativeValueForGas = BigInt(0);
|
|
1184
1181
|
let gasToken = selectors_1.ZERO_ADDRESS;
|
|
1185
1182
|
let sizingDecisionR3Svm;
|
|
1186
1183
|
if (prc20Token !== selectors_1.ZERO_ADDRESS) {
|
|
1187
1184
|
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_302_01, sourceChain);
|
|
1188
1185
|
try {
|
|
1189
|
-
|
|
1186
|
+
let result = yield (0, gas_calculator_1.queryOutboundGasFee)(ctx, prc20Token, outboundReq.gasLimit, sourceChain);
|
|
1187
|
+
result = yield (0, svm_rent_1.ensureSvmFinalizeGasBudgetQuote)({
|
|
1188
|
+
ctx,
|
|
1189
|
+
ueaAddress,
|
|
1190
|
+
targetChain: sourceChain,
|
|
1191
|
+
prc20Token,
|
|
1192
|
+
quote: result,
|
|
1193
|
+
splMintBase58: undefined,
|
|
1194
|
+
burnAmount: BigInt(0),
|
|
1195
|
+
pathTag: 'executeCeaToPushSvm',
|
|
1196
|
+
});
|
|
1190
1197
|
gasToken = result.gasToken;
|
|
1191
1198
|
gasFee = result.gasFee;
|
|
1199
|
+
outboundGasPriceR3Svm = result.gasPrice;
|
|
1192
1200
|
protocolFeeR3Svm = result.protocolFee;
|
|
1193
1201
|
nativeValueForGas = result.nativeValueForGas;
|
|
1194
1202
|
sizingDecisionR3Svm = result.sizing;
|
|
1195
|
-
|
|
1203
|
+
effectiveGasLimit = result.gasLimitUsed;
|
|
1204
|
+
outboundReq = (0, payload_builders_1.buildOutboundRequest)(gatewayProgramHex, prc20Token, burnAmount, effectiveGasLimit, svmPayload, ueaAddress, (_c = params.maxPCForGas) !== null && _c !== void 0 ? _c : BigInt(0), outboundGasPriceR3Svm);
|
|
1205
|
+
(0, context_1.printLog)(ctx, `executeCeaToPushSvm — resolved effectiveGasLimit: ${effectiveGasLimit} ` +
|
|
1206
|
+
`(gasFee=${result.gasFee}, gasPrice=${result.gasPrice})`);
|
|
1207
|
+
(0, context_1.printLog)(ctx, `executeCeaToPushSvm — gasFee: ${gasFee.toString()}, gasToken: ${gasToken}, nativeValueForGas: ${nativeValueForGas.toString()}, sizing=${(_e = (_d = result.sizing) === null || _d === void 0 ? void 0 : _d.category) !== null && _e !== void 0 ? _e : 'legacy'}`);
|
|
1196
1208
|
(0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_302_02, sourceChain, protocolFeeR3Svm, gasFee);
|
|
1197
1209
|
}
|
|
1198
1210
|
catch (err) {
|
|
@@ -1252,9 +1264,8 @@ function executeCeaToPushSvm(ctx, params, sourceChain, executeFn) {
|
|
|
1252
1264
|
}
|
|
1253
1265
|
// SVM warn-threshold telemetry (no truncation — pre-flight handles drain protection).
|
|
1254
1266
|
(0, preflight_1.maybeFireSvmWarnThreshold)(ctx, nativeValueForGas, gasToken, 'R3_SVM');
|
|
1255
|
-
// Pre-flight (R3 SVM): no PRC-20 burn check
|
|
1256
|
-
//
|
|
1257
|
-
// (see plan §9 #4 / §10.2 latent-bug ticket). Native UPC check still applies.
|
|
1267
|
+
// Pre-flight (R3 SVM): no PRC-20 burn check. R3 SVM uses burnAmount=0
|
|
1268
|
+
// because the drain amount lives inside the SVM instruction data.
|
|
1258
1269
|
(0, preflight_1.runPreflight)({
|
|
1259
1270
|
ctx,
|
|
1260
1271
|
ueaAddress,
|
|
@@ -1299,17 +1310,11 @@ function executeCeaToPushSvm(ctx, params, sourceChain, executeFn) {
|
|
|
1299
1310
|
response.chain = sourceChain;
|
|
1300
1311
|
const chainInfo = chain_1.CHAIN_INFO[sourceChain];
|
|
1301
1312
|
response.chainNamespace = `${chain_1.VM_NAMESPACE[chainInfo.vm]}:${chainInfo.chainId}`;
|
|
1302
|
-
// R3 SVM
|
|
1303
|
-
//
|
|
1304
|
-
//
|
|
1305
|
-
//
|
|
1306
|
-
|
|
1307
|
-
// log — the parent utxId's `outboundStatus=OBSERVED` is the terminal state.
|
|
1308
|
-
// Polling for a deterministically-derived child id therefore never
|
|
1309
|
-
// resolves, and the cosmos `inbound_tx_hash` text-search fallback also
|
|
1310
|
-
// returns 0 hits. Receipts now resolve as soon as the Solana outbound is
|
|
1311
|
-
// observed instead of timing out at 300s.
|
|
1312
|
-
response._expectsInboundRoundTrip = false;
|
|
1313
|
+
// R3 SVM mirrors EVM R3: when funds drain back to Push, the Solana-side
|
|
1314
|
+
// send_universal_tx_to_uea emits an inbound leg whose payload can execute on
|
|
1315
|
+
// Push. Payload-only R3 has no child inbound UTX, so skip round-trip tracking
|
|
1316
|
+
// when no amount is being drained.
|
|
1317
|
+
response._expectsInboundRoundTrip = drainAmount > BigInt(0);
|
|
1313
1318
|
return response;
|
|
1314
1319
|
});
|
|
1315
1320
|
}
|
|
@@ -1335,7 +1340,7 @@ function executeCeaToCea(ctx, params, executeFn) {
|
|
|
1335
1340
|
*/
|
|
1336
1341
|
function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
1337
1342
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1338
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
1343
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
1339
1344
|
const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
|
|
1340
1345
|
switch (route) {
|
|
1341
1346
|
case route_detector_1.TransactionRoute.UOA_TO_PUSH: {
|
|
@@ -1379,13 +1384,13 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1379
1384
|
}
|
|
1380
1385
|
else if (hasExecute) {
|
|
1381
1386
|
prc20Token = (0, helpers_1.getNativePRC20ForChain)(target.chain, ctx.pushNetwork);
|
|
1382
|
-
burnAmount = BigInt(
|
|
1387
|
+
burnAmount = BigInt(0);
|
|
1383
1388
|
}
|
|
1384
|
-
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, (_b = params.gasLimit) !== null && _b !== void 0 ? _b : BigInt(0), payload, ueaAddress);
|
|
1389
|
+
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, (_b = params.gasLimit) !== null && _b !== void 0 ? _b : BigInt(0), payload, ueaAddress, (_c = params.maxPCForGas) !== null && _c !== void 0 ? _c : BigInt(0));
|
|
1385
1390
|
return { payload, gatewayRequest: outboundReq };
|
|
1386
1391
|
}
|
|
1387
1392
|
// EVM path: Resolve CEA address first (needed for self-transfer check)
|
|
1388
|
-
const { cea: ceaAddress } = yield (0, cea_utils_1.getCEAAddress)(ueaAddress, target.chain, (
|
|
1393
|
+
const { cea: ceaAddress } = yield (0, cea_utils_1.getCEAAddress)(ueaAddress, target.chain, (_d = ctx.rpcUrls[target.chain]) === null || _d === void 0 ? void 0 : _d[0]);
|
|
1389
1394
|
// Build CEA outbound payload
|
|
1390
1395
|
const multicalls = [];
|
|
1391
1396
|
if (params.data) {
|
|
@@ -1418,21 +1423,24 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1418
1423
|
const payload = (0, payload_builders_1.buildCeaMulticallPayload)(multicalls);
|
|
1419
1424
|
let prc20Token = selectors_1.ZERO_ADDRESS;
|
|
1420
1425
|
let burnAmount = BigInt(0);
|
|
1421
|
-
if ((
|
|
1426
|
+
if ((_e = params.funds) === null || _e === void 0 ? void 0 : _e.amount) {
|
|
1422
1427
|
const token = params.funds.token;
|
|
1423
1428
|
if (token) {
|
|
1424
1429
|
prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token).address;
|
|
1425
1430
|
burnAmount = params.funds.amount;
|
|
1426
1431
|
}
|
|
1427
1432
|
}
|
|
1428
|
-
const targetBytes =
|
|
1429
|
-
|
|
1433
|
+
const targetBytes = payload === '0x'
|
|
1434
|
+
? selectors_1.ZERO_ADDRESS
|
|
1435
|
+
: ceaAddress;
|
|
1436
|
+
(0, payload_builders_1.assertCeaFundsParkingInvariant)(targetBytes, payload);
|
|
1437
|
+
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, (_f = params.gasLimit) !== null && _f !== void 0 ? _f : BigInt(0), payload, ueaAddress, (_g = params.maxPCForGas) !== null && _g !== void 0 ? _g : BigInt(0));
|
|
1430
1438
|
return { payload, gatewayRequest: outboundReq };
|
|
1431
1439
|
}
|
|
1432
1440
|
case route_detector_1.TransactionRoute.CEA_TO_PUSH: {
|
|
1433
1441
|
// Route 3: CEA -> Push Chain
|
|
1434
|
-
// Build CEA multicall (
|
|
1435
|
-
if (!((
|
|
1442
|
+
// Build CEA multicall (sendUniversalTxToUEA self-call) and wrap in outbound
|
|
1443
|
+
if (!((_h = params.from) === null || _h === void 0 ? void 0 : _h.chain)) {
|
|
1436
1444
|
throw new Error('Route 3 (CEA -> Push) requires from.chain');
|
|
1437
1445
|
}
|
|
1438
1446
|
const sourceChain = params.from.chain;
|
|
@@ -1445,21 +1453,7 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1445
1453
|
}
|
|
1446
1454
|
const programPk = new web3_js_1.PublicKey(lockerContract);
|
|
1447
1455
|
const gatewayProgramHex = ('0x' + Buffer.from(programPk.toBytes()).toString('hex'));
|
|
1448
|
-
|
|
1449
|
-
let tokenMintHex;
|
|
1450
|
-
if (((_g = params.funds) === null || _g === void 0 ? void 0 : _g.amount) && params.funds.amount > BigInt(0)) {
|
|
1451
|
-
drainAmount = params.funds.amount;
|
|
1452
|
-
const token = params.funds.token;
|
|
1453
|
-
if (token && token.address) {
|
|
1454
|
-
const mintPk = new web3_js_1.PublicKey(token.address);
|
|
1455
|
-
tokenMintHex = ('0x' + Buffer.from(mintPk.toBytes()).toString('hex'));
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
else if (params.value && params.value > BigInt(0)) {
|
|
1459
|
-
drainAmount = params.value;
|
|
1460
|
-
}
|
|
1461
|
-
// Route 3 SVM: ALWAYS use native PRC-20, CEA uses its own balance.
|
|
1462
|
-
const prc20Token = (0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork);
|
|
1456
|
+
const { prc20Token, drainAmount, tokenMintHex } = resolveR3SvmDrain(params, sourceChain, ctx.pushNetwork);
|
|
1463
1457
|
// Derive CEA PDA as revert recipient
|
|
1464
1458
|
const ueaBytes2 = Buffer.from(ueaAddress.slice(2), 'hex');
|
|
1465
1459
|
const [ceaPda2] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('push_identity'), ueaBytes2], programPk);
|
|
@@ -1468,25 +1462,22 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1468
1462
|
gatewayProgramHex,
|
|
1469
1463
|
drainAmount,
|
|
1470
1464
|
tokenMintHex,
|
|
1465
|
+
extraPayload: buildR3SvmExtraPayload(ctx, params, ueaAddress, sourceChain, nonce + BigInt(1)),
|
|
1471
1466
|
revertRecipientHex: ceaPdaHex2,
|
|
1472
1467
|
});
|
|
1473
|
-
//
|
|
1474
|
-
const burnAmount = BigInt(
|
|
1475
|
-
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(gatewayProgramHex, prc20Token, burnAmount, (
|
|
1468
|
+
// Payload-only outbound: drain amount lives inside ixData.
|
|
1469
|
+
const burnAmount = BigInt(0);
|
|
1470
|
+
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(gatewayProgramHex, prc20Token, burnAmount, (_j = params.gasLimit) !== null && _j !== void 0 ? _j : BigInt(0), svmPayload, ueaAddress, (_k = params.maxPCForGas) !== null && _k !== void 0 ? _k : BigInt(0));
|
|
1476
1471
|
return { payload: svmPayload, gatewayRequest: outboundReq };
|
|
1477
1472
|
}
|
|
1478
|
-
const { cea: ceaAddress } = yield (0, cea_utils_1.getCEAAddress)(ueaAddress, sourceChain, (
|
|
1473
|
+
const { cea: ceaAddress } = yield (0, cea_utils_1.getCEAAddress)(ueaAddress, sourceChain, (_l = ctx.rpcUrls[sourceChain]) === null || _l === void 0 ? void 0 : _l[0]);
|
|
1479
1474
|
// CEA auto-deploys on-chain: Vault.finalizeUniversalTx calls CEAFactory.deployCEA()
|
|
1480
1475
|
// if CEA doesn't exist yet. No SDK-side blocking needed.
|
|
1481
|
-
const gatewayAddr = chain_1.UNIVERSAL_GATEWAY_ADDRESSES[sourceChain];
|
|
1482
|
-
if (!gatewayAddr) {
|
|
1483
|
-
throw new Error(`No UniversalGateway address configured for chain ${sourceChain}`);
|
|
1484
|
-
}
|
|
1485
1476
|
// Build CEA multicalls (self-calls via sendUniversalTxToUEA)
|
|
1486
1477
|
const ceaMulticalls = [];
|
|
1487
1478
|
let tokenAddress = selectors_1.ZERO_ADDRESS;
|
|
1488
1479
|
let amount = BigInt(0);
|
|
1489
|
-
if ((
|
|
1480
|
+
if ((_m = params.funds) === null || _m === void 0 ? void 0 : _m.amount) {
|
|
1490
1481
|
const token = params.funds.token;
|
|
1491
1482
|
if (token) {
|
|
1492
1483
|
if (token.mechanism === 'native') {
|
|
@@ -1496,27 +1487,6 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1496
1487
|
else {
|
|
1497
1488
|
tokenAddress = token.address;
|
|
1498
1489
|
amount = params.funds.amount;
|
|
1499
|
-
// Reset allowance to 0 first for USDT-style tokens, then approve
|
|
1500
|
-
const approveZeroData = (0, viem_1.encodeFunctionData)({
|
|
1501
|
-
abi: erc20_evm_1.ERC20_EVM,
|
|
1502
|
-
functionName: 'approve',
|
|
1503
|
-
args: [gatewayAddr, BigInt(0)],
|
|
1504
|
-
});
|
|
1505
|
-
ceaMulticalls.push({
|
|
1506
|
-
to: tokenAddress,
|
|
1507
|
-
value: BigInt(0),
|
|
1508
|
-
data: approveZeroData,
|
|
1509
|
-
});
|
|
1510
|
-
const approveData = (0, viem_1.encodeFunctionData)({
|
|
1511
|
-
abi: erc20_evm_1.ERC20_EVM,
|
|
1512
|
-
functionName: 'approve',
|
|
1513
|
-
args: [gatewayAddr, amount],
|
|
1514
|
-
});
|
|
1515
|
-
ceaMulticalls.push({
|
|
1516
|
-
to: tokenAddress,
|
|
1517
|
-
value: BigInt(0),
|
|
1518
|
-
data: approveData,
|
|
1519
|
-
});
|
|
1520
1490
|
}
|
|
1521
1491
|
}
|
|
1522
1492
|
}
|
|
@@ -1551,8 +1521,8 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1551
1521
|
// Route 3: CEA uses its own pre-existing balance — no PRC-20 burn needed.
|
|
1552
1522
|
// burnAmount = 0 makes this a payload-only outbound relay.
|
|
1553
1523
|
const burnAmount = BigInt(0);
|
|
1554
|
-
const outboundGasLimit = (
|
|
1555
|
-
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, prc20Token, burnAmount, outboundGasLimit, ceaPayload, ueaAddress);
|
|
1524
|
+
const outboundGasLimit = (_o = params.gasLimit) !== null && _o !== void 0 ? _o : selectors_1.DEFAULT_CEA_TO_PUSH_GAS_LIMIT;
|
|
1525
|
+
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, prc20Token, burnAmount, outboundGasLimit, ceaPayload, ueaAddress, (_p = params.maxPCForGas) !== null && _p !== void 0 ? _p : BigInt(0));
|
|
1556
1526
|
return { payload: ceaPayload, gatewayRequest: outboundReq };
|
|
1557
1527
|
}
|
|
1558
1528
|
default:
|
|
@@ -16,6 +16,11 @@ const enums_1 = require("../../constants/enums");
|
|
|
16
16
|
// ============================================================================
|
|
17
17
|
// EIP-712 Domain Separator (shared by execution & migration hashes)
|
|
18
18
|
// ============================================================================
|
|
19
|
+
// NOTE: Push Chain testnet UEA implementation (UEA_VM[EVM] =
|
|
20
|
+
// 0x4C8401F885c79b0e6e0241812f089e8529045d11) still uses the pre-audit
|
|
21
|
+
// 4-field domain (typehash 0x2aef22f9…) — the salted post-audit typehash
|
|
22
|
+
// 0xb90aaffa… in the audit-fixes contracts hasn't been deployed yet. Drop
|
|
23
|
+
// `salt` until the contracts redeploy. See docs/audit-2026-05/sdk-changes-required.md#11.
|
|
19
24
|
function buildDomainSeparator(vm, chainId, version, verifyingContract) {
|
|
20
25
|
const domainTypeHash = (0, viem_1.keccak256)((0, viem_1.toBytes)(vm === enums_1.VM.EVM
|
|
21
26
|
? 'EIP712Domain(string version,uint256 chainId,address verifyingContract)'
|
|
@@ -23,12 +28,12 @@ function buildDomainSeparator(vm, chainId, version, verifyingContract) {
|
|
|
23
28
|
return (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)([
|
|
24
29
|
{ name: 'typeHash', type: 'bytes32' },
|
|
25
30
|
{ name: 'version', type: 'bytes32' },
|
|
26
|
-
{ name: 'chainId', type: vm === enums_1.VM.EVM ? 'uint256' : '
|
|
31
|
+
{ name: 'chainId', type: vm === enums_1.VM.EVM ? 'uint256' : 'bytes32' },
|
|
27
32
|
{ name: 'verifyingContract', type: 'address' },
|
|
28
33
|
], [
|
|
29
34
|
domainTypeHash,
|
|
30
35
|
(0, viem_1.keccak256)((0, viem_1.toBytes)(version)),
|
|
31
|
-
vm === enums_1.VM.EVM ? BigInt(chainId) : chainId,
|
|
36
|
+
vm === enums_1.VM.EVM ? BigInt(chainId) : (0, viem_1.keccak256)((0, viem_1.toBytes)(chainId)),
|
|
32
37
|
verifyingContract,
|
|
33
38
|
]));
|
|
34
39
|
}
|