diff --git a/README.md b/README.md
index 662cd55..2ae0182 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ In addition to workshop materials, this repository includes reference guides on
| Topic | Description |
|-------|-------------|
| [Soroban Development](./soroban-development/) | Smart contract development with Rust SDK |
-| [Wallet Integration](./wallet-integration/) | Freighter, Stellar Wallets Kit, Smart Account Kit |
+| [Wallet Integration](./wallet-integration/) | Freighter, Stellar Wallets Kit, Smart Account Kit, Cavos |
| [OpenZeppelin Tools](./openzeppelin/) | Audited contracts, Contract Wizard, Relayer, Monitor |
| [DeFi Protocols](./defi/) | Lending, DEXs, vaults, and stablecoins |
| [Tokens](./tokens/) | Stellar Assets vs Soroban Tokens |
@@ -49,6 +49,7 @@ In addition to workshop materials, this repository includes reference guides on
- [Freighter](./wallet-integration/freighter.md) - Browser extension wallet
- [Stellar Wallets Kit](./wallet-integration/stellar-wallets-kit.md) - Multi-wallet SDK
- [Smart Account Kit](./wallet-integration/smart-account-kit.md) - Passkey-based smart wallets
+- [Cavos](./wallet-integration/cavos.md) - Embedded self-custodial wallet SDK
### OpenZeppelin Stellar Suite
diff --git a/wallet-integration/README.md b/wallet-integration/README.md
index 0929285..637fdd3 100644
--- a/wallet-integration/README.md
+++ b/wallet-integration/README.md
@@ -11,6 +11,7 @@ Stellar offers multiple approaches to wallet integration, each suited for differ
| [Freighter](./freighter.md) | Quick integration, SDF's official wallet | Browser extension or Freighter Mobile app | Low |
| [Stellar Wallets Kit](./stellar-wallets-kit.md) | Multi-wallet support | Users choose their preferred wallet | Medium |
| [Smart Account Kit](./smart-account-kit.md) | Modern dapps, best UX | Passkey-based, no extension needed | Medium |
+| [Cavos](./cavos.md) | Embedded self-custodial SDK | Google or Apple login; control key unwrapped locally | Medium |
## Quick Decision Guide
@@ -30,6 +31,13 @@ Stellar offers multiple approaches to wallet integration, each suited for differ
- You're building a consumer-facing application
- You want passkey-based authentication (FaceID, TouchID, etc.)
+**Choose Cavos if:**
+- You want an embedded self-custodial wallet (no extension, no seed phrase)
+- Users should sign in with Google or Apple
+- The Ed25519 control key is unwrapped locally on the device (Cavos cannot see it or move funds)
+- You are building with React or React Native
+- Optional pass-through gas sponsorship would help onboarding
+
## Comparison
See [comparison.md](./comparison.md) for a detailed feature comparison.
@@ -44,6 +52,8 @@ For most new projects in 2026, we recommend **Smart Account Kit** for the best u
Note that the kit is still pre-1.0 (v0.4.x) with occasional breaking changes between minor versions — pin your version and check the repo README when upgrading.
+If you want Google or Apple login with a device-native embedded wallet (the Stellar control key is unwrapped locally and Cavos cannot see it), see **Cavos**.
+
## Additional Resources
- [Official Stellar Developer Docs](https://developers.stellar.org/docs/build/apps)
diff --git a/wallet-integration/cavos.md b/wallet-integration/cavos.md
new file mode 100644
index 0000000..159b034
--- /dev/null
+++ b/wallet-integration/cavos.md
@@ -0,0 +1,301 @@
+# Cavos
+
+Cavos is a device-native embedded self-custodial wallet SDK. Users sign in with Google or Apple. No seed phrase, no browser extension, and no MPC.
+
+On Stellar, Cavos provisions a classic `G…` account (not a Soroban contract) that interoperates with existing Stellar tools and can still invoke Soroban contracts. Starknet and Solana use non-extractable P-256 device signers to sign. Stellar is different: a device-bound P-256 ECDH key locally unwraps an encrypted Ed25519 control key; the control key signs Stellar transactions. Unwrap happens on the device. Cavos cannot see the control key or move funds. Passkeys enroll additional devices; they do not sign. The same SDK also supports Solana and Starknet.
+
+The kit README notes that production launch still requires operational, security, and relayer hardening for the target deployment.
+
+## Overview
+
+- **Type:** Embedded self-custodial wallet SDK
+- **User Experience:** Google or Apple login; the control key is unwrapped locally on the device
+- **Best for:** Consumer apps that want in-app wallets without extensions or seed phrases
+- **Package:** [`@cavos/kit`](https://www.npmjs.com/package/@cavos/kit) (React and React Native)
+- **GitHub:** [cavos-labs/kit](https://github.com/cavos-labs/kit)
+
+## Why Cavos?
+
+| Typical wallet onboarding | Cavos |
+|---------------------------|-------|
+| Install a browser extension | No installation; embed the wallet in your app |
+| Save a seed phrase | Sign in with Google or Apple |
+| Key material held by a third party or split across servers | Control key is unwrapped locally; Cavos never sees it |
+| Desktop-oriented popups | Works in the browser and in React Native |
+
+## Key Features
+
+- **Embedded self-custody:** The Ed25519 control key is unwrapped locally on the device. Cavos cannot see it, sign transactions, or move funds.
+- **Familiar login:** Hosted Google or Apple auth. Login never signs transactions.
+- **No seed phrase, no extension, no MPC.**
+- **Classic Stellar account:** Deterministic `G…` address derived from identity plus app salt.
+- **Silent local signing:** On a known device, the device-bound P-256 key unwraps the control key locally and the control key signs without a wallet popup.
+- **Passkeys enroll devices:** A passkey is a second factor for adding a new device. It does not sign transactions.
+- **Optional gas sponsorship:** Pass-through relayer that sponsors reserves and fees when configured. The relayer is not a custodian and cannot move funds.
+- **React and React Native:** Same package, including a React Native entrypoint.
+
+## Installation
+
+```bash
+npm install @cavos/kit
+```
+
+Create an app in the [Cavos dashboard](https://cavos.xyz) and copy its App ID. The App ID is a public client identifier used to enable hosted auth and optional sponsorship.
+
+React Native needs extra native peers and a rebuild; see [React Native](#react-native) below.
+
+## Hosted Login (Google or Apple)
+
+`CavosAuth` provides hosted Google and Apple login that resolves to an identity you pass into `connect`. Handle the OAuth callback first; only generate a new OAuth URL when this page load is not a callback.
+
+```typescript
+import { Cavos, CavosAuth } from "@cavos/kit";
+
+const auth = new CavosAuth({
+ appId: process.env.NEXT_PUBLIC_CAVOS_APP_ID,
+});
+
+const params = new URLSearchParams(window.location.search);
+if (!params.has("cavos_auth_code")) {
+ window.location.href = await auth.getGoogleOAuthUrl();
+} else {
+ const identity = await auth.handleCallback(window.location.search);
+
+ const wallet = await Cavos.connect({
+ chain: "stellar",
+ network: "testnet",
+ appSalt: "my-app",
+ identity,
+ appId: process.env.NEXT_PUBLIC_CAVOS_APP_ID,
+ });
+
+ console.log(wallet.address);
+}
+```
+
+Register every callback URL for your app in the Cavos dashboard (scheme, host, path; no wildcards). Treat `appSalt` as permanent. Changing it derives a different wallet for every user.
+
+Login never signs transactions. On Stellar the device-bound P-256 key unwraps the Ed25519 control key locally, and that control key signs.
+
+### Advanced: bring your own identity
+
+If you already authenticate users, kit still accepts `{ userId, email }` as `identity` instead of hosted login. This is not the default path. The Stellar address is derived from `userId` plus `appSalt`, so both must stay stable. Do not use a guessable or public identifier as `userId`.
+
+## Sign and Send Transactions
+
+The returned wallet is a discriminated union. Narrow on `wallet.chain` and gate on `status === "ready"` before executing.
+
+Native XLM transfer (amount is stroops; 1 XLM = 10_000_000 stroops). `execute` takes options as the third argument:
+
+```typescript
+if (wallet.chain === "stellar" && wallet.status === "ready") {
+ const hash = await wallet.execute(
+ 10_000_000n,
+ "GDESTINATION...ADDRESS"
+ );
+ console.log(hash);
+
+ // await wallet.execute(10_000_000n, "GDESTINATION...ADDRESS", { sponsored: false });
+}
+```
+
+Soroban contract invocation. `invokeContract` applies `nativeToScVal` without an address type hint, so a raw G address string becomes an ScVal string. For `require_auth` arguments, pass an explicit address ScVal. Sponsorship options go in `opts` inside the parameter object, not as a top-level `sponsored` field:
+
+```typescript
+import { nativeToScVal } from "@stellar/stellar-sdk";
+
+if (wallet.chain === "stellar" && wallet.status === "ready") {
+ const hash = await wallet.invokeContract({
+ contractId: "C...CONTRACT",
+ method: "do_thing",
+ args: [nativeToScVal(wallet.address, { type: "address" })],
+ // opts: { sponsored: false },
+ });
+}
+```
+
+On a new device the same identity lands on the same `G…` with `status: "needs-device-approval"`. Do not create a second wallet. Enroll the device with a passkey or a recovery code.
+
+## React Integration
+
+Bindings ship in the same package under `@cavos/kit/react`:
+
+```tsx
+import { CavosProvider, useCavos } from "@cavos/kit/react";
+
+export function Providers({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
+```
+
+```tsx
+export function WalletButton() {
+ const { isAuthenticated, address, wallet, walletStatus, openModal, logout } =
+ useCavos();
+
+ if (!isAuthenticated) {
+ return ;
+ }
+
+ const send = async () => {
+ if (wallet?.chain === "stellar" && walletStatus.isReady) {
+ await wallet.execute(10_000_000n, "GDESTINATION...ADDRESS");
+ }
+ };
+
+ return (
+
+ );
+}
+```
+
+Gate execution on `walletStatus.isReady`, not merely `isAuthenticated`.
+
+## React Native
+
+Switching the import to `@cavos/kit/react-native` is not enough. Expo Go is not supported: the kit ships a custom native module, so you need an Expo development build / EAS or bare React Native, then a native rebuild after installing peers and the config plugin.
+
+Install the packages the kit docs require:
+
+```bash
+npm install @cavos/kit expo expo-modules-core expo-web-browser expo-linking react-native-get-random-values
+npx expo prebuild
+npx expo run:ios # or: npx expo run:android
+```
+
+Add the `@cavos/kit` config plugin and set `redirectUri` plus `rpId`:
+
+```json
+{
+ "expo": {
+ "scheme": "myapp",
+ "plugins": [["@cavos/kit", {
+ "rpId": "auth.example.com",
+ "scheme": "myapp"
+ }]]
+ }
+}
+```
+
+```tsx
+import { CavosProvider } from "@cavos/kit/react-native";
+
+export function Providers({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
+```
+
+Register that same `redirectUri` exactly in the Cavos dashboard under Callback URLs. `rpId` is required for native passkeys and must be a domain associated with the app.
+
+## Gas Sponsorship
+
+Setting `appId` activates the hosted Stellar relayer, which can sponsor account reserves and fee-bump submission. Sponsorship is pass-through: the relayer is a fee payer and reserve sponsor only. It is not a custodian, cannot see the control key, and cannot move funds. A missing or unavailable relayer can affect fees; it cannot squat the address or authorize transactions.
+
+```typescript
+const wallet = await Cavos.connect({
+ chain: "stellar",
+ network: "testnet",
+ appSalt: "my-app",
+ identity,
+ appId: process.env.NEXT_PUBLIC_CAVOS_APP_ID,
+});
+```
+
+To have the account pay its own fee:
+
+- `execute(amount, destination, { sponsored: false })` — options are the third argument
+- `invokeContract({ contractId, method, args, opts: { sponsored: false } })` — `opts` sits inside the parameter object
+
+You can also supply your own funded source (`stellarSourceKeypair`) instead of the hosted relayer.
+
+## Passkeys and Recovery
+
+Passkeys enroll devices. They do not sign transactions. On Stellar the device-bound P-256 key unwraps the encrypted Ed25519 control key locally; the control key signs.
+
+After signup, prompt the user to enroll a passkey so they can approve a new device later without finding one that is already logged in. `PasskeyPrf.enroll()` may omit `secret` when the authenticator does not return a PRF result on create; fall back to `getSecret()` as the React provider does:
+
+```typescript
+import { PasskeyPrf } from "@cavos/kit";
+
+if (wallet.chain === "stellar" && wallet.status === "ready") {
+ const prf = new PasskeyPrf({ rpName: "My App" });
+ const { secret } = await prf.enroll({
+ userId: user.id,
+ userName: user.email ?? user.id,
+ });
+ await wallet.enrollPasskey(secret ?? (await prf.getSecret()));
+}
+```
+
+On a new device:
+
+```typescript
+if (wallet.chain === "stellar" && wallet.status === "needs-device-approval") {
+ const prf = new PasskeyPrf({ rpName: "My App" });
+ await wallet.approveThisDeviceWithPasskey(await prf.getSecret());
+}
+```
+
+The React provider wraps this as `enrollPasskeyDefault()` and `approveDeviceWithPasskey()`. An optional recovery code is a last-resort unlock factor (`setupRecovery` / `approveThisDeviceWithRecovery`). Cavos never sees the code.
+
+## Best Practices
+
+1. **Keep `userId` and `appSalt` stable** — both are inputs to the derived address
+2. **Gate transactions on `status === "ready"`** — handle `needs-device-approval` instead of creating a new wallet
+3. **Enroll a passkey after signup** — it only adds devices; it does not sign
+4. **Treat the App ID as public** — do not put operator or treasury secrets in client code
+5. **Register callback URLs exactly** in the dashboard (scheme, host, path; no wildcards)
+6. **Test React Native on a development build** — Expo Go cannot load the native module; install the Expo native peers, add the config plugin, set `redirectUri` and `rpId`, then rebuild
+
+## When to Use Cavos
+
+**Use it when:**
+- You want an embedded wallet inside your app (no extension, no seed phrase)
+- Users should sign in with Google or Apple
+- The control key must be unwrapped only on the device (Cavos cannot see it or move funds)
+- You are building for the web (React) and/or React Native
+- Optional pass-through gas sponsorship would reduce onboarding friction
+
+**Consider another approach when:**
+- Users already have Stellar wallets they want to connect
+- You need hardware wallet support
+- You need a wallet-agnostic connect-button that talks to many existing wallets
+
+## Resources
+
+- [Website](https://cavos.xyz)
+- [Docs](https://docs.cavos.xyz)
+- [Live demo](https://demo.cavos.xyz)
+- [GitHub](https://github.com/cavos-labs/kit)
+- [Twitter/X](https://x.com/cavosxyz)
+- [npm — `@cavos/kit`](https://www.npmjs.com/package/@cavos/kit)
diff --git a/wallet-integration/comparison.md b/wallet-integration/comparison.md
index 33bad5e..689b3ba 100644
--- a/wallet-integration/comparison.md
+++ b/wallet-integration/comparison.md
@@ -4,17 +4,17 @@ A detailed comparison of wallet integration approaches for Stellar.
## Feature Comparison
-| Feature | Freighter | Stellar Wallets Kit | Smart Account Kit |
-|---------|-----------|---------------------|-------------------|
-| **Installation Required** | Browser extension or mobile app | None (library only) | None |
-| **User Authentication** | Extension popup | Wallet-specific | Passkey (biometric) |
-| **Mobile Support** | Yes (Freighter Mobile app, via WalletConnect) | Partial (LOBSTR, WalletConnect) | Yes |
-| **Gasless Transactions** | No | No | Yes (via Relayer) |
-| **Multi-wallet Support** | Freighter only | 15+ wallets | Smart wallets only |
-| **Hardware Wallets** | Ledger | Ledger, Trezor | No |
-| **Smart Wallet Features** | No | No | Yes (multisig, policies) |
-| **Setup Complexity** | Low | Medium | Medium |
-| **User Onboarding** | Must install extension | Choose from wallets | Create passkey |
+| Feature | Freighter | Stellar Wallets Kit | Smart Account Kit | Cavos |
+|---------|-----------|---------------------|-------------------|-------|
+| **Installation Required** | Browser extension or mobile app | None (library only) | None | None |
+| **User Authentication** | Extension popup | Wallet-specific | Passkey (biometric) | Google or Apple |
+| **Mobile Support** | Yes (Freighter Mobile app, via WalletConnect) | Partial (LOBSTR, WalletConnect) | Yes | Yes (React Native) |
+| **Gasless Transactions** | No | No | Yes (via Relayer) | Yes (pass-through relayer) |
+| **Multi-wallet Support** | Freighter only | 15+ wallets | Smart wallets only | Embedded wallet only |
+| **Hardware Wallets** | Ledger | Ledger, Trezor | No | No |
+| **Smart Wallet Features** | No | No | Yes (multisig, policies) | Classic `G…` account (device-native) |
+| **Setup Complexity** | Low | Medium | Medium | Medium |
+| **User Onboarding** | Must install extension | Choose from wallets | Create passkey | Sign in with Google or Apple |
## Integration Complexity
@@ -39,29 +39,36 @@ Lines of code: ~50-100
Dependencies: 1 (smart-account-kit) + Relayer setup
```
+### Cavos
+```
+Complexity: ⭐⭐ Medium
+Lines of code: ~50-100
+Dependencies: 1 (@cavos/kit) on web; React Native also needs Expo native peers (expo-modules-core, expo-web-browser, expo-linking)
+```
+
## User Experience Comparison
### New User Onboarding
-| Step | Freighter | Stellar Wallets Kit | Smart Account Kit |
-|------|-----------|---------------------|-------------------|
-| 1 | Install extension | Install extension OR use web wallet | Click "Sign Up" |
-| 2 | Create new wallet | Create new wallet | Scan fingerprint/face |
-| 3 | Save seed phrase | Save seed phrase | Done! |
-| 4 | Fund account | Fund account | (Optional) Fund later |
-| 5 | Connect to dapp | Connect to dapp | - |
+| Step | Freighter | Stellar Wallets Kit | Smart Account Kit | Cavos |
+|------|-----------|---------------------|-------------------|-------|
+| 1 | Install extension | Install extension OR use web wallet | Click "Sign Up" | Click "Sign in" |
+| 2 | Create new wallet | Create new wallet | Scan fingerprint/face | Google or Apple |
+| 3 | Save seed phrase | Save seed phrase | Done! | Done! |
+| 4 | Fund account | Fund account | (Optional) Fund later | - |
+| 5 | Connect to dapp | Connect to dapp | - | - |
-**Winner: Smart Account Kit** (2 steps vs 5)
+**Winner: Smart Account Kit or Cavos** (2 steps vs 5)
### Returning User Login
-| Step | Freighter | Stellar Wallets Kit | Smart Account Kit |
-|------|-----------|---------------------|-------------------|
-| 1 | Click "Connect" | Click "Connect" | Click "Sign In" |
-| 2 | Approve in extension | Select wallet | Scan fingerprint/face |
-| 3 | - | Approve in wallet | Done! |
+| Step | Freighter | Stellar Wallets Kit | Smart Account Kit | Cavos |
+|------|-----------|---------------------|-------------------|-------|
+| 1 | Click "Connect" | Click "Connect" | Click "Sign In" | Click "Sign in" |
+| 2 | Approve in extension | Select wallet | Scan fingerprint/face | Google or Apple (returning device is silent) |
+| 3 | - | Approve in wallet | Done! | Done! |
-**Winner: Smart Account Kit** (2 steps, no popups)
+**Winner: Smart Account Kit or Cavos** (2 steps, no wallet popups)
## Transaction Flow
@@ -80,6 +87,11 @@ User → Dapp → Selected wallet popup → User approves → Submit to network
User → Dapp → Passkey prompt → Submit to Relayer → Relayer pays fee
```
+### Cavos
+```
+User → Dapp → Google or Apple → Device P-256 key unwraps control key locally → Ed25519 control key signs → Relayer may sponsor fee
+```
+
## Cost Comparison
| Approach | User Pays Fees | Developer Pays Fees |
@@ -87,6 +99,7 @@ User → Dapp → Passkey prompt → Submit to Relayer → Relayer pays fee
| Freighter | Yes | No |
| Stellar Wallets Kit | Yes | No |
| Smart Account Kit | Optional | Optional (when a relayer is configured) |
+| Cavos | Optional | Optional (pass-through relayer when configured) |
## Use Case Recommendations
@@ -97,7 +110,7 @@ User → Dapp → Passkey prompt → Submit to Relayer → Relayer pays fee
- Users expect to pay their own fees
### Consumer Mobile App
-**Recommended:** Smart Account Kit
+**Recommended:** Smart Account Kit or Cavos
- Users may not have crypto experience
- Mobile-first experience needed
- Gasless transactions reduce friction
@@ -115,7 +128,7 @@ User → Dapp → Passkey prompt → Submit to Relayer → Relayer pays fee
- Flexibility for different user types
### Gaming / Social App
-**Recommended:** Smart Account Kit
+**Recommended:** Smart Account Kit or Cavos
- Mass market audience
- Users shouldn't need to understand crypto
- Fast, seamless transactions
@@ -133,6 +146,9 @@ Requires users to create new smart wallets. Consider:
### From Passkey Kit to Smart Account Kit
passkey-kit remains a maintained sibling SDK — migrate to Smart Account Kit when you need context rules and policy signers. The APIs and on-chain authorization models differ, so there is no drop-in upgrade path.
+### Adding Cavos
+Cavos provisions a new embedded classic account from Google or Apple login. It does not wrap existing extension wallets. Consider running it alongside an existing-wallet option during transition.
+
## Decision Flowchart
```
@@ -151,15 +167,19 @@ Are your users crypto-native?
│ │
│ └─ No → Stellar Wallets Kit
│
- └─ No → Is mobile support important?
+ └─ No → Should users sign in with Google or Apple?
│
- ├─ Yes → Smart Account Kit
+ ├─ Yes → Cavos
│
- └─ No → Do you want gasless transactions?
+ └─ No → Is mobile support important?
│
├─ Yes → Smart Account Kit
│
- └─ No → Consider your UX priorities
+ └─ No → Do you want gasless transactions?
+ │
+ ├─ Yes → Smart Account Kit
+ │
+ └─ No → Consider your UX priorities
```
## Summary
@@ -169,3 +189,4 @@ Are your users crypto-native?
| **Freighter** | Quick prototypes, developer tools | Broad multi-wallet user base |
| **Stellar Wallets Kit** | DeFi, existing crypto users | Non-crypto users, mobile-first |
| **Smart Account Kit** | Consumer apps, best UX | Hardware wallet requirement |
+| **Cavos** | Embedded self-custodial SDK, Google/Apple login | Existing wallets or hardware wallets |