Developers
Open source monorepo: Foundry contracts, a shared TypeScript core, the subgraph, the agent and this dashboard.
Source code
github.com/rsodre/spirith, a pnpm workspace. The parts:
- contracts/: the vault, the yield adapters, the vendored ENSv2 interfaces, unit, fuzz and invariant tests, and the deploy and proof scripts.
- packages/core: chain config, the address and ABI registry, pricing, runway and liveness math, the subgraph client.
- packages/subgraph: schema, manifest template and mappings.
- packages/agent: the MCP server, the cadence optimiser and the keeper CLI.
- apps/web: this dashboard.
Contracts on Sepolia
Verified on Etherscan. The vault never holds a name; it holds USDC earmarked per name and has exactly two exits for it.
| Contract | Address | Does |
|---|---|---|
| SpirithVault | 0xaC0F…2d32 | per-name earmarks, endow, notice and withdraw, permissionless renew, record write |
| MockYieldAdapter | 0xb449…0832 | simulated 4% on Sepolia; ERC4626Adapter is the mainnet one, proven on a fork |
The contracts of the ENSv2 hackathon deployment on Sepolia the vault calls, verified against that deployment's universal resolver entry point. The set is served by its own ENS app and explorer; the environment is chosen by NEXT_PUBLIC_ENV.
| Contract | Address | Does |
|---|---|---|
| ETHRegistrar | 0x7d1B…270b | renew(), getRenewPrice(), isRenewable() |
| ETHRegistry | 0x1D78…971e | findExpiry(), findOwner(), getResolver() |
| MockUSDC | 0xcBFD…6F05 | the payment token; permissionless mint |
| PermissionedResolverImpl | 0xa9d3…614e | the resolver that carries spirith.* records |
| VerifiableFactory | 0x894b…7780 | deploys a resolver proxy per owner |
Subgraph
spirith-sepolia on Subgraph Studio indexes every .eth name on the registry of the ENSv2 hackathon deployment on Sepolia and every Spirith event: Name, Endowment, Patron, RenewalEvent and a Namespace row of running totals. Nothing time-dependent is stored; risk bands and funded-until are computed at read time.
MCP server
The agent is an MCP server over that subgraph and the vault, with five tools. Its job is not to watch for expiry but to optimise renewal cadence against ENSv2's duration discounts.
namesAtRisk(days): names expiring within the window, ranked by band, price tier and timerunway(name): funded-until range for one name, with the rate assumption statedoptimalCadence(name): the renewal block with the longest runway against the discount curveportfolioHealth(address): every name a patron supports, soonest to run dry firstrescueProposal(name): how much to endow, what it buys, and the exact approve and endow calls
Clone the repository, run pnpm install, put a Sepolia RPC URL in .env, and Claude Code picks the server up from the repository's .mcp.json:
{
"mcpServers": {
"spirith": {
"command": "pnpm",
"args": ["--silent", "--filter", "@spirith/agent", "mcp"]
}
}
}Then ask: which endowed names die in the next 30 days and what should each renew for? Claude Desktop needs the built server; the package README has that form.
Keeper
A CLI in the same package asks the vault whether a name may be renewed and for how long, simulates, sends, and collects the tip. Without a key it only simulates.
pnpm --filter @spirith/agent keeper once --label <name> --dry-run
pnpm --filter @spirith/agent keeper watch --interval 300