Signet is a verifiable developer career record built on Stellar/Soroban. Developers link their deployment wallets to a profile; on-chain attestations bind wallet → identity; an indexer pulls every contract they've deployed along with its activity. Public profiles become the canonical record of a developer's smart-contract career.
| Component | Network / host | State |
|---|---|---|
| Identity Registry contract | Stellar testnet | Deployed 2026-07-09 — CASFJHI5PQSRWS7JV25CF7FOMRKIVBP3RXRP3E2GH2CV4BCAG7FUJRCN, wasm executable, initialized |
| Identity Registry contract | Stellar mainnet | Not deployed |
Web app (apps/web) |
Netlify (netlify.toml) |
Deployed — landing, /how-it-works, /handles, tRPC API, SIWS auth, demo profiles |
Indexer (apps/indexer) |
GHCR image, opt-in deploy.yml |
Code-complete, not provisioned — needs a Postgres to point at |
PostgreSQL (packages/db) |
— | Prisma schema + migrations committed; no hosted instance |
Point the app at the deployed registry with:
NEXT_PUBLIC_IDENTITY_REGISTRY_ID=CASFJHI5PQSRWS7JV25CF7FOMRKIVBP3RXRP3E2GH2CV4BCAG7FUJRCNWhat the deployment does not change: the three profiles at /p/{handle}
still render the curated synthetic testnet manifest in
apps/web/public/data/ — a live registry does not make that data real activity.
/handles is the one surface that reads live on-chain state. It discovers candidate
handles from the registry's claimed/released event stream, then confirms each one
with a resolve call before listing it as bound, and takes its headline number from
the contract's own count(). Curated demo handles that do not resolve are shown in a
separate section labelled not bound on-chain and are never counted — with no contract
id configured, the page says so rather than presenting the manifest as registry state.
https://signet-web-pearl.vercel.app — deployed from main.
Demo profiles use synthetic data on Stellar testnet — generated, unowned accounts — so no real wallet's activity is attributed to an invented persona. Production renders real mainnet activity bound on-chain via the Identity Registry. Provenance, schema, regeneration, and the honesty policy:
docs/DEMO_DATA.md.
| URL | Description |
|---|---|
/ |
Landing page with "See it in action" section |
/p/aquawolf |
Demo profile — Blend-style collateral ops (testnet, synthetic) |
/p/sorobuilder |
Demo profile — Soroswap-style DEX swaps (testnet, synthetic) |
/p/stellardev |
Demo profile — USDC token transfers (testnet, synthetic) |
/handles |
Handle directory — bindings confirmed against the registry via resolve, counted by its own count(); demo personas listed separately and labelled not bound on-chain |
/how-it-works |
How Signet works + what's coming |
docs/DEMO_DATA.md |
Demo fixture provenance, schema, and honesty policy |
- Landing page — polished marketing page with animated sections and a live "See it in action" demos block linking to the 3 profiles
- Demo profiles at
/p/{handle}— server-rendered (SSG) profile pages reading synthetic testnet operation data fromapps/web/public/data/{handle}.json; clearly labelled as demo data - How it works page — explains the thesis, what's live, and what's coming
- Middleware routing —
/p/and/how-it-workspass through; handles validated; legacy/profile/redirects to/p/ - Production data path — the same UI renders real Horizon API data once the indexer + a Postgres instance are provisioned (
safeDbProfilealready wires the DB-with-static fallback)
- On-chain Identity Registry — deployed to testnet — a real Soroban contract (
packages/contracts/identity-registry) binds a wallet to a handle via a signedclaim; ownership is enforced byrequire_auth. Live atCASFJHI5PQSRWS7JV25CF7FOMRKIVBP3RXRP3E2GH2CV4BCAG7FUJRCNsince 2026-07-09 (see Status). 24 unit tests, builds to wasm. - Wallet connect + claim flow — live —
Connect wallet/Claim your handleuse Stellar Wallets Kit and submit a real on-chainclaimagainst the deployed registry (apps/web/lib/{wallet,registry}.ts) wheneverNEXT_PUBLIC_IDENTITY_REGISTRY_IDis set. With no contract id configured,claimHandlethrowsRegistryNotConfiguredErrorand the UI shows an honest "Phase 2" message rather than a broken button. - Public handle directory —
/handlesrebuilds the currently-bound set from the registry'sclaimed/releasedevent stream over Soroban RPC, with no database in the path (apps/web/lib/directory.ts). - Real API + SDK — tRPC
profile.byHandle/profile.list/health;@signet/sdkfetches them. Both covered by tests. - CI gates lint · typecheck · test · build, plus a Rust contract job.
- Mainnet deploy of the Identity Registry (testnet is live — see Status), plus a contract audit before it.
- Run the indexer against a Postgres instance to populate full deployment/activity history;
/palready has a DB-with-static-fallback loader (safeDbProfile). - Self-sovereign bindings replace the curated
DEMO_PROFILESmapping as claims land on the deployed registry. - Developer dashboard (
/app/*) — currently an honest read-only preview pending wallet auth. - Reputation scoring — attestations, TVL tracking, incident records.
git clone <repo> signet && cd signet
pnpm install
# Run just the web app (no database needed for the demo routes)
pnpm --filter @signet/web devVisit http://localhost:3000 for the landing page.
Visit http://localhost:3000/p/aquawolf for the first demo profile.
Requires Node 22+. Fonts (
IBM Plex Sans/Mono) load via a browser-side@importinglobals.css(notnext/font), so the build never blocks on font downloads.
First-run failures (stellar CLI passphrase bug, Friendbot funding, missing
wasm32v1-none, no DATABASE_URL, Phase 2 claim message, indexer without a
registry id): see docs/TROUBLESHOOTING.md.
See docs/DEPLOYMENT.md for a clone-to-running guide:
prerequisites, deploy key + Friendbot, wasm build, infra/deploy-contract.sh,
initialize(admin), Netlify (netlify.toml) and Vercel production env
(including SIGNET_AUTH_SECRET), verification checklist, and rollback.
See PROPOSAL.md for the grant proposal: the problem
statement, an itemized budget, dated milestones through 2027-04-30, and a
fix-log of resolved issues with the tests that keep them closed.
See ARCHITECTURE.md for the real data flows
(claim → event → attestation → DB and wallet → operations → DB), the read
path, and a precise breakdown of what is deployed vs operational-only.
Both flows are code-complete; the sketch below marks which pieces are running.
browser ──▶ apps/web (Next.js) [DEPLOYED]
/p/{handle} · /handles · /how-it-works · /api/trpc · /api/auth
│ │
reads profile │ │ submits signed claim
(DB first, │ ▼
static │ Identity Registry (Soroban) [DEPLOYED 2026-07-09]
fallback) │ testnet · CASFJHI5…AG7FUJRCN
│ │ emits claimed / released
│ ▼
│ apps/indexer (worker) [OPERATIONAL-ONLY]
│ attestation ← Soroban RPC getEvents
│ deployment · operations · activity ← Horizon
│ │ upserts
▼ ▼
packages/db (PostgreSQL) [OPERATIONAL-ONLY]
Profile · Wallet · Contract · Operation · ContractSnapshot
/handles reads the registry's event stream over Soroban RPC directly — the
indexer's Postgres sync is an accelerant for it, not a dependency.
Deployed & serving traffic
apps/webon Netlify — landing,/how-it-works,/handles, demo profiles (synthetic manifest), tRPC API, SIWS authpackages/contracts/identity-registry— Soroban contract on Stellar testnet, 24cargo testunit tests, builds to wasm
Operational-only — built and tested, needs provisioning to go live
apps/indexer— attestation + deployment + operations + activity workers; needsDATABASE_URLpackages/db— Prisma schema + committed migrations; no hosted Postgres yetpackages/sdk— external SDK over the tRPC API; in-tree, not yet published to npm
See docs/INDEXER.md — the operator runbook: what each worker
does, how cursors and the ledger-window cold start work, every INDEXER_* setting,
running locally and in Docker, what the structured log lines mean, and a troubleshooting
table for the common failures.
See docs/REGISTRY_INTEGRATION.md to resolve Signet
handles from your own app: the deployed testnet contract id and passphrase, every
contracterror code, the event topic/data layout, and @stellar/stellar-sdk snippets for
reading (resolve / lookup / is_bound / count), claiming, and rebuilding the handle
set from the event stream.
| Path | Purpose |
|---|---|
apps/web |
Next.js App Router + tRPC API |
apps/indexer |
Long-running TypeScript indexer worker |
packages/contracts |
Soroban Rust contracts |
packages/db |
Prisma schema + generated client |
packages/sdk |
External SDK for integrators |
packages/types |
Shared TypeScript types |
packages/ui |
Shared React components |
infra |
Local dev infra (Docker Postgres) |
| Command | Description |
|---|---|
pnpm dev |
Run all apps via Turborepo |
pnpm --filter @signet/web dev |
Run web app only (no DB required for demo) |
pnpm --filter @signet/web build |
Build web app |
pnpm --filter @signet/web typecheck |
Typecheck web app |
pnpm db:up / db:down |
Start / stop local Postgres |
pnpm db:migrate |
Run Prisma migrations |
pnpm test |
All TypeScript tests via Turborepo |
cargo test (in packages/contracts) |
Identity Registry unit tests |
| Suite | Count |
|---|---|
pnpm test |
208 — @signet/web 137 · @signet/indexer 36 · @signet/sdk 26 · @signet/types 9 (ui, db have no tests yet) |
cargo test |
30 — packages/contracts/identity-registry |
Both are CI gates (ci.yml), alongside lint,
typecheck, build and the wasm contract build.
Signet is licensed under the Apache License 2.0 — see LICENSE for the
full text. This covers every workspace package (@signet/sdk, @signet/types,
@signet/ui, @signet/db, @signet/web, @signet/indexer) and the Soroban
identity-registry contract.