UNPKG

@biconomy/abstractjs

Version:

SDK for Biconomy integration with support for account abstraction, smart accounts, ERC-4337.

94 lines 3.51 kB
import { createWalletClient, custom, getAddress, hexToBytes } from "viem"; import { toAccount } from "viem/accounts"; import { signTypedData } from "viem/actions"; import { getAction } from "viem/utils"; /** * Converts various signer types into a standardized LocalAccount format. * Handles conversion from different wallet implementations including ethers.js wallets, * EIP-1193 providers, and existing LocalAccounts. * * @param signer - The signer to convert, must implement required signing methods * @param address - Optional address to use for the account * @returns A Promise resolving to a LocalAccount * * @throws {Error} When signTransaction is called (not supported) * @throws {Error} When address is required but not provided */ export async function toSigner({ signer, address }) { if (!signer) { throw new Error("Signer is required"); } if ("provider" in signer) { const wallet = signer; const address = await wallet.getAddress(); return toAccount({ address: getAddress(address), async signMessage({ message }) { if (typeof message === "string") { return await wallet.signMessage(message); } if (typeof message?.raw === "string") { return await wallet.signMessage(hexToBytes(message.raw)); } return await wallet.signMessage(message.raw); }, async signTransaction(_) { throw new Error("Not supported"); }, async signTypedData(typedData) { // ethers doesn't expect EIP712Domain in types (it adds it automatically) // so we need to remove it to avoid "ambiguous primary types" error const { EIP712Domain: _, ...typesWithoutDomain } = typedData.types; return wallet.signTypedData(typedData.domain, typesWithoutDomain, typedData.message); } }); } if ("type" in signer && signer.type === "local") { return signer; } let walletClient = undefined; if ("request" in signer) { if (!address) { try { ; [address] = await signer.request({ method: "eth_requestAccounts" }); } catch { ; [address] = await signer.request({ method: "eth_accounts" }); } } if (!address) { // For TS to be happy throw new Error("address is required"); } walletClient = createWalletClient({ account: address, transport: custom(signer) }); } if (!walletClient) { walletClient = signer; } const addressFromWalletClient = walletClient?.account?.address ?? (await walletClient?.getAddresses())?.[0]; if (!addressFromWalletClient) { throw new Error("address not found in wallet client"); } return toAccount({ address: addressFromWalletClient, async signMessage({ message }) { return walletClient.signMessage({ message }); }, async signTypedData(typedData) { return getAction(walletClient, signTypedData, "signTypedData")(typedData); }, async signTransaction(_) { throw new Error("Not supported"); } }); } //# sourceMappingURL=toSigner.js.map