The Virto Client SDK provides functionalities that allow web applications to interact with the blockchain using WebAuthn authentication directly from the browser. This SDK is designed to run in browser environments and leverages native WebAuthn APIs.
Configuration
importSDKfrom'@virtonetwork/sdk';constsdk=newSDK({federate_server:'https://your-federate-server.com/api',provider_url:'wss://your-blockchain-provider:12281',config:{wallet:'polkadotjs'// Wallet type to use (polkadotjs or virto)}});
Authentication Methods
The sdk.auth object provides the following methods:
register(user)
Registers a new user using a WebAuthn passkey. This method is only available in browser environments as it uses WebAuthn APIs.
Parameters:
user: Object containing the user profile and metadata
Returns: Promise that resolves with the registration response, including the blockchain address.
Example:
prepareRegistration(user)
Prepares registration data on the client side using WebAuthn. This method is used internally by register(), but can be useful for custom authentication flows.
Parameters:
user: Object containing the user profile and metadata (same format as register)
Returns: Promise that resolves with the prepared registration data.
Example:
connect(userId)
Authenticates a user with their existing passkey and establishes a session. This method is only available in browser environments.
Parameters:
userId: String - The unique identifier for the user (the same as profile.id used during registration)
Returns: Promise that resolves to an object containing session information.
Example:
prepareConnection(userId)
Prepares connection data on the client side using WebAuthn. This method is used internally by connect(), but can be useful for custom authentication flows.
Parameters:
userId: String - The unique identifier for the user
Returns: Promise that resolves with the prepared connection data.
Example:
isRegistered(userId)
Checks if a user is already registered with the federate server.
Parameters:
userId: String - The unique identifier for the user
Returns: Promise that resolves to a boolean indicating if the user is registered.
Example:
sign(userId, command)
Signs a blockchain extrinsic using the user's active session.
Parameters:
userId: String - The unique identifier for the user
command: Object containing the extrinsic details
Returns: Promise that resolves to an object containing the signed extrinsic.
Example:
Authentication Flow
The typical flow for implementing authentication with the Virto SDK is:
Verify registration: Use isRegistered() to check if the user is already registered
Registration (if necessary): If not registered, use register() to create a new passkey
Connection: Use connect() to authenticate the user with their existing passkey
Sign transactions: Once connected, use sign() to sign blockchain transactions
Error Handling
All methods may throw errors that should be handled appropriately:
try {
const preparedData = await sdk.auth.prepareRegistration({
profile: {
id: "alice@example.com",
name: "Alice Smith"
}
});
// The prepared data can be sent to your server
console.log("Prepared registration data:", preparedData);
} catch (error) {
console.error("Error preparing registration:", error.message);
}
try {
const preparedData = await sdk.auth.prepareConnection("alice@example.com");
// The prepared data can be sent to your server
console.log("Prepared connection data:", preparedData);
} catch (error) {
console.error("Error preparing connection:", error.message);
}
try {
const exists = await sdk.auth.isRegistered("alice@example.com");
if (exists) {
console.log("User is already registered, proceed to connect");
} else {
console.log("User needs to register first");
}
} catch (error) {
console.error("Error checking registration:", error.message);
}
{
hex: string, // Required: Hexadecimal representation of the extrinsic
url: string, // Optional: URL endpoint for the extrinsic
body: any // Optional: Additional data for the request
}
async function authenticateUser(userId) {
try {
// Check if the user is already registered
const isRegistered = await sdk.auth.isRegistered(userId);
if (!isRegistered) {
// Register a new user
await sdk.auth.register({
profile: {
id: userId,
name: "New User"
}
});
console.log("User successfully registered");
}
// Connect the user (log in)
const session = await sdk.auth.connect(userId);
console.log("User connected with address:", session.address);
return session;
} catch (error) {
console.error("Error in authentication process:", error);
throw error;
}
}
try {
const result = await sdk.auth.connect("alice@example.com");
// Process successful result
} catch (error) {
if (error.code === "E_CANT_GET_CREDENTIAL") {
console.error("Session expired or passkey not found");
// Prompt user to connect again
} else if (error.code === "E_ENVIRONMENT") {
console.error("This method can only be called in a browser environment");
} else {
console.error("Authentication error:", error.message);
}
}