import { startAuthentication, startRegistration, bufferToBase64URLString, } from '@simplewebauthn/browser'; import { PublicKeyCredentialCreationOptionsJSON } from '@simplewebauthn/typescript-types'; import { decodeRegistrationCredential, decodeAuthenticationCredential, } from '@prex0/prex-webauthn'; import { decodeAbiParameters, Hex, toBytes } from 'viem'; function getChallenge() { const array = new Uint8Array(32); crypto.getRandomValues(array); return bufferToBase64URLString(array.buffer); } export async function registerByWebAuthn( options: PublicKeyCredentialCreationOptionsJSON ) { const response = await startRegistration(options); const decodedCred = await decodeRegistrationCredential(response); return { response, decodedCred, }; } export async function getCredentialID() { const credential = await startAuthentication({ challenge: getChallenge(), userVerification: 'required', }); return credential.id; } export async function signByPasskey(message: string, passkeyIds?: string[]) { const challenge = bufferToBase64URLString(getChallengeBuffer(message)); const credential = await startAuthentication({ challenge: challenge, userVerification: 'required', allowCredentials: passkeyIds?.map((id) => ({ id: id, type: 'public-key', })), }); const decodedCred = decodeAuthenticationCredential(credential); return { userHandle: decodedCred.userHandle, name: '', signature: decodedCred.signature, }; } function getChallengeBuffer(message: string) { return new Uint8Array(toBytes(message)).buffer; } // decode publicKey for Smart Wallet export function decodePublicKey(publicKey: Hex) { return decodeAbiParameters( [{ type: 'uint256' }, { type: 'uint256' }], publicKey ); }