Multi-chain Web3 login for React apps, self-hosted auth servers, and wallet adapter authors.
Dolphin ID is a TypeScript monorepo for SIWX-style authentication across EVM, Sui, Solana, Bitcoin, and Aptos. SIWX ("Sign-In With X") generalizes EIP-4361 / Sign-In With Ethereum to every supported chain. It provides chain-neutral adapter contracts, React hooks, optional default UI, self-hosted server auth primitives, CLI app scaffolding, hosted-service primitives, runnable examples, and Go/Rust/Python verification helpers.
Current scope: v1.0.0, released on 2026-06-01. Read the
v1.0.0 release notes for the full release scope.
| Need | Start here |
|---|---|
| Add wallet login to a React app | @dolphin-id/react with adapters and optional @dolphin-id/ui |
| Run auth on your own server | @dolphin-id/server and the security guide |
| Scaffold a Next.js integration | dolphin-id create |
| Build a third-party chain adapter | Adapter specification and examples/adapter-third-party |
| Verify sessions outside Node.js | Go/Rust/Python server SDKs |
| Try the complete browser flow | examples/next |
| Chain | Client package | Server verification |
|---|---|---|
| EVM | @dolphin-id/adapter-evm |
EIP-4361 SIWE |
| Sui | @dolphin-id/adapter-sui |
Sui personal-message signatures |
| Solana | @dolphin-id/adapter-solana |
SIWS Ed25519 signatures |
| Bitcoin | @dolphin-id/adapter-bitcoin |
P2PKH SIWX signatures |
| Aptos | @dolphin-id/adapter-aptos |
Aptos Ed25519 SIWX signatures |
Using an AI coding agent? This repo ships a
dolphin-idskill. Ask your agent to "install and configure Dolphin ID" and it will add the packages, wire upDolphinProvider, and scaffold server auth for you. To start a fresh app instead, use thedolphin-id createscaffolder.
Prerequisites: Node.js 22+, a package manager (examples use pnpm 11), and React 18+ for the client packages.
Install the core runtime, the adapters you need, and any optional packages:
# React app: core + provider + optional default UI + the adapters you support
pnpm add @dolphin-id/core @dolphin-id/react @dolphin-id/ui \
@dolphin-id/adapter-evm @dolphin-id/adapter-sui @dolphin-id/adapter-solana
# Self-hosted auth server
pnpm add @dolphin-id/server
# Add Bitcoin / Aptos only when your app needs them
pnpm add @dolphin-id/adapter-bitcoin @dolphin-id/adapter-aptosCreate the chain adapters your app supports:
import { createEvmAdapter } from "@dolphin-id/adapter-evm";
import { createSolanaAdapter } from "@dolphin-id/adapter-solana";
import { createSuiAdapter } from "@dolphin-id/adapter-sui";
export const adapters = [
createEvmAdapter({ chainId: 1, chainName: "Ethereum" }),
createSuiAdapter({ network: "testnet" }),
createSolanaAdapter({ network: "devnet" })
];Wrap your app with the headless provider and default UI components:
import { DolphinProvider } from "@dolphin-id/react";
import { AccountDisplay, ConnectButton } from "@dolphin-id/ui";
import { adapters } from "./adapters";
export function App() {
return (
<DolphinProvider
config={{
adapters,
auth: {
nonceUrl: "/auth/nonce",
verifyUrl: "/auth/verify",
refreshUrl: "/auth/refresh",
logoutUrl: "/auth/logout",
credentials: "same-origin"
}
}}
>
<ConnectButton />
<AccountDisplay />
</DolphinProvider>
);
}Create server auth with chain-specific verification:
import {
createServerAuth,
verifyEvmSiweMessage,
verifySolanaSiwsMessage,
verifySuiPersonalMessage
} from "@dolphin-id/server";
export const auth = createServerAuth({
jwtSecret: process.env.DOLPHIN_JWT_SECRET ?? "",
runtimeEnvironment: process.env.NODE_ENV,
publicOrigin: process.env.NEXT_PUBLIC_APP_ORIGIN,
verifySiwx: async (request) => {
switch (request.message.chainType) {
case "evm":
return verifyEvmSiweMessage(request, {
expectedDomain: "example.com",
expectedChainId: 1
});
case "sui":
return verifySuiPersonalMessage(request, {
expectedChainId: "testnet"
});
case "solana":
return verifySolanaSiwsMessage(request, {
expectedDomain: "example.com",
expectedChainId: "devnet"
});
default:
return { ok: false, reason: "Unsupported chain." };
}
}
});Expose auth routes for:
POST /auth/noncePOST /auth/verifyPOST /auth/refreshGET /auth/mePOST /auth/logout
See docs/getting-started.md for the route flow and
examples/next for complete Next.js App Router handlers.
Generate a runnable Next.js app with selected chains, UI mode, auth mode, and token storage mode:
dolphin-id create my-dolphin-app --framework next --chains evm,sui --ui default --auth self-hosted --token-storage cookieThen run the generated app:
cd my-dolphin-app
pnpm install
pnpm test
pnpm devMore recipes live in docs/cli.md.
Run the repository's Next.js example:
pnpm install
pnpm --filter @dolphin-id/example-next devOpen http://127.0.0.1:3000, connect a mocked EVM or Sui wallet, and sign in.
The example stores the issued session in an HTTP-only cookie and restores it
through /auth/me after refresh.
Run its browser coverage:
pnpm --filter @dolphin-id/example-next test| Path | Package | Purpose |
|---|---|---|
packages/core |
@dolphin-id/core |
Chain-neutral contracts, SIWX types, events, errors, and shared state |
packages/react |
@dolphin-id/react |
DolphinProvider, headless hooks, auth client integration, and session state |
packages/ui |
@dolphin-id/ui |
Default UI components, themes, locales, and copy overrides |
packages/server |
@dolphin-id/server |
Self-hosted nonce, verification, identity, JWT session, refresh, and middleware helpers |
packages/cli |
@dolphin-id/cli |
App scaffolder for Next.js integrations |
packages/hosted |
@dolphin-id/hosted |
Hosted nonce/session service primitives and development stores |
packages/adapter-* |
@dolphin-id/adapter-* |
Chain-specific wallet discovery, SIWX signing, and address normalization |
sdks/go |
Go SDK | EVM/Sui verification and HS256 session claim helpers |
sdks/rust |
Rust SDK | EVM/Sui verification and HS256 session claim helpers |
sdks/python |
Python SDK | EVM/Sui verification and HS256 session claim helpers |
apps/docs |
@dolphin-id/docs |
Next.js documentation site |
examples/next |
@dolphin-id/example-next |
Full EVM/Sui login example with Playwright coverage |
examples/basic |
@dolphin-id/example-basic |
Minimal adapter construction playground |
examples/adapter-third-party |
@dolphin-id/example-adapter-third-party |
Contract-tested sample external adapter |
CI runs on Node.js 22 and pnpm 11.0.9.
pnpm install
pnpm typecheck
pnpm test
pnpm lint
pnpm buildAdditional local commands:
pnpm format:check
pnpm --filter @dolphin-id/docs dev
pnpm changeset
pnpm version-packagesRun multi-language SDK parity tests:
cd sdks/go && go test ./...
cd ../rust && cargo test
cd ../python && python3 -m pip install -e '.[test]' && pytestStart at the documentation index, or jump to:
- Product overview
- Getting started
- API reference
- Server SDKs
- CLI scaffolder
- Third-party adapter specification
- Adapter test fixtures
- Security guide
- v1.0 security audit summary
- Troubleshooting
- Roadmap
- Contributing & workflow
- v1.0.0 release notes
Production integrations should review docs/security.md
before accepting traffic.
- Sign-in nonces are random, expiring, single-use, and domain-bound.
createServerAuthrejects short or obvious JWT secrets in production.- Production origins must use HTTPS unless an explicit insecure override is reviewed.
- Cookie-backed sessions use HttpOnly cookies and production
Secureenforcement throughcreateSessionCookieOptions. - Refresh tokens rotate on every successful refresh.
invalidateSessions(subject)forces existing access and refresh tokens to fail.- Hosted projects must enforce exact allowed domains, scoped API keys, quotas, and audit logging.
To report a vulnerability privately, open a GitHub security advisory rather than a public issue.
Contributions are welcome. The
contributing & collaboration workflow
describes branch, review, and release conventions. Before opening a pull
request, run the development checks (typecheck, test,
lint, build) and add a changeset with pnpm changeset when your change
affects a published package.
Dolphin ID is licensed under the Apache License 2.0.