Starknet
Use @cavos/kit on Starknet — silent device signing, gasless execution, and the Cairo DeviceAccount.
Starknet is the first implemented chain in @cavos/kit. A deterministic address
derived from the user's identity is controlled by a silent secp256r1 (P-256)
device key, validated on-chain by the Cairo DeviceAccount account contract.
Deploy and execution are sponsored by the Cavos paymaster, so the user pays no
gas.
Connect
Cavos.connect with chain: "starknet" (the default) does everything:
authenticate, derive the deterministic address, create/load the silent device
key, auto-deploy the account on first use, and wire up the gas sponsor.
import { Cavos } from "@cavos/kit";
const wallet = await Cavos.connect({
chain: "starknet", // default; shown for clarity
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!, // sponsors deploy + execute
});
console.log(wallet.address); // deterministic; deployed on first connectwallet.chain narrows to "starknet". The instance members (address,
status, execute, addSigner, setupRecovery) are the ones documented in
the API reference.
Execute a transaction
When status === "ready", call execute with standard Starknet calls. It is
signed silently by the device key and sponsored by the paymaster — the user sees
nothing.
if (wallet.chain === "starknet" && wallet.status === "ready") {
const { transactionHash } = await wallet.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.
How signing works
The device key is a non-extractable secp256r1 key held in IndexedDB via
WebCrypto. When you call execute:
- starknet.js computes the v3 transaction hash.
- The device key signs
sha256(tx_hash)— WebCrypto's ECDSA hashes the message internally, so there is no user interaction. - The signature is serialized as 5 felts:
[r_low, r_high, s_low, s_high, y_parity]. - On-chain,
DeviceAccount.__validate__recomputessha256(tx_hash), normalizes high-s, recovers the secp256r1 signer, and checks it is authorized.
This 5-felt encoding is byte-compatible with the contract and covered by a
cross-checked test in the account-contracts repo.
Gasless execution
execute routes through the Cavos paymaster (SNIP-9 execute_from_outside),
so the user pays no gas. Both account deployment (on first connect) and
every execution are sponsored — the user never needs ETH or STRK to start.
Advanced: a plain starknet.js Account
StarknetDeviceSigner is a drop-in starknet.js SignerInterface, so you can
plug the device key into a standard Account and your own paymaster flow:
import { Account, RpcProvider } from "starknet";
import { StarknetDeviceSigner, WebCryptoSigner } from "@cavos/kit";
const provider = new RpcProvider({ nodeUrl: "https://api.cartridge.gg/x/starknet/sepolia" });
const signer = await WebCryptoSigner.loadOrCreate({ keyId: address });
const account = new Account({
provider,
address,
signer: new StarknetDeviceSigner(signer),
cairoVersion: "1",
});Gas estimation gotcha (self-funded path). secp256r1 validation is heavy
(~27M L2 gas). Default fee estimation uses SKIP_VALIDATE, which under-bounds
and causes "Out of gas". Estimate with validation on and pass those bounds:
const fee = await account.estimateInvokeFee(calls, { skipValidate: false });
await account.execute(calls, { resourceBounds: fee.resourceBounds });The Cavos paymaster path handles this for you — this only matters when you submit transactions yourself.
Networks & constants
import { STARKNET_NETWORKS, DEVICE_ACCOUNT_CLASS_HASH } from "@cavos/kit";
STARKNET_NETWORKS.sepolia; // RPC + chain config
DEVICE_ACCOUNT_CLASS_HASH.sepolia; // deployed DeviceAccount class hashnetwork accepts "testnet" (resolves to sepolia) and "mainnet". The class
hash is the declared DeviceAccount contract; the kit ships the current values.
What's available
- ✅ Silent secp256r1 device signer, auto-deployed deterministic account.
- ✅ Gasless execute + deployment via the Cavos paymaster.
- ✅ Multi-device approval + recovery (passphrase backup) — non-custodial.
For the cross-chain model and how Solana compares, see Chains and Solana.