diff --git a/src/utils/getL1ToL2MessagesAndDepositMessages.ts b/src/utils/getL1ToL2MessagesAndDepositMessages.ts index f061faf..b304b4c 100644 --- a/src/utils/getL1ToL2MessagesAndDepositMessages.ts +++ b/src/utils/getL1ToL2MessagesAndDepositMessages.ts @@ -2,6 +2,7 @@ import { EthDepositMessageWithNetwork, L1ToL2MessagesAndDepositMessages, } from '@/types'; +import { ChainId, rpcURLs } from '@/utils/network'; import { getL2Network, L1Network, L1TransactionReceipt } from '@arbitrum/sdk'; import { StaticJsonRpcProvider } from '@ethersproject/providers'; @@ -24,22 +25,7 @@ export const getL1ToL2MessagesAndDepositMessages = async ( return; } - let l2RpcURL; - switch (l2ChainID) { - case 42161: - l2RpcURL = 'https://arb1.arbitrum.io/rpc'; - break; - case 42170: - l2RpcURL = 'https://nova.arbitrum.io/rpc'; - break; - case 421613: - l2RpcURL = 'https://goerli-rollup.arbitrum.io/rpc'; - break; - default: - throw new Error( - 'Unknown L2 chain id. This chain is not supported by dashboard', - ); - } + const l2RpcURL = rpcURLs[l2ChainID as ChainId]; const l2Provider = new StaticJsonRpcProvider(l2RpcURL); const isClassic = await l1TxnReceipt.isClassic(l2Provider); diff --git a/src/utils/network.ts b/src/utils/network.ts index edf9c35..9872488 100644 --- a/src/utils/network.ts +++ b/src/utils/network.ts @@ -1,7 +1,8 @@ import { addDefaultLocalNetwork } from '@arbitrum/sdk'; import { loadEnvironmentVariableWithFallback } from './loadEnvironmentVariableWithFallback'; -export const INFURA_KEY = process.env.NEXT_PUBLIC_INFURA_KEY; +const INFURA_KEY = process.env.NEXT_PUBLIC_INFURA_KEY; + if (typeof INFURA_KEY === 'undefined') { throw new Error('process.env.NEXT_PUBLIC_INFURA_KEY not provided'); } diff --git a/synpress.config.ts b/synpress.config.ts index bb21062..b6ac461 100644 --- a/synpress.config.ts +++ b/synpress.config.ts @@ -4,6 +4,7 @@ import { safeAddDefaultLocalNetwork } from './src/utils/network'; const ethRpcUrl = process.env.NEXT_PUBLIC_LOCAL_ETHEREUM_RPC_URL; const arbRpcUrl = process.env.NEXT_PUBLIC_LOCAL_ARBITRUM_RPC_URL; +const privateKey = process.env.PRIVATE_KEY; if (!ethRpcUrl) { throw new Error('process.env.NEXT_PUBLIC_LOCAL_ETHEREUM_RPC_URL is not set'); @@ -13,6 +14,10 @@ if (!arbRpcUrl) { throw new Error('process.env.NEXT_PUBLIC_LOCAL_ARBITRUM_RPC_URL is not set'); } +if (!privateKey) { + throw new Error('process.env.PRIVATE_KEY is not set'); +} + export default defineConfig({ userAgent: 'synpress', retries: 2, @@ -36,9 +41,11 @@ export default defineConfig({ safeAddDefaultLocalNetwork(); // Set Cypress variables + config.env = { ...process.env }; config.env.ETH_RPC_URL = ethRpcUrl; config.env.ARB_RPC_URL = arbRpcUrl; config.env.INFURA_KEY = process.env.NEXT_PUBLIC_INFURA_KEY; + config.env.PRIVATE_KEY = privateKey; synpressPlugins(on, config); return config; diff --git a/tests/e2e/specs/redeem-retryables.cy.ts b/tests/e2e/specs/redeem-retryables.cy.ts new file mode 100644 index 0000000..bb3b42b --- /dev/null +++ b/tests/e2e/specs/redeem-retryables.cy.ts @@ -0,0 +1,92 @@ +import { addDefaultLocalNetwork } from '@arbitrum/sdk'; +import { L1ToL2MessageCreator } from '@arbitrum/sdk/dist/lib/message/L1ToL2MessageCreator'; +import { StaticJsonRpcProvider } from '@ethersproject/providers'; +import { BigNumber, Wallet } from 'ethers'; + +const createRetryable = async () => { + try { + addDefaultLocalNetwork(); + } catch (e) {} + const ethProvider = new StaticJsonRpcProvider(Cypress.env('ETH_RPC_URL')); + const arbProvider = new StaticJsonRpcProvider(Cypress.env('ARB_RPC_URL')); + const privateKey = Cypress.env('PRIVATE_KEY'); + const userWallet = new Wallet(privateKey); + + const l1Signer = userWallet.connect(ethProvider); + const signerAddress = await l1Signer.getAddress(); + + // Instantiate the object + const l1ToL2MessageCreator = new L1ToL2MessageCreator(l1Signer); + + // And create the retryable ticket + const l1SubmissionTx = await l1ToL2MessageCreator.createRetryableTicket( + { + from: signerAddress, + l2CallValue: BigNumber.from(0), + to: signerAddress, + data: '0x', + retryableData: { + data: '0x', + from: signerAddress, + l2CallValue: BigNumber.from(0), + to: signerAddress, + deposit: BigNumber.from(0), + maxFeePerGas: BigNumber.from(10), + gasLimit: BigNumber.from(10), + maxSubmissionCost: BigNumber.from(10), + callValueRefundAddress: signerAddress, + excessFeeRefundAddress: signerAddress, + }, + }, + arbProvider, + ); + const l1SubmissionTxReceipt = await l1SubmissionTx.wait(); + return l1SubmissionTxReceipt; +}; + +function goToTransactionPage(transactionHash: string) { + cy.findByText('Arbitrum Cross-chain Message Dashboard').click(); + cy.findByPlaceholderText('Paste your transaction hash') + .should('exist') + .type(transactionHash); + return cy.findByDisplayValue('Submit').click(); +} + +describe('Retryable', () => { + beforeEach(() => { + cy.visit('/'); + }); + + it("Display retryable information before it's claimed", async () => { + const retryable = await createRetryable(); + goToTransactionPage(retryable.transactionHash); + cy.findByDisplayValue('Submit').click(); + + cy.findByText('Cross chain messages found').should('exist'); + cy.findByText( + 'L1 to L2 message initiated from L1, but not yet created — check again in a few minutes!', + ).should('exist'); + cy.findByText('Redeem').should('not.exist'); + cy.findByText('Connect').should('not.exist'); + }); + + it('Display expired retryable', () => { + goToTransactionPage( + '0xd5114540abaf1442b5bf2b1f31a4e49d333bb585bb39e87d99b2667b9e25c1f3', + ); + cy.findByText('Cross chain messages found').should('exist'); + cy.findByText('Retryable ticket expired.').should('exist'); + cy.findByText('Redeem').should('not.exist'); + cy.findByText('Connect').should('not.exist'); + }); + + it('Display successful retryable information', () => { + goToTransactionPage( + '0xe07401ee4ba9131f6efe367eaace256a59daaf162a53e2e105caa810228487c8', + ); + cy.findByText('Cross chain messages found').should('exist'); + cy.findByText('Success! 🎉 Your retryable was executed.').should('exist'); + cy.findByText('Redeem').should('not.exist'); + cy.findByText('Connect').should('not.exist'); + }); +});