Setup:By choosing this method, the user will be prompted to add their passkey to their device, either through the browser’s built-in passkey management, through a third-party passkey manager, or through their mobile device’s passkey management.Once the passkey is created by the user, it will be used to authenticate the user when making transactions. A same user can have multiple passkeys, and can use different passkeys for different purposes.Rather than implementing the passkey creation process yourself, you can use our Integrator SDK to easily create the passkey for your users.Installation
npm install @byzantine/integrator-sdk
Initialize the Byzantine Client
import { ByzantineClient } from '@byzantine/integrator-sdk';
// Prepare the webauthn stamper configuration
const webauthnStamperConfig: TWebauthnStamperConfig = {
// The RPID ("Relying Party ID") for your origin.
// For an origin named "https://www.example.com", the RPID is typically "example.com".
// If you're testing on localhost, the RPID should be "localhost".
rpId: string;
// The Relying Party name (e.g., "Example Corp")
rpName: string;
// Optional timeout value. Defaults to 10 minutes.
timeout?: number;
// Optional override for UV flag. Defaults to "preferred".
userVerification?: UserVerificationRequirement;
/**
* If you want to create discoverable credentials whenever possible both on Android and iOS,
* set `requireResidentKey` to `false` and `residentKey` to `preferred`.
* By doing so, it enables discoverable credential which is a self-contained key pair, stored on the end-user's device.
*/
// Resident key requirement (default: "preferred")
residentKey?: ResidentKeyRequirement;
// Whether to require resident key (default: false)
requireResidentKey?: boolean;
};
const client = new ByzantineClient({
webauthn: webauthnStamperConfig,
});
Usage example
import { PasskeyCreationConfig } from '@byzantine/integrator-sdk';
// Generate a random challenge for registration
const challenge = "your-challenge-generation-logic";
// Create the passkey configuration
const passkeyConfig: PasskeyCreationConfig = {
userId: "user-123",
userEmail: "[email protected]",
userName: "John Doe",
challenge: challenge,
};
// Create the passkey for the user
const { attestationData, challengeFromClientData } =
await client.webauthn.createPasskey(passkeyConfig);
// Now that the user's passkey is created, you have to register it within the user/entity account creation:
const response = await fetch(
"https://api.byzantine.fi/v1/submit/create-user",
{
method: "POST",
headers: { /* ... */ },
body: {
// ... other required fields
authenticators: [{
authenticatorName: "passkey",
challenge: challengeFromClientData,
attestation: attestationData
}]
},
}
);
Discoverable and non-discoverable credentials
A discoverable credential is a self-contained credential that is stored on the end-user’s device. For UX, the end-user is prompted to select their passkey from a list of their passkeys and choose which device/passkey they’d like to use.If you choose to create discoverable credentials for your users, it is not necessary to store their credential ID.
A non-discoverable credential is a credential that isn’t fully stored on the end-user’s device. The integrator must store the credential ID. For UX, the user is prompted to authenticate with their passkey directly without having to select it from a list.For non-discoverable credentials, you must store the credential ID returned from createPasskey, namely, attestationData.credentialId. When authenticating transactions, pass this credential ID as the second parameter to client.webauthn.getStamp(payload, credentialId) (cf. Passkey Authentication tab).
By default, the Byzantine SDK will create discoverable credentials when the device supports it. To create non-discoverable credentials, you can set the residentKey option to "discouraged":