SDK Reference
Complete API reference for the Veridex Core SDK (@veridex/sdk).
Installation
npm install @veridex/sdk ethersInitialization
createSDK
Creates a new VeridexSDK instance with sensible defaults.
import { createSDK } from '@veridex/sdk';
const sdk = createSDK(chain, config?);Parameters:
| Parameter | Type | Description |
|---|---|---|
chain | ChainName | Chain name (see supported chains below) |
config | SimpleSDKConfig | Optional configuration |
Supported chain names: 'base', 'optimism', 'arbitrum', 'ethereum', 'polygon', 'monad', 'solana', 'aptos', 'sui', 'starknet', 'stacks'
Config:
interface SimpleSDKConfig {
network?: 'testnet' | 'mainnet'; // Default: 'testnet'
rpcUrl?: string; // Custom RPC URL
relayerUrl?: string; // Relayer for gasless transactions
relayerApiKey?: string; // Relayer API key
sponsorPrivateKey?: string; // For gasless vault creation
integratorSponsorKey?: string; // Platform-level sponsorship
rpcUrls?: Record<ChainName, string>; // Multi-chain RPC URLs
}Example:
// Simplest — testnet by default
const sdk = createSDK('base');
// With relayer for gasless transactions
const sdk = createSDK('base', {
network: 'testnet',
relayerUrl: 'https://relayer.veridex.network',
});
// Stacks
const stacksSdk = createSDK('stacks', { network: 'testnet' });VeridexSDK (Direct Constructor)
For full control over chain configuration, use the VeridexSDK class directly with an EVMClient. This is the pattern used for multi-chain support.
import { VeridexSDK } from '@veridex/sdk';
import { EVMClient } from '@veridex/sdk/chains/evm';
const evmClient = new EVMClient({
chainId: 84532,
wormholeChainId: 10004,
rpcUrl: 'https://sepolia.base.org',
hubContractAddress: '0x66D87dE68327f48A099c5B9bE97020Feab9a7c82',
wormholeCoreBridge: '0x79A1027a6A159502049F10906D333EC57E95F083',
name: 'Base Sepolia',
explorerUrl: 'https://sepolia.basescan.org',
vaultFactory: '0xCFaEb5652aa2Ee60b2229dC8895B4159749C7e53',
vaultImplementation: '0x0d13367C16c6f0B24eD275CC67C7D9f42878285c',
});
const sdk = new VeridexSDK({
chain: evmClient,
persistWallet: true,
testnet: true,
relayerUrl: '/api/relayer',
relayerApiKey: process.env.NEXT_PUBLIC_RELAYER_API_KEY,
queryApiKey: process.env.NEXT_PUBLIC_WORMHOLE_QUERY_API_KEY,
sponsorPrivateKey: process.env.NEXT_PUBLIC_VERIDEX_SPONSOR_KEY,
chainRpcUrls: {
10004: 'https://sepolia.base.org',
10005: 'https://sepolia.optimism.io',
10003: 'https://sepolia-rollup.arbitrum.io/rpc',
},
});Config:
interface VeridexSDKConfig {
chain: EVMClient; // Hub chain client
persistWallet?: boolean; // Persist wallet state (default: true)
testnet?: boolean; // Use testnet (default: true)
relayerUrl?: string; // Relayer URL for gasless transactions
relayerApiKey?: string; // Relayer API key
queryApiKey?: string; // Wormhole query API key
sponsorPrivateKey?: string; // For gasless vault creation
integratorSponsorKey?: string; // Platform-level sponsorship
chainRpcUrls?: Record<number, string>; // RPC URLs keyed by Wormhole chain ID
}Dynamic Import (SSR-Safe)
For Next.js apps, use dynamic imports to avoid SSR issues:
let sdkInstance: any = null;
export async function getVeridexSDK() {
if (!sdkInstance) {
const { createSDK } = await import('@veridex/sdk');
sdkInstance = createSDK('base', {
network: 'testnet',
relayerUrl: process.env.NEXT_PUBLIC_RELAYER_URL,
});
}
return sdkInstance;
}Convenience Factories
import { createHubSDK, createTestnetSDK, createMainnetSDK, createSessionSDK } from '@veridex/sdk';
const hubSdk = createHubSDK(); // Base hub chain
const testSdk = createTestnetSDK('optimism'); // Force testnet
const mainSdk = createMainnetSDK('base'); // Force mainnet
const sessSdk = createSessionSDK('base'); // Session-optimizedPasskey Management (sdk.passkey)
The passkey property is a PasskeyManager instance.
sdk.passkey.register
Register a new passkey with biometric authentication.
const credential = await sdk.passkey.register(username, displayName);Parameters:
| Parameter | Type | Description |
|---|---|---|
username | string | Username (shown in passkey prompt) |
displayName | string | Display name for the credential |
Returns: Promise<PasskeyCredential>
interface PasskeyCredential {
credentialId: string;
publicKeyX: bigint;
publicKeyY: bigint;
keyHash: string;
}sdk.passkey.authenticate
Authenticate with an existing passkey (shows passkey picker).
const { credential, signature } = await sdk.passkey.authenticate();Returns: Promise<{ credential: PasskeyCredential; signature: WebAuthnSignature }>
sdk.passkey.getCredential
Get the currently active credential (set by register or authenticate).
const credential = sdk.passkey.getCredential();Returns: PasskeyCredential | null
sdk.passkey.setCredential
Manually set the active credential.
sdk.passkey.setCredential(credential);sdk.passkey.getAllStoredCredentials
Get all passkey credentials saved in local storage.
const credentials = sdk.passkey.getAllStoredCredentials();Returns: PasskeyCredential[]
sdk.passkey.sign
Sign a challenge with the passkey.
const signature = await sdk.passkey.sign(challenge);Returns: Promise<WebAuthnSignature>
sdk.passkey.saveToLocalStorage
Save the current credential to localStorage for auto-login on next visit.
sdk.passkey.saveToLocalStorage();sdk.passkey.loadFromLocalStorage
Load a saved credential from localStorage.
const credential = sdk.passkey.loadFromLocalStorage();
if (credential) {
sdk.setCredential(credential);
}Returns: PasskeyCredential | null
sdk.passkey.hasStoredCredential
Check if a credential exists in localStorage.
const hasStored = sdk.passkey.hasStoredCredential();Returns: boolean
sdk.passkey.saveCredentialToRelayer
Sync the credential to the relayer for cross-device recovery.
await sdk.passkey.saveCredentialToRelayer();sdk.passkey.loadCredentialFromRelayer
Recover a credential from the relayer (cross-device login).
const credential = await sdk.passkey.loadCredentialFromRelayer();Returns: Promise<PasskeyCredential | null>
Credential Management
sdk.setCredential
Set the active credential on the SDK instance (used after loading from storage or cross-origin auth).
sdk.setCredential(credential);sdk.clearCredential
Clear the active credential and reset SDK state.
sdk.clearCredential();Vault & Identity
sdk.getVaultAddress
Get the deterministic vault address derived from the passkey.
const address = sdk.getVaultAddress();Returns: string — Same address on all EVM chains for the same passkey.
sdk.getChainConfig
Get the current chain's configuration.
const config = sdk.getChainConfig();sdk.getUnifiedIdentity
Get the unified identity across all chains, including vault addresses, deployment status, and key hash.
const identity = await sdk.getUnifiedIdentity();Returns: Promise<UnifiedIdentity>
interface UnifiedIdentity {
keyHash: string;
addresses: Array<{
wormholeChainId: number;
chainName: string;
address: string;
deployed: boolean;
}>;
}Example:
const identity = await sdk.getUnifiedIdentity();
const baseAddr = identity.addresses.find(a => a.wormholeChainId === 10004);
console.log('Base vault:', baseAddr?.address, 'deployed:', baseAddr?.deployed);sdk.vaultExists
Check if the vault is deployed on the current chain.
const exists = await sdk.vaultExists();Returns: Promise<boolean>
sdk.getReceiveAddress
Get the address that can receive tokens (vault address if deployed, otherwise the computed address).
const receiveAddr = sdk.getReceiveAddress();Returns: string
sdk.getNonce
Get the current nonce for the authenticated passkey.
const nonce = await sdk.getNonce();Returns: Promise<bigint>
Transfers
sdk.prepareTransfer
Prepare a transfer with gas estimation. Call this before signing to show the user costs.
const prepared = await sdk.prepareTransfer(params);Parameters:
interface TransferParams {
targetChain: number; // Wormhole chain ID
token: string; // Token address or 'native'
recipient: string; // Recipient address
amount: bigint; // Amount in smallest unit
}Returns: Promise<PreparedTransfer>
interface PreparedTransfer {
params: TransferParams;
actionPayload: string;
nonce: bigint;
challenge: string;
estimatedGas: bigint;
gasPrice: bigint;
messageFee: bigint;
totalCost: bigint;
formattedCost: string;
preparedAt: number;
expiresAt: number; // 5 minutes TTL
}Example:
const prepared = await sdk.prepareTransfer({
targetChain: 10004,
token: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f5A234',
amount: 1000000n,
});
console.log('Gas cost:', prepared.formattedCost);
console.log('Expires:', new Date(prepared.expiresAt));sdk.executeTransfer
Execute a prepared transfer (requires a signer to pay gas).
const result = await sdk.executeTransfer(prepared, signer);Returns: Promise<DispatchResult>
interface DispatchResult {
transactionHash: string;
sequence: bigint;
userKeyHash: string;
targetChain: number;
blockNumber: number;
}sdk.transferViaRelayer
Execute a gasless transfer through the relayer. The user only needs their passkey — no MetaMask or gas tokens required. This is the primary transfer method used by both the test-app and sera/dashboard.
const result = await sdk.transferViaRelayer(params);Parameters: TransferParams (same as prepareTransfer)
Returns: Promise<TransferResult>
interface TransferResult {
transactionHash: string;
sequence?: bigint;
status: 'pending' | 'confirmed' | 'failed';
}Example:
import { ethers } from 'ethers';
const result = await sdk.transferViaRelayer({
targetChain: 10004, // Base Sepolia
token: '0x036CbD53842c5426634e7929541eC2318f3dCF7e', // USDC
recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f5A234',
amount: ethers.parseUnits('10', 6), // 10 USDC
});
console.log('Tx:', result.transactionHash);sdk.getTransactionSummary
Get a human-readable summary of a prepared transaction.
const summary = await sdk.getTransactionSummary(prepared);Returns: Promise<TransactionSummary>
interface TransactionSummary {
title: string; // e.g., "Transfer"
description: string; // e.g., "Send 1.0 USDC to 0x742d...5A234"
details: ActionDetails;
risks: RiskWarning[]; // e.g., large_transaction, unknown_recipient
gasCost: string;
expiresIn: number;
}Example:
const prepared = await sdk.prepareTransfer({ ... });
const summary = await sdk.getTransactionSummary(prepared);
console.log(summary.title); // "Transfer"
console.log(summary.description); // "Send 1.0 USDC to 0x742d...5A234"
if (summary.risks.length > 0) {
console.warn('Risks:', summary.risks.map(r => r.message));
}Cross-Chain Bridges
sdk.prepareBridge
Prepare a cross-chain bridge with fee estimation.
const prepared = await sdk.prepareBridge(params);Parameters:
interface BridgeParams {
sourceChain: number; // Source Wormhole chain ID
destinationChain: number; // Destination Wormhole chain ID
token: string;
recipient: string;
amount: bigint;
}sdk.executeBridge
Execute a prepared bridge with cross-chain tracking.
const result = await sdk.executeBridge(prepared, signer, onProgress?);Progress callback:
sdk.executeBridge(prepared, signer, (progress) => {
console.log(`Step ${progress.step}/${progress.totalSteps}: ${progress.message}`);
// Steps: signing → dispatching → waiting_confirmations → fetching_vaa → relaying → completed
});sdk.bridgeViaRelayer
Execute a gasless bridge using the relayer.
const result = await sdk.bridgeViaRelayer(params, onProgress?);sdk.bridgeWithTracking
Convenience method that prepares and executes a bridge in one call.
const result = await sdk.bridgeWithTracking(params, signer, onProgress?);sdk.getBridgeFees
Estimate bridge fees without executing.
const fees = await sdk.getBridgeFees(params);Returns: Promise<CrossChainFees>
interface CrossChainFees {
sourceGas: bigint;
messageFee: bigint;
relayerFee: bigint;
totalCost: bigint;
formattedTotal: string;
currency: string;
}Spending Limits (sdk.spendingLimits)
sdk.getSpendingLimits
Get current on-chain spending limits for your vault.
const limits = await sdk.getSpendingLimits(chainId?);Returns: Promise<SpendingLimits>
sdk.getFormattedSpendingLimits
Get spending limits formatted for UI display.
const formatted = await sdk.getFormattedSpendingLimits();
console.log(`${formatted.dailyUsedPercentage}% of daily limit used`);
console.log(`Resets in: ${formatted.timeUntilReset}`);sdk.checkSpendingLimit
Check if a transaction amount is within limits.
import { ethers } from 'ethers';
const check = await sdk.checkSpendingLimit(ethers.parseEther('1.0'));
if (!check.allowed) {
console.log(check.message);
console.log('Suggestions:', check.suggestions);
}Returns: Promise<LimitCheckResult>
sdk.prepareSetDailyLimit
Prepare a transaction to update the daily spending limit.
const prepared = await sdk.prepareSetDailyLimit(ethers.parseEther('5.0'));
// Sign and execute with sdk.executeTransfer(prepared, signer)sdk.preparePauseVault
Prepare an emergency pause transaction.
const prepared = await sdk.preparePauseVault();Sponsored Vault Creation
sdk.isSponsorshipAvailable
Check if the SDK has a sponsor key configured for gasless vault creation.
const canSponsor = sdk.isSponsorshipAvailable();Returns: boolean
sdk.ensureSponsoredVaultsOnAllChains
Auto-create vaults on all configured chains using the sponsor key. No gas required from the user. This is called automatically after registration in the test-app.
const result = await sdk.ensureSponsoredVaultsOnAllChains();
console.log(`Created vaults on ${result.results.filter(r => r.success).length} chains`);Returns: Promise<{ results: Array<{ chainId: number; success: boolean; error?: string }> }>
Token Management
sdk.getTokenList
Get the list of supported tokens on the current chain.
const tokens = sdk.getTokenList();
for (const token of tokens) {
console.log(`${token.symbol}: ${token.address} (${token.decimals} decimals)`);
}Returns: TokenInfo[]
interface TokenInfo {
address: string;
symbol: string;
name: string;
decimals: number;
wormholeChainId: number;
logoUrl?: string;
}Balance Management
sdk.getVaultNativeBalance
Get the native token balance of the vault.
const native = await sdk.getVaultNativeBalance();
console.log(`${native.token.symbol}: ${native.formatted}`);sdk.getVaultBalances
Get all token balances on the current chain.
const portfolio = await sdk.getVaultBalances();
for (const entry of portfolio.tokens) {
console.log(`${entry.token.symbol}: ${entry.formatted}`);
}
console.log('Total USD:', portfolio.totalUsdValue);sdk.getVaultTokenBalance
Get balance of a specific token.
const balance = await sdk.getVaultTokenBalance(tokenAddress);
console.log(`${balance.token.symbol}: ${balance.formatted}`);sdk.getMultiChainBalances
Get balances across multiple chains.
const results = await sdk.getMultiChainBalances([10004, 10005, 10003]);
for (const chain of results) {
console.log(`${chain.chainName}: ${chain.tokens.length} tokens`);
}sdk.balance (Low-Level)
Direct access to the BalanceManager for advanced queries:
const portfolio = await sdk.balance.getPortfolioBalance(chainId, address);
const multi = await sdk.balance.getMultiChainBalances(address, [10004, 10005]);Transaction Tracking (sdk.transactions)
sdk.transactions.track
Track a transaction's status.
sdk.transactions.track(txHash, chainId, callback?, sequence?);Gas Sponsorship (sdk.sponsor)
sdk.sponsor
Gasless vault creation for new users.
const result = await sdk.sponsor.createVault(chainId, credential);Chain Clients
The SDK provides chain-specific clients:
import {
EVMClient,
SolanaClient,
AptosClient,
SuiClient,
StarknetClient,
StacksClient,
} from '@veridex/sdk';Session Key Utilities
import {
SessionManager,
generateSecp256k1KeyPair,
computeSessionKeyHash,
signWithSessionKey,
hashAction,
verifySessionSignature,
deriveEncryptionKey,
encrypt,
decrypt,
createSessionStorage,
} from '@veridex/sdk';Chain Presets & Utilities
import {
getChainConfig,
getSupportedChains,
getHubChains,
isChainSupported,
getDefaultHub,
CHAIN_PRESETS,
CHAIN_NAMES,
} from '@veridex/sdk';
// Get all supported chains
const chains = getSupportedChains('testnet');
// ['base', 'optimism', 'arbitrum', 'solana', 'aptos', 'sui', 'starknet', 'stacks']
// Get chain config
const config = getChainConfig('stacks', 'testnet');
console.log('Wormhole ID:', config.wormholeChainId); // 50003Token Constants
import {
NATIVE_TOKEN_ADDRESS,
BASE_SEPOLIA_TOKENS,
TOKEN_REGISTRY,
getTokenList,
getTokenBySymbol,
getTokenByAddress,
isNativeToken,
} from '@veridex/sdk';
const usdc = getTokenBySymbol(10004, 'USDC');
console.log('USDC address:', usdc?.address);ERC-8004 Utilities (erc8004/)
The core SDK provides low-level ERC-8004 contract utilities for direct registry interaction.
import {
// Addresses
getERC8004Addresses,
isERC8004Chain,
ERC8004_CHAINS,
// ABIs
IDENTITY_REGISTRY_ABI,
IDENTITY_REGISTRY_READ_ABI,
REPUTATION_REGISTRY_ABI,
REPUTATION_REGISTRY_READ_ABI,
VALIDATION_REGISTRY_ABI,
// Types
type ERC8004AgentRegistration,
type ERC8004MetadataEntry,
type ERC8004FeedbackEntry,
type ERC8004FeedbackSummary,
type ERC8004ValidationStatus,
type UniversalAgentIdentifier,
} from '@veridex/sdk';getERC8004Addresses
Get canonical ERC-8004 registry addresses for a network.
const addresses = getERC8004Addresses('mainnet');
// {
// identityRegistry: '0x8004A169FB4a3325136EB29fA0ceB6D2e539a432',
// reputationRegistry: '0x8004BAa17C55a88189AE136b182e5fdA19dE9b63',
// }
const testnetAddresses = getERC8004Addresses('testnet');
// {
// identityRegistry: '0x8004A818BFB912233c491871b3d84c89A494BD9e',
// reputationRegistry: '0x8004B663056A597Dffe9eCcC1965A193B7388713',
// }isERC8004Chain
Check if a chain has ERC-8004 singleton registries deployed.
const supported = isERC8004Chain('base'); // true
const supported2 = isERC8004Chain('monad'); // true
const supported3 = isERC8004Chain('solana'); // false (non-EVM)ERC8004_CHAINS
List of all chains with ERC-8004 singletons:
console.log(ERC8004_CHAINS);
// ['base', 'ethereum', 'polygon', 'arbitrum', 'optimism', 'linea', 'megaeth', 'monad', ...]Canonical Addresses
The same singleton addresses work on every EVM chain (deployed via CREATE2):
| Registry | Mainnet | Testnet |
|---|---|---|
| Identity | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 | 0x8004A818BFB912233c491871b3d84c89A494BD9e |
| Reputation | 0x8004BAa17C55a88189AE136b182e5fdA19dE9b63 | 0x8004B663056A597Dffe9eCcC1965A193B7388713 |
Types
Full TypeScript types are available:
import type {
// Config
VeridexConfig, SimpleSDKConfig, ChainConfig, ChainName, NetworkType,
// Passkey
PasskeyCredential, WebAuthnSignature,
// Cross-Origin Authentication
CrossOriginAuth, CrossOriginAuthConfig, CrossOriginSession,
ServerSessionToken, AuthPortalMessage,
createCrossOriginAuth, sendAuthResponse, sendAuthError,
DEFAULT_AUTH_PORTAL_URL, DEFAULT_RELAYER_URL, AUTH_MESSAGE_TYPES,
// Actions
TransferParams, ExecuteParams, BridgeParams,
DispatchResult, PreparedTransfer, PreparedBridge,
// Results
TransferResult, BridgeResult, CrossChainFees,
// Spending Limits
SpendingLimits, FormattedSpendingLimits, LimitCheckResult,
// Sessions
SessionConfig, SessionSignature, KeyPair,
// Balances
TokenBalance, PortfolioBalance,
// Transaction Summaries
TransactionSummary, RiskWarning,
// Vault & Identity
VaultInfo, UnifiedIdentity,
// ERC-8004
ERC8004AgentRegistration, ERC8004MetadataEntry,
ERC8004FeedbackEntry, ERC8004FeedbackSummary,
ERC8004ValidationStatus, UniversalAgentIdentifier,
} from '@veridex/sdk';