UNPKG

@zerodev/sdk

Version:

A utility library for working with ERC-4337

135 lines (122 loc) 4.23 kB
import { EventEmitter } from "events" import { hexToBigInt } from "viem" import type { EIP1193Parameters, EIP1193RequestFn, Hash, Hex, SendTransactionParameters } from "viem" import type { KernelAccountClient } from "../clients/kernelAccountClient.js" export class KernelEIP1193Provider extends EventEmitter { private kernelClient: KernelAccountClient constructor(kernelClient: KernelAccountClient) { super() this.kernelClient = kernelClient } async request({ method, params = [] }: EIP1193Parameters): ReturnType<EIP1193RequestFn> { switch (method) { case "eth_requestAccounts": return this.handleEthRequestAccounts() case "eth_accounts": return this.handleEthAccounts() case "eth_sendTransaction": return this.handleEthSendTransaction(params) case "eth_sign": return this.handleEthSign(params as [string, string]) case "personal_sign": return this.handlePersonalSign(params as [string, string]) case "eth_signTypedData": case "eth_signTypedData_v4": return this.handleEthSignTypedDataV4(params as [string, string]) default: return this.kernelClient.transport.request({ method, params }) } } private async handleEthRequestAccounts(): Promise<string[]> { if (!this.kernelClient.account) { return [] } return [this.kernelClient.account.address] } private async handleEthAccounts(): Promise<string[]> { if (!this.kernelClient.account) { return [] } return [this.kernelClient.account.address] } private async handleEthSendTransaction(params: unknown): Promise<Hash> { const [tx] = params as [ Omit<SendTransactionParameters, "value"> & { value?: Hex } ] return this.kernelClient.sendTransaction({ ...tx, value: tx.value ? hexToBigInt(tx.value) : undefined } as SendTransactionParameters) } private async handleEthSign(params: [string, string]): Promise<string> { if (!this.kernelClient?.account) { throw new Error("account not connected!") } const [address, message] = params if ( address.toLowerCase() !== this.kernelClient.account.address.toLowerCase() ) { throw new Error( "cannot sign for address that is not the current account" ) } return this.kernelClient.signMessage({ message, account: this.kernelClient.account }) } private async handlePersonalSign( params: [string, string] ): Promise<string> { if (!this.kernelClient?.account) { throw new Error("account not connected!") } const [message, address] = params if ( address.toLowerCase() !== this.kernelClient.account.address.toLowerCase() ) { throw new Error( "cannot sign for address that is not the current account" ) } return this.kernelClient.signMessage({ message, account: this.kernelClient.account }) } private async handleEthSignTypedDataV4( params: [string, string] ): Promise<string> { if (!this.kernelClient?.account) { throw new Error("account not connected!") } const [address, typedDataJSON] = params const typedData = JSON.parse(typedDataJSON) if ( address.toLowerCase() !== this.kernelClient.account.address.toLowerCase() ) { throw new Error( "cannot sign for address that is not the current account" ) } return this.kernelClient.signTypedData({ account: this.kernelClient.account, domain: typedData.domain, types: typedData.types, message: typedData.message, primaryType: typedData.primaryType }) } }