@pushchain/core 5.1.18 → 6.0.1
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 +118 -2
- package/src/lib/constants/abi/universalGatewayPC.evm.js +41 -2
- package/src/lib/constants/abi/universalGatewayV0.json +1 -1
- package/src/lib/constants/chain.d.ts +2 -0
- package/src/lib/constants/chain.js +18 -14
- package/src/lib/constants/index.d.ts +1 -1
- package/src/lib/constants/tokens.d.ts +10 -1
- package/src/lib/constants/tokens.js +5 -2
- 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.d.ts +3 -1
- package/src/lib/orchestrator/internals/cascade.js +189 -103
- 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 +2 -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/preflight.d.ts +8 -5
- package/src/lib/orchestrator/internals/preflight.js +35 -21
- package/src/lib/orchestrator/internals/push-chain-tx.js +5 -1
- package/src/lib/orchestrator/internals/route-handlers.js +175 -202
- 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 +157 -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 +6 -6
- package/src/lib/orchestrator/orchestrator.js +10 -3
- package/src/lib/orchestrator/orchestrator.types.d.ts +48 -10
- package/src/lib/orchestrator/payload-builders.d.ts +7 -6
- package/src/lib/orchestrator/payload-builders.js +19 -7
- package/src/lib/progress-hook/progress-hook.js +59 -27
- package/src/lib/progress-hook/progress-hook.types.d.ts +3 -3
- package/src/lib/progress-hook/progress-hook.types.js +4 -2
- package/src/lib/push-chain/push-chain.d.ts +10 -4
- package/src/lib/push-chain/push-chain.js +2 -2
- 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
- package/src/lib/utils.js +1 -1
|
@@ -137,13 +137,14 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
|
|
|
137
137
|
params,
|
|
138
138
|
route: routeStr,
|
|
139
139
|
gasLimit,
|
|
140
|
+
maxPCForGas: (_c = params.maxPCForGas) !== null && _c !== void 0 ? _c : BigInt(0),
|
|
140
141
|
ueaAddress,
|
|
141
142
|
revertRecipient: ueaAddress,
|
|
142
143
|
};
|
|
143
144
|
switch (route) {
|
|
144
145
|
case route_detector_1.TransactionRoute.UOA_TO_PUSH: {
|
|
145
146
|
// Route 1: Build Push Chain multicalls
|
|
146
|
-
const seedAmount = (
|
|
147
|
+
const seedAmount = (_d = params.value) !== null && _d !== void 0 ? _d : BigInt(0);
|
|
147
148
|
if (isValueOnlyNativeSeedToOwnUea(params, ueaAddress)) {
|
|
148
149
|
return Object.assign(Object.assign({}, baseDescriptor), { pushMulticalls: [], nativeSeedOnly: true, nativeSeedAmount: seedAmount });
|
|
149
150
|
}
|
|
@@ -168,7 +169,7 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
|
|
|
168
169
|
});
|
|
169
170
|
let prc20Token = selectors_1.ZERO_ADDRESS;
|
|
170
171
|
let burnAmount = BigInt(0);
|
|
171
|
-
if ((
|
|
172
|
+
if ((_e = params.funds) === null || _e === void 0 ? void 0 : _e.amount) {
|
|
172
173
|
const token = params.funds.token;
|
|
173
174
|
if (token) {
|
|
174
175
|
prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token).address;
|
|
@@ -190,35 +191,46 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
|
|
|
190
191
|
}
|
|
191
192
|
let gasToken = selectors_1.ZERO_ADDRESS;
|
|
192
193
|
let gasFee = BigInt(0);
|
|
194
|
+
let gasPrice = BigInt(0);
|
|
193
195
|
let sizing;
|
|
194
|
-
//
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
// SVM finalize budget: compare the quoted gasFee in lamports against
|
|
197
|
+
// the gateway finalize minimum, then re-query with a bumped gasLimit
|
|
198
|
+
// if the default quote is too low.
|
|
199
|
+
const svmFundsToken = burnAmount > BigInt(0)
|
|
200
|
+
? (_f = params.funds) === null || _f === void 0 ? void 0 : _f.token
|
|
198
201
|
: undefined;
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
splMintBase58,
|
|
204
|
-
burnAmount,
|
|
205
|
-
effectiveGasLimit: gasLimit,
|
|
206
|
-
});
|
|
202
|
+
const splMintBase58 = (svmFundsToken === null || svmFundsToken === void 0 ? void 0 : svmFundsToken.mechanism) === 'approve'
|
|
203
|
+
? svmFundsToken.address
|
|
204
|
+
: undefined;
|
|
205
|
+
let effectiveGasLimit = gasLimit;
|
|
207
206
|
if (prc20Token !== selectors_1.ZERO_ADDRESS) {
|
|
208
|
-
|
|
207
|
+
let result = yield (0, gas_calculator_1.queryOutboundGasFee)(ctx, prc20Token, effectiveGasLimit, targetChain);
|
|
208
|
+
result = yield (0, svm_rent_1.ensureSvmFinalizeGasBudgetQuote)({
|
|
209
|
+
ctx,
|
|
210
|
+
ueaAddress,
|
|
211
|
+
targetChain,
|
|
212
|
+
prc20Token,
|
|
213
|
+
quote: result,
|
|
214
|
+
splMintBase58,
|
|
215
|
+
burnAmount,
|
|
216
|
+
pathTag: 'buildHopDescriptor',
|
|
217
|
+
});
|
|
209
218
|
gasToken = result.gasToken;
|
|
210
219
|
gasFee = result.gasFee;
|
|
220
|
+
gasPrice = result.gasPrice;
|
|
211
221
|
sizing = result.sizing;
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
(0, context_1.printLog)(ctx, `buildHopDescriptor — SVM
|
|
222
|
+
effectiveGasLimit = result.gasLimitUsed;
|
|
223
|
+
if (!params.gasLimit) {
|
|
224
|
+
(0, context_1.printLog)(ctx, `buildHopDescriptor — SVM resolved effectiveGasLimit: ${effectiveGasLimit} ` +
|
|
225
|
+
`(gasFee=${result.gasFee}, gasPrice=${result.gasPrice})`);
|
|
215
226
|
}
|
|
216
227
|
}
|
|
217
228
|
return Object.assign(Object.assign({}, baseDescriptor), { targetChain, isSvmTarget: true, svmPayload,
|
|
218
229
|
prc20Token,
|
|
219
230
|
burnAmount,
|
|
220
231
|
gasToken,
|
|
221
|
-
gasFee,
|
|
232
|
+
gasFee,
|
|
233
|
+
gasPrice, gasLimit: effectiveGasLimit, sizing });
|
|
222
234
|
}
|
|
223
235
|
// EVM path: Resolve CEA address + build CEA multicalls
|
|
224
236
|
const { cea: ceaAddress } = yield (0, cea_utils_1.getCEAAddress)(ueaAddress, targetChain, (_g = ctx.rpcUrls[targetChain]) === null || _g === void 0 ? void 0 : _g[0]);
|
|
@@ -228,18 +240,21 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
|
|
|
228
240
|
const burnAmount = BigInt(0); // Migration is logic-only — no funds. CEA rejects msg.value != 0.
|
|
229
241
|
let gasToken = selectors_1.ZERO_ADDRESS;
|
|
230
242
|
let gasFee = BigInt(0);
|
|
243
|
+
let gasPrice = BigInt(0);
|
|
231
244
|
let sizing;
|
|
232
245
|
if (prc20Token !== selectors_1.ZERO_ADDRESS) {
|
|
233
246
|
const result = yield (0, gas_calculator_1.queryOutboundGasFee)(ctx, prc20Token, gasLimit, targetChain);
|
|
234
247
|
gasToken = result.gasToken;
|
|
235
248
|
gasFee = result.gasFee;
|
|
249
|
+
gasPrice = result.gasPrice;
|
|
236
250
|
sizing = result.sizing;
|
|
237
251
|
}
|
|
238
252
|
return Object.assign(Object.assign({}, baseDescriptor), { targetChain,
|
|
239
253
|
ceaAddress, ceaMulticalls: [], prc20Token,
|
|
240
254
|
burnAmount,
|
|
241
255
|
gasToken,
|
|
242
|
-
gasFee,
|
|
256
|
+
gasFee,
|
|
257
|
+
gasPrice, isMigration: true, sizing });
|
|
243
258
|
}
|
|
244
259
|
// Build CEA multicalls
|
|
245
260
|
const ceaMulticalls = [];
|
|
@@ -342,11 +357,13 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
|
|
|
342
357
|
// Query gas fee
|
|
343
358
|
let gasToken = selectors_1.ZERO_ADDRESS;
|
|
344
359
|
let gasFee = BigInt(0);
|
|
360
|
+
let gasPrice = BigInt(0);
|
|
345
361
|
let sizing;
|
|
346
362
|
if (prc20Token !== selectors_1.ZERO_ADDRESS) {
|
|
347
363
|
const result = yield (0, gas_calculator_1.queryOutboundGasFee)(ctx, prc20Token, gasLimit, targetChain);
|
|
348
364
|
gasToken = result.gasToken;
|
|
349
365
|
gasFee = result.gasFee;
|
|
366
|
+
gasPrice = result.gasPrice;
|
|
350
367
|
sizing = result.sizing;
|
|
351
368
|
}
|
|
352
369
|
return Object.assign(Object.assign({}, baseDescriptor), { targetChain,
|
|
@@ -356,6 +373,7 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
|
|
|
356
373
|
burnAmount,
|
|
357
374
|
gasToken,
|
|
358
375
|
gasFee,
|
|
376
|
+
gasPrice,
|
|
359
377
|
sizing });
|
|
360
378
|
}
|
|
361
379
|
case route_detector_1.TransactionRoute.CEA_TO_PUSH: {
|
|
@@ -401,19 +419,33 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
|
|
|
401
419
|
}
|
|
402
420
|
let gasToken = selectors_1.ZERO_ADDRESS;
|
|
403
421
|
let gasFee = BigInt(0);
|
|
422
|
+
let gasPrice = BigInt(0);
|
|
404
423
|
let sizing;
|
|
424
|
+
let effectiveGasLimit = gasLimit;
|
|
405
425
|
if (prc20Token !== selectors_1.ZERO_ADDRESS) {
|
|
406
|
-
|
|
426
|
+
let result = yield (0, gas_calculator_1.queryOutboundGasFee)(ctx, prc20Token, effectiveGasLimit, sourceChain);
|
|
427
|
+
result = yield (0, svm_rent_1.ensureSvmFinalizeGasBudgetQuote)({
|
|
428
|
+
ctx,
|
|
429
|
+
ueaAddress,
|
|
430
|
+
targetChain: sourceChain,
|
|
431
|
+
prc20Token,
|
|
432
|
+
quote: result,
|
|
433
|
+
splMintBase58: undefined,
|
|
434
|
+
burnAmount: BigInt(0),
|
|
435
|
+
pathTag: 'buildHopDescriptor',
|
|
436
|
+
});
|
|
407
437
|
gasToken = result.gasToken;
|
|
408
438
|
gasFee = result.gasFee;
|
|
439
|
+
gasPrice = result.gasPrice;
|
|
409
440
|
sizing = result.sizing;
|
|
441
|
+
effectiveGasLimit = result.gasLimitUsed;
|
|
410
442
|
}
|
|
411
443
|
return Object.assign(Object.assign({}, baseDescriptor), { sourceChain, ceaAddress: ceaPdaHex, isSvmTarget: true, prc20Token,
|
|
412
444
|
// Route 3 is payload-only on Push: the drain amount lives inside the
|
|
413
445
|
// SVM payload. Burning here would require the UEA to pre-hold pSOL.
|
|
414
446
|
burnAmount: BigInt(0), gasToken,
|
|
415
447
|
gasFee,
|
|
416
|
-
sizing });
|
|
448
|
+
gasPrice, gasLimit: effectiveGasLimit, sizing });
|
|
417
449
|
}
|
|
418
450
|
const { cea: ceaAddress } = yield (0, cea_utils_1.getCEAAddress)(ueaAddress, sourceChain, (_p = ctx.rpcUrls[sourceChain]) === null || _p === void 0 ? void 0 : _p[0]);
|
|
419
451
|
// CEA auto-deploys on-chain: Vault.finalizeUniversalTx calls CEAFactory.deployCEA()
|
|
@@ -443,11 +475,13 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
|
|
|
443
475
|
const prc20Token = (0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork);
|
|
444
476
|
let gasToken = selectors_1.ZERO_ADDRESS;
|
|
445
477
|
let gasFee = BigInt(0);
|
|
478
|
+
let gasPrice = BigInt(0);
|
|
446
479
|
let sizing;
|
|
447
480
|
if (prc20Token !== selectors_1.ZERO_ADDRESS) {
|
|
448
481
|
const result = yield (0, gas_calculator_1.queryOutboundGasFee)(ctx, prc20Token, gasLimit, sourceChain);
|
|
449
482
|
gasToken = result.gasToken;
|
|
450
483
|
gasFee = result.gasFee;
|
|
484
|
+
gasPrice = result.gasPrice;
|
|
451
485
|
sizing = result.sizing;
|
|
452
486
|
}
|
|
453
487
|
return Object.assign(Object.assign({}, baseDescriptor), { sourceChain,
|
|
@@ -458,6 +492,7 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
|
|
|
458
492
|
// token it is trying to receive from the external CEA.
|
|
459
493
|
burnAmount: BigInt(0), gasToken,
|
|
460
494
|
gasFee,
|
|
495
|
+
gasPrice,
|
|
461
496
|
sizing });
|
|
462
497
|
}
|
|
463
498
|
default:
|
|
@@ -512,6 +547,8 @@ function classifyIntoSegments(hops) {
|
|
|
512
547
|
// Accumulate gas fees
|
|
513
548
|
currentSegment.gasFee =
|
|
514
549
|
(currentSegment.gasFee || BigInt(0)) + (hop.gasFee || BigInt(0));
|
|
550
|
+
currentSegment.gasPrice = mergeGasPrice(currentSegment.gasPrice, hop.gasPrice);
|
|
551
|
+
currentSegment.maxPCForGas = mergeMaxPCForGas(currentSegment.maxPCForGas, hop.maxPCForGas);
|
|
515
552
|
}
|
|
516
553
|
else if (segType === 'INBOUND_FROM_CEA') {
|
|
517
554
|
// Sum burn amounts so the single sendUniversalTxToUEA carries the
|
|
@@ -524,6 +561,8 @@ function classifyIntoSegments(hops) {
|
|
|
524
561
|
}
|
|
525
562
|
currentSegment.gasFee =
|
|
526
563
|
(currentSegment.gasFee || BigInt(0)) + (hop.gasFee || BigInt(0));
|
|
564
|
+
currentSegment.gasPrice = mergeGasPrice(currentSegment.gasPrice, hop.gasPrice);
|
|
565
|
+
currentSegment.maxPCForGas = mergeMaxPCForGas(currentSegment.maxPCForGas, hop.maxPCForGas);
|
|
527
566
|
}
|
|
528
567
|
else if (segType === 'PUSH_EXECUTION') {
|
|
529
568
|
currentSegment.mergedPushMulticalls = [
|
|
@@ -561,7 +600,9 @@ function classifyIntoSegments(hops) {
|
|
|
561
600
|
prc20Token: hop.prc20Token,
|
|
562
601
|
gasToken: hop.gasToken,
|
|
563
602
|
gasFee: hop.gasFee,
|
|
603
|
+
gasPrice: hop.gasPrice,
|
|
564
604
|
gasLimit: hop.gasLimit,
|
|
605
|
+
maxPCForGas: hop.maxPCForGas,
|
|
565
606
|
sizing: hop.sizing,
|
|
566
607
|
};
|
|
567
608
|
segments.push(currentSegment);
|
|
@@ -573,6 +614,18 @@ function classifyIntoSegments(hops) {
|
|
|
573
614
|
function categoryRank(c) {
|
|
574
615
|
return c === 'C' ? 2 : c === 'B' ? 1 : 0;
|
|
575
616
|
}
|
|
617
|
+
function mergeMaxPCForGas(current, next) {
|
|
618
|
+
const a = current !== null && current !== void 0 ? current : BigInt(0);
|
|
619
|
+
const b = next !== null && next !== void 0 ? next : BigInt(0);
|
|
620
|
+
if (a === BigInt(0) || b === BigInt(0))
|
|
621
|
+
return BigInt(0);
|
|
622
|
+
return a + b;
|
|
623
|
+
}
|
|
624
|
+
function mergeGasPrice(current, next) {
|
|
625
|
+
const a = current !== null && current !== void 0 ? current : BigInt(0);
|
|
626
|
+
const b = next !== null && next !== void 0 ? next : BigInt(0);
|
|
627
|
+
return a > b ? a : b;
|
|
628
|
+
}
|
|
576
629
|
// ============================================================================
|
|
577
630
|
// getSegmentType
|
|
578
631
|
// ============================================================================
|
|
@@ -615,6 +668,34 @@ function isNativeSeedOnlySegment(segment) {
|
|
|
615
668
|
function segmentNeedsOutboundGas(segment) {
|
|
616
669
|
return segment.type !== 'PUSH_EXECUTION' && !isNativeSeedOnlySegment(segment);
|
|
617
670
|
}
|
|
671
|
+
function buildRootOutboundIndexByHop(segments, hops) {
|
|
672
|
+
var _a;
|
|
673
|
+
const hopIndexByDescriptor = new Map();
|
|
674
|
+
hops.forEach((hop, index) => hopIndexByDescriptor.set(hop, index));
|
|
675
|
+
const nextIndexByChain = new Map();
|
|
676
|
+
const result = new Map();
|
|
677
|
+
for (const segment of segments) {
|
|
678
|
+
let chain;
|
|
679
|
+
if (segment.type === 'OUTBOUND_TO_CEA') {
|
|
680
|
+
chain = segment.targetChain;
|
|
681
|
+
}
|
|
682
|
+
else if (segment.type === 'INBOUND_FROM_CEA' &&
|
|
683
|
+
!isNativeSeedOnlySegment(segment)) {
|
|
684
|
+
chain = segment.sourceChain;
|
|
685
|
+
}
|
|
686
|
+
if (!chain)
|
|
687
|
+
continue;
|
|
688
|
+
const outboundIndex = (_a = nextIndexByChain.get(chain)) !== null && _a !== void 0 ? _a : 0;
|
|
689
|
+
for (const hop of segment.hops) {
|
|
690
|
+
const hopIndex = hopIndexByDescriptor.get(hop);
|
|
691
|
+
if (hopIndex !== undefined) {
|
|
692
|
+
result.set(hopIndex, outboundIndex);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
nextIndexByChain.set(chain, outboundIndex + 1);
|
|
696
|
+
}
|
|
697
|
+
return result;
|
|
698
|
+
}
|
|
618
699
|
function sumNativeSeedAmount(hops) {
|
|
619
700
|
return hops.reduce((sum, hop) => { var _a; return sum + ((_a = hop.nativeSeedAmount) !== null && _a !== void 0 ? _a : BigInt(0)); }, BigInt(0));
|
|
620
701
|
}
|
|
@@ -672,15 +753,17 @@ function getInboundFundingForBurnToken(segments, beforeSegmentIndex, burnToken,
|
|
|
672
753
|
}
|
|
673
754
|
return total;
|
|
674
755
|
}
|
|
675
|
-
function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce) {
|
|
756
|
+
function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce, options) {
|
|
676
757
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
677
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
758
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
678
759
|
let accumulatedPushMulticalls = [];
|
|
679
760
|
let requiredNativeValue = BigInt(0);
|
|
680
761
|
const gatewayPcAddress = (0, helpers_1.getUniversalGatewayPCAddress)();
|
|
681
762
|
const currentUeaBalance = ueaBalance !== null && ueaBalance !== void 0 ? ueaBalance : BigInt(0);
|
|
682
763
|
const cascadeNativeSeed = getCascadeNativeSeed(segments);
|
|
683
764
|
const effectiveUeaBalance = currentUeaBalance + cascadeNativeSeed;
|
|
765
|
+
const enforceGasCheck = (options === null || options === void 0 ? void 0 : options.enforceGasCheck) === true ||
|
|
766
|
+
segments.some((segment) => segment.hops.some((hop) => { var _a; return ((_a = hop.params.options) === null || _a === void 0 ? void 0 : _a.enforceGasCheck) === true; }));
|
|
684
767
|
if (cascadeNativeSeed > BigInt(0)) {
|
|
685
768
|
(0, context_1.printLog)(ctx, `composeCascade — counting cascade native seed ${cascadeNativeSeed.toString()} for cascade sizing (current UEA balance ${currentUeaBalance.toString()})`);
|
|
686
769
|
}
|
|
@@ -692,8 +775,8 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
692
775
|
// Cascade pre-flight: catches the zero-balance silent-segment-zero failure
|
|
693
776
|
// mode. When `ueaBalance <= CASCADE_GAS_RESERVE`, `perOutboundNativeValue`
|
|
694
777
|
// is left undefined and downstream segments silently allocate value=0,
|
|
695
|
-
// producing under-funded swaps that revert inside Uniswap.
|
|
696
|
-
//
|
|
778
|
+
// producing under-funded swaps that revert inside Uniswap. Warn by default
|
|
779
|
+
// and throw only when enforceGasCheck=true.
|
|
697
780
|
if (numOutbounds > 0) {
|
|
698
781
|
(0, preflight_1.runPreflight)({
|
|
699
782
|
ctx,
|
|
@@ -704,6 +787,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
704
787
|
requiredValue: BigInt(1),
|
|
705
788
|
gasReserve: CASCADE_GAS_RESERVE,
|
|
706
789
|
pathTag: 'CASCADE',
|
|
790
|
+
enforceGasCheck,
|
|
707
791
|
});
|
|
708
792
|
}
|
|
709
793
|
let perOutboundNativeValue;
|
|
@@ -729,7 +813,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
729
813
|
const universalCoreAddress = yield ctx.pushClient.readContract({
|
|
730
814
|
address: gatewayPcAddress,
|
|
731
815
|
abi: abi_1.UNIVERSAL_GATEWAY_PC,
|
|
732
|
-
functionName: '
|
|
816
|
+
functionName: 'universalCore',
|
|
733
817
|
args: [],
|
|
734
818
|
});
|
|
735
819
|
// Compute per-SVM budget = ueaBalance − (PC needed for EVM outbounds) − 1 PC safety
|
|
@@ -786,6 +870,17 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
786
870
|
// knows which hop's pool is misbehaving.
|
|
787
871
|
if (estimated > BigInt(0) && value < estimated) {
|
|
788
872
|
const shortfall = estimated - value;
|
|
873
|
+
(0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_003_03, estimated, value, false, ueaAddress, 'CASCADE', {
|
|
874
|
+
kind: 'NATIVE',
|
|
875
|
+
segmentIndex: cascadeIdx,
|
|
876
|
+
enforceGasCheck,
|
|
877
|
+
shortfall,
|
|
878
|
+
});
|
|
879
|
+
if (!enforceGasCheck) {
|
|
880
|
+
(0, context_1.printLog)(ctx, `composeCascade — SVM outbound segment ${cascadeIdx} has native shortfall ${shortfall.toString()}; proceeding because enforceGasCheck=false`);
|
|
881
|
+
svmNativeValueBySegment.set(seg, value);
|
|
882
|
+
continue;
|
|
883
|
+
}
|
|
789
884
|
(0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_003_04, estimated, value, shortfall, ueaAddress, 'CASCADE', { kind: 'NATIVE', segmentIndex: cascadeIdx });
|
|
790
885
|
throw new errors_1.InsufficientUEABalanceError({
|
|
791
886
|
required: estimated,
|
|
@@ -838,7 +933,10 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
838
933
|
// EVM: build CEA payload from merged multicalls
|
|
839
934
|
outboundPayload = (0, payload_builders_1.buildCeaMulticallPayload)(segment.mergedCeaMulticalls || []);
|
|
840
935
|
// Get CEA address from the first hop
|
|
841
|
-
targetForOutbound =
|
|
936
|
+
targetForOutbound = outboundPayload === '0x'
|
|
937
|
+
? selectors_1.ZERO_ADDRESS
|
|
938
|
+
: (firstHop === null || firstHop === void 0 ? void 0 : firstHop.ceaAddress) || ueaAddress;
|
|
939
|
+
(0, payload_builders_1.assertCeaFundsParkingInvariant)(targetForOutbound, outboundPayload);
|
|
842
940
|
}
|
|
843
941
|
// Per-segment PRC-20 burn-balance pre-check (cascade R2-style segments
|
|
844
942
|
// only — INBOUND_FROM_CEA segments are payload-only with totalBurnAmount=0
|
|
@@ -856,7 +954,13 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
856
954
|
args: [ueaAddress],
|
|
857
955
|
});
|
|
858
956
|
const sufficient = onHand >= segBurnAmount;
|
|
859
|
-
(0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_003_03, segBurnAmount, onHand, sufficient, ueaAddress, 'CASCADE', {
|
|
957
|
+
(0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_003_03, segBurnAmount, onHand, sufficient, ueaAddress, 'CASCADE', {
|
|
958
|
+
kind: 'PRC20',
|
|
959
|
+
burnToken: segBurnToken,
|
|
960
|
+
segmentIndex: segIdxLoop,
|
|
961
|
+
enforceGasCheck,
|
|
962
|
+
shortfall: sufficient ? BigInt(0) : segBurnAmount - onHand,
|
|
963
|
+
});
|
|
860
964
|
const priorPushExecutionMayFundBurn = segments
|
|
861
965
|
.slice(0, segIdxLoop)
|
|
862
966
|
.some((s) => s.type === 'PUSH_EXECUTION');
|
|
@@ -867,21 +971,26 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
867
971
|
!priorInboundMayFundBurn) {
|
|
868
972
|
const projectedOnHand = onHand + priorInboundFundingForBurn;
|
|
869
973
|
const shortfall = segBurnAmount - projectedOnHand;
|
|
870
|
-
(
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
974
|
+
if (!enforceGasCheck) {
|
|
975
|
+
(0, context_1.printLog)(ctx, `composeCascade — PRC-20 shortfall ${shortfall.toString()} for segment ${segIdxLoop}; proceeding because enforceGasCheck=false`);
|
|
976
|
+
}
|
|
977
|
+
else {
|
|
978
|
+
(0, context_2.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_003_04, segBurnAmount, projectedOnHand, shortfall, ueaAddress, 'CASCADE', {
|
|
979
|
+
kind: 'PRC20',
|
|
980
|
+
burnToken: segBurnToken,
|
|
981
|
+
segmentIndex: segIdxLoop,
|
|
982
|
+
});
|
|
983
|
+
throw new errors_1.InsufficientUEABalanceError({
|
|
984
|
+
required: segBurnAmount,
|
|
985
|
+
available: projectedOnHand,
|
|
986
|
+
shortfall,
|
|
987
|
+
ueaAddress,
|
|
988
|
+
pathTag: 'CASCADE',
|
|
989
|
+
reason: 'PRC20',
|
|
990
|
+
burnToken: segBurnToken,
|
|
991
|
+
segmentIndex: segIdxLoop,
|
|
992
|
+
});
|
|
993
|
+
}
|
|
885
994
|
}
|
|
886
995
|
else if (!sufficient && priorPushExecutionMayFundBurn) {
|
|
887
996
|
(0, context_1.printLog)(ctx, `composeCascade — skipping PRC-20 preflight failure for segment ${segIdxLoop}; earlier Push execution may fund ${segBurnToken} before this outbound runs`);
|
|
@@ -891,7 +1000,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
891
1000
|
}
|
|
892
1001
|
}
|
|
893
1002
|
// Build outbound request
|
|
894
|
-
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetForOutbound, segment.prc20Token || selectors_1.ZERO_ADDRESS, segment.totalBurnAmount || BigInt(0), (_e = segment.gasLimit) !== null && _e !== void 0 ? _e : BigInt(0), outboundPayload, ueaAddress);
|
|
1003
|
+
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetForOutbound, segment.prc20Token || selectors_1.ZERO_ADDRESS, segment.totalBurnAmount || BigInt(0), (_e = segment.gasLimit) !== null && _e !== void 0 ? _e : BigInt(0), outboundPayload, ueaAddress, (_f = segment.maxPCForGas) !== null && _f !== void 0 ? _f : BigInt(0), (_g = segment.gasPrice) !== null && _g !== void 0 ? _g : BigInt(0));
|
|
895
1004
|
// Build approval + outbound multicalls
|
|
896
1005
|
const segGasFee = segment.gasFee || BigInt(0);
|
|
897
1006
|
const svmOverride = svmNativeValueBySegment.get(segment);
|
|
@@ -908,7 +1017,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
908
1017
|
else {
|
|
909
1018
|
evmFallbackValue = segGasFee * BigInt(1000000);
|
|
910
1019
|
}
|
|
911
|
-
let nativeValueForGas = (
|
|
1020
|
+
let nativeValueForGas = (_h = svmOverride !== null && svmOverride !== void 0 ? svmOverride : perOutboundNativeValue) !== null && _h !== void 0 ? _h : evmFallbackValue;
|
|
912
1021
|
// SDK 5.2 Case C: when the segment's sizing is category C, compose
|
|
913
1022
|
// R2/OUTBOUND_TO_CEA segments no longer apply Case A/B/C sizing
|
|
914
1023
|
// (scoped to R1 + R3 only). segment.sizing may still be populated
|
|
@@ -949,7 +1058,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
949
1058
|
// UEA multicall so no nested outbound is needed.
|
|
950
1059
|
const mergedHopMulticalls = [];
|
|
951
1060
|
for (const h of segment.hops) {
|
|
952
|
-
if (((
|
|
1061
|
+
if (((_j = h === null || h === void 0 ? void 0 : h.params) === null || _j === void 0 ? void 0 : _j.data) || ((_k = h === null || h === void 0 ? void 0 : h.params) === null || _k === void 0 ? void 0 : _k.value)) {
|
|
953
1062
|
const hopCalls = (0, payload_builders_1.buildExecuteMulticall)({
|
|
954
1063
|
execute: {
|
|
955
1064
|
to: h.params.to,
|
|
@@ -993,7 +1102,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
993
1102
|
let drainAmount = BigInt(0);
|
|
994
1103
|
let tokenMintHex;
|
|
995
1104
|
const params = hop.params;
|
|
996
|
-
if (((
|
|
1105
|
+
if (((_l = params.funds) === null || _l === void 0 ? void 0 : _l.amount) && params.funds.amount > BigInt(0)) {
|
|
997
1106
|
drainAmount = params.funds.amount;
|
|
998
1107
|
const token = params.funds.token;
|
|
999
1108
|
if (token && token.address) {
|
|
@@ -1022,7 +1131,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
1022
1131
|
});
|
|
1023
1132
|
const svmBurnAmount = segment.totalBurnAmount || BigInt(0);
|
|
1024
1133
|
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(gatewayProgramHex, segment.prc20Token ||
|
|
1025
|
-
(0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork), svmBurnAmount, (
|
|
1134
|
+
(0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork), svmBurnAmount, (_m = segment.gasLimit) !== null && _m !== void 0 ? _m : BigInt(0), svmPayload, ueaAddress, (_o = segment.maxPCForGas) !== null && _o !== void 0 ? _o : BigInt(0), (_p = segment.gasPrice) !== null && _p !== void 0 ? _p : BigInt(0));
|
|
1026
1135
|
const inboundGasFee = segment.gasFee || BigInt(0);
|
|
1027
1136
|
let svmInboundFallback;
|
|
1028
1137
|
if (effectiveUeaBalance > BigInt(0)) {
|
|
@@ -1036,7 +1145,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
1036
1145
|
// SDK 5.2 R3-style Case C bump: when the inbound segment's sizing
|
|
1037
1146
|
// is C, top up the swap budget by the overflow. No bridge-swap —
|
|
1038
1147
|
// R3 has no destination funds delivery.
|
|
1039
|
-
if (((
|
|
1148
|
+
if (((_q = segment.sizing) === null || _q === void 0 ? void 0 : _q.category) === 'C' &&
|
|
1040
1149
|
segment.sizing.overflowNativePc > BigInt(0)) {
|
|
1041
1150
|
const bumped = svmInboundNativeValue + segment.sizing.overflowNativePc;
|
|
1042
1151
|
(0, context_1.printLog)(ctx, `composeCascade — INBOUND_FROM_CEA (SVM) Case C: bumping nativeValueForGas from ${svmInboundNativeValue} to ${bumped} (overflow=${segment.sizing.overflowNativePc})`);
|
|
@@ -1056,7 +1165,8 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
1056
1165
|
accumulatedPushMulticalls = [...outboundMulticalls];
|
|
1057
1166
|
break;
|
|
1058
1167
|
}
|
|
1059
|
-
// EVM path: Build CEA multicall:
|
|
1168
|
+
// EVM path: Build CEA multicall: sendUniversalTxToUEA(payload).
|
|
1169
|
+
// CEA handles ERC20 gateway approval internally.
|
|
1060
1170
|
const ceaMulticalls = [];
|
|
1061
1171
|
// Add primary hop's own CEA operations if any
|
|
1062
1172
|
// (e.g., approve + swap before bridging back)
|
|
@@ -1072,7 +1182,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
1072
1182
|
let amount = BigInt(0);
|
|
1073
1183
|
for (const mergedHop of segment.hops) {
|
|
1074
1184
|
const hParams = mergedHop.params;
|
|
1075
|
-
if ((
|
|
1185
|
+
if ((_r = hParams.funds) === null || _r === void 0 ? void 0 : _r.amount) {
|
|
1076
1186
|
const token = hParams.funds.token;
|
|
1077
1187
|
if (token) {
|
|
1078
1188
|
if (token.mechanism === 'native') {
|
|
@@ -1086,32 +1196,6 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
1086
1196
|
}
|
|
1087
1197
|
tokenAddress = addr;
|
|
1088
1198
|
amount += hParams.funds.amount;
|
|
1089
|
-
// CEA approves gateway once with the cumulative allowance.
|
|
1090
|
-
const gatewayAddr = chain_1.UNIVERSAL_GATEWAY_ADDRESSES[sourceChain];
|
|
1091
|
-
if (!gatewayAddr) {
|
|
1092
|
-
throw new Error(`No UniversalGateway address configured for chain ${sourceChain}`);
|
|
1093
|
-
}
|
|
1094
|
-
// Reset allowance to 0 first for USDT-style tokens
|
|
1095
|
-
const approveZeroData = (0, viem_1.encodeFunctionData)({
|
|
1096
|
-
abi: erc20_evm_1.ERC20_EVM,
|
|
1097
|
-
functionName: 'approve',
|
|
1098
|
-
args: [gatewayAddr, BigInt(0)],
|
|
1099
|
-
});
|
|
1100
|
-
ceaMulticalls.push({
|
|
1101
|
-
to: tokenAddress,
|
|
1102
|
-
value: BigInt(0),
|
|
1103
|
-
data: approveZeroData,
|
|
1104
|
-
});
|
|
1105
|
-
const approveData = (0, viem_1.encodeFunctionData)({
|
|
1106
|
-
abi: erc20_evm_1.ERC20_EVM,
|
|
1107
|
-
functionName: 'approve',
|
|
1108
|
-
args: [gatewayAddr, hParams.funds.amount],
|
|
1109
|
-
});
|
|
1110
|
-
ceaMulticalls.push({
|
|
1111
|
-
to: tokenAddress,
|
|
1112
|
-
value: BigInt(0),
|
|
1113
|
-
data: approveData,
|
|
1114
|
-
});
|
|
1115
1199
|
}
|
|
1116
1200
|
}
|
|
1117
1201
|
}
|
|
@@ -1134,7 +1218,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
1134
1218
|
? segment.gasLimit
|
|
1135
1219
|
: selectors_1.DEFAULT_CEA_TO_PUSH_GAS_LIMIT;
|
|
1136
1220
|
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, segment.prc20Token ||
|
|
1137
|
-
(0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork), segment.totalBurnAmount || BigInt(0), effectiveGasLimit, ceaPayload, ueaAddress);
|
|
1221
|
+
(0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork), segment.totalBurnAmount || BigInt(0), effectiveGasLimit, ceaPayload, ueaAddress, (_s = segment.maxPCForGas) !== null && _s !== void 0 ? _s : BigInt(0), (_t = segment.gasPrice) !== null && _t !== void 0 ? _t : BigInt(0));
|
|
1138
1222
|
const inboundGasFee = segment.gasFee || BigInt(0);
|
|
1139
1223
|
let evmInboundFallback;
|
|
1140
1224
|
if (effectiveUeaBalance > BigInt(0)) {
|
|
@@ -1148,7 +1232,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce)
|
|
|
1148
1232
|
// SDK 5.2 R3-style Case C bump: when the inbound segment's sizing
|
|
1149
1233
|
// is C, top up the swap budget by the overflow. No bridge-swap —
|
|
1150
1234
|
// R3 has no destination funds delivery.
|
|
1151
|
-
if (((
|
|
1235
|
+
if (((_u = segment.sizing) === null || _u === void 0 ? void 0 : _u.category) === 'C' &&
|
|
1152
1236
|
segment.sizing.overflowNativePc > BigInt(0)) {
|
|
1153
1237
|
const bumped = evmInboundNativeValue + segment.sizing.overflowNativePc;
|
|
1154
1238
|
(0, context_1.printLog)(ctx, `composeCascade — INBOUND_FROM_CEA (EVM) Case C: bumping nativeValueForGas from ${evmInboundNativeValue} to ${bumped} (overflow=${segment.sizing.overflowNativePc})`);
|
|
@@ -1193,11 +1277,14 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1193
1277
|
const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
|
|
1194
1278
|
// Extract HopDescriptors
|
|
1195
1279
|
const hops = preparedTxs.map((tx) => tx._hop);
|
|
1280
|
+
const enforceGasCheck = hops.some((hop) => { var _a; return ((_a = hop.params.options) === null || _a === void 0 ? void 0 : _a.enforceGasCheck) === true; });
|
|
1281
|
+
const withCascadeOptions = (params) => enforceGasCheck
|
|
1282
|
+
? Object.assign(Object.assign({}, params), { options: Object.assign(Object.assign({}, params.options), { enforceGasCheck: true }) }) : params;
|
|
1196
1283
|
// Classify into segments
|
|
1197
1284
|
const segments = classifyIntoSegments(hops);
|
|
1198
1285
|
// Check if this is a single-hop Route 1 (no composition needed)
|
|
1199
1286
|
if (preparedTxs.length === 1 && preparedTxs[0].route === 'UOA_TO_PUSH') {
|
|
1200
|
-
const response = yield callbacks.executeFn(hops[0].params);
|
|
1287
|
+
const response = yield callbacks.executeFn(withCascadeOptions(hops[0].params));
|
|
1201
1288
|
const singleRoute1Result = {
|
|
1202
1289
|
initialTxHash: response.hash,
|
|
1203
1290
|
initialTxResponse: response,
|
|
@@ -1231,7 +1318,7 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1231
1318
|
}
|
|
1232
1319
|
// Check if single-hop Route 2 (just execute directly)
|
|
1233
1320
|
if (preparedTxs.length === 1 && preparedTxs[0].route === 'UOA_TO_CEA') {
|
|
1234
|
-
const response = yield callbacks.executeFn(hops[0].params);
|
|
1321
|
+
const response = yield callbacks.executeFn(withCascadeOptions(hops[0].params));
|
|
1235
1322
|
const targetChain = hops[0].targetChain || (0, helpers_1.getPushChainForNetwork)(ctx.pushNetwork);
|
|
1236
1323
|
const singleRoute2Result = {
|
|
1237
1324
|
initialTxHash: response.hash,
|
|
@@ -1276,7 +1363,7 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1276
1363
|
let composedMulticalls;
|
|
1277
1364
|
let cascadeRequiredNativeValue = BigInt(0);
|
|
1278
1365
|
try {
|
|
1279
|
-
const composed = yield composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonceCascade);
|
|
1366
|
+
const composed = yield composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonceCascade, { enforceGasCheck });
|
|
1280
1367
|
composedMulticalls = composed.multicalls;
|
|
1281
1368
|
cascadeRequiredNativeValue = composed.requiredNativeValue;
|
|
1282
1369
|
}
|
|
@@ -1319,7 +1406,7 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1319
1406
|
hops: hopInfos,
|
|
1320
1407
|
hopCount: hops.length,
|
|
1321
1408
|
waitForAll: (opts) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1322
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
1409
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1323
1410
|
const { pollingIntervalMs = 10000, timeout = 300000, progressHook: cascadeProgressHook, eventHook = defaultEventHook, } = opts || {};
|
|
1324
1411
|
const startTime = Date.now();
|
|
1325
1412
|
// Per-hop progress emission. Fans out cascade markers to BOTH the
|
|
@@ -1398,8 +1485,9 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1398
1485
|
yield response.wait();
|
|
1399
1486
|
const ceaToPushIndex = hopInfos.findIndex((h, index) => h.route === 'CEA_TO_PUSH' && !isNativeSeedOnlyHop(hops[index]));
|
|
1400
1487
|
const isAfterCeaToPush = (index) => ceaToPushIndex >= 0 && index > ceaToPushIndex;
|
|
1401
|
-
const
|
|
1402
|
-
|
|
1488
|
+
const rootOutboundIndexByHop = buildRootOutboundIndexByHop(segments, hops);
|
|
1489
|
+
const trackOutboundHops = (outboundHops, pushTxHash, resolvedSubTxId, outboundIndexByHop) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1490
|
+
var _a, _b, _c, _d;
|
|
1403
1491
|
if (outboundHops.length === 0)
|
|
1404
1492
|
return null;
|
|
1405
1493
|
if (outboundHops.length === 1) {
|
|
@@ -1434,13 +1522,11 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1434
1522
|
});
|
|
1435
1523
|
let lastEmittedStatus;
|
|
1436
1524
|
try {
|
|
1437
|
-
const outboundDetails = yield callbacks.waitForOutboundTxFn(pushTxHash, {
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
_expectedDestinationChain: hop.executionChain,
|
|
1443
|
-
progressHook: (event) => {
|
|
1525
|
+
const outboundDetails = yield callbacks.waitForOutboundTxFn(pushTxHash, Object.assign(Object.assign({ initialWaitMs: Math.min(60000, remainingTimeout), pollingIntervalMs, timeout: remainingTimeout, _resolvedSubTxId: resolvedSubTxId, _expectedDestinationChain: hop.executionChain }, (outboundIndexByHop
|
|
1526
|
+
? {
|
|
1527
|
+
_outboundIndex: (_a = outboundIndexByHop.get(hop.hopIndex)) !== null && _a !== void 0 ? _a : 0,
|
|
1528
|
+
}
|
|
1529
|
+
: {})), { progressHook: (event) => {
|
|
1444
1530
|
cascadeProgressHook === null || cascadeProgressHook === void 0 ? void 0 : cascadeProgressHook({
|
|
1445
1531
|
hopIndex: hop.hopIndex,
|
|
1446
1532
|
route: hop.route,
|
|
@@ -1453,14 +1539,13 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1453
1539
|
lastEmittedStatus = 'polling';
|
|
1454
1540
|
emitHopEvent(hopHooks.polling(hop.executionChain, event.elapsed));
|
|
1455
1541
|
}
|
|
1456
|
-
}
|
|
1457
|
-
});
|
|
1542
|
+
} }));
|
|
1458
1543
|
// `outboundDetails.externalTxHash` from waitForOutboundTx
|
|
1459
1544
|
// is the raw `0x`-hex form (internal canonical). For the
|
|
1460
1545
|
// user-facing `hop.txHash`, `hop.outboundDetails`, and
|
|
1461
1546
|
// cascade progress event, normalize to base58 for SVM so
|
|
1462
1547
|
// consumers can paste it straight into a Solana explorer.
|
|
1463
|
-
const displayTxHash = (
|
|
1548
|
+
const displayTxHash = (_b = (0, helpers_1.toExternalTxHashDisplay)(outboundDetails.destinationChain, outboundDetails.externalTxHash)) !== null && _b !== void 0 ? _b : outboundDetails.externalTxHash;
|
|
1464
1549
|
const userFacingOutboundDetails = Object.assign(Object.assign({}, outboundDetails), { externalTxHash: displayTxHash });
|
|
1465
1550
|
hop.status = 'confirmed';
|
|
1466
1551
|
hop.txHash = displayTxHash;
|
|
@@ -1549,12 +1634,12 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1549
1634
|
},
|
|
1550
1635
|
});
|
|
1551
1636
|
if (!allOutboundDetails.success) {
|
|
1552
|
-
const failedIdx = (
|
|
1637
|
+
const failedIdx = (_c = allOutboundDetails.failedAt) !== null && _c !== void 0 ? _c : 0;
|
|
1553
1638
|
const failedHop = outboundHops.find((h) => h.hopIndex === failedIdx);
|
|
1554
1639
|
const failMsg = failedHop
|
|
1555
1640
|
? `Outbound failed for hop ${failedIdx} on ${failedHop.executionChain}`
|
|
1556
1641
|
: `Outbound cascade failed at hop ${failedIdx}`;
|
|
1557
|
-
emitHopEvent((0, progress_route_hooks_1.pickWaitHooks)(failedHop === null || failedHop === void 0 ? void 0 : failedHop.route).failed((
|
|
1642
|
+
emitHopEvent((0, progress_route_hooks_1.pickWaitHooks)(failedHop === null || failedHop === void 0 ? void 0 : failedHop.route).failed((_d = failedHop === null || failedHop === void 0 ? void 0 : failedHop.executionChain) !== null && _d !== void 0 ? _d : '', failMsg));
|
|
1558
1643
|
emitCascadeFailed(failedIdx, failMsg);
|
|
1559
1644
|
return {
|
|
1560
1645
|
success: false,
|
|
@@ -1603,7 +1688,7 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1603
1688
|
// 2. Track direct outbound hops (Route 2: UOA_TO_CEA) that belong
|
|
1604
1689
|
// to the root Push UTX.
|
|
1605
1690
|
const rootOutboundHops = hopInfos.filter((h) => h.route === 'UOA_TO_CEA' && !isAfterCeaToPush(h.hopIndex));
|
|
1606
|
-
const rootOutboundFailure = yield trackOutboundHops(rootOutboundHops, response.hash);
|
|
1691
|
+
const rootOutboundFailure = yield trackOutboundHops(rootOutboundHops, response.hash, undefined, rootOutboundIndexByHop);
|
|
1607
1692
|
if (rootOutboundFailure)
|
|
1608
1693
|
return rootOutboundFailure;
|
|
1609
1694
|
let childInbound;
|
|
@@ -1638,6 +1723,7 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1638
1723
|
pollingIntervalMs,
|
|
1639
1724
|
timeout: remainingTimeout,
|
|
1640
1725
|
_expectedDestinationChain: inboundHop.executionChain,
|
|
1726
|
+
_outboundIndex: (_d = rootOutboundIndexByHop.get(inboundHop.hopIndex)) !== null && _d !== void 0 ? _d : 0,
|
|
1641
1727
|
progressHook: (event) => {
|
|
1642
1728
|
cascadeProgressHook === null || cascadeProgressHook === void 0 ? void 0 : cascadeProgressHook({
|
|
1643
1729
|
hopIndex: inboundHop.hopIndex,
|
|
@@ -1666,7 +1752,7 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1666
1752
|
emitCascadeFailed(inboundHop.hopIndex, errMsg);
|
|
1667
1753
|
inboundHop.status = 'failed';
|
|
1668
1754
|
const failedExternalTxHash = err === null || err === void 0 ? void 0 : err.externalTxHash;
|
|
1669
|
-
const failedDisplayTxHash = (
|
|
1755
|
+
const failedDisplayTxHash = (_e = (0, helpers_1.toExternalTxHashDisplay)(inboundHop.executionChain, failedExternalTxHash)) !== null && _e !== void 0 ? _e : failedExternalTxHash;
|
|
1670
1756
|
if (failedDisplayTxHash)
|
|
1671
1757
|
inboundHop.txHash = failedDisplayTxHash;
|
|
1672
1758
|
cascadeProgressHook === null || cascadeProgressHook === void 0 ? void 0 : cascadeProgressHook({
|
|
@@ -1683,7 +1769,7 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1683
1769
|
failedAt: inboundHop.hopIndex,
|
|
1684
1770
|
};
|
|
1685
1771
|
}
|
|
1686
|
-
const displayExternalTxHash = (
|
|
1772
|
+
const displayExternalTxHash = (_f = (0, helpers_1.toExternalTxHashDisplay)(sourceOutboundDetails.destinationChain, sourceOutboundDetails.externalTxHash)) !== null && _f !== void 0 ? _f : sourceOutboundDetails.externalTxHash;
|
|
1687
1773
|
inboundHop.outboundDetails = Object.assign(Object.assign({}, sourceOutboundDetails), { externalTxHash: displayExternalTxHash });
|
|
1688
1774
|
inboundHop.txHash = displayExternalTxHash;
|
|
1689
1775
|
emitHopEvent(hopHooks.success(inboundHop.outboundDetails));
|
|
@@ -1691,7 +1777,7 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1691
1777
|
let inboundLastStatus;
|
|
1692
1778
|
const inboundRemainingTimeout = timeout - (Date.now() - startTime);
|
|
1693
1779
|
try {
|
|
1694
|
-
childInbound = yield ((
|
|
1780
|
+
childInbound = yield ((_g = callbacks.waitForInboundPushTxFn) !== null && _g !== void 0 ? _g : ((externalTxHash, sourceChain, opts) => (0, inbound_tracker_1.waitForInboundPushTx)(ctx, externalTxHash, sourceChain, opts)))(sourceOutboundDetails.externalTxHash, inboundHop.executionChain, {
|
|
1695
1781
|
initialWaitMs: Math.min(60000, inboundRemainingTimeout),
|
|
1696
1782
|
pollingIntervalMs,
|
|
1697
1783
|
timeout: inboundRemainingTimeout,
|
|
@@ -1729,7 +1815,7 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks, defaultEventHook) {
|
|
|
1729
1815
|
};
|
|
1730
1816
|
}
|
|
1731
1817
|
if (childInbound.status !== 'confirmed') {
|
|
1732
|
-
const failMsg = (
|
|
1818
|
+
const failMsg = (_h = childInbound.errorMessage) !== null && _h !== void 0 ? _h : 'inbound execution failed on Push Chain';
|
|
1733
1819
|
inboundHop.status = 'failed';
|
|
1734
1820
|
inboundHop.txHash =
|
|
1735
1821
|
childInbound.pushTxHash || displayExternalTxHash;
|