Skip to content

Commit

Permalink
fix: account hoisting fix for signEip712Transaction and `sendEip712…
Browse files Browse the repository at this point in the history
…Transaction` (#3109)

fix(zksync): fix account hoisting for `signEip712Transaction` and `sendEip712Transaction`
danijelTxFusion authored Dec 29, 2024

Unverified

No user is associated with the committer email.
1 parent 40b411a commit e03f948
Showing 6 changed files with 87 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/tall-pets-impress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"viem": patch
---

Fixed account hoisting for `signEip712Transaction` and `sendEip712Transaction` in ZKsync extension.
8 changes: 5 additions & 3 deletions src/zksync/actions/sendEip712Transaction.ts
Original file line number Diff line number Diff line change
@@ -92,13 +92,15 @@ export async function sendEip712Transaction<
request
>,
): Promise<SendEip712TransactionReturnType> {
const { chain = client.chain } = parameters
const { account: account_ = client.account, chain = client.chain } =
parameters

if (!parameters.account)
const account = account_ ? parseAccount(account_) : client.account

if (!account)
throw new AccountNotFoundError({
docsPath: '/docs/actions/wallet/sendTransaction',
})
const account = parseAccount(parameters.account)

try {
assertEip712Request(parameters)
2 changes: 1 addition & 1 deletion src/zksync/actions/signEip712Transaction.test.ts
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import { expect, test } from 'vitest'

import { accounts } from '~test/src/constants.js'

import { anvilZksync } from '../../../test/src/anvil.js'
import { anvilZksync } from '~test/src/anvil.js'
import { privateKeyToAccount } from '../../accounts/privateKeyToAccount.js'
import type { ZksyncTransactionRequestEIP712 } from '../../zksync/index.js'
import { signTransaction } from './signTransaction.js'
7 changes: 5 additions & 2 deletions src/zksync/actions/signEip712Transaction.ts
Original file line number Diff line number Diff line change
@@ -53,6 +53,8 @@ export type SignEip712TransactionErrorType = SignTransactionErrorType
/**
* Signs an EIP712 transaction.
*
*
* @param client - Client to use
* @param args - {@link SignTransactionParameters}
* @returns The signed serialized transaction. {@link SignTransactionReturnType}
*
@@ -102,11 +104,12 @@ export async function signEip712Transaction<
...transaction
} = args

if (!account_)
const account = account_ ? parseAccount(account_) : client.account

if (!account)
throw new AccountNotFoundError({
docsPath: '/docs/actions/wallet/signTransaction',
})
const account = parseAccount(account_)

assertEip712Request({
account,
57 changes: 56 additions & 1 deletion src/zksync/decorators/eip712.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { expect, test } from 'vitest'

import { greeterContract } from '~test/src/abis.js'
import { anvilZksync } from '~test/src/anvil.js'
import { accounts } from '~test/src/constants.js'
import { anvilZksync } from '../../../test/src/anvil.js'
import { privateKeyToAccount } from '../../accounts/privateKeyToAccount.js'
import { simulateContract } from '../../actions/index.js'
import type { EIP1193RequestFn } from '../../types/eip1193.js'
@@ -11,6 +11,9 @@ import { eip712WalletActions } from './eip712.js'
const client = anvilZksync.getClient()
const zksyncClient = client.extend(eip712WalletActions())

const clientWithAccount = anvilZksync.getClient({ account: true })
const zksyncClientWithAccount = clientWithAccount.extend(eip712WalletActions())

test('default', async () => {
expect(eip712WalletActions()(client)).toMatchInlineSnapshot(`
{
@@ -47,6 +50,32 @@ test('sendTransaction', async () => {
expect(result).toBeDefined()
})

test('sendTransaction with account hoisting', async () => {
zksyncClientWithAccount.request = (async ({ method, params }) => {
if (method === 'eth_sendRawTransaction')
return '0x9afe47f3d95eccfc9210851ba5f877f76d372514a26b48bad848a07f77c33b87'
if (method === 'eth_signTypedData_v4')
return '0x71f8da808502540be4008502540be40083026c369470997970c51812dc3a010c7d01b50e0d17dc79c88502540be4000082014480808201448082c350c0b841cee039b6d00ff61277ac416a0c98d23d9bfc64e024cd3d3f946ab33cdfe4576b5e4d3bed2c0a2383a1a13f0777b46ca2c19edefb67d8d8584af7d963f5284ca81bf85b94fd9ae5ebb0f6656f4b77a0e99dcbc5138d54b0bab8448c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000'
return anvilZksync.getClient().request({ method, params } as any)
}) as EIP1193RequestFn
const client = zksyncClientWithAccount.extend(eip712WalletActions())

const result = await client.sendTransaction({
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
maxFeePerGas: 10000000000n,
maxPriorityFeePerGas: 10000000000n,
gas: 158774n,
value: 10000000000n,
data: '0x0',
paymaster: '0xFD9aE5ebB0F6656f4b77a0E99dCbc5138d54b0BA',
paymasterInput:
'0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000',
type: 'eip712',
gasPerPubdata: 50000n,
})
expect(result).toBeDefined()
})

test('signTransaction', async () => {
const signature = await zksyncClient.signTransaction({
account: privateKeyToAccount(accounts[0].privateKey),
@@ -65,6 +94,32 @@ test('signTransaction', async () => {
expect(signature).toBeDefined()
})

test('signTransaction with account hoisting', async () => {
zksyncClientWithAccount.request = (async ({ method, params }) => {
if (method === 'eth_signTypedData_v4')
return '0x71f8da808502540be4008502540be40083026c369470997970c51812dc3a010c7d01b50e0d17dc79c88502540be4000082014480808201448082c350c0b841cee039b6d00ff61277ac416a0c98d23d9bfc64e024cd3d3f946ab33cdfe4576b5e4d3bed2c0a2383a1a13f0777b46ca2c19edefb67d8d8584af7d963f5284ca81bf85b94fd9ae5ebb0f6656f4b77a0e99dcbc5138d54b0bab8448c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000'
return anvilZksync
.getClient({ account: true })
.request({ method, params } as any)
}) as EIP1193RequestFn
const client = zksyncClientWithAccount.extend(eip712WalletActions())

const signature = await client.signTransaction({
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
maxFeePerGas: 10000000000n,
maxPriorityFeePerGas: 10000000000n,
gas: 158774n,
value: 10000000000n,
data: '0x0',
paymaster: '0xFD9aE5ebB0F6656f4b77a0E99dCbc5138d54b0BA',
paymasterInput:
'0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000',
type: 'eip712',
gasPerPubdata: 50000n,
})
expect(signature).toBeDefined()
})

test('writeContract', async () => {
zksyncClient.request = (async ({ method, params }) => {
if (method === 'eth_sendRawTransaction')
17 changes: 15 additions & 2 deletions test/src/zksync.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { zksyncLocalNode } from '~viem/chains/index.js'
import { createClient } from '~viem/clients/createClient.js'
import { http } from '~viem/index.js'
import { accounts } from './constants.js'
import { accounts as acc } from './constants.js'

export const zksyncClientLocalNode = createClient({
chain: zksyncLocalNode,
transport: http(),
})

export const zksyncClientLocalNodeWithAccount = createClient({
account: accounts[0].address,
account: acc[0].address,
chain: zksyncLocalNode,
transport: http(),
})
@@ -209,3 +209,16 @@ export function mockClientPublicActionsL2(client: any) {
return mockRequestReturnData(method)
}
}

export const accounts = [
{
address: '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049',
privateKey:
'0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110',
},
{
address: '0xa61464658AfeAf65CccaaFD3a512b69A83B77618',
privateKey:
'0xac1e735be8536c6534bb4f17f06f6afc73b2b5ba84ac2cfb12f7461b20c0bbe3',
},
] as const

0 comments on commit e03f948

Please sign in to comment.