diff --git a/.github/workflows/ci-test.yaml b/.github/workflows/ci-test.yaml index 5b4b58d..6ee4b9f 100644 --- a/.github/workflows/ci-test.yaml +++ b/.github/workflows/ci-test.yaml @@ -64,7 +64,10 @@ jobs: version: v1.5.1 - name: Run ZKsync OS (L1-L2) - uses: dutterbutter/zksync-server-action@e0401b155b1fa0f4f3629d569db3ae7094383729 # main + uses: dutterbutter/zksync-server-action@54ebddef27a0bd7ef30246f94add1c9091ae23be # v0.2.0 + with: + version: v0.15.1 + protocol_version: v30.2 - name: Compile test contracts working-directory: tests/contracts @@ -190,7 +193,10 @@ jobs: version: v1.5.1 - name: Run ZKsync OS (L1-L2) - uses: dutterbutter/zksync-server-action@e0401b155b1fa0f4f3629d569db3ae7094383729 # main + uses: dutterbutter/zksync-server-action@54ebddef27a0bd7ef30246f94add1c9091ae23be # v0.2.0 + with: + version: v0.15.1 + protocol_version: v30.2 - name: Setup Bun uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2 diff --git a/src/adapters/ethers/e2e/helpers.ts b/src/adapters/ethers/e2e/helpers.ts index cc65523..1ccac9d 100644 --- a/src/adapters/ethers/e2e/helpers.ts +++ b/src/adapters/ethers/e2e/helpers.ts @@ -20,7 +20,8 @@ import { expect } from 'bun:test'; // TODO: make this shared across resources const L1_RPC_URL = 'http://127.0.0.1:8545'; const L2_RPC_URL = 'http://127.0.0.1:3050'; -const PRIVATE_KEY = '0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6'; +const PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'; +const L2_RICH_PRIVATE_KEY = '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); export const DEPLOYER_PRIVATE_KEY = @@ -37,6 +38,18 @@ export function createTestClientAndSdk() { return { client, sdk }; } +// Ensure the test signer has enough ETH on L2 for withdrawal tests. +export async function ensureL2Balance(client: any, minBalance: bigint): Promise { + const me = (await client.signer.getAddress()) as Address; + const current = (await client.l2.getBalance(me)) as bigint; + if (current >= minBalance) return; + + const topUp = minBalance - current + 1_000_000_000_000_000n; // +0.001 ETH buffer for gas + const funder = new Wallet(L2_RICH_PRIVATE_KEY, client.l2); + const tx = await funder.sendTransaction({ to: me, value: topUp }); + await tx.wait(); +} + /** Create deployer wallets bound to current providers (same PK on both chains). */ export function makeDeployers(l1: JsonRpcProvider, l2: JsonRpcProvider) { const baseL1 = new Wallet(DEPLOYER_PRIVATE_KEY, l1); diff --git a/src/adapters/ethers/e2e/withdrawals.eth.e2e.ts b/src/adapters/ethers/e2e/withdrawals.eth.e2e.ts index cf12d3c..4ceed54 100644 --- a/src/adapters/ethers/e2e/withdrawals.eth.e2e.ts +++ b/src/adapters/ethers/e2e/withdrawals.eth.e2e.ts @@ -10,6 +10,7 @@ import type { Address, Hex } from '../../../core/types/primitives.ts'; import { ETH_ADDRESS } from '../../../core/constants.ts'; import { createTestClientAndSdk, + ensureL2Balance, waitUntilReadyToFinalize, verifyWithdrawalBalancesAfterFinalize, waitForL2InclusionWithdraw, @@ -29,6 +30,7 @@ describe('withdrawals.e2e (ethers): ETH withdrawal', () => { beforeAll(async () => { ({ client, sdk } = createTestClientAndSdk()); me = (await client.signer.getAddress()) as Address; + await ensureL2Balance(client, WITHDRAW_WEI); // Ensure L2 has funds to withdraw const l2Bal = await client.l2.getBalance(me); diff --git a/src/adapters/viem/e2e/helpers.ts b/src/adapters/viem/e2e/helpers.ts index 7296ee1..91af60e 100644 --- a/src/adapters/viem/e2e/helpers.ts +++ b/src/adapters/viem/e2e/helpers.ts @@ -27,7 +27,8 @@ import { createViemSdk } from '../sdk.ts'; // TODO: refactor with shared mocks const L1_RPC = 'http://127.0.0.1:8545'; const L2_RPC = 'http://127.0.0.1:3050'; -const PRIVATE_KEY = '0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6'; +const PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'; +const L2_RICH_PRIVATE_KEY = '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; const DEPLOYER_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'; const L1_CHAIN: Chain | undefined = undefined; const L2_CHAIN: Chain | undefined = undefined; @@ -66,6 +67,27 @@ export function createTestClientAndSdk() { return { client, sdk }; } +// Ensure the test signer has enough ETH on L2 for withdrawal tests. +export async function ensureL2Balance(client: any, minBalance: bigint): Promise { + const me = client.account.address as Address; + const current = (await client.l2.getBalance({ address: me })) as bigint; + if (current >= minBalance) return; + + const topUp = minBalance - current + 1_000_000_000_000_000n; // +0.001 ETH buffer for gas + const funderAccount = privateKeyToAccount(L2_RICH_PRIVATE_KEY); + const l2Funder = createWalletClient({ + account: funderAccount, + transport: http(L2_RPC), + ...(L2_CHAIN ? { chain: L2_CHAIN } : {}), + }); + const hash = await l2Funder.sendTransaction({ + account: funderAccount, + to: me, + value: topUp, + }); + await client.l2.waitForTransactionReceipt({ hash }); +} + export function makeDeployers() { const deployerAccount = privateKeyToAccount(DEPLOYER_PRIVATE_KEY); diff --git a/src/adapters/viem/e2e/withdrawals.eth.e2e.ts b/src/adapters/viem/e2e/withdrawals.eth.e2e.ts index 8fd3052..3979ea4 100644 --- a/src/adapters/viem/e2e/withdrawals.eth.e2e.ts +++ b/src/adapters/viem/e2e/withdrawals.eth.e2e.ts @@ -10,6 +10,7 @@ import type { Address, Hex } from '../../../core/types/primitives.ts'; import { ETH_ADDRESS } from '../../../core/constants.ts'; import { createTestClientAndSdk, + ensureL2Balance, waitForL2InclusionWithdraw, waitUntilReadyToFinalize, verifyWithdrawalBalancesAfterFinalize, @@ -28,6 +29,7 @@ describe('withdrawals.e2e (viem): ETH withdrawal', () => { beforeAll(async () => { ({ client, sdk } = createTestClientAndSdk()); me = client.account.address as Address; + await ensureL2Balance(client, WITHDRAW_WEI); // Ensure L2 has funds to withdraw const l2Bal = await client.l2.getBalance({ address: me });