Seed Identity
Anky v2 uses EVM seed-based identity. A seedphrase generates a wallet on the device. The backend only ever sees the derived wallet address and signed messages. Never the seed.
How It Works
On the Device (iOS App)
- User creates or imports a BIP-39 seedphrase
- The app derives an EVM wallet (secp256k1) from the seed
- The wallet address becomes the user's identity
Authentication Flow
Device Server
│ │
│ POST /swift/v2/auth/challenge
│ { wallet_address: "0x..." } │
│──────────────────────────────▶│
│ │ Generate random challenge
│ { challenge: "Sign this..." }│ Store in auth_challenges
│◀──────────────────────────────│ with expiry
│ │
│ Sign challenge with │
│ private key (EIP-191) │
│ │
│ POST /swift/v2/auth/verify │
│ { wallet, signature, │
│ challenge } │
│──────────────────────────────▶│
│ │ Verify EIP-191 signature
│ │ Find/create user
│ │ Consume challenge
│ { session_token: "..." } │ Mint bearer session
│◀──────────────────────────────│
│ │
│ All subsequent requests: │
│ Authorization: Bearer <token>│
│──────────────────────────────▶│Child Wallet Derivation
Child identities are derived from the parent's seed on-device:
Parent seed → Parent wallet (m/44'/60'/0'/0/0)
→ Child 1 wallet (m/44'/60'/0'/0/1)
→ Child 2 wallet (m/44'/60'/0'/0/2)
→ ...The server stores child_profiles.derived_wallet_address but never computes it. The device tells the server "this child wallet belongs to this parent wallet" and the server trusts the relationship because the parent authenticated.
Privacy Properties
- Seedphrase: Never leaves the device. Never sent to the server.
- Private key: Never leaves the device. Only used to sign challenges.
- Wallet address: Public. Used as the identity key.
- Writings: Keyed by wallet address in both SQLite and the file archive.
- Children: Derived wallets are computed on-device, stored on-server as associations only.
Why Not OAuth/Privy?
v1 uses Privy (OAuth-style). v2 moved to direct seed auth because:
- No dependency on Privy's servers — if Privy goes down, v2 auth still works
- Deterministic identity — the same seed always produces the same wallet. No account recovery, no email, no phone number.
- Child derivation — you can't derive child wallets from an OAuth token
- Philosophical alignment — the user owns their identity by holding their seed, not by having an account in someone else's database