diff --git a/.changeset/curly-tomatoes-eat.md b/.changeset/curly-tomatoes-eat.md new file mode 100644 index 00000000..c4d58114 --- /dev/null +++ b/.changeset/curly-tomatoes-eat.md @@ -0,0 +1,7 @@ +--- +"@delvtech/evm-client-ethers": patch +"@delvtech/evm-client-viem": patch +"@delvtech/evm-client": patch +--- + +Added getChainId method to the Network interface. diff --git a/packages/evm-client-ethers/README.md b/packages/evm-client-ethers/README.md index 6e9b74c0..c03c95af 100644 --- a/packages/evm-client-ethers/README.md +++ b/packages/evm-client-ethers/README.md @@ -1,6 +1,6 @@ # @delvtech/evm-client-ethers -Ethers bindings for [@delvtech/evm-client](https://github.com/delvtech/evm-client/tree/main/packages/evm-client) +Ethers implementations of [@delvtech/evm-client](https://github.com/delvtech/evm-client/tree/main/packages/evm-client). ```ts import { createCachedReadContract } from '@delvtech/evm-client-ethers'; diff --git a/packages/evm-client-ethers/src/network/createNetwork.ts b/packages/evm-client-ethers/src/network/createNetwork.ts index 5d081a73..5d312e16 100644 --- a/packages/evm-client-ethers/src/network/createNetwork.ts +++ b/packages/evm-client-ethers/src/network/createNetwork.ts @@ -31,6 +31,11 @@ export function createNetwork(provider: Provider): Network { }; }, + async getChainId() { + const network = await provider.getNetwork(); + return Number(network.chainId); + }, + async getTransaction(hash) { const transaction = await provider.getTransaction(hash); diff --git a/packages/evm-client-viem/README.md b/packages/evm-client-viem/README.md index d59e424f..5da90a56 100644 --- a/packages/evm-client-viem/README.md +++ b/packages/evm-client-viem/README.md @@ -1,6 +1,6 @@ # @delvtech/evm-client-viem -Viem bindings for [@delvtech/evm-client](https://github.com/delvtech/evm-client/tree/main/packages/evm-client) +Viem implementations of [@delvtech/evm-client](https://github.com/delvtech/evm-client/tree/main/packages/evm-client). ```ts import { createCachedReadContract } from '@delvtech/evm-client-viem'; diff --git a/packages/evm-client-viem/src/network/createNetwork.ts b/packages/evm-client-viem/src/network/createNetwork.ts index ee0a6731..60068fb7 100644 --- a/packages/evm-client-viem/src/network/createNetwork.ts +++ b/packages/evm-client-viem/src/network/createNetwork.ts @@ -37,6 +37,10 @@ export function createNetwork(publicClient: PublicClient): Network { return { blockNumber: block.number, timestamp: block.timestamp }; }, + getChainId() { + return publicClient.getChainId(); + }, + async getTransaction(hash) { const { blockHash, diff --git a/packages/evm-client/src/network/stubs/NetworkStub.test.ts b/packages/evm-client/src/network/stubs/NetworkStub.test.ts index 7f2bc0f5..d8e62e2b 100644 --- a/packages/evm-client/src/network/stubs/NetworkStub.test.ts +++ b/packages/evm-client/src/network/stubs/NetworkStub.test.ts @@ -1,10 +1,75 @@ +import { ALICE } from 'src/base/testing/accounts'; import { NetworkStub, transactionToReceipt, } from 'src/network/stubs/NetworkStub'; import { describe, expect, it } from 'vitest'; +import { Transaction } from '../types/Transaction'; describe('NetworkStub', () => { + it('stubs getBalance', async () => { + const network = new NetworkStub(); + + network.stubGetBalance({ + args: [ALICE], + value: 100n, + }); + + const balance = await network.getBalance(ALICE); + + expect(balance).toEqual(100n); + }); + + it('stubs getBlock', async () => { + const network = new NetworkStub(); + + const block = { + blockNumber: 1n, + timestamp: 1000n, + }; + network.stubGetBlock({ + args: [{ blockNumber: 1n }], + value: block, + }); + + const blockResponse = await network.getBlock({ blockNumber: 1n }); + + expect(blockResponse).toEqual(block); + }); + + it('stubs getChainId', async () => { + const network = new NetworkStub(); + + network.stubGetChainId(42069); + + const chainId = await network.getChainId(); + + expect(chainId).toEqual(42069); + }); + + it('stubs getTransaction', async () => { + const network = new NetworkStub(); + + const txHash = '0x123abc'; + const tx: Transaction = { + gas: 100n, + gasPrice: 100n, + input: '0x456def', + nonce: 0, + type: '0x0', + value: 0n, + }; + + network.stubGetTransaction({ + args: [txHash], + value: tx, + }); + + const transaction = await network.getTransaction(txHash); + + expect(transaction).toEqual(tx); + }); + it('waits for stubbed transactions', async () => { const network = new NetworkStub(); diff --git a/packages/evm-client/src/network/stubs/NetworkStub.ts b/packages/evm-client/src/network/stubs/NetworkStub.ts index 1ca88933..dce98cea 100644 --- a/packages/evm-client/src/network/stubs/NetworkStub.ts +++ b/packages/evm-client/src/network/stubs/NetworkStub.ts @@ -20,6 +20,7 @@ export class NetworkStub implements Network { protected getBlockStub: | SinonStub<[NetworkGetBlockArgs?], Promise> | undefined; + protected getChainIdStub: SinonStub<[], Promise> | undefined; protected getTransactionStub: | SinonStub<[NetworkGetTransactionArgs?], Promise> | undefined; @@ -64,6 +65,14 @@ export class NetworkStub implements Network { this.getBlockStub.resolves(value); } + stubGetChainId(id: number): void { + if (!this.getChainIdStub) { + this.getChainIdStub = stub(); + } + + this.getChainIdStub.resolves(id); + } + stubGetTransaction({ args, value, @@ -102,6 +111,15 @@ export class NetworkStub implements Network { return this.getBlockStub(args); } + getChainId(): Promise { + if (!this.getChainIdStub) { + throw new Error( + `The getChainId function must be stubbed first:\n\tcontract.stubGetChainId()`, + ); + } + return this.getChainIdStub(); + } + getTransaction( ...args: NetworkGetTransactionArgs ): Promise { diff --git a/packages/evm-client/src/network/types/Network.ts b/packages/evm-client/src/network/types/Network.ts index ad8f9dda..ff4e55ca 100644 --- a/packages/evm-client/src/network/types/Network.ts +++ b/packages/evm-client/src/network/types/Network.ts @@ -18,6 +18,11 @@ export interface Network { */ getBlock(...args: NetworkGetBlockArgs): Promise; + /** + * Get the chain ID of the network. + */ + getChainId(): Promise; + /** * Get a transaction from a transaction hash. */