@pushchain/core 5.1.17 → 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.
Files changed (36) hide show
  1. package/package.json +1 -1
  2. package/src/lib/constants/index.d.ts +1 -1
  3. package/src/lib/constants/index.js +2 -1
  4. package/src/lib/constants/selectors.d.ts +8 -0
  5. package/src/lib/constants/selectors.js +9 -1
  6. package/src/lib/formatters.d.ts +1 -0
  7. package/src/lib/formatters.js +32 -0
  8. package/src/lib/orchestrator/internals/cascade.d.ts +8 -1
  9. package/src/lib/orchestrator/internals/cascade.js +486 -143
  10. package/src/lib/orchestrator/internals/error-decoder.d.ts +2 -6
  11. package/src/lib/orchestrator/internals/error-decoder.js +10 -10
  12. package/src/lib/orchestrator/internals/errors.d.ts +1 -1
  13. package/src/lib/orchestrator/internals/errors.js +7 -4
  14. package/src/lib/orchestrator/internals/execute-standard.js +7 -6
  15. package/src/lib/orchestrator/internals/gas-calculator.js +78 -11
  16. package/src/lib/orchestrator/internals/helpers.d.ts +2 -1
  17. package/src/lib/orchestrator/internals/helpers.js +13 -11
  18. package/src/lib/orchestrator/internals/outbound-sync.d.ts +1 -0
  19. package/src/lib/orchestrator/internals/outbound-sync.js +93 -37
  20. package/src/lib/orchestrator/internals/preflight.d.ts +2 -16
  21. package/src/lib/orchestrator/internals/preflight.js +2 -36
  22. package/src/lib/orchestrator/internals/response-builder.js +23 -7
  23. package/src/lib/orchestrator/internals/route-handlers.js +34 -49
  24. package/src/lib/orchestrator/orchestrator.d.ts +7 -1
  25. package/src/lib/orchestrator/orchestrator.js +40 -2
  26. package/src/lib/orchestrator/orchestrator.types.d.ts +4 -14
  27. package/src/lib/progress-hook/progress-hook.js +13 -20
  28. package/src/lib/push-chain/push-chain.d.ts +11 -1
  29. package/src/lib/push-chain/push-chain.js +2 -2
  30. package/src/lib/universal-tx-detector/cascade.js +14 -4
  31. package/src/lib/universal-tx-detector/child-inbounds.js +9 -1
  32. package/src/lib/universal-tx-detector/detector.js +9 -3
  33. package/src/lib/universal-tx-detector/normalize.d.ts +42 -0
  34. package/src/lib/universal-tx-detector/normalize.js +127 -0
  35. package/src/lib/utils/external-tx-hash.d.ts +37 -0
  36. package/src/lib/utils/external-tx-hash.js +62 -0
@@ -26,31 +26,13 @@ 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 UPC error.
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, allowUnderfundedSwap, } = opts;
35
+ const { ctx, ueaAddress, ueaBalance, requiredValue, gasReserve, pathTag, burnToken, burnAmount, prc20Balance, segmentIndex, } = opts;
54
36
  // Each route bucket gets its own preflight IDs so hook streams stay
55
37
  // self-consistent within their convention (R2 → 203-xx, R3 → 303-xx,
56
38
  // cascade → 003-xx). The three hook formatters share an identical
@@ -75,15 +57,6 @@ function runPreflight(opts) {
75
57
  (0, context_1.fireProgressHook)(ctx, HOOK_PRE_INFO, burnAmount, onHand, sufficient, ueaAddress, pathTag, { kind: 'PRC20', burnToken, segmentIndex });
76
58
  if (!sufficient) {
77
59
  const shortfall = burnAmount - onHand;
78
- if (allowUnderfundedSwap) {
79
- (0, context_1.printLog)(ctx, `[preflight ${pathTag}] PRC-20 shortfall ${shortfall} of ${burnToken}; ` +
80
- `allowUnderfundedSwap=true — proceeding with legacy clamp behaviour, ` +
81
- `swap is expected to revert with InsufficientBalance(0xf4d678b8) on-chain.`);
82
- return {
83
- ok: false,
84
- legacyClampedValue: legacyClamp(ueaBalance, requiredValue, gasReserve),
85
- };
86
- }
87
60
  (0, context_1.fireProgressHook)(ctx, HOOK_PRE_FAIL, burnAmount, onHand, shortfall, ueaAddress, pathTag, { kind: 'PRC20', burnToken, segmentIndex });
88
61
  throw new errors_1.InsufficientUEABalanceError({
89
62
  required: burnAmount,
@@ -105,13 +78,6 @@ function runPreflight(opts) {
105
78
  return { ok: true, adjustedValue: requiredValue };
106
79
  }
107
80
  const shortfall = totalRequired - ueaBalance;
108
- if (allowUnderfundedSwap) {
109
- const clamped = legacyClamp(ueaBalance, requiredValue, gasReserve);
110
- (0, context_1.printLog)(ctx, `[preflight ${pathTag}] UPC shortfall ${shortfall} wei; ` +
111
- `allowUnderfundedSwap=true — proceeding with legacy clamped value ${clamped}, ` +
112
- `swap may revert inside Uniswap with Error("STF") if the clamp under-funds the pool quote.`);
113
- return { ok: false, legacyClampedValue: clamped };
114
- }
115
81
  (0, context_1.fireProgressHook)(ctx, HOOK_PRE_FAIL, totalRequired, ueaBalance, shortfall, ueaAddress, pathTag, { kind: 'NATIVE', segmentIndex });
116
82
  throw new errors_1.InsufficientUEABalanceError({
117
83
  required: totalRequired,
@@ -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
- emit(hooks.success(outboundDetails));
609
- // Merge external chain details into receipt
610
- baseReceipt = Object.assign(Object.assign({}, baseReceipt), { externalTxHash: outboundDetails.externalTxHash, externalChain: outboundDetails.destinationChain, externalExplorerUrl: outboundDetails.explorerUrl, externalRecipient: outboundDetails.recipient, externalAmount: outboundDetails.amount, externalAssetAddr: outboundDetails.assetAddr, externalStatus: 'success' });
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 = (_f = inbound.errorMessage) !== null && _f !== void 0 ? _f : 'inbound execution failed on Push Chain';
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
- baseReceipt = Object.assign(Object.assign(Object.assign({}, baseReceipt), { externalStatus: isTimeout ? 'timeout' : 'failed', externalError: errMsg }), (failedExternalTxHash
673
- ? { externalTxHash: failedExternalTxHash }
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, _d;
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
- // Pool-quote + 10% safety buffer. Over-send is refunded by the contract.
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
- const estimated = yield (0, gas_calculator_1.estimateNativeValueForSwap)(ctx, universalCoreAddress, gasToken, gasFee, effectiveBalance);
437
- nativeValueForGas = (estimated * BigInt(110)) / BigInt(100);
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
- const allowUnderfundedR2Evm = ((_d = params.options) === null || _d === void 0 ? void 0 : _d.allowUnderfundedSwap) === true;
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
- if (!preflightR2Evm.ok) {
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, _j;
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 plus
652
- // a 10% safety buffer. swapAndBurnGas refunds the excess as PC via
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
- const estimated = yield (0, gas_calculator_1.estimateNativeValueForSwap)(ctx, universalCoreAddress, gasToken, gasFee, ueaBalance);
668
- nativeValueForGas = (estimated * BigInt(110)) / BigInt(100);
669
- (0, context_1.printLog)(ctx, `executeUoaToCeaSvm — nativeValueForGas: pool-quote=${estimated.toString()}, with 10% buffer=${nativeValueForGas.toString()}`);
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
- const allowUnderfundedR2Svm = ((_j = params.options) === null || _j === void 0 ? void 0 : _j.allowUnderfundedSwap) === true;
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, _j;
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
- // CEA multicall: to=CEA (self-call), value=0
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
- (_f = params.gasLimit) !== null && _f !== void 0 ? _f : BigInt(0), ceaPayload, // payload: ABI-encoded CEA multicall
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, gasLimit, sourceChain);
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
- const allowUnderfundedR3Evm = ((_j = params.options) === null || _j === void 0 ? void 0 : _j.allowUnderfundedSwap) === true;
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, _e;
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
- const allowUnderfundedR3Svm = ((_e = params.options) === null || _e === void 0 ? void 0 : _e.allowUnderfundedSwap) === true;
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 (to=CEA, value=0)
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 outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, prc20Token, burnAmount, (_l = params.gasLimit) !== null && _l !== void 0 ? _l : BigInt(0), ceaPayload, ueaAddress);
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:
@@ -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
- return (0, internals_1.createCascadedBuilder)(this.ctx, preparedTxs, this._getCascadeCallbacks());
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
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.classifyDeclineError = classifyDeclineError;
4
+ const formatters_1 = require("../formatters");
4
5
  const utils_1 = require("../utils");
5
6
  const progress_hook_types_1 = require("./progress-hook.types");
6
7
  // Helper to wrap a hook function with timestamp
@@ -22,14 +23,6 @@ const friendlyChain = (chainOrNs) => {
22
23
  const key = utils_1.Utils.chains.getChainName(asString);
23
24
  return key ? toTitleCase(key) : asString;
24
25
  };
25
- /**
26
- * Format a wei-denominated UPC bigint as a human-readable PC string for use
27
- * in progress-hook `message` fields. Used by the pre-flight hooks
28
- * (203-03/04/05 + 003-03/04/05) so consumers see "956.7834 PC" instead of
29
- * "956783432238079848707 wei UPC". Response payload bigints are NOT
30
- * transformed — programmatic consumers still get raw wei.
31
- */
32
- const formatPC = (wei, precision = 4) => `${utils_1.Utils.helpers.formatUnits(wei, { decimals: 18, precision })} PC`;
33
26
  /**
34
27
  * Classify a sign-time error as either a true wallet user-decline
35
28
  * (viem `UserRejectedRequestError`, ethers `ACTION_REJECTED`, EIP-1193 4001,
@@ -313,8 +306,8 @@ const RAW_HOOKS_R2 = {
313
306
  [progress_hook_types_1.PROGRESS_HOOK.SEND_TX_203_03]: (required, available, sufficient, ueaAddress, pathTag, extra) => {
314
307
  var _a, _b, _c;
315
308
  const kind = (_a = extra === null || extra === void 0 ? void 0 : extra.kind) !== null && _a !== void 0 ? _a : 'NATIVE';
316
- const availableStr = kind === 'PRC20' ? `${available} units` : formatPC(available);
317
- const requiredStr = kind === 'PRC20' ? `${required} units` : formatPC(required);
309
+ const availableStr = kind === 'PRC20' ? `${available} units` : (0, formatters_1.formatPc)(available, 4);
310
+ const requiredStr = kind === 'PRC20' ? `${required} units` : (0, formatters_1.formatPc)(required, 4);
318
311
  return {
319
312
  id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_203_03,
320
313
  title: 'Pre-flight Balance Check',
@@ -336,7 +329,7 @@ const RAW_HOOKS_R2 = {
336
329
  [progress_hook_types_1.PROGRESS_HOOK.SEND_TX_203_04]: (required, available, shortfall, ueaAddress, pathTag, extra) => {
337
330
  var _a, _b, _c, _d;
338
331
  const kind = (_a = extra === null || extra === void 0 ? void 0 : extra.kind) !== null && _a !== void 0 ? _a : 'NATIVE';
339
- const shortfallStr = kind === 'PRC20' ? `${shortfall} units` : formatPC(shortfall);
332
+ const shortfallStr = kind === 'PRC20' ? `${shortfall} units` : (0, formatters_1.formatPc)(shortfall, 4);
340
333
  const remediation = kind === 'PRC20'
341
334
  ? `Bridge the burn token (${(_b = extra === null || extra === void 0 ? void 0 : extra.burnToken) !== null && _b !== void 0 ? _b : 'PRC-20'}) to UEA ${ueaAddress} before retrying.`
342
335
  : `Bridge >=${shortfallStr} to UEA ${ueaAddress} before retrying.`;
@@ -360,7 +353,7 @@ const RAW_HOOKS_R2 = {
360
353
  [progress_hook_types_1.PROGRESS_HOOK.SEND_TX_203_05]: (quoted, threshold, gasToken, pathTag) => ({
361
354
  id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_203_05,
362
355
  title: 'SVM Native-Value Warn Threshold',
363
- message: `Buffered pool quote ${formatPC(quoted)} exceeds warn threshold ${formatPC(threshold)} ` +
356
+ message: `Buffered pool quote ${(0, formatters_1.formatPc)(quoted, 4)} exceeds warn threshold ${(0, formatters_1.formatPc)(threshold, 4)} ` +
364
357
  `for ${gasToken} (${pathTag}). Pool may be skewed or quote is unusually large. ` +
365
358
  `No action taken — pre-flight will determine if balance covers it.`,
366
359
  response: { quoted, threshold, gasToken, pathTag },
@@ -527,8 +520,8 @@ const RAW_HOOKS_R3 = {
527
520
  [progress_hook_types_1.PROGRESS_HOOK.SEND_TX_303_04]: (required, available, sufficient, ueaAddress, pathTag, extra) => {
528
521
  var _a, _b, _c;
529
522
  const kind = (_a = extra === null || extra === void 0 ? void 0 : extra.kind) !== null && _a !== void 0 ? _a : 'NATIVE';
530
- const availableStr = kind === 'PRC20' ? `${available} units` : formatPC(available);
531
- const requiredStr = kind === 'PRC20' ? `${required} units` : formatPC(required);
523
+ const availableStr = kind === 'PRC20' ? `${available} units` : (0, formatters_1.formatPc)(available, 4);
524
+ const requiredStr = kind === 'PRC20' ? `${required} units` : (0, formatters_1.formatPc)(required, 4);
532
525
  return {
533
526
  id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_303_04,
534
527
  title: 'Pre-flight Balance Check',
@@ -550,7 +543,7 @@ const RAW_HOOKS_R3 = {
550
543
  [progress_hook_types_1.PROGRESS_HOOK.SEND_TX_303_05]: (required, available, shortfall, ueaAddress, pathTag, extra) => {
551
544
  var _a, _b, _c, _d;
552
545
  const kind = (_a = extra === null || extra === void 0 ? void 0 : extra.kind) !== null && _a !== void 0 ? _a : 'NATIVE';
553
- const shortfallStr = kind === 'PRC20' ? `${shortfall} units` : formatPC(shortfall);
546
+ const shortfallStr = kind === 'PRC20' ? `${shortfall} units` : (0, formatters_1.formatPc)(shortfall, 4);
554
547
  const remediation = kind === 'PRC20'
555
548
  ? `Bridge the burn token (${(_b = extra === null || extra === void 0 ? void 0 : extra.burnToken) !== null && _b !== void 0 ? _b : 'PRC-20'}) to UEA ${ueaAddress} before retrying.`
556
549
  : `Bridge >=${shortfallStr} to UEA ${ueaAddress} before retrying.`;
@@ -574,7 +567,7 @@ const RAW_HOOKS_R3 = {
574
567
  [progress_hook_types_1.PROGRESS_HOOK.SEND_TX_303_06]: (quoted, threshold, gasToken, pathTag) => ({
575
568
  id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_303_06,
576
569
  title: 'SVM Native-Value Warn Threshold',
577
- message: `Buffered pool quote ${formatPC(quoted)} exceeds warn threshold ${formatPC(threshold)} ` +
570
+ message: `Buffered pool quote ${(0, formatters_1.formatPc)(quoted, 4)} exceeds warn threshold ${(0, formatters_1.formatPc)(threshold, 4)} ` +
578
571
  `for ${gasToken} (${pathTag}). Pool may be skewed or quote is unusually large. ` +
579
572
  `No action taken — pre-flight will determine if balance covers it.`,
580
573
  response: { quoted, threshold, gasToken, pathTag },
@@ -786,8 +779,8 @@ const RAW_HOOKS_MULTICHAIN = {
786
779
  [progress_hook_types_1.PROGRESS_HOOK.SEND_TX_003_03]: (required, available, sufficient, ueaAddress, pathTag, extra) => {
787
780
  var _a, _b, _c;
788
781
  const kind = (_a = extra === null || extra === void 0 ? void 0 : extra.kind) !== null && _a !== void 0 ? _a : 'NATIVE';
789
- const availableStr = kind === 'PRC20' ? `${available} units` : formatPC(available);
790
- const requiredStr = kind === 'PRC20' ? `${required} units` : formatPC(required);
782
+ const availableStr = kind === 'PRC20' ? `${available} units` : (0, formatters_1.formatPc)(available, 4);
783
+ const requiredStr = kind === 'PRC20' ? `${required} units` : (0, formatters_1.formatPc)(required, 4);
791
784
  return {
792
785
  id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_003_03,
793
786
  title: 'Cascade Pre-flight Balance Check',
@@ -809,7 +802,7 @@ const RAW_HOOKS_MULTICHAIN = {
809
802
  [progress_hook_types_1.PROGRESS_HOOK.SEND_TX_003_04]: (required, available, shortfall, ueaAddress, pathTag, extra) => {
810
803
  var _a, _b, _c, _d;
811
804
  const kind = (_a = extra === null || extra === void 0 ? void 0 : extra.kind) !== null && _a !== void 0 ? _a : 'NATIVE';
812
- const shortfallStr = kind === 'PRC20' ? `${shortfall} units` : formatPC(shortfall);
805
+ const shortfallStr = kind === 'PRC20' ? `${shortfall} units` : (0, formatters_1.formatPc)(shortfall, 4);
813
806
  const remediation = kind === 'PRC20'
814
807
  ? `Bridge the burn token (${(_b = extra === null || extra === void 0 ? void 0 : extra.burnToken) !== null && _b !== void 0 ? _b : 'PRC-20'}) to UEA ${ueaAddress} before retrying.`
815
808
  : `Bridge >=${shortfallStr} to UEA ${ueaAddress} before retrying.`;
@@ -833,7 +826,7 @@ const RAW_HOOKS_MULTICHAIN = {
833
826
  [progress_hook_types_1.PROGRESS_HOOK.SEND_TX_003_05]: (quoted, threshold, gasToken, pathTag) => ({
834
827
  id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_003_05,
835
828
  title: 'Cascade SVM Native-Value Warn Threshold',
836
- message: `Buffered pool quote ${formatPC(quoted)} exceeds warn threshold ${formatPC(threshold)} ` +
829
+ message: `Buffered pool quote ${(0, formatters_1.formatPc)(quoted, 4)} exceeds warn threshold ${(0, formatters_1.formatPc)(threshold, 4)} ` +
837
830
  `for ${gasToken} (${pathTag}). Pool may be skewed or quote is unusually large. ` +
838
831
  `No action taken — pre-flight will determine if balance covers it.`,
839
832
  response: { quoted, threshold, gasToken, pathTag },
@@ -77,8 +77,18 @@ export declare class PushChain {
77
77
  /**
78
78
  * Execute one or more prepared transactions as a cascade across chains.
79
79
  * Accepts an array of PreparedUniversalTx (from prepareTransaction).
80
+ *
81
+ * @param txs - Prepared transactions to execute as a cascade.
82
+ * @param options.progressHook - Optional per-call progress callback.
83
+ * Additive with the init-time `progressHook` passed to `initialize`:
84
+ * both hooks receive every `ProgressEvent` emitted during this call
85
+ * (pre-flight, broadcast, and cascade tracking). Dedups by reference
86
+ * if it matches the init-time hook. Note: concurrent calls on the
87
+ * same instance share the hook channel during the broadcast phase.
80
88
  */
81
- executeTransactions: (txs: PreparedUniversalTx[]) => Promise<CascadedTxResponse>;
89
+ executeTransactions: (txs: PreparedUniversalTx[], options?: {
90
+ progressHook?: (event: ProgressEvent) => void;
91
+ }) => Promise<CascadedTxResponse>;
82
92
  /**
83
93
  * Tracks a transaction by hash on Push Chain
84
94
  */
@@ -84,11 +84,11 @@ class PushChain {
84
84
  prepareTransaction: (params) => {
85
85
  return orchestrator.prepareTransaction.bind(orchestrator)(params);
86
86
  },
87
- executeTransactions: (txs) => tslib_1.__awaiter(this, void 0, void 0, function* () {
87
+ executeTransactions: (txs, options) => tslib_1.__awaiter(this, void 0, void 0, function* () {
88
88
  if (this.isReadMode) {
89
89
  throw new Error('Read only mode cannot call executeTransactions function');
90
90
  }
91
- return orchestrator.createCascadedBuilder(txs).send();
91
+ return orchestrator.createCascadedBuilder(txs, options).send();
92
92
  }),
93
93
  trackTransaction: (txHash, options) => {
94
94
  return orchestrator.trackTransaction.bind(orchestrator)(txHash, options);