UNPKG

permissionless

Version:

A utility library for working with ERC-4337

143 lines (129 loc) 4.14 kB
// import { Base64 } from "ox" import type { Account, Chain, Client, Hex, Transport } from "viem" import type { PasskeyServerRpcSchema } from "../../types/passkeyServer.js" import { getOxExports } from "../../utils/ox.js" export type VerifyAuthenticationParameters = { raw: { id: string rawId: ArrayBuffer authenticatorAttachment: string response: { authenticatorData?: ArrayBuffer signature?: ArrayBuffer userHandle?: ArrayBuffer clientDataJSON: ArrayBuffer } getClientExtensionResults: () => Record<string, unknown> type: string } uuid: string } export type VerifyAuthenticationReturnType = { success: boolean id: string publicKey: Hex userName: string } export const verifyAuthentication = async ( client: Client< Transport, Chain | undefined, Account | undefined, PasskeyServerRpcSchema >, args: VerifyAuthenticationParameters ): Promise<VerifyAuthenticationReturnType> => { const { raw, uuid } = args const { Base64 } = await getOxExports() let responseAuthenticatorData: string if ("authenticatorData" in raw.response) { responseAuthenticatorData = Base64.fromBytes( new Uint8Array(raw.response.authenticatorData as ArrayBuffer), { url: true } ) } else { throw new Error("authenticatorData not found in the signature") } let signature: string if ("signature" in raw.response) { signature = Base64.fromBytes( new Uint8Array(raw.response.signature as ArrayBuffer), { pad: false, url: true } ) } else { throw new Error("signature not found in the signature") } let userHandle: string | undefined if ("userHandle" in raw.response) { userHandle = Base64.fromBytes( new Uint8Array(raw.response.userHandle as ArrayBuffer), { pad: false, url: true } ) } const serverResponse = await client.request( { method: "pks_verifyAuthentication", params: [ { id: raw.id, rawId: Base64.fromBytes(new Uint8Array(raw.rawId), { pad: false, url: true }), authenticatorAttachment: raw.authenticatorAttachment as | "cross-platform" | "platform", response: { clientDataJSON: Base64.fromBytes( new Uint8Array(raw.response.clientDataJSON), { pad: false, url: true } ), authenticatorData: responseAuthenticatorData, signature, userHandle }, clientExtensionResults: raw.getClientExtensionResults(), type: raw.type as "public-key" }, { uuid } ] }, { retryCount: 0 } ) const success = Boolean(serverResponse?.success) const id = serverResponse?.id const publicKey = serverResponse?.publicKey const userName = serverResponse?.userName if (typeof id !== "string") { throw new Error("Invalid passkey id returned from server") } if (typeof publicKey !== "string" || !publicKey.startsWith("0x")) { throw new Error( "Invalid public key returned from server - must be hex string starting with 0x" ) } if (typeof userName !== "string") { throw new Error("Invalid user name returned from server") } return { success, id, publicKey: publicKey as Hex, userName } }