Create Wallet
This guide walks through creating a passkey-authenticated wallet with Veridex.
Prerequisites
- Veridex SDK installed (
npm install @veridex/sdk) - WebAuthn-compatible browser
- Device with biometric capability (FaceID, TouchID, fingerprint)
Basic Wallet Creation
1. Initialize the SDK
import { createSDK } from '@veridex/sdk';
const sdk = createSDK('base', {
network: 'testnet', // or 'mainnet'
relayerUrl: 'https://relayer.veridex.network',
});2. Register a Passkey
const credential = await sdk.passkey.register(
'user@example.com', // Username (shown in passkey prompt)
'My Veridex Wallet' // Display name
);
console.log('Credential ID:', credential.credentialId);
console.log('Key Hash:', credential.keyHash);
console.log('Public Key X:', credential.publicKeyX);
console.log('Public Key Y:', credential.publicKeyY);The browser will prompt the user for biometric authentication (FaceID, TouchID, etc.).
3. Get Your Vault Address
const vaultAddress = sdk.getVaultAddress();
console.log('Your vault address:', vaultAddress);
// This address is the SAME on all EVM chains!
// You can share it as your receiving addressReturning Users (Login)
Check for Existing Credentials
// Check if user has stored credentials
const storedCredentials = sdk.passkey.getAllStoredCredentials();
if (storedCredentials.length > 0) {
// User has previously registered
console.log(`Found ${storedCredentials.length} stored passkey(s)`);
} else {
// First time user
console.log('No passkey found, will need to register');
}Authenticate with Existing Passkey
// Authenticate — shows passkey picker with all available credentials
const { credential, signature } = await sdk.passkey.authenticate();
// Now the SDK is authenticated and ready to use
const vault = sdk.getVaultAddress();
console.log('Logged in as:', credential.keyHash);
console.log('Vault:', vault);Complete Flow Example
import { createSDK } from '@veridex/sdk';
async function connectWallet() {
const sdk = createSDK('base', {
network: 'testnet',
relayerUrl: 'https://relayer.veridex.network',
});
// Check for existing credentials
const storedCredentials = sdk.passkey.getAllStoredCredentials();
if (storedCredentials.length > 0) {
// Returning user — authenticate (shows passkey picker)
console.log('Logging in with existing passkey...');
await sdk.passkey.authenticate();
} else {
// New user — register
console.log('Creating new passkey wallet...');
await sdk.passkey.register(
'user@example.com',
'My Veridex Wallet'
);
}
// Get vault info
const vaultAddress = sdk.getVaultAddress();
const credential = sdk.passkey.getCredential();
return {
vaultAddress,
credentialId: credential?.credentialId,
};
}
// Usage
connectWallet()
.then(({ vaultAddress }) => {
console.log('Connected! Vault:', vaultAddress);
})
.catch((error) => {
console.error('Failed to connect:', error);
});React Component Example
import { useState, useEffect } from 'react';
import { createSDK } from '@veridex/sdk';
const sdk = createSDK('base', {
network: 'testnet',
relayerUrl: 'https://relayer.veridex.network',
});
export function ConnectButton() {
const [vault, setVault] = useState<string | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
// Check for existing credentials on mount
useEffect(() => {
const stored = sdk.passkey.getAllStoredCredentials();
if (stored.length > 0) {
// Auto-login if credentials exist
handleConnect();
}
}, []);
const handleConnect = async () => {
setLoading(true);
setError(null);
try {
const stored = sdk.passkey.getAllStoredCredentials();
if (stored.length > 0) {
await sdk.passkey.authenticate();
} else {
await sdk.passkey.register('user@example.com', 'My Wallet');
}
setVault(sdk.getVaultAddress());
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to connect');
} finally {
setLoading(false);
}
};
const handleDisconnect = () => {
// Clear the active credential from memory
sdk.passkey.clearCredential();
setVault(null);
};
if (vault) {
return (
<div className="flex items-center gap-4">
<span className="text-sm font-mono">
{vault.slice(0, 6)}...{vault.slice(-4)}
</span>
<button
onClick={handleDisconnect}
className="text-red-500 text-sm"
>
Disconnect
</button>
</div>
);
}
return (
<div>
<button
onClick={handleConnect}
disabled={loading}
className="bg-blue-600 text-white px-4 py-2 rounded-lg"
>
{loading ? 'Connecting...' : 'Connect with Passkey'}
</button>
{error && (
<p className="text-red-500 text-sm mt-2">{error}</p>
)}
</div>
);
}Credential Storage
By default, credentials are stored in localStorage under the veridex_credentials key. The PasskeyManager handles persistence automatically:
// Get all stored credentials
const all = sdk.passkey.getAllStoredCredentials();
// Manually save credentials (e.g., after migration)
sdk.passkey.saveCredentials(all);
// Add a credential to storage
sdk.passkey.addCredentialToStorage(credential);
// Check if any credentials exist
const hasCredentials = sdk.passkey.hasStoredCredentials();Error Handling
try {
await sdk.passkey.register('user@example.com', 'My Wallet');
} catch (error) {
if (error.name === 'NotAllowedError') {
// User cancelled the passkey prompt
console.log('User cancelled passkey creation');
} else if (error.name === 'NotSupportedError') {
// WebAuthn not supported
console.log('Passkeys not supported on this device');
} else if (error.name === 'SecurityError') {
// Not in secure context (need HTTPS)
console.log('HTTPS required for passkeys');
} else {
console.error('Unexpected error:', error);
}
}Agent Wallet Creation
For AI agents that need autonomous payment capabilities:
import { createAgentWallet } from '@veridex/agentic-payments';
// Use the credential from passkey registration
const agent = await createAgentWallet({
masterCredential: {
credentialId: credential.credentialId,
publicKeyX: credential.publicKeyX,
publicKeyY: credential.publicKeyY,
keyHash: credential.keyHash,
},
session: {
dailyLimitUSD: 50,
perTransactionLimitUSD: 10,
expiryHours: 24,
allowedChains: [10004], // Base Sepolia (Wormhole chain ID)
},
});
const status = agent.getSessionStatus();
console.log('Session valid:', status.isValid);
console.log('Agent wallet:', status.address);
console.log('Daily limit:', `$${status.limits!.dailyLimitUSD}`);Stacks Wallet
Create a wallet on Stacks with native passkey support:
import { createSDK } from '@veridex/sdk';
const stacksSdk = createSDK('stacks', { network: 'testnet' });
// Passkey verified natively via Clarity's secp256r1-verify
const credential = await stacksSdk.passkey.register('alice', 'My Stacks Wallet');
const vault = stacksSdk.getVaultAddress();
console.log('Stacks vault:', vault);