@pushchain/core 2.0.21 → 2.1.1-alpha-v0

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.
@@ -82,8 +82,9 @@ class Orchestrator {
82
82
  if (!(chain === enums_1.CHAIN.ETHEREUM_SEPOLIA ||
83
83
  chain === enums_1.CHAIN.ARBITRUM_SEPOLIA ||
84
84
  chain === enums_1.CHAIN.BASE_SEPOLIA ||
85
+ chain === enums_1.CHAIN.BNB_TESTNET ||
85
86
  chain === enums_1.CHAIN.SOLANA_DEVNET)) {
86
- throw new Error('Funds bridging is only supported on Ethereum Sepolia, Arbitrum Sepolia, Base Sepolia, and Solana Devnet for now');
87
+ throw new Error('Funds bridging is only supported on Ethereum Sepolia, Arbitrum Sepolia, Base Sepolia, BNB Testnet, and Solana Devnet for now');
87
88
  }
88
89
  // Progress: Origin chain detected
89
90
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_01, chain);
@@ -438,7 +439,7 @@ class Orchestrator {
438
439
  bridgeAmount,
439
440
  universalPayload,
440
441
  revertCFG,
441
- eip712SignatureHex,
442
+ '0x',
442
443
  ],
443
444
  signer: this.universalSigner,
444
445
  value: nativeAmount,
@@ -698,7 +699,7 @@ class Orchestrator {
698
699
  to: payloadTo,
699
700
  value: execute.value,
700
701
  data: payloadData,
701
- gasLimit: execute.gasLimit || BigInt(1e7),
702
+ gasLimit: execute.gasLimit || BigInt(5e7),
702
703
  maxFeePerGas: execute.maxFeePerGas || BigInt(1e10),
703
704
  maxPriorityFeePerGas: execute.maxPriorityFeePerGas || BigInt(0),
704
705
  nonce,
@@ -734,28 +735,101 @@ class Orchestrator {
734
735
  }
735
736
  else {
736
737
  /**
737
- * Fee Locking
738
+ * Fee Locking - For all chains, EVM and Solana
738
739
  */
739
740
  const fundDifference = requiredFunds - funds;
740
741
  const fixedPushAmount = push_chain_1.PushChain.utils.helpers.parseUnits('0.001', 18); // Minimum lock 0.001 Push tokens
741
742
  const lockAmount = funds < requiredFunds ? fundDifference : fixedPushAmount;
742
743
  const lockAmountInUSD = this.pushClient.pushToUSDC(lockAmount);
743
744
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_05_01, lockAmount);
744
- const feeLockTxHashBytes = yield this.lockFee(lockAmountInUSD, executionHash);
745
+ const feeLockTxHashBytes = yield this.lockFee(lockAmountInUSD, universalPayload);
745
746
  feeLockTxHash = (0, viem_1.bytesToHex)(feeLockTxHashBytes);
746
747
  verificationData = (0, viem_1.bytesToHex)(feeLockTxHashBytes);
747
- /**
748
- * Waiting for Confirmations
749
- */
750
748
  const { vm } = chain_1.CHAIN_INFO[chain];
751
749
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_05_02, vm === enums_1.VM.SVM
752
750
  ? anchor_1.utils.bytes.bs58.encode(feeLockTxHashBytes)
753
751
  : feeLockTxHash, chain_1.CHAIN_INFO[chain].confirmations);
752
+ // Waiting for blocks confirmations
754
753
  yield this.waitForLockerFeeConfirmation(feeLockTxHashBytes);
755
754
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_05_03);
755
+ // Query nodes via gRPC for Push Chain transaction
756
+ const { defaultRPC, lockerContract } = chain_1.CHAIN_INFO[chain];
757
+ yield this.queryUniversalTxStatusFromGatewayTx(new evm_client_1.EvmClient({ rpcUrls: this.rpcUrls[chain] || defaultRPC }), lockerContract, feeLockTxHash, 'sendTxWithGas');
758
+ /**
759
+ * Return response directly (skip sendUniversalTx for sendTxWithGas flow)
760
+ * Note: queryTx may be undefined since validators don't recognize new UniversalTx event yet
761
+ */
762
+ this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06);
763
+ // Transform to UniversalTxResponse (follow sendFunds pattern)
764
+ if (vm === enums_1.VM.EVM) {
765
+ // Get EVM transaction for full response
766
+ const evmClient = new evm_client_1.EvmClient({
767
+ rpcUrls: this.rpcUrls[chain] || chain_1.CHAIN_INFO[chain].defaultRPC,
768
+ });
769
+ const tx = yield evmClient.getTransaction(feeLockTxHash);
770
+ const response = yield this.transformToUniversalTxResponse(tx);
771
+ this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_01, [response]);
772
+ return response;
773
+ }
774
+ else {
775
+ // SVM: build minimal response (follow sendFunds SVM pattern)
776
+ const chainId = chain_1.CHAIN_INFO[chain].chainId;
777
+ const origin = `${chain_1.VM_NAMESPACE[vm]}:${chainId}:${this.universalSigner.account.address}`;
778
+ const response = {
779
+ hash: anchor_1.utils.bytes.bs58.encode(feeLockTxHashBytes),
780
+ origin,
781
+ blockNumber: BigInt(0),
782
+ blockHash: '',
783
+ transactionIndex: 0,
784
+ chainId,
785
+ from: this.universalSigner.account.address,
786
+ to: '0x0000000000000000000000000000000000000000',
787
+ nonce: 0,
788
+ data: '0x',
789
+ value: BigInt(0),
790
+ gasLimit: BigInt(0),
791
+ gasPrice: undefined,
792
+ maxFeePerGas: undefined,
793
+ maxPriorityFeePerGas: undefined,
794
+ accessList: [],
795
+ wait: () => tslib_1.__awaiter(this, void 0, void 0, function* () {
796
+ return ({
797
+ hash: anchor_1.utils.bytes.bs58.encode(feeLockTxHashBytes),
798
+ blockNumber: BigInt(0),
799
+ blockHash: '',
800
+ transactionIndex: 0,
801
+ from: this.universalSigner.account.address,
802
+ to: '0x0000000000000000000000000000000000000000',
803
+ contractAddress: null,
804
+ gasPrice: BigInt(0),
805
+ gasUsed: BigInt(0),
806
+ cumulativeGasUsed: BigInt(0),
807
+ logs: [],
808
+ logsBloom: '0x',
809
+ status: 1,
810
+ raw: {
811
+ from: this.universalSigner.account.address,
812
+ to: '0x0000000000000000000000000000000000000000',
813
+ },
814
+ });
815
+ }),
816
+ type: '99',
817
+ typeVerbose: 'universal',
818
+ signature: { r: '0x0', s: '0x0', v: 0 },
819
+ raw: {
820
+ from: this.universalSigner.account.address,
821
+ to: '0x0000000000000000000000000000000000000000',
822
+ nonce: 0,
823
+ data: '0x',
824
+ value: BigInt(0),
825
+ },
826
+ };
827
+ this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_01, [response]);
828
+ return response;
829
+ }
756
830
  }
757
831
  /**
758
- * Broadcasting Tx to PC
832
+ * Non-fee-locking path: Broadcasting Tx to PC via sendUniversalTx
759
833
  */
760
834
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06);
761
835
  const transactions = yield this.sendUniversalTx(isUEADeployed, feeLockTxHash, universalPayload, verificationData);
@@ -785,11 +859,11 @@ class Orchestrator {
785
859
  *
786
860
  * @param amount - Fee amount in USDC (8 Decimals)
787
861
  * @param executionHash - Optional execution payload hash (default: zeroHash)
788
- * @returns Transaction hash of the locking transaction
862
+ * @returns Transaction hash bytes
789
863
  */
790
- lockFee(amount_1) {
791
- return tslib_1.__awaiter(this, arguments, void 0, function* (amount, // USD with 8 decimals
792
- executionHash = viem_1.zeroHash) {
864
+ lockFee(amount, // USD with 8 decimals
865
+ universalPayload) {
866
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
793
867
  const chain = this.universalSigner.account.chain;
794
868
  const { lockerContract, vm, defaultRPC } = chain_1.CHAIN_INFO[chain];
795
869
  if (!lockerContract) {
@@ -804,35 +878,88 @@ class Orchestrator {
804
878
  Promise.resolve(new evm_client_1.EvmClient({ rpcUrls })),
805
879
  ]);
806
880
  const nativeDecimals = 18; // ETH, MATIC, etc.
807
- const nativeAmount = (amount * BigInt(Math.pow(10, nativeDecimals))) / nativeTokenUsdPrice;
881
+ // Ensure deposit respects gateway USD caps (min $1, max $10) and avoid rounding below min
882
+ const oneUsd = push_chain_1.PushChain.utils.helpers.parseUnits('1', 8);
883
+ const tenUsd = push_chain_1.PushChain.utils.helpers.parseUnits('10', 8);
884
+ let depositUsd = amount < oneUsd ? oneUsd : amount;
885
+ if (depositUsd > tenUsd)
886
+ depositUsd = tenUsd;
887
+ // Ceil division to avoid falling below on-chain min due to rounding, then add 1 wei safety
888
+ let nativeAmount = (depositUsd * BigInt(Math.pow(10, nativeDecimals)) +
889
+ (nativeTokenUsdPrice - BigInt(1))) /
890
+ nativeTokenUsdPrice;
891
+ nativeAmount = nativeAmount + BigInt(1);
892
+ // Deposit-only funding via UniversalGatewayV0 (no payload execution)
893
+ const revertCFG = {
894
+ fundRecipient: this.universalSigner.account.address,
895
+ revertMsg: '0x',
896
+ };
897
+ // Sign the universal payload
898
+ const ueaAddress = this.computeUEAOffchain();
899
+ const ueaVersion = yield this.fetchUEAVersion();
900
+ const eip712Signature = yield this.signUniversalPayload(universalPayload, ueaAddress, ueaVersion);
901
+ const eip712SignatureHex = typeof eip712Signature === 'string'
902
+ ? eip712Signature
903
+ : (0, viem_1.bytesToHex)(eip712Signature);
808
904
  const txHash = yield evmClient.writeContract({
809
- abi: abi_1.FEE_LOCKER_EVM,
905
+ abi: abi_1.UNIVERSAL_GATEWAY_V0,
810
906
  address: lockerContract,
811
- functionName: 'addFunds',
812
- args: [executionHash],
907
+ functionName: 'sendTxWithGas',
908
+ args: [universalPayload, revertCFG, '0x'],
813
909
  signer: this.universalSigner,
814
910
  value: nativeAmount,
815
911
  });
816
912
  return (0, viem_1.hexToBytes)(txHash);
817
913
  }
818
914
  case enums_1.VM.SVM: {
819
- // Run price fetching, client creation, and PDA computation in parallel
820
- const [nativeTokenUsdPrice, svmClient, [lockerPda]] = yield Promise.all([
915
+ // Run price fetching and client creation in parallel
916
+ const [nativeTokenUsdPrice, svmClient] = yield Promise.all([
821
917
  new price_fetch_1.PriceFetch(this.rpcUrls).getPrice(chain), // 8 decimals
822
918
  Promise.resolve(new svm_client_1.SvmClient({ rpcUrls })),
823
- Promise.resolve(anchor.web3.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('locker')], new web3_js_1.PublicKey(lockerContract))),
824
919
  ]);
920
+ // Ensure deposit respects gateway USD caps (min $1, max $10) and avoid rounding below min
825
921
  const nativeDecimals = 9; // SOL lamports
826
- const nativeAmount = (amount * BigInt(Math.pow(10, nativeDecimals))) / nativeTokenUsdPrice;
922
+ const oneUsd = push_chain_1.PushChain.utils.helpers.parseUnits('1', 8);
923
+ const tenUsd = push_chain_1.PushChain.utils.helpers.parseUnits('10', 8);
924
+ let depositUsd = amount < oneUsd ? oneUsd : amount;
925
+ if (depositUsd > tenUsd)
926
+ depositUsd = tenUsd;
927
+ // Ceil division to avoid falling below on-chain min due to rounding, then add 1 lamport safety
928
+ let nativeAmount = (depositUsd * BigInt(Math.pow(10, nativeDecimals)) +
929
+ (nativeTokenUsdPrice - BigInt(1))) /
930
+ nativeTokenUsdPrice;
931
+ nativeAmount = nativeAmount + BigInt(1);
932
+ // Program & PDAs
933
+ const programId = new web3_js_1.PublicKey(abi_1.SVM_GATEWAY_IDL.address);
934
+ const [configPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('config')], programId);
935
+ const [vaultPda] = web3_js_1.PublicKey.findProgramAddressSync([(0, viem_1.stringToBytes)('vault')], programId);
936
+ const userPk = new web3_js_1.PublicKey(this.universalSigner.account.address);
937
+ const revertSvm = {
938
+ fundRecipient: userPk,
939
+ revertMsg: Buffer.from([]),
940
+ };
941
+ // const ueaAddressSvm = this.computeUEAOffchain();
942
+ // const ueaVersion = await this.fetchUEAVersion();
943
+ // const svmSignature = await this.signUniversalPayload(
944
+ // universalPayload,
945
+ // ueaAddressSvm,
946
+ // ueaVersion
947
+ // );
827
948
  const txHash = yield svmClient.writeContract({
828
- abi: abi_1.FEE_LOCKER_SVM,
829
- address: lockerContract,
830
- functionName: 'addFunds',
831
- args: [nativeAmount, (0, viem_1.toBytes)(executionHash)],
949
+ abi: abi_1.SVM_GATEWAY_IDL,
950
+ address: programId.toBase58(),
951
+ functionName: 'sendTxWithGas',
952
+ args: [
953
+ universalPayload,
954
+ revertSvm,
955
+ new anchor.BN(nativeAmount.toString()),
956
+ '0x',
957
+ ],
832
958
  signer: this.universalSigner,
833
959
  accounts: {
834
- locker: lockerPda,
835
- user: new web3_js_1.PublicKey(this.universalSigner.account.address),
960
+ config: configPda,
961
+ vault: vaultPda,
962
+ user: userPk,
836
963
  priceUpdate: new web3_js_1.PublicKey('7UVimffxr9ow1uXYxsr4LHAcV58mLzhmwaeKvJ1pjLiE'),
837
964
  systemProgram: web3_js_1.SystemProgram.programId,
838
965
  },
@@ -1171,20 +1298,12 @@ class Orchestrator {
1171
1298
  switch (vm) {
1172
1299
  case enums_1.VM.EVM: {
1173
1300
  const evmClient = new evm_client_1.EvmClient({ rpcUrls });
1174
- yield evmClient.waitForConfirmations({
1175
- txHash: (0, viem_1.bytesToHex)(txHashBytes),
1176
- confirmations,
1177
- timeoutMs: timeout,
1178
- });
1301
+ yield this.waitForEvmConfirmationsWithCountdown(evmClient, (0, viem_1.bytesToHex)(txHashBytes), confirmations, timeout);
1179
1302
  return;
1180
1303
  }
1181
1304
  case enums_1.VM.SVM: {
1182
1305
  const svmClient = new svm_client_1.SvmClient({ rpcUrls });
1183
- yield svmClient.waitForConfirmations({
1184
- txSignature: anchor_1.utils.bytes.bs58.encode(txHashBytes),
1185
- confirmations,
1186
- timeoutMs: timeout,
1187
- });
1306
+ yield this.waitForSvmConfirmationsWithCountdown(svmClient, anchor_1.utils.bytes.bs58.encode(txHashBytes), confirmations, timeout);
1188
1307
  return;
1189
1308
  }
1190
1309
  default:
@@ -1257,8 +1376,9 @@ class Orchestrator {
1257
1376
  if (chain !== enums_1.CHAIN.ETHEREUM_SEPOLIA &&
1258
1377
  chain !== enums_1.CHAIN.ARBITRUM_SEPOLIA &&
1259
1378
  chain !== enums_1.CHAIN.BASE_SEPOLIA &&
1379
+ chain !== enums_1.CHAIN.BNB_TESTNET &&
1260
1380
  chain !== enums_1.CHAIN.SOLANA_DEVNET) {
1261
- throw new Error('Funds + payload bridging is only supported on Ethereum Sepolia, Arbitrum Sepolia, Base Sepolia, and Solana Devnet for now');
1381
+ throw new Error('Funds + payload bridging is only supported on Ethereum Sepolia, Arbitrum Sepolia, Base Sepolia, BNB Testnet, and Solana Devnet for now');
1262
1382
  }
1263
1383
  // For EVM (Sepolia), return client and gateway address. For SVM (Solana Devnet), only chain is needed here.
1264
1384
  if (chain_1.CHAIN_INFO[chain].vm === enums_1.VM.EVM) {
@@ -1318,7 +1438,7 @@ class Orchestrator {
1318
1438
  maxPriorityFeePerGas: execute.maxPriorityFeePerGas || BigInt(0),
1319
1439
  nonce,
1320
1440
  deadline: execute.deadline || BigInt(9999999999),
1321
- vType: tx_1.VerificationType.signedVerification,
1441
+ vType: tx_1.VerificationType.universalTxVerification,
1322
1442
  };
1323
1443
  return { payload: universalPayload, gasAmount };
1324
1444
  });
@@ -1566,15 +1686,16 @@ class Orchestrator {
1566
1686
  continue;
1567
1687
  const discriminatorHex = (0, viem_1.bytesToHex)(decoded.slice(0, 8)).slice(2);
1568
1688
  // Skip add_funds discriminator; return the first other Program data event
1569
- if (discriminatorHex === '7f1f6cffbb134644')
1570
- continue;
1571
- return i;
1689
+ // if (discriminatorHex === '7f1f6cffbb134644') continue;
1690
+ if (discriminatorHex === '6c9ad829b5ea1d7c')
1691
+ return i;
1692
+ // return i;
1572
1693
  }
1573
1694
  // Fallback to first log
1574
1695
  return 0;
1575
1696
  }
1576
1697
  // Query Push Chain for UniversalTx status given an origin gateway tx (EVM or SVM)
1577
- queryUniversalTxStatusFromGatewayTx(evmClient, gatewayAddress, txHash, fromBranch) {
1698
+ queryUniversalTxStatusFromGatewayTx(evmClient, gatewayAddress, txHash, evmGatewayMethod) {
1578
1699
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
1579
1700
  var _a, _b;
1580
1701
  try {
@@ -1585,11 +1706,22 @@ class Orchestrator {
1585
1706
  if (vm === enums_1.VM.EVM) {
1586
1707
  if (!evmClient || !gatewayAddress)
1587
1708
  throw new Error('Missing EVM context');
1588
- const receipt = yield evmClient.publicClient.getTransactionReceipt({
1589
- hash: txHash,
1590
- });
1709
+ let receipt;
1710
+ try {
1711
+ receipt = yield evmClient.publicClient.getTransactionReceipt({
1712
+ hash: txHash,
1713
+ });
1714
+ }
1715
+ catch (_c) {
1716
+ // Receipt might not be indexed yet on this RPC; wait briefly for it
1717
+ receipt = yield evmClient.publicClient.waitForTransactionReceipt({
1718
+ hash: txHash,
1719
+ confirmations: 0,
1720
+ timeout: chain_1.CHAIN_INFO[chain].timeout,
1721
+ });
1722
+ }
1591
1723
  const gatewayLogs = (receipt.logs || []).filter((l) => (l.address || '').toLowerCase() === gatewayAddress.toLowerCase());
1592
- const logIndexToUse = fromBranch === 'sendTxWithFunds' ? 1 : 0;
1724
+ const logIndexToUse = evmGatewayMethod === 'sendTxWithFunds' ? 1 : 0;
1593
1725
  const firstLog = (gatewayLogs[logIndexToUse] ||
1594
1726
  ((_a = receipt.logs) === null || _a === void 0 ? void 0 : _a[logIndexToUse]));
1595
1727
  const logIndexVal = (_b = firstLog === null || firstLog === void 0 ? void 0 : firstLog.logIndex) !== null && _b !== void 0 ? _b : 0;
@@ -1657,7 +1789,7 @@ class Orchestrator {
1657
1789
  // );
1658
1790
  return universalTxObj;
1659
1791
  }
1660
- catch (_c) {
1792
+ catch (_d) {
1661
1793
  // Best-effort; do not fail flow if PC query is unavailable
1662
1794
  this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_06);
1663
1795
  return undefined;
@@ -1675,15 +1807,31 @@ class Orchestrator {
1675
1807
  hash: txHash,
1676
1808
  });
1677
1809
  const targetBlock = receipt.blockNumber + BigInt(confirmations);
1810
+ // Track last emitted confirmation to avoid duplicates
1811
+ let lastEmitted = 0;
1678
1812
  // Poll blocks and emit remaining confirmations
1679
1813
  // eslint-disable-next-line no-constant-condition
1680
1814
  while (true) {
1681
1815
  const currentBlock = yield evmClient.publicClient.getBlockNumber();
1682
- if (currentBlock >= targetBlock)
1816
+ // If already confirmed, emit progress for final confirmation
1817
+ if (currentBlock >= targetBlock) {
1818
+ // Only emit if we haven't already shown this confirmation
1819
+ if (lastEmitted < confirmations) {
1820
+ this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_04, confirmations, confirmations);
1821
+ }
1683
1822
  return;
1823
+ }
1684
1824
  const remaining = Number(targetBlock - currentBlock);
1685
1825
  const completed = Math.max(1, confirmations - remaining + 1);
1686
- this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_04, completed, confirmations);
1826
+ // Only emit if this is a new confirmation count
1827
+ if (completed > lastEmitted) {
1828
+ this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_04, completed, confirmations);
1829
+ lastEmitted = completed;
1830
+ // If we've reached required confirmations, we're done
1831
+ if (completed >= confirmations) {
1832
+ return;
1833
+ }
1834
+ }
1687
1835
  if (Date.now() - start > timeoutMs) {
1688
1836
  throw new Error(`Timeout: transaction ${txHash} not confirmed with ${confirmations} confirmations within ${timeoutMs} ms`);
1689
1837
  }
@@ -1691,6 +1839,44 @@ class Orchestrator {
1691
1839
  }
1692
1840
  });
1693
1841
  }
1842
+ // Emit countdown updates while waiting for SVM confirmations
1843
+ waitForSvmConfirmationsWithCountdown(svmClient, txSignature, confirmations, timeoutMs) {
1844
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
1845
+ var _a;
1846
+ // initial emit
1847
+ this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_03, confirmations);
1848
+ const start = Date.now();
1849
+ // Poll for confirmations and emit progress
1850
+ let lastConfirmed = 0;
1851
+ // eslint-disable-next-line no-constant-condition
1852
+ while (true) {
1853
+ const connection = svmClient.connections[svmClient.currentConnectionIndex];
1854
+ const { value } = yield connection.getSignatureStatuses([txSignature]);
1855
+ const status = value[0];
1856
+ if (status) {
1857
+ const currentConfirms = (_a = status.confirmations) !== null && _a !== void 0 ? _a : 0;
1858
+ const hasEnoughConfirmations = currentConfirms >= confirmations;
1859
+ const isSuccessfullyFinalized = status.err === null && status.confirmationStatus !== null;
1860
+ // Emit progress if we have more confirmations than before OR if finalized
1861
+ if (currentConfirms > lastConfirmed ||
1862
+ (isSuccessfullyFinalized && lastConfirmed === 0)) {
1863
+ const confirmCount = isSuccessfullyFinalized && currentConfirms === 0
1864
+ ? confirmations
1865
+ : currentConfirms;
1866
+ this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_04, Math.max(1, confirmCount), confirmations);
1867
+ lastConfirmed = currentConfirms;
1868
+ }
1869
+ if (hasEnoughConfirmations || isSuccessfullyFinalized) {
1870
+ return;
1871
+ }
1872
+ }
1873
+ if (Date.now() - start > timeoutMs) {
1874
+ throw new Error(`Timeout: transaction ${txSignature} not confirmed with ${confirmations} confirmations within ${timeoutMs} ms`);
1875
+ }
1876
+ yield new Promise((r) => setTimeout(r, 500));
1877
+ }
1878
+ });
1879
+ }
1694
1880
  // Fetch and cache UEA version from the contract on Push Chain
1695
1881
  fetchUEAVersion() {
1696
1882
  return tslib_1.__awaiter(this, void 0, void 0, function* () {