Introduction

SIWX (Sign-In With X) is the authentication project of TUWA Stage 1: headless, framework-agnostic sign-in for EVM and Solana accounts, built on the CAIP-122 standard. It builds and signs chain-agnostic sign-in messages, verifies them on your backend with single-use nonces and cookie sessions, and tracks the sign-in state in React, with no UI components and no hosted services.
🏛️ Where SIWX Fits in TUWA
TUWA is built in stages. Each stage builds on the ones below it, and SIWX sits at the bottom:
| Stage | Projects | Role |
|---|---|---|
| 1 — Core Auth & Primitives | SIWX, Orbit Utils | CAIP-122 authentication and multi-chain primitives |
| 2 — State & Connection | Satellite Connect , Pulsar | Wallet connection state machine and transaction tracking |
| 3 — Backend & Sync | Quasar Cloud or self-hosted Quasar Community | Transaction indexing and cross-device sync |
| 4 — User Interface | Nova UI Kit | React design system and components |
Besides Orbit Utils (chain and account IDs from @tuwaio/orbit-core, and the Solana message signer from @tuwaio/orbit-solana), SIWX depends on nothing else in TUWA. Higher layers use it (for example, Satellite Connect and the TUWA SDK), never the other way around. You can also use SIWX on its own in any app.
🧭 Principles
- One standard for every chain: messages follow CAIP-122 (the EIP-4361 text layout), with CAIP-2 chain IDs such as
eip155:1and CAIP-10 accounts. EVM and Solana use the same flow, types and backend routes. - Headless and framework-agnostic: no CSS or UI components. The core and server packages are plain functions and use Web APIs (
Request,Response, Web Crypto); React bindings live in their own package. - Modern Web3 libraries only:
viemand@wagmi/corefor EVM,@solana/kitand Web Crypto ed25519 for Solana. Noethers.js,web3.js,@solana/web3.jsorgill. - Your backend, your data: there is no hosted authentication service. Nonces and sessions live in stores you provide (Redis, SQL, KV…), and wallets stay with the user.
- The server decides: the client state is for the UI only. Sessions are
HttpOnlycookies checked on the server, nonces are single-use, and every verifier documents what it checks.
🔐 How a Sign-In Works
Browser (@tuwaio/siwx-react) Wallet Your backend (@tuwaio/siwx-server)
│── GET /api/siwx/nonce ───────────────────────────────────▶ issue nonce (SiwxNonceStore, 300 s)
│◀─ { nonce } ────────────────────────────────────────────── │
│── buildMessage(fields) ─────────▶ sign (EIP-191 / ed25519) │
│◀─ signature ─────────────────────│ │
│── POST /api/siwx/verify { message, signature } ──────────▶ verify policy + signature,
│ consume nonce, create session
│◀─ session JSON + Set-Cookie (HttpOnly) ─────────────────── │
│── useSiwxSession(): authenticated │The message the wallet signs:
app.tuwa.io wants you to sign in with your blockchain account:
eip155:1:0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B
Sign in to TUWA.
URI: https://app.tuwa.io
Version: 1
Chain ID: eip155:1
Nonce: 3f9c1e2a7b4d8f6051c2e9a0d7b3f418
Issued At: 2026-09-26T10:00:00.000Z
Expiration Time: 2026-09-26T10:10:00.000Z🧩 Packages
| Package | Layer | Provides | Peer dependencies |
|---|---|---|---|
@tuwaio/siwx-core | L1 | CAIP-122 build, parse and validate; verification policies, session matching, nonces, errors and types | @tuwaio/orbit-core ≥ 0.5 |
@tuwaio/siwx-evm | L2 | EVM signer, EIP-191 (EOA), EIP-1271 and ERC-6492 (smart contract wallet) verification | @tuwaio/siwx-core, @tuwaio/orbit-core, viem ≥ 2.18.6, @wagmi/core ≥ 3 |
@tuwaio/siwx-solana | L2 | Solana signer, ed25519 verification with Web Crypto | @tuwaio/siwx-core, @tuwaio/orbit-core, @tuwaio/orbit-solana ≥ 0.7.1, @solana/kit ≥ 6, @wallet-standard/base ≥ 1.1.0 |
@tuwaio/siwx-react | L2 | useSiwx and useSiwxSession hooks, persisted zustand session store, Satellite Connect helpers | @tuwaio/siwx-core, @tuwaio/orbit-core, react ≥ 18, zustand ≥ 5, immer ≥ 10 |
@tuwaio/siwx-server | L2 | Server verification, nonce and session stores, cookies, Next.js App Router handlers, JWT/JWKS for external auth | @tuwaio/siwx-core, @tuwaio/orbit-core; optional: @tuwaio/siwx-evm ≥ 0.5, @tuwaio/siwx-solana, viem ≥ 2 |
Each package page shows the package README followed by a reference of every export, generated from the TypeScript source.
💾 Installation
Install the core package and the L2 packages your app needs:
# L1 core
pnpm add @tuwaio/siwx-core @tuwaio/orbit-core
# L2 EVM
pnpm add @tuwaio/siwx-evm @tuwaio/siwx-core @tuwaio/orbit-core @wagmi/core viem
# L2 Solana
pnpm add @tuwaio/siwx-solana @tuwaio/siwx-core @tuwaio/orbit-core @tuwaio/orbit-solana @solana/kit @wallet-standard/base
# L2 React
pnpm add @tuwaio/siwx-react @tuwaio/siwx-core @tuwaio/orbit-core react zustand immer
# L2 Server
pnpm add @tuwaio/siwx-server @tuwaio/siwx-core @tuwaio/orbit-core📚 Next Steps
- Browse the Packages section for usage examples and the full reference of each package.
- Follow the Multi-Chain Authentication guide for why CAIP-122 replaces single-chain SIWE flows and how SIWX implements it across EVM and Solana.
- Hand a sign-in to Coinbase CDP custom authentication, other embedded wallet providers or your own services as a JWT with the External Auth guide .
- Let Supabase trust the same JWT and give each wallet only its own rows with Row Level Security: Supabase RLS guide .
- Find more ecosystem guides at docs.tuwa.io/guides .
- Read the CAIP-122 specification and the source on GitHub .