
Meigi (名義)
Confirmation of Payee for stablecoins and AI agents. Pay companies, not addresses.
Demo
About
Stablecoin payments go to an address, and nothing checks that the address belongs to the company you mean to pay. A fake "our bank details changed" email, a prompt injection hidden in an invoice, or a hacked x402 server that swaps payTo all redirect the money the same way. Banks fixed this for wires with Confirmation of Payee (UK) and Verification of Payee (mandatory in the euro area since October 2025). Stablecoins, and the AI agents now paying with them, have nothing like it. Meigi (名義, the name on an account) binds a Japanese company's T-number, the registration number printed on its qualified invoices, to exactly one payout address: - Registering needs an exact name match against the NTA corporate-number registry (5.79M records, 5.0M open), a DNS proof on a domain the registrant controls, and World ID officers. - A payout changes only through a 72-hour public window: the business key with its World ID officers (verifier-checked, attester co-signed, verified on-chain), or a governance ruling on a dispute. Nothing changes it instantly. - A second claim on a number freezes it instead of overwriting it. Payers check it three ways: - ENS: t2011001234567.payee.eth resolves to the active payout in stock viem and ENS's own app and explorer on Sepolia; unknown or disputed numbers resolve to nothing. - AgentVault: our AI accounts-payable agent can pay only registered payees, within caps. Prompt-inject it into trying to pay a scammer and the vault reverts PayeeMismatch, returning the registered payout, and the agent names the company it belongs to. - x402 guard: before an agent signs, a merchant that declares its T-number must be paid at its registered payout; one that declares none gets at most a small screened allowance (¥50 by default), or nothing. Other agent-payment guards limit what their own agent may do. Meigi is a public payee registry that every agent, wallet and exchange can check: a company's government-issued number, bound to one wallet that nobody, including us, can change in under 72 hours. Japan comes first, but any official business ID works the same way, and the verifier already checks LEIs against GLEIF. Proving that the registrant represents the company, through its 商業登記電子証明書 (commercial-registration e-certificate), is the production step.
How it's made
Contracts (Solidity 0.8.28, Foundry, OpenZeppelin 5.4), all five Sourcify exact matches on Sepolia: - PayeeRegistry: one payout per T-number. A payout changes only through a 72-hour public window (set at deploy; the contract enforces at least 1 hour): the business key with its World ID officers (verifier-checked, attester co-signed as one EIP-712 approval, verified on-chain by OfficerQuorum), or a governance ruling on a dispute, which only governance can dismiss. Disputes freeze a number, and attesters can be revoked. - PayeeResolver: an ENSIP-10 wildcard resolver on payee.eth that answers from the registry at call time. - AgentVault: owner-approved vendors, per-vendor caps, a pinned payout that must still match the registry, invoice de-duplication. - PayRouter (pay by T-number from any wallet) and a mock JPYC with EIP-3009. 164 Foundry tests (156 run without an RPC; the 8 fork tests need one), including a fuzz test that a change never lands early. Three review rounds by separate AI reviewers covered the core contracts, with proof-of-concept exploits: 16 findings, 14 fixed, 2 documented as by design, every fix mutation-tested. CompanyNamespace and MandateGate, added later, passed reviews of their own; the ENS claim resolver has tests only, and none of this is a professional audit. Verifier (TypeScript, Hono, node:sqlite): an index of the NTA's public bulk data (5,787,472 corporate-number records), matched exactly after NFKC normalisation; a Keybase-style DNS TXT proof; World ID 4.0 through IDKit sessions. An officer enrolls once, and every later approval must come from the same session, with a signal that pins chain, registry, T-number, action, target, nonce and deadline. World ID 4.0's on-chain verifier isn't deployed on Sepolia, so the verifier checks each proof server-side with the Developer Portal's v4 verify API, then signs an EIP-712 approval that the registry checks on-chain. That one signature is the officer quorum on-chain, so the registry trusts the verifier to have checked each proof. ENSv2 (Sepolia Beta): payee.eth names companies, meigi.eth names agents. A company can claim its name as a token in a UserRegistry subregistry. Enhanced Access Control lets it set only text records on its profile, and ClaimedPayeeResolver forwards the money records from the registry, so a claim never changes an address. ap.meigi.eth carries ENSIP-26 records, is linked to ERC-8004 agent 10525 per ENSIP-25, is the AgentVault's ENSIP-19 primary name, and its key can write only agent-status. CompanyNamespace lets a claimed company open its own ENSv2 UserRegistry and issue soulbound, expiring, text-only names, each with its own PermissionedResolver. MandateGate, the AgentVault's agent, passes payInvoice on only while the buyer's ap.t4999900000005.payee.eth answers and the caller holds it. AP agent (TypeScript): deterministic extraction of Japanese invoices (T-number, 振込先, 税込 total, hidden text) → System-1 triage by our fine-tuned model → a deterministic kernel, the only part that decides → Intercepta screening → pay or hold. A local LLM on Ollama (Gemma 4 E4B in our demo) proposes, deliberately gullibly, and explains; it never decides. The agent holds no key and refuses to start if one is in its environment. A separate loopback signer holds the agent's key and signs only payInvoice (through the MandateGate, now the vault's agent), built from typed fields and simulated first. Held invoices go to a human through World ID for Agents (an OAuth device grant). The agent verifies the ID token and requires the enrolled approver; the separate signer enforces the ¥150,000 ceiling and independently verifies the token too (on in our demo stack). A hash-chained audit log records every verdict, approval and payment (GET /audit?verify=1). Fine-tuned triage model: payee-0.8b, a LoRA fine-tune of Kev-0.8B on PayeeBench-JA, our Japanese-first benchmark for payment-redirection triage, in which every identifier is provably fictional. Trained in 39 minutes on an M5 Max MacBook (PyTorch MPS), served with MLX. On our own synthetic benchmark it reaches 0.918 mean accuracy on the held-out test templates, at 39 ms p50 on the laptop; Llama 3.3 70B has lower mean accuracy (0.815) but ranks safe versus held items at least as well, so the model only routes and the registry match decides. At a 1% error budget it sends 45% of legitimate items straight to the kernel. One item that should have been held slipped through, and the kernel's exact registry match is the backstop for exactly that. x402 v2: a meigi-payee extension (T-number, plus the ENS name where the chain has ENS) in the 402 response; a client hook that holds a declared merchant to its registered payout, checking the registry and ENS independently, and aborts before signing on a mismatch; merchants that declare no payee get at most a small allowance (¥50 by default) after a clean Intercepta screen, or nothing; a self-hosted facilitator settling EIP-3009 mJPYC. Curvegrid MultiBaas and Mizuhiki: two MultiBaas deployments. One indexes the live demo's Sepolia contracts. The other indexes Meigi on Mizuhiki's Awaji testnet (chain 6497), where the registry and PayRouter are deployed, a registered vendor was paid in Mizuhiki's MJPY and MUSD test tokens, and an x402 purchase settled in MJPY. Seven saved queries in the format of Curvegrid's Matsuri sample confirm settlements and feed the site's settlements panel. Hack: the free plan backfills only 100 blocks, so we load the ABIs and queries before deploying, link right after the broadcast, and merge MultiBaas rows with RPC logs for older history. Front end and hosting: React and React Three Fiber (one "Sakasa Fuji" scene shared by the landing and the app), on Cloudflare Workers. A Worker serves the settlements API with the MultiBaas key kept as a secret; another proxies Workers AI for the benchmark's Llama baseline. AI usage: Claude Code (Claude Opus 5.5) wrote the code and docs under our direction, as a lead session plus parallel sub-agents; OpenAI Codex made one revision to the landing's garden. We chose the idea, the prizes, the scope and the constraints, handled accounts, keys and funds, and tested the demos. Every project-building sub-agent's brief is committed verbatim in docs/ai/briefs (15 of the 43 did the team's private preparation or tooling, and are listed by name without their briefs), Karan's own calls and the messages behind them are in docs/ai/calls-we-made.md, AI-assisted commits carry a Co-Authored-By trailer (except 32 made between 13:50 and 16:14 JST on Sep 26), and AI_USAGE.md says who wrote what.