Skip to main content

Wallet Lifecycle

After login(), the SDK fully automates wallet setup in the background:
login() called
  → Session key generated
  → Wallet address derived (Poseidon(sub, salt))
  → Account deployed on-chain (gasless, if not already deployed)
  → Session key registered on-chain
  → walletStatus.isReady = true ✅
You never need to manually deploy or register — just observe walletStatus:
const { login, walletStatus, address } = useCavos();

if (!address) {
  return <button onClick={() => login('google')}>Login</button>;
}

if (!walletStatus.isReady) {
  return (
    <div>
      {walletStatus.isDeploying && <p>Deploying wallet...</p>}
      {walletStatus.isRegistering && <p>Activating session...</p>}
    </div>
  );
}

return <App />;

Wallet Status

interface WalletStatus {
  isDeploying: boolean;           // Account contract is being deployed on-chain
  isDeployed: boolean;            // Account contract exists on-chain
  isRegistering: boolean;         // Session key is being registered on-chain
  isSessionActive: boolean;       // Session key is registered and not expired
  isReady: boolean;               // Fully ready — deployed + session active
  pendingDeployTxHash?: string;   // Set when deploy tx was submitted but confirmation timed out
}

Pending Deploy Recovery

If the deploy transaction times out (e.g., network congestion), the SDK persists the tx hash in localStorage. On the next init() call (page load), it re-polls the hash automatically. You can surface a link to the user in the meantime:
const { walletStatus } = useCavos();

{walletStatus.pendingDeployTxHash && (
  <a
    href={`https://sepolia.starkscan.co/tx/${walletStatus.pendingDeployTxHash}`}
    target="_blank"
  >
    Deployment pending — view on explorer
  </a>
)}

Wallet Address

The wallet address is deterministic — derived from the user’s OAuth identity and a per-app salt. The same user + same app always produces the same address.
const { address } = useCavos();

// or directly from the SDK
const address = cavos.getAddress();
Use it as the funding address (send tokens to this address to fund the wallet):
<p>Fund your wallet: {address}</p>

Check Deployment

const { isAccountDeployed } = useCavos();

const deployed = await isAccountDeployed();
Or use walletStatus.isDeployed which is kept in sync automatically:
const { walletStatus } = useCavos();

console.log('Deployed:', walletStatus.isDeployed);

Manual Deployment

In most cases deployment is automatic. If you ever need to trigger it manually:
const { deployAccount } = useCavos();

const txHash = await deployAccount();
console.log('Deploy tx:', txHash);

Balance

Get the ETH balance of the wallet (in wei, as a string):
const { getBalance } = useCavos();

const balance = await getBalance();
const eth = (BigInt(balance) / 10n**18n).toString();

Multi-Wallet (Named Sub-Accounts)

A single user can have multiple wallets per app, differentiated by name. Each named wallet has its own deterministic address derived from Poseidon(sub, salt, walletName).

Discover Wallets

Returns all wallets the user has used in this app:
const { getAssociatedWallets } = useCavos();

const wallets = await getAssociatedWallets();
// [
//   { address: '0x...', name: undefined },      // default wallet
//   { address: '0x...', name: 'trading' },
//   { address: '0x...', name: 'savings' },
// ]

Switch Wallet

const { switchWallet, address } = useCavos();

// Switch to a named sub-wallet
await switchWallet('trading');
console.log('Now using:', address); // new address

// Switch back to default
await switchWallet();
After switching, walletStatus resets and the deployment/session flow runs for the new wallet.

Session Export

Export the active session as a base64 token for use in the CLI or autonomous agents. The token encodes the session private key, wallet address, and policy — it does not include the JWT.
const { exportSession, walletStatus, sessionPublicKey } = useCavos();

// Only export when session is active and registered on-chain
if (walletStatus.isSessionActive) {
  const token = exportSession();
  navigator.clipboard.writeText(token);
}
CLI Usage:
export CAVOS_TOKEN="<base64_token>"

cavos balance
cavos transfer --to 0x... --amount 1.5 --token STRK --wait
[!WARNING] The exported token contains the session private key. Treat it like a password — never commit it to source control or share it publicly.

Logout

Clears the local session and wallet state. The on-chain account remains intact and can be restored by logging in with the same identity.
const { logout } = useCavos();

await logout();
// isAuthenticated → false, address → null

Subscribing to Status Changes

For custom UI outside of React context, subscribe directly to the SDK:
const { cavos } = useCavos();

// Subscribe to wallet status
const unsubscribe = cavos.onWalletStatusChange((status) => {
  console.log('Wallet status changed:', status);
});

// Subscribe to auth state changes (e.g., magic link completing)
const unsubscribeAuth = cavos.onAuthChange(() => {
  console.log('Auth state changed');
});

// Cleanup
return () => {
  unsubscribe();
  unsubscribeAuth();
};