Cavos

Chains

Cavos is built for every chain. Starknet, Solana, and Stellar are available today.

Cavos is built for every chain, with a native adapter boundary instead of a lowest-common-denominator transaction format. Your application keeps the same identity and connection model while each adapter implements its network's address, authority, execution, recovery, and sponsorship rules.

Status

ChainSDK statusNetworks
StarknetAvailablesepolia, mainnet
SolanaAvailablesolana-devnet, solana-mainnet
StellarAvailablestellar-testnet, stellar-mainnet
Additional chainsDesign-partner and adapter roadmapPublished after implementation and validation

All three chain adapters are shipped in the SDK. Release compatibility still requires the physical-device E2E matrix described in the React Native guide; the docs do not treat simulator/emulator results as hardware validation.

Per-chain guides

Each implemented chain has its own page with a quickstart and the chain-specific details:

How the abstraction works

Three layers keep Cavos portable:

  • The product contract is the constant. Stable identity, local authority, self-custody, recovery, and optional sponsorship are required of every adapter.
  • Device-native keys stay local. Every chain derives its account key from a MasterDEK: a stark key on Starknet, Ed25519 on Solana and Stellar.
  • A ChainAdapter per chain is a native client per chain: CavosStarknet (OpenZeppelin account), CavosSolana (system account), and CavosStellar (classic G… account).

Curves differ across ecosystems, and each adapter resolves that:

  • Starknet — the standard upgradeable OpenZeppelin account, validating a stark key derived from the MasterDEK.
  • Solana — native Ed25519 system account. The user key signs the Solana message; the relayer is fee payer only.
  • Stellar — classic G…. With enclave or passkey, the address is HKDF of the same MasterDEK as Solana. Older wallets still use extra Horizon signers.

Writing every-chain application code

Target the unified Cavos.connect with { chains, defaultChain, network }. Use session.wallet(chain) to get the wallet for a specific chain, and narrow on wallet.chain before calling chain-native methods:

TypeScript
import { Cavos } from "@cavos/kit";

// One entry point; connect to one or more chains at once.
const session = await Cavos.connect({
  chains: ["starknet"],       // or ["starknet", "solana", "stellar"] for multi-chain
  defaultChain: "starknet",
  network: "testnet",         // resolves to sepolia / solana-devnet / stellar-testnet
  identity: { userId, email },
  appSalt: "my-app",
  appId: process.env.NEXT_PUBLIC_CAVOS_APP_ID,
  // Starknet-only:
  paymasterApiKey: process.env.NEXT_PUBLIC_CAVOS_PAYMASTER_API_KEY!,
});

const wallet = session.wallet("starknet");
console.log(wallet.address);   // address is available immediately
console.log(wallet.status);    // "undeployed" | "ready" | "needs-device-approval"

// execute() keeps each chain's native signature — narrow on `chain`:
if (wallet.chain === "starknet" && wallet.status !== "needs-device-approval") {
  await wallet.execute(calls);                 // arbitrary Starknet calls
} else if (wallet.chain === "solana" && wallet.status !== "needs-device-approval") {
  await wallet.execute(amount, destination);   // lamport transfer
} else if (wallet.chain === "stellar" && wallet.status !== "needs-device-approval") {
  await wallet.execute(amount, destination);   // XLM transfer (stroops)
}

Lazy deploy: Connect NEVER deploys the account. Wallets start as undeployed and the first execute deploys + runs atomically. signMessage works on undeployed wallets too.

When a new adapter ships, the SDK adds its typed chain and network values. Identity and onboarding remain stable; execution stays chain-native. See Concepts for the architecture rationale.

On this page