From 0cd1a9e43a485969fe360a3971a1652525484d40 Mon Sep 17 00:00:00 2001 From: npty <78221556+npty@users.noreply.github.com> Date: Thu, 7 Mar 2024 09:28:36 +0700 Subject: [PATCH] fix: custom rpc provider is not used for tx recovery (#305) * chore: change the rpc endpoint for ethereum-2 * chore: allow passing custom rpc endpoint * chore: fix tests * fix: not utilized given rpc provider * chore: update changelog --------- Co-authored-by: Canh Trinh --- CHANGELOG.md | 3 +- .../AxelarGMPRecoveryAPI.ts | 40 ++++++++++++++----- .../client/EVMClient/index.ts | 2 +- .../constants/chain/testnet.ts | 2 +- .../AxelarGMPRecoveryAPI.spec.ts | 6 +-- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1c7c690..1e2b7bd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [0.15.0] - 2024-FEBRUARY-21 +## [0.15.0] - 2024-MARCH-X - Improved the accuracy of `estimateGasFee` function by incorporating L1 rollup fee for destination L2 chain. +- Fix for `manualRelayToDestinationChain` to respect optional `provider` parameter Breaking Changes: diff --git a/src/libs/TransactionRecoveryApi/AxelarGMPRecoveryAPI.ts b/src/libs/TransactionRecoveryApi/AxelarGMPRecoveryAPI.ts index d32e12d4..238f2184 100644 --- a/src/libs/TransactionRecoveryApi/AxelarGMPRecoveryAPI.ts +++ b/src/libs/TransactionRecoveryApi/AxelarGMPRecoveryAPI.ts @@ -57,6 +57,7 @@ import s3 from "./constants/s3"; import { Coin, OfflineSigner } from "@cosmjs/proto-signing"; import { DeliverTxResponse, SigningStargateClient, StdFee } from "@cosmjs/stargate"; import { COSMOS_GAS_RECEIVER_OPTIONS } from "./constants/cosmosGasReceiverOptions"; +import { JsonRpcProvider } from "@ethersproject/providers"; export const GMPErrorMap: Record = { [GMPStatus.CANNOT_FETCH_STATUS]: ApproveGatewayError.FETCHING_STATUS_FAILED, [GMPStatus.DEST_EXECUTED]: ApproveGatewayError.ALREADY_EXECUTED, @@ -175,14 +176,15 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi { return getCommandId(destChainId, txHash, eventIndex, this.environment, rpcInfo); } - public async doesTxMeetConfirmHt(chain: string, txHash: string) { - const confirmations = await this.getSigner(chain, { useWindowEthereum: false }) + public async doesTxMeetConfirmHt(chain: string, txHash: string, provider?: JsonRpcProvider) { + const confirmations = await this.getSigner(chain, { useWindowEthereum: false, provider }) .provider.getTransactionReceipt(txHash) .then(async (receipt?: TransactionReceipt) => { if (!receipt) { const gmpTx = await this.fetchGMPTransaction(txHash); const currentBlock = await this.getSigner(chain, { useWindowEthereum: false, + provider, }).provider.getBlockNumber(); return currentBlock - gmpTx.call.blockNumber; } @@ -216,7 +218,8 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi { srcChainId: string, destChainId: string, srcTxHash: string, - srcTxEventIndex: number | undefined + srcTxEventIndex: number | undefined, + evmWalletDetails?: EvmWalletDetails ): Promise<{ commandId: string; eventResponse: EventResponse; @@ -226,7 +229,7 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi { }> { const eventIndex = srcTxEventIndex ?? - (await this.getEventIndex(srcChainId, srcTxHash) + (await this.getEventIndex(srcChainId, srcTxHash, evmWalletDetails) .then((index) => index as number) .catch(() => -1)); @@ -292,7 +295,11 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi { ], }; } else { - const isConfirmFinalized = await this.doesTxMeetConfirmHt(srcChain, txHash); + const isConfirmFinalized = await this.doesTxMeetConfirmHt( + srcChain, + txHash, + evmWalletDetails.provider + ); if (!isConfirmFinalized) { const minConfirmLevel = await this.axelarQueryApi.getConfirmationHeight(srcChain); return { @@ -315,7 +322,13 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi { }; } - const updatedEvent = await this.getEvmEvent(srcChain, destChain, txHash, txEventIndex); + const updatedEvent = await this.getEvmEvent( + srcChain, + destChain, + txHash, + txEventIndex, + evmWalletDetails + ); if (this.isEVMEventCompleted(updatedEvent?.eventResponse)) { return { @@ -460,7 +473,7 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi { if (routeDir === RouteDir.COSMOS_TO_EVM) { return this.recoverCosmosToEvmTx(txHash, _evmWalletDetails, messageId); } else if (routeDir === RouteDir.EVM_TO_COSMOS) { - return this.recoverEvmToCosmosTx(srcChain, txHash, eventIndex); + return this.recoverEvmToCosmosTx(srcChain, txHash, eventIndex, _evmWalletDetails); } else { return this.recoverEvmToEvmTx( srcChain, @@ -486,10 +499,15 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi { private async recoverEvmToCosmosTx( srcChain: string, txHash: string, - txEventIndex?: number | null + txEventIndex?: number | null, + evmWalletDetails?: EvmWalletDetails ) { // Check if the tx is confirmed on the source chain - const isConfirmed = await this.doesTxMeetConfirmHt(srcChain, txHash); + const isConfirmed = await this.doesTxMeetConfirmHt( + srcChain, + txHash, + evmWalletDetails?.provider + ); if (!isConfirmed) { const minConfirmLevel = await this.axelarQueryApi.getConfirmationHeight(srcChain); return { @@ -790,8 +808,8 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi { ); } - public async getEventIndex(chain: string, txHash: string) { - const signer = this.getSigner(chain, { useWindowEthereum: false }); + public async getEventIndex(chain: string, txHash: string, evmWalletDetails?: EvmWalletDetails) { + const signer = this.getSigner(chain, evmWalletDetails || { useWindowEthereum: false }); const receipt = await signer.provider.getTransactionReceipt(txHash).catch(() => undefined); if (!receipt) { diff --git a/src/libs/TransactionRecoveryApi/client/EVMClient/index.ts b/src/libs/TransactionRecoveryApi/client/EVMClient/index.ts index e6b24c19..10277883 100644 --- a/src/libs/TransactionRecoveryApi/client/EVMClient/index.ts +++ b/src/libs/TransactionRecoveryApi/client/EVMClient/index.ts @@ -15,7 +15,7 @@ export default class EVMClient { this.provider = useWindowEthereum && typeof window !== "undefined" && window?.ethereum ? new ethers.providers.Web3Provider(window.ethereum, networkOptions) - : new ethers.providers.JsonRpcProvider(rpcUrl, networkOptions); + : provider || new ethers.providers.JsonRpcProvider(rpcUrl, networkOptions); } this.signer = privateKey ? new ethers.Wallet(privateKey).connect(this.provider) diff --git a/src/libs/TransactionRecoveryApi/constants/chain/testnet.ts b/src/libs/TransactionRecoveryApi/constants/chain/testnet.ts index 3ec3e20b..09dc6075 100644 --- a/src/libs/TransactionRecoveryApi/constants/chain/testnet.ts +++ b/src/libs/TransactionRecoveryApi/constants/chain/testnet.ts @@ -6,7 +6,7 @@ export const rpcMap: Record = { [EvmChain.POLYGON]: "https://rpc-mumbai.maticvigil.com", [EvmChain.MOONBEAM]: "https://rpc.api.moonbase.moonbeam.network", [EvmChain.AVALANCHE]: "https://api.avax-test.network/ext/bc/C/rpc", - "ethereum-2": "https://eth-goerli.api.onfinality.io/public", + "ethereum-2": "https://ethereum-goerli-rpc.publicnode.com", [EvmChain.AURORA]: "https://testnet.aurora.dev", [EvmChain.BINANCE]: "https://data-seed-prebsc-1-s1.binance.org:8545", [EvmChain.BNBCHAIN]: "https://data-seed-prebsc-1-s1.binance.org:8545", diff --git a/src/libs/test/TransactionRecoveryAPI/AxelarGMPRecoveryAPI.spec.ts b/src/libs/test/TransactionRecoveryAPI/AxelarGMPRecoveryAPI.spec.ts index 881f71e1..63e752ca 100644 --- a/src/libs/test/TransactionRecoveryAPI/AxelarGMPRecoveryAPI.spec.ts +++ b/src/libs/test/TransactionRecoveryAPI/AxelarGMPRecoveryAPI.spec.ts @@ -98,7 +98,7 @@ describe("AxelarGMPRecoveryAPI", () => { undefined ); expect(mockConfirmGatewayTx).toHaveBeenCalledWith(txHash, EvmChain.AVALANCHE); - expect(mockDoesTxMeetConfirmHt).toHaveBeenCalledWith(EvmChain.AVALANCHE, txHash); + expect(mockDoesTxMeetConfirmHt).toHaveBeenCalledWith(EvmChain.AVALANCHE, txHash, undefined); expect(response).toBeDefined(); expect(response.infoLogs.length).toBeGreaterThan(0); expect(response.eventResponse).toBeDefined(); @@ -165,7 +165,7 @@ describe("AxelarGMPRecoveryAPI", () => { ); expect(mockConfirmGatewayTx).toBeCalledTimes(0); - expect(mockDoesTxMeetConfirmHt).toHaveBeenCalledWith(EvmChain.AVALANCHE, txHash); + expect(mockDoesTxMeetConfirmHt).toHaveBeenCalledWith(EvmChain.AVALANCHE, txHash, undefined); expect(response.success).toBeFalsy(); expect(response.eventResponse).toBeDefined(); expect(response.commandId).toBe("commandId"); @@ -198,7 +198,7 @@ describe("AxelarGMPRecoveryAPI", () => { ); expect(mockConfirmGatewayTx).toHaveBeenCalledWith(txHash, EvmChain.AVALANCHE); - expect(mockDoesTxMeetConfirmHt).toHaveBeenCalledWith(EvmChain.AVALANCHE, txHash); + expect(mockDoesTxMeetConfirmHt).toHaveBeenCalledWith(EvmChain.AVALANCHE, txHash, undefined); expect(response.success).toBeFalsy(); expect(response.eventResponse).toBeDefined(); expect(response.commandId).toBe("commandId");