From 43b710b723491478d138c7c2937a298148fe2f03 Mon Sep 17 00:00:00 2001 From: Roberts Ivanovs Date: Fri, 22 Dec 2023 19:31:26 +0200 Subject: [PATCH] wip: type fixes post rebase --- .../actions/prepareTransactionRequest.ts | 129 +++-------- .../zksync/actions/sendTransaction.test.ts | 16 +- src/chains/zksync/actions/sendTransaction.ts | 214 ++++-------------- .../zksync/actions/signTransaction.test.ts | 6 +- src/chains/zksync/actions/signTransaction.ts | 135 ++++------- src/chains/zksync/actions/writeContract.ts | 17 +- src/chains/zksync/chainConfig.ts | 4 + src/chains/zksync/chains.ts | 1 + src/chains/zksync/decorators/eip712.test.ts | 12 +- src/chains/zksync/decorators/eip712.ts | 32 ++- src/chains/zksync/eip712signers.test.ts | 8 +- src/chains/zksync/formatters.ts | 4 +- src/chains/zksync/index.ts | 22 +- src/chains/zksync/types.ts | 24 +- src/types/chain.ts | 3 + src/utils/transaction/assertRequest.ts | 13 +- 16 files changed, 198 insertions(+), 442 deletions(-) diff --git a/src/chains/zksync/actions/prepareTransactionRequest.ts b/src/chains/zksync/actions/prepareTransactionRequest.ts index 14952b4a6c9..3860799dacf 100644 --- a/src/chains/zksync/actions/prepareTransactionRequest.ts +++ b/src/chains/zksync/actions/prepareTransactionRequest.ts @@ -1,72 +1,20 @@ +import { getChainId } from '~viem/actions/index.js' +import type { Chain } from '~viem/index.js' import type { Account } from '../../../accounts/types.js' +import { parseAccount } from '../../../accounts/utils/parseAccount.js' +import { estimateGas } from '../../../actions/public/estimateGas.js' +import { getTransactionCount } from '../../../actions/public/getTransactionCount.js' import { - type ParseAccountErrorType, - parseAccount, -} from '../../../accounts/utils/parseAccount.js' -import { type EstimateFeesPerGasErrorType } from '../../../actions/public/estimateFeesPerGas.js' -import { - type EstimateGasErrorType, - type EstimateGasParameters, - estimateGas, -} from '../../../actions/public/estimateGas.js' -import { type GetBlockErrorType } from '../../../actions/public/getBlock.js' -import { - type GetTransactionCountErrorType, - getTransactionCount, -} from '../../../actions/public/getTransactionCount.js' -import { prepareTransactionRequest as originalPrepareTransactionRequest } from '../../../actions/wallet/prepareTransactionRequest.js' + type PrepareTransactionRequestParameters, + type PrepareTransactionRequestReturnType, + prepareTransactionRequest as originalPrepareTransactionRequest, +} from '../../../actions/wallet/prepareTransactionRequest.js' import type { Client } from '../../../clients/createClient.js' import type { Transport } from '../../../clients/transports/createTransport.js' -import { - AccountNotFoundError, - type AccountNotFoundErrorType, -} from '../../../errors/account.js' -import type { GetAccountParameter } from '../../../types/account.js' -import type { GetChain } from '../../../types/chain.js' -import { type TransactionSerializable } from '../../../types/transaction.js' -import type { UnionOmit } from '../../../types/utils.js' -import type { FormattedTransactionRequest } from '../../../utils/formatters/transactionRequest.js' +import { AccountNotFoundError } from '../../../errors/account.js' import { getAction } from '../../../utils/getAction.js' -import type { - AssertRequestErrorType, - AssertRequestParameters, -} from '../../../utils/transaction/assertRequest.js' -import { assertRequest } from '../../../utils/transaction/assertRequest.js' -import { type GetTransactionType } from '../../../utils/transaction/getTransactionType.js' import { type ChainEIP712, isEip712Transaction } from '../types.js' -export type PrepareTransactionRequestParameters< - TChain extends ChainEIP712 | undefined = ChainEIP712 | undefined, - TAccount extends Account | undefined = Account | undefined, - TChainOverride extends ChainEIP712 | undefined = ChainEIP712 | undefined, -> = UnionOmit< - FormattedTransactionRequest< - TChainOverride extends ChainEIP712 ? TChainOverride : TChain - >, - 'from' -> & - GetAccountParameter & - GetChain - -export type PrepareTransactionRequestReturnType< - TChain extends ChainEIP712 | undefined = ChainEIP712 | undefined, - TAccount extends Account | undefined = Account | undefined, - TChainOverride extends ChainEIP712 | undefined = ChainEIP712 | undefined, -> = FormattedTransactionRequest< - TChainOverride extends ChainEIP712 ? TChainOverride : TChain -> & - GetAccountParameter & - GetChain - -export type PrepareTransactionRequestErrorType = - | AccountNotFoundErrorType - | AssertRequestErrorType - | ParseAccountErrorType - | GetBlockErrorType - | GetTransactionCountErrorType - | EstimateGasErrorType - | EstimateFeesPerGasErrorType - /** * Prepares a transaction request for signing. * @@ -110,59 +58,56 @@ export type PrepareTransactionRequestErrorType = export async function prepareTransactionRequest< TChain extends ChainEIP712 | undefined, TAccount extends Account | undefined, - TChainOverride extends ChainEIP712 | undefined = undefined, + TChainOverride extends Chain | undefined = undefined, >( client: Client, - args: PrepareTransactionRequestParameters, + argsIncoming: PrepareTransactionRequestParameters< + TChain, + TAccount, + TChainOverride + >, ): Promise< PrepareTransactionRequestReturnType > { - const { account: account_ = client.account, nonce, gas } = args - if (!account_) throw new AccountNotFoundError() - const account = parseAccount(account_) + const args = { + ...argsIncoming, + account: argsIncoming.account || client.account, + chain: argsIncoming.chain || client.chain, + } + + if (!args.account) throw new AccountNotFoundError() + const account = parseAccount(args.account) - const request = { ...args, from: account.address } + const chainId = await getAction(client, getChainId, 'getChainId')({}) + const request = { ...args, from: account.address, chainId } - if (typeof nonce === 'undefined') { + if (args.nonce === undefined) { request.nonce = await getAction( client, getTransactionCount, + 'getTransactionCount', )({ address: account.address, blockTag: 'pending', }) } - if (isEip712Transaction(request as TransactionSerializable)) { - request.type = - 'eip712' as GetTransactionType as any - // Do nothing... + if (isEip712Transaction({ ...request })) { + request.type = 'eip712' - assertRequest(request as AssertRequestParameters) - - if (typeof gas === 'undefined') { + if (request.gas === undefined) { request.gas = await getAction( client, - estimateGas, + estimateGas, + 'estimateGas', )({ ...request, - account: { address: account.address, type: 'json-rpc' }, - } as EstimateGasParameters) + type: 'eip712', + }) } - return request as unknown as PrepareTransactionRequestReturnType< - TChain, - TAccount, - TChainOverride - > + return request } - return originalPrepareTransactionRequest( - client, - args as unknown as PrepareTransactionRequestParameters, - ) as unknown as PrepareTransactionRequestReturnType< - TChain, - TAccount, - TChainOverride - > + return originalPrepareTransactionRequest(client, args) } diff --git a/src/chains/zksync/actions/sendTransaction.test.ts b/src/chains/zksync/actions/sendTransaction.test.ts index 94a57f761db..461107364ec 100644 --- a/src/chains/zksync/actions/sendTransaction.test.ts +++ b/src/chains/zksync/actions/sendTransaction.test.ts @@ -5,22 +5,21 @@ import { privateKeyToAccount } from '../../../accounts/privateKeyToAccount.js' import { createWalletClient } from '../../../clients/createWalletClient.js' import { http } from '../../../clients/transports/http.js' import { parseGwei } from '../../../utils/unit/parseGwei.js' -import { zkSyncTestnet } from '../index.js' -import { sendTransaction } from './sendTransaction.js' +import { zkSyncSepoliaTestnet } from '../chains.js' +import { sendTransactionZ } from './sendTransaction.js' const sourceAccount = accounts[0] const targetAccount = accounts[1] describe('zksync on anvil', () => { const walletClient = createWalletClient({ - chain: zkSyncTestnet, + chain: zkSyncSepoliaTestnet, transport: http(localHttpUrl), }) test('non-eip712', async () => { expect( - await sendTransaction(walletClient, { - chain: zkSyncTestnet, + await sendTransactionZ(walletClient, { account: privateKeyToAccount(sourceAccount.privateKey), to: targetAccount.address, maxFeePerGas: parseGwei('25'), @@ -36,13 +35,12 @@ describe('zksync on anvil', () => { describe('zksync on zkSyncTestnet', () => { const walletClient = createWalletClient({ - chain: zkSyncTestnet, - transport: http(zkSyncTestnet.rpcUrls.default.http[0]), + chain: zkSyncSepoliaTestnet, + transport: http(zkSyncSepoliaTestnet.rpcUrls.default.http[0]), }) test('eip712', async () => { expect( - await sendTransaction(walletClient, { - chain: zkSyncTestnet, + await sendTransactionZ(walletClient, { account: privateKeyToAccount(sourceAccount.privateKey), to: targetAccount.address, maxFeePerGas: parseGwei('25'), diff --git a/src/chains/zksync/actions/sendTransaction.ts b/src/chains/zksync/actions/sendTransaction.ts index 285c3ef2216..db89f78b72c 100644 --- a/src/chains/zksync/actions/sendTransaction.ts +++ b/src/chains/zksync/actions/sendTransaction.ts @@ -1,101 +1,29 @@ +import { sendTransaction as sendTransactionOriginal } from '~viem/actions/index.js' +import type { + SendTransactionParameters, + SendTransactionReturnType, +} from '~viem/index.js' import type { Account } from '../../../accounts/types.js' -import { - type ParseAccountErrorType, - parseAccount, -} from '../../../accounts/utils/parseAccount.js' -import type { SignTransactionErrorType } from '../../../accounts/utils/signTransaction.js' -import { - type GetChainIdErrorType, - getChainId, -} from '../../../actions/public/getChainId.js' -import { - type SendRawTransactionReturnType, - sendRawTransaction, -} from '../../../actions/wallet/sendRawTransaction.js' +import { parseAccount } from '../../../accounts/utils/parseAccount.js' +import { getChainId } from '../../../actions/public/getChainId.js' +import { sendRawTransaction } from '../../../actions/wallet/sendRawTransaction.js' import type { Client } from '../../../clients/createClient.js' import type { Transport } from '../../../clients/transports/createTransport.js' import { AccountNotFoundError } from '../../../errors/account.js' import { BaseError } from '../../../errors/base.js' -import type { ErrorType } from '../../../errors/utils.js' -import type { GetAccountParameter } from '../../../types/account.js' -import { - type Chain, - type ExtractChainFormatterParameters, -} from '../../../types/chain.js' -import type { GetChain } from '../../../types/chain.js' +import { type Chain } from '../../../types/chain.js' import type { Hash } from '../../../types/misc.js' -import type { - TransactionRequest, - TransactionSerializable, -} from '../../../types/transaction.js' -import type { UnionOmit } from '../../../types/utils.js' -import type { RequestErrorType } from '../../../utils/buildRequest.js' -import { - type AssertCurrentChainErrorType, - assertCurrentChain, -} from '../../../utils/chain/assertCurrentChain.js' +import type { TransactionSerializable } from '../../../types/transaction.js' +import { assertCurrentChain } from '../../../utils/chain/assertCurrentChain.js' import { type GetTransactionErrorParameters, - type GetTransactionErrorReturnType, getTransactionError, } from '../../../utils/errors/getTransactionError.js' -import { extract } from '../../../utils/formatters/extract.js' -import { formatTransactionRequest } from '../../../utils/formatters/transactionRequest.js' import { getAction } from '../../../utils/getAction.js' -import { - type AssertRequestErrorType, - type AssertRequestParameters, - assertRequest, -} from '../../../utils/transaction/assertRequest.js' -import { - type ChainEIP712, - type TransactionRequestEIP712, - isEip712Transaction, -} from '../types.js' -import { - type PrepareTransactionRequestErrorType, - prepareTransactionRequest, -} from './prepareTransactionRequest.js' -import { - type SignEip712TransactionParameters, - signEip712Transaction, -} from './signTransaction.js' - -export type FormattedTransactionRequest< - TChain extends Chain | undefined = Chain | undefined, -> = ExtractChainFormatterParameters< - TChain, - 'transactionRequest', - TransactionRequestEIP712 -> - -export type SendTransactionParameters< - TChain extends ChainEIP712 | undefined = ChainEIP712 | undefined, - TAccount extends Account | undefined = Account | undefined, - TChainOverride extends ChainEIP712 | undefined = ChainEIP712 | undefined, -> = UnionOmit< - FormattedTransactionRequest< - TChainOverride extends ChainEIP712 ? TChainOverride : TChain - >, - 'from' -> & - GetAccountParameter & - GetChain - -export type SendTransactionReturnType = Hash - -export type SendTransactionErrorType = - | ParseAccountErrorType - | GetTransactionErrorReturnType< - | AssertCurrentChainErrorType - | AssertRequestErrorType - | GetChainIdErrorType - | PrepareTransactionRequestErrorType - | SendRawTransactionReturnType - | SignTransactionErrorType - | RequestErrorType - > - | ErrorType +import { assertRequest } from '../../../utils/transaction/assertRequest.js' +import { type ChainEIP712, isEip712Transaction } from '../types.js' +import { prepareTransactionRequest } from './prepareTransactionRequest.js' +import { signEip712Transaction } from './signTransaction.js' /** * Creates, signs, and sends a new transaction to the network. @@ -147,60 +75,36 @@ export async function sendTransaction< TChainOverride extends Chain | undefined = undefined, >( client: Client, - args: SendTransactionParameters, + argsIncoming: SendTransactionParameters, ): Promise { - const { - account: account_ = client.account, - chain = client.chain, - accessList, - data, - gas, - gasPrice, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - to, - value, - ...rest - } = args + const args = { + ...argsIncoming, + chain: argsIncoming.chain || client.chain, + account: argsIncoming.account || client.account, + } - if (!account_) + if (!args.account) throw new AccountNotFoundError({ docsPath: '/docs/actions/wallet/sendTransaction', }) - const account = parseAccount(account_) + const account = parseAccount(args.account) try { - assertRequest(args as AssertRequestParameters) + assertRequest(argsIncoming) - let chainId - if (chain !== null) { - chainId = await getAction(client, getChainId)({}) + let chainId = await getAction(client, getChainId, 'getChainId')({}) + if (args.chain !== null) { assertCurrentChain({ currentChainId: chainId, - chain, + chain: args.chain, }) } - const transaction = { - account, - accessList, - data, - gas, - gasPrice, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - to, - value, - ...rest, - } - if ( - client.chain?.eip712domain?.eip712domain && - isEip712Transaction(transaction as unknown as TransactionSerializable) + client.chain?.custom.eip712domain?.eip712domain && + isEip712Transaction({ ...args, chainId }) ) { - const eip712signer = client.chain?.eip712domain?.eip712domain + const eip712signer = client.chain?.custom.eip712domain?.eip712domain if (eip712signer === undefined) throw new BaseError('Chain doesnt define EIP712 signer.') @@ -209,19 +113,22 @@ export async function sendTransaction< const request = await getAction( client, prepareTransactionRequest, - )(transaction as any) + 'prepareTransactionRequest', + )({ ...args }) - if (!chainId) chainId = await getAction(client, getChainId)({}) + if (!chainId) + chainId = await getAction(client, getChainId, 'getChainId')({}) // EIP712 sign will be done inside the sign transaction const serializedTransaction = (await signEip712Transaction(client, { ...request, chainId, - } as unknown as SignEip712TransactionParameters)) as Hash + })) as Hash return await getAction( client, sendRawTransaction, + 'sendRawTransaction', )({ serializedTransaction, }) @@ -232,24 +139,13 @@ export async function sendTransaction< const request = await getAction( client, prepareTransactionRequest, - )({ - account, - accessList, - chain, - data, - gas, - gasPrice, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - to, - value, - ...rest, - } as any) + 'prepareTransactionRequest', + )({ ...argsIncoming, chainId }) - if (!chainId) chainId = await getAction(client, getChainId)({}) + if (!chainId) + chainId = await getAction(client, getChainId, 'getChainId')({}) - const serializer = chain?.serializers?.transaction + const serializer = args.chain?.serializers?.transaction const serializedTransaction = (await account.signTransaction( { ...request, @@ -260,37 +156,17 @@ export async function sendTransaction< return await getAction( client, sendRawTransaction, + 'sendRawTransaction', )({ serializedTransaction, }) } - - 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: chainFormat }), - accessList, - data, - from: account.address, - gas, - gasPrice, - maxFeePerGas, - maxPriorityFeePerGas, - nonce, - to, - value, - } as TransactionRequest) - return await client.request({ - method: 'eth_sendTransaction', - params: [request], - }) + return sendTransactionOriginal(client, argsIncoming) } catch (err) { throw getTransactionError(err as BaseError, { - ...(args as GetTransactionErrorParameters), + ...(argsIncoming as GetTransactionErrorParameters), account, - chain: args.chain || undefined, + chain: argsIncoming.chain || undefined, }) } } diff --git a/src/chains/zksync/actions/signTransaction.test.ts b/src/chains/zksync/actions/signTransaction.test.ts index 0bba9e210b4..f581faf3b66 100644 --- a/src/chains/zksync/actions/signTransaction.test.ts +++ b/src/chains/zksync/actions/signTransaction.test.ts @@ -6,7 +6,7 @@ import { privateKeyToAccount } from '../../../accounts/privateKeyToAccount.js' import { createWalletClient } from '../../../clients/createWalletClient.js' import { http } from '../../../clients/transports/http.js' import { parseGwei } from '../../../utils/unit/parseGwei.js' -import { zkSyncTestnet } from '../../index.js' +import { zkSyncSepoliaTestnet } from '../../index.js' import { signEip712Transaction as signTransaction } from './signTransaction.js' const sourceAccount = accounts[0] @@ -19,7 +19,7 @@ const base: TransactionRequestBase = { describe('custom (eip712)', () => { const walletClient = createWalletClient({ - chain: zkSyncTestnet, + chain: zkSyncSepoliaTestnet, transport: http(localHttpUrl), }) @@ -27,7 +27,7 @@ describe('custom (eip712)', () => { expect( await signTransaction(walletClient, { account: privateKeyToAccount(sourceAccount.privateKey), - chain: zkSyncTestnet, + chain: zkSyncSepoliaTestnet, ...base, maxFeePerGas: parseGwei('20'), maxPriorityFeePerGas: parseGwei('2'), diff --git a/src/chains/zksync/actions/signTransaction.ts b/src/chains/zksync/actions/signTransaction.ts index d65bd9e6c0e..1d6dec1a355 100644 --- a/src/chains/zksync/actions/signTransaction.ts +++ b/src/chains/zksync/actions/signTransaction.ts @@ -1,70 +1,22 @@ +import type { + Chain, + SignTransactionParameters, + SignTransactionReturnType, +} from '~viem/index.js' import type { Account } from '../../../accounts/types.js' -import { - type ParseAccountErrorType, - parseAccount, -} from '../../../accounts/utils/parseAccount.js' -import type { SignTransactionErrorType as SignTransactionErrorType_account } from '../../../accounts/utils/signTransaction.js' -import { - type GetChainIdErrorType, - getChainId, -} from '../../../actions/public/getChainId.js' +import { parseAccount } from '../../../accounts/utils/parseAccount.js' +import { getChainId } from '../../../actions/public/getChainId.js' import { signTypedData } from '../../../actions/wallet/signTypedData.js' import type { Client } from '../../../clients/createClient.js' import type { Transport } from '../../../clients/transports/createTransport.js' import { AccountNotFoundError } from '../../../errors/account.js' -import type { ErrorType } from '../../../errors/utils.js' -import type { GetAccountParameter } from '../../../types/account.js' -import { type GetChain } from '../../../types/chain.js' -import { type RpcTransactionRequest } from '../../../types/rpc.js' -import type { - TransactionRequest, - TransactionSerializable, - TransactionSerialized, -} from '../../../types/transaction.js' -import type { UnionOmit } from '../../../types/utils.js' -import type { RequestErrorType } from '../../../utils/buildRequest.js' -import { - type AssertCurrentChainErrorType, - assertCurrentChain, -} from '../../../utils/chain/assertCurrentChain.js' -import type { NumberToHexErrorType } from '../../../utils/encoding/toHex.js' -import { - type FormattedTransactionRequest, - formatTransactionRequest, -} from '../../../utils/formatters/transactionRequest.js' +import { assertCurrentChain } from '../../../utils/chain/assertCurrentChain.js' +import { formatTransactionRequest } from '../../../utils/formatters/transactionRequest.js' import { getAction } from '../../../utils/getAction.js' import { numberToHex } from '../../../utils/index.js' -import { - type AssertRequestErrorType, - assertRequest, -} from '../../../utils/transaction/assertRequest.js' +import { assertRequest } from '../../../utils/transaction/assertRequest.js' import { type ChainEIP712, isEip712Transaction } from '../types.js' -export type SignEip712TransactionParameters< - TChain extends ChainEIP712 | undefined = ChainEIP712 | undefined, - TAccount extends Account | undefined = Account | undefined, - TChainOverride extends ChainEIP712 | undefined = ChainEIP712 | undefined, -> = UnionOmit< - FormattedTransactionRequest< - TChainOverride extends ChainEIP712 ? TChainOverride : TChain - >, - 'from' -> & - GetAccountParameter & - GetChain - -export type SignEip712TransactionReturnType = TransactionSerialized - -export type SignEip712TransactionErrorType = - | ParseAccountErrorType - | AssertRequestErrorType - | GetChainIdErrorType - | AssertCurrentChainErrorType - | SignTransactionErrorType_account - | NumberToHexErrorType - | RequestErrorType - | ErrorType - /** * Signs a transaction. * @@ -111,47 +63,47 @@ export type SignEip712TransactionErrorType = export async function signEip712Transaction< TChain extends ChainEIP712 | undefined, TAccount extends Account | undefined, - TChainOverride extends ChainEIP712 | undefined = undefined, + TChainOverride extends Chain | undefined = undefined, >( client: Client, - args: SignEip712TransactionParameters, -): Promise { - const { - account: account_ = client.account, - chain = client.chain, - ...transaction - } = args + argsIncoming: SignTransactionParameters, +): Promise { + const args = { + ...argsIncoming, + account: argsIncoming.account || client.account, + chain: argsIncoming.chain || client.chain, + } - if (!account_) + if (!args.account) throw new AccountNotFoundError({ docsPath: '/docs/actions/wallet/signTransaction', }) - const account = parseAccount(account_) + const account = parseAccount(args.account) - assertRequest({ - account, - ...args, - }) + assertRequest(args) - const chainId = await getAction(client, getChainId)({}) - if (chain !== null) + const chainId = await getAction(client, getChainId, 'getChainId')({}) + if (args.chain !== null) assertCurrentChain({ currentChainId: chainId, - chain, + chain: args.chain, }) - const formatters = chain?.formatters || client.chain?.formatters + const formatters = args.chain?.formatters || client.chain?.formatters const format = formatters?.transactionRequest?.format || formatTransactionRequest if ( - client.chain?.eip712domain?.eip712domain && + client.chain?.custom.eip712domain?.eip712domain && client.chain?.serializers?.transaction && - isEip712Transaction(transaction as unknown as TransactionSerializable) + isEip712Transaction({ ...args, chainId }) ) { - const eip712Domain = client.chain?.eip712domain?.eip712domain( - transaction as unknown as TransactionSerializable, - ) + const eip712Domain = client.chain?.custom.eip712domain?.eip712domain({ + ...args, + type: 'eip712', + from: account.address, + gasPrice: undefined, + }) const customSignature = await signTypedData(client, { ...eip712Domain, @@ -162,10 +114,13 @@ export async function signEip712Transaction< // is `local` or `json-rpc`. return client.chain?.serializers?.transaction( { + ...args, chainId, - ...transaction, + type: 'eip712', + from: account.address, customSignature, - } as unknown as TransactionSerializable, + gasPrice: undefined, + }, // Use this blank private key, probably we should change the code to be optional, // or option if it is EIP712. { r: '0x0', s: '0x0', v: 0n }, @@ -175,11 +130,15 @@ export async function signEip712Transaction< if (account.type === 'local') { return account.signTransaction( { - ...transaction, + ...args, chainId, - } as unknown as TransactionSerializable, + // TODO: I am suspicious that we actually don't want to override the type here. + type: 'eip712', + from: account.address, + gasPrice: undefined, + }, { serializer: client.chain?.serializers?.transaction }, - ) as Promise + ) } // For EIP712 we don't need to ask MetaMask to sign it, @@ -187,10 +146,10 @@ export async function signEip712Transaction< method: 'eth_signTransaction', params: [ { - ...format(transaction as unknown as TransactionRequest), + ...format(args), chainId: numberToHex(chainId), from: account.address, - } as unknown as RpcTransactionRequest, + }, ], }) } diff --git a/src/chains/zksync/actions/writeContract.ts b/src/chains/zksync/actions/writeContract.ts index b7ec184795d..d5f0b2f6916 100644 --- a/src/chains/zksync/actions/writeContract.ts +++ b/src/chains/zksync/actions/writeContract.ts @@ -5,11 +5,7 @@ import type { Client } from '../../../clients/createClient.js' import type { Transport } from '../../../clients/transports/createTransport.js' import type { ErrorType } from '../../../errors/utils.js' import type { GetAccountParameter } from '../../../types/account.js' -import type { GetChain } from '../../../types/chain.js' -import type { - ContractFunctionConfig, - GetValue, -} from '../../../types/contract.js' +import type { GetValue } from '../../../types/contract.js' import type { Hex } from '../../../types/misc.js' import type { UnionOmit } from '../../../types/utils.js' import { @@ -20,12 +16,7 @@ import { import type { FormattedTransactionRequest } from '../../../utils/formatters/transactionRequest.js' import { getAction } from '../../../utils/getAction.js' import type { ChainEIP712 } from '../types.js' -import { - type SendTransactionErrorType, - type SendTransactionParameters, - type SendTransactionReturnType, - sendTransaction, -} from './sendTransaction.js' +import { sendTransaction } from './sendTransaction.js' export type WriteContractParameters< TAbi extends Abi | readonly unknown[] = Abi, @@ -34,9 +25,7 @@ export type WriteContractParameters< TAccount extends Account | undefined = Account | undefined, TChainOverride extends ChainEIP712 | undefined = ChainEIP712 | undefined, > = ContractFunctionConfig & - GetAccountParameter & - GetChain & - UnionOmit< + GetAccountParameter & { chain: TChainOverride | null } & UnionOmit< FormattedTransactionRequest< TChainOverride extends ChainEIP712 ? TChainOverride : TChain >, diff --git a/src/chains/zksync/chainConfig.ts b/src/chains/zksync/chainConfig.ts index 0935189755b..f55e293a665 100644 --- a/src/chains/zksync/chainConfig.ts +++ b/src/chains/zksync/chainConfig.ts @@ -1,7 +1,11 @@ +import { eip712domainZkSync } from './eip712signers.js' import { formatters } from './formatters.js' import { serializers } from './serializers.js' export const chainConfig = { formatters, serializers, + custom: { + eip712Domain: eip712domainZkSync, + }, } as const diff --git a/src/chains/zksync/chains.ts b/src/chains/zksync/chains.ts index 745e2ce1669..71af3aeeb17 100644 --- a/src/chains/zksync/chains.ts +++ b/src/chains/zksync/chains.ts @@ -1,2 +1,3 @@ export { zkSync } from '../definitions/zkSync.js' export { zkSyncTestnet } from '../definitions/zkSyncTestnet.js' +export { zkSyncSepoliaTestnet } from '../definitions/zkSyncSepoliaTestnet.js' diff --git a/src/chains/zksync/decorators/eip712.test.ts b/src/chains/zksync/decorators/eip712.test.ts index 2ec06f0f62c..6dcad684904 100644 --- a/src/chains/zksync/decorators/eip712.test.ts +++ b/src/chains/zksync/decorators/eip712.test.ts @@ -6,12 +6,12 @@ import { privateKeyToAccount } from '~viem/accounts/privateKeyToAccount.js' import { simulateContract } from '~viem/actions/index.js' import { createWalletClient } from '~viem/index.js' import { http } from '../../../clients/transports/http.js' -import { zkSyncTestnet } from '../chains.js' +import { zkSyncSepoliaTestnet } from '../chains.js' import { eip712Actions } from './eip712.js' const zkSyncClient = createWalletClient({ - chain: zkSyncTestnet, - transport: http(zkSyncTestnet.rpcUrls.default.http[0]), + chain: zkSyncSepoliaTestnet, + transport: http(zkSyncSepoliaTestnet.rpcUrls.default.http[0]), }).extend(eip712Actions()) test('default', async () => { @@ -25,7 +25,7 @@ test('default', async () => { `) }) -type Args = Parameters +type Args = Parameters<(typeof zkSyncClient)['prepareEip712TransactionRequest']> const root: Args[0] = { account: privateKeyToAccount(accounts[0].privateKey), to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', @@ -48,7 +48,7 @@ describe('smoke test', () => { }) test('sendEip712Transaction', async () => { - const base: Parameters = [ + const base: Parameters<(typeof zkSyncClient)['sendEip712Transaction']> = [ root, ] const request = await zkSyncClient.sendEip712Transaction(base[0]) @@ -56,7 +56,7 @@ describe('smoke test', () => { }) test('signEip712Transaction', async () => { - const base: Parameters = [ + const base: Parameters<(typeof zkSyncClient)['signEip712Transaction']> = [ root, ] const signature = await zkSyncClient.signEip712Transaction(base[0]) diff --git a/src/chains/zksync/decorators/eip712.ts b/src/chains/zksync/decorators/eip712.ts index 0229bf69c29..2b8663bfc90 100644 --- a/src/chains/zksync/decorators/eip712.ts +++ b/src/chains/zksync/decorators/eip712.ts @@ -1,22 +1,18 @@ import type { Abi } from 'abitype' +import { sendTransaction } from '~viem/actions/wallet/sendTransaction.js' +import type { + PrepareTransactionRequestParameters, + PrepareTransactionRequestReturnType, + SendTransactionParameters, + SendTransactionReturnType, + SignTransactionParameters, + SignTransactionReturnType, +} from '~viem/index.js' import type { Client } from '../../../clients/createClient.js' import type { Transport } from '../../../clients/transports/createTransport.js' import type { Account } from '../../../types/account.js' -import { - type PrepareTransactionRequestParameters, - type PrepareTransactionRequestReturnType, - prepareTransactionRequest, -} from '../actions/prepareTransactionRequest.js' -import { - type SendTransactionParameters, - type SendTransactionReturnType, - sendTransaction, -} from '../actions/sendTransaction.js' -import { - type SignEip712TransactionParameters, - type SignEip712TransactionReturnType, - signEip712Transaction, -} from '../actions/signTransaction.js' +import { prepareTransactionRequest } from '../actions/prepareTransactionRequest.js' +import { signEip712Transaction } from '../actions/signTransaction.js' import { type WriteContractParameters, type WriteContractReturnType, @@ -25,7 +21,7 @@ import { import type { ChainEIP712 } from '../types.js' export type Eip712Actions< - TChain extends ChainEIP712 | undefined = ChainEIP712 | undefined, + TChain extends ChainEIP712 | undefined = ChainEIP712, TAccount extends Account | undefined = Account | undefined, > = { /** @@ -172,8 +168,8 @@ export type Eip712Actions< signEip712Transaction: < TChainOverride extends ChainEIP712 | undefined = undefined, >( - args: SignEip712TransactionParameters, - ) => Promise + args: SignTransactionParameters, + ) => Promise /** * Executes a write function on a contract. diff --git a/src/chains/zksync/eip712signers.test.ts b/src/chains/zksync/eip712signers.test.ts index c91ce9fc4f1..695de2304ed 100644 --- a/src/chains/zksync/eip712signers.test.ts +++ b/src/chains/zksync/eip712signers.test.ts @@ -3,14 +3,14 @@ import { describe, expect, test } from 'vitest' import { accounts } from '~test/src/constants.js' import { signTransaction } from '../../accounts/utils/signTransaction.js' import { type TransactionSerializableEIP1559, parseEther } from '../../index.js' -import { zkSyncTestnet } from '../index.js' +import { zkSyncSepoliaTestnet } from '../index.js' import { getZkSyncEIP712Domain } from './eip712signers.js' -import { serializeTransactionZkSync } from './serializers.js' +import { serializeTransaction } from './serializers.js' import type { ZkSyncTransactionSerializableEIP712 } from './types.js' const baseTransaction: TransactionSerializableEIP1559 = { to: '0x111C3E89Ce80e62EE88318C2804920D4c96f92bb', - chainId: zkSyncTestnet.id, + chainId: zkSyncSepoliaTestnet.id, nonce: 7, maxFeePerGas: 250000000n, maxPriorityFeePerGas: 2n, @@ -123,7 +123,7 @@ test('signed', async () => { const signed = await signTransaction({ privateKey: accounts[0].privateKey, transaction: baseEip712, - serializer: serializeTransactionZkSync, + serializer: serializeTransaction, }) expect(signed).toEqual( diff --git a/src/chains/zksync/formatters.ts b/src/chains/zksync/formatters.ts index a312a00ee04..215e8363b88 100644 --- a/src/chains/zksync/formatters.ts +++ b/src/chains/zksync/formatters.ts @@ -32,7 +32,7 @@ export const formatters = { } { const transactions = args.transactions?.map((transaction) => { if (typeof transaction === 'string') return transaction - const formatted = formatters.transaction.format( + const formatted = formatters.transaction?.format( transaction as ZkSyncRpcTransaction, ) as ZkSyncTransaction if (formatted.typeHex === '0x71') formatted.type = 'eip712' @@ -146,5 +146,3 @@ export const formatters = { }, }), } as const satisfies ChainFormatters - -// eth_call needs customSignature to use 'Array.from(hexToBytes()' diff --git a/src/chains/zksync/index.ts b/src/chains/zksync/index.ts index 8dc3dbfe762..0eab09fded7 100644 --- a/src/chains/zksync/index.ts +++ b/src/chains/zksync/index.ts @@ -31,20 +31,6 @@ export type { ZkSyncTransactionSerializedEIP712, ZkSyncTransactionType, } from './types.js' -export { - sendTransaction as sendEip712Transaction, - type SendTransactionParameters as SendEip712TransactionParameters, - type SendTransactionErrorType as SendEip712TransactionErrorType, - type SendTransactionReturnType as SendEip712TransactionReturnType, -} from './actions/sendTransaction.js' - -export { - signEip712Transaction, - type SignEip712TransactionParameters, - type SignEip712TransactionReturnType, - type SignEip712TransactionErrorType, -} from './actions/signTransaction.js' - export { writeContract as writeEip712Contract, type WriteContractParameters as WriteEip712ContractParameters, @@ -52,16 +38,12 @@ export { type WriteContractReturnType as WriteEip712ContractReturnType, } from './actions/writeContract.js' -export { - prepareTransactionRequest as prepareEip712TransactionRequest, - type PrepareTransactionRequestParameters as PrepareEip712TransactionRequestParameters, - type PrepareTransactionRequestErrorType as PrepareEip712TransactionRequestErrorType, - type PrepareTransactionRequestReturnType as PrepareEip712TransactionRequestReturnType, -} from './actions/prepareTransactionRequest.js' +export { prepareTransactionRequest as prepareEip712TransactionRequest } from './actions/prepareTransactionRequest.js' export { zkSync, zkSyncTestnet, + zkSyncSepoliaTestnet, } from './chains.js' export { eip712Actions, type Eip712Actions } from './decorators/eip712.js' diff --git a/src/chains/zksync/types.ts b/src/chains/zksync/types.ts index 55a9e81f3eb..00392ea0db7 100644 --- a/src/chains/zksync/types.ts +++ b/src/chains/zksync/types.ts @@ -1,10 +1,6 @@ import type { Abi, AbiEvent, Address, TypedDataDomain } from 'abitype' import type { ChainFormatters } from '~viem/index.js' -import type { - ChainConfig, - ChainConstants, - ChainFormatter, -} from '~viem/types/chain.js' +import type { Chain, ChainFormatter } from '~viem/types/chain.js' import type { Block, BlockTag } from '../../types/block.js' import type { FeeValuesEIP1559 } from '../../types/fee.js' import type { Log as Log_ } from '../../types/log.js' @@ -32,6 +28,7 @@ import type { TransactionType, } from '../../types/transaction.js' import type { UnionOmit } from '../../types/utils.js' +import type { formatters } from './formatters.js' import { isEIP712 } from './serializers.js' type EIP712Type = '0x71' @@ -355,7 +352,8 @@ export type EIP712Domain = { // Used to define the EIP712signer field in the chain. export type EIP712DomainFn< - TTransactionSerializable extends TransactionSerializable = TransactionSerializable, + TTransactionSerializable extends + TransactionSerializable = TransactionSerializable, TransactionToSign = {}, > = (transaction: TTransactionSerializable) => EIP712Domain @@ -375,14 +373,12 @@ export type TransactionRequestEIP712< } export type ChainEIP712< - formatters extends ChainFormatters | undefined = ChainFormatters | undefined, -> = ChainConstants & ChainConfigEIP712 - -export type ChainConfigEIP712< - formatters extends ChainFormatters | undefined = ChainFormatters | undefined, -> = ChainConfig & { - /** Return EIP712 Domain for EIP712 transaction */ - eip712domain?: ChainEIP712Domain | undefined + formatters extends ChainFormatters | undefined = typeof formatters, +> = Chain & { + custom: { + /** Return EIP712 Domain for EIP712 transaction */ + eip712domain?: ChainEIP712Domain | undefined + } } export type ChainEIP712Domain< diff --git a/src/types/chain.ts b/src/types/chain.ts index 1a0fa213391..3014abbe9bf 100644 --- a/src/types/chain.ts +++ b/src/types/chain.ts @@ -14,9 +14,12 @@ import type { IsUndefined, Prettify } from '../types/utils.js' import type { FormattedBlock } from '../utils/formatters/block.js' import type { SerializeTransactionFn } from '../utils/transaction/serializeTransaction.js' +type Custom = { [key: string]: unknown } + export type Chain< formatters extends ChainFormatters | undefined = ChainFormatters | undefined, > = { + custom?: Custom | undefined /** Collection of block explorers */ blockExplorers?: | { diff --git a/src/utils/transaction/assertRequest.ts b/src/utils/transaction/assertRequest.ts index c0b1b8a8174..720ed912602 100644 --- a/src/utils/transaction/assertRequest.ts +++ b/src/utils/transaction/assertRequest.ts @@ -1,3 +1,4 @@ +import type { Account } from '~viem/index.js' import { type ParseAccountErrorType, parseAccount, @@ -21,7 +22,11 @@ import type { ErrorType } from '../../errors/utils.js' import type { Chain } from '../../types/chain.js' import { isAddress } from '../address/isAddress.js' -export type AssertRequestParameters = Partial> +export type AssertRequestParameters< + TChain extends Chain | undefined = Chain | undefined, + TAccount extends Account | undefined = Account | undefined, + TChainOverride extends Chain | undefined = Chain | undefined, +> = Partial> export type AssertRequestErrorType = | InvalidAddressErrorType @@ -31,7 +36,11 @@ export type AssertRequestErrorType = | TipAboveFeeCapErrorType | ErrorType -export function assertRequest(args: AssertRequestParameters) { +export function assertRequest< + TChain extends Chain | undefined = Chain | undefined, + TAccount extends Account | undefined = Account | undefined, + TChainOverride extends Chain | undefined = Chain | undefined, +>(args: AssertRequestParameters) { const { account: account_, gasPrice,