Skip to content

Commit

Permalink
fix: add parseEip712Transaction util function
Browse files Browse the repository at this point in the history
  • Loading branch information
nikola-bozin-txfusion authored and danijelTxFusion committed Nov 9, 2024
1 parent 413910b commit 09689f7
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 29 deletions.
8 changes: 4 additions & 4 deletions src/account-abstraction/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ export {
type ToWebAuthnAccountErrorType,
toWebAuthnAccount,
} from './accounts/toWebAuthnAccount.js'
export {
type SmartAccount,
type SmartAccountImplementation,
type WebAuthnAccount,
export type {
SmartAccount,
SmartAccountImplementation,
WebAuthnAccount,
} from './accounts/types.js'

export {
Expand Down
20 changes: 10 additions & 10 deletions src/experimental/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,17 @@ export {
type SignAuthorizationErrorType,
signAuthorization,
} from './eip7702/actions/signAuthorization.js'
export {
type Authorization,
type SignedAuthorization,
type AuthorizationList,
type SignedAuthorizationList,
type SerializedAuthorization,
type SerializedAuthorizationList,
export type {
Authorization,
SignedAuthorization,
AuthorizationList,
SignedAuthorizationList,
SerializedAuthorization,
SerializedAuthorizationList,
} from './eip7702/types/authorization.js'
export {
type RpcAuthorizationList,
type RpcAuthorization,
export type {
RpcAuthorizationList,
RpcAuthorization,
} from './eip7702/types/rpc.js'
export {
type HashAuthorizationParameters,
Expand Down
30 changes: 15 additions & 15 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,24 @@ export {
type GetContractParameters,
type GetContractReturnType,
} from './actions/getContract.js'
export {
type GetContractEventsErrorType,
type GetContractEventsParameters,
type GetContractEventsReturnType,
export type {
GetContractEventsErrorType,
GetContractEventsParameters,
GetContractEventsReturnType,
} from './actions/public/getContractEvents.js'
export {
type GetEip712DomainErrorType,
type GetEip712DomainParameters,
type GetEip712DomainReturnType,
export type {
GetEip712DomainErrorType,
GetEip712DomainParameters,
GetEip712DomainReturnType,
} from './actions/public/getEip712Domain.js'
export {
type AddChainErrorType,
type AddChainParameters,
export type {
AddChainErrorType,
AddChainParameters,
} from './actions/wallet/addChain.js'
export {
type CallErrorType,
type CallParameters,
type CallReturnType,
export type {
CallErrorType,
CallParameters,
CallReturnType,
} from './actions/public/call.js'
export type {
CreateBlockFilterErrorType,
Expand Down
68 changes: 68 additions & 0 deletions src/zksync/utils/parseEip712Transaction.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { expect, test } from 'vitest'
import { parseEip712Transaction } from './parseEip712Transaction.js'

test('default', () => {
const serializedTransaction =
'0x71f87f8080808094a61464658afeaf65cccaafd3a512b69a83b77618830f42408001a073a20167b8d23b610b058c05368174495adf7da3a4ed4a57eb6dbdeb1fafc24aa02f87530d663a0d061f69bb564d2c6fb46ae5ae776bbd4bd2a2a4478b9cd1b42a82010e9436615cf349d7f6344891b1e7ca7c72883f5dc04982c350c080c0'
const transaction = parseEip712Transaction(serializedTransaction)
expect(transaction).toEqual({
type: 'eip712',
nonce: 0,
maxPriorityFeePerGas: 0n,
maxFeePerGas: 0n,
gas: 0n,
to: '0xa61464658afeaf65cccaafd3a512b69a83b77618',
value: 1000000n,
data: '0x',
chainId: 270,
from: '0x36615cf349d7f6344891b1e7ca7c72883f5dc049',
v: 1n,
r: '0x73a20167b8d23b610b058c05368174495adf7da3a4ed4a57eb6dbdeb1fafc24a',
s: '0x2f87530d663a0d061f69bb564d2c6fb46ae5ae776bbd4bd2a2a4478b9cd1b42a',
gasPerPubdata: 50000n,
factoryDeps: [],
customSignature: '0x',
paymaster: undefined,
paymasterInput: undefined,
})
})

test('with paymaster', async () => {
const serializedTransaction =
'0x71f8c880808080808000820144808082014494000000000000000000000000000000000000000082c350c0b841bb509f381d29a038bd2f700bd6a1f1138edfd7a3cf7234c13a03b01a023a30aa53e6bd5e6a50fdcdcf74587c9395b8a314690abbc85aadab5ebcb7678994eacf1bf85b94fd9ae5ebb0f6656f4b77a0e99dcbc5138d54b0bab8448c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000'

const transaction = parseEip712Transaction(serializedTransaction)
expect(transaction).toEqual({
type: 'eip712',
nonce: 0,
maxPriorityFeePerGas: 0n,
maxFeePerGas: 0n,
gas: 0n,
to: '0x',
value: 0n,
data: '0x00',
chainId: 324,
from: '0x0000000000000000000000000000000000000000',
v: 324n,
r: '0x',
s: '0x',
gasPerPubdata: 50000n,
factoryDeps: [],
customSignature:
'0xbb509f381d29a038bd2f700bd6a1f1138edfd7a3cf7234c13a03b01a023a30aa53e6bd5e6a50fdcdcf74587c9395b8a314690abbc85aadab5ebcb7678994eacf1b',
paymaster: '0xfd9ae5ebb0f6656f4b77a0e99dcbc5138d54b0ba',
paymasterInput:
'0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000',
})
})

test('not eip712 transaction', () => {
const serializedTransaction =
'0x73a20167b8d23b610b058c05368174495adf7da3a4ed4a57eb6dbdeb1fafc24aaf87530d663a0d061f69bb564d2c6fb46ae5ae776bbd4bd2a2a4478b9cd1b42a'

try {
parseEip712Transaction(serializedTransaction)
} catch (e: any) {
expect(e.shortMessage).toEqual('transaction type must be eip712')
}
})
57 changes: 57 additions & 0 deletions src/zksync/utils/parseEip712Transaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { BaseError } from '../../errors/base.js'
import type { Hex } from '../../types/misc.js'
import {
fromHex,
fromRlp,
hexToBigInt,
hexToNumber,
} from '../../utils/index.js'
import type { ZksyncTransactionSerializableEIP712 } from '../types/transaction.js'

export function parseEip712Transaction(
transaction: Hex,
): ZksyncTransactionSerializableEIP712 {
const payload = fromHex(transaction, 'bytes')
if (payload[0] !== 113) throw new BaseError('transaction type must be eip712')

function validHex(value: Hex): Hex {
if (!value || value === '0x') return '0x0'
return value
}

function parsePaymasterArray(arr: Hex[]) {
if (arr.length === 0) return undefined
if (arr.length !== 2)
throw new BaseError(
`Invalid paymaster parameters, expected to have length of 2, found ${arr.length}!`,
)

return {
paymaster: arr[0],
paymasterInput: arr[1],
}
}

const raw = fromRlp(payload.slice(1)) as Hex[]
const paymasterParams = parsePaymasterArray(raw[15] as unknown as Hex[])
return {
type: 'eip712',
nonce: hexToNumber(validHex(raw[0])),
maxPriorityFeePerGas: hexToBigInt(validHex(raw[1])),
maxFeePerGas: hexToBigInt(validHex(raw[2])),
gas: hexToBigInt(validHex(raw[3])),
to: raw[4],
value: hexToBigInt(validHex(raw[5])),
data: raw[6],
v: hexToBigInt(validHex(raw[7])),
r: raw[8],
s: raw[9],
chainId: hexToNumber(validHex(raw[10])),
from: raw[11],
gasPerPubdata: hexToBigInt(validHex(raw[12])),
factoryDeps: raw[13] as unknown as Hex[],
customSignature: raw[14],
paymaster: paymasterParams?.paymaster,
paymasterInput: paymasterParams?.paymasterInput,
}
}

0 comments on commit 09689f7

Please sign in to comment.