Cavos

Quickstart

Install @cavos/kit and send a gasless transaction with a silent device signer.

This page takes you from install to a gasless transaction. The happy path is a single Cavos.connect call.

1. Install

Terminal
npm install @cavos/kit

Requirements: a Cavos App ID and a paymaster API key (from the Cavos dashboard at cavos.xyz).

2. Connect

Cavos.connect does everything: authenticate the user, derive the deterministic address, create/load the silent device key, auto-deploy the account on first use, and wire up the gas sponsor.

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

const cavos = await Cavos.connect({
  chain: "starknet",                  // "starknet" | "solana" | "stellar"
  network: "testnet",                 // "testnet" (sepolia) | "mainnet"
  appSalt: "my-app",                  // namespaces addresses to your app
  identity: {                         // from your login (see Authentication)
    userId: user.id,
    email: user.email,
  },
  appId: process.env.NEXT_PUBLIC_CAVOS_APP_ID,
  paymasterApiKey: process.env.CAVOS_PAYMASTER_API_KEY!,
});

console.log(cavos.address); // deterministic; deployed on first connect

connect returns a Cavos instance with:

  • cavos.address — the smart account address (stable across devices).
  • cavos.status"ready" or "needs-device-approval" (see Multi-device).
  • cavos.publicKey — this device's public key.

3. Execute a transaction

When status is "ready", call execute with standard Starknet calls. It is signed silently by the device key and sponsored by the paymaster — the user sees nothing.

TypeScript
if (cavos.status === "ready") {
  const { transactionHash } = await cavos.execute([
    {
      contractAddress: STRK_TOKEN,
      entrypoint: "approve",
      calldata: [spender, amountLow, amountHigh],
    },
  ]);
  console.log(transactionHash);
}

If status is "needs-device-approval", this device is new to an existing wallet. Approve it from an already-registered device — see Multi-device.

So the user can recover if they lose every device, register a passphrase-derived backup signer once:

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

const code = generateRecoveryCode();     // show this to the user ONCE to store
await cavos.setupRecovery(code);         // registers the backup signer on-chain

The code never leaves the device — only its derived public key is registered. See Recovery for the full lifecycle.

So the user can log in on a new device without finding an already-logged-in one, prompt them for a passkey right after signup. Treat it as a 2FA step — it approves new devices, it never signs transactions.

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

if (await PasskeySigner.isSupported()) {
  const passkey = new PasskeySigner();
  await cavos.enrollPasskey(passkey, {
    userId: user.id,
    userName: user.email ?? user.id,
  }); // gasless; registers the passkey's pubkey as a device approver
}

Later, on a new device, the user confirms one prompt to authorize that device — no second device required. See Passkeys for the full flow.

What you get

  • A deployed, gas-sponsored smart account controlled by a silent device key.
  • A deterministic address you can reference before deployment.
  • Multi-device + passphrase recovery, all non-custodial.

Next: wire up real login in Authentication, or read how signing works under the hood in Signing & gasless.

On this page