From c0764a2745818e28d2d6a19dae32e194221c0280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Magalh=C3=A3es?= Date: Tue, 17 Oct 2023 12:28:57 +0100 Subject: [PATCH 01/13] ZkSync formatters --- src/chains/definitions/zkSync.ts | 58 +- src/chains/definitions/zkSyncTestnet.ts | 52 +- src/chains/package.json | 6 +- src/chains/utils/index.test.ts | 1 + src/chains/utils/index.ts | 15 + src/chains/zksync/formatters.test-d.ts | 218 +++++ src/chains/zksync/formatters.test.ts | 1148 +++++++++++++++++++++++ src/chains/zksync/formatters.ts | 112 +++ src/chains/zksync/types.ts | 264 ++++++ 9 files changed, 1821 insertions(+), 53 deletions(-) create mode 100644 src/chains/zksync/formatters.test-d.ts create mode 100644 src/chains/zksync/formatters.test.ts create mode 100644 src/chains/zksync/formatters.ts create mode 100644 src/chains/zksync/types.ts diff --git a/src/chains/definitions/zkSync.ts b/src/chains/definitions/zkSync.ts index 06bd6e7fa8..ee2e58d054 100644 --- a/src/chains/definitions/zkSync.ts +++ b/src/chains/definitions/zkSync.ts @@ -1,33 +1,39 @@ import { defineChain } from '../../utils/chain.js' +import { formattersZkSync } from '../zksync/formatters.js' -export const zkSync = /*#__PURE__*/ defineChain({ - id: 324, - name: 'zkSync Era', - network: 'zksync-era', - nativeCurrency: { - decimals: 18, - name: 'Ether', - symbol: 'ETH', - }, - rpcUrls: { - default: { - http: ['https://mainnet.era.zksync.io'], - webSocket: ['wss://mainnet.era.zksync.io/ws'], +export const zkSync = /*#__PURE__*/ defineChain( + { + id: 324, + name: 'zkSync Era', + network: 'zksync-era', + nativeCurrency: { + decimals: 18, + name: 'Ether', + symbol: 'ETH', }, - public: { - http: ['https://mainnet.era.zksync.io'], - webSocket: ['wss://mainnet.era.zksync.io/ws'], + rpcUrls: { + default: { + http: ['https://mainnet.era.zksync.io'], + webSocket: ['wss://mainnet.era.zksync.io/ws'], + }, + public: { + http: ['https://mainnet.era.zksync.io'], + webSocket: ['wss://mainnet.era.zksync.io/ws'], + }, }, - }, - blockExplorers: { - default: { - name: 'zkExplorer', - url: 'https://explorer.zksync.io', + blockExplorers: { + default: { + name: 'zkExplorer', + url: 'https://explorer.zksync.io', + }, }, - }, - contracts: { - multicall3: { - address: '0xF9cda624FBC7e059355ce98a31693d299FACd963', + contracts: { + multicall3: { + address: '0xF9cda624FBC7e059355ce98a31693d299FACd963', + }, }, }, -}) + { + formatters: formattersZkSync, + }, +) diff --git a/src/chains/definitions/zkSyncTestnet.ts b/src/chains/definitions/zkSyncTestnet.ts index 5bd917717a..f133b28709 100644 --- a/src/chains/definitions/zkSyncTestnet.ts +++ b/src/chains/definitions/zkSyncTestnet.ts @@ -1,30 +1,36 @@ import { defineChain } from '../../utils/chain.js' +import { formattersZkSync } from '../zksync/formatters.js' -export const zkSyncTestnet = /*#__PURE__*/ defineChain({ - id: 280, - name: 'zkSync Era Testnet', - network: 'zksync-era-testnet', - nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, - rpcUrls: { - default: { - http: ['https://testnet.era.zksync.dev'], - webSocket: ['wss://testnet.era.zksync.dev/ws'], +export const zkSyncTestnet = /*#__PURE__*/ defineChain( + { + id: 280, + name: 'zkSync Era Testnet', + network: 'zksync-era-testnet', + nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, + rpcUrls: { + default: { + http: ['https://testnet.era.zksync.dev'], + webSocket: ['wss://testnet.era.zksync.dev/ws'], + }, + public: { + http: ['https://testnet.era.zksync.dev'], + webSocket: ['wss://testnet.era.zksync.dev/ws'], + }, }, - public: { - http: ['https://testnet.era.zksync.dev'], - webSocket: ['wss://testnet.era.zksync.dev/ws'], + blockExplorers: { + default: { + name: 'zkExplorer', + url: 'https://goerli.explorer.zksync.io', + }, }, - }, - blockExplorers: { - default: { - name: 'zkExplorer', - url: 'https://goerli.explorer.zksync.io', + contracts: { + multicall3: { + address: '0xF9cda624FBC7e059355ce98a31693d299FACd963', + }, }, + testnet: true, }, - contracts: { - multicall3: { - address: '0xF9cda624FBC7e059355ce98a31693d299FACd963', - }, + { + formatters: formattersZkSync, }, - testnet: true, -}) +) diff --git a/src/chains/package.json b/src/chains/package.json index 92a465994d..98d45778d8 100644 --- a/src/chains/package.json +++ b/src/chains/package.json @@ -1,6 +1,4 @@ { - "type": "module", - "types": "../_types/chains/index.d.ts", - "module": "../_esm/chains/index.js", - "main": "../_cjs/chains/index.js" + "name": "viem_zksync_chains1", + "type": "module" } diff --git a/src/chains/utils/index.test.ts b/src/chains/utils/index.test.ts index c5c78f03cb..2064b1d3ef 100644 --- a/src/chains/utils/index.test.ts +++ b/src/chains/utils/index.test.ts @@ -10,6 +10,7 @@ test('exports', () => { "serializersCelo", "parseTransactionCelo", "formattersOptimism", + "formattersZkSync" ] `) }) diff --git a/src/chains/utils/index.ts b/src/chains/utils/index.ts index d14375fc7e..24d12dd6bd 100644 --- a/src/chains/utils/index.ts +++ b/src/chains/utils/index.ts @@ -43,3 +43,18 @@ export type { OptimismTransactionReceipt, OptimismTransactionReceiptOverrides, } from '../optimism/types.js' + +export { formattersZkSync } from '../zksync/formatters.js' +export type { + ZkSyncBlock, + ZkSyncBlockOverrides, + ZkSyncRpcTransaction, + ZkSyncRpcTransactionReceipt, + ZkSyncRpcTransactionReceiptOverrides, + ZkSyncRpcTransactionRequest, + ZkSyncTransaction, + ZkSyncTransactionReceipt, + ZkSyncTransactionReceiptOverrides, + ZkSyncTransactionRequest, + TransactionRequestEIP712, +} from '../zksync/types.js' diff --git a/src/chains/zksync/formatters.test-d.ts b/src/chains/zksync/formatters.test-d.ts new file mode 100644 index 0000000000..21f4fceac5 --- /dev/null +++ b/src/chains/zksync/formatters.test-d.ts @@ -0,0 +1,218 @@ +import { describe, expectTypeOf, test } from 'vitest' + +import { getBlock } from '../../actions/public/getBlock.js' +import { getTransaction } from '../../actions/public/getTransaction.js' +import { getTransactionReceipt } from '../../actions/public/getTransactionReceipt.js' +import { prepareTransactionRequest } from '../../actions/wallet/prepareTransactionRequest.js' +import { signTransaction } from '../../actions/wallet/signTransaction.js' +import { createPublicClient } from '../../clients/createPublicClient.js' +import { createWalletClient } from '../../clients/createWalletClient.js' +import { http } from '../../clients/transports/http.js' +import type { Hash } from '../../types/misc.js' +import type { RpcBlock } from '../../types/rpc.js' +import type { TransactionRequest } from '../../types/transaction.js' +import type { Assign } from '../../types/utils.js' +import { sendTransaction } from '../../wallet/index.js' +import { zkSync } from '../index.js' +import { formattersZkSync } from './formatters.js' +import type { ZkSyncRpcTransaction, ZkSyncTransactionRequest } from './types.js' + +describe('block', () => { + expectTypeOf(formattersZkSync.block.format).parameter(0).toEqualTypeOf< + Assign< + Partial, + { + l1BatchNumber: `0x${string}` + l1BatchTimestamp: `0x${string}` | null + } & { + transactions: `0x${string}`[] | ZkSyncRpcTransaction[] + } + > + >() + expectTypeOf< + ReturnType['l1BatchNumber'] + >().toEqualTypeOf<`0x${string}`> + expectTypeOf< + ReturnType['l1BatchTimestamp'] + >().toEqualTypeOf<`0x${string}` | null> +}) + +describe('transactionReceipt', () => { + // Cannot make this match + /*expectTypeOf(formattersZkSync.transactionReceipt.format) + .parameter(0) + .toEqualTypeOf & { + l1BatchNumber: Hex | null + l1BatchTxIndex: Hex | null + logs: { + address: Address + blockHash: Hash + blockNumber: Hex + data: Hex + logIndex:Hex + transactionHash: Hash + transactionIndex: Hex + removed: boolean + l1BatchNumber: Hex + transactionLogIndex: Hex + logType: Hex | null + }[] + l2ToL1Logs: { + blockNumber: Hex + blockHash: Hex + l1BatchNumber: Hex + transactionIndex: Hex + shardId: Hex + isService: boolean + sender: Hex + key: Hex + value: Hex + transactionHash: Hex + logIndex: Hex + }[] + root: Hex + }>()*/ + + expectTypeOf< + ReturnType< + typeof formattersZkSync.transactionReceipt.format + >['l1BatchNumber'] + >().toEqualTypeOf() + expectTypeOf< + ReturnType< + typeof formattersZkSync.transactionReceipt.format + >['l1BatchTxIndex'] + >().toEqualTypeOf() +}) + +describe('transactionRequest', () => { + expectTypeOf(formattersZkSync.transactionRequest.format) + .parameter(0) + .toEqualTypeOf< + Assign, ZkSyncTransactionRequest> + >() +}) + +describe('smoke', () => { + test('block', async () => { + const client = createPublicClient({ + chain: zkSync, + transport: http(), + }) + const block = await getBlock(client, { + blockNumber: 35533n, + }) + + expectTypeOf(block.transactions).toEqualTypeOf() + }) + + test('transaction', async () => { + const client = createPublicClient({ + chain: zkSync, + transport: http(), + }) + + const transaction = await getTransaction(client, { + blockNumber: 16280770n, + index: 0, + }) + + expectTypeOf(transaction.type).toEqualTypeOf< + 'legacy' | 'eip2930' | 'eip1559' | 'eip712' | 'priority' + >() + }) + + test('transactionReceipt', async () => { + const client = createPublicClient({ + chain: zkSync, + transport: http(), + }) + + const transaction = await getTransactionReceipt(client, { + hash: '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + }) + + expectTypeOf(transaction.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(transaction.l1BatchNumber).toEqualTypeOf() + expectTypeOf(transaction.logs[0].l1BatchNumber).toEqualTypeOf() + expectTypeOf(transaction.l2ToL1Logs).toEqualTypeOf< + { + blockNumber: bigint + blockHash: string + l1BatchNumber: bigint + transactionIndex: bigint + shardId: bigint + isService: boolean + sender: string + key: string + value: string + transactionHash: string + logIndex: bigint + }[] + >() + }) + + test('transactionRequest (prepareTransactionRequest)', async () => { + const client = createWalletClient({ + account: '0x', + chain: zkSync, + transport: http(), + }) + + prepareTransactionRequest(client, { + gasPerPubdata: 50000n, + paymaster: '0x094499df5ee555ffc33af07862e43c90e6fee501', + paymasterInput: + '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', + customSignature: '0x', + }) + + // @ts-expect-error `customSignature` not provided + prepareTransactionRequest(client, { + paymaster: '0x094499df5ee555ffc33af07862e43c90e6fee501', + paymasterInput: + '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', + type: 'eip712', + }) + }) + + test('transactionRequest (sendTransaction)', async () => { + const client = createWalletClient({ + account: '0x094499df5ee555ffc33af07862e43c90e6fee501', + chain: zkSync, + transport: http(), + }) + + sendTransaction(client, { + gasPerPubdata: 50000n, + paymaster: '0x094499df5ee555ffc33af07862e43c90e6fee501', + paymasterInput: + '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', + customSignature: '0x', + }) + + // @ts-expect-error `customSignature` not provided + sendTransaction(client, { + paymaster: '0x094499df5ee555ffc33af07862e43c90e6fee501', + paymasterInput: + '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', + type: 'eip712', + }) + }) + + test('transactionRequest (signTransaction)', async () => { + const client = createWalletClient({ + account: '0x094499df5ee555ffc33af07862e43c90e6fee501', + chain: zkSync, + transport: http(), + }) + + signTransaction(client, { + gasPerPubdata: 50000n, + paymaster: '0x094499df5ee555ffc33af07862e43c90e6fee501', + paymasterInput: + '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', + customSignature: '0x', + }) + }) +}) diff --git a/src/chains/zksync/formatters.test.ts b/src/chains/zksync/formatters.test.ts new file mode 100644 index 0000000000..1ddc57b1e7 --- /dev/null +++ b/src/chains/zksync/formatters.test.ts @@ -0,0 +1,1148 @@ +import { describe, expect, test } from 'vitest' + +import { getBlock } from '../../actions/public/getBlock.js' +import { getTransaction } from '../../actions/public/getTransaction.js' +import { getTransactionReceipt } from '../../actions/public/getTransactionReceipt.js' +import { createPublicClient } from '../../clients/createPublicClient.js' +import { http } from '../../clients/transports/http.js' +import { zkSync } from '../index.js' + +describe('block', () => { + test('formatter', async () => { + const { block } = zkSync.formatters! + + expect( + block.format({ + baseFeePerGas: '0x0', + difficulty: '0x0', + extraData: '0x', + gasLimit: '0xffffffff', + gasUsed: '0xa55c0', + hash: '0xe04cda3bc5633f0e1bff94fc84310da2a0c608192aae0fa0e412c2350c135f75', + l1BatchNumber: '0x1', + l1BatchTimestamp: null, + logsBloom: + '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + miner: '0x0000000000000000000000000000000000000000', + mixHash: + '0x0000000000000000000000000000000000000000000000000000000000000000', + nonce: '0x0000000000000000', + number: '0x1', + parentHash: + '0x0000000000000000000000000000000000000000000000000000000000000000', + receiptsRoot: + '0x0000000000000000000000000000000000000000000000000000000000000000', + sealFields: [], + sha3Uncles: + '0x0000000000000000000000000000000000000000000000000000000000000000', + size: '0x0', + stateRoot: + '0x0000000000000000000000000000000000000000000000000000000000000000', + timestamp: '0x3e9', + totalDifficulty: '0x0', + transactions: [ + '0xf24f67fb9f8fb300164045fe6ba409acb03904e680ec7df41ed2d331dc38f545', + ], + transactionsRoot: + '0x0000000000000000000000000000000000000000000000000000000000000000', + uncles: [], + }), + ).toMatchInlineSnapshot(` + { + "baseFeePerGas": 0n, + "difficulty": 0n, + "extraData": "0x", + "gasLimit": 4294967295n, + "gasUsed": 677312n, + "hash": "0xe04cda3bc5633f0e1bff94fc84310da2a0c608192aae0fa0e412c2350c135f75", + "l1BatchNumber": 1n, + "l1BatchTimestamp": null, + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "miner": "0x0000000000000000000000000000000000000000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "number": 1n, + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "sealFields": [], + "sha3Uncles": "0x0000000000000000000000000000000000000000000000000000000000000000", + "size": 0n, + "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp": 1001n, + "totalDifficulty": 0n, + "transactions": [ + "0xf24f67fb9f8fb300164045fe6ba409acb03904e680ec7df41ed2d331dc38f545", + ], + "transactionsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "uncles": [], + } + `) + + expect( + block.format({ + hash: '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + parentHash: + '0x4adced86c99c6a0db3288bcb1c99ab984f2c51ecf5b9efa243ca029b86ce1476', + sha3Uncles: + '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', + miner: '0x0000000000000000000000000000000000000000', + stateRoot: + '0x0000000000000000000000000000000000000000000000000000000000000000', + transactionsRoot: + '0x0000000000000000000000000000000000000000000000000000000000000000', + receiptsRoot: + '0x0000000000000000000000000000000000000000000000000000000000000000', + number: '0x8acd', + l1BatchNumber: '0x239', + gasUsed: '0x318fd7', + gasLimit: '0xffffffff', + baseFeePerGas: '0xee6b280', + extraData: '0x', + logsBloom: + '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + timestamp: '0x641e1763', + l1BatchTimestamp: '0x641e16e8', + difficulty: '0x0', + totalDifficulty: '0x0', + sealFields: [], + uncles: [], + transactions: [ + { + hash: '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + nonce: '0xf', + blockHash: + '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + blockNumber: '0x8acd', + transactionIndex: '0x0', + from: '0xef9e8e39782b1b544a6eb6db6aa85207bacb4c20', + to: '0x8b791913eb07c32779a16750e3868aa8495f5964', + value: '0x0', + gasPrice: '0xee6b280', + gas: '0x86084b', + input: + '0x0fc87d250000000000000000000000003355df6d4c9c3035724fd0e3914de96a5a83aaf40000000000000000000000003f81edcbd9bc84271fb8fdf270257a18f4d47e9b0000000000000000000000000000000000000000000002b94cc7d236b39b0bff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c2000000000000000000000000000000000000000000000000000000000641e1c0b0000000000000000000000000000000000000000000000000000000000000000', + v: '0x0', + r: '0xfdea6b4ea965cb184257159dfdcbbe6045bf264c0de4d1b76c06821e4c33284', + s: '0x39d0abb813b58d4ebd9c085cc31df866df218803e6a7808f21c3c651e4609981', + type: '0x71', + maxFeePerGas: '0xee6b280', + maxPriorityFeePerGas: '0xee6b280', + chainId: '0x144', + l1BatchNumber: '0x239', + l1BatchTxIndex: '0x154', + }, + ], + size: '0x0', + mixHash: + '0x0000000000000000000000000000000000000000000000000000000000000000', + nonce: '0x0000000000000000', + }), + ).toMatchInlineSnapshot(` + { + "baseFeePerGas": 250000000n, + "difficulty": 0n, + "extraData": "0x", + "gasLimit": 4294967295n, + "gasUsed": 3248087n, + "hash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "l1BatchNumber": 569n, + "l1BatchTimestamp": 1679693544n, + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "miner": "0x0000000000000000000000000000000000000000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "number": 35533n, + "parentHash": "0x4adced86c99c6a0db3288bcb1c99ab984f2c51ecf5b9efa243ca029b86ce1476", + "receiptsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "sealFields": [], + "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "size": 0n, + "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp": 1679693667n, + "totalDifficulty": 0n, + "transactions": [ + { + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "chainId": 324, + "from": "0xef9e8e39782b1b544a6eb6db6aa85207bacb4c20", + "gas": 8783947n, + "gasPrice": 250000000n, + "hash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "input": "0x0fc87d250000000000000000000000003355df6d4c9c3035724fd0e3914de96a5a83aaf40000000000000000000000003f81edcbd9bc84271fb8fdf270257a18f4d47e9b0000000000000000000000000000000000000000000002b94cc7d236b39b0bff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c2000000000000000000000000000000000000000000000000000000000641e1c0b0000000000000000000000000000000000000000000000000000000000000000", + "l1BatchNumber": 569n, + "l1BatchTxIndex": 340n, + "maxFeePerGas": 250000000n, + "maxPriorityFeePerGas": 250000000n, + "nonce": 15, + "r": "0xfdea6b4ea965cb184257159dfdcbbe6045bf264c0de4d1b76c06821e4c33284", + "s": "0x39d0abb813b58d4ebd9c085cc31df866df218803e6a7808f21c3c651e4609981", + "to": "0x8b791913eb07c32779a16750e3868aa8495f5964", + "transactionIndex": 0, + "type": "eip712", + "typeHex": "0x71", + "v": 0n, + "value": 0n, + }, + ], + "transactionsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "uncles": [], + } + `) + }) + + test('action', async () => { + const client = createPublicClient({ + chain: zkSync, + transport: http(), + }) + + const block = await getBlock(client, { + blockNumber: 1n, + includeTransactions: true, + }) + + const { extraData: _extraData, transactions, ...rest } = block + expect(transactions[0]).toMatchInlineSnapshot(` + { + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 1n, + "chainId": 324, + "from": "0x29df43f75149d0552475a6f9b2ac96e28796ed0b", + "gas": 72000000n, + "gasPrice": 0n, + "hash": "0xe9a1a8601bc9199c80c97169fdc9e1fc7c307185a0c9fa2cfab04098a7840645", + "input": "0x3cda33510000000000000000000000000000000000000000000000000000000000000000010000553109a66f1432eb2286c54694784d1b6993bc24a168be0a49b4d0fd4500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "l1BatchNumber": 1n, + "l1BatchTxIndex": 0n, + "maxFeePerGas": 0n, + "maxPriorityFeePerGas": 0n, + "nonce": 0, + "to": "0x0000000000000000000000000000000000008006", + "transactionIndex": 0, + "type": "priority", + "typeHex": "0xff", + "v": undefined, + "value": 0n, + } + `) + expect(rest).toMatchInlineSnapshot(` + { + "baseFeePerGas": 500000000n, + "difficulty": 0n, + "gasLimit": 4294967295n, + "gasUsed": 432000000n, + "hash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "l1BatchNumber": 1n, + "l1BatchTimestamp": 1676384542n, + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "miner": "0x0000000000000000000000000000000000000000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "number": 1n, + "parentHash": "0xe8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244c", + "receiptsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "sealFields": [], + "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "size": 0n, + "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp": 1676384542n, + "totalDifficulty": 0n, + "transactionsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "uncles": [], + } + `) + }) +}) + +describe('transaction', () => { + test('formatter', () => { + const { transaction } = zkSync.formatters! + + expect( + transaction.format({ + blockHash: + '0xf24f67fb9f8fb300164045fe6ba409acb03904e680ec7df41ed2d331dc38f545', + blockNumber: '0x1', + chainId: '0x104', + from: '0x36615cf349d7f6344891b1e7ca7c72883f5dc049', + gas: '0x0', + gasPrice: '0x0', + hash: '0xf24f67fb9f8fb300164045fe6ba409acb03904e680ec7df41ed2d331dc38f545', + input: + '0x02f87582010480840ee6b280840ee6b2808312b84b94a61464658afeaf65cccaafd3a512b69a83b77618880de0b6b3a764000080c080a08ab03d8a1aa4ab231867d9b12a1d7ebacaec3395cf9c4940674f83d79e342e4ca0475dda75d501e72fd816a9699f02af05ef7305668ee4acd0e25561d4628758a3', + l1BatchNumber: '0x1', + maxFeePerGas: '0xee6b280', + maxPriorityFeePerGas: '0xee6b280', + nonce: '0x0', + r: '0x0', + s: '0x0', + to: '0xa61464658afeaf65cccaafd3a512b69a83b77618', + transactionIndex: '0x1', + type: '0x2', + v: '0x104', + value: '0xde0b6b3a7640000', + l1BatchTxIndex: '0x5', + }), + ).toMatchInlineSnapshot(` + { + "blockHash": "0xf24f67fb9f8fb300164045fe6ba409acb03904e680ec7df41ed2d331dc38f545", + "blockNumber": 1n, + "chainId": 260, + "from": "0x36615cf349d7f6344891b1e7ca7c72883f5dc049", + "gas": 0n, + "gasPrice": 0n, + "hash": "0xf24f67fb9f8fb300164045fe6ba409acb03904e680ec7df41ed2d331dc38f545", + "input": "0x02f87582010480840ee6b280840ee6b2808312b84b94a61464658afeaf65cccaafd3a512b69a83b77618880de0b6b3a764000080c080a08ab03d8a1aa4ab231867d9b12a1d7ebacaec3395cf9c4940674f83d79e342e4ca0475dda75d501e72fd816a9699f02af05ef7305668ee4acd0e25561d4628758a3", + "l1BatchNumber": 1n, + "l1BatchTxIndex": 5n, + "maxFeePerGas": 250000000n, + "maxPriorityFeePerGas": 250000000n, + "nonce": 0, + "r": "0x0", + "s": "0x0", + "to": "0xa61464658afeaf65cccaafd3a512b69a83b77618", + "transactionIndex": 1, + "type": "eip1559", + "typeHex": "0x2", + "v": 260n, + "value": 1000000000000000000n, + } + `) + }) + + test('action - Priority', async () => { + const client = createPublicClient({ + chain: zkSync, + transport: http(), + }) + + const transaction = await getTransaction(client, { + blockNumber: 1n, + index: 0, + }) + + expect(transaction).toMatchInlineSnapshot(` + { + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 1n, + "chainId": 324, + "from": "0x29df43f75149d0552475a6f9b2ac96e28796ed0b", + "gas": 72000000n, + "gasPrice": 0n, + "hash": "0xe9a1a8601bc9199c80c97169fdc9e1fc7c307185a0c9fa2cfab04098a7840645", + "input": "0x3cda33510000000000000000000000000000000000000000000000000000000000000000010000553109a66f1432eb2286c54694784d1b6993bc24a168be0a49b4d0fd4500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "l1BatchNumber": 1n, + "l1BatchTxIndex": 0n, + "maxFeePerGas": 0n, + "maxPriorityFeePerGas": 0n, + "nonce": 0, + "to": "0x0000000000000000000000000000000000008006", + "transactionIndex": 0, + "type": "priority", + "typeHex": "0xff", + "v": undefined, + "value": 0n, + } + `) + }) + + test('action - Legacy', async () => { + const client = createPublicClient({ + chain: zkSync, + transport: http(), + }) + + const transaction = await getTransaction(client, { + blockNumber: 150n, + index: 0, + }) + + expect(transaction).toMatchInlineSnapshot(` + { + "blockHash": "0x3e9b219693a0850d24f1739869ccb3a867d521c5adaf53c87706ab810d32bed2", + "blockNumber": 150n, + "chainId": 324, + "from": "0xcd5b610c0b53f63d9edaf0672929ddbfcbf15456", + "gas": 1482241n, + "gasPrice": 250000000n, + "hash": "0x6bc7e6b26858b9aeb5958e3757d755738b0a792b829a4f6fffb72f5d2cb34709", + "input": "0x", + "l1BatchNumber": 26n, + "l1BatchTxIndex": 19n, + "nonce": 49, + "r": "0x324e0198438135fe1a627a7f8844986a23471e71d33217db0621a4b380a0303f", + "s": "0xba25941249fdb7b3948961ca007fed8b898d5f6f75d20564e970fb8ac769ce3", + "to": "0x93235e9c76a90fc5320513d07b6e24293b8fcca8", + "transactionIndex": 0, + "type": "legacy", + "typeHex": "0x0", + "v": 683n, + "value": 1000000000000000n, + } + `) + }) + + test('action - EIP1559', async () => { + const client = createPublicClient({ + chain: zkSync, + transport: http(), + }) + + const transaction = await getTransaction(client, { + blockNumber: 35530n, + index: 0, + }) + + expect(transaction).toMatchInlineSnapshot(` + { + "blockHash": "0x3f95d3889717d263348ef9c8bf11438e102b7f6ac5c09ddf2afa1061506ff095", + "blockNumber": 35530n, + "chainId": 324, + "from": "0x9bbfc28528f65df1d5acaa1d3cc402d30ad7a89c", + "gas": 4500010n, + "gasPrice": 250000000n, + "hash": "0x573bd41a8a4b35cf171107f628851234d7cb83bb18fd47c601823839a3faae03", + "input": "0x7ff36ab500000000000000000000000000000000000000000000000000000000009b2d0400000000000000000000000000000000000000000000000000000000000000800000000000000000000000009bbfc28528f65df1d5acaa1d3cc402d30ad7a89c00000000000000000000000000000000000000000000000000000000641e1c0100000000000000000000000000000000000000000000000000000000000000020000000000000000000000005aea5775959fbc2557cc8789bc1bf90a239d9a910000000000000000000000003355df6d4c9c3035724fd0e3914de96a5a83aaf4", + "l1BatchNumber": 569n, + "l1BatchTxIndex": 331n, + "maxFeePerGas": 250000000n, + "maxPriorityFeePerGas": 250000000n, + "nonce": 3, + "r": "0x74a76f0ec59c3ea5021c81c4f70453c1ae0184ca0fbb8112ac8dfe359d8ed7c6", + "s": "0x162d33d2ab26e232e76928a2229394eaed8c66e6f39f784e3fb276b7438bab9a", + "to": "0xbe7d1fd1f6748bbdefc4fbacafbb11c6fc506d1d", + "transactionIndex": 0, + "type": "eip1559", + "typeHex": "0x2", + "v": 0n, + "value": 6000000000000000n, + } + `) + }) + + test('action - EIP712', async () => { + const client = createPublicClient({ + chain: zkSync, + transport: http(), + }) + + const transaction = await getTransaction(client, { + blockNumber: 35533n, + index: 0, + }) + + expect(transaction).toMatchInlineSnapshot(` + { + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "chainId": 324, + "from": "0xef9e8e39782b1b544a6eb6db6aa85207bacb4c20", + "gas": 8783947n, + "gasPrice": 250000000n, + "hash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "input": "0x0fc87d250000000000000000000000003355df6d4c9c3035724fd0e3914de96a5a83aaf40000000000000000000000003f81edcbd9bc84271fb8fdf270257a18f4d47e9b0000000000000000000000000000000000000000000002b94cc7d236b39b0bff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c2000000000000000000000000000000000000000000000000000000000641e1c0b0000000000000000000000000000000000000000000000000000000000000000", + "l1BatchNumber": 569n, + "l1BatchTxIndex": 340n, + "maxFeePerGas": 250000000n, + "maxPriorityFeePerGas": 250000000n, + "nonce": 15, + "r": "0xfdea6b4ea965cb184257159dfdcbbe6045bf264c0de4d1b76c06821e4c33284", + "s": "0x39d0abb813b58d4ebd9c085cc31df866df218803e6a7808f21c3c651e4609981", + "to": "0x8b791913eb07c32779a16750e3868aa8495f5964", + "transactionIndex": 0, + "type": "eip712", + "typeHex": "0x71", + "v": 0n, + "value": 0n, + } + `) + }) +}) + +describe('transaction receipt', () => { + test('formatter', () => { + const { transactionReceipt } = zkSync.formatters! + + expect( + transactionReceipt.format({ + transactionHash: + '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + transactionIndex: '0x0', + blockHash: + '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + blockNumber: '0x8acd', + l1BatchTxIndex: '0x154', + l1BatchNumber: '0x239', + from: '0xef9e8e39782b1b544a6eb6db6aa85207bacb4c20', + to: '0x8b791913eb07c32779a16750e3868aa8495f5964', + cumulativeGasUsed: '0x0', + gasUsed: '0x318fd7', + contractAddress: null, + logs: [ + { + address: '0x000000000000000000000000000000000000800a', + topics: [ + '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', + '0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20', + '0x0000000000000000000000000000000000000000000000000000000000008001', + ], + data: '0x0000000000000000000000000000000000000000000000000007cd3d022a4b80', + blockHash: + '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + blockNumber: '0x8acd', + l1BatchNumber: '0x239', + transactionHash: + '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + transactionIndex: '0x0', + logIndex: '0x0', + transactionLogIndex: '0x0', + logType: null, + removed: false, + }, + { + address: '0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e', + topics: [ + '0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724', + '0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20', + ], + data: '0x0000000000000000000000000000000000000000000002b94cc7d236b39b0bff0000000000000000000000000000000000000000000000000000000000000000', + blockHash: + '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + blockNumber: '0x8acd', + l1BatchNumber: '0x239', + transactionHash: + '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + transactionIndex: '0x0', + logIndex: '0x1', + transactionLogIndex: '0x1', + logType: null, + removed: false, + }, + { + address: '0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e', + topics: [ + '0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724', + '0x000000000000000000000000e0cdfcec9dcde1ec6b29d38673d3336a3a219c1e', + ], + data: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b94cc7d236b39b0bff', + blockHash: + '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + blockNumber: '0x8acd', + l1BatchNumber: '0x239', + transactionHash: + '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + transactionIndex: '0x0', + logIndex: '0x2', + transactionLogIndex: '0x2', + logType: null, + removed: false, + }, + { + address: '0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e', + topics: [ + '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', + '0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20', + '0x000000000000000000000000e0cdfcec9dcde1ec6b29d38673d3336a3a219c1e', + ], + data: '0x0000000000000000000000000000000000000000000002b94cc7d236b39b0bff', + blockHash: + '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + blockNumber: '0x8acd', + l1BatchNumber: '0x239', + transactionHash: + '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + transactionIndex: '0x0', + logIndex: '0x3', + transactionLogIndex: '0x3', + logType: null, + removed: false, + }, + { + address: '0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e', + topics: [ + '0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724', + '0x000000000000000000000000e0cdfcec9dcde1ec6b29d38673d3336a3a219c1e', + ], + data: '0x0000000000000000000000000000000000000000000002b94cc7d236b39b0bff0000000000000000000000000000000000000000000000000000000000000000', + blockHash: + '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + blockNumber: '0x8acd', + l1BatchNumber: '0x239', + transactionHash: + '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + transactionIndex: '0x0', + logIndex: '0x4', + transactionLogIndex: '0x4', + logType: null, + removed: false, + }, + { + address: '0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e', + topics: [ + '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', + '0x000000000000000000000000e0cdfcec9dcde1ec6b29d38673d3336a3a219c1e', + '0x0000000000000000000000000000000000000000000000000000000000000000', + ], + data: '0x0000000000000000000000000000000000000000000002b94cc7d236b39b0bff', + blockHash: + '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + blockNumber: '0x8acd', + l1BatchNumber: '0x239', + transactionHash: + '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + transactionIndex: '0x0', + logIndex: '0x5', + transactionLogIndex: '0x5', + logType: null, + removed: false, + }, + { + address: '0x3355df6d4c9c3035724fd0e3914de96a5a83aaf4', + topics: [ + '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', + '0x000000000000000000000000e0cdfcec9dcde1ec6b29d38673d3336a3a219c1e', + '0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20', + ], + data: '0x0000000000000000000000000000000000000000000000000000000009f62322', + blockHash: + '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + blockNumber: '0x8acd', + l1BatchNumber: '0x239', + transactionHash: + '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + transactionIndex: '0x0', + logIndex: '0x6', + transactionLogIndex: '0x6', + logType: null, + removed: false, + }, + { + address: '0x3f81edcbd9bc84271fb8fdf270257a18f4d47e9b', + topics: [ + '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', + '0x000000000000000000000000e0cdfcec9dcde1ec6b29d38673d3336a3a219c1e', + '0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20', + ], + data: '0x0000000000000000000000000000000000beaac4bd1b7f557aaca0ff08cfb011', + blockHash: + '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + blockNumber: '0x8acd', + l1BatchNumber: '0x239', + transactionHash: + '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + transactionIndex: '0x0', + logIndex: '0x7', + transactionLogIndex: '0x7', + logType: null, + removed: false, + }, + { + address: '0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e', + topics: [ + '0xcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a', + ], + data: '0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000001116facf7304fef', + blockHash: + '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + blockNumber: '0x8acd', + l1BatchNumber: '0x239', + transactionHash: + '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + transactionIndex: '0x0', + logIndex: '0x8', + transactionLogIndex: '0x8', + logType: null, + removed: false, + }, + { + address: '0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e', + topics: [ + '0xdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496', + '0x0000000000000000000000008b791913eb07c32779a16750e3868aa8495f5964', + '0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20', + ], + data: '0x0000000000000000000000000000000000000000000000000000000009f623220000000000000000000000000000000000beaac4bd1b7f557aaca0ff08cfb011', + blockHash: + '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + blockNumber: '0x8acd', + l1BatchNumber: '0x239', + transactionHash: + '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + transactionIndex: '0x0', + logIndex: '0x9', + transactionLogIndex: '0x9', + logType: null, + removed: false, + }, + { + address: '0x000000000000000000000000000000000000800a', + topics: [ + '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', + '0x0000000000000000000000000000000000000000000000000000000000008001', + '0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20', + ], + data: '0x0000000000000000000000000000000000000000000000000004eab57634e200', + blockHash: + '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + blockNumber: '0x8acd', + l1BatchNumber: '0x239', + transactionHash: + '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', + transactionIndex: '0x0', + logIndex: '0xa', + transactionLogIndex: '0xa', + logType: null, + removed: false, + }, + ], + l2ToL1Logs: [], + status: '0x1', + root: '0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2', + logsBloom: + '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + type: '0x71', + effectiveGasPrice: '0xee6b280', + }), + ).toMatchInlineSnapshot(` + { + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "contractAddress": null, + "cumulativeGasUsed": 0n, + "effectiveGasPrice": 250000000n, + "from": "0xef9e8e39782b1b544a6eb6db6aa85207bacb4c20", + "gasUsed": 3248087n, + "l1BatchNumber": 569n, + "l1BatchTxIndex": 340n, + "l2ToL1Logs": [], + "logs": [ + { + "address": "0x000000000000000000000000000000000000800a", + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "data": "0x0000000000000000000000000000000000000000000000000007cd3d022a4b80", + "l1BatchNumber": 569n, + "logIndex": 0, + "logType": null, + "removed": false, + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20", + "0x0000000000000000000000000000000000000000000000000000000000008001", + ], + "transactionHash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "transactionIndex": 0, + "transactionLogIndex": 0, + }, + { + "address": "0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e", + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "data": "0x0000000000000000000000000000000000000000000002b94cc7d236b39b0bff0000000000000000000000000000000000000000000000000000000000000000", + "l1BatchNumber": 569n, + "logIndex": 1, + "logType": null, + "removed": false, + "topics": [ + "0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724", + "0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20", + ], + "transactionHash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "transactionIndex": 0, + "transactionLogIndex": 1, + }, + { + "address": "0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e", + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b94cc7d236b39b0bff", + "l1BatchNumber": 569n, + "logIndex": 2, + "logType": null, + "removed": false, + "topics": [ + "0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724", + "0x000000000000000000000000e0cdfcec9dcde1ec6b29d38673d3336a3a219c1e", + ], + "transactionHash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "transactionIndex": 0, + "transactionLogIndex": 2, + }, + { + "address": "0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e", + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "data": "0x0000000000000000000000000000000000000000000002b94cc7d236b39b0bff", + "l1BatchNumber": 569n, + "logIndex": 3, + "logType": null, + "removed": false, + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20", + "0x000000000000000000000000e0cdfcec9dcde1ec6b29d38673d3336a3a219c1e", + ], + "transactionHash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "transactionIndex": 0, + "transactionLogIndex": 3, + }, + { + "address": "0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e", + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "data": "0x0000000000000000000000000000000000000000000002b94cc7d236b39b0bff0000000000000000000000000000000000000000000000000000000000000000", + "l1BatchNumber": 569n, + "logIndex": 4, + "logType": null, + "removed": false, + "topics": [ + "0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724", + "0x000000000000000000000000e0cdfcec9dcde1ec6b29d38673d3336a3a219c1e", + ], + "transactionHash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "transactionIndex": 0, + "transactionLogIndex": 4, + }, + { + "address": "0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e", + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "data": "0x0000000000000000000000000000000000000000000002b94cc7d236b39b0bff", + "l1BatchNumber": 569n, + "logIndex": 5, + "logType": null, + "removed": false, + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x000000000000000000000000e0cdfcec9dcde1ec6b29d38673d3336a3a219c1e", + "0x0000000000000000000000000000000000000000000000000000000000000000", + ], + "transactionHash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "transactionIndex": 0, + "transactionLogIndex": 5, + }, + { + "address": "0x3355df6d4c9c3035724fd0e3914de96a5a83aaf4", + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "data": "0x0000000000000000000000000000000000000000000000000000000009f62322", + "l1BatchNumber": 569n, + "logIndex": 6, + "logType": null, + "removed": false, + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x000000000000000000000000e0cdfcec9dcde1ec6b29d38673d3336a3a219c1e", + "0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20", + ], + "transactionHash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "transactionIndex": 0, + "transactionLogIndex": 6, + }, + { + "address": "0x3f81edcbd9bc84271fb8fdf270257a18f4d47e9b", + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "data": "0x0000000000000000000000000000000000beaac4bd1b7f557aaca0ff08cfb011", + "l1BatchNumber": 569n, + "logIndex": 7, + "logType": null, + "removed": false, + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x000000000000000000000000e0cdfcec9dcde1ec6b29d38673d3336a3a219c1e", + "0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20", + ], + "transactionHash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "transactionIndex": 0, + "transactionLogIndex": 7, + }, + { + "address": "0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e", + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "data": "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000001116facf7304fef", + "l1BatchNumber": 569n, + "logIndex": 8, + "logType": null, + "removed": false, + "topics": [ + "0xcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a", + ], + "transactionHash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "transactionIndex": 0, + "transactionLogIndex": 8, + }, + { + "address": "0xe0cdfcec9dcde1ec6b29d38673d3336a3a219c1e", + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "data": "0x0000000000000000000000000000000000000000000000000000000009f623220000000000000000000000000000000000beaac4bd1b7f557aaca0ff08cfb011", + "l1BatchNumber": 569n, + "logIndex": 9, + "logType": null, + "removed": false, + "topics": [ + "0xdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496", + "0x0000000000000000000000008b791913eb07c32779a16750e3868aa8495f5964", + "0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20", + ], + "transactionHash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "transactionIndex": 0, + "transactionLogIndex": 9, + }, + { + "address": "0x000000000000000000000000000000000000800a", + "blockHash": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "blockNumber": 35533n, + "data": "0x0000000000000000000000000000000000000000000000000004eab57634e200", + "l1BatchNumber": 569n, + "logIndex": 10, + "logType": null, + "removed": false, + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000008001", + "0x000000000000000000000000ef9e8e39782b1b544a6eb6db6aa85207bacb4c20", + ], + "transactionHash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "transactionIndex": 0, + "transactionLogIndex": 10, + }, + ], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "root": "0xfd73aaef0e91fcd6c171056b235a2b0f17650dcbe17038d17f76bbf3980c4da2", + "status": "success", + "to": "0x8b791913eb07c32779a16750e3868aa8495f5964", + "transactionHash": "0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6", + "transactionIndex": 0, + "type": "0x71", + } + `) + }) + + test('action', async () => { + const client = createPublicClient({ + chain: zkSync, + transport: http(), + }) + + const transaction = await getTransactionReceipt(client, { + hash: '0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec', + }) + + expect(transaction).toMatchInlineSnapshot(` + { + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 1n, + "contractAddress": "0x11f943b2c77b743ab90f4a0ae7d5a4e7fca3e102", + "cumulativeGasUsed": 0n, + "effectiveGasPrice": 0n, + "from": "0x689a1966931eb4bb6fb81430e6ce0a03aabdf174", + "gasUsed": 72000000n, + "l1BatchNumber": 1n, + "l1BatchTxIndex": 5n, + "l2ToL1Logs": [ + { + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 37075710707809432191796592030900317027155189206620910115769376626082614840703n, + "isService": true, + "key": "0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec", + "l1BatchNumber": 1n, + "logIndex": 6n, + "sender": "0x0000000000000000000000000000000000008001", + "shardId": 0n, + "transactionHash": "0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec", + "transactionIndex": 5n, + "value": "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + "logs": [ + { + "address": "0x11f943b2c77b743ab90f4a0ae7d5a4e7fca3e102", + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 1n, + "data": "0x", + "l1BatchNumber": 1n, + "logIndex": 14, + "logType": null, + "removed": false, + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000006d7a34eb3055549866a227df64e954b142d97430", + ], + "transactionHash": "0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec", + "transactionIndex": 5, + "transactionLogIndex": 14, + }, + { + "address": "0x9c931462ac1bf8b47a727aaad7776405ac894482", + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 1n, + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "l1BatchNumber": 1n, + "logIndex": 15, + "logType": null, + "removed": false, + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498", + ], + "transactionHash": "0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec", + "transactionIndex": 5, + "transactionLogIndex": 15, + }, + { + "address": "0x0000000000000000000000000000000000008006", + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 1n, + "data": "0x", + "l1BatchNumber": 1n, + "logIndex": 16, + "logType": null, + "removed": false, + "topics": [ + "0x290afdae231a3fc0bbae8b1af63698b0a1d79b21ad17df0342dfb952fe74f8e5", + "0x00000000000000000000000011f943b2c77b743ab90f4a0ae7d5a4e7fca3e102", + "0x0100033fd2449be163d507a8801182eb51381e623e8fad17a786ffb51b75d882", + "0x0000000000000000000000009c931462ac1bf8b47a727aaad7776405ac894482", + ], + "transactionHash": "0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec", + "transactionIndex": 5, + "transactionLogIndex": 16, + }, + { + "address": "0x1eb710030273e529a6ad7e1e14d4e601765ba3c6", + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 1n, + "data": "0x", + "l1BatchNumber": 1n, + "logIndex": 17, + "logType": null, + "removed": false, + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000011f943b2c77b743ab90f4a0ae7d5a4e7fca3e102", + ], + "transactionHash": "0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec", + "transactionIndex": 5, + "transactionLogIndex": 17, + }, + { + "address": "0x0000000000000000000000000000000000008006", + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 1n, + "data": "0x", + "l1BatchNumber": 1n, + "logIndex": 18, + "logType": null, + "removed": false, + "topics": [ + "0x290afdae231a3fc0bbae8b1af63698b0a1d79b21ad17df0342dfb952fe74f8e5", + "0x00000000000000000000000011f943b2c77b743ab90f4a0ae7d5a4e7fca3e102", + "0x0100009979ec46148a53897990610eee987ed2b2498649d890a8b8303cc9a719", + "0x0000000000000000000000001eb710030273e529a6ad7e1e14d4e601765ba3c6", + ], + "transactionHash": "0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec", + "transactionIndex": 5, + "transactionLogIndex": 18, + }, + { + "address": "0x1eb710030273e529a6ad7e1e14d4e601765ba3c6", + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 1n, + "data": "0x", + "l1BatchNumber": 1n, + "logIndex": 19, + "logType": null, + "removed": false, + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x00000000000000000000000011f943b2c77b743ab90f4a0ae7d5a4e7fca3e102", + "0x00000000000000000000000029df43f75149d0552475a6f9b2ac96e28796ed0b", + ], + "transactionHash": "0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec", + "transactionIndex": 5, + "transactionLogIndex": 19, + }, + { + "address": "0x11f943b2c77b743ab90f4a0ae7d5a4e7fca3e102", + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 1n, + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "l1BatchNumber": 1n, + "logIndex": 20, + "logType": null, + "removed": false, + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498", + ], + "transactionHash": "0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec", + "transactionIndex": 5, + "transactionLogIndex": 20, + }, + { + "address": "0x11f943b2c77b743ab90f4a0ae7d5a4e7fca3e102", + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 1n, + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029df43f75149d0552475a6f9b2ac96e28796ed0b", + "l1BatchNumber": 1n, + "logIndex": 21, + "logType": null, + "removed": false, + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f", + ], + "transactionHash": "0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec", + "transactionIndex": 5, + "transactionLogIndex": 21, + }, + { + "address": "0x0000000000000000000000000000000000008006", + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 1n, + "data": "0x", + "l1BatchNumber": 1n, + "logIndex": 22, + "logType": null, + "removed": false, + "topics": [ + "0x290afdae231a3fc0bbae8b1af63698b0a1d79b21ad17df0342dfb952fe74f8e5", + "0x000000000000000000000000689a1966931eb4bb6fb81430e6ce0a03aabdf174", + "0x010001731d2166e711848b2386b8da623c20fc3c2e428eadca169a615ddec57a", + "0x00000000000000000000000011f943b2c77b743ab90f4a0ae7d5a4e7fca3e102", + ], + "transactionHash": "0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec", + "transactionIndex": 5, + "transactionLogIndex": 22, + }, + { + "address": "0x000000000000000000000000000000000000800a", + "blockHash": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "blockNumber": 1n, + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "l1BatchNumber": 1n, + "logIndex": 23, + "logType": null, + "removed": false, + "topics": [ + "0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885", + "0x000000000000000000000000c301f8b2a2c08958e6e7a286ab49a986c1f7ef6a", + ], + "transactionHash": "0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec", + "transactionIndex": 5, + "transactionLogIndex": 23, + }, + ], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "root": "0x51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f", + "status": "success", + "to": "0x0000000000000000000000000000000000008006", + "transactionHash": "0xec06ab90e8cbada2b205874567504ceed9e005df452a997472823a8b59cb30ec", + "transactionIndex": 5, + "type": "0xff", + } + `) + }) +}) diff --git a/src/chains/zksync/formatters.ts b/src/chains/zksync/formatters.ts new file mode 100644 index 0000000000..f83509aa8d --- /dev/null +++ b/src/chains/zksync/formatters.ts @@ -0,0 +1,112 @@ +import { type ChainFormatters } from '../../types/chain.js' +import type { Hash } from '../../types/misc.js' +import { hexToBigInt, hexToNumber } from '../../utils/encoding/fromHex.js' +import { defineBlock } from '../../utils/formatters/block.js' +import { formatLog } from '../../utils/formatters/log.js' +import { defineTransaction } from '../../utils/formatters/transaction.js' +import { defineTransactionReceipt } from '../../utils/formatters/transactionReceipt.js' +import { defineTransactionRequest } from '../../utils/formatters/transactionRequest.js' +import type { + L2ToL1Log, + Log, + ZkSyncBlockOverrides, + ZkSyncRpcBlockOverrides, + ZkSyncRpcTransaction, + ZkSyncRpcTransactionReceipt, + ZkSyncRpcTransactionRequest, + ZkSyncTransaction, + ZkSyncTransactionReceipt, + ZkSyncTransactionRequest, +} from './types.js' + +export const formattersZkSync = { + block: /*#__PURE__*/ defineBlock({ + format( + args: ZkSyncRpcBlockOverrides & { + transactions: Hash[] | ZkSyncRpcTransaction[] + }, + ): ZkSyncBlockOverrides & { + transactions: Hash[] | ZkSyncTransaction[] + } { + const transactions = args.transactions?.map((transaction) => { + if (typeof transaction === 'string') return transaction + const formatted = formattersZkSync.transaction.format( + transaction as ZkSyncRpcTransaction, + ) as ZkSyncTransaction + if (formatted.typeHex === '0x71') { + formatted.type = 'eip712' + } else if (formatted.typeHex === '0xff') { + formatted.type = 'priority' + } + return formatted + }) as Hash[] | ZkSyncTransaction[] + return { + l1BatchNumber: hexToBigInt(args.l1BatchNumber), + l1BatchTimestamp: args.l1BatchTimestamp + ? hexToBigInt(args.l1BatchTimestamp) + : null, + transactions, + } + }, + }), + transaction: /*#__PURE__*/ defineTransaction({ + format(args: ZkSyncRpcTransaction): ZkSyncTransaction { + const transaction = {} as ZkSyncTransaction + if (args.type === '0x71') { + transaction.type = 'eip712' + } else if (args.type === '0xff') { + transaction.type = 'priority' + } + return { + ...transaction, + l1BatchNumber: args.l1BatchNumber + ? hexToBigInt(args.l1BatchNumber) + : null, + l1BatchTxIndex: args.l1BatchTxIndex + ? hexToBigInt(args.l1BatchTxIndex) + : null, + } as ZkSyncTransaction + }, + }), + transactionReceipt: /*#__PURE__*/ defineTransactionReceipt({ + format(args: ZkSyncRpcTransactionReceipt): ZkSyncTransactionReceipt { + return { + l1BatchNumber: args.l1BatchNumber + ? hexToBigInt(args.l1BatchNumber) + : null, + l1BatchTxIndex: args.l1BatchTxIndex + ? hexToBigInt(args.l1BatchTxIndex) + : null, + logs: args.logs.map((log) => { + return { + ...formatLog(log), + l1BatchNumber: hexToBigInt(log.l1BatchNumber), + transactionLogIndex: hexToNumber(log.transactionLogIndex), + } + }) as Log[], + l2ToL1Logs: args.l2ToL1Logs.map((l2ToL1Log) => { + return { + blockNumber: hexToBigInt(l2ToL1Log.blockHash), + blockHash: l2ToL1Log.blockHash, + l1BatchNumber: hexToBigInt(l2ToL1Log.l1BatchNumber), + transactionIndex: hexToBigInt(l2ToL1Log.transactionIndex), + shardId: hexToBigInt(l2ToL1Log.shardId), + isService: l2ToL1Log.isService, + sender: l2ToL1Log.sender, + key: l2ToL1Log.key, + value: l2ToL1Log.value, + transactionHash: l2ToL1Log.transactionHash, + logIndex: hexToBigInt(l2ToL1Log.logIndex), + } + }) as L2ToL1Log[], + } as ZkSyncTransactionReceipt + }, + }), + transactionRequest: /*#__PURE__*/ defineTransactionRequest({ + format(args: ZkSyncTransactionRequest): ZkSyncRpcTransactionRequest { + const request = {} as ZkSyncRpcTransactionRequest + if (args.type === 'eip712') request.type = '0x71' + return request + }, + }), +} as const satisfies ChainFormatters diff --git a/src/chains/zksync/types.ts b/src/chains/zksync/types.ts new file mode 100644 index 0000000000..76d17c4815 --- /dev/null +++ b/src/chains/zksync/types.ts @@ -0,0 +1,264 @@ +import type { Address } from 'abitype' +import type { Block, BlockTag } from '../../types/block.js' +import type { FeeValuesEIP1559 } from '../../types/fee.js' +import type { Log as Log_ } from '../../types/log.js' +import type { Hex } from '../../types/misc.js' +import type { + Index, + Quantity, + RpcBlock, + RpcLog as RpcLog_, + RpcTransaction as RpcTransaction_, + RpcTransactionReceipt, + RpcTransactionRequest, + TransactionType, +} from '../../types/rpc.js' +import type { + Transaction as Transaction_, + TransactionBase, + TransactionReceipt, + TransactionRequest as TransactionRequest_, + TransactionRequestBase, +} from '../../types/transaction.js' +import type { UnionOmit } from '../../types/utils.js' + +import type { Abi, AbiEvent } from 'abitype' + +// Types +// https://era.zksync.io/docs/api/js/types.html + +export type Log< + TQuantity = bigint, + TIndex = number, + TPending extends boolean = boolean, + TAbiEvent extends AbiEvent | undefined = undefined, + TStrict extends boolean | undefined = undefined, + TAbi extends Abi | readonly unknown[] | undefined = TAbiEvent extends AbiEvent + ? [TAbiEvent] + : undefined, + TEventName extends string | undefined = TAbiEvent extends AbiEvent + ? TAbiEvent['name'] + : undefined, +> = Log_ & { + l1BatchNumber: TQuantity + transactionLogIndex: TIndex + logType: Hex | null +} + +export type RpcLog = RpcLog_ & { + l1BatchNumber: Hex + // These are returned but doesn't apear in Log structure neither is mentioned in https://era.zksync.io/docs/api/js/types.html + transactionLogIndex: Hex + logType: Hex | null +} + +export type L2ToL1Log = { + blockNumber: bigint + blockHash: string + l1BatchNumber: bigint + transactionIndex: bigint + shardId: bigint + isService: boolean + sender: string + key: string + value: string + transactionHash: string + logIndex: bigint +} + +export type RpcL2ToL1Log = { + blockNumber: Hex + blockHash: Hex + l1BatchNumber: Hex + transactionIndex: Hex + shardId: Hex + isService: boolean + sender: Hex + key: Hex + value: Hex + transactionHash: Hex + logIndex: Hex +} + +export type ZkSyncFeeValues = { + gasPrice: TQuantity + maxFeePerGas: TQuantity + maxPriorityFeePerGas: TQuantity +} + +// Block +// https://era.zksync.io/docs/api/js/types.html#block + +export type ZkSyncBlockOverrides = { + l1BatchNumber: bigint + l1BatchTimestamp: bigint | null +} + +export type ZkSyncRpcBlockOverrides = { + l1BatchNumber: Hex + l1BatchTimestamp: Hex | null +} +export type ZkSyncRpcBlock< + TBlockTag extends BlockTag = BlockTag, + TIncludeTransactions extends boolean = boolean, +> = RpcBlock< + TBlockTag, + TIncludeTransactions, + ZkSyncRpcTransaction +> & + ZkSyncRpcBlockOverrides + +export type ZkSyncBlock< + TIncludeTransactions extends boolean = boolean, + TBlockTag extends BlockTag = BlockTag, +> = Block< + bigint, + TIncludeTransactions, + TBlockTag, + ZkSyncTransaction +> & + ZkSyncBlockOverrides + +// +// Transaction +// +type TransactionOverrides = { + l1BatchNumber: bigint | null + l1BatchTxIndex: bigint | null +} + +type TransactionPriority = TransactionBase< + bigint, + number, + TPending +> & + TransactionOverrides & + FeeValuesEIP1559 & { + type: 'priority' + } + +type TransactionEIP712 = TransactionBase< + bigint, + number, + TPending +> & + TransactionOverrides & + FeeValuesEIP1559 & { + type: 'eip712' + } + +type Transaction = Transaction_< + bigint, + number, + TPending +> & + TransactionOverrides + +export type ZkSyncTransaction = + | Transaction + | TransactionPriority + | TransactionEIP712 + +// RPC + +type RpcTransactionOverrides = { + l1BatchNumber: Hex | null + l1BatchTxIndex: Hex | null +} + +export type RpcTransaction = + RpcTransaction_ & + Partial> & + RpcTransactionOverrides + +export type RpcTransactionLegacy = + TransactionBase & + ZkSyncFeeValues & + RpcTransactionOverrides & { + type: '0x0' + } + +export type RpcTransactionEIP1559 = + TransactionBase & + ZkSyncFeeValues & + RpcTransactionOverrides & { + type: '0x2' + } + +export type RpcTransactionPriority = + TransactionBase & + ZkSyncFeeValues & + RpcTransactionOverrides & { + type: '0xff' + } + +export type RpcTransactionEIP712 = + TransactionBase & + ZkSyncFeeValues & + RpcTransactionOverrides & { + type: '0x71' + } + +export type ZkSyncRpcTransaction = + UnionOmit< + | RpcTransaction + | RpcTransactionLegacy + | RpcTransactionEIP1559 + | RpcTransactionPriority + | RpcTransactionEIP712, + 'typeHex' + > & { chainId: Hex } + +// Transaction Request +// https://era.zksync.io/docs/reference/concepts/transactions.html + +export type TransactionRequestEIP712 = TransactionRequestBase & + Partial & { + gasPerPubdata?: bigint + customSignature: Hex + paymaster?: Address + paymasterInput?: Hex + factoryDeps?: Hex[] + type?: 'eip712' + } + +type TransactionRequest = TransactionRequest_ & {} + +export type ZkSyncTransactionRequest = + | TransactionRequest + | TransactionRequestEIP712 + +type RpcTransactionRequestEIP712 = TransactionRequestBase & + Partial> & { + type?: '0x71' + } + +export type ZkSyncRpcTransactionRequest = + | RpcTransactionRequest + | RpcTransactionRequestEIP712 + +export type ZkSyncTransactionType = TransactionType | 'eip712' | 'priority' + +// Transaction Receipt +// https://era.zksync.io/docs/api/js/types.html#transactionreceipt + +export type ZkSyncRpcTransactionReceiptOverrides = { + l1BatchNumber: Hex | null + l1BatchTxIndex: Hex | null + logs: RpcLog[] + l2ToL1Logs: RpcL2ToL1Log[] + // Why root isn't added into RpcTransactionReceipt? + root: Hex +} + +export type ZkSyncRpcTransactionReceipt = Omit & + ZkSyncRpcTransactionReceiptOverrides + +export type ZkSyncTransactionReceiptOverrides = { + l1BatchNumber: bigint | null + l1BatchTxIndex: bigint | null + logs: Log[] + l2ToL1Logs: L2ToL1Log[] +} +export type ZkSyncTransactionReceipt = Omit & + ZkSyncTransactionReceiptOverrides From 7cec75e4b909c5fcd964620a9f6fd42275436355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Magalh=C3=A3es?= Date: Tue, 24 Oct 2023 19:31:07 +0100 Subject: [PATCH 02/13] Update formatters and types --- src/chains/package.json | 6 +- src/chains/utils/index.ts | 2 +- src/chains/zksync/formatters.test-d.ts | 223 ++++++++++++++++--------- src/chains/zksync/formatters.ts | 49 +++++- src/chains/zksync/types.ts | 89 +++++++--- src/utils/formatters/extract.ts | 4 +- src/utils/formatters/formatter.ts | 2 +- 7 files changed, 254 insertions(+), 121 deletions(-) diff --git a/src/chains/package.json b/src/chains/package.json index 98d45778d8..92a465994d 100644 --- a/src/chains/package.json +++ b/src/chains/package.json @@ -1,4 +1,6 @@ { - "name": "viem_zksync_chains1", - "type": "module" + "type": "module", + "types": "../_types/chains/index.d.ts", + "module": "../_esm/chains/index.js", + "main": "../_cjs/chains/index.js" } diff --git a/src/chains/utils/index.ts b/src/chains/utils/index.ts index 24d12dd6bd..3cfbfe52ba 100644 --- a/src/chains/utils/index.ts +++ b/src/chains/utils/index.ts @@ -46,6 +46,7 @@ export type { export { formattersZkSync } from '../zksync/formatters.js' export type { + TransactionEIP712, ZkSyncBlock, ZkSyncBlockOverrides, ZkSyncRpcTransaction, @@ -56,5 +57,4 @@ export type { ZkSyncTransactionReceipt, ZkSyncTransactionReceiptOverrides, ZkSyncTransactionRequest, - TransactionRequestEIP712, } from '../zksync/types.js' diff --git a/src/chains/zksync/formatters.test-d.ts b/src/chains/zksync/formatters.test-d.ts index 21f4fceac5..b3a14cb993 100644 --- a/src/chains/zksync/formatters.test-d.ts +++ b/src/chains/zksync/formatters.test-d.ts @@ -1,5 +1,6 @@ import { describe, expectTypeOf, test } from 'vitest' - +import { accounts } from '~test/src/constants.js' +import { privateKeyToAccount } from '../../accounts/privateKeyToAccount.js' import { getBlock } from '../../actions/public/getBlock.js' import { getTransaction } from '../../actions/public/getTransaction.js' import { getTransactionReceipt } from '../../actions/public/getTransactionReceipt.js' @@ -8,21 +9,30 @@ import { signTransaction } from '../../actions/wallet/signTransaction.js' import { createPublicClient } from '../../clients/createPublicClient.js' import { createWalletClient } from '../../clients/createWalletClient.js' import { http } from '../../clients/transports/http.js' +import type { Log } from '../../types/log.js' import type { Hash } from '../../types/misc.js' -import type { RpcBlock } from '../../types/rpc.js' +import type { + RpcBlock, + RpcLog, + RpcTransactionReceipt, +} from '../../types/rpc.js' import type { TransactionRequest } from '../../types/transaction.js' import type { Assign } from '../../types/utils.js' import { sendTransaction } from '../../wallet/index.js' -import { zkSync } from '../index.js' +import { zkSync, zkSyncTestnet } from '../index.js' import { formattersZkSync } from './formatters.js' -import type { ZkSyncRpcTransaction, ZkSyncTransactionRequest } from './types.js' - +import type { + L2ToL1Log, + Log as ZkSyncLog, + ZkSyncRpcTransaction, + ZkSyncTransactionRequest, +} from './types.js' describe('block', () => { expectTypeOf(formattersZkSync.block.format).parameter(0).toEqualTypeOf< Assign< Partial, { - l1BatchNumber: `0x${string}` + l1BatchNumber: `0x${string}` | null l1BatchTimestamp: `0x${string}` | null } & { transactions: `0x${string}`[] | ZkSyncRpcTransaction[] @@ -38,40 +48,36 @@ describe('block', () => { }) describe('transactionReceipt', () => { - // Cannot make this match - /*expectTypeOf(formattersZkSync.transactionReceipt.format) + expectTypeOf(formattersZkSync.transactionReceipt.format) .parameter(0) - .toEqualTypeOf & { - l1BatchNumber: Hex | null - l1BatchTxIndex: Hex | null - logs: { - address: Address - blockHash: Hash - blockNumber: Hex - data: Hex - logIndex:Hex - transactionHash: Hash - transactionIndex: Hex - removed: boolean - l1BatchNumber: Hex - transactionLogIndex: Hex - logType: Hex | null - }[] - l2ToL1Logs: { - blockNumber: Hex - blockHash: Hex - l1BatchNumber: Hex - transactionIndex: Hex - shardId: Hex - isService: boolean - sender: Hex - key: Hex - value: Hex - transactionHash: Hex - logIndex: Hex - }[] - root: Hex - }>()*/ + .toEqualTypeOf< + Assign< + Partial, + { + l1BatchNumber: `0x${string}` | null + l1BatchTxIndex: `0x${string}` | null + logs: (RpcLog & { + l1BatchNumber: `0x${string}` + transactionLogIndex: `0x${string}` + logType: `0x${string}` | null + })[] + l2ToL1Logs: { + blockNumber: `0x${string}` + blockHash: `0x${string}` + l1BatchNumber: `0x${string}` + transactionIndex: `0x${string}` + shardId: `0x${string}` + isService: boolean + sender: `0x${string}` + key: `0x${string}` + value: `0x${string}` + transactionHash: `0x${string}` + logIndex: `0x${string}` + }[] + root: `0x${string}` + } + > + >() expectTypeOf< ReturnType< @@ -83,6 +89,57 @@ describe('transactionReceipt', () => { typeof formattersZkSync.transactionReceipt.format >['l1BatchTxIndex'] >().toEqualTypeOf() + expectTypeOf< + ReturnType['l2ToL1Logs'] + >().toEqualTypeOf< + { + blockNumber: bigint + blockHash: string + l1BatchNumber: bigint + transactionIndex: bigint + shardId: bigint + isService: boolean + sender: string + key: string + value: string + transactionHash: string + logIndex: bigint + }[] + >() + + expectTypeOf< + ReturnType['logs'] + >().toEqualTypeOf< + (Log< + bigint, + number, + boolean, + undefined, + undefined, + undefined, + undefined + > & { + l1BatchNumber: bigint + transactionLogIndex: number + logType: `0x${string}` | null + })[] + >() + + expectTypeOf< + ReturnType< + typeof formattersZkSync.transactionReceipt.format + >['logs'][0]['l1BatchNumber'] + >().toEqualTypeOf() + expectTypeOf< + ReturnType< + typeof formattersZkSync.transactionReceipt.format + >['logs'][0]['transactionLogIndex'] + >().toEqualTypeOf() + expectTypeOf< + ReturnType< + typeof formattersZkSync.transactionReceipt.format + >['logs'][0]['logType'] + >().toEqualTypeOf<`0x${string}` | null>() }) describe('transactionRequest', () => { @@ -91,6 +148,32 @@ describe('transactionRequest', () => { .toEqualTypeOf< Assign, ZkSyncTransactionRequest> >() + expectTypeOf< + ReturnType< + typeof formattersZkSync.transactionRequest.format + >['eip712Meta']['gasPerPubdata'] + >().toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf< + ReturnType< + typeof formattersZkSync.transactionRequest.format + >['eip712Meta']['customSignature'] + >().toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf< + ReturnType< + typeof formattersZkSync.transactionRequest.format + >['eip712Meta']['factoryDeps'] + >().toEqualTypeOf<`0x${string}`[] | undefined>() + expectTypeOf< + ReturnType< + typeof formattersZkSync.transactionRequest.format + >['eip712Meta']['paymasterParams'] + >().toEqualTypeOf< + | { + paymaster: `0x${string}` + paymasterInput: number[] + } + | undefined + >() }) describe('smoke', () => { @@ -134,85 +217,61 @@ describe('smoke', () => { expectTypeOf(transaction.l1BatchTxIndex).toEqualTypeOf() expectTypeOf(transaction.l1BatchNumber).toEqualTypeOf() - expectTypeOf(transaction.logs[0].l1BatchNumber).toEqualTypeOf() - expectTypeOf(transaction.l2ToL1Logs).toEqualTypeOf< - { - blockNumber: bigint - blockHash: string - l1BatchNumber: bigint - transactionIndex: bigint - shardId: bigint - isService: boolean - sender: string - key: string - value: string - transactionHash: string - logIndex: bigint - }[] - >() + expectTypeOf(transaction.l2ToL1Logs).toEqualTypeOf() + expectTypeOf(transaction.logs).toEqualTypeOf() }) test('transactionRequest (prepareTransactionRequest)', async () => { const client = createWalletClient({ - account: '0x', - chain: zkSync, + account: privateKeyToAccount(accounts[0].privateKey), + chain: zkSyncTestnet, transport: http(), }) prepareTransactionRequest(client, { + to: '0x111C3E89Ce80e62EE88318C2804920D4c96f92bb', + data: '0xa4136862000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000094869204461766964340000000000000000000000000000000000000000000000', gasPerPubdata: 50000n, - paymaster: '0x094499df5ee555ffc33af07862e43c90e6fee501', + paymaster: '0xFD9aE5ebB0F6656f4b77a0E99dCbc5138d54b0BA', paymasterInput: '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', - customSignature: '0x', - }) - - // @ts-expect-error `customSignature` not provided - prepareTransactionRequest(client, { - paymaster: '0x094499df5ee555ffc33af07862e43c90e6fee501', - paymasterInput: - '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', - type: 'eip712', }) }) test('transactionRequest (sendTransaction)', async () => { const client = createWalletClient({ - account: '0x094499df5ee555ffc33af07862e43c90e6fee501', - chain: zkSync, + account: privateKeyToAccount(accounts[0].privateKey), + chain: zkSyncTestnet, transport: http(), }) sendTransaction(client, { + to: '0x111C3E89Ce80e62EE88318C2804920D4c96f92bb', + maxFeePerGas: 0n, gasPerPubdata: 50000n, - paymaster: '0x094499df5ee555ffc33af07862e43c90e6fee501', - paymasterInput: - '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', - customSignature: '0x', - }) - - // @ts-expect-error `customSignature` not provided - sendTransaction(client, { - paymaster: '0x094499df5ee555ffc33af07862e43c90e6fee501', + paymaster: '0xFD9aE5ebB0F6656f4b77a0E99dCbc5138d54b0BA', paymasterInput: '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', - type: 'eip712', }) }) test('transactionRequest (signTransaction)', async () => { const client = createWalletClient({ - account: '0x094499df5ee555ffc33af07862e43c90e6fee501', + account: privateKeyToAccount(accounts[0].privateKey), chain: zkSync, transport: http(), }) signTransaction(client, { gasPerPubdata: 50000n, - paymaster: '0x094499df5ee555ffc33af07862e43c90e6fee501', + maxFeePerGas: 250000000n, + maxPriorityFeePerGas: 0n, + to: '0x111C3E89Ce80e62EE88318C2804920D4c96f92bb', + data: '0xa4136862000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000094869204461766964340000000000000000000000000000000000000000000000', + paymaster: '0x4B5DF730c2e6b28E17013A1485E5d9BC41Efe021', paymasterInput: '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', - customSignature: '0x', + customSignature: '0x1', }) }) }) diff --git a/src/chains/zksync/formatters.ts b/src/chains/zksync/formatters.ts index f83509aa8d..e604231e0b 100644 --- a/src/chains/zksync/formatters.ts +++ b/src/chains/zksync/formatters.ts @@ -1,6 +1,8 @@ import { type ChainFormatters } from '../../types/chain.js' import type { Hash } from '../../types/misc.js' import { hexToBigInt, hexToNumber } from '../../utils/encoding/fromHex.js' +import { hexToBytes } from '../../utils/encoding/toBytes.js' +import { toHex } from '../../utils/encoding/toHex.js' import { defineBlock } from '../../utils/formatters/block.js' import { formatLog } from '../../utils/formatters/log.js' import { defineTransaction } from '../../utils/formatters/transaction.js' @@ -12,10 +14,12 @@ import type { ZkSyncBlockOverrides, ZkSyncRpcBlockOverrides, ZkSyncRpcTransaction, - ZkSyncRpcTransactionReceipt, + //ZkSyncRpcTransactionReceipt, + ZkSyncRpcTransactionReceiptOverrides, ZkSyncRpcTransactionRequest, ZkSyncTransaction, ZkSyncTransactionReceipt, + ZkSyncTransactionReceiptOverrides, ZkSyncTransactionRequest, } from './types.js' @@ -41,7 +45,9 @@ export const formattersZkSync = { return formatted }) as Hash[] | ZkSyncTransaction[] return { - l1BatchNumber: hexToBigInt(args.l1BatchNumber), + l1BatchNumber: args.l1BatchNumber + ? hexToBigInt(args.l1BatchNumber) + : null, l1BatchTimestamp: args.l1BatchTimestamp ? hexToBigInt(args.l1BatchTimestamp) : null, @@ -69,7 +75,9 @@ export const formattersZkSync = { }, }), transactionReceipt: /*#__PURE__*/ defineTransactionReceipt({ - format(args: ZkSyncRpcTransactionReceipt): ZkSyncTransactionReceipt { + format( + args: ZkSyncRpcTransactionReceiptOverrides, + ): ZkSyncTransactionReceiptOverrides { return { l1BatchNumber: args.l1BatchNumber ? hexToBigInt(args.l1BatchNumber) @@ -82,6 +90,7 @@ export const formattersZkSync = { ...formatLog(log), l1BatchNumber: hexToBigInt(log.l1BatchNumber), transactionLogIndex: hexToNumber(log.transactionLogIndex), + logType: log.logType, } }) as Log[], l2ToL1Logs: args.l2ToL1Logs.map((l2ToL1Log) => { @@ -103,10 +112,38 @@ export const formattersZkSync = { }, }), transactionRequest: /*#__PURE__*/ defineTransactionRequest({ + exclude: [ + 'paymaster', + 'paymasterInput', + 'customSignature', + 'gasPerPubdata', + 'factoryDeps', + ], format(args: ZkSyncTransactionRequest): ZkSyncRpcTransactionRequest { - const request = {} as ZkSyncRpcTransactionRequest - if (args.type === 'eip712') request.type = '0x71' - return request + // eip712Meta is optional, to still support other transactions + if (args.paymaster && args.paymasterInput && args.gasPerPubdata) { + const request = { + eip712Meta: { + ...(args.factoryDeps ? { factoryDeps: args.factoryDeps } : {}), + ...(args.paymaster && args.paymasterInput + ? { + paymasterParams: { + paymaster: args.paymaster, + paymasterInput: hexToBytes(args.paymasterInput), + }, + } + : {}), + ...(args.gasPerPubdata + ? { gasPerPubdata: toHex(args.gasPerPubdata) } + : {}), + }, + type: '0x71', + } as ZkSyncRpcTransactionRequest + + return request + } + + return {} as ZkSyncRpcTransactionRequest }, }), } as const satisfies ChainFormatters diff --git a/src/chains/zksync/types.ts b/src/chains/zksync/types.ts index 76d17c4815..94b52d039d 100644 --- a/src/chains/zksync/types.ts +++ b/src/chains/zksync/types.ts @@ -10,15 +10,17 @@ import type { RpcLog as RpcLog_, RpcTransaction as RpcTransaction_, RpcTransactionReceipt, - RpcTransactionRequest, TransactionType, } from '../../types/rpc.js' import type { Transaction as Transaction_, TransactionBase, TransactionReceipt, - TransactionRequest as TransactionRequest_, + TransactionRequest, TransactionRequestBase, + TransactionSerializable, + TransactionSerializableBase, + TransactionSerialized, } from '../../types/transaction.js' import type { UnionOmit } from '../../types/utils.js' @@ -52,6 +54,19 @@ export type RpcLog = RpcLog_ & { logType: Hex | null } +// User to get gas estimate +type PaymasterParams = { + paymaster: Address + paymasterInput: number[] +} + +export type Eip712Meta = { + gasPerPubdata?: Hex + factoryDeps?: Hex[] + customSignature?: Hex + paymasterParams?: PaymasterParams +} + export type L2ToL1Log = { blockNumber: bigint blockHash: string @@ -90,12 +105,12 @@ export type ZkSyncFeeValues = { // https://era.zksync.io/docs/api/js/types.html#block export type ZkSyncBlockOverrides = { - l1BatchNumber: bigint + l1BatchNumber: bigint | null l1BatchTimestamp: bigint | null } export type ZkSyncRpcBlockOverrides = { - l1BatchNumber: Hex + l1BatchNumber: Hex | null l1BatchTimestamp: Hex | null } export type ZkSyncRpcBlock< @@ -119,9 +134,8 @@ export type ZkSyncBlock< > & ZkSyncBlockOverrides -// // Transaction -// + type TransactionOverrides = { l1BatchNumber: bigint | null l1BatchTxIndex: bigint | null @@ -137,15 +151,12 @@ type TransactionPriority = TransactionBase< type: 'priority' } -type TransactionEIP712 = TransactionBase< - bigint, - number, - TPending -> & - TransactionOverrides & - FeeValuesEIP1559 & { - type: 'eip712' - } +export type TransactionEIP712 = + TransactionBase & + TransactionOverrides & + FeeValuesEIP1559 & { + type: 'eip712' + } type Transaction = Transaction_< bigint, @@ -212,30 +223,23 @@ export type ZkSyncRpcTransaction = // Transaction Request // https://era.zksync.io/docs/reference/concepts/transactions.html -export type TransactionRequestEIP712 = TransactionRequestBase & +export type ZkSyncTransactionRequest = TransactionRequest & Partial & { - gasPerPubdata?: bigint - customSignature: Hex + gasPerPubdata: bigint + customSignature?: Hex paymaster?: Address paymasterInput?: Hex factoryDeps?: Hex[] type?: 'eip712' } -type TransactionRequest = TransactionRequest_ & {} - -export type ZkSyncTransactionRequest = - | TransactionRequest - | TransactionRequestEIP712 - type RpcTransactionRequestEIP712 = TransactionRequestBase & Partial> & { + eip712Meta: Eip712Meta type?: '0x71' } -export type ZkSyncRpcTransactionRequest = - | RpcTransactionRequest - | RpcTransactionRequestEIP712 +export type ZkSyncRpcTransactionRequest = RpcTransactionRequestEIP712 export type ZkSyncTransactionType = TransactionType | 'eip712' | 'priority' @@ -262,3 +266,34 @@ export type ZkSyncTransactionReceiptOverrides = { } export type ZkSyncTransactionReceipt = Omit & ZkSyncTransactionReceiptOverrides + +// +// Serializers +// + +export type ZkSyncTransactionSerializable = + | TransactionSerializable + | TransactionSerializableEIP712 + +export type ZkSyncTransactionSerialized< + TType extends ZkSyncTransactionType = 'eip1559', +> = TransactionSerialized | TransactionSerializedEIP712 + +export type TransactionSerializableEIP712< + TQuantity = bigint, + TIndex = number, +> = TransactionSerializableBase & + FeeValuesEIP1559 & { + from: Hex + maxFeePerGas?: TQuantity + maxPriorityFeePerGas?: TQuantity + gasPerPubdata?: bigint + paymaster?: Address + factoryDeps?: Hex[] + paymasterInput?: Hex + customSignature: Hex + chainId: number + type?: 'eip712' + } + +export type TransactionSerializedEIP712 = `0x71${string}` diff --git a/src/utils/formatters/extract.ts b/src/utils/formatters/extract.ts index 1533d1a5a8..3b6cb257a7 100644 --- a/src/utils/formatters/extract.ts +++ b/src/utils/formatters/extract.ts @@ -4,14 +4,14 @@ import type { ChainFormatter } from '../../types/chain.js' export type ExtractErrorType = ErrorType /** - * @description Picks out the keys from `value` that exist in the formatter. + * @description Picks out the keys from `value`. */ export function extract( value: Record, { format }: { format?: ChainFormatter['format'] }, ) { if (!format) return {} - const keys = Object.keys(format({})) + const keys = Object.keys(value) return keys.reduce((data: Record, key) => { // biome-ignore lint/suspicious/noPrototypeBuiltins: if (value?.hasOwnProperty(key)) { diff --git a/src/utils/formatters/formatter.ts b/src/utils/formatters/formatter.ts index 365b803e99..d3d84d1fc7 100644 --- a/src/utils/formatters/formatter.ts +++ b/src/utils/formatters/formatter.ts @@ -10,7 +10,7 @@ export function defineFormatter( return < TOverrideParameters, TOverrideReturnType, - TExclude extends (keyof TParameters)[] = [], + TExclude extends (keyof (TParameters & TOverrideParameters))[] = [], >({ exclude, format: overrides, From 29ba2db156ed57f061db494a49ca547bfbe56997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Magalh=C3=A3es?= Date: Tue, 24 Oct 2023 20:07:03 +0100 Subject: [PATCH 03/13] Remove serializer code --- src/chains/zksync/types.ts | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/src/chains/zksync/types.ts b/src/chains/zksync/types.ts index 94b52d039d..b351cb3045 100644 --- a/src/chains/zksync/types.ts +++ b/src/chains/zksync/types.ts @@ -18,9 +18,6 @@ import type { TransactionReceipt, TransactionRequest, TransactionRequestBase, - TransactionSerializable, - TransactionSerializableBase, - TransactionSerialized, } from '../../types/transaction.js' import type { UnionOmit } from '../../types/utils.js' @@ -266,34 +263,3 @@ export type ZkSyncTransactionReceiptOverrides = { } export type ZkSyncTransactionReceipt = Omit & ZkSyncTransactionReceiptOverrides - -// -// Serializers -// - -export type ZkSyncTransactionSerializable = - | TransactionSerializable - | TransactionSerializableEIP712 - -export type ZkSyncTransactionSerialized< - TType extends ZkSyncTransactionType = 'eip1559', -> = TransactionSerialized | TransactionSerializedEIP712 - -export type TransactionSerializableEIP712< - TQuantity = bigint, - TIndex = number, -> = TransactionSerializableBase & - FeeValuesEIP1559 & { - from: Hex - maxFeePerGas?: TQuantity - maxPriorityFeePerGas?: TQuantity - gasPerPubdata?: bigint - paymaster?: Address - factoryDeps?: Hex[] - paymasterInput?: Hex - customSignature: Hex - chainId: number - type?: 'eip712' - } - -export type TransactionSerializedEIP712 = `0x71${string}` From 3d374a3bb1c148c3a2fa1feb7074205a112928df Mon Sep 17 00:00:00 2001 From: "moxey.eth" Date: Wed, 25 Oct 2023 11:03:13 +1100 Subject: [PATCH 04/13] refactor --- src/actions/public/call.ts | 8 +++---- src/actions/public/estimateGas.ts | 8 +++---- src/actions/test/sendUnsignedTransaction.ts | 8 +++---- src/actions/wallet/sendTransaction.ts | 7 +++--- src/chains/utils/index.test.ts | 2 +- src/utils/formatters/extract.test.ts | 11 +++++++++ src/utils/formatters/extract.ts | 25 +++++++++++++-------- 7 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/actions/public/call.ts b/src/actions/public/call.ts index 4684a848cf..af4a4a9192 100644 --- a/src/actions/public/call.ts +++ b/src/actions/public/call.ts @@ -151,12 +151,12 @@ export async function call( const blockNumberHex = blockNumber ? numberToHex(blockNumber) : undefined const block = blockNumberHex || blockTag - const format = - client.chain?.formatters?.transactionRequest?.format || - formatTransactionRequest + const chainFormat = client.chain?.formatters?.transactionRequest?.format + const format = chainFormat || formatTransactionRequest + const request = format({ // Pick out extra data that might exist on the chain's transaction request type. - ...extract(rest, { format }), + ...extract(rest, { format: chainFormat }), from: account?.address, accessList, data, diff --git a/src/actions/public/estimateGas.ts b/src/actions/public/estimateGas.ts index 19279ab441..42e3705a1f 100644 --- a/src/actions/public/estimateGas.ts +++ b/src/actions/public/estimateGas.ts @@ -136,12 +136,12 @@ export async function estimateGas< assertRequest(args as AssertRequestParameters) - const format = - client.chain?.formatters?.transactionRequest?.format || - formatTransactionRequest + const chainFormat = client.chain?.formatters?.transactionRequest?.format + const format = chainFormat || formatTransactionRequest + const request = format({ // Pick out extra data that might exist on the chain's transaction request type. - ...extract(rest, { format }), + ...extract(rest, { format: chainFormat }), from: account.address, accessList, data, diff --git a/src/actions/test/sendUnsignedTransaction.ts b/src/actions/test/sendUnsignedTransaction.ts index b584ae32e9..88f23d1a99 100644 --- a/src/actions/test/sendUnsignedTransaction.ts +++ b/src/actions/test/sendUnsignedTransaction.ts @@ -69,12 +69,12 @@ export async function sendUnsignedTransaction< ...rest } = args - const format = - client.chain?.formatters?.transactionRequest?.format || - formatTransactionRequest + const chainFormat = client.chain?.formatters?.transactionRequest?.format + const format = chainFormat || formatTransactionRequest + const request = format({ // Pick out extra data that might exist on the chain's transaction request type. - ...extract(rest, { format }), + ...extract(rest, { format: chainFormat }), accessList, data, from, diff --git a/src/actions/wallet/sendTransaction.ts b/src/actions/wallet/sendTransaction.ts index 2404f1936b..6afd6a7000 100644 --- a/src/actions/wallet/sendTransaction.ts +++ b/src/actions/wallet/sendTransaction.ts @@ -200,11 +200,12 @@ export async function sendTransaction< }) } - const format = - chain?.formatters?.transactionRequest?.format || formatTransactionRequest + const chainFormat = client.chain?.formatters?.transactionRequest?.format + const format = chainFormat || formatTransactionRequest + const request = format({ // Pick out extra data that might exist on the chain's transaction request type. - ...extract(rest, { format }), + ...extract(rest, { format: chainFormat }), accessList, data, from: account.address, diff --git a/src/chains/utils/index.test.ts b/src/chains/utils/index.test.ts index 2064b1d3ef..78d25dbf26 100644 --- a/src/chains/utils/index.test.ts +++ b/src/chains/utils/index.test.ts @@ -10,7 +10,7 @@ test('exports', () => { "serializersCelo", "parseTransactionCelo", "formattersOptimism", - "formattersZkSync" + "formattersZkSync", ] `) }) diff --git a/src/utils/formatters/extract.test.ts b/src/utils/formatters/extract.test.ts index 88e38f1dfa..2a3b4e47f4 100644 --- a/src/utils/formatters/extract.test.ts +++ b/src/utils/formatters/extract.test.ts @@ -10,4 +10,15 @@ test('default', () => { extract({ foo: 1, bar: 'wagmi' }, { format: () => ({ baz: null }) }), ).toEqual({}) expect(extract({ foo: 1, bar: 'wagmi' }, { format: undefined })).toEqual({}) + expect( + extract( + { foo: 1, bar: 'wagmi', baz: 'foo' }, + { + format: () => ({ + x: null, + nested: { baz: null, x: { bar: null } }, + }), + }, + ), + ).toEqual({ bar: 'wagmi', baz: 'foo' }) }) diff --git a/src/utils/formatters/extract.ts b/src/utils/formatters/extract.ts index 3b6cb257a7..4b2d9da75d 100644 --- a/src/utils/formatters/extract.ts +++ b/src/utils/formatters/extract.ts @@ -4,19 +4,26 @@ import type { ChainFormatter } from '../../types/chain.js' export type ExtractErrorType = ErrorType /** - * @description Picks out the keys from `value`. + * @description Picks out the keys from `value` that exist in the formatter.. */ export function extract( - value: Record, + value_: Record, { format }: { format?: ChainFormatter['format'] }, ) { if (!format) return {} - const keys = Object.keys(value) - return keys.reduce((data: Record, key) => { - // biome-ignore lint/suspicious/noPrototypeBuiltins: - if (value?.hasOwnProperty(key)) { - data[key] = value[key] + + const value: Record = {} + function extract_(formatted: Record) { + const keys = Object.keys(formatted) + for (const key of keys) { + if (key in value_) value[key] = value_[key] + if (formatted[key] && typeof formatted[key] === 'object') + extract_(formatted[key]) } - return data - }, {}) + } + + const formatted = format(value_ || {}) + extract_(formatted) + + return value } From 1c59acdc4baa5c49d7b1c3b63ba67fa67661bd9b Mon Sep 17 00:00:00 2001 From: "moxey.eth" Date: Wed, 25 Oct 2023 12:21:27 +1100 Subject: [PATCH 05/13] fix --- src/utils/formatters/extract.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/utils/formatters/extract.ts b/src/utils/formatters/extract.ts index 4b2d9da75d..0b3d63fa1a 100644 --- a/src/utils/formatters/extract.ts +++ b/src/utils/formatters/extract.ts @@ -17,7 +17,11 @@ export function extract( const keys = Object.keys(formatted) for (const key of keys) { if (key in value_) value[key] = value_[key] - if (formatted[key] && typeof formatted[key] === 'object') + if ( + formatted[key] && + typeof formatted[key] === 'object' && + !Array.isArray(formatted[key]) + ) extract_(formatted[key]) } } From b09a47f98484272cfa919f3ca98fdb17b6678479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Magalh=C3=A3es?= Date: Wed, 25 Oct 2023 18:52:26 +0100 Subject: [PATCH 06/13] Update types, improve code coverage --- src/chains/utils/index.ts | 1 - src/chains/zksync/formatters.test.ts | 393 ++++++++++++++++++++++++--- src/chains/zksync/formatters.ts | 47 ++-- src/chains/zksync/types.ts | 107 ++++---- 4 files changed, 439 insertions(+), 109 deletions(-) diff --git a/src/chains/utils/index.ts b/src/chains/utils/index.ts index 3cfbfe52ba..d89d0a3f0c 100644 --- a/src/chains/utils/index.ts +++ b/src/chains/utils/index.ts @@ -50,7 +50,6 @@ export type { ZkSyncBlock, ZkSyncBlockOverrides, ZkSyncRpcTransaction, - ZkSyncRpcTransactionReceipt, ZkSyncRpcTransactionReceiptOverrides, ZkSyncRpcTransactionRequest, ZkSyncTransaction, diff --git a/src/chains/zksync/formatters.test.ts b/src/chains/zksync/formatters.test.ts index 1ddc57b1e7..c29c40d079 100644 --- a/src/chains/zksync/formatters.test.ts +++ b/src/chains/zksync/formatters.test.ts @@ -13,65 +13,65 @@ describe('block', () => { expect( block.format({ - baseFeePerGas: '0x0', - difficulty: '0x0', - extraData: '0x', - gasLimit: '0xffffffff', - gasUsed: '0xa55c0', - hash: '0xe04cda3bc5633f0e1bff94fc84310da2a0c608192aae0fa0e412c2350c135f75', - l1BatchNumber: '0x1', - l1BatchTimestamp: null, - logsBloom: - '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + hash: '0x288c26fa1cc1814b638f3010f20d17fc5d1a2667fb5aa1dd6354ad889fa335b4', + parentHash: + '0xb1f996bdcc7c1f1893b016bd47150a846ac1e11f443d23df4cbc7c36fa1d4ae1', + sha3Uncles: + '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', miner: '0x0000000000000000000000000000000000000000', - mixHash: + stateRoot: '0x0000000000000000000000000000000000000000000000000000000000000000', - nonce: '0x0000000000000000', - number: '0x1', - parentHash: + transactionsRoot: '0x0000000000000000000000000000000000000000000000000000000000000000', receiptsRoot: '0x0000000000000000000000000000000000000000000000000000000000000000', - sealFields: [], - sha3Uncles: - '0x0000000000000000000000000000000000000000000000000000000000000000', - size: '0x0', - stateRoot: - '0x0000000000000000000000000000000000000000000000000000000000000000', - timestamp: '0x3e9', + number: '0x232223', + l1BatchNumber: '0x5076', + gasUsed: '0x20d70b', + gasLimit: '0xffffffff', + baseFeePerGas: '0xee6b280', + extraData: '0x', + logsBloom: + '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + timestamp: '0x64495efe', + l1BatchTimestamp: '0x64495ec1', + difficulty: '0x0', totalDifficulty: '0x0', + sealFields: [], + uncles: [], transactions: [ - '0xf24f67fb9f8fb300164045fe6ba409acb03904e680ec7df41ed2d331dc38f545', + '0xae443579604b132e8e8a9a03a09f4ba1c8387190d4feac2f60283a6df564b66c', ], - transactionsRoot: + size: '0x0', + mixHash: '0x0000000000000000000000000000000000000000000000000000000000000000', - uncles: [], + nonce: '0x0000000000000000', }), ).toMatchInlineSnapshot(` { - "baseFeePerGas": 0n, + "baseFeePerGas": 250000000n, "difficulty": 0n, "extraData": "0x", "gasLimit": 4294967295n, - "gasUsed": 677312n, - "hash": "0xe04cda3bc5633f0e1bff94fc84310da2a0c608192aae0fa0e412c2350c135f75", - "l1BatchNumber": 1n, - "l1BatchTimestamp": null, + "gasUsed": 2152203n, + "hash": "0x288c26fa1cc1814b638f3010f20d17fc5d1a2667fb5aa1dd6354ad889fa335b4", + "l1BatchNumber": 20598n, + "l1BatchTimestamp": 1682529985n, "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", - "number": 1n, - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "number": 2302499n, + "parentHash": "0xb1f996bdcc7c1f1893b016bd47150a846ac1e11f443d23df4cbc7c36fa1d4ae1", "receiptsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "sealFields": [], - "sha3Uncles": "0x0000000000000000000000000000000000000000000000000000000000000000", + "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "size": 0n, "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": 1001n, + "timestamp": 1682530046n, "totalDifficulty": 0n, "transactions": [ - "0xf24f67fb9f8fb300164045fe6ba409acb03904e680ec7df41ed2d331dc38f545", + "0xae443579604b132e8e8a9a03a09f4ba1c8387190d4feac2f60283a6df564b66c", ], "transactionsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "uncles": [], @@ -1146,3 +1146,328 @@ describe('transaction receipt', () => { `) }) }) + +describe('transactionRequest', () => { + test('formatter', () => { + const { transactionRequest } = zkSync.formatters! + + const baseRequest = { + from: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9' as `0x${string}`, + gas: 13000n, + nonce: 4, + maxFeePerGas: 2n, + maxPriorityFeePerGas: 1n, + value: 0n, + } + + // Provide all EIP712Meta fields, except customSignature + expect( + transactionRequest.format({ + ...baseRequest, + paymaster: '0x4B5DF730c2e6b28E17013A1485E5d9BC41Efe021', + paymasterInput: + '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', + gasPerPubdata: 50000n, + factoryDeps: ['0x1234', '0xabcd'], + type: 'eip712', + }), + ).toMatchInlineSnapshot(` + { + "eip712Meta": { + "factoryDeps": [ + "0x1234", + "0xabcd", + ], + "gasPerPubdata": "0xc350", + "paymasterParams": { + "paymaster": "0x4B5DF730c2e6b28E17013A1485E5d9BC41Efe021", + "paymasterInput": [ + 140, + 90, + 52, + 69, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + }, + }, + "from": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", + "gas": "0x32c8", + "gasPrice": undefined, + "maxFeePerGas": "0x2", + "maxPriorityFeePerGas": "0x1", + "nonce": "0x4", + "type": "0x71", + "value": "0x0", + } + `) + + // Only factoryDeps defined + expect( + transactionRequest.format({ + ...baseRequest, + factoryDeps: ['0x1234', '0xabcd'], + type: 'eip712', + }), + ).toMatchInlineSnapshot(` + { + "eip712Meta": { + "factoryDeps": [ + "0x1234", + "0xabcd", + ], + }, + "from": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", + "gas": "0x32c8", + "gasPrice": undefined, + "maxFeePerGas": "0x2", + "maxPriorityFeePerGas": "0x1", + "nonce": "0x4", + "type": "0x71", + "value": "0x0", + } + `) + + // Only customSignature defined + expect( + transactionRequest.format({ + ...baseRequest, + customSignature: '0x1234', + type: 'eip712', + }), + ).toMatchInlineSnapshot(` + { + "eip712Meta": { + "customSignature": "0x1234", + }, + "from": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", + "gas": "0x32c8", + "gasPrice": undefined, + "maxFeePerGas": "0x2", + "maxPriorityFeePerGas": "0x1", + "nonce": "0x4", + "type": "0x71", + "value": "0x0", + } + `) + + // Only paymaster and paymasterInput defined + expect( + transactionRequest.format({ + ...baseRequest, + paymaster: '0x4B5DF730c2e6b28E17013A1485E5d9BC41Efe021', + paymasterInput: + '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', + type: 'eip712', + }), + ).toMatchInlineSnapshot(` + { + "eip712Meta": { + "paymasterParams": { + "paymaster": "0x4B5DF730c2e6b28E17013A1485E5d9BC41Efe021", + "paymasterInput": [ + 140, + 90, + 52, + 69, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + }, + }, + "from": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", + "gas": "0x32c8", + "gasPrice": undefined, + "maxFeePerGas": "0x2", + "maxPriorityFeePerGas": "0x1", + "nonce": "0x4", + "type": "0x71", + "value": "0x0", + } + `) + + // Only gasPerPubdata defined + expect( + transactionRequest.format({ + ...baseRequest, + gasPerPubdata: 50000n, + type: 'eip712', + }), + ).toMatchInlineSnapshot(` + { + "eip712Meta": { + "gasPerPubdata": "0xc350", + }, + "from": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", + "gas": "0x32c8", + "gasPrice": undefined, + "maxFeePerGas": "0x2", + "maxPriorityFeePerGas": "0x1", + "nonce": "0x4", + "type": "0x71", + "value": "0x0", + } + `) + + // Only gasPerPubdata defined with type priority + expect( + transactionRequest.format({ + ...baseRequest, + gasPerPubdata: 50000n, + type: 'priority', + }), + ).toMatchInlineSnapshot(` + { + "eip712Meta": { + "gasPerPubdata": "0xc350", + }, + "from": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", + "gas": "0x32c8", + "gasPrice": undefined, + "maxFeePerGas": "0x2", + "maxPriorityFeePerGas": "0x1", + "nonce": "0x4", + "type": "0xff", + "value": "0x0", + } + `) + + // No EIP712 field defined + expect(transactionRequest.format(baseRequest)).toMatchInlineSnapshot(` + { + "from": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", + "gas": "0x32c8", + "gasPrice": undefined, + "maxFeePerGas": "0x2", + "maxPriorityFeePerGas": "0x1", + "nonce": "0x4", + "type": undefined, + "value": "0x0", + } + `) + }) +}) diff --git a/src/chains/zksync/formatters.ts b/src/chains/zksync/formatters.ts index e604231e0b..f99665aa6f 100644 --- a/src/chains/zksync/formatters.ts +++ b/src/chains/zksync/formatters.ts @@ -14,7 +14,6 @@ import type { ZkSyncBlockOverrides, ZkSyncRpcBlockOverrides, ZkSyncRpcTransaction, - //ZkSyncRpcTransactionReceipt, ZkSyncRpcTransactionReceiptOverrides, ZkSyncRpcTransactionRequest, ZkSyncTransaction, @@ -45,12 +44,8 @@ export const formattersZkSync = { return formatted }) as Hash[] | ZkSyncTransaction[] return { - l1BatchNumber: args.l1BatchNumber - ? hexToBigInt(args.l1BatchNumber) - : null, - l1BatchTimestamp: args.l1BatchTimestamp - ? hexToBigInt(args.l1BatchTimestamp) - : null, + l1BatchNumber: hexToBigInt(args.l1BatchNumber), + l1BatchTimestamp: hexToBigInt(args.l1BatchTimestamp), transactions, } }, @@ -65,12 +60,8 @@ export const formattersZkSync = { } return { ...transaction, - l1BatchNumber: args.l1BatchNumber - ? hexToBigInt(args.l1BatchNumber) - : null, - l1BatchTxIndex: args.l1BatchTxIndex - ? hexToBigInt(args.l1BatchTxIndex) - : null, + l1BatchNumber: hexToBigInt(args.l1BatchNumber), + l1BatchTxIndex: hexToBigInt(args.l1BatchTxIndex), } as ZkSyncTransaction }, }), @@ -79,12 +70,8 @@ export const formattersZkSync = { args: ZkSyncRpcTransactionReceiptOverrides, ): ZkSyncTransactionReceiptOverrides { return { - l1BatchNumber: args.l1BatchNumber - ? hexToBigInt(args.l1BatchNumber) - : null, - l1BatchTxIndex: args.l1BatchTxIndex - ? hexToBigInt(args.l1BatchTxIndex) - : null, + l1BatchNumber: hexToBigInt(args.l1BatchNumber), + l1BatchTxIndex: hexToBigInt(args.l1BatchTxIndex), logs: args.logs.map((log) => { return { ...formatLog(log), @@ -120,24 +107,32 @@ export const formattersZkSync = { 'factoryDeps', ], format(args: ZkSyncTransactionRequest): ZkSyncRpcTransactionRequest { - // eip712Meta is optional, to still support other transactions - if (args.paymaster && args.paymasterInput && args.gasPerPubdata) { + if ( + (args.type === 'eip712' || args.type === 'priority') && + (args.gasPerPubdata || + (args.paymaster && args.paymasterInput) || + args.factoryDeps || + args.customSignature) + ) { const request = { eip712Meta: { - ...(args.factoryDeps ? { factoryDeps: args.factoryDeps } : {}), + ...(args.gasPerPubdata + ? { gasPerPubdata: toHex(args.gasPerPubdata) } + : {}), ...(args.paymaster && args.paymasterInput ? { paymasterParams: { paymaster: args.paymaster, - paymasterInput: hexToBytes(args.paymasterInput), + paymasterInput: Array.from(hexToBytes(args.paymasterInput)), }, } : {}), - ...(args.gasPerPubdata - ? { gasPerPubdata: toHex(args.gasPerPubdata) } + ...(args.factoryDeps ? { factoryDeps: args.factoryDeps } : {}), + ...(args.customSignature + ? { customSignature: args.customSignature } : {}), }, - type: '0x71', + type: args.type === 'eip712' ? '0x71' : '0xff', } as ZkSyncRpcTransactionRequest return request diff --git a/src/chains/zksync/types.ts b/src/chains/zksync/types.ts index b351cb3045..6824c0a839 100644 --- a/src/chains/zksync/types.ts +++ b/src/chains/zksync/types.ts @@ -8,13 +8,14 @@ import type { Quantity, RpcBlock, RpcLog as RpcLog_, - RpcTransaction as RpcTransaction_, - RpcTransactionReceipt, + RpcTransactionRequest, TransactionType, } from '../../types/rpc.js' import type { Transaction as Transaction_, TransactionBase, + TransactionEIP2930, + TransactionLegacy, TransactionReceipt, TransactionRequest, TransactionRequestBase, @@ -51,7 +52,6 @@ export type RpcLog = RpcLog_ & { logType: Hex | null } -// User to get gas estimate type PaymasterParams = { paymaster: Address paymasterInput: number[] @@ -98,6 +98,9 @@ export type ZkSyncFeeValues = { maxPriorityFeePerGas: TQuantity } +type EIP712Type = '0x71' +type PriorityType = '0xff' + // Block // https://era.zksync.io/docs/api/js/types.html#block @@ -106,9 +109,22 @@ export type ZkSyncBlockOverrides = { l1BatchTimestamp: bigint | null } +export type ZkSyncBlock< + TIncludeTransactions extends boolean = boolean, + TBlockTag extends BlockTag = BlockTag, +> = Block< + bigint, + TIncludeTransactions, + TBlockTag, + ZkSyncTransaction +> & + ZkSyncBlockOverrides + +// Block (RPC) + export type ZkSyncRpcBlockOverrides = { - l1BatchNumber: Hex | null - l1BatchTimestamp: Hex | null + l1BatchNumber: Hex + l1BatchTimestamp: Hex } export type ZkSyncRpcBlock< TBlockTag extends BlockTag = BlockTag, @@ -120,22 +136,12 @@ export type ZkSyncRpcBlock< > & ZkSyncRpcBlockOverrides -export type ZkSyncBlock< - TIncludeTransactions extends boolean = boolean, - TBlockTag extends BlockTag = BlockTag, -> = Block< - bigint, - TIncludeTransactions, - TBlockTag, - ZkSyncTransaction -> & - ZkSyncBlockOverrides - // Transaction +// https://era.zksync.io/docs/api/js/types.html#transactionresponse type TransactionOverrides = { - l1BatchNumber: bigint | null - l1BatchTxIndex: bigint | null + l1BatchNumber: bigint + l1BatchTxIndex: bigint } type TransactionPriority = TransactionBase< @@ -152,7 +158,7 @@ export type TransactionEIP712 = TransactionBase & TransactionOverrides & FeeValuesEIP1559 & { - type: 'eip712' + type: 'eip712' | 'priority' } type Transaction = Transaction_< @@ -167,25 +173,20 @@ export type ZkSyncTransaction = | TransactionPriority | TransactionEIP712 -// RPC +// Transaction (RPC) type RpcTransactionOverrides = { - l1BatchNumber: Hex | null - l1BatchTxIndex: Hex | null + l1BatchNumber: Hex + l1BatchTxIndex: Hex } -export type RpcTransaction = - RpcTransaction_ & - Partial> & - RpcTransactionOverrides - export type RpcTransactionLegacy = - TransactionBase & - ZkSyncFeeValues & - RpcTransactionOverrides & { - type: '0x0' - } + TransactionLegacy & RpcTransactionOverrides +export type RpcTransactionEIP2930 = + TransactionEIP2930 & RpcTransactionOverrides + +// Cannot use default EIP1559 transaction because the fee `gasPrice` parameter is set to `never` export type RpcTransactionEIP1559 = TransactionBase & ZkSyncFeeValues & @@ -197,46 +198,59 @@ export type RpcTransactionPriority = TransactionBase & ZkSyncFeeValues & RpcTransactionOverrides & { - type: '0xff' + type: PriorityType } export type RpcTransactionEIP712 = TransactionBase & ZkSyncFeeValues & RpcTransactionOverrides & { - type: '0x71' + type: EIP712Type } export type ZkSyncRpcTransaction = UnionOmit< - | RpcTransaction | RpcTransactionLegacy + | RpcTransactionEIP2930 | RpcTransactionEIP1559 | RpcTransactionPriority | RpcTransactionEIP712, 'typeHex' - > & { chainId: Hex } + > // Transaction Request // https://era.zksync.io/docs/reference/concepts/transactions.html -export type ZkSyncTransactionRequest = TransactionRequest & +type ZkSyncTransactionRequestEIP712 = Omit & Partial & { - gasPerPubdata: bigint + gasPerPubdata?: bigint customSignature?: Hex paymaster?: Address paymasterInput?: Hex factoryDeps?: Hex[] - type?: 'eip712' + type: 'eip712' | 'priority' } +export type ZkSyncTransactionRequest = + // Not sure why I need to add the fields with never, but exclude complains if not added. + | /*(TransactionRequest & { + paymaster: never + paymasterInput: never + gasPerPubdata: never + customSignature: never + factoryDeps: never + })*/ TransactionRequest + | ZkSyncTransactionRequestEIP712 + type RpcTransactionRequestEIP712 = TransactionRequestBase & Partial> & { eip712Meta: Eip712Meta - type?: '0x71' + type: EIP712Type | PriorityType } -export type ZkSyncRpcTransactionRequest = RpcTransactionRequestEIP712 +export type ZkSyncRpcTransactionRequest = + // Not sure why I need to add the fields with never. + (RpcTransactionRequest & { eip712Meta: never }) | RpcTransactionRequestEIP712 export type ZkSyncTransactionType = TransactionType | 'eip712' | 'priority' @@ -244,20 +258,17 @@ export type ZkSyncTransactionType = TransactionType | 'eip712' | 'priority' // https://era.zksync.io/docs/api/js/types.html#transactionreceipt export type ZkSyncRpcTransactionReceiptOverrides = { - l1BatchNumber: Hex | null - l1BatchTxIndex: Hex | null + l1BatchNumber: Hex + l1BatchTxIndex: Hex logs: RpcLog[] l2ToL1Logs: RpcL2ToL1Log[] // Why root isn't added into RpcTransactionReceipt? root: Hex } -export type ZkSyncRpcTransactionReceipt = Omit & - ZkSyncRpcTransactionReceiptOverrides - export type ZkSyncTransactionReceiptOverrides = { - l1BatchNumber: bigint | null - l1BatchTxIndex: bigint | null + l1BatchNumber: bigint + l1BatchTxIndex: bigint logs: Log[] l2ToL1Logs: L2ToL1Log[] } From 610f7b00f6f94463f6a2b06378e9b7fcce66fcb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Magalh=C3=A3es?= Date: Wed, 25 Oct 2023 19:45:12 +0100 Subject: [PATCH 07/13] Fix types --- src/chains/zksync/formatters.test-d.ts | 16 ++++++++-------- src/chains/zksync/types.ts | 22 +++++++++------------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/chains/zksync/formatters.test-d.ts b/src/chains/zksync/formatters.test-d.ts index b3a14cb993..7b690ccd33 100644 --- a/src/chains/zksync/formatters.test-d.ts +++ b/src/chains/zksync/formatters.test-d.ts @@ -32,8 +32,8 @@ describe('block', () => { Assign< Partial, { - l1BatchNumber: `0x${string}` | null - l1BatchTimestamp: `0x${string}` | null + l1BatchNumber: `0x${string}` + l1BatchTimestamp: `0x${string}` } & { transactions: `0x${string}`[] | ZkSyncRpcTransaction[] } @@ -54,8 +54,8 @@ describe('transactionReceipt', () => { Assign< Partial, { - l1BatchNumber: `0x${string}` | null - l1BatchTxIndex: `0x${string}` | null + l1BatchNumber: `0x${string}` + l1BatchTxIndex: `0x${string}` logs: (RpcLog & { l1BatchNumber: `0x${string}` transactionLogIndex: `0x${string}` @@ -83,12 +83,12 @@ describe('transactionReceipt', () => { ReturnType< typeof formattersZkSync.transactionReceipt.format >['l1BatchNumber'] - >().toEqualTypeOf() + >().toEqualTypeOf() expectTypeOf< ReturnType< typeof formattersZkSync.transactionReceipt.format >['l1BatchTxIndex'] - >().toEqualTypeOf() + >().toEqualTypeOf() expectTypeOf< ReturnType['l2ToL1Logs'] >().toEqualTypeOf< @@ -215,8 +215,8 @@ describe('smoke', () => { hash: '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', }) - expectTypeOf(transaction.l1BatchTxIndex).toEqualTypeOf() - expectTypeOf(transaction.l1BatchNumber).toEqualTypeOf() + expectTypeOf(transaction.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(transaction.l1BatchNumber).toEqualTypeOf() expectTypeOf(transaction.l2ToL1Logs).toEqualTypeOf() expectTypeOf(transaction.logs).toEqualTypeOf() }) diff --git a/src/chains/zksync/types.ts b/src/chains/zksync/types.ts index 6824c0a839..3837617570 100644 --- a/src/chains/zksync/types.ts +++ b/src/chains/zksync/types.ts @@ -221,7 +221,7 @@ export type ZkSyncRpcTransaction = // Transaction Request // https://era.zksync.io/docs/reference/concepts/transactions.html -type ZkSyncTransactionRequestEIP712 = Omit & +export type ZkSyncTransactionRequestEIP712 = Omit & Partial & { gasPerPubdata?: bigint customSignature?: Hex @@ -233,24 +233,20 @@ type ZkSyncTransactionRequestEIP712 = Omit & export type ZkSyncTransactionRequest = // Not sure why I need to add the fields with never, but exclude complains if not added. - | /*(TransactionRequest & { - paymaster: never - paymasterInput: never - gasPerPubdata: never - customSignature: never - factoryDeps: never - })*/ TransactionRequest - | ZkSyncTransactionRequestEIP712 - -type RpcTransactionRequestEIP712 = TransactionRequestBase & + TransactionRequest | ZkSyncTransactionRequestEIP712 + +export type RpcTransactionRequestEIP712 = TransactionRequestBase< + Quantity, + Index +> & Partial> & { eip712Meta: Eip712Meta type: EIP712Type | PriorityType } export type ZkSyncRpcTransactionRequest = - // Not sure why I need to add the fields with never. - (RpcTransactionRequest & { eip712Meta: never }) | RpcTransactionRequestEIP712 + | RpcTransactionRequest + | RpcTransactionRequestEIP712 export type ZkSyncTransactionType = TransactionType | 'eip712' | 'priority' From 364ef5e61b68bc2f04fbb4e9318e5de49d1b705f Mon Sep 17 00:00:00 2001 From: "moxey.eth" Date: Thu, 26 Oct 2023 06:53:56 +1100 Subject: [PATCH 08/13] refactor --- src/chains/zksync/formatters.test-d.ts | 29 ++++---------------------- src/chains/zksync/formatters.ts | 29 ++++++-------------------- src/chains/zksync/types.ts | 7 +++---- src/utils/formatters/formatter.ts | 2 +- 4 files changed, 14 insertions(+), 53 deletions(-) diff --git a/src/chains/zksync/formatters.test-d.ts b/src/chains/zksync/formatters.test-d.ts index 7b690ccd33..000fd03224 100644 --- a/src/chains/zksync/formatters.test-d.ts +++ b/src/chains/zksync/formatters.test-d.ts @@ -22,11 +22,13 @@ import { sendTransaction } from '../../wallet/index.js' import { zkSync, zkSyncTestnet } from '../index.js' import { formattersZkSync } from './formatters.js' import type { + Eip712Meta, L2ToL1Log, Log as ZkSyncLog, ZkSyncRpcTransaction, ZkSyncTransactionRequest, } from './types.js' + describe('block', () => { expectTypeOf(formattersZkSync.block.format).parameter(0).toEqualTypeOf< Assign< @@ -149,31 +151,8 @@ describe('transactionRequest', () => { Assign, ZkSyncTransactionRequest> >() expectTypeOf< - ReturnType< - typeof formattersZkSync.transactionRequest.format - >['eip712Meta']['gasPerPubdata'] - >().toEqualTypeOf<`0x${string}` | undefined>() - expectTypeOf< - ReturnType< - typeof formattersZkSync.transactionRequest.format - >['eip712Meta']['customSignature'] - >().toEqualTypeOf<`0x${string}` | undefined>() - expectTypeOf< - ReturnType< - typeof formattersZkSync.transactionRequest.format - >['eip712Meta']['factoryDeps'] - >().toEqualTypeOf<`0x${string}`[] | undefined>() - expectTypeOf< - ReturnType< - typeof formattersZkSync.transactionRequest.format - >['eip712Meta']['paymasterParams'] - >().toEqualTypeOf< - | { - paymaster: `0x${string}` - paymasterInput: number[] - } - | undefined - >() + ReturnType['eip712Meta'] + >().toEqualTypeOf() }) describe('smoke', () => { diff --git a/src/chains/zksync/formatters.ts b/src/chains/zksync/formatters.ts index f99665aa6f..804f988770 100644 --- a/src/chains/zksync/formatters.ts +++ b/src/chains/zksync/formatters.ts @@ -36,11 +36,8 @@ export const formattersZkSync = { const formatted = formattersZkSync.transaction.format( transaction as ZkSyncRpcTransaction, ) as ZkSyncTransaction - if (formatted.typeHex === '0x71') { - formatted.type = 'eip712' - } else if (formatted.typeHex === '0xff') { - formatted.type = 'priority' - } + if (formatted.typeHex === '0x71') formatted.type = 'eip712' + else if (formatted.typeHex === '0xff') formatted.type = 'priority' return formatted }) as Hash[] | ZkSyncTransaction[] return { @@ -53,11 +50,8 @@ export const formattersZkSync = { transaction: /*#__PURE__*/ defineTransaction({ format(args: ZkSyncRpcTransaction): ZkSyncTransaction { const transaction = {} as ZkSyncTransaction - if (args.type === '0x71') { - transaction.type = 'eip712' - } else if (args.type === '0xff') { - transaction.type = 'priority' - } + if (args.type === '0x71') transaction.type = 'eip712' + else if (args.type === '0xff') transaction.type = 'priority' return { ...transaction, l1BatchNumber: hexToBigInt(args.l1BatchNumber), @@ -99,13 +93,6 @@ export const formattersZkSync = { }, }), transactionRequest: /*#__PURE__*/ defineTransactionRequest({ - exclude: [ - 'paymaster', - 'paymasterInput', - 'customSignature', - 'gasPerPubdata', - 'factoryDeps', - ], format(args: ZkSyncTransactionRequest): ZkSyncRpcTransactionRequest { if ( (args.type === 'eip712' || args.type === 'priority') && @@ -113,8 +100,8 @@ export const formattersZkSync = { (args.paymaster && args.paymasterInput) || args.factoryDeps || args.customSignature) - ) { - const request = { + ) + return { eip712Meta: { ...(args.gasPerPubdata ? { gasPerPubdata: toHex(args.gasPerPubdata) } @@ -134,10 +121,6 @@ export const formattersZkSync = { }, type: args.type === 'eip712' ? '0x71' : '0xff', } as ZkSyncRpcTransactionRequest - - return request - } - return {} as ZkSyncRpcTransactionRequest }, }), diff --git a/src/chains/zksync/types.ts b/src/chains/zksync/types.ts index 3837617570..4dd53ab88f 100644 --- a/src/chains/zksync/types.ts +++ b/src/chains/zksync/types.ts @@ -232,8 +232,8 @@ export type ZkSyncTransactionRequestEIP712 = Omit & } export type ZkSyncTransactionRequest = - // Not sure why I need to add the fields with never, but exclude complains if not added. - TransactionRequest | ZkSyncTransactionRequestEIP712 + | (TransactionRequest & { eip712Meta?: never }) + | ZkSyncTransactionRequestEIP712 export type RpcTransactionRequestEIP712 = TransactionRequestBase< Quantity, @@ -245,7 +245,7 @@ export type RpcTransactionRequestEIP712 = TransactionRequestBase< } export type ZkSyncRpcTransactionRequest = - | RpcTransactionRequest + | (RpcTransactionRequest & { eip712Meta?: never }) | RpcTransactionRequestEIP712 export type ZkSyncTransactionType = TransactionType | 'eip712' | 'priority' @@ -258,7 +258,6 @@ export type ZkSyncRpcTransactionReceiptOverrides = { l1BatchTxIndex: Hex logs: RpcLog[] l2ToL1Logs: RpcL2ToL1Log[] - // Why root isn't added into RpcTransactionReceipt? root: Hex } diff --git a/src/utils/formatters/formatter.ts b/src/utils/formatters/formatter.ts index d3d84d1fc7..365b803e99 100644 --- a/src/utils/formatters/formatter.ts +++ b/src/utils/formatters/formatter.ts @@ -10,7 +10,7 @@ export function defineFormatter( return < TOverrideParameters, TOverrideReturnType, - TExclude extends (keyof (TParameters & TOverrideParameters))[] = [], + TExclude extends (keyof TParameters)[] = [], >({ exclude, format: overrides, From bce930fa805e91c739f0a5046593553722e4a8f4 Mon Sep 17 00:00:00 2001 From: "moxey.eth" Date: Thu, 26 Oct 2023 07:29:34 +1100 Subject: [PATCH 09/13] refactor --- src/chains/zksync/types.ts | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/chains/zksync/types.ts b/src/chains/zksync/types.ts index 4dd53ab88f..3c3b8aae02 100644 --- a/src/chains/zksync/types.ts +++ b/src/chains/zksync/types.ts @@ -8,7 +8,7 @@ import type { Quantity, RpcBlock, RpcLog as RpcLog_, - RpcTransactionRequest, + RpcTransactionRequest as RpcTransactionRequest_, TransactionType, } from '../../types/rpc.js' import type { @@ -17,7 +17,7 @@ import type { TransactionEIP2930, TransactionLegacy, TransactionReceipt, - TransactionRequest, + TransactionRequest as TransactionRequest_, TransactionRequestBase, } from '../../types/transaction.js' import type { UnionOmit } from '../../types/utils.js' @@ -221,7 +221,18 @@ export type ZkSyncRpcTransaction = // Transaction Request // https://era.zksync.io/docs/reference/concepts/transactions.html -export type ZkSyncTransactionRequestEIP712 = Omit & +type TransactionRequest = TransactionRequest_ & { + gasPerPubdata?: undefined + customSignature?: undefined + paymaster?: undefined + paymasterInput?: undefined + factoryDeps?: undefined +} + +export type ZkSyncTransactionRequestEIP712 = Omit< + TransactionRequestBase, + 'type' +> & Partial & { gasPerPubdata?: bigint customSignature?: Hex @@ -232,9 +243,11 @@ export type ZkSyncTransactionRequestEIP712 = Omit & } export type ZkSyncTransactionRequest = - | (TransactionRequest & { eip712Meta?: never }) + | TransactionRequest | ZkSyncTransactionRequestEIP712 +type RpcTransactionRequest = RpcTransactionRequest_ & { eip712Meta?: undefined } + export type RpcTransactionRequestEIP712 = TransactionRequestBase< Quantity, Index @@ -245,7 +258,7 @@ export type RpcTransactionRequestEIP712 = TransactionRequestBase< } export type ZkSyncRpcTransactionRequest = - | (RpcTransactionRequest & { eip712Meta?: never }) + | RpcTransactionRequest | RpcTransactionRequestEIP712 export type ZkSyncTransactionType = TransactionType | 'eip712' | 'priority' From 224f2b2e6150b037b383d3fe0b431b9636456cff Mon Sep 17 00:00:00 2001 From: "moxey.eth" Date: Thu, 26 Oct 2023 08:33:55 +1100 Subject: [PATCH 10/13] types --- src/actions/public/simulateContract.ts | 2 +- src/actions/wallet/deployContract.ts | 2 +- src/actions/wallet/prepareTransactionRequest.ts | 2 +- src/actions/wallet/sendTransaction.ts | 2 +- src/actions/wallet/signTransaction.ts | 2 +- src/actions/wallet/writeContract.ts | 2 +- src/chains/zksync/formatters.test-d.ts | 3 +++ src/chains/zksync/types.ts | 7 ++++--- src/clients/decorators/public.ts | 12 ++++++++---- src/clients/decorators/wallet.ts | 12 +++++++----- src/utils/chain.ts | 2 +- 11 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/actions/public/simulateContract.ts b/src/actions/public/simulateContract.ts index 9d665ca4a5..1e9f792657 100644 --- a/src/actions/public/simulateContract.ts +++ b/src/actions/public/simulateContract.ts @@ -120,7 +120,7 @@ export async function simulateContract< TChain extends Chain | undefined, const TAbi extends Abi | readonly unknown[], TFunctionName extends string, - TChainOverride extends Chain | undefined, + TChainOverride extends Chain | undefined = undefined, >( client: Client, { diff --git a/src/actions/wallet/deployContract.ts b/src/actions/wallet/deployContract.ts index ebed71eff1..dcd66a6daf 100644 --- a/src/actions/wallet/deployContract.ts +++ b/src/actions/wallet/deployContract.ts @@ -67,7 +67,7 @@ export function deployContract< const TAbi extends Abi | readonly unknown[], TChain extends Chain | undefined, TAccount extends Account | undefined, - TChainOverride extends Chain | undefined, + TChainOverride extends Chain | undefined = undefined, >( walletClient: Client, { diff --git a/src/actions/wallet/prepareTransactionRequest.ts b/src/actions/wallet/prepareTransactionRequest.ts index 6fae265dd5..c32851bb4e 100644 --- a/src/actions/wallet/prepareTransactionRequest.ts +++ b/src/actions/wallet/prepareTransactionRequest.ts @@ -119,7 +119,7 @@ export type PrepareTransactionRequestErrorType = export async function prepareTransactionRequest< TChain extends Chain | undefined, TAccount extends Account | undefined, - TChainOverride extends Chain | undefined, + TChainOverride extends Chain | undefined = undefined, >( client: Client, args: PrepareTransactionRequestParameters, diff --git a/src/actions/wallet/sendTransaction.ts b/src/actions/wallet/sendTransaction.ts index 6afd6a7000..a06366fbc9 100644 --- a/src/actions/wallet/sendTransaction.ts +++ b/src/actions/wallet/sendTransaction.ts @@ -124,7 +124,7 @@ export type SendTransactionErrorType = export async function sendTransaction< TChain extends Chain | undefined, TAccount extends Account | undefined, - TChainOverride extends Chain | undefined, + TChainOverride extends Chain | undefined = undefined, >( client: Client, args: SendTransactionParameters, diff --git a/src/actions/wallet/signTransaction.ts b/src/actions/wallet/signTransaction.ts index 0a5c818702..e1ece92ad5 100644 --- a/src/actions/wallet/signTransaction.ts +++ b/src/actions/wallet/signTransaction.ts @@ -106,7 +106,7 @@ export type SignTransactionErrorType = export async function signTransaction< TChain extends Chain | undefined, TAccount extends Account | undefined, - TChainOverride extends Chain | undefined, + TChainOverride extends Chain | undefined = undefined, >( client: Client, args: SignTransactionParameters, diff --git a/src/actions/wallet/writeContract.ts b/src/actions/wallet/writeContract.ts index f655b821a2..ff45027fbd 100644 --- a/src/actions/wallet/writeContract.ts +++ b/src/actions/wallet/writeContract.ts @@ -116,7 +116,7 @@ export async function writeContract< TAccount extends Account | undefined, const TAbi extends Abi | readonly unknown[], TFunctionName extends string, - TChainOverride extends Chain | undefined, + TChainOverride extends Chain | undefined = undefined, >( client: Client, { diff --git a/src/chains/zksync/formatters.test-d.ts b/src/chains/zksync/formatters.test-d.ts index 000fd03224..27ce97b2af 100644 --- a/src/chains/zksync/formatters.test-d.ts +++ b/src/chains/zksync/formatters.test-d.ts @@ -214,6 +214,7 @@ describe('smoke', () => { paymaster: '0xFD9aE5ebB0F6656f4b77a0E99dCbc5138d54b0BA', paymasterInput: '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', + type: 'eip712', }) }) @@ -231,6 +232,7 @@ describe('smoke', () => { paymaster: '0xFD9aE5ebB0F6656f4b77a0E99dCbc5138d54b0BA', paymasterInput: '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', + type: 'eip712', }) }) @@ -251,6 +253,7 @@ describe('smoke', () => { paymasterInput: '0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', customSignature: '0x1', + type: 'eip712', }) }) }) diff --git a/src/chains/zksync/types.ts b/src/chains/zksync/types.ts index 3c3b8aae02..4008003a94 100644 --- a/src/chains/zksync/types.ts +++ b/src/chains/zksync/types.ts @@ -236,11 +236,12 @@ export type ZkSyncTransactionRequestEIP712 = Omit< Partial & { gasPerPubdata?: bigint customSignature?: Hex - paymaster?: Address - paymasterInput?: Hex factoryDeps?: Hex[] type: 'eip712' | 'priority' - } + } & ( + | { paymaster: Address; paymasterInput: Hex } + | { paymaster?: undefined; paymasterInput?: undefined } + ) export type ZkSyncTransactionRequest = | TransactionRequest diff --git a/src/clients/decorators/public.ts b/src/clients/decorators/public.ts index 037dd5b8d1..3d063aaf0d 100644 --- a/src/clients/decorators/public.ts +++ b/src/clients/decorators/public.ts @@ -859,7 +859,7 @@ export type PublicActions< * // { maxFeePerGas: ..., maxPriorityFeePerGas: ... } */ estimateFeesPerGas: < - TChainOverride extends Chain | undefined, + TChainOverride extends Chain | undefined = undefined, TType extends FeeValuesType = 'eip1559', >( args?: EstimateFeesPerGasParameters, @@ -1115,7 +1115,9 @@ export type PublicActions< * const maxPriorityFeePerGas = await client.estimateMaxPriorityFeePerGas() * // 10000000n */ - estimateMaxPriorityFeePerGas: ( + estimateMaxPriorityFeePerGas: < + TChainOverride extends Chain | undefined = undefined, + >( args?: EstimateMaxPriorityFeePerGasParameters, ) => Promise /** @@ -1324,7 +1326,9 @@ export type PublicActions< * value: 1n, * }) */ - prepareTransactionRequest: ( + prepareTransactionRequest: < + TChainOverride extends Chain | undefined = undefined, + >( args: PrepareTransactionRequestParameters, ) => Promise /** @@ -1424,7 +1428,7 @@ export type PublicActions< simulateContract: < const TAbi extends Abi | readonly unknown[], TFunctionName extends string, - TChainOverride extends Chain | undefined, + TChainOverride extends Chain | undefined = undefined, >( args: SimulateContractParameters< TAbi, diff --git a/src/clients/decorators/wallet.ts b/src/clients/decorators/wallet.ts index 0cddc9def3..8fa57341ea 100644 --- a/src/clients/decorators/wallet.ts +++ b/src/clients/decorators/wallet.ts @@ -128,7 +128,7 @@ export type WalletActions< */ deployContract: < const TAbi extends Abi | readonly unknown[], - TChainOverride extends Chain | undefined, + TChainOverride extends Chain | undefined = undefined, >( args: DeployContractParameters, ) => Promise @@ -228,7 +228,9 @@ export type WalletActions< * value: 1n, * }) */ - prepareTransactionRequest: ( + prepareTransactionRequest: < + TChainOverride extends Chain | undefined = undefined, + >( args: PrepareTransactionRequestParameters, ) => Promise /** @@ -347,7 +349,7 @@ export type WalletActions< * value: 1000000000000000000n, * }) */ - sendTransaction: ( + sendTransaction: ( args: SendTransactionParameters, ) => Promise /** @@ -439,7 +441,7 @@ export type WalletActions< * }) * const signature = await client.signTransaction(request) */ - signTransaction: ( + signTransaction: ( args: SignTransactionParameters, ) => Promise /** @@ -640,7 +642,7 @@ export type WalletActions< writeContract: < const TAbi extends Abi | readonly unknown[], TFunctionName extends string, - TChainOverride extends Chain | undefined, + TChainOverride extends Chain | undefined = undefined, >( args: WriteContractParameters< TAbi, diff --git a/src/utils/chain.ts b/src/utils/chain.ts index 81bf6b9ab6..693f16bd37 100644 --- a/src/utils/chain.ts +++ b/src/utils/chain.ts @@ -36,7 +36,7 @@ export function assertCurrentChain({ export function defineChain< const chain extends Chain, - formatters extends ChainFormatters, + formatters extends ChainFormatters | undefined = undefined, >( chain: chain, config: ChainConfig = {}, From b89b4fb734170174cef4141a9f853cadc44cb3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Magalh=C3=A3es?= Date: Thu, 26 Oct 2023 17:36:59 +0100 Subject: [PATCH 11/13] Support null in some fields, because when nonce is wrong can lead to some weird behaviour. Having it support null it won't complain in the browser side --- src/chains/zksync/formatters.ts | 20 +++++++++++++++----- src/chains/zksync/types.ts | 10 +++++----- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/chains/zksync/formatters.ts b/src/chains/zksync/formatters.ts index 804f988770..eefd902ff0 100644 --- a/src/chains/zksync/formatters.ts +++ b/src/chains/zksync/formatters.ts @@ -54,8 +54,12 @@ export const formattersZkSync = { else if (args.type === '0xff') transaction.type = 'priority' return { ...transaction, - l1BatchNumber: hexToBigInt(args.l1BatchNumber), - l1BatchTxIndex: hexToBigInt(args.l1BatchTxIndex), + l1BatchNumber: args.l1BatchNumber + ? hexToBigInt(args.l1BatchNumber) + : null, + l1BatchTxIndex: args.l1BatchTxIndex + ? hexToBigInt(args.l1BatchTxIndex) + : null, } as ZkSyncTransaction }, }), @@ -64,12 +68,18 @@ export const formattersZkSync = { args: ZkSyncRpcTransactionReceiptOverrides, ): ZkSyncTransactionReceiptOverrides { return { - l1BatchNumber: hexToBigInt(args.l1BatchNumber), - l1BatchTxIndex: hexToBigInt(args.l1BatchTxIndex), + l1BatchNumber: args.l1BatchNumber + ? hexToBigInt(args.l1BatchNumber) + : null, + l1BatchTxIndex: args.l1BatchTxIndex + ? hexToBigInt(args.l1BatchTxIndex) + : null, logs: args.logs.map((log) => { return { ...formatLog(log), - l1BatchNumber: hexToBigInt(log.l1BatchNumber), + l1BatchNumber: log.l1BatchNumber + ? hexToBigInt(log.l1BatchNumber) + : null, transactionLogIndex: hexToNumber(log.transactionLogIndex), logType: log.logType, } diff --git a/src/chains/zksync/types.ts b/src/chains/zksync/types.ts index 4008003a94..8c710aab96 100644 --- a/src/chains/zksync/types.ts +++ b/src/chains/zksync/types.ts @@ -46,7 +46,7 @@ export type Log< } export type RpcLog = RpcLog_ & { - l1BatchNumber: Hex + l1BatchNumber: Hex | null // These are returned but doesn't apear in Log structure neither is mentioned in https://era.zksync.io/docs/api/js/types.html transactionLogIndex: Hex logType: Hex | null @@ -140,8 +140,8 @@ export type ZkSyncRpcBlock< // https://era.zksync.io/docs/api/js/types.html#transactionresponse type TransactionOverrides = { - l1BatchNumber: bigint - l1BatchTxIndex: bigint + l1BatchNumber: bigint | null + l1BatchTxIndex: bigint | null } type TransactionPriority = TransactionBase< @@ -276,8 +276,8 @@ export type ZkSyncRpcTransactionReceiptOverrides = { } export type ZkSyncTransactionReceiptOverrides = { - l1BatchNumber: bigint - l1BatchTxIndex: bigint + l1BatchNumber: bigint | null + l1BatchTxIndex: bigint | null logs: Log[] l2ToL1Logs: L2ToL1Log[] } From b0c0fb2ba7a701b8ded3e8f23f8a62c7ffda326b Mon Sep 17 00:00:00 2001 From: "moxey.eth" Date: Fri, 27 Oct 2023 07:53:34 +1100 Subject: [PATCH 12/13] fix --- src/chains/zksync/formatters.test-d.ts | 39 +++++--------------------- src/chains/zksync/formatters.ts | 7 +++++ src/utils/formatters/formatter.ts | 2 +- 3 files changed, 15 insertions(+), 33 deletions(-) diff --git a/src/chains/zksync/formatters.test-d.ts b/src/chains/zksync/formatters.test-d.ts index 27ce97b2af..02af754527 100644 --- a/src/chains/zksync/formatters.test-d.ts +++ b/src/chains/zksync/formatters.test-d.ts @@ -11,11 +11,7 @@ import { createWalletClient } from '../../clients/createWalletClient.js' import { http } from '../../clients/transports/http.js' import type { Log } from '../../types/log.js' import type { Hash } from '../../types/misc.js' -import type { - RpcBlock, - RpcLog, - RpcTransactionReceipt, -} from '../../types/rpc.js' +import type { RpcBlock, RpcTransactionReceipt } from '../../types/rpc.js' import type { TransactionRequest } from '../../types/transaction.js' import type { Assign } from '../../types/utils.js' import { sendTransaction } from '../../wallet/index.js' @@ -26,6 +22,7 @@ import type { L2ToL1Log, Log as ZkSyncLog, ZkSyncRpcTransaction, + ZkSyncRpcTransactionReceiptOverrides, ZkSyncTransactionRequest, } from './types.js' @@ -55,29 +52,7 @@ describe('transactionReceipt', () => { .toEqualTypeOf< Assign< Partial, - { - l1BatchNumber: `0x${string}` - l1BatchTxIndex: `0x${string}` - logs: (RpcLog & { - l1BatchNumber: `0x${string}` - transactionLogIndex: `0x${string}` - logType: `0x${string}` | null - })[] - l2ToL1Logs: { - blockNumber: `0x${string}` - blockHash: `0x${string}` - l1BatchNumber: `0x${string}` - transactionIndex: `0x${string}` - shardId: `0x${string}` - isService: boolean - sender: `0x${string}` - key: `0x${string}` - value: `0x${string}` - transactionHash: `0x${string}` - logIndex: `0x${string}` - }[] - root: `0x${string}` - } + ZkSyncRpcTransactionReceiptOverrides > >() @@ -85,12 +60,12 @@ describe('transactionReceipt', () => { ReturnType< typeof formattersZkSync.transactionReceipt.format >['l1BatchNumber'] - >().toEqualTypeOf() + >().toEqualTypeOf() expectTypeOf< ReturnType< typeof formattersZkSync.transactionReceipt.format >['l1BatchTxIndex'] - >().toEqualTypeOf() + >().toEqualTypeOf() expectTypeOf< ReturnType['l2ToL1Logs'] >().toEqualTypeOf< @@ -194,8 +169,8 @@ describe('smoke', () => { hash: '0xe56c11904d690e1bd41a7e901df609c2dc011d1033415379193ebc4197f32fc6', }) - expectTypeOf(transaction.l1BatchTxIndex).toEqualTypeOf() - expectTypeOf(transaction.l1BatchNumber).toEqualTypeOf() + expectTypeOf(transaction.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(transaction.l1BatchNumber).toEqualTypeOf() expectTypeOf(transaction.l2ToL1Logs).toEqualTypeOf() expectTypeOf(transaction.logs).toEqualTypeOf() }) diff --git a/src/chains/zksync/formatters.ts b/src/chains/zksync/formatters.ts index eefd902ff0..86adcbab19 100644 --- a/src/chains/zksync/formatters.ts +++ b/src/chains/zksync/formatters.ts @@ -103,6 +103,13 @@ export const formattersZkSync = { }, }), transactionRequest: /*#__PURE__*/ defineTransactionRequest({ + exclude: [ + 'customSignature', + 'factoryDeps', + 'gasPerPubdata', + 'paymaster', + 'paymasterInput', + ], format(args: ZkSyncTransactionRequest): ZkSyncRpcTransactionRequest { if ( (args.type === 'eip712' || args.type === 'priority') && diff --git a/src/utils/formatters/formatter.ts b/src/utils/formatters/formatter.ts index 365b803e99..a2dc8bd15b 100644 --- a/src/utils/formatters/formatter.ts +++ b/src/utils/formatters/formatter.ts @@ -10,7 +10,7 @@ export function defineFormatter( return < TOverrideParameters, TOverrideReturnType, - TExclude extends (keyof TParameters)[] = [], + TExclude extends (keyof TParameters | keyof TOverrideParameters)[] = [], >({ exclude, format: overrides, From db5ac41aa9dc9efa26569aa8689cdc1c0ebd0f55 Mon Sep 17 00:00:00 2001 From: jxom Date: Fri, 27 Oct 2023 07:55:16 +1100 Subject: [PATCH 13/13] Create tiny-dolls-look.md --- .changeset/tiny-dolls-look.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tiny-dolls-look.md diff --git a/.changeset/tiny-dolls-look.md b/.changeset/tiny-dolls-look.md new file mode 100644 index 0000000000..a85d1ad5ea --- /dev/null +++ b/.changeset/tiny-dolls-look.md @@ -0,0 +1,5 @@ +--- +"viem": minor +--- + +Added ZkSync formatters.