@pushchain/core 6.0.7 → 6.0.9

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushchain/core",
3
- "version": "6.0.7",
3
+ "version": "6.0.9",
4
4
  "homepage": "https://push.org",
5
5
  "keywords": [
6
6
  "pushchain",
@@ -262,6 +262,12 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
262
262
  // Build CEA multicalls
263
263
  const ceaMulticalls = [];
264
264
  const hasData = (0, data_utils_1.hasExecutablePayloadData)(params.data);
265
+ const fundsToken = ((_h = params.funds) === null || _h === void 0 ? void 0 : _h.amount)
266
+ ? (0, route_handlers_1.resolveR2DestinationFundsToken)(params.funds.token, targetChain, ctx.pushNetwork)
267
+ : undefined;
268
+ const nativeFundsValue = ((_j = params.funds) === null || _j === void 0 ? void 0 : _j.amount) && (fundsToken === null || fundsToken === void 0 ? void 0 : fundsToken.mechanism) === 'native'
269
+ ? params.funds.amount
270
+ : BigInt(0);
265
271
  if (hasData) {
266
272
  if (Array.isArray(params.data)) {
267
273
  ceaMulticalls.push(...params.data);
@@ -270,16 +276,15 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
270
276
  // When ERC-20 funds are provided with a single payload, auto-prepend a
271
277
  // transfer() call so the tokens minted to the CEA are forwarded to the
272
278
  // target address. This mirrors the Route 1 behavior in buildExecuteMulticall.
273
- if ((_h = params.funds) === null || _h === void 0 ? void 0 : _h.amount) {
274
- const token = params.funds.token;
275
- if (token && token.mechanism !== 'native') {
279
+ if ((_k = params.funds) === null || _k === void 0 ? void 0 : _k.amount) {
280
+ if (fundsToken && fundsToken.mechanism !== 'native') {
276
281
  const erc20Transfer = (0, viem_1.encodeFunctionData)({
277
282
  abi: erc20_evm_1.ERC20_EVM,
278
283
  functionName: 'transfer',
279
284
  args: [target.address, params.funds.amount],
280
285
  });
281
286
  ceaMulticalls.push({
282
- to: token.address,
287
+ to: fundsToken.address,
283
288
  value: BigInt(0),
284
289
  data: erc20Transfer,
285
290
  });
@@ -290,23 +295,20 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
290
295
  // native value to the CEA, and the multicall forwards it to the target.
291
296
  ceaMulticalls.push({
292
297
  to: target.address,
293
- value: (_j = params.value) !== null && _j !== void 0 ? _j : BigInt(0),
298
+ value: ((_l = params.value) !== null && _l !== void 0 ? _l : BigInt(0)) + nativeFundsValue,
294
299
  data: params.data,
295
300
  });
296
301
  }
297
302
  }
298
303
  else {
299
- const token = ((_k = params.funds) === null || _k === void 0 ? void 0 : _k.amount)
300
- ? params.funds.token
301
- : undefined;
302
- if (((_l = params.funds) === null || _l === void 0 ? void 0 : _l.amount) && token && token.mechanism !== 'native') {
304
+ if (((_m = params.funds) === null || _m === void 0 ? void 0 : _m.amount) && fundsToken && fundsToken.mechanism !== 'native') {
303
305
  const erc20Transfer = (0, viem_1.encodeFunctionData)({
304
306
  abi: erc20_evm_1.ERC20_EVM,
305
307
  functionName: 'transfer',
306
308
  args: [target.address, params.funds.amount],
307
309
  });
308
310
  ceaMulticalls.push({
309
- to: token.address,
311
+ to: fundsToken.address,
310
312
  value: BigInt(0),
311
313
  data: erc20Transfer,
312
314
  });
@@ -322,11 +324,11 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
322
324
  });
323
325
  }
324
326
  }
325
- else if (((_m = params.funds) === null || _m === void 0 ? void 0 : _m.amount) && (token === null || token === void 0 ? void 0 : token.mechanism) === 'native') {
327
+ else if (nativeFundsValue > BigInt(0)) {
326
328
  if (target.address.toLowerCase() !== ceaAddress.toLowerCase()) {
327
329
  ceaMulticalls.push({
328
330
  to: target.address,
329
- value: params.funds.amount,
331
+ value: nativeFundsValue,
330
332
  data: '0x',
331
333
  });
332
334
  }
@@ -781,7 +783,7 @@ function getInboundFundingForBurnToken(segments, beforeSegmentIndex, burnToken,
781
783
  }
782
784
  function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce, options) {
783
785
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
784
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
786
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
785
787
  let accumulatedPushMulticalls = [];
786
788
  let requiredNativeValue = BigInt(0);
787
789
  const gatewayPcAddress = (0, helpers_1.getUniversalGatewayPCAddress)();
@@ -1026,7 +1028,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce,
1026
1028
  }
1027
1029
  }
1028
1030
  // Build outbound request
1029
- 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));
1031
+ 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));
1030
1032
  // Build approval + outbound multicalls
1031
1033
  const segGasFee = segment.gasFee || BigInt(0);
1032
1034
  const svmOverride = svmNativeValueBySegment.get(segment);
@@ -1043,7 +1045,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce,
1043
1045
  else {
1044
1046
  evmFallbackValue = segGasFee * BigInt(1000000);
1045
1047
  }
1046
- let nativeValueForGas = (_h = svmOverride !== null && svmOverride !== void 0 ? svmOverride : perOutboundNativeValue) !== null && _h !== void 0 ? _h : evmFallbackValue;
1048
+ let nativeValueForGas = (_g = svmOverride !== null && svmOverride !== void 0 ? svmOverride : perOutboundNativeValue) !== null && _g !== void 0 ? _g : evmFallbackValue;
1047
1049
  // SDK 5.2 Case C: when the segment's sizing is category C, compose
1048
1050
  // R2/OUTBOUND_TO_CEA segments no longer apply Case A/B/C sizing
1049
1051
  // (scoped to R1 + R3 only). segment.sizing may still be populated
@@ -1084,7 +1086,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce,
1084
1086
  // UEA multicall so no nested outbound is needed.
1085
1087
  const mergedHopMulticalls = [];
1086
1088
  for (const h of segment.hops) {
1087
- if ((0, data_utils_1.hasExecutablePayloadData)((_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)) {
1089
+ if ((0, data_utils_1.hasExecutablePayloadData)((_h = h === null || h === void 0 ? void 0 : h.params) === null || _h === void 0 ? void 0 : _h.data) || ((_j = h === null || h === void 0 ? void 0 : h.params) === null || _j === void 0 ? void 0 : _j.value)) {
1088
1090
  const hopCalls = (0, payload_builders_1.buildExecuteMulticall)({
1089
1091
  execute: {
1090
1092
  to: h.params.to,
@@ -1129,7 +1131,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce,
1129
1131
  let drainAmount = BigInt(0);
1130
1132
  let tokenMintHex;
1131
1133
  const params = hop.params;
1132
- if (((_l = params.funds) === null || _l === void 0 ? void 0 : _l.amount) && params.funds.amount > BigInt(0)) {
1134
+ if (((_k = params.funds) === null || _k === void 0 ? void 0 : _k.amount) && params.funds.amount > BigInt(0)) {
1133
1135
  drainAmount = params.funds.amount;
1134
1136
  const token = params.funds.token;
1135
1137
  if (token && token.address) {
@@ -1158,7 +1160,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce,
1158
1160
  });
1159
1161
  const svmBurnAmount = segment.totalBurnAmount || BigInt(0);
1160
1162
  const outboundReq = (0, payload_builders_1.buildOutboundRequest)(gatewayProgramHex, segment.prc20Token ||
1161
- (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));
1163
+ (0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork), svmBurnAmount, (_l = segment.gasLimit) !== null && _l !== void 0 ? _l : BigInt(0), svmPayload, ueaAddress, (_m = segment.maxPCForGas) !== null && _m !== void 0 ? _m : BigInt(0));
1162
1164
  const inboundGasFee = segment.gasFee || BigInt(0);
1163
1165
  let svmInboundFallback;
1164
1166
  if (effectiveUeaBalance > BigInt(0)) {
@@ -1172,7 +1174,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce,
1172
1174
  // SDK 5.2 R3-style Case C bump: when the inbound segment's sizing
1173
1175
  // is C, top up the swap budget by the overflow. No bridge-swap —
1174
1176
  // R3 has no destination funds delivery.
1175
- if (((_q = segment.sizing) === null || _q === void 0 ? void 0 : _q.category) === 'C' &&
1177
+ if (((_o = segment.sizing) === null || _o === void 0 ? void 0 : _o.category) === 'C' &&
1176
1178
  segment.sizing.overflowNativePc > BigInt(0)) {
1177
1179
  const bumped = svmInboundNativeValue + segment.sizing.overflowNativePc;
1178
1180
  (0, context_1.printLog)(ctx, `composeCascade — INBOUND_FROM_CEA (SVM) Case C: bumping nativeValueForGas from ${svmInboundNativeValue} to ${bumped} (overflow=${segment.sizing.overflowNativePc})`);
@@ -1209,7 +1211,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce,
1209
1211
  let amount = BigInt(0);
1210
1212
  for (const mergedHop of segment.hops) {
1211
1213
  const hParams = mergedHop.params;
1212
- if ((_r = hParams.funds) === null || _r === void 0 ? void 0 : _r.amount) {
1214
+ if ((_p = hParams.funds) === null || _p === void 0 ? void 0 : _p.amount) {
1213
1215
  const token = hParams.funds.token;
1214
1216
  if (token) {
1215
1217
  if (token.mechanism === 'native') {
@@ -1245,7 +1247,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce,
1245
1247
  ? segment.gasLimit
1246
1248
  : selectors_1.DEFAULT_CEA_TO_PUSH_GAS_LIMIT;
1247
1249
  const outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, segment.prc20Token ||
1248
- (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));
1250
+ (0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork), segment.totalBurnAmount || BigInt(0), effectiveGasLimit, ceaPayload, ueaAddress, (_q = segment.maxPCForGas) !== null && _q !== void 0 ? _q : BigInt(0));
1249
1251
  const inboundGasFee = segment.gasFee || BigInt(0);
1250
1252
  let evmInboundFallback;
1251
1253
  if (effectiveUeaBalance > BigInt(0)) {
@@ -1259,7 +1261,7 @@ function composeCascadeDetailed(ctx, segments, ueaAddress, ueaBalance, ueaNonce,
1259
1261
  // SDK 5.2 R3-style Case C bump: when the inbound segment's sizing
1260
1262
  // is C, top up the swap budget by the overflow. No bridge-swap —
1261
1263
  // R3 has no destination funds delivery.
1262
- if (((_u = segment.sizing) === null || _u === void 0 ? void 0 : _u.category) === 'C' &&
1264
+ if (((_r = segment.sizing) === null || _r === void 0 ? void 0 : _r.category) === 'C' &&
1263
1265
  segment.sizing.overflowNativePc > BigInt(0)) {
1264
1266
  const bumped = evmInboundNativeValue + segment.sizing.overflowNativePc;
1265
1267
  (0, context_1.printLog)(ctx, `composeCascade — INBOUND_FROM_CEA (EVM) Case C: bumping nativeValueForGas from ${evmInboundNativeValue} to ${bumped} (overflow=${segment.sizing.overflowNativePc})`);
@@ -46,6 +46,12 @@ exports.KNOWN_ERROR_SELECTORS = {
46
46
  hint: 'Likely cause: provided gasLimit is below the chain minimum. Omit `gasLimit` to use the per-chain default.',
47
47
  provenance: 'Observed in dev (selector source unverified — see plan §9 #5)',
48
48
  },
49
+ '0x05aab006': {
50
+ name: 'GasPriceBelowBase',
51
+ hint: 'Likely cause: an explicit outbound gasPrice override is below the current UniversalCore base price. ' +
52
+ 'Omit gasPrice so the gateway resolves the live base price at execution time.',
53
+ provenance: 'TypesUGPC/UniversalGatewayPC live Route 2 docs e2e, 2026-05-19: gateway tx 0xe1b549eb47c3cbf1abc69ba6e85927832e482147b49a01a0364206098367dbf7.',
54
+ },
49
55
  };
50
56
  /** Selector for `Error(string)` (Solidity `require(false, "msg")`). */
51
57
  exports.ERROR_STRING_SELECTOR = '0x08c379a0';
@@ -12,7 +12,7 @@ export declare const OUTBOUND_INITIAL_WAIT_MS = 15000;
12
12
  /** Interval between consecutive polls (ms). */
13
13
  export declare const OUTBOUND_POLL_INTERVAL_MS = 3000;
14
14
  /** Maximum total timeout for the outbound polling loop (ms). */
15
- export declare const OUTBOUND_MAX_TIMEOUT_MS = 180000;
15
+ export declare const OUTBOUND_MAX_TIMEOUT_MS = 300000;
16
16
  /** Maximum total timeout for the R3 inbound round-trip polling loop (ms). */
17
17
  export declare const INBOUND_MAX_TIMEOUT_MS = 300000;
18
18
  /** Initial wait before the first inbound poll (ms). Validator observation + Push commit + indexer ingestion realistically take 15-25 s on testnet (esp. SVM source), so polling immediately just burns RPC on guaranteed-empty results. */
@@ -49,7 +49,7 @@ export declare class OutboundFailedError extends Error {
49
49
  * @internal Used by .wait() for outbound routes - not part of public API.
50
50
  * Uses polling with configurable initial wait, interval, and timeout.
51
51
  *
52
- * Default strategy: 15s initial wait, then poll every 3s, 180s total timeout.
52
+ * Default strategy: 15s initial wait, then poll every 3s, 300s total timeout.
53
53
  *
54
54
  * @param ctx - Orchestrator context
55
55
  * @param pushChainTxHash - The Push Chain transaction hash
@@ -27,7 +27,7 @@ exports.OUTBOUND_INITIAL_WAIT_MS = 15000; // 15s
27
27
  /** Interval between consecutive polls (ms). */
28
28
  exports.OUTBOUND_POLL_INTERVAL_MS = 3000; // 3s
29
29
  /** Maximum total timeout for the outbound polling loop (ms). */
30
- exports.OUTBOUND_MAX_TIMEOUT_MS = 180000; // 180s (3 min)
30
+ exports.OUTBOUND_MAX_TIMEOUT_MS = 300000; // 300s (5 min)
31
31
  /** Maximum total timeout for the R3 inbound round-trip polling loop (ms). */
32
32
  exports.INBOUND_MAX_TIMEOUT_MS = 300000; // 300s (5 min) — covers R3 inbound latency on testnet
33
33
  /** Initial wait before the first inbound poll (ms). Validator observation + Push commit + indexer ingestion realistically take 15-25 s on testnet (esp. SVM source), so polling immediately just burns RPC on guaranteed-empty results. */
@@ -75,7 +75,7 @@ exports.OutboundFailedError = OutboundFailedError;
75
75
  *
76
76
  * Cosmos sometimes populates `observedTx.txHash` while the relayer is still
77
77
  * voting on the outboundStatus update. The Push indexer can stay at
78
- * UNSPECIFIED for the full 180s budget even though the destination tx mined
78
+ * UNSPECIFIED for the full timeout budget even though the destination tx mined
79
79
  * minutes earlier. To avoid those false timeouts we ask the destination
80
80
  * chain's own RPC: if it has a confirmed receipt with status=success, we
81
81
  * trust it and return FOUND; if status=reverted, we throw OutboundFailedError
@@ -132,7 +132,7 @@ function verifyExternalEvmReceipt(ctx, destinationChain, externalTxHash) {
132
132
  * @internal Used by .wait() for outbound routes - not part of public API.
133
133
  * Uses polling with configurable initial wait, interval, and timeout.
134
134
  *
135
- * Default strategy: 15s initial wait, then poll every 3s, 180s total timeout.
135
+ * Default strategy: 15s initial wait, then poll every 3s, 300s total timeout.
136
136
  *
137
137
  * @param ctx - Orchestrator context
138
138
  * @param pushChainTxHash - The Push Chain transaction hash
@@ -15,8 +15,11 @@
15
15
  */
16
16
  import type { OrchestratorContext } from './context';
17
17
  import { CHAIN } from '../../constants/enums';
18
+ import { MoveableToken } from '../../constants/tokens';
18
19
  import { TransactionRoute } from '../route-detector';
19
20
  import type { ChainTarget, ExecuteParams, UniversalExecuteParams, UniversalOutboundTxRequest, UniversalTxRequest, UniversalTxResponse } from '../orchestrator.types';
21
+ import type { PUSH_NETWORK } from '../../constants/enums';
22
+ export declare function resolveR2DestinationFundsToken(token: MoveableToken, targetChain: CHAIN, pushNetwork: PUSH_NETWORK): MoveableToken;
20
23
  type ExecuteFn = (params: ExecuteParams | UniversalExecuteParams) => Promise<UniversalTxResponse>;
21
24
  /**
22
25
  * Dispatch a universal execution to the correct route handler.
@@ -15,6 +15,7 @@
15
15
  * `executeFn` callback that replaces the former `this.execute()` call.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.resolveR2DestinationFundsToken = resolveR2DestinationFundsToken;
18
19
  exports.executeMultiChain = executeMultiChain;
19
20
  exports.executeUoaToCea = executeUoaToCea;
20
21
  exports.executeUoaToCeaSvm = executeUoaToCeaSvm;
@@ -34,6 +35,7 @@ const gas_calculator_1 = require("./gas-calculator");
34
35
  const preflight_1 = require("./preflight");
35
36
  const svm_rent_1 = require("./svm-rent");
36
37
  const chain_1 = require("../../constants/chain");
38
+ const tokens_1 = require("../../constants/tokens");
37
39
  const utils_1 = require("../../utils");
38
40
  const price_fetch_1 = require("../../price-fetch/price-fetch");
39
41
  const route_detector_1 = require("../route-detector");
@@ -81,6 +83,24 @@ function resolveR2Prc20TokenEvm(params, targetChain, pushNetwork) {
81
83
  }
82
84
  return { prc20Token, burnAmount };
83
85
  }
86
+ function resolveR2DestinationFundsToken(token, targetChain, pushNetwork) {
87
+ var _a, _b, _c;
88
+ const pushToken = token;
89
+ if (!pushToken.prc20Address || pushToken.sourceChain !== targetChain) {
90
+ return token;
91
+ }
92
+ const destinationTokens = (_a = tokens_1.MOVEABLE_TOKENS[targetChain]) !== null && _a !== void 0 ? _a : [];
93
+ const nativePrc20 = (0, helpers_1.getNativePRC20ForChain)(targetChain, pushNetwork);
94
+ if (pushToken.prc20Address.toLowerCase() === nativePrc20.toLowerCase()) {
95
+ return ((_b = destinationTokens.find((candidate) => candidate.mechanism === 'native')) !== null && _b !== void 0 ? _b : {
96
+ symbol: token.symbol,
97
+ decimals: token.decimals,
98
+ address: selectors_1.ZERO_ADDRESS,
99
+ mechanism: 'native',
100
+ });
101
+ }
102
+ return ((_c = destinationTokens.find((candidate) => candidate.symbol === token.symbol)) !== null && _c !== void 0 ? _c : token);
103
+ }
84
104
  /**
85
105
  * SVM counterpart to `resolveR2Prc20TokenEvm`. SVM adds an EXECUTE-only
86
106
  * branch (no value, no funds, but `hasSvmExecute === true`) that still needs
@@ -156,13 +176,19 @@ function buildR3SvmExtraPayload(ctx, params, ueaAddress, sourceChain, inboundNon
156
176
  * resolved `ceaAddress` because the native-value self-call branch skips the
157
177
  * multicall when the target IS the CEA (avoids a CEA._handleMulticall revert).
158
178
  */
159
- function buildR2CeaPayloadEvm(params, ceaAddress, targetAddress) {
179
+ function buildR2CeaPayloadEvm(params, ceaAddress, targetAddress, targetChain, pushNetwork) {
160
180
  var _a, _b, _c, _d, _e;
161
181
  if (params.migration) {
162
182
  return (0, payload_builders_1.buildMigrationPayload)();
163
183
  }
164
184
  const ceaMulticalls = [];
165
185
  const hasData = (0, data_utils_1.hasExecutablePayloadData)(params.data);
186
+ const fundsToken = ((_a = params.funds) === null || _a === void 0 ? void 0 : _a.amount)
187
+ ? resolveR2DestinationFundsToken(params.funds.token, targetChain, pushNetwork)
188
+ : undefined;
189
+ const nativeFundsValue = ((_b = params.funds) === null || _b === void 0 ? void 0 : _b.amount) && (fundsToken === null || fundsToken === void 0 ? void 0 : fundsToken.mechanism) === 'native'
190
+ ? params.funds.amount
191
+ : BigInt(0);
166
192
  if (hasData) {
167
193
  if (Array.isArray(params.data)) {
168
194
  ceaMulticalls.push(...params.data);
@@ -171,16 +197,15 @@ function buildR2CeaPayloadEvm(params, ceaAddress, targetAddress) {
171
197
  // When ERC-20 funds are provided with a single payload, auto-prepend a
172
198
  // transfer() call so the tokens minted to the CEA are forwarded to the
173
199
  // target address. Mirrors the Route 1 behavior in buildExecuteMulticall.
174
- if ((_a = params.funds) === null || _a === void 0 ? void 0 : _a.amount) {
175
- const token = params.funds.token;
176
- if (token && token.mechanism !== 'native') {
200
+ if ((_c = params.funds) === null || _c === void 0 ? void 0 : _c.amount) {
201
+ if (fundsToken && fundsToken.mechanism !== 'native') {
177
202
  const erc20Transfer = (0, viem_1.encodeFunctionData)({
178
203
  abi: erc20_evm_1.ERC20_EVM,
179
204
  functionName: 'transfer',
180
205
  args: [targetAddress, params.funds.amount],
181
206
  });
182
207
  ceaMulticalls.push({
183
- to: token.address,
208
+ to: fundsToken.address,
184
209
  value: BigInt(0),
185
210
  data: erc20Transfer,
186
211
  });
@@ -190,29 +215,24 @@ function buildR2CeaPayloadEvm(params, ceaAddress, targetAddress) {
190
215
  // contract receives it alongside the payload call.
191
216
  ceaMulticalls.push({
192
217
  to: targetAddress,
193
- value: (_b = params.value) !== null && _b !== void 0 ? _b : BigInt(0),
218
+ value: ((_d = params.value) !== null && _d !== void 0 ? _d : BigInt(0)) + nativeFundsValue,
194
219
  data: params.data,
195
220
  });
196
221
  }
197
222
  }
198
223
  else {
199
- const token = ((_c = params.funds) === null || _c === void 0 ? void 0 : _c.amount)
200
- ? params.funds.token
201
- : undefined;
202
- if (((_d = params.funds) === null || _d === void 0 ? void 0 : _d.amount) && token && token.mechanism !== 'native') {
224
+ if (((_e = params.funds) === null || _e === void 0 ? void 0 : _e.amount) && fundsToken && fundsToken.mechanism !== 'native') {
203
225
  // ERC-20 funds: forward via ERC20.transfer from the CEA.
204
- if (token) {
205
- const erc20Transfer = (0, viem_1.encodeFunctionData)({
206
- abi: erc20_evm_1.ERC20_EVM,
207
- functionName: 'transfer',
208
- args: [targetAddress, params.funds.amount],
209
- });
210
- ceaMulticalls.push({
211
- to: token.address,
212
- value: BigInt(0),
213
- data: erc20Transfer,
214
- });
215
- }
226
+ const erc20Transfer = (0, viem_1.encodeFunctionData)({
227
+ abi: erc20_evm_1.ERC20_EVM,
228
+ functionName: 'transfer',
229
+ args: [targetAddress, params.funds.amount],
230
+ });
231
+ ceaMulticalls.push({
232
+ to: fundsToken.address,
233
+ value: BigInt(0),
234
+ data: erc20Transfer,
235
+ });
216
236
  }
217
237
  if (params.value) {
218
238
  // Native value transfer only. Skip the multicall when sending to the CEA
@@ -225,13 +245,13 @@ function buildR2CeaPayloadEvm(params, ceaAddress, targetAddress) {
225
245
  });
226
246
  }
227
247
  }
228
- else if (((_e = params.funds) === null || _e === void 0 ? void 0 : _e.amount) && (token === null || token === void 0 ? void 0 : token.mechanism) === 'native') {
248
+ else if (nativeFundsValue > BigInt(0)) {
229
249
  // Native funds (e.g. pETH → ETH): forward value to the recipient.
230
250
  // Self-CEA is skipped — the gateway already deposits into the CEA.
231
251
  if (targetAddress.toLowerCase() !== ceaAddress.toLowerCase()) {
232
252
  ceaMulticalls.push({
233
253
  to: targetAddress,
234
- value: params.funds.amount,
254
+ value: nativeFundsValue,
235
255
  data: '0x',
236
256
  });
237
257
  }
@@ -378,7 +398,6 @@ function executeUoaToCea(ctx, params, executeFn) {
378
398
  // --- 202: Gas estimation (spec-ordered before 203) ---
379
399
  let gasFee = BigInt(0);
380
400
  let protocolFee = BigInt(0);
381
- let outboundGasPrice = BigInt(0);
382
401
  let gasToken = selectors_1.ZERO_ADDRESS;
383
402
  let universalCoreAddress;
384
403
  if (prc20Token !== selectors_1.ZERO_ADDRESS) {
@@ -387,7 +406,6 @@ function executeUoaToCea(ctx, params, executeFn) {
387
406
  const result = yield (0, gas_calculator_1.queryOutboundGasFee)(ctx, prc20Token, gasLimitForQuery, targetChain);
388
407
  gasFee = result.gasFee;
389
408
  protocolFee = result.protocolFee;
390
- outboundGasPrice = result.gasPrice;
391
409
  gasToken = result.gasToken;
392
410
  universalCoreAddress = result.universalCoreAddress;
393
411
  (0, context_1.printLog)(ctx, `executeUoaToCea — queried gas fee: ${gasFee.toString()}, gasToken: ${gasToken}`);
@@ -414,7 +432,7 @@ function executeUoaToCea(ctx, params, executeFn) {
414
432
  const ueaNonce = (!isUEADeployed || isNativePushEOA) ? BigInt(0) : yield (0, uea_manager_1.getUEANonce)(ctx, ueaAddress);
415
433
  // --- Build CEA payload (requires ceaAddress for self-call check) ---
416
434
  // Delegates to `buildR2CeaPayloadEvm` — see helper definition above.
417
- const ceaPayload = buildR2CeaPayloadEvm(params, ceaAddress, targetAddress);
435
+ const ceaPayload = buildR2CeaPayloadEvm(params, ceaAddress, targetAddress, targetChain, ctx.pushNetwork);
418
436
  if (params.migration) {
419
437
  (0, context_1.printLog)(ctx, `executeUoaToCea — MIGRATION: using raw MIGRATION_SELECTOR payload (${ceaPayload}), native PRC-20 ${prc20Token}`);
420
438
  }
@@ -426,7 +444,7 @@ function executeUoaToCea(ctx, params, executeFn) {
426
444
  : ceaAddress;
427
445
  (0, payload_builders_1.assertCeaFundsParkingInvariant)(targetBytes, ceaPayload);
428
446
  const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, gasLimitForQuery, ceaPayload, ueaAddress, // revert recipient is the UEA
429
- (_d = params.maxPCForGas) !== null && _d !== void 0 ? _d : BigInt(0), outboundGasPrice);
447
+ (_d = params.maxPCForGas) !== null && _d !== void 0 ? _d : BigInt(0));
430
448
  (0, context_1.printLog)(ctx, `executeUoaToCea — outbound request: ${JSON.stringify({
431
449
  recipient: outboundReq.recipient,
432
450
  token: outboundReq.token,
@@ -605,7 +623,6 @@ function executeUoaToCeaSvm(ctx, params, target, executeFn) {
605
623
  // --- 202: Gas estimation (spec-ordered before 203) ---
606
624
  let gasFee = BigInt(0);
607
625
  let protocolFeeSvm = BigInt(0);
608
- let outboundGasPriceSvm = BigInt(0);
609
626
  let gasToken = selectors_1.ZERO_ADDRESS;
610
627
  let universalCoreAddress;
611
628
  // Effective gas limit seeded from the user param. When the user omits
@@ -637,7 +654,6 @@ function executeUoaToCeaSvm(ctx, params, target, executeFn) {
637
654
  });
638
655
  gasFee = result.gasFee;
639
656
  protocolFeeSvm = result.protocolFee;
640
- outboundGasPriceSvm = result.gasPrice;
641
657
  gasToken = result.gasToken;
642
658
  universalCoreAddress = result.universalCoreAddress;
643
659
  // When user omits gasLimit (sent as 0), the contract computes fees using
@@ -664,7 +680,7 @@ function executeUoaToCeaSvm(ctx, params, target, executeFn) {
664
680
  // --- Build outbound request ---
665
681
  // targetBytes: for execute = program id (resolver output); for withdraw = to.address
666
682
  const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, effectiveGasLimit, svmPayload, ueaAddress, // revert recipient is the UEA
667
- (_f = params.maxPCForGas) !== null && _f !== void 0 ? _f : BigInt(0), outboundGasPriceSvm);
683
+ (_f = params.maxPCForGas) !== null && _f !== void 0 ? _f : BigInt(0));
668
684
  (0, context_1.printLog)(ctx, `executeUoaToCeaSvm — outbound request: ${JSON.stringify({
669
685
  recipient: outboundReq.recipient,
670
686
  token: outboundReq.token,
@@ -971,7 +987,6 @@ function executeCeaToPush(ctx, params, executeFn) {
971
987
  // 11. Query gas fees from UniversalCore
972
988
  let gasFee = BigInt(0);
973
989
  let protocolFeeR3 = BigInt(0);
974
- let outboundGasPriceR3 = BigInt(0);
975
990
  let nativeValueForGas = BigInt(0);
976
991
  let gasToken = selectors_1.ZERO_ADDRESS;
977
992
  let sizingDecisionR3;
@@ -981,11 +996,10 @@ function executeCeaToPush(ctx, params, executeFn) {
981
996
  const result = yield (0, gas_calculator_1.queryOutboundGasFee)(ctx, prc20Token, outboundGasLimit, sourceChain);
982
997
  gasToken = result.gasToken;
983
998
  gasFee = result.gasFee;
984
- outboundGasPriceR3 = result.gasPrice;
985
999
  protocolFeeR3 = result.protocolFee;
986
1000
  nativeValueForGas = result.nativeValueForGas;
987
1001
  sizingDecisionR3 = result.sizing;
988
- outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, prc20Token, burnAmount, outboundGasLimit, ceaPayload, ueaAddress, (_k = params.maxPCForGas) !== null && _k !== void 0 ? _k : BigInt(0), outboundGasPriceR3);
1002
+ outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, prc20Token, burnAmount, outboundGasLimit, ceaPayload, ueaAddress, (_k = params.maxPCForGas) !== null && _k !== void 0 ? _k : BigInt(0));
989
1003
  (0, context_1.printLog)(ctx, `executeCeaToPush — queried gas fee: ${gasFee.toString()}, gasToken: ${gasToken}, nativeValueForGas: ${nativeValueForGas.toString()}, sizing=${(_m = (_l = result.sizing) === null || _l === void 0 ? void 0 : _l.category) !== null && _m !== void 0 ? _m : 'legacy'}`);
990
1004
  (0, context_1.fireProgressHook)(ctx, progress_hook_types_1.PROGRESS_HOOK.SEND_TX_302_02, sourceChain, protocolFeeR3, gasFee);
991
1005
  }
@@ -1190,7 +1204,6 @@ function executeCeaToPushSvm(ctx, params, sourceChain, executeFn) {
1190
1204
  // Query gas fees
1191
1205
  let gasFee = BigInt(0);
1192
1206
  let protocolFeeR3Svm = BigInt(0);
1193
- let outboundGasPriceR3Svm = BigInt(0);
1194
1207
  let nativeValueForGas = BigInt(0);
1195
1208
  let gasToken = selectors_1.ZERO_ADDRESS;
1196
1209
  let sizingDecisionR3Svm;
@@ -1210,12 +1223,11 @@ function executeCeaToPushSvm(ctx, params, sourceChain, executeFn) {
1210
1223
  });
1211
1224
  gasToken = result.gasToken;
1212
1225
  gasFee = result.gasFee;
1213
- outboundGasPriceR3Svm = result.gasPrice;
1214
1226
  protocolFeeR3Svm = result.protocolFee;
1215
1227
  nativeValueForGas = result.nativeValueForGas;
1216
1228
  sizingDecisionR3Svm = result.sizing;
1217
1229
  effectiveGasLimit = result.gasLimitUsed;
1218
- outboundReq = (0, payload_builders_1.buildOutboundRequest)(gatewayProgramHex, prc20Token, burnAmount, effectiveGasLimit, svmPayload, ueaAddress, (_c = params.maxPCForGas) !== null && _c !== void 0 ? _c : BigInt(0), outboundGasPriceR3Svm);
1230
+ outboundReq = (0, payload_builders_1.buildOutboundRequest)(gatewayProgramHex, prc20Token, burnAmount, effectiveGasLimit, svmPayload, ueaAddress, (_c = params.maxPCForGas) !== null && _c !== void 0 ? _c : BigInt(0));
1219
1231
  (0, context_1.printLog)(ctx, `executeCeaToPushSvm — resolved effectiveGasLimit: ${effectiveGasLimit} ` +
1220
1232
  `(gasFee=${result.gasFee}, gasPrice=${result.gasPrice})`);
1221
1233
  (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'}`);
@@ -1355,7 +1367,7 @@ function executeCeaToCea(ctx, params, executeFn) {
1355
1367
  */
1356
1368
  function buildPayloadForRoute(ctx, params, route, nonce) {
1357
1369
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
1358
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
1370
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
1359
1371
  const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
1360
1372
  switch (route) {
1361
1373
  case route_detector_1.TransactionRoute.UOA_TO_PUSH: {
@@ -1406,56 +1418,19 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
1406
1418
  }
1407
1419
  // EVM path: Resolve CEA address first (needed for self-transfer check)
1408
1420
  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]);
1409
- // Build CEA outbound payload
1410
- const multicalls = [];
1411
- if ((0, data_utils_1.hasExecutablePayloadData)(params.data)) {
1412
- if (Array.isArray(params.data)) {
1413
- multicalls.push(...params.data);
1414
- }
1415
- else {
1416
- // Single call with data. Native value (if any) is already delivered to
1417
- // CEA by the Vault via executeUniversalTx{value: amount}(). Attaching
1418
- // value to the call would revert if the target function is not payable.
1419
- // To call a payable function with value, use explicit multicalls.
1420
- multicalls.push({
1421
- to: target.address,
1422
- value: BigInt(0),
1423
- data: params.data,
1424
- });
1425
- }
1426
- }
1427
- else if (params.value) {
1428
- // Skip multicall when sending native value to own CEA — gateway deposits directly.
1429
- // Self-call with value would revert (CEA._handleMulticall rejects it).
1430
- if (target.address.toLowerCase() !== ceaAddress.toLowerCase()) {
1431
- multicalls.push({
1432
- to: target.address,
1433
- value: params.value,
1434
- data: '0x',
1435
- });
1436
- }
1437
- }
1438
- const payload = (0, payload_builders_1.buildCeaMulticallPayload)(multicalls);
1439
- let prc20Token = selectors_1.ZERO_ADDRESS;
1440
- let burnAmount = BigInt(0);
1441
- if ((_e = params.funds) === null || _e === void 0 ? void 0 : _e.amount) {
1442
- const token = params.funds.token;
1443
- if (token) {
1444
- prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token).address;
1445
- burnAmount = params.funds.amount;
1446
- }
1447
- }
1421
+ const payload = buildR2CeaPayloadEvm(params, ceaAddress, target.address, target.chain, ctx.pushNetwork);
1422
+ const { prc20Token, burnAmount } = resolveR2Prc20TokenEvm(params, target.chain, ctx.pushNetwork);
1448
1423
  const targetBytes = payload === '0x'
1449
1424
  ? selectors_1.ZERO_ADDRESS
1450
1425
  : ceaAddress;
1451
1426
  (0, payload_builders_1.assertCeaFundsParkingInvariant)(targetBytes, payload);
1452
- 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));
1427
+ const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, (_e = params.gasLimit) !== null && _e !== void 0 ? _e : BigInt(0), payload, ueaAddress, (_f = params.maxPCForGas) !== null && _f !== void 0 ? _f : BigInt(0));
1453
1428
  return { payload, gatewayRequest: outboundReq };
1454
1429
  }
1455
1430
  case route_detector_1.TransactionRoute.CEA_TO_PUSH: {
1456
1431
  // Route 3: CEA -> Push Chain
1457
1432
  // Build CEA multicall (sendUniversalTxToUEA self-call) and wrap in outbound
1458
- if (!((_h = params.from) === null || _h === void 0 ? void 0 : _h.chain)) {
1433
+ if (!((_g = params.from) === null || _g === void 0 ? void 0 : _g.chain)) {
1459
1434
  throw new Error('Route 3 (CEA -> Push) requires from.chain');
1460
1435
  }
1461
1436
  const sourceChain = params.from.chain;
@@ -1482,17 +1457,17 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
1482
1457
  });
1483
1458
  // Payload-only outbound: drain amount lives inside ixData.
1484
1459
  const burnAmount = BigInt(0);
1485
- 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));
1460
+ const outboundReq = (0, payload_builders_1.buildOutboundRequest)(gatewayProgramHex, prc20Token, burnAmount, (_h = params.gasLimit) !== null && _h !== void 0 ? _h : BigInt(0), svmPayload, ueaAddress, (_j = params.maxPCForGas) !== null && _j !== void 0 ? _j : BigInt(0));
1486
1461
  return { payload: svmPayload, gatewayRequest: outboundReq };
1487
1462
  }
1488
- const { cea: ceaAddress } = yield (0, cea_utils_1.getCEAAddress)(ueaAddress, sourceChain, (_l = ctx.rpcUrls[sourceChain]) === null || _l === void 0 ? void 0 : _l[0]);
1463
+ const { cea: ceaAddress } = yield (0, cea_utils_1.getCEAAddress)(ueaAddress, sourceChain, (_k = ctx.rpcUrls[sourceChain]) === null || _k === void 0 ? void 0 : _k[0]);
1489
1464
  // CEA auto-deploys on-chain: Vault.finalizeUniversalTx calls CEAFactory.deployCEA()
1490
1465
  // if CEA doesn't exist yet. No SDK-side blocking needed.
1491
1466
  // Build CEA multicalls (self-calls via sendUniversalTxToUEA)
1492
1467
  const ceaMulticalls = [];
1493
1468
  let tokenAddress = selectors_1.ZERO_ADDRESS;
1494
1469
  let amount = BigInt(0);
1495
- if ((_m = params.funds) === null || _m === void 0 ? void 0 : _m.amount) {
1470
+ if ((_l = params.funds) === null || _l === void 0 ? void 0 : _l.amount) {
1496
1471
  const token = params.funds.token;
1497
1472
  if (token) {
1498
1473
  if (token.mechanism === 'native') {
@@ -1516,7 +1491,7 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
1516
1491
  // Wrap in UniversalPayload struct for the relay.
1517
1492
  let pushPayload = '0x';
1518
1493
  if ((0, data_utils_1.hasExecutablePayloadData)(params.data) ||
1519
- (((_o = params.funds) === null || _o === void 0 ? void 0 : _o.amount) && ((_p = params.value) !== null && _p !== void 0 ? _p : BigInt(0)) > BigInt(0))) {
1494
+ (((_m = params.funds) === null || _m === void 0 ? void 0 : _m.amount) && ((_o = params.value) !== null && _o !== void 0 ? _o : BigInt(0)) > BigInt(0))) {
1520
1495
  const multicallData = (0, payload_builders_1.buildExecuteMulticall)({
1521
1496
  execute: {
1522
1497
  to: pushDestination,
@@ -1538,8 +1513,8 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
1538
1513
  // Route 3: CEA uses its own pre-existing balance — no PRC-20 burn needed.
1539
1514
  // burnAmount = 0 makes this a payload-only outbound relay.
1540
1515
  const burnAmount = BigInt(0);
1541
- const outboundGasLimit = (_q = params.gasLimit) !== null && _q !== void 0 ? _q : selectors_1.DEFAULT_CEA_TO_PUSH_GAS_LIMIT;
1542
- const outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, prc20Token, burnAmount, outboundGasLimit, ceaPayload, ueaAddress, (_r = params.maxPCForGas) !== null && _r !== void 0 ? _r : BigInt(0));
1516
+ const outboundGasLimit = (_p = params.gasLimit) !== null && _p !== void 0 ? _p : selectors_1.DEFAULT_CEA_TO_PUSH_GAS_LIMIT;
1517
+ const outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, prc20Token, burnAmount, outboundGasLimit, ceaPayload, ueaAddress, (_q = params.maxPCForGas) !== null && _q !== void 0 ? _q : BigInt(0));
1543
1518
  return { payload: ceaPayload, gatewayRequest: outboundReq };
1544
1519
  }
1545
1520
  default:
@@ -275,7 +275,7 @@ export interface WaitOptions {
275
275
  inboundTimeoutMs?: number;
276
276
  /**
277
277
  * Override the poll interval (ms) between outbound status checks. Default
278
- * is 5000ms. Lower values give faster feedback on fast relays; higher
278
+ * is 3000ms. Lower values give faster feedback on fast relays; higher
279
279
  * values reduce RPC pressure. Only applies to R2 / R3 outbound polling.
280
280
  */
281
281
  outboundPollingIntervalMs?: number;
@@ -671,7 +671,7 @@ export interface CascadeHopInfo {
671
671
  export interface CascadeTrackOptions {
672
672
  /** Polling interval (default: 5000ms) */
673
673
  pollingIntervalMs?: number;
674
- /** Total timeout (default: 600000ms = 10 min) */
674
+ /** Total timeout (default: 300000ms = 5 min) */
675
675
  timeout?: number;
676
676
  /** Per-hop progress callback */
677
677
  progressHook?: (event: CascadeProgressEvent) => void;
@@ -777,16 +777,16 @@ export interface OutboundTxDetails {
777
777
  */
778
778
  export interface WaitForOutboundOptions {
779
779
  /**
780
- * Initial wait before first poll (default: 30000ms)
780
+ * Initial wait before first poll (default: 15000ms)
781
781
  * Gives relay time to process before we start polling
782
782
  */
783
783
  initialWaitMs?: number;
784
784
  /**
785
- * Interval between polls (default: 5000ms)
785
+ * Interval between polls (default: 3000ms)
786
786
  */
787
787
  pollingIntervalMs?: number;
788
788
  /**
789
- * Total timeout in milliseconds (default: 120000ms)
789
+ * Total timeout in milliseconds (default: 300000ms)
790
790
  * Measured from start, includes initial wait
791
791
  */
792
792
  timeout?: number;