DragonGlass: Earned, Soulbound Marks
What this chapter covers
Chapter 24 covers the SBT โ your one NightWatch identity. Chapter 25 covers your verified-contribution reputation number. This chapter covers DragonGlass: a growing shelf of distinct, soulbound proof-of-achievement marks bound to your SBT โ verified work, delivered notional, a completed 30-day pilot โ that you mint yourself on-chain, and that together rank wallets publicly in the Hall.
What it is
DragonGlass marks are earned, never bought. NightWatch detects when an
account qualifies (from facts it already records elsewhere โ verified
contributions, auction delivered notional, a pilot vault's own record) and
writes an off-chain row. The holder then mints the on-chain token
themselves, presenting a signed voucher; nobody else can mint it for them,
and once minted it can never be transferred, approved for transfer, sold,
or burned by anyone (contracts/DragonGlassMarks.sol).
Mark types live today:
| Mark | Levels | Detected from |
|---|---|---|
| Verified work | 1 ยท 5 ยท 20 ยท 50 | verified_contribution_count (ch. 25's own reputation count) |
| Delivered notional | $100k ยท $1M ยท $100M | svc/common/auction_tiers.py delivered-notional tier ladder |
| Pilot completed | 30 days | a non-house pilot vault's record_start age |
Planned, not yet detectable: first vault created, re-observation streak (docs/pm/DRAGONGLASS_ORDER.md "v1.1" row).
Delivered notional is turned off entirely while the underlying vault
flows run on a testnet (NW_VAULT_BSC_TESTNET=1) โ a testnet mock
delivery must never earn a real "Delivered" mark. This one environment
variable is read identically by the API and by the detector-sweep worker,
so the two can never disagree about it.
The state machine
Each (SBT, mark type, level) on a given chain moves through three
states, tracked in nw_dragonglass_marks โ the same numeric SBT id on Base
Sepolia and Base mainnet names two different holders, so a mark earned on
one chain is a completely separate record from the same-numbered id on
another:
- issued โ NightWatch's detector found you eligible. Today every live
detector writes
issuedandclaimablein the same instant (no manual review gate on these three types yet) โ the two states stay distinct in the schema so a future mark type that DOES need review can pause atissuedwithout a migration. - claimable โ ready to mint.
GET /dragonglass/meshows it with a Mint button. - minted โ on-chain. The mint indexer (
svc/worker/ nw_dragonglass_indexer.py) confirmed the transaction and recorded its hash; onlymintedmarks count toward the Hall.
Minting: who signs what
- You call
POST /dragonglass/claimwith{mark_type, level}for a mark you already haveclaimable. The server checks you own it, then signs an EIP-712 voucher (holder,sbtTokenId,markType,level,nonce,expiry) with the dedicated DragonGlass issuer key โ a key that only ever SIGNS, never sends a transaction. - Your own wallet submits that voucher to
DragonGlassMarks.mint(...). The contract checks: you aremsg.sender == holder; the voucher isn't expired;sbtTokenIdreally is your own NightWatchSBT (read live fromNightWatchSBT.agentToken); the nonce hasn't been used before; the signature recovers to a currently-held issuer role; and you don't already hold this exact (SBT, type, level). - The mint indexer picks up the
MarkMintedevent and flips your row tominted.
Gas for the mint is paid by the holder's own wallet, in the chain's own native gas token โ the existing Cherry gas payer does not support this chain yet, so minting is not Cherry-sponsored today. Cherry-sponsored gas for DragonGlass is planned for v1.1.
Where you see it
- Forge โ ๏ผ Create (
/forge/new) โ the "3 DragonGlass" card shows your live states when signed in, and the mark catalog (neutral, no fake per-account state) when signed out. - Account โ Identity (
/account?tab=identity) โ the profile shelf: the same live data, with mint transaction links once minted. - The Hall (
/forge/hall) โ wallets ranked by total mark weight (verified work 1/3/8/15 ยท delivered 5/15/40 ยท pilot completed 5), ties broken by most recent mint activity. Public, no auth. Linked from the Makers tab (/forge/makers).
Minting sends a real transaction from your own wallet, to the exact chain the contract lives on. Your wallet is switched to (or asked to add) that chain before the transaction is sent, and checked again afterward โ the transaction is only sent once your wallet actually confirms it is on that chain, not merely once the switch request itself resolved. If your connected wallet doesn't match the mark's own holder address, or if you're using the NightWatch embedded wallet and it can't reach that chain, you get a plain message instead of a transaction that would only fail.
API
GET /dragonglass/meโ the caller's own marks (auth required; runs the live detectors inline so a freshly-earned mark shows immediately).POST /dragonglass/claimโ{mark_type, level}โ a signed voucher for a mark you already haveclaimable, for the contract above. Rate-limited per account.GET /dragonglass/hallโ the public ranking (no auth), capped at 100 rows and scoped to the currently-deployed contract.
What is planned
First-vault-created and re-observation-streak marks (v1.1) โ the contract and API already support adding a new (markType, level) with no redeploy; only the server-side detector for each is unbuilt yet.