This repo now runs the SIGIL website and protocol API from one service.
- Static website pages (
index.html,register.html,dashboard.html,gallery.html,stake.html,portfolio.html,leaderboard.html,passport.html) - Integrated API under
/api/*inapi/server.mjs - SQLite persistence in
api/db/sigil.db - Core protocol surfaces:
- Registration + challenge/verify
- One-time action challenge nonces for signed mutations
- Session/domain-bound action signatures (anti-replay + anti-origin confusion)
- Deterministic glyph rendering
- Signed receipt ingestion
- Merkle anchor commitments + proof verification
- Staking state + cooldown/emergency flows
- Passport issuance records + metadata endpoint
- Token-2022 non-transferable passport mint prepare/finalize endpoints
- Unified agent verification endpoint (
/api/verification/agent/:publicKey) - Compact verification + embeddable badge endpoints
npm install
npm run devVisit:
- http://localhost:3141
- http://localhost:3141/register.html
- http://localhost:3141/stake.html
- http://localhost:3141/passport.html
- http://localhost:3141/verify.html
- http://localhost:3141/integrations.html
npm testRuns the full real flow against Solana devnet:
- register + verify
- stake prepare/sign/send/finalize
- begin + complete unstake prepare/sign/send/finalize
- Token-2022 non-transferable passport mint prepare/sign/send/finalize
- readiness gate validation
npm run e2e:devnetIf devnet faucet is rate-limited, provide a funded keypair:
E2E_FUNDED_SECRET='<base58_or_json_secret>' npm run e2e:devnet# Local runtime verification (readiness + on-chain config sanity)
npm run verify:local
# Live production verification (expects productionReady=true)
npm run verify:prod
# Real mainnet smoke run (requires a funded wallet with SOL,
# and for staking, enough SIGIL balance)
SMOKE_WALLET_SECRET='<base58_or_json_secret>' npm run smoke:prodIf browser automation gets stuck on Chrome profile locks:
npm run playwright:resetcurl http://localhost:3141/api/health
curl http://localhost:3141/api/readiness
curl http://localhost:3141/api/stats
curl http://localhost:3141/api/agents?limit=10POST /api/auth/action-challengenow requires:sessionId(16-128 chars,[A-Za-z0-9_-])domain(origin URL, e.g.https://sigilprotocol.xyz)
- Mutation endpoints consuming nonce signatures require the same
sessionId+domain. - Staking supports two modes:
- legacy API-managed mode via
POST /api/staking/stake - real on-chain SPL transfer mode via:
POST /api/staking/stake-preparePOST /api/staking/stake-finalizePOST /api/staking/complete-unstake-preparePOST /api/staking/complete-unstake-finalizePOST /api/staking/emergency-unstake-preparePOST /api/staking/emergency-unstake-finalize
- on-chain mode is enabled with
SIGIL_STAKING_ONCHAIN=true. - in on-chain mode, both prepare and finalize writes require signed action challenges (session/domain-bound).
- legacy API-managed mode via
- Passport on-chain mint flow:
POST /api/passport/:publicKey/mint-preparePOST /api/passport/:publicKey/mint-finalizemint-finalizealso requires a signed action challenge (scope=passport,action=finalize).
GET /api/verification/agent/:publicKey?requirePassport=1GET /api/verification/agent/:publicKey/compact?requirePassport=1GET /api/verification/badge/:publicKey.svg?requirePassport=1GET /.well-known/sigil.json/.well-known/sigil.jsonis also checked in as a static file for edge/static hosts that intercept requests before Node routes.GET /api/readinessreturns production gate checks (missing/invalid env keys are explicit).
status = mintedmeans a real on-chain Token-2022 non-transferable passport was verified.status = legacy_simulatedmeans an old simulated passport record (non-on-chain) and is intentionally not counted as production passport issuance.
PORT(default3141)SIGIL_DB_PATH(defaultapi/db/sigil.db)PUBLIC_BASE_URL(optional; used for profile and metadata URLs)CORS_ORIGINS(comma-separated additional allowed origins)SOLANA_NETWORK(defaultmainnet-beta)SOLANA_RPC_URL(optional; defaults to cluster RPC forSOLANA_NETWORK)SIGIL_MINT(optional token mint address)SIGIL_STAKING_PROGRAM_ID(optional; set when a dedicated on-chain staking program is deployed)SIGIL_PASSPORT_COLLECTION(optional; set when enforcing a canonical collection marker)SIGIL_STAKING_ONCHAIN(defaultfalse; enables real on-chain staking flow)SIGIL_STAKING_TOKEN_PROGRAM(tokenortoken2022, defaulttoken)SIGIL_STAKING_VAULT_OWNER(vault owner wallet public key; required for on-chain staking)SIGIL_STAKING_AUTHORITY_SECRET(required to co-sign complete/emergency unstake payouts in on-chain mode)SIGIL_PASSPORT_SYMBOL(defaultSIGIL)SIGIL_ALLOW_LEGACY_PASSPORT_ISSUE(defaultfalse; keep disabled in production)STAKE_COOLDOWN_DAYS(default7)EMERGENCY_SLASH_BPS(default1000)MIN_STAKE(default1000)MAX_STAKE(default50000)ACTION_CHALLENGE_TTL_MS(default300000)
See .env.example for a complete configuration template.
For single-node deployments, use:
DEPLOY_HOST=<host> DEPLOY_PATH=<remote_path> ./scripts/deploy-production.shSee docs/PRODUCTION_RUNBOOK.md for the full production checklist and go/no-go gates.
docs/PROTOCOL_INTEL_AND_ROADMAP.mddocs/DEPLOYMENT_CHECKLIST.mddocs/NEXT_STEPS_AND_USER_EXPERIENCE.mddocs/PRODUCTION_RUNBOOK.md