From bb0aadc94214831822df077b5a63908b86aa1070 Mon Sep 17 00:00:00 2001 From: yivlad Date: Thu, 12 Dec 2024 12:42:58 +0100 Subject: [PATCH 01/13] Add common-testnets package Co-authored-by: Oskar --- .github/workflows/ci.yml | 14 +- packages/common-testnets/.mocharc.json | 7 + packages/common-testnets/package.json | 61 ++++ packages/common-testnets/src/TestnetClient.ts | 15 + .../src/TestnetFactory.test.ts | 104 +++++++ .../common-testnets/src/TestnetFactory.ts | 19 ++ .../common-testnets/src/anvil/AnvilClient.ts | 61 ++++ .../src/anvil/AnvilTestnetFactory.ts | 71 +++++ packages/common-testnets/src/anvil/index.ts | 2 + packages/common-testnets/src/index.ts | 4 + .../src/tenderly/TenderlyClient.ts | 54 ++++ .../src/tenderly/TenderlyTestnetFactory.ts | 87 ++++++ .../common-testnets/src/tenderly/index.ts | 1 + packages/common-testnets/tsconfig.cjs.json | 11 + packages/common-testnets/tsconfig.esm.json | 7 + packages/common-testnets/tsconfig.json | 6 + pnpm-lock.yaml | 284 ++++++++++++++++-- 17 files changed, 779 insertions(+), 29 deletions(-) create mode 100644 packages/common-testnets/.mocharc.json create mode 100644 packages/common-testnets/package.json create mode 100644 packages/common-testnets/src/TestnetClient.ts create mode 100644 packages/common-testnets/src/TestnetFactory.test.ts create mode 100644 packages/common-testnets/src/TestnetFactory.ts create mode 100644 packages/common-testnets/src/anvil/AnvilClient.ts create mode 100644 packages/common-testnets/src/anvil/AnvilTestnetFactory.ts create mode 100644 packages/common-testnets/src/anvil/index.ts create mode 100644 packages/common-testnets/src/index.ts create mode 100644 packages/common-testnets/src/tenderly/TenderlyClient.ts create mode 100644 packages/common-testnets/src/tenderly/TenderlyTestnetFactory.ts create mode 100644 packages/common-testnets/src/tenderly/index.ts create mode 100644 packages/common-testnets/tsconfig.cjs.json create mode 100644 packages/common-testnets/tsconfig.esm.json create mode 100644 packages/common-testnets/tsconfig.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 10d087faf..bd921e8a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,8 +64,18 @@ jobs: cache: "pnpm" - run: pnpm install + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1.2.0 + with: + version: nightly-58bf161bc9dd6e74de8cb61e3ae23f701feb5512 + - run: pnpm check - run: pnpm verify # does linting, type checking, and tests in parallel + env: + TENDERLY_API_KEY: "${{ secrets.TENDERLY_API_KEY }}" + TENDERLY_ACCOUNT: phoenixlabs + TENDERLY_PROJECT: spark-app-e2e-tests + TEST_E2E_ALCHEMY_API_KEY: "${{ secrets.ALCHEMY_API_KEY }}" storybook-visual-regression: strategy: @@ -132,9 +142,7 @@ jobs: env: TENDERLY_API_KEY: "${{ secrets.TENDERLY_API_KEY }}" TENDERLY_ACCOUNT: phoenixlabs - TENDERLY_PROJECT: sparklend - TENDERLY_BASE_DEVNET_CONTAINER_ID: "${{ secrets.TENDERLY_BASE_DEVNET_CONTAINER_ID }}" - VITE_DEV_BASE_DEVNET_RPC_URL: "${{ secrets.VITE_DEV_BASE_DEVNET_RPC_URL }}" + TENDERLY_PROJECT: spark-app-e2e-tests PLAYWRIGHT_TRACE: 1 - name: Upload report to GitHub Actions Artifacts if: failure() diff --git a/packages/common-testnets/.mocharc.json b/packages/common-testnets/.mocharc.json new file mode 100644 index 000000000..e6ab882fe --- /dev/null +++ b/packages/common-testnets/.mocharc.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://json.schemastore.org/mocharc", + "extension": ["ts"], + "require": "dotenv/config", + "node-option": ["import=tsx", "conditions=@marsfoundation/local-spark-monorepo"], + "timeout": 60000 +} diff --git a/packages/common-testnets/package.json b/packages/common-testnets/package.json new file mode 100644 index 000000000..d7fadb111 --- /dev/null +++ b/packages/common-testnets/package.json @@ -0,0 +1,61 @@ +{ + "name": "@marsfoundation/common-testnets", + "version": "0.1.1", + "engines": { + "node": ">=18.0.0" + }, + "type": "module", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/types/index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/marsfoundation/spark-app.git", + "directory": "packages/common-testnets" + }, + "exports": { + ".": { + "import": { + "@marsfoundation/local-spark-monorepo": "./src/index.ts", + "types": "./dist/types/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "@marsfoundation/local-spark-monorepo": "./src/index.ts", + "types": "./dist/types/index.d.ts", + "default": "./dist/cjs/index.js" + } + } + }, + "files": [ + "dist" + ], + "scripts": { + "lint": "eslint src", + "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run test --silent\" \"pnpm run typecheck\"", + "fix": "cd ../../ && pnpm run check:fix && cd - && pnpm run verify", + "test": "mocha src/**/*.test.ts", + "typecheck": "tsc --noEmit", + "build:cjs": "tsc -p tsconfig.cjs.json", + "build:esm": "tsc -p tsconfig.esm.json", + "build": "pnpm run build:cjs && pnpm run build:esm", + "clean": "rm -rf dist", + "prepublishOnly": "pnpm run clean && pnpm run build" + }, + "dependencies": { + "@marsfoundation/common-nodejs": "workspace:^", + "@marsfoundation/common-universal": "workspace:^", + "@viem/anvil": "^0.0.10", + "get-port": "^7.1.0", + "viem": "2.21.18", + "viem-deal": "^2.0.0", + "zod": "^3.23.8" + }, + "devDependencies": { + "@types/mocha": "^10.0.10", + "@types/uuid": "^10.0.0", + "earl": "^1.3.0", + "mocha": "^10.8.2", + "uuid": "^11.0.2" + } +} diff --git a/packages/common-testnets/src/TestnetClient.ts b/packages/common-testnets/src/TestnetClient.ts new file mode 100644 index 000000000..30bb565fb --- /dev/null +++ b/packages/common-testnets/src/TestnetClient.ts @@ -0,0 +1,15 @@ +import { raise } from '@marsfoundation/common-universal' +import { Address, PublicActions, WalletClient } from 'viem' + +export interface TestnetClient extends WalletClient, PublicActions { + setErc20Balance(tkn: Address, usr: Address, amount: bigint): Promise + setBalance(usr: Address, amount: bigint): Promise + snapshot(): Promise + revert(snapshotId: string): Promise // @note: returns new snapshot id (may be the same as the input) + mineBlocks(blocks: bigint): Promise + setNextBlockTimestamp(timestamp: bigint): Promise +} + +export function getUrlFromClient(client: TestnetClient): string { + return client.transport.type === 'http' ? client.transport.url : raise('Only http transport is supported') +} diff --git a/packages/common-testnets/src/TestnetFactory.test.ts b/packages/common-testnets/src/TestnetFactory.test.ts new file mode 100644 index 000000000..7137d24c9 --- /dev/null +++ b/packages/common-testnets/src/TestnetFactory.test.ts @@ -0,0 +1,104 @@ +import { getEnv } from '@marsfoundation/common-nodejs/env' +import { expect } from 'earl' +import { describe, it, before, after } from 'mocha' +import { TestnetClient } from './TestnetClient' +import { TestnetFactory } from './TestnetFactory' +import { AnvilTestnetFactory } from './anvil' +import { TenderlyTestnetFactory } from './tenderly' + +const env = getEnv() + +describe('TestnetFactory', () => { + const factories: TestnetFactory[] = [ + new TenderlyTestnetFactory({ + apiKey: env.string('TENDERLY_API_KEY'), + account: env.string('TENDERLY_ACCOUNT'), + project: env.string('TENDERLY_PROJECT'), + }), + new AnvilTestnetFactory({ alchemyApiKey: env.string('TEST_E2E_ALCHEMY_API_KEY') }), + ] + + for (const factory of factories) { + describe(factory.constructor.name, () => { + const expectedChainId = 2137 + + describe('With block specified', () => { + let testnetClient: TestnetClient + let cleanup: () => Promise + const blockNumber = 21378357n + const expectedTimestamp = 1733909123n + 2n + + before(async () => { + ({ client: testnetClient, cleanup } = await factory.create({ + id: 'test', + originChainId: 1, + forkChainId: expectedChainId, + blockNumber, + })) + }) + + after(async () => { + await cleanup() + }) + + it('creates a testnet with desired block', async () => { + const currentBlockNumber = await testnetClient.getBlockNumber() + + expect(currentBlockNumber).toEqual(blockNumber + 2n) + }) + + it('creates a testnet with desired timestamp', async () => { + const currentBlockNumber = await testnetClient.getBlockNumber() + const currentBlock = await testnetClient.getBlock({ blockNumber: currentBlockNumber }) + + expect(currentBlock.timestamp).toEqual(expectedTimestamp) + }) + + it('creates a testnet with desired chainId', async () => { + const chainId = await testnetClient.getChainId() + + expect(chainId).toEqual(expectedChainId) + }) + + it('contains tx from a top of the forked blockchain', async () => { + const receipt = await testnetClient.getTransactionReceipt({ + hash: '0x3c66f14cafc6b806538d97953be5bf4775be4f851448e937a612007c9e207c37', + }) + + expect(receipt).toEqual( + expect.subset({ + status: 'success', + }), + ) + }) + + it('does not contain tx from future block', async () => { + await expect(testnetClient.getTransactionReceipt({ + hash: '0x7057abf025862e54cb1c33b4f4d4e6f8793383098abb84e58a85d1f10d14b765', + })).toBeRejectedWith('The Transaction may not be processed on a block yet.') + }) + }) + + describe('Without block specified', () => { + let testnetClient: TestnetClient + let cleanup: () => Promise + + before(async () => { + ({ client: testnetClient, cleanup } = await factory.create({ + id: 'test', + originChainId: 1, + forkChainId: expectedChainId, + })) + }) + after(async () => { + await cleanup() + }) + + it('can fetch block number', async () => { + const currentBlockNumber = await testnetClient.getBlockNumber() + expect(currentBlockNumber).toBeGreaterThan(21385842n) + }) + }) + }) + } +}) diff --git a/packages/common-testnets/src/TestnetFactory.ts b/packages/common-testnets/src/TestnetFactory.ts new file mode 100644 index 000000000..73fe218ab --- /dev/null +++ b/packages/common-testnets/src/TestnetFactory.ts @@ -0,0 +1,19 @@ +import { TestnetClient } from './TestnetClient' + +export interface TestnetCreateResult { + client: TestnetClient + cleanup: () => Promise +} + +export interface TestnetFactory { + create(network: CreateNetworkArgs): Promise + createClientFromUrl(rpcUrl: string): TestnetClient +} + +export interface CreateNetworkArgs { + id: string + displayName?: string + originChainId: number + forkChainId: number + blockNumber?: bigint +} diff --git a/packages/common-testnets/src/anvil/AnvilClient.ts b/packages/common-testnets/src/anvil/AnvilClient.ts new file mode 100644 index 000000000..e0fbd7572 --- /dev/null +++ b/packages/common-testnets/src/anvil/AnvilClient.ts @@ -0,0 +1,61 @@ +import { assert } from '@marsfoundation/common-universal' +import { http, Address, createTestClient, numberToHex, publicActions, walletActions } from 'viem' +import { dealActions } from 'viem-deal' +import { mainnet } from 'viem/chains' +import { TestnetClient } from '../TestnetClient' + +export function getAnvilClient(rpc: string): TestnetClient { + return createTestClient({ + chain: mainnet, + mode: 'anvil', + transport: http(rpc), + cacheTime: 0, // do not cache block numbers + }) + .extend(publicActions) + .extend(dealActions) + .extend((c) => ({ + async setErc20Balance(tkn: Address, usr: Address, amt: bigint): Promise { + return await c.deal({ + erc20: tkn.toLowerCase() as any, + account: usr.toLowerCase() as any, + amount: amt, + }) + }, + async setBalance(usr: Address, amt: bigint): Promise { + return c.request({ + method: 'anvil_setBalance', + params: [usr.toString(), `0x${amt.toString(16)}`], + } as any) + }, + async snapshot(): Promise { + return c.request({ + method: 'evm_snapshot', + params: [], + } as any) + }, + async revert(snapshotId: string) { + const result = await c.request({ + method: 'evm_revert', + params: [snapshotId], + } as any) + + assert(result === true, 'revert failed') + + // anvil snapshot are "burned" after revert so we need to create a new one + return await c.snapshot() + }, + async mineBlocks(blocks: bigint) { + await c.request({ + method: 'anvil_mine', + params: [numberToHex(blocks), '0x1'], + }) + }, + async setNextBlockTimestamp(timestamp: bigint) { + await c.request({ + method: 'evm_setNextBlockTimestamp', + params: [numberToHex(timestamp)], + }) + }, + })) + .extend(walletActions) +} diff --git a/packages/common-testnets/src/anvil/AnvilTestnetFactory.ts b/packages/common-testnets/src/anvil/AnvilTestnetFactory.ts new file mode 100644 index 000000000..8264f7c89 --- /dev/null +++ b/packages/common-testnets/src/anvil/AnvilTestnetFactory.ts @@ -0,0 +1,71 @@ +import { assert } from '@marsfoundation/common-universal' +import { TestnetClient } from '../TestnetClient' +import { CreateNetworkArgs, TestnetCreateResult, TestnetFactory } from '../TestnetFactory' + +import { createAnvil } from '@viem/anvil' +import { getAnvilClient } from './AnvilClient' +import { createPublicClient, http } from 'viem' +import getPort from 'get-port' + +export class AnvilTestnetFactory implements TestnetFactory { + constructor(private readonly opts: { alchemyApiKey: string }) {} + + async create(args: CreateNetworkArgs): Promise { + const { originChainId, forkChainId, blockNumber } = args + + const forkUrl = originChainIdToForkUrl(originChainId, this.opts.alchemyApiKey) + // if forkChainId is specified, anvil requires blockNumber to be specified as well + const forkBlockNumber = await (async () => { + if (blockNumber) { + return blockNumber + } + + const publicClient = createPublicClient({ transport: http(forkUrl)}) + return publicClient.getBlockNumber() + })() + const port = await getPort({ port: 8545 }) + + const anvil = createAnvil({ + forkUrl, + autoImpersonate: true, + forkBlockNumber, + forkChainId, + port, + gasPrice: 0, + blockBaseFeePerGas: 0, + }) + + await anvil.start() + + const url = `http://${anvil.host}:${anvil.port}` + + assert(anvil.status === 'listening', `Anvil failed to start: ${anvil.status}`) + + const client = getAnvilClient(url) + + await client.mineBlocks(2n) + + return { + client, + cleanup: async () => { + await anvil.stop() + }, + } + } + + createClientFromUrl(rpcUrl: string): TestnetClient { + return getAnvilClient(rpcUrl) + } +} + +function originChainIdToForkUrl(originChainId: number, alchemyApiKey: string): string { + switch (originChainId) { + case 1: + return `https://eth-mainnet.g.alchemy.com/v2/${alchemyApiKey}` + case 8453: + return `https://base-mainnet.g.alchemy.com/v2/${alchemyApiKey}` + default: + throw new Error(`Unsupported origin chain id: ${originChainId}`) + } +} + diff --git a/packages/common-testnets/src/anvil/index.ts b/packages/common-testnets/src/anvil/index.ts new file mode 100644 index 000000000..0147555c3 --- /dev/null +++ b/packages/common-testnets/src/anvil/index.ts @@ -0,0 +1,2 @@ +export * from './AnvilClient' +export * from './AnvilTestnetFactory' diff --git a/packages/common-testnets/src/index.ts b/packages/common-testnets/src/index.ts new file mode 100644 index 000000000..d20d81b08 --- /dev/null +++ b/packages/common-testnets/src/index.ts @@ -0,0 +1,4 @@ +export * from './TestnetClient' +export * from './TestnetFactory' +export * from './tenderly' +export * from './anvil' diff --git a/packages/common-testnets/src/tenderly/TenderlyClient.ts b/packages/common-testnets/src/tenderly/TenderlyClient.ts new file mode 100644 index 000000000..c6a9b501b --- /dev/null +++ b/packages/common-testnets/src/tenderly/TenderlyClient.ts @@ -0,0 +1,54 @@ +import { http, Address, createTestClient, numberToHex, publicActions, walletActions } from 'viem' +import { mainnet } from 'viem/chains' +import { TestnetClient } from '../TestnetClient' + +export function getTenderlyClient(rpc: string): TestnetClient { + return createTestClient({ + chain: mainnet, + mode: 'anvil', + transport: http(rpc), + cacheTime: 0, // do not cache block numbers + }) + .extend((c) => ({ + async setErc20Balance(tkn: Address, usr: Address, amt: bigint): Promise { + return c.request({ + method: 'tenderly_setErc20Balance', + params: [tkn.toString(), usr.toString(), numberToHex(amt)], + } as any) + }, + async setBalance(usr: Address, amt: bigint): Promise { + return c.request({ + method: 'tenderly_setBalance', + params: [usr.toString(), numberToHex(amt)], + } as any) + }, + async snapshot(): Promise { + return c.request({ + method: 'evm_snapshot', + params: [], + } as any) + }, + async revert(snapshotId: string) { + await c.request({ + method: 'evm_revert', + params: [snapshotId], + } as any) + // tenderly doesn't burn the snapshots id so we can reuse it + return snapshotId + }, + async mineBlocks(blocks: bigint) { + await c.request({ + method: 'evm_increaseBlocks', + params: [numberToHex(blocks)], + } as any) + }, + async setNextBlockTimestamp(timestamp: bigint) { + await c.request({ + method: 'tenderly_setNextBlockTimestamp', + params: [numberToHex(timestamp)], + } as any) + }, + })) + .extend(walletActions) + .extend(publicActions) +} diff --git a/packages/common-testnets/src/tenderly/TenderlyTestnetFactory.ts b/packages/common-testnets/src/tenderly/TenderlyTestnetFactory.ts new file mode 100644 index 000000000..f7a8bc60c --- /dev/null +++ b/packages/common-testnets/src/tenderly/TenderlyTestnetFactory.ts @@ -0,0 +1,87 @@ +import { assert, solidFetch } from '@marsfoundation/common-universal' +import { v4 as uuidv4 } from 'uuid' +import { numberToHex } from 'viem' +import { z } from 'zod' +import { TestnetClient } from '../TestnetClient' +import { CreateNetworkArgs, TestnetCreateResult, TestnetFactory } from '../TestnetFactory' +import { getTenderlyClient } from './TenderlyClient' + +export class TenderlyTestnetFactory implements TestnetFactory { + constructor(private readonly opts: { apiKey: string; account: string; project: string }) {} + + async create(args: CreateNetworkArgs): Promise { + const { id, displayName, originChainId, forkChainId, blockNumber } = args + const uniqueId = uuidv4() + + const response = await solidFetch( + `https://api.tenderly.co/api/v1/account/${this.opts.account}/project/${this.opts.project}/vnets`, + { + method: 'post', + headers: { + 'Content-Type': 'application/json', + 'X-Access-Key': this.opts.apiKey, + }, + body: JSON.stringify({ + slug: `${id}-${uniqueId}`, + display_name: displayName, + fork_config: { + network_id: originChainId, + block_number: Number(blockNumber) + 1, + }, + virtual_network_config: { + chain_config: { + chain_id: forkChainId, + }, + }, + sync_state_config: { + enabled: false, + commitment_level: 'latest', + }, + explorer_page_config: { + enabled: false, + verification_visibility: 'bytecode', + }, + }), + }, + ) + + const data = createVnetSchema.parse(await response.json()) + + const adminRpc = data.rpcs.find((rpc: any) => rpc.name === 'Admin RPC') + const publicRpc = data.rpcs.find((rpc: any) => rpc.name === 'Public RPC') + assert(adminRpc && publicRpc, 'Missing admin or public RPC') + + const client = getTenderlyClient(adminRpc.url) + const legacyClient = client.extend((c) => ({ + async legacySetNextBlockTimestamp(timestamp: bigint) { + await c.request({ + method: 'evm_setNextBlockTimestamp', + params: [numberToHex(timestamp)], + } as any) + }, + })) + + const block = await client.getBlock({ blockNumber }) + const nextBlockTimestamp = block.timestamp + 2n // to normalize with anvil we need to lowest common timestamp + + await legacyClient.legacySetNextBlockTimestamp(nextBlockTimestamp) + + return { + client, + cleanup: () => Promise.resolve(), + } + } + + createClientFromUrl(rpcUrl: string): TestnetClient { + return getTenderlyClient(rpcUrl) + } +} + +const createVnetSchema = z.object({ + rpcs: z.array( + z.object({ + name: z.string(), + url: z.string(), + }), + ), +}) diff --git a/packages/common-testnets/src/tenderly/index.ts b/packages/common-testnets/src/tenderly/index.ts new file mode 100644 index 000000000..ae249985a --- /dev/null +++ b/packages/common-testnets/src/tenderly/index.ts @@ -0,0 +1 @@ +export * from './TenderlyTestnetFactory' diff --git a/packages/common-testnets/tsconfig.cjs.json b/packages/common-testnets/tsconfig.cjs.json new file mode 100644 index 000000000..e093f0a9c --- /dev/null +++ b/packages/common-testnets/tsconfig.cjs.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "customConditions": null, + "moduleResolution": "node", + "outDir": "./dist/cjs", + "declaration": true, + "declarationDir": "./dist/types" + } +} diff --git a/packages/common-testnets/tsconfig.esm.json b/packages/common-testnets/tsconfig.esm.json new file mode 100644 index 000000000..0ebcdc1ac --- /dev/null +++ b/packages/common-testnets/tsconfig.esm.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "esnext", + "outDir": "./dist/esm" + } +} diff --git a/packages/common-testnets/tsconfig.json b/packages/common-testnets/tsconfig.json new file mode 100644 index 000000000..51527e361 --- /dev/null +++ b/packages/common-testnets/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "./src" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 28bd5e2df..106534718 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -202,7 +202,7 @@ importers: version: 1.0.6(tailwindcss@3.4.3) viem: specifier: ^2.9.21 - version: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.22.4) + version: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4) wagmi: specifier: ^2.5.20 version: 2.5.20(@react-native-async-storage/async-storage@1.22.0(react-native@0.76.1(@babel/core@7.22.9)(@babel/preset-env@7.24.6(@babel/core@7.22.9))(@types/react@18.2.14)(bufferutil@4.0.8)(react@18.2.0)))(@tanstack/query-core@5.28.8)(@tanstack/react-query@5.28.8(react@18.2.0))(@types/react@18.2.14)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.76.1(@babel/core@7.22.9)(@babel/preset-env@7.24.6(@babel/core@7.22.9))(@types/react@18.2.14)(bufferutil@4.0.8)(react@18.2.0))(react@18.2.0)(rollup@4.27.4)(typescript@5.6.3)(viem@2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4))(zod@3.22.4) @@ -398,6 +398,46 @@ importers: specifier: ^10.8.2 version: 10.8.2 + packages/common-testnets: + dependencies: + '@marsfoundation/common-nodejs': + specifier: workspace:^ + version: link:../common-nodejs + '@marsfoundation/common-universal': + specifier: workspace:^ + version: link:../common-universal + '@viem/anvil': + specifier: ^0.0.10 + version: 0.0.10(bufferutil@4.0.8)(utf-8-validate@6.0.3) + get-port: + specifier: ^7.1.0 + version: 7.1.0 + viem: + specifier: 2.21.18 + version: 2.21.18(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.24.1) + viem-deal: + specifier: ^2.0.0 + version: 2.0.4(viem@2.21.18(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.24.1)) + zod: + specifier: ^3.23.8 + version: 3.24.1 + devDependencies: + '@types/mocha': + specifier: ^10.0.10 + version: 10.0.10 + '@types/uuid': + specifier: ^10.0.0 + version: 10.0.0 + earl: + specifier: ^1.3.0 + version: 1.3.0 + mocha: + specifier: ^10.8.2 + version: 10.8.2 + uuid: + specifier: ^11.0.2 + version: 11.0.3 + packages/common-universal: dependencies: bignumber.js: @@ -411,7 +451,7 @@ importers: version: 6.1.0 viem: specifier: ^2.9.21 - version: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.22.4) + version: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.24.1) devDependencies: '@sinonjs/fake-timers': specifier: ^13.0.5 @@ -2558,6 +2598,9 @@ packages: '@noble/curves@1.3.0': resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} + '@noble/curves@1.4.0': + resolution: {integrity: sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==} + '@noble/hashes@1.3.2': resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} engines: {node: '>= 16'} @@ -2566,6 +2609,14 @@ packages: resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} engines: {node: '>= 16'} + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@noble/hashes@1.5.0': + resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} + engines: {node: ^14.21.3 || >=16} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -3325,18 +3376,27 @@ packages: '@scure/base@1.1.6': resolution: {integrity: sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==} + '@scure/base@1.1.9': + resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} + '@scure/bip32@1.3.2': resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} '@scure/bip32@1.3.3': resolution: {integrity: sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==} + '@scure/bip32@1.4.0': + resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + '@scure/bip39@1.2.1': resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} '@scure/bip39@1.2.2': resolution: {integrity: sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==} + '@scure/bip39@1.4.0': + resolution: {integrity: sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw==} + '@sentry-internal/feedback@7.114.0': resolution: {integrity: sha512-kUiLRUDZuh10QE9JbSVVLgqxFoD9eDPOzT0MmzlPuas8JlTmJuV4FtSANNcqctd5mBuLt2ebNXH0MhRMwyae4A==} engines: {node: '>=12'} @@ -4338,6 +4398,9 @@ packages: peerDependencies: '@vanilla-extract/css': ^1.0.0 + '@viem/anvil@0.0.10': + resolution: {integrity: sha512-9PzYXBRikfSUhhm8Bd0avv07agwcbMJ5FaSu2D2vbE0cxkvXGtolL3fW5nz2yefMqOqVQL4XzfM5nwY81x3ytw==} + '@viem/anvil@0.0.6': resolution: {integrity: sha512-OjKR/+FVwzuygXYFqP8MBal1SXG8bT2gbZwqqB0XuLw81LNBBvmE/Repm6+5kkBh4IUj0PhYdrqOsnayS14Gtg==} @@ -4594,6 +4657,17 @@ packages: zod: optional: true + abitype@1.0.5: + resolution: {integrity: sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + abitype@1.0.6: resolution: {integrity: sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A==} peerDependencies: @@ -6250,6 +6324,10 @@ packages: resolution: {integrity: sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + get-port@7.1.0: + resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==} + engines: {node: '>=16'} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -6818,6 +6896,11 @@ packages: peerDependencies: ws: '*' + isows@1.0.4: + resolution: {integrity: sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ==} + peerDependencies: + ws: '*' + istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -7515,10 +7598,6 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} - npm-run-path@5.1.0: - resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - npm-run-path@5.3.0: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -9331,6 +9410,11 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + viem-deal@2.0.4: + resolution: {integrity: sha512-gd1+pnLissjxYbaJ8u2UtdOOpv0o4W8RsVlSwy5w+SEasi/f5VJvrCVmE8cBrcHpvWYqoaxwj4VfJG45oLPnyQ==} + peerDependencies: + viem: ^2.21.18 + viem@1.21.4: resolution: {integrity: sha512-BNVYdSaUjeS2zKQgPs+49e5JKocfo60Ib2yiXOWBT6LuVxY1I/6fFX3waEtpXvL1Xn4qu+BVitVtMh9lyThyhQ==} peerDependencies: @@ -9339,6 +9423,14 @@ packages: typescript: optional: true + viem@2.21.18: + resolution: {integrity: sha512-CuZpymwBsuK2/YNDJE06EXxpfYs71X4v5ZwiGV5RczLKOwfHa/XuM3+GKbAoKCVeQ/tFt5n8XeHsMnbvEAauTg==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + viem@2.9.21: resolution: {integrity: sha512-8GtxPjPGpiN5cmr19zSX9mb1LX/eON3MPxxAd3QmyUFn69Rp566zlREOqE7zM35y5yX59fXwnz6O3X7e9+C9zg==} peerDependencies: @@ -9453,6 +9545,9 @@ packages: wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + webauthn-p256@0.0.5: + resolution: {integrity: sha512-drMGNWKdaixZNobeORVIqq7k5DsRC9FnG201K2QjeOoQLmtSDaSsVZdkg6n5jUALJKcAG++zBPJXmv6hy0nWFg==} + webextension-polyfill-ts@0.25.0: resolution: {integrity: sha512-ikQhwwHYkpBu00pFaUzIKY26I6L87DeRI+Q6jBT1daZUNuu8dSrg5U9l/ZbqdaQ1M/TTSPKeAa3kolP5liuedw==} deprecated: This project has moved to @types/webextension-polyfill @@ -9625,6 +9720,18 @@ packages: utf-8-validate: optional: true + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + xml-name-validator@4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} @@ -9705,6 +9812,9 @@ packages: zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + zod@3.24.1: + resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==} + zustand@4.4.1: resolution: {integrity: sha512-QCPfstAS4EBiTQzlaGP1gmorkh/UL1Leaj2tdj+zZCZ/9bm0WS7sI2wnfD5lpOszFqWJ1DcPnGoY8RDL61uokw==} engines: {node: '>=12.7.0'} @@ -9949,7 +10059,7 @@ snapshots: '@babel/helper-function-name': 7.24.6 '@babel/helper-member-expression-to-functions': 7.24.6 '@babel/helper-optimise-call-expression': 7.24.6 - '@babel/helper-replace-supers': 7.24.6(@babel/core@7.22.9) + '@babel/helper-replace-supers': 7.24.6(@babel/core@7.24.5) '@babel/helper-skip-transparent-expression-wrappers': 7.24.6 '@babel/helper-split-export-declaration': 7.24.6 semver: 6.3.1 @@ -10102,6 +10212,15 @@ snapshots: '@babel/helper-split-export-declaration': 7.24.6 '@babel/helper-validator-identifier': 7.24.6 + '@babel/helper-module-transforms@7.24.6(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-module-imports': 7.24.6 + '@babel/helper-simple-access': 7.24.6 + '@babel/helper-split-export-declaration': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 + '@babel/helper-module-transforms@7.26.0(@babel/core@7.22.9)': dependencies: '@babel/core': 7.22.9 @@ -10168,6 +10287,13 @@ snapshots: '@babel/helper-member-expression-to-functions': 7.24.6 '@babel/helper-optimise-call-expression': 7.24.6 + '@babel/helper-replace-supers@7.24.6(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-member-expression-to-functions': 7.24.6 + '@babel/helper-optimise-call-expression': 7.24.6 + '@babel/helper-replace-supers@7.25.9(@babel/core@7.22.9)': dependencies: '@babel/core': 7.22.9 @@ -10493,6 +10619,11 @@ snapshots: '@babel/core': 7.22.9 '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -10518,6 +10649,11 @@ snapshots: '@babel/core': 7.22.9 '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -10817,7 +10953,7 @@ snapshots: '@babel/plugin-transform-modules-commonjs@7.24.6(@babel/core@7.24.5)': dependencies: '@babel/core': 7.24.5 - '@babel/helper-module-transforms': 7.24.6(@babel/core@7.22.9) + '@babel/helper-module-transforms': 7.24.6(@babel/core@7.24.5) '@babel/helper-plugin-utils': 7.24.6 '@babel/helper-simple-access': 7.24.6 @@ -10880,7 +11016,7 @@ snapshots: dependencies: '@babel/core': 7.24.5 '@babel/helper-plugin-utils': 7.24.6 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.5) '@babel/plugin-transform-nullish-coalescing-operator@7.25.9(@babel/core@7.22.9)': dependencies: @@ -10942,7 +11078,7 @@ snapshots: '@babel/core': 7.24.5 '@babel/helper-plugin-utils': 7.24.6 '@babel/helper-skip-transparent-expression-wrappers': 7.24.6 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.5) '@babel/plugin-transform-optional-chaining@7.25.9(@babel/core@7.22.9)': dependencies: @@ -12233,10 +12369,18 @@ snapshots: dependencies: '@noble/hashes': 1.3.3 + '@noble/curves@1.4.0': + dependencies: + '@noble/hashes': 1.4.0 + '@noble/hashes@1.3.2': {} '@noble/hashes@1.3.3': {} + '@noble/hashes@1.4.0': {} + + '@noble/hashes@1.5.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -12851,7 +12995,7 @@ snapshots: react-dom: 18.2.0(react@18.2.0) react-remove-scroll: 2.5.7(@types/react@18.2.14)(react@18.2.0) ua-parser-js: 1.0.37 - viem: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.22.4) + viem: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4) wagmi: 2.5.20(@react-native-async-storage/async-storage@1.22.0(react-native@0.76.1(@babel/core@7.22.9)(@babel/preset-env@7.24.6(@babel/core@7.22.9))(@types/react@18.2.14)(bufferutil@4.0.8)(react@18.2.0)))(@tanstack/query-core@5.28.8)(@tanstack/react-query@5.28.8(react@18.2.0))(@types/react@18.2.14)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.76.1(@babel/core@7.22.9)(@babel/preset-env@7.24.6(@babel/core@7.22.9))(@types/react@18.2.14)(bufferutil@4.0.8)(react@18.2.0))(react@18.2.0)(rollup@4.27.4)(typescript@5.6.3)(viem@2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4))(zod@3.22.4) transitivePeerDependencies: - '@types/react' @@ -13092,6 +13236,8 @@ snapshots: '@scure/base@1.1.6': {} + '@scure/base@1.1.9': {} + '@scure/bip32@1.3.2': dependencies: '@noble/curves': 1.2.0 @@ -13104,6 +13250,12 @@ snapshots: '@noble/hashes': 1.3.3 '@scure/base': 1.1.6 + '@scure/bip32@1.4.0': + dependencies: + '@noble/curves': 1.4.0 + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.6 + '@scure/bip39@1.2.1': dependencies: '@noble/hashes': 1.3.3 @@ -13114,6 +13266,11 @@ snapshots: '@noble/hashes': 1.3.3 '@scure/base': 1.1.6 + '@scure/bip39@1.4.0': + dependencies: + '@noble/hashes': 1.5.0 + '@scure/base': 1.1.9 + '@sentry-internal/feedback@7.114.0': dependencies: '@sentry/core': 7.114.0 @@ -13757,7 +13914,7 @@ snapshots: util: 0.12.5 util-deprecate: 1.0.2 watchpack: 2.4.1 - ws: 8.14.2(bufferutil@4.0.8) + ws: 8.14.2(bufferutil@4.0.8)(utf-8-validate@6.0.3) transitivePeerDependencies: - bufferutil - encoding @@ -14612,6 +14769,17 @@ snapshots: dependencies: '@vanilla-extract/css': 1.14.0 + '@viem/anvil@0.0.10(bufferutil@4.0.8)(utf-8-validate@6.0.3)': + dependencies: + execa: 7.2.0 + get-port: 6.1.2 + http-proxy: 1.18.1 + ws: 8.14.2(bufferutil@4.0.8)(utf-8-validate@6.0.3) + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + '@viem/anvil@0.0.6(bufferutil@4.0.8)': dependencies: execa: 7.2.0 @@ -14836,7 +15004,7 @@ snapshots: picocolors: 1.0.0 picomatch: 3.0.1 prettier: 3.2.5 - viem: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.22.4) + viem: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4) zod: 3.22.4 optionalDependencies: typescript: 5.6.3 @@ -14853,7 +15021,7 @@ snapshots: '@wagmi/core': 2.6.17(@tanstack/query-core@5.28.8)(@types/react@18.2.14)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.6.3)(viem@2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4))(zod@3.22.4) '@walletconnect/ethereum-provider': 2.11.2(@react-native-async-storage/async-storage@1.22.0(react-native@0.76.1(@babel/core@7.22.9)(@babel/preset-env@7.24.6(@babel/core@7.22.9))(@types/react@18.2.14)(bufferutil@4.0.8)(react@18.2.0)))(@types/react@18.2.14)(bufferutil@4.0.8)(react@18.2.0) '@walletconnect/modal': 2.6.2(@types/react@18.2.14)(react@18.2.0) - viem: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.22.4) + viem: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: @@ -14884,7 +15052,7 @@ snapshots: dependencies: eventemitter3: 5.0.1 mipd: 0.0.5(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4) - viem: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.22.4) + viem: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4) zustand: 4.4.1(@types/react@18.2.14)(react@18.2.0) optionalDependencies: '@tanstack/query-core': 5.28.8 @@ -15242,6 +15410,16 @@ snapshots: typescript: 5.6.3 zod: 3.22.4 + abitype@1.0.0(typescript@5.6.3)(zod@3.24.1): + optionalDependencies: + typescript: 5.6.3 + zod: 3.24.1 + + abitype@1.0.5(typescript@5.6.3)(zod@3.24.1): + optionalDependencies: + typescript: 5.6.3 + zod: 3.24.1 + abitype@1.0.6(typescript@5.6.3)(zod@3.22.4): optionalDependencies: typescript: 5.6.3 @@ -16881,7 +17059,7 @@ snapshots: human-signals: 4.3.1 is-stream: 3.0.0 merge-stream: 2.0.0 - npm-run-path: 5.1.0 + npm-run-path: 5.3.0 onetime: 6.0.0 signal-exit: 3.0.7 strip-final-newline: 3.0.0 @@ -17185,6 +17363,8 @@ snapshots: get-port@6.1.2: {} + get-port@7.1.0: {} + get-stream@6.0.1: {} get-stream@8.0.1: {} @@ -17770,10 +17950,14 @@ snapshots: transitivePeerDependencies: - encoding - isows@1.0.3(ws@8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)): + isows@1.0.3(ws@8.13.0(bufferutil@4.0.8)): dependencies: ws: 8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) + isows@1.0.4(ws@8.17.1(bufferutil@4.0.8)(utf-8-validate@6.0.3)): + dependencies: + ws: 8.17.1(bufferutil@4.0.8)(utf-8-validate@6.0.3) + istanbul-lib-coverage@3.2.2: {} istanbul-lib-instrument@5.2.1: @@ -18674,10 +18858,6 @@ snapshots: dependencies: path-key: 3.1.1 - npm-run-path@5.1.0: - dependencies: - path-key: 4.0.0 - npm-run-path@5.3.0: dependencies: path-key: 4.0.0 @@ -20644,6 +20824,10 @@ snapshots: vary@1.1.2: {} + viem-deal@2.0.4(viem@2.21.18(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.24.1)): + dependencies: + viem: 2.21.18(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.24.1) + viem@1.21.4(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4): dependencies: '@adraffy/ens-normalize': 1.10.0 @@ -20652,7 +20836,42 @@ snapshots: '@scure/bip32': 1.3.2 '@scure/bip39': 1.2.1 abitype: 0.9.8(typescript@5.6.3)(zod@3.22.4) - isows: 1.0.3(ws@8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)) + isows: 1.0.3(ws@8.13.0(bufferutil@4.0.8)) + ws: 8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.21.18(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.24.1): + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.4.0 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.4.0 + abitype: 1.0.5(typescript@5.6.3)(zod@3.24.1) + isows: 1.0.4(ws@8.17.1(bufferutil@4.0.8)(utf-8-validate@6.0.3)) + webauthn-p256: 0.0.5 + ws: 8.17.1(bufferutil@4.0.8)(utf-8-validate@6.0.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.24.1): + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 1.0.0(typescript@5.6.3)(zod@3.24.1) + isows: 1.0.3(ws@8.13.0(bufferutil@4.0.8)) ws: 8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) optionalDependencies: typescript: 5.6.3 @@ -20661,7 +20880,7 @@ snapshots: - utf-8-validate - zod - viem@2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.22.4): + viem@2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4): dependencies: '@adraffy/ens-normalize': 1.10.0 '@noble/curves': 1.2.0 @@ -20669,7 +20888,7 @@ snapshots: '@scure/bip32': 1.3.2 '@scure/bip39': 1.2.1 abitype: 1.0.0(typescript@5.6.3)(zod@3.22.4) - isows: 1.0.3(ws@8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)) + isows: 1.0.3(ws@8.13.0(bufferutil@4.0.8)) ws: 8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) optionalDependencies: typescript: 5.6.3 @@ -20777,7 +20996,7 @@ snapshots: '@wagmi/core': 2.6.17(@tanstack/query-core@5.28.8)(@types/react@18.2.14)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.6.3)(viem@2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4))(zod@3.22.4) react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) - viem: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.22.4) + viem: 2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: @@ -20818,6 +21037,11 @@ snapshots: dependencies: defaults: 1.0.4 + webauthn-p256@0.0.5: + dependencies: + '@noble/curves': 1.4.0 + '@noble/hashes': 1.4.0 + webextension-polyfill-ts@0.25.0: dependencies: webextension-polyfill: 0.7.0 @@ -20979,9 +21203,15 @@ snapshots: bufferutil: 4.0.8 utf-8-validate: 6.0.3 - ws@8.14.2(bufferutil@4.0.8): + ws@8.14.2(bufferutil@4.0.8)(utf-8-validate@6.0.3): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 6.0.3 + + ws@8.17.1(bufferutil@4.0.8)(utf-8-validate@6.0.3): optionalDependencies: bufferutil: 4.0.8 + utf-8-validate: 6.0.3 xml-name-validator@4.0.0: {} @@ -21061,6 +21291,8 @@ snapshots: zod@3.22.4: {} + zod@3.24.1: {} + zustand@4.4.1(@types/react@18.2.14)(react@18.2.0): dependencies: use-sync-external-store: 1.2.0(react@18.2.0) From d77b367b122912bfdb79233a281c3998d76e1c5b Mon Sep 17 00:00:00 2001 From: yivlad Date: Thu, 12 Dec 2024 12:44:32 +0100 Subject: [PATCH 02/13] Change version to 0.0.1 --- packages/common-testnets/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common-testnets/package.json b/packages/common-testnets/package.json index d7fadb111..267a2fafe 100644 --- a/packages/common-testnets/package.json +++ b/packages/common-testnets/package.json @@ -1,6 +1,6 @@ { "name": "@marsfoundation/common-testnets", - "version": "0.1.1", + "version": "0.0.1", "engines": { "node": ">=18.0.0" }, From a57ae3283916abead8c65c3a1fc4b8f3202267b0 Mon Sep 17 00:00:00 2001 From: yivlad Date: Thu, 12 Dec 2024 12:49:33 +0100 Subject: [PATCH 03/13] Lint --- packages/common-testnets/package.json | 4 +--- .../common-testnets/src/TestnetFactory.test.ts | 16 +++++++++------- .../src/anvil/AnvilTestnetFactory.ts | 7 +++---- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/common-testnets/package.json b/packages/common-testnets/package.json index 267a2fafe..eba4f1a12 100644 --- a/packages/common-testnets/package.json +++ b/packages/common-testnets/package.json @@ -27,9 +27,7 @@ } } }, - "files": [ - "dist" - ], + "files": ["dist"], "scripts": { "lint": "eslint src", "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run test --silent\" \"pnpm run typecheck\"", diff --git a/packages/common-testnets/src/TestnetFactory.test.ts b/packages/common-testnets/src/TestnetFactory.test.ts index 7137d24c9..020c1b14f 100644 --- a/packages/common-testnets/src/TestnetFactory.test.ts +++ b/packages/common-testnets/src/TestnetFactory.test.ts @@ -1,6 +1,6 @@ import { getEnv } from '@marsfoundation/common-nodejs/env' import { expect } from 'earl' -import { describe, it, before, after } from 'mocha' +import { after, before, describe, it } from 'mocha' import { TestnetClient } from './TestnetClient' import { TestnetFactory } from './TestnetFactory' import { AnvilTestnetFactory } from './anvil' @@ -29,7 +29,7 @@ describe('TestnetFactory', () => { const expectedTimestamp = 1733909123n + 2n before(async () => { - ({ client: testnetClient, cleanup } = await factory.create({ + ;({ client: testnetClient, cleanup } = await factory.create({ id: 'test', originChainId: 1, forkChainId: expectedChainId, @@ -73,18 +73,20 @@ describe('TestnetFactory', () => { }) it('does not contain tx from future block', async () => { - await expect(testnetClient.getTransactionReceipt({ - hash: '0x7057abf025862e54cb1c33b4f4d4e6f8793383098abb84e58a85d1f10d14b765', - })).toBeRejectedWith('The Transaction may not be processed on a block yet.') + await expect( + testnetClient.getTransactionReceipt({ + hash: '0x7057abf025862e54cb1c33b4f4d4e6f8793383098abb84e58a85d1f10d14b765', + }), + ).toBeRejectedWith('The Transaction may not be processed on a block yet.') }) }) - + describe('Without block specified', () => { let testnetClient: TestnetClient let cleanup: () => Promise before(async () => { - ({ client: testnetClient, cleanup } = await factory.create({ + ;({ client: testnetClient, cleanup } = await factory.create({ id: 'test', originChainId: 1, forkChainId: expectedChainId, diff --git a/packages/common-testnets/src/anvil/AnvilTestnetFactory.ts b/packages/common-testnets/src/anvil/AnvilTestnetFactory.ts index 8264f7c89..6d4438ef6 100644 --- a/packages/common-testnets/src/anvil/AnvilTestnetFactory.ts +++ b/packages/common-testnets/src/anvil/AnvilTestnetFactory.ts @@ -3,9 +3,9 @@ import { TestnetClient } from '../TestnetClient' import { CreateNetworkArgs, TestnetCreateResult, TestnetFactory } from '../TestnetFactory' import { createAnvil } from '@viem/anvil' -import { getAnvilClient } from './AnvilClient' -import { createPublicClient, http } from 'viem' import getPort from 'get-port' +import { http, createPublicClient } from 'viem' +import { getAnvilClient } from './AnvilClient' export class AnvilTestnetFactory implements TestnetFactory { constructor(private readonly opts: { alchemyApiKey: string }) {} @@ -20,7 +20,7 @@ export class AnvilTestnetFactory implements TestnetFactory { return blockNumber } - const publicClient = createPublicClient({ transport: http(forkUrl)}) + const publicClient = createPublicClient({ transport: http(forkUrl) }) return publicClient.getBlockNumber() })() const port = await getPort({ port: 8545 }) @@ -68,4 +68,3 @@ function originChainIdToForkUrl(originChainId: number, alchemyApiKey: string): s throw new Error(`Unsupported origin chain id: ${originChainId}`) } } - From c672445c75a8f10a738f47233b23173fe09a55f0 Mon Sep 17 00:00:00 2001 From: yivlad Date: Thu, 12 Dec 2024 16:37:20 +0100 Subject: [PATCH 04/13] Add Ci (common-testnets) job --- .github/workflows/ci-common-testnets.yml | 43 ++++++++++++++++++++++++ .github/workflows/ci.yml | 23 +++++++------ packages/app/package.json | 4 ++- packages/common-nodejs/package.json | 4 ++- packages/common-testnets/package.json | 2 ++ packages/common-universal/package.json | 2 ++ 6 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/ci-common-testnets.yml diff --git a/.github/workflows/ci-common-testnets.yml b/.github/workflows/ci-common-testnets.yml new file mode 100644 index 000000000..a94f9c7ae --- /dev/null +++ b/.github/workflows/ci-common-testnets.yml @@ -0,0 +1,43 @@ +name: CI (common-testnets) + +on: + pull_request: + paths: + - "packages/common-testnets/**" + - "pnpm-lock.yaml" + push: + branches: + - main + +jobs: + test: + strategy: + matrix: + node: [ "20" ] + os: [ ubuntu-latest ] + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 9.14.2 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + cache: "pnpm" + - run: pnpm install + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1.2.0 + with: + version: nightly-58bf161bc9dd6e74de8cb61e3ae23f701feb5512 + + - run: pnpm check + - run: pnpm verify + working-directory: ./packages/common-testnets + env: + TENDERLY_API_KEY: "${{ secrets.TENDERLY_API_KEY }}" + TENDERLY_ACCOUNT: phoenixlabs + TENDERLY_PROJECT: spark-app-e2e-tests + TEST_E2E_ALCHEMY_API_KEY: "${{ secrets.ALCHEMY_API_KEY }}" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bd921e8a1..f663909ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,18 +64,19 @@ jobs: cache: "pnpm" - run: pnpm install - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1.2.0 - with: - version: nightly-58bf161bc9dd6e74de8cb61e3ae23f701feb5512 - - run: pnpm check - - run: pnpm verify # does linting, type checking, and tests in parallel - env: - TENDERLY_API_KEY: "${{ secrets.TENDERLY_API_KEY }}" - TENDERLY_ACCOUNT: phoenixlabs - TENDERLY_PROJECT: spark-app-e2e-tests - TEST_E2E_ALCHEMY_API_KEY: "${{ secrets.ALCHEMY_API_KEY }}" + + - name: Verify app + working-directory: ./packages/app + run: pnpm verify + + - name: Verify common-universal + working-directory: ./packages/app + run: pnpm verify + + - name: Verify common-nodejs + working-directory: ./packages/app + run: pnpm verify storybook-visual-regression: strategy: diff --git a/packages/app/package.json b/packages/app/package.json index ef288e826..b315d8af4 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -13,7 +13,9 @@ "lint": "eslint src", "lint:custom": "tsx ./scripts/verify-svgs.ts", "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run test --silent\" \"pnpm run typecheck\" \"pnpm run lint:custom\"", - "fix": "cd ../../ && pnpm run check:fix && cd - && pnpm run verify", + "check": "cd ../../ && pnpm run check && cd -", + "check:fix": "cd ../../ && pnpm run check:fix && cd -", + "fix": "pnpm run check:fix && pnpm run verify", "test": "DEBUG_PRINT_LIMIT=100000 vitest --run", "test-e2e": "playwright test", "test-e2e:ui": "pnpm test-e2e --ui --headed", diff --git a/packages/common-nodejs/package.json b/packages/common-nodejs/package.json index 62c2e9796..4436875bc 100644 --- a/packages/common-nodejs/package.json +++ b/packages/common-nodejs/package.json @@ -59,7 +59,9 @@ "scripts": { "lint": "eslint src", "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run test --silent\" \"pnpm run typecheck\"", - "fix": "cd ../../ && pnpm run check:fix && cd - && pnpm run verify", + "check": "cd ../../ && pnpm run check && cd -", + "check:fix": "cd ../../ && pnpm run check:fix && cd -", + "fix": "pnpm run check:fix && pnpm run verify", "test": "mocha src/**/*.test.ts", "typecheck": "tsc --noEmit", "build:cjs": "tsc -p tsconfig.cjs.json", diff --git a/packages/common-testnets/package.json b/packages/common-testnets/package.json index eba4f1a12..6dcca0770 100644 --- a/packages/common-testnets/package.json +++ b/packages/common-testnets/package.json @@ -31,6 +31,8 @@ "scripts": { "lint": "eslint src", "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run test --silent\" \"pnpm run typecheck\"", + "check": "cd ../../ && pnpm run check && cd -", + "check:fix": "cd ../../ && pnpm run check:fix && cd -", "fix": "cd ../../ && pnpm run check:fix && cd - && pnpm run verify", "test": "mocha src/**/*.test.ts", "typecheck": "tsc --noEmit", diff --git a/packages/common-universal/package.json b/packages/common-universal/package.json index 024e5bd5a..8d5714231 100644 --- a/packages/common-universal/package.json +++ b/packages/common-universal/package.json @@ -31,6 +31,8 @@ "scripts": { "lint": "eslint src", "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run test --silent\" \"pnpm run typecheck\"", + "check": "cd ../../ && pnpm run check && cd -", + "check:fix": "cd ../../ && pnpm run check:fix && cd -", "fix": "cd ../../ && pnpm run check:fix && cd - && pnpm run verify", "test": "mocha src/**/*.test.ts", "typecheck": "tsc --noEmit", From 8ebef65dd12d1e57c04e255e95ab8883748b05ab Mon Sep 17 00:00:00 2001 From: yivlad Date: Thu, 12 Dec 2024 16:47:17 +0100 Subject: [PATCH 05/13] Run verify in parallel --- .github/workflows/ci.yml | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f663909ea..91772719c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,18 +65,8 @@ jobs: - run: pnpm install - run: pnpm check - - - name: Verify app - working-directory: ./packages/app - run: pnpm verify - - - name: Verify common-universal - working-directory: ./packages/app - run: pnpm verify - - - name: Verify common-nodejs - working-directory: ./packages/app - run: pnpm verify + - name: Verify # verifies all packages except common-testnets + run: pnpm run --parallel --aggregate-output --reporter append-only --filter './packages/{app,common-nodejs,common-universal}' verify storybook-visual-regression: strategy: From f17fb5b97e3a65cac4ced20a4ca6a2cc26f33fc8 Mon Sep 17 00:00:00 2001 From: oskarvu Date: Fri, 13 Dec 2024 09:31:52 +0700 Subject: [PATCH 06/13] Add comments --- packages/common-testnets/src/TestnetFactory.ts | 6 +++++- packages/common-testnets/src/anvil/AnvilClient.ts | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/common-testnets/src/TestnetFactory.ts b/packages/common-testnets/src/TestnetFactory.ts index 73fe218ab..075aac2de 100644 --- a/packages/common-testnets/src/TestnetFactory.ts +++ b/packages/common-testnets/src/TestnetFactory.ts @@ -4,7 +4,11 @@ export interface TestnetCreateResult { client: TestnetClient cleanup: () => Promise } - +/** + * The created testnet may have a slight deviation in both the final block number + * and its timestamp compared to the requested block. This is due to necessary normalization + * steps that ensure compatibility with different client implementations. + */ export interface TestnetFactory { create(network: CreateNetworkArgs): Promise createClientFromUrl(rpcUrl: string): TestnetClient diff --git a/packages/common-testnets/src/anvil/AnvilClient.ts b/packages/common-testnets/src/anvil/AnvilClient.ts index e0fbd7572..f86aec63a 100644 --- a/packages/common-testnets/src/anvil/AnvilClient.ts +++ b/packages/common-testnets/src/anvil/AnvilClient.ts @@ -41,7 +41,7 @@ export function getAnvilClient(rpc: string): TestnetClient { assert(result === true, 'revert failed') - // anvil snapshot are "burned" after revert so we need to create a new one + // anvil snapshots are "burned" after revert so we need to create a new one return await c.snapshot() }, async mineBlocks(blocks: bigint) { From 097d46815a6d6f35195083ae04c942d883ae1660 Mon Sep 17 00:00:00 2001 From: oskarvu Date: Fri, 13 Dec 2024 09:43:24 +0700 Subject: [PATCH 07/13] Simplify ci by running only e2e tests for testnet package --- .github/workflows/ci-common-testnets.yml | 3 +-- .github/workflows/ci.yml | 3 +-- packages/app/package.json | 4 +--- packages/common-nodejs/package.json | 4 +--- packages/common-testnets/package.json | 4 ++-- packages/common-universal/package.json | 2 -- 6 files changed, 6 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci-common-testnets.yml b/.github/workflows/ci-common-testnets.yml index a94f9c7ae..b9dc787e9 100644 --- a/.github/workflows/ci-common-testnets.yml +++ b/.github/workflows/ci-common-testnets.yml @@ -33,8 +33,7 @@ jobs: with: version: nightly-58bf161bc9dd6e74de8cb61e3ae23f701feb5512 - - run: pnpm check - - run: pnpm verify + - run: pnpm test-e2e working-directory: ./packages/common-testnets env: TENDERLY_API_KEY: "${{ secrets.TENDERLY_API_KEY }}" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 91772719c..ea73ae002 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,8 +65,7 @@ jobs: - run: pnpm install - run: pnpm check - - name: Verify # verifies all packages except common-testnets - run: pnpm run --parallel --aggregate-output --reporter append-only --filter './packages/{app,common-nodejs,common-universal}' verify + - run: pnpm verify # runs linting, type checking, and unit tests in parallel storybook-visual-regression: strategy: diff --git a/packages/app/package.json b/packages/app/package.json index b315d8af4..ef288e826 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -13,9 +13,7 @@ "lint": "eslint src", "lint:custom": "tsx ./scripts/verify-svgs.ts", "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run test --silent\" \"pnpm run typecheck\" \"pnpm run lint:custom\"", - "check": "cd ../../ && pnpm run check && cd -", - "check:fix": "cd ../../ && pnpm run check:fix && cd -", - "fix": "pnpm run check:fix && pnpm run verify", + "fix": "cd ../../ && pnpm run check:fix && cd - && pnpm run verify", "test": "DEBUG_PRINT_LIMIT=100000 vitest --run", "test-e2e": "playwright test", "test-e2e:ui": "pnpm test-e2e --ui --headed", diff --git a/packages/common-nodejs/package.json b/packages/common-nodejs/package.json index 4436875bc..62c2e9796 100644 --- a/packages/common-nodejs/package.json +++ b/packages/common-nodejs/package.json @@ -59,9 +59,7 @@ "scripts": { "lint": "eslint src", "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run test --silent\" \"pnpm run typecheck\"", - "check": "cd ../../ && pnpm run check && cd -", - "check:fix": "cd ../../ && pnpm run check:fix && cd -", - "fix": "pnpm run check:fix && pnpm run verify", + "fix": "cd ../../ && pnpm run check:fix && cd - && pnpm run verify", "test": "mocha src/**/*.test.ts", "typecheck": "tsc --noEmit", "build:cjs": "tsc -p tsconfig.cjs.json", diff --git a/packages/common-testnets/package.json b/packages/common-testnets/package.json index 6dcca0770..96d505afd 100644 --- a/packages/common-testnets/package.json +++ b/packages/common-testnets/package.json @@ -30,11 +30,11 @@ "files": ["dist"], "scripts": { "lint": "eslint src", - "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run test --silent\" \"pnpm run typecheck\"", + "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run typecheck\"", "check": "cd ../../ && pnpm run check && cd -", "check:fix": "cd ../../ && pnpm run check:fix && cd -", "fix": "cd ../../ && pnpm run check:fix && cd - && pnpm run verify", - "test": "mocha src/**/*.test.ts", + "test-e2e": "mocha src/**/*.test.ts", "typecheck": "tsc --noEmit", "build:cjs": "tsc -p tsconfig.cjs.json", "build:esm": "tsc -p tsconfig.esm.json", diff --git a/packages/common-universal/package.json b/packages/common-universal/package.json index 8d5714231..024e5bd5a 100644 --- a/packages/common-universal/package.json +++ b/packages/common-universal/package.json @@ -31,8 +31,6 @@ "scripts": { "lint": "eslint src", "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run test --silent\" \"pnpm run typecheck\"", - "check": "cd ../../ && pnpm run check && cd -", - "check:fix": "cd ../../ && pnpm run check:fix && cd -", "fix": "cd ../../ && pnpm run check:fix && cd - && pnpm run verify", "test": "mocha src/**/*.test.ts", "typecheck": "tsc --noEmit", From 20b4f7074e4773213f7cba5d6933a182bd5fe154 Mon Sep 17 00:00:00 2001 From: oskarvu Date: Fri, 13 Dec 2024 09:44:37 +0700 Subject: [PATCH 08/13] Change job name --- .github/workflows/ci-common-testnets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-common-testnets.yml b/.github/workflows/ci-common-testnets.yml index b9dc787e9..a05250fdb 100644 --- a/.github/workflows/ci-common-testnets.yml +++ b/.github/workflows/ci-common-testnets.yml @@ -10,7 +10,7 @@ on: - main jobs: - test: + test-e2e: strategy: matrix: node: [ "20" ] From b5a80b0113a6fcff2ecc7885e32cb5af74baa906 Mon Sep 17 00:00:00 2001 From: yivlad Date: Fri, 13 Dec 2024 09:40:27 +0100 Subject: [PATCH 09/13] Comments paths in common-testnets e2e test job definition --- .github/workflows/ci-common-testnets.yml | 7 ++++--- packages/common-testnets/package.json | 5 ++--- packages/common-testnets/src/TestnetFactory.ts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-common-testnets.yml b/.github/workflows/ci-common-testnets.yml index a05250fdb..f94728892 100644 --- a/.github/workflows/ci-common-testnets.yml +++ b/.github/workflows/ci-common-testnets.yml @@ -2,9 +2,10 @@ name: CI (common-testnets) on: pull_request: - paths: - - "packages/common-testnets/**" - - "pnpm-lock.yaml" + # @todo: uncomment when testnet factories are stable + # paths: + # - "packages/common-testnets/**" + # - "pnpm-lock.yaml" push: branches: - main diff --git a/packages/common-testnets/package.json b/packages/common-testnets/package.json index 96d505afd..1077169e5 100644 --- a/packages/common-testnets/package.json +++ b/packages/common-testnets/package.json @@ -30,10 +30,9 @@ "files": ["dist"], "scripts": { "lint": "eslint src", - "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run typecheck\"", - "check": "cd ../../ && pnpm run check && cd -", - "check:fix": "cd ../../ && pnpm run check:fix && cd -", + "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run test --silent\" \"pnpm run typecheck\"", "fix": "cd ../../ && pnpm run check:fix && cd - && pnpm run verify", + "test": "true", "test-e2e": "mocha src/**/*.test.ts", "typecheck": "tsc --noEmit", "build:cjs": "tsc -p tsconfig.cjs.json", diff --git a/packages/common-testnets/src/TestnetFactory.ts b/packages/common-testnets/src/TestnetFactory.ts index 075aac2de..2f70ab919 100644 --- a/packages/common-testnets/src/TestnetFactory.ts +++ b/packages/common-testnets/src/TestnetFactory.ts @@ -5,7 +5,7 @@ export interface TestnetCreateResult { cleanup: () => Promise } /** - * The created testnet may have a slight deviation in both the final block number + * The created testnet will have a small, though known beforehand, difference in both the final block number * and its timestamp compared to the requested block. This is due to necessary normalization * steps that ensure compatibility with different client implementations. */ From fcad2e915a576f5be7ba0f4971540269aa65f3da Mon Sep 17 00:00:00 2001 From: yivlad Date: Fri, 13 Dec 2024 10:18:19 +0100 Subject: [PATCH 10/13] AnvilFactory set next block timestamp before mining blocks --- packages/common-testnets/src/anvil/AnvilTestnetFactory.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/common-testnets/src/anvil/AnvilTestnetFactory.ts b/packages/common-testnets/src/anvil/AnvilTestnetFactory.ts index 6d4438ef6..c08954059 100644 --- a/packages/common-testnets/src/anvil/AnvilTestnetFactory.ts +++ b/packages/common-testnets/src/anvil/AnvilTestnetFactory.ts @@ -43,6 +43,8 @@ export class AnvilTestnetFactory implements TestnetFactory { const client = getAnvilClient(url) + const lastBlockTimestamp = (await client.getBlock()).timestamp + await client.setNextBlockTimestamp(lastBlockTimestamp + 1n) // mineBlocks does not respect interval for the first block await client.mineBlocks(2n) return { From e02e75afa32cd7e7dabaa4c8bd39e0cdff40777b Mon Sep 17 00:00:00 2001 From: yivlad Date: Fri, 13 Dec 2024 10:38:05 +0100 Subject: [PATCH 11/13] Pin zod version --- package.json | 3 +- packages/common-testnets/package.json | 3 +- pnpm-lock.yaml | 51 +++++++-------------------- 3 files changed, 16 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index 2d4c1466a..207859f68 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "clean": "pnpm run --parallel --aggregate-output --reporter append-only --filter './packages/**' clean" }, "dependencies": { - "bignumber.js": "^9.1.2" + "bignumber.js": "^9.1.2", + "zod": "3.22.4" }, "devDependencies": { "@biomejs/biome": "^1.8.1", diff --git a/packages/common-testnets/package.json b/packages/common-testnets/package.json index 1077169e5..cef3dccdd 100644 --- a/packages/common-testnets/package.json +++ b/packages/common-testnets/package.json @@ -47,8 +47,7 @@ "@viem/anvil": "^0.0.10", "get-port": "^7.1.0", "viem": "2.21.18", - "viem-deal": "^2.0.0", - "zod": "^3.23.8" + "viem-deal": "^2.0.0" }, "devDependencies": { "@types/mocha": "^10.0.10", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 106534718..8f021e5be 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,6 +16,9 @@ importers: bignumber.js: specifier: ^9.1.2 version: 9.1.2 + zod: + specifier: 3.22.4 + version: 3.22.4 devDependencies: '@biomejs/biome': specifier: ^1.8.1 @@ -418,9 +421,6 @@ importers: viem-deal: specifier: ^2.0.0 version: 2.0.4(viem@2.21.18(bufferutil@4.0.8)(typescript@5.6.3)(utf-8-validate@6.0.3)(zod@3.24.1)) - zod: - specifier: ^3.23.8 - version: 3.24.1 devDependencies: '@types/mocha': specifier: ^10.0.10 @@ -10059,7 +10059,7 @@ snapshots: '@babel/helper-function-name': 7.24.6 '@babel/helper-member-expression-to-functions': 7.24.6 '@babel/helper-optimise-call-expression': 7.24.6 - '@babel/helper-replace-supers': 7.24.6(@babel/core@7.24.5) + '@babel/helper-replace-supers': 7.24.6(@babel/core@7.22.9) '@babel/helper-skip-transparent-expression-wrappers': 7.24.6 '@babel/helper-split-export-declaration': 7.24.6 semver: 6.3.1 @@ -10212,15 +10212,6 @@ snapshots: '@babel/helper-split-export-declaration': 7.24.6 '@babel/helper-validator-identifier': 7.24.6 - '@babel/helper-module-transforms@7.24.6(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.24.6 - '@babel/helper-module-imports': 7.24.6 - '@babel/helper-simple-access': 7.24.6 - '@babel/helper-split-export-declaration': 7.24.6 - '@babel/helper-validator-identifier': 7.24.6 - '@babel/helper-module-transforms@7.26.0(@babel/core@7.22.9)': dependencies: '@babel/core': 7.22.9 @@ -10287,13 +10278,6 @@ snapshots: '@babel/helper-member-expression-to-functions': 7.24.6 '@babel/helper-optimise-call-expression': 7.24.6 - '@babel/helper-replace-supers@7.24.6(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.24.6 - '@babel/helper-member-expression-to-functions': 7.24.6 - '@babel/helper-optimise-call-expression': 7.24.6 - '@babel/helper-replace-supers@7.25.9(@babel/core@7.22.9)': dependencies: '@babel/core': 7.22.9 @@ -10619,11 +10603,6 @@ snapshots: '@babel/core': 7.22.9 '@babel/helper-plugin-utils': 7.24.6 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.6 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -10649,11 +10628,6 @@ snapshots: '@babel/core': 7.22.9 '@babel/helper-plugin-utils': 7.24.6 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.6 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -10953,7 +10927,7 @@ snapshots: '@babel/plugin-transform-modules-commonjs@7.24.6(@babel/core@7.24.5)': dependencies: '@babel/core': 7.24.5 - '@babel/helper-module-transforms': 7.24.6(@babel/core@7.24.5) + '@babel/helper-module-transforms': 7.24.6(@babel/core@7.22.9) '@babel/helper-plugin-utils': 7.24.6 '@babel/helper-simple-access': 7.24.6 @@ -11016,7 +10990,7 @@ snapshots: dependencies: '@babel/core': 7.24.5 '@babel/helper-plugin-utils': 7.24.6 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.5) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.9) '@babel/plugin-transform-nullish-coalescing-operator@7.25.9(@babel/core@7.22.9)': dependencies: @@ -11078,7 +11052,7 @@ snapshots: '@babel/core': 7.24.5 '@babel/helper-plugin-utils': 7.24.6 '@babel/helper-skip-transparent-expression-wrappers': 7.24.6 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.5) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.9) '@babel/plugin-transform-optional-chaining@7.25.9(@babel/core@7.22.9)': dependencies: @@ -17950,7 +17924,7 @@ snapshots: transitivePeerDependencies: - encoding - isows@1.0.3(ws@8.13.0(bufferutil@4.0.8)): + isows@1.0.3(ws@8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)): dependencies: ws: 8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) @@ -20836,7 +20810,7 @@ snapshots: '@scure/bip32': 1.3.2 '@scure/bip39': 1.2.1 abitype: 0.9.8(typescript@5.6.3)(zod@3.22.4) - isows: 1.0.3(ws@8.13.0(bufferutil@4.0.8)) + isows: 1.0.3(ws@8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)) ws: 8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) optionalDependencies: typescript: 5.6.3 @@ -20871,7 +20845,7 @@ snapshots: '@scure/bip32': 1.3.2 '@scure/bip39': 1.2.1 abitype: 1.0.0(typescript@5.6.3)(zod@3.24.1) - isows: 1.0.3(ws@8.13.0(bufferutil@4.0.8)) + isows: 1.0.3(ws@8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)) ws: 8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) optionalDependencies: typescript: 5.6.3 @@ -20888,7 +20862,7 @@ snapshots: '@scure/bip32': 1.3.2 '@scure/bip39': 1.2.1 abitype: 1.0.0(typescript@5.6.3)(zod@3.22.4) - isows: 1.0.3(ws@8.13.0(bufferutil@4.0.8)) + isows: 1.0.3(ws@8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)) ws: 8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) optionalDependencies: typescript: 5.6.3 @@ -21291,7 +21265,8 @@ snapshots: zod@3.22.4: {} - zod@3.24.1: {} + zod@3.24.1: + optional: true zustand@4.4.1(@types/react@18.2.14)(react@18.2.0): dependencies: From b789873ccad015e8e5e5d9ca2a81bce319c4eefe Mon Sep 17 00:00:00 2001 From: yivlad Date: Fri, 13 Dec 2024 10:38:32 +0100 Subject: [PATCH 12/13] Pin zod version v2 --- packages/app/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/app/package.json b/packages/app/package.json index ef288e826..60f4e0d15 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -78,7 +78,6 @@ "tailwindcss-animate": "^1.0.6", "viem": "^2.9.21", "wagmi": "^2.5.20", - "zod": "^3.22.4", "zustand": "^4.4.1" }, "devDependencies": { From 428c8e152d3e1e207b98d3510292ca09485e94dc Mon Sep 17 00:00:00 2001 From: yivlad Date: Fri, 13 Dec 2024 10:40:14 +0100 Subject: [PATCH 13/13] Update lock file --- pnpm-lock.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8f021e5be..cc5e79f56 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -209,9 +209,6 @@ importers: wagmi: specifier: ^2.5.20 version: 2.5.20(@react-native-async-storage/async-storage@1.22.0(react-native@0.76.1(@babel/core@7.22.9)(@babel/preset-env@7.24.6(@babel/core@7.22.9))(@types/react@18.2.14)(bufferutil@4.0.8)(react@18.2.0)))(@tanstack/query-core@5.28.8)(@tanstack/react-query@5.28.8(react@18.2.0))(@types/react@18.2.14)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.76.1(@babel/core@7.22.9)(@babel/preset-env@7.24.6(@babel/core@7.22.9))(@types/react@18.2.14)(bufferutil@4.0.8)(react@18.2.0))(react@18.2.0)(rollup@4.27.4)(typescript@5.6.3)(viem@2.9.21(bufferutil@4.0.8)(typescript@5.6.3)(zod@3.22.4))(zod@3.22.4) - zod: - specifier: ^3.22.4 - version: 3.22.4 zustand: specifier: ^4.4.1 version: 4.4.1(@types/react@18.2.14)(react@18.2.0)