@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.
- package/package.json +1 -1
- package/src/lib/constants/abi/universalGatewayV0.evm.d.ts +48 -1
- package/src/lib/constants/abi/universalGatewayV0.evm.js +1061 -29
- package/src/lib/constants/abi/universalGatewayV0.evm.js.map +1 -1
- package/src/lib/constants/abi/universalGatewayV0.json +1223 -206
- package/src/lib/constants/chain.js +10 -2
- package/src/lib/constants/chain.js.map +1 -1
- package/src/lib/constants/enums.d.ts +1 -0
- package/src/lib/constants/enums.js +1 -0
- package/src/lib/constants/enums.js.map +1 -1
- package/src/lib/constants/tokens.js +29 -0
- package/src/lib/constants/tokens.js.map +1 -1
- package/src/lib/generated/v1/tx.d.ts +1 -2
- package/src/lib/generated/v1/tx.js +2 -1
- package/src/lib/generated/v1/tx.js.map +1 -1
- package/src/lib/orchestrator/orchestrator.d.ts +2 -1
- package/src/lib/orchestrator/orchestrator.js +236 -50
- package/src/lib/orchestrator/orchestrator.js.map +1 -1
- package/src/lib/universal/account/account.js +1 -0
- package/src/lib/universal/account/account.js.map +1 -1
- package/src/lib/vm-client/svm-client.js +24 -3
- package/src/lib/vm-client/svm-client.js.map +1 -1
|
@@ -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
|
-
|
|
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(
|
|
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,
|
|
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
|
|
862
|
+
* @returns Transaction hash bytes
|
|
789
863
|
*/
|
|
790
|
-
lockFee(
|
|
791
|
-
|
|
792
|
-
|
|
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
|
-
|
|
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.
|
|
905
|
+
abi: abi_1.UNIVERSAL_GATEWAY_V0,
|
|
810
906
|
address: lockerContract,
|
|
811
|
-
functionName: '
|
|
812
|
-
args: [
|
|
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
|
|
820
|
-
const [nativeTokenUsdPrice, svmClient
|
|
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
|
|
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.
|
|
829
|
-
address:
|
|
830
|
-
functionName: '
|
|
831
|
-
args: [
|
|
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
|
-
|
|
835
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
1571
|
-
|
|
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,
|
|
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
|
-
|
|
1589
|
-
|
|
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 =
|
|
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 (
|
|
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
|
-
|
|
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
|
|
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* () {
|