UNPKG

viem

Version:

TypeScript Interface for Ethereum

123 lines (108 loc) 3.65 kB
import { InvalidAddressError } from '../../errors/address.js' import { BaseError } from '../../errors/base.js' import { InvalidChainIdError } from '../../errors/chain.js' import type { ChainSerializers } from '../../types/chain.js' import type { TransactionSerializable } from '../../types/transaction.js' import { isAddress } from '../../utils/address/isAddress.js' import { concatHex } from '../../utils/data/concat.js' import { toHex } from '../../utils/encoding/toHex.js' import { toRlp } from '../../utils/encoding/toRlp.js' import { type SerializeTransactionFn, serializeTransaction as serializeTransaction_, } from '../../utils/transaction/serializeTransaction.js' import type { ZkSyncTransactionSerializable, ZkSyncTransactionSerializableEIP712, ZkSyncTransactionSerializedEIP712, } from './types.js' export const serializeTransaction: SerializeTransactionFn< ZkSyncTransactionSerializable > = (tx, signature) => { if (isEIP712(tx)) return serializeTransactionEIP712(tx as ZkSyncTransactionSerializableEIP712) return serializeTransaction_(tx as TransactionSerializable, signature) } export const serializers = { transaction: serializeTransaction, } as const satisfies ChainSerializers ////////////////////////////////////////////////////////////////////////////// // Serializers export type SerializeTransactionEIP712ReturnType = ZkSyncTransactionSerializedEIP712 function serializeTransactionEIP712( transaction: ZkSyncTransactionSerializableEIP712, ): SerializeTransactionEIP712ReturnType { const { chainId, gas, nonce, to, from, value, maxFeePerGas, maxPriorityFeePerGas, customSignature, factoryDeps, paymaster, paymasterInput, gasPerPubdata, data, } = transaction assertTransactionEIP712(transaction) const serializedTransaction = [ nonce ? toHex(nonce) : '0x', maxPriorityFeePerGas ? toHex(maxPriorityFeePerGas) : '0x', maxFeePerGas ? toHex(maxFeePerGas) : '0x', gas ? toHex(gas) : '0x', to ?? '0x', value ? toHex(value) : '0x', data ?? '0x', toHex(chainId), toHex(''), toHex(''), toHex(chainId), from ?? '0x', gasPerPubdata ? toHex(gasPerPubdata) : '0x', factoryDeps ?? [], customSignature ?? '0x', // EIP712 signature paymaster && paymasterInput ? [paymaster, paymasterInput] : [], ] return concatHex([ '0x71', toRlp(serializedTransaction), ]) as SerializeTransactionEIP712ReturnType } ////////////////////////////////////////////////////////////////////////////// // Utilities function isEIP712(transaction: ZkSyncTransactionSerializable) { if ( 'customSignature' in transaction || 'paymaster' in transaction || 'paymasterInput' in transaction || 'gasPerPubdata' in transaction || 'factoryDeps' in transaction ) return true return false } export function assertTransactionEIP712( transaction: ZkSyncTransactionSerializableEIP712, ) { const { chainId, to, from, paymaster, paymasterInput } = transaction if (chainId <= 0) throw new InvalidChainIdError({ chainId }) if (to && !isAddress(to)) throw new InvalidAddressError({ address: to }) if (from && !isAddress(from)) throw new InvalidAddressError({ address: from }) if (paymaster && !isAddress(paymaster)) throw new InvalidAddressError({ address: paymaster }) if (paymaster && !paymasterInput) { throw new BaseError( '`paymasterInput` must be provided when `paymaster` is defined', ) } if (!paymaster && paymasterInput) { throw new BaseError( '`paymaster` must be provided when `paymasterInput` is defined', ) } }