@zerodev/sdk
Version:
A utility library for working with ERC-4337
118 lines (111 loc) • 3.38 kB
text/typescript
// Copied from: https://github.com/pimlicolabs/permissionless.js/blob/main/packages/permissionless/utils/toOwner.ts
import {
type Account,
type Address,
type Chain,
type EIP1193Provider,
type EIP1193RequestFn,
type EIP1474Methods,
type LocalAccount,
type Transport,
type TypedData,
type TypedDataDefinition,
type WalletClient,
createWalletClient,
custom
} from "viem"
import { toAccount } from "viem/accounts"
import type { SmartAccount } from "viem/account-abstraction"
import { signAuthorization, signMessage, signTypedData } from "viem/actions"
import type { Signer } from "../types/index.js"
export async function toSigner({
signer,
address
}: {
signer: Signer
address?: Address
}): Promise<LocalAccount | SmartAccount> {
if (
"type" in signer &&
(signer.type === "local" || signer.type === "smart")
) {
return signer as LocalAccount | SmartAccount
}
let walletClient:
| WalletClient<Transport, Chain | undefined, Account>
| undefined = undefined
if ("request" in signer && !signer?.account) {
if (!address) {
address = (
await Promise.any([
(signer.request as EIP1193RequestFn<EIP1474Methods>)({
method: "eth_requestAccounts"
}),
(signer.request as EIP1193RequestFn<EIP1474Methods>)({
method: "eth_accounts"
})
])
)[0]
}
if (!address) {
// For TS to be happy
throw new Error("address is required")
}
walletClient = createWalletClient({
account: address,
transport: custom(signer as EIP1193Provider)
})
}
if (!walletClient) {
walletClient = signer as WalletClient<
Transport,
Chain | undefined,
Account
>
}
return toAccount({
address: walletClient.account.address,
async signMessage({ message }) {
return signMessage(
walletClient as WalletClient<
Transport,
Chain | undefined,
Account
>,
{ message }
)
},
async signTypedData(typedData) {
const { primaryType, domain, message, types } =
typedData as TypedDataDefinition<TypedData, string>
return signTypedData(
walletClient as WalletClient<
Transport,
Chain | undefined,
Account
>,
{
primaryType,
domain,
message,
types
}
)
},
async signTransaction(_) {
throw new Error(
"Smart account signer doesn't need to sign transactions"
)
},
async signAuthorization(authorization) {
return signAuthorization(
walletClient as WalletClient<
Transport,
Chain | undefined,
Account
>,
authorization
)
}
}) as LocalAccount
}