@pushchain/core 4.0.12-alpha.0 → 4.0.12

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.
@@ -65,6 +65,15 @@ class Orchestrator {
65
65
  execute(execute) {
66
66
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
67
67
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
68
+ // Create buffer to collect events during execution for tx.progressHook() replay
69
+ const eventBuffer = [];
70
+ // Store original progressHook and wrap to collect events
71
+ const originalHook = this.progressHook;
72
+ this.progressHook = (event) => {
73
+ eventBuffer.push(event);
74
+ if (originalHook)
75
+ originalHook(event);
76
+ };
68
77
  try {
69
78
  if (execute.funds) {
70
79
  if (!execute.data || execute.data === '0x') {
@@ -114,7 +123,7 @@ class Orchestrator {
114
123
  const { nonce, deployed } = yield this.getUeaStatusAndNonce();
115
124
  const { payload: universalPayload, req } = yield this.buildGatewayPayloadAndGas(execute, nonce, 'sendFunds', bridgeAmount);
116
125
  const ueaAddress = this.computeUEAOffchain();
117
- console.log('[DEBUG] sendFunds — buildGatewayPayloadAndGas result:', JSON.stringify({
126
+ this.printLog('sendFunds — buildGatewayPayloadAndGas result: ' + JSON.stringify({
118
127
  recipient: execute.to,
119
128
  ueaAddress,
120
129
  isSelfBridge: execute.to.toLowerCase() === ueaAddress.toLowerCase(),
@@ -128,11 +137,11 @@ class Orchestrator {
128
137
  // Compute minimal native amount to deposit for gas on Push Chain
129
138
  const ueaBalanceForGas = yield this.pushClient.getBalance(ueaAddress);
130
139
  const nativeAmount = yield this.calculateNativeAmountForDeposit(chain, BigInt(0), ueaBalanceForGas);
131
- console.log('[DEBUG] sendFunds — nativeAmount:', nativeAmount.toString(), 'ueaBalanceForGas:', ueaBalanceForGas.toString());
140
+ this.printLog(`sendFunds — nativeAmount: ${nativeAmount.toString()}, ueaBalanceForGas: ${ueaBalanceForGas.toString()}`);
132
141
  // We log the SEND_TX_03_01 here because the progress hook for gas estimation should arrive before the resolving of UEA.
133
142
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_03_01);
134
143
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_03_02, ueaAddress, deployed);
135
- console.log('[DEBUG] UEA resolved:', ueaAddress, 'deployed:', deployed);
144
+ this.printLog(`UEA resolved: ${ueaAddress}, deployed: ${deployed}`);
136
145
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_01, amount, execute.funds.token.decimals, symbol);
137
146
  if (vm === enums_1.VM.EVM) {
138
147
  const evmClient = new evm_client_1.EvmClient({ rpcUrls });
@@ -171,7 +180,7 @@ class Orchestrator {
171
180
  // revertInstruction: revertCFG,
172
181
  // signatureData: '0x',
173
182
  // } as unknown as never;
174
- console.log('[DEBUG] FUNDS ONLY SELF — gateway call payload:', JSON.stringify({
183
+ this.printLog('FUNDS ONLY SELF — gateway call payload: ' + JSON.stringify({
175
184
  gatewayAddress, functionName: 'sendUniversalTx', req,
176
185
  value: (isNative ? nativeAmount + bridgeAmount : nativeAmount).toString(),
177
186
  isNative, bridgeAmount: bridgeAmount.toString(),
@@ -199,7 +208,7 @@ class Orchestrator {
199
208
  // revertInstruction: revertCFG,
200
209
  // signatureData: '0x',
201
210
  // } as unknown as never;
202
- console.log('[DEBUG] FUNDS ONLY OTHER — gateway call payload:', JSON.stringify({
211
+ this.printLog('FUNDS ONLY OTHER — gateway call payload: ' + JSON.stringify({
203
212
  gatewayAddress, functionName: 'sendUniversalTx', req,
204
213
  value: nativeAmount.toString(),
205
214
  isNative, bridgeAmount: bridgeAmount.toString(),
@@ -226,10 +235,10 @@ class Orchestrator {
226
235
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_04);
227
236
  // Syncing with Push Chain - emit before query
228
237
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_05);
229
- console.log('[DEBUG] sendFunds — querying Push Chain status:', {
238
+ this.printLog('sendFunds — querying Push Chain status: ' + JSON.stringify({
230
239
  txHash,
231
240
  evmGatewayMethod: execute.to === ueaAddress ? 'sendFunds' : 'sendTxWithFunds',
232
- });
241
+ }));
233
242
  const pushChainUniversalTx = yield this.queryUniversalTxStatusFromGatewayTx(evmClient, gatewayAddress, txHash, execute.to === ueaAddress ? 'sendFunds' : 'sendTxWithFunds');
234
243
  if (!((_a = pushChainUniversalTx === null || pushChainUniversalTx === void 0 ? void 0 : pushChainUniversalTx.pcTx) === null || _a === void 0 ? void 0 : _a.length)) {
235
244
  throw new Error(`Failed to retrieve Push Chain transaction status for gateway tx: ${txHash}. ` +
@@ -238,8 +247,8 @@ class Orchestrator {
238
247
  // For sendFunds operations, MintPC (first) succeeds and executePayload (second) may fail
239
248
  // Always use the last pcTx entry as it represents the final execution result
240
249
  const lastPcTransaction = pushChainUniversalTx.pcTx.at(-1);
241
- console.log('[DEBUG] sendFunds — pushChainUniversalTx pcTx:', JSON.stringify((_b = pushChainUniversalTx === null || pushChainUniversalTx === void 0 ? void 0 : pushChainUniversalTx.pcTx) === null || _b === void 0 ? void 0 : _b.map((p) => ({ txHash: p.txHash, status: p.status, errorMsg: p.errorMsg })), null, 2));
242
- console.log('[DEBUG] sendFunds — using lastPcTransaction:', JSON.stringify(lastPcTransaction, null, 2));
250
+ this.printLog('sendFunds — pushChainUniversalTx pcTx: ' + JSON.stringify((_b = pushChainUniversalTx === null || pushChainUniversalTx === void 0 ? void 0 : pushChainUniversalTx.pcTx) === null || _b === void 0 ? void 0 : _b.map((p) => ({ txHash: p.txHash, status: p.status, errorMsg: p.errorMsg })), null, 2));
251
+ this.printLog('sendFunds — using lastPcTransaction: ' + JSON.stringify(lastPcTransaction, null, 2));
243
252
  if (!(lastPcTransaction === null || lastPcTransaction === void 0 ? void 0 : lastPcTransaction.txHash)) {
244
253
  // Check for error messages in failed entries
245
254
  const failedPcTx = pushChainUniversalTx.pcTx.find((pcTx) => pcTx.status === 'FAILED' && pcTx.errorMsg);
@@ -249,7 +258,7 @@ class Orchestrator {
249
258
  throw new Error(`No transaction hash found in Push Chain response for gateway tx: ${txHash}${errorDetails}`);
250
259
  }
251
260
  const tx = yield this.pushClient.getTransaction(lastPcTransaction.txHash);
252
- const response = yield this.transformToUniversalTxResponse(tx);
261
+ const response = yield this.transformToUniversalTxResponse(tx, eventBuffer);
253
262
  // Funds Flow: Funds credited on Push Chain
254
263
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_06, bridgeAmount, execute.funds.token.decimals, symbol);
255
264
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_01, [response]);
@@ -416,7 +425,7 @@ class Orchestrator {
416
425
  throw new Error(`No transaction hash found in Push Chain response for gateway tx: ${txSignature}${errorDetails}`);
417
426
  }
418
427
  const tx = yield this.pushClient.getTransaction(lastPcTransaction.txHash);
419
- const response = yield this.transformToUniversalTxResponse(tx);
428
+ const response = yield this.transformToUniversalTxResponse(tx, eventBuffer);
420
429
  // Funds Flow: Funds credited on Push Chain
421
430
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_06, bridgeAmount, execute.funds.token.decimals, symbol);
422
431
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_01, [response]);
@@ -710,7 +719,7 @@ class Orchestrator {
710
719
  throw new Error(`No transaction hash found in Push Chain response for gateway tx: ${txHash}${errorDetails}`);
711
720
  }
712
721
  const tx = yield this.pushClient.getTransaction(lastPcTransaction.txHash);
713
- const response = yield this.transformToUniversalTxResponse(tx);
722
+ const response = yield this.transformToUniversalTxResponse(tx, eventBuffer);
714
723
  // Funds Flow: Funds credited on Push Chain
715
724
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_06, bridgeAmount, execute.funds.token.decimals, symbol);
716
725
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_01, [response]);
@@ -729,7 +738,7 @@ class Orchestrator {
729
738
  */
730
739
  if (this.isPushChain(chain)) {
731
740
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_07);
732
- const tx = yield this.sendPushTx(execute);
741
+ const tx = yield this.sendPushTx(execute, eventBuffer);
733
742
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_01, [tx]);
734
743
  return tx;
735
744
  }
@@ -778,7 +787,7 @@ class Orchestrator {
778
787
  // execute.to = zeroAddress;
779
788
  payloadTo = viem_1.zeroAddress;
780
789
  console.warn(`Multicalls should have execute.to as ${viem_1.zeroAddress}`);
781
- payloadData = this._buildMulticallPayloadData(execute.to, (0, payload_builders_1.buildExecuteMulticall)({ execute, ueaAddress: UEA }));
790
+ payloadData = this._buildMulticallPayloadData(execute.to, (0, payload_builders_1.buildExecuteMulticall)({ execute, ueaAddress: UEA, logger: this.printLog.bind(this) }));
782
791
  req = this._buildUniversalTxRequest({
783
792
  recipient: viem_1.zeroAddress,
784
793
  token: viem_1.zeroAddress,
@@ -794,7 +803,7 @@ class Orchestrator {
794
803
  // TODO: Check but I beleive this code section is never reached.
795
804
  if (execute.funds) {
796
805
  payloadTo = viem_1.zeroAddress;
797
- payloadData = this._buildMulticallPayloadData(execute.to, (0, payload_builders_1.buildExecuteMulticall)({ execute, ueaAddress: UEA }));
806
+ payloadData = this._buildMulticallPayloadData(execute.to, (0, payload_builders_1.buildExecuteMulticall)({ execute, ueaAddress: UEA, logger: this.printLog.bind(this) }));
798
807
  req = this._buildUniversalTxRequest({
799
808
  recipient: viem_1.zeroAddress,
800
809
  token: viem_1.zeroAddress,
@@ -807,7 +816,7 @@ class Orchestrator {
807
816
  // VALUE + PAYLOAD ONLY OTHER
808
817
  payloadTo = execute.to;
809
818
  payloadData = execute.data || '0x';
810
- const reqData = this._buildMulticallPayloadData(execute.to, (0, payload_builders_1.buildExecuteMulticall)({ execute, ueaAddress: UEA }));
819
+ const reqData = this._buildMulticallPayloadData(execute.to, (0, payload_builders_1.buildExecuteMulticall)({ execute, ueaAddress: UEA, logger: this.printLog.bind(this) }));
811
820
  const universalPayload = JSON.parse(JSON.stringify({
812
821
  to: viem_1.zeroAddress,
813
822
  value: execute.value,
@@ -923,7 +932,7 @@ class Orchestrator {
923
932
  throw new Error(`No transaction hash found in Push Chain response for gateway tx: ${feeLockTxHash}${errorDetails}`);
924
933
  }
925
934
  const tx = yield this.pushClient.getTransaction(lastPcTransaction.txHash);
926
- const response = yield this.transformToUniversalTxResponse(tx);
935
+ const response = yield this.transformToUniversalTxResponse(tx, eventBuffer);
927
936
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_01, [response]);
928
937
  return response;
929
938
  }
@@ -932,7 +941,7 @@ class Orchestrator {
932
941
  */
933
942
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_07);
934
943
  // We don't need to query via gRPC the PC transaction since it's getting returned it here already.
935
- const transactions = yield this.sendUniversalTx(isUEADeployed, feeLockTxHash, universalPayload, verificationData);
944
+ const transactions = yield this.sendUniversalTx(isUEADeployed, feeLockTxHash, universalPayload, verificationData, eventBuffer);
936
945
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_01, transactions);
937
946
  return transactions[transactions.length - 1];
938
947
  }
@@ -952,6 +961,10 @@ class Orchestrator {
952
961
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_02, errMessage);
953
962
  throw err;
954
963
  }
964
+ finally {
965
+ // Restore original progressHook
966
+ this.progressHook = originalHook;
967
+ }
955
968
  });
956
969
  }
957
970
  /**
@@ -1218,8 +1231,8 @@ class Orchestrator {
1218
1231
  /**
1219
1232
  * Sends a custom Cosmos tx to Push Chain (gasless) to execute user intent.
1220
1233
  */
1221
- sendUniversalTx(isUEADeployed, feeLockTxHash, universalPayload, verificationData) {
1222
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
1234
+ sendUniversalTx(isUEADeployed_1, feeLockTxHash_1, universalPayload_1, verificationData_1) {
1235
+ return tslib_1.__awaiter(this, arguments, void 0, function* (isUEADeployed, feeLockTxHash, universalPayload, verificationData, eventBuffer = []) {
1223
1236
  var _a, _b;
1224
1237
  const { chain, address } = this.universalSigner.account;
1225
1238
  const { vm, chainId } = chain_1.CHAIN_INFO[chain];
@@ -1280,7 +1293,8 @@ class Orchestrator {
1280
1293
  const evmTxs = yield Promise.all(ethTxHashes.map((hash) => tslib_1.__awaiter(this, void 0, void 0, function* () {
1281
1294
  return yield this.pushClient.getTransaction(hash);
1282
1295
  })));
1283
- return yield Promise.all(evmTxs.map((tx) => this.transformToUniversalTxResponse(tx)));
1296
+ // Pass eventBuffer only to the last transaction (which is the one returned to user)
1297
+ return yield Promise.all(evmTxs.map((tx, index) => this.transformToUniversalTxResponse(tx, index === evmTxs.length - 1 ? eventBuffer : [])));
1284
1298
  });
1285
1299
  }
1286
1300
  /**
@@ -1289,8 +1303,8 @@ class Orchestrator {
1289
1303
  * @param execute
1290
1304
  * @returns Cosmos Tx Response for a given Evm Tx
1291
1305
  */
1292
- sendPushTx(execute) {
1293
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
1306
+ sendPushTx(execute_1) {
1307
+ return tslib_1.__awaiter(this, arguments, void 0, function* (execute, eventBuffer = []) {
1294
1308
  // For PushChain, multicall is not supported. Ensure data is hex string.
1295
1309
  if (Array.isArray(execute.data)) {
1296
1310
  throw new Error('Multicall is not supported on PushChain');
@@ -1302,7 +1316,7 @@ class Orchestrator {
1302
1316
  signer: this.universalSigner,
1303
1317
  });
1304
1318
  const txResponse = yield this.pushClient.getTransaction(txHash);
1305
- return yield this.transformToUniversalTxResponse(txResponse);
1319
+ return yield this.transformToUniversalTxResponse(txResponse, eventBuffer);
1306
1320
  });
1307
1321
  }
1308
1322
  /**
@@ -1487,13 +1501,22 @@ class Orchestrator {
1487
1501
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
1488
1502
  const { chain = this.getPushChainForNetwork(), progress, waitForCompletion = true, advanced = {}, } = options !== null && options !== void 0 ? options : {};
1489
1503
  const { pollingIntervalMs = 1000, timeout = 300000, rpcUrls = {}, } = advanced;
1490
- // Use custom progress hook if provided, otherwise use instance hook
1491
- const progressHookFn = progress !== null && progress !== void 0 ? progress : this.progressHook;
1504
+ // Helper to invoke both per-transaction and orchestrator hooks
1505
+ const invokeProgressHook = (hookPayload) => {
1506
+ this.printLog(hookPayload.message);
1507
+ // Per-transaction hook called FIRST
1508
+ if (progress) {
1509
+ progress(hookPayload);
1510
+ }
1511
+ // Orchestrator-level hook called SECOND
1512
+ if (this.progressHook) {
1513
+ this.progressHook(hookPayload);
1514
+ }
1515
+ };
1492
1516
  // Emit TRACK_TX_01 - tracking started
1493
- if (progressHookFn) {
1517
+ if (progress || this.progressHook) {
1494
1518
  const hookPayload = progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.TRACK_TX_01](txHash, chain);
1495
- this.printLog(hookPayload.message);
1496
- progressHookFn(hookPayload);
1519
+ invokeProgressHook(hookPayload);
1497
1520
  }
1498
1521
  // Create client for target chain with optional RPC override
1499
1522
  const chainRPCs = rpcUrls[chain] || this.rpcUrls[chain] || chain_1.CHAIN_INFO[chain].defaultRPC;
@@ -1514,10 +1537,9 @@ class Orchestrator {
1514
1537
  const receipt = yield tx.wait(1);
1515
1538
  const universalTxResponse = yield this.transformToUniversalTxResponse(tx);
1516
1539
  // Emit TRACK_TX_99_01 - tracking complete
1517
- if (progressHookFn) {
1540
+ if (progress || this.progressHook) {
1518
1541
  const hookPayload = progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.TRACK_TX_99_01](txHash, universalTxResponse);
1519
- this.printLog(hookPayload.message);
1520
- progressHookFn(hookPayload);
1542
+ invokeProgressHook(hookPayload);
1521
1543
  }
1522
1544
  return this.transformToUniversalTxReceipt(receipt, universalTxResponse);
1523
1545
  }
@@ -1526,31 +1548,29 @@ class Orchestrator {
1526
1548
  if (!waitForCompletion) {
1527
1549
  // Non-blocking and tx not found - throw error
1528
1550
  const errorMsg = initialError instanceof Error ? initialError.message : 'Transaction not found';
1529
- if (progressHookFn) {
1551
+ if (progress || this.progressHook) {
1530
1552
  const hookPayload = progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.TRACK_TX_99_02](txHash, errorMsg);
1531
- this.printLog(hookPayload.message);
1532
- progressHookFn(hookPayload);
1553
+ invokeProgressHook(hookPayload);
1533
1554
  }
1534
1555
  throw new Error(`Transaction ${txHash} not found: ${errorMsg}`);
1535
1556
  }
1536
1557
  // Blocking mode: poll until found or timeout
1537
1558
  const start = Date.now();
1559
+ // eslint-disable-next-line no-constant-condition
1538
1560
  while (true) {
1539
1561
  // Emit TRACK_TX_02 - querying status
1540
- if (progressHookFn) {
1562
+ if (progress || this.progressHook) {
1541
1563
  const hookPayload = progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.TRACK_TX_02](txHash);
1542
- this.printLog(hookPayload.message);
1543
- progressHookFn(hookPayload);
1564
+ invokeProgressHook(hookPayload);
1544
1565
  }
1545
1566
  try {
1546
1567
  const tx = yield client.getTransaction(txHash);
1547
1568
  const receipt = yield tx.wait(1);
1548
1569
  const universalTxResponse = yield this.transformToUniversalTxResponse(tx);
1549
1570
  // Success - emit TRACK_TX_99_01
1550
- if (progressHookFn) {
1571
+ if (progress || this.progressHook) {
1551
1572
  const hookPayload = progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.TRACK_TX_99_01](txHash, universalTxResponse);
1552
- this.printLog(hookPayload.message);
1553
- progressHookFn(hookPayload);
1573
+ invokeProgressHook(hookPayload);
1554
1574
  }
1555
1575
  return this.transformToUniversalTxReceipt(receipt, universalTxResponse);
1556
1576
  }
@@ -1561,10 +1581,9 @@ class Orchestrator {
1561
1581
  // Check timeout
1562
1582
  if (Date.now() - start > timeout) {
1563
1583
  const timeoutMsg = `Timeout: transaction ${txHash} not confirmed within ${timeout}ms`;
1564
- if (progressHookFn) {
1584
+ if (progress || this.progressHook) {
1565
1585
  const hookPayload = progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.TRACK_TX_99_02](txHash, 'Timeout');
1566
- this.printLog(hookPayload.message);
1567
- progressHookFn(hookPayload);
1586
+ invokeProgressHook(hookPayload);
1568
1587
  }
1569
1588
  throw new Error(timeoutMsg);
1570
1589
  }
@@ -1631,7 +1650,7 @@ class Orchestrator {
1631
1650
  });
1632
1651
  }
1633
1652
  _buildMulticallPayloadData(to, data) {
1634
- console.log('[DEBUG] _buildMulticallPayloadData — input:', data.length, 'calls:', JSON.stringify(data, (_, v) => typeof v === 'bigint' ? v.toString() : v, 2));
1653
+ this.printLog('_buildMulticallPayloadData — input: ' + data.length + ' calls: ' + JSON.stringify(data, (_, v) => typeof v === 'bigint' ? v.toString() : v, 2));
1635
1654
  const allowedChains = [
1636
1655
  enums_1.CHAIN.ETHEREUM_SEPOLIA,
1637
1656
  enums_1.CHAIN.ARBITRUM_SEPOLIA,
@@ -2151,6 +2170,7 @@ class Orchestrator {
2151
2170
  const multicallData = (0, payload_builders_1.buildExecuteMulticall)({
2152
2171
  execute,
2153
2172
  ueaAddress: this.computeUEAOffchain(),
2173
+ logger: this.printLog.bind(this),
2154
2174
  });
2155
2175
  // THIS ABOVE WILL CHANGE WHEN FUNDS ARE PASSED
2156
2176
  const universalPayload = {
@@ -2165,7 +2185,7 @@ class Orchestrator {
2165
2185
  deadline: execute.deadline || BigInt(9999999999),
2166
2186
  vType: tx_1.VerificationType.universalTxVerification,
2167
2187
  };
2168
- console.log('[DEBUG] (universalPayload) ' + universalPayload);
2188
+ this.printLog('(universalPayload) ' + universalPayload);
2169
2189
  // Temporary while we don't change the native address from 0xeee... to 0x0000...
2170
2190
  let tokenAddress = (_f = (_e = execute.funds) === null || _e === void 0 ? void 0 : _e.token) === null || _f === void 0 ? void 0 : _f.address;
2171
2191
  if (((_h = (_g = execute.funds) === null || _g === void 0 ? void 0 : _g.token) === null || _h === void 0 ? void 0 : _h.address) ===
@@ -2186,6 +2206,7 @@ class Orchestrator {
2186
2206
  const multicallData = (0, payload_builders_1.buildExecuteMulticall)({
2187
2207
  execute,
2188
2208
  ueaAddress: this.computeUEAOffchain(),
2209
+ logger: this.printLog.bind(this),
2189
2210
  });
2190
2211
  // // The data will be the abi-encoded transfer function from erc-20 function. The recipient will be `execute.to`, the value
2191
2212
  // // will be the fundsValue property.
@@ -2197,7 +2218,7 @@ class Orchestrator {
2197
2218
  // const pushChainTo = PushChain.utils.tokens.getPRC20Address(
2198
2219
  // execute.funds!.token as MoveableToken
2199
2220
  // );
2200
- console.log('[DEBUG] sendFunds — execute params:', JSON.stringify({
2221
+ this.printLog('sendFunds — execute params: ' + JSON.stringify({
2201
2222
  to: execute.to,
2202
2223
  value: (_l = (_k = execute.value) === null || _k === void 0 ? void 0 : _k.toString()) !== null && _l !== void 0 ? _l : 'undefined',
2203
2224
  data: (_m = execute.data) !== null && _m !== void 0 ? _m : 'undefined',
@@ -2207,9 +2228,9 @@ class Orchestrator {
2207
2228
  tokenAddress: (_v = (_u = execute.funds) === null || _u === void 0 ? void 0 : _u.token) === null || _v === void 0 ? void 0 : _v.address,
2208
2229
  gasLimit: (_x = (_w = execute.gasLimit) === null || _w === void 0 ? void 0 : _w.toString()) !== null && _x !== void 0 ? _x : 'undefined',
2209
2230
  }, null, 2));
2210
- console.log('[DEBUG] sendFunds — multicallData:', JSON.stringify(multicallData, (_, v) => typeof v === 'bigint' ? v.toString() : v, 2), '(length:', multicallData.length, ')');
2231
+ this.printLog('sendFunds — multicallData: ' + JSON.stringify(multicallData, (_, v) => typeof v === 'bigint' ? v.toString() : v, 2) + ' (length: ' + multicallData.length + ')');
2211
2232
  const multicallPayloadData = this._buildMulticallPayloadData(execute.to, multicallData);
2212
- console.log('[DEBUG] sendFunds — multicallPayloadData (first 66 chars):', multicallPayloadData.slice(0, 66), '(full length:', multicallPayloadData.length, ')');
2233
+ this.printLog('sendFunds — multicallPayloadData (first 66 chars): ' + multicallPayloadData.slice(0, 66) + ' (full length: ' + multicallPayloadData.length + ')');
2213
2234
  const universalPayload = {
2214
2235
  to: viem_1.zeroAddress, // We can't simply do `0x` because we will get an error when eip712 signing the transaction.
2215
2236
  value: (_y = execute.value) !== null && _y !== void 0 ? _y : BigInt(0),
@@ -2224,7 +2245,7 @@ class Orchestrator {
2224
2245
  deadline: execute.deadline || BigInt(9999999999),
2225
2246
  vType: tx_1.VerificationType.universalTxVerification,
2226
2247
  };
2227
- console.log('[DEBUG] sendFunds — universalPayload (pre-encode):', JSON.stringify({
2248
+ this.printLog('sendFunds — universalPayload (pre-encode): ' + JSON.stringify({
2228
2249
  to: viem_1.zeroAddress,
2229
2250
  value: ((_z = execute.value) !== null && _z !== void 0 ? _z : BigInt(0)).toString(),
2230
2251
  data: multicallPayloadData,
@@ -2241,14 +2262,14 @@ class Orchestrator {
2241
2262
  tokenAddress = viem_1.zeroAddress;
2242
2263
  }
2243
2264
  const encodedPayload = this.encodeUniversalPayload(universalPayload);
2244
- console.log('[DEBUG] sendFunds — encodedPayload (first 66 chars):', encodedPayload.slice(0, 66), '(full length:', encodedPayload.length, ')');
2265
+ this.printLog('sendFunds — encodedPayload (first 66 chars): ' + encodedPayload.slice(0, 66) + ' (full length: ' + encodedPayload.length + ')');
2245
2266
  const req = this._buildUniversalTxRequest({
2246
2267
  recipient: viem_1.zeroAddress,
2247
2268
  token: tokenAddress,
2248
2269
  amount: (_4 = execute.funds) === null || _4 === void 0 ? void 0 : _4.amount,
2249
2270
  payload: encodedPayload,
2250
2271
  });
2251
- console.log('[DEBUG] sendFunds — final req:', JSON.stringify({
2272
+ this.printLog('sendFunds — final req: ' + JSON.stringify({
2252
2273
  recipient: viem_1.zeroAddress,
2253
2274
  token: tokenAddress,
2254
2275
  amount: (_6 = (_5 = execute.funds) === null || _5 === void 0 ? void 0 : _5.amount) === null || _6 === void 0 ? void 0 : _6.toString(),
@@ -2294,8 +2315,8 @@ class Orchestrator {
2294
2315
  /**
2295
2316
  * Transforms a TxResponse to the new UniversalTxResponse format
2296
2317
  */
2297
- transformToUniversalTxResponse(tx) {
2298
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
2318
+ transformToUniversalTxResponse(tx_2) {
2319
+ return tslib_1.__awaiter(this, arguments, void 0, function* (tx, eventBuffer = []) {
2299
2320
  const chain = this.universalSigner.account.chain;
2300
2321
  const { vm, chainId } = chain_1.CHAIN_INFO[chain];
2301
2322
  let from;
@@ -2324,6 +2345,32 @@ class Orchestrator {
2324
2345
  to = universalPayload.to;
2325
2346
  value = BigInt(universalPayload.value);
2326
2347
  data = universalPayload.data;
2348
+ // Extract 'to' from single-element multicall
2349
+ if (data && data.length >= 10) {
2350
+ const multicallSelector = (0, viem_1.keccak256)((0, viem_1.toBytes)('UEA_MULTICALL')).slice(0, 10);
2351
+ if (data.slice(0, 10) === multicallSelector) {
2352
+ try {
2353
+ const innerData = ('0x' + data.slice(10));
2354
+ const [decodedCalls] = (0, viem_1.decodeAbiParameters)([
2355
+ {
2356
+ type: 'tuple[]',
2357
+ components: [
2358
+ { name: 'to', type: 'address' },
2359
+ { name: 'value', type: 'uint256' },
2360
+ { name: 'data', type: 'bytes' },
2361
+ ],
2362
+ },
2363
+ ], innerData);
2364
+ // If single call, use its 'to' address
2365
+ if (decodedCalls.length === 1) {
2366
+ to = (0, viem_1.getAddress)(decodedCalls[0].to);
2367
+ }
2368
+ }
2369
+ catch (_a) {
2370
+ // Keep original 'to' if decoding fails
2371
+ }
2372
+ }
2373
+ }
2327
2374
  rawTransactionData = {
2328
2375
  from: (0, viem_1.getAddress)(tx.from),
2329
2376
  to: (0, viem_1.getAddress)(tx.to),
@@ -2370,7 +2417,7 @@ class Orchestrator {
2370
2417
  yParity: tx.yParity,
2371
2418
  };
2372
2419
  }
2373
- catch (_a) {
2420
+ catch (_b) {
2374
2421
  // Fallback signature if parsing fails
2375
2422
  signature = {
2376
2423
  r: '0x0000000000000000000000000000000000000000000000000000000000000000',
@@ -2401,6 +2448,8 @@ class Orchestrator {
2401
2448
  typeVerbose = 'eip4844';
2402
2449
  }
2403
2450
  }
2451
+ // Storage for registered progress callback (used by progressHook method)
2452
+ let registeredProgressHook;
2404
2453
  const universalTxResponse = {
2405
2454
  // 1. Identity
2406
2455
  hash: tx.hash,
@@ -2425,9 +2474,25 @@ class Orchestrator {
2425
2474
  accessList: Array.isArray(tx.accessList) ? [...tx.accessList] : [],
2426
2475
  // 6. Utilities
2427
2476
  wait: () => tslib_1.__awaiter(this, void 0, void 0, function* () {
2477
+ // Use trackTransaction with registered hook if available
2478
+ if (registeredProgressHook) {
2479
+ return this.trackTransaction(tx.hash, {
2480
+ waitForCompletion: true,
2481
+ progress: registeredProgressHook,
2482
+ });
2483
+ }
2428
2484
  const receipt = yield tx.wait();
2429
2485
  return this.transformToUniversalTxReceipt(receipt, universalTxResponse);
2430
2486
  }),
2487
+ progressHook: (callback) => {
2488
+ registeredProgressHook = callback;
2489
+ // Immediately replay buffered events from execution
2490
+ if (eventBuffer.length > 0) {
2491
+ for (const event of eventBuffer) {
2492
+ callback(event);
2493
+ }
2494
+ }
2495
+ },
2431
2496
  // 7. Metadata
2432
2497
  type,
2433
2498
  typeVerbose,
@@ -2473,10 +2538,9 @@ class Orchestrator {
2473
2538
  const hookEntry = progress_hook_1.default[hookId];
2474
2539
  const hookPayload = hookEntry(...args);
2475
2540
  this.printLog(hookPayload.message);
2476
- if (!this.progressHook)
2477
- return;
2478
- // invoke the user-provided callback
2479
- this.progressHook(hookPayload);
2541
+ if (this.progressHook) {
2542
+ this.progressHook(hookPayload);
2543
+ }
2480
2544
  }
2481
2545
  // Derive the SVM gateway log index from a Solana transaction's log messages
2482
2546
  getSvmGatewayLogIndexFromTx(txResp) {
@@ -2545,14 +2609,14 @@ class Orchestrator {
2545
2609
  });
2546
2610
  }
2547
2611
  const gatewayLogs = (receipt.logs || []).filter((l) => (l.address || '').toLowerCase() === gatewayAddress.toLowerCase());
2548
- console.log('[DEBUG] queryUniversalTxStatus — receipt logs count:', (_a = receipt.logs) === null || _a === void 0 ? void 0 : _a.length, 'gateway logs count:', gatewayLogs.length, 'evmGatewayMethod:', evmGatewayMethod);
2549
- console.log('[DEBUG] queryUniversalTxStatus — gatewayLogs:', JSON.stringify(gatewayLogs.map((l) => { var _a; return ({ address: l.address, logIndex: l.logIndex, topics: (_a = l.topics) === null || _a === void 0 ? void 0 : _a[0] }); }), null, 2));
2612
+ this.printLog(`queryUniversalTxStatus — receipt logs count: ${(_a = receipt.logs) === null || _a === void 0 ? void 0 : _a.length}, gateway logs count: ${gatewayLogs.length}, evmGatewayMethod: ${evmGatewayMethod}`);
2613
+ this.printLog('queryUniversalTxStatus — gatewayLogs: ' + JSON.stringify(gatewayLogs.map((l) => { var _a; return ({ address: l.address, logIndex: l.logIndex, topics: (_a = l.topics) === null || _a === void 0 ? void 0 : _a[0] }); }), null, 2));
2550
2614
  // TEMP: use last gateway log instead of hardcoded 0/1 index
2551
2615
  const logIndexToUse = gatewayLogs.length - 1;
2552
2616
  const firstLog = (gatewayLogs[logIndexToUse] ||
2553
2617
  (receipt.logs || []).at(-1));
2554
2618
  const logIndexVal = (_b = firstLog === null || firstLog === void 0 ? void 0 : firstLog.logIndex) !== null && _b !== void 0 ? _b : 0;
2555
- console.log('[DEBUG] queryUniversalTxStatus — logIndexToUse:', logIndexToUse, 'firstLog.logIndex:', firstLog === null || firstLog === void 0 ? void 0 : firstLog.logIndex, 'logIndexVal:', logIndexVal);
2619
+ this.printLog(`queryUniversalTxStatus — logIndexToUse: ${logIndexToUse}, firstLog.logIndex: ${firstLog === null || firstLog === void 0 ? void 0 : firstLog.logIndex}, logIndexVal: ${logIndexVal}`);
2556
2620
  logIndexStr =
2557
2621
  typeof logIndexVal === 'bigint'
2558
2622
  ? logIndexVal.toString()
@@ -2586,7 +2650,7 @@ class Orchestrator {
2586
2650
  // ID = sha256("${sourceChain}:${txHash}:${logIndex}") as hex string (no 0x)
2587
2651
  const idInput = `${sourceChain}:${txHashHex}:${logIndexStr}`;
2588
2652
  const idHex = (0, viem_1.sha256)((0, viem_1.stringToBytes)(idInput)).slice(2);
2589
- console.log('[DEBUG] Query ID extraction:', JSON.stringify({
2653
+ this.printLog('Query ID extraction: ' + JSON.stringify({
2590
2654
  sourceChain,
2591
2655
  txHashHex,
2592
2656
  logIndexStr,
@@ -2600,7 +2664,7 @@ class Orchestrator {
2600
2664
  const MAX_ATTEMPTS = 20;
2601
2665
  let universalTxObj;
2602
2666
  for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
2603
- console.log(`[Sync] Attempt ${attempt + 1}/${MAX_ATTEMPTS} | Query ID: ${idHex}`);
2667
+ this.printLog(`[Sync] Attempt ${attempt + 1}/${MAX_ATTEMPTS} | Query ID: ${idHex}`);
2604
2668
  try {
2605
2669
  const universalTxResp = yield this.pushClient.getUniversalTxById(idHex);
2606
2670
  universalTxObj = universalTxResp === null || universalTxResp === void 0 ? void 0 : universalTxResp.universalTx;