Register a Passkey with the Service and attest the knowledge of a KeyPair.
Who is this for?
Browser Wallets that want to communicate with the service and other clients
Client
Creating a passkey and registering it with the service using an instance of the SignalClient
.
attestation
is a convenience method that handles the entire process of creating a passkey and registering it with the service.
The caller must provide a callback that will be called when a challenge is received from the service.
import * as nacl from ' tweetnacl '
import {toBase64URL} from ' @algorandfoundation/liquid-client/encoding '
// Sign in to the service with a new credential and wallet
await client . attestation (
// Callback when a challenge is received, return a signed challenge
async ( challenge : Uint8Array ) => ({
// The type of signature and public key
// The address of the account
// The signature of the challenge, signed by the account
signature: toBase64URL (nacl . sign . detached (challenge, seceretKey)),
// Optionally authenticate a remote peer
requestId: " <UUID_FROM_QR_CODE> " ,
device: ' Demo Web Wallet '
Stateless
Using the attestation
method to create a passkey without using the SignalClient
import * as nacl from ' tweetnacl '
import {attestation} from ' @algorandfoundation/liquid-client/attestation '
import {toBase64URL} from ' @algorandfoundation/liquid-client/encoding '
" https://my-liquid-service.com " ,
// Callback when a challenge is received, return a signed challenge
async ( challenge : Uint8Array ) => ({
// The type of signature and public key
// The address of the account
// The signature of the challenge, signed by the account
signature: toBase64URL (nacl . sign . detached (challenge, seceretKey)),
// Optionally authenticate a remote peer
device: ' Demo Web Wallet '
Manual
If you want to manually handle the process of creating a passkey, you can use the following methods and preforming
the three steps of the process.
🧮 Options
Manually fetching the PublicKeyCredentialCreationOptions from the service.
import {fetchAttestationRequest} from ' @algorandfoundation/liquid-client/attestation '
const encodedOptions = await fetchAttestationRequest ( " https://my-liquid-service.com " )
✨ Creating
Decode the options and create a new passkey.
import {decodeAddress, fromBase64Url} from " @algorandfoundation/liquid-client/encoding " ;
const options = { ... encodedOptions } ;
// Uint8Array of the user's id, is set as the encoded address for this type of key
options . user . id = decodeAddress (address);
// Must be string that is equal to the id bytes using the appropriate encoding
options . user . name = address;
// Friendly name to display for the user
options . user . displayName = " Hello World " ;
// Challenge from the service
options . challenge = fromBase64Url (options . challenge );
// Decode any known credentials
if (options . excludeCredentials ) {
for ( const cred of options . excludeCredentials ) {
cred . id = fromBase64Url (cred . id );
const credential = navigator . credentials . create ( {
🔐 Liquid Extension
Sign the challenge with an additional KeyPair.
import * as nacl from ' tweetnacl '
import {toBase64URL} from ' @algorandfoundation/liquid-client/encoding '
credential . clientExtensionResults = {
// The type of signature and public key, this is also used
// to determine the type of encoding for the user.id
// The address of the account
// The signature of the challenge, signed by the account
signature: toBase64URL (nacl . sign . detached (options . challenge , seceretKey)),
// Optionally authenticate a remote peer
requestId: " <UUID_FROM_QR_CODE> " ,
device: ' Demo Web Wallet '
🚚 Response
Encode and submit the passkey to the service.
import {fetchAttestationResponse} from ' @algorandfoundation/liquid-client/attestation '
import {toBase64URL} from ' @algorandfoundation/liquid-client/encoding '
const result = await fetchAttestationResponse ( " https://my-liquid-service.com " , {
rawId: toBase64URL (credential . rawId ) ,
clientDataJSON: toBase64URL (response . clientDataJSON ) ,
attestationObject: toBase64URL (response . attestationObject ) ,
clientExtensionResults: credential . clientExtensionResults