diff --git a/docs/apps/guides/verify-onchain.mdx b/docs/apps/guides/verify-onchain.mdx
index 431220e5d..4ed88e0d9 100644
--- a/docs/apps/guides/verify-onchain.mdx
+++ b/docs/apps/guides/verify-onchain.mdx
@@ -7,10 +7,11 @@ description: "Enforce Sybil resistance and policy gating inside any Base contrac
**Base Verify Onchain lets your smart contract enforce "one real person, once" and gate on real-world traits, like an active Coinbase One membership. The check runs in your contract, so you don't run a verification backend.** Base Verify signs a short-lived verification your contract checks in the same transaction as a claim, deposit, or vote.
-
- Live on Base Sepolia! Try the [demo](https://verify.base.dev/onchain-demo), or [reach
+
+ Base Verify Onchain runs on Base Sepolia only. It is not deployed on Base mainnet, so build and test against it, but
+ do not put production value behind it. Try the [demo](https://verify.base.dev/onchain-demo), or [reach
out](https://forms.gle/WTcuWyKkvUV6gGik6) if you have use cases in mind.
-
+
Integration is three steps:
@@ -22,7 +23,7 @@ Integration is three steps:
| :--------------- | :------------------------------------------------------------------------------------------------------------------------------ |
| `SignerRegistry` | [`0x4f15593fbF7e3491d15080e1610E7AF8deBA1a02`](https://sepolia.basescan.org/address/0x4f15593fbF7e3491d15080e1610E7AF8deBA1a02) |
| API base URL | `https://verify.base.dev/v1` |
-| Chain | Base Sepolia (`84532`) |
+| Chain | Base Sepolia (`84532`), testnet only |
| Consumer base | `BaseVerifyConsumer.sol` |
Two example consumers to copy from:
@@ -41,6 +42,8 @@ Two example consumers to copy from:
A single check can do both at once: gate on your policy _and_ dedupe on identity in the same transaction. If your app already enforces this offchain (your own backend and database), start with [Verify Social Accounts](/base-account/guides/verify-social-accounts) instead. This guide is for enforcing it in a contract.
+Neither the API response nor your contract carries the user's identity, but a claim is still a public transaction. See [What goes onchain](#what-goes-onchain) for exactly what it publishes.
+
## Core concepts
### Verification
@@ -79,6 +82,49 @@ A claim moves through your app, the Base Verify API, and your contract:
6. Your app submits the verification to your contract's `enroll` function (or your deposit, borrow, or claim path).
7. Your contract calls `registry.verifyVerification(...)`, which checks the signature and expiry and recomputes `policyHash` from your live policy. Your contract then dedupes on `identityHash` and lets the user participate.
+## What goes onchain
+
+A claim is an ordinary public transaction. Once it is mined, everything below is permanent, world-readable, and outside Base Verify's control. Weigh that when you design your policy and your contract.
+
+### Written onchain
+
+| Data | Where it appears | Notes |
+| :------------------------------------------ | :---------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------- |
+| `identityHash` | Transaction calldata, your contract's storage, and any event you emit with it | Permanently ties the claiming wallet to this identity inside your contract |
+| Claiming wallet address | The transaction sender, and any event you emit with it | The wallet that signed the SIWE message and submitted the claim |
+| `expiration` and the Base Verify `signature` | Transaction calldata | Public, but bound to your contract and that wallet, and it expires within minutes |
+| Your `provider` and `conditions` | Public view functions on your deployed contract | Anyone can read your policy without sending a transaction |
+
+Whatever your own contract stores or emits alongside a claim is public too. The two example consumers linked above keep a `mapping(bytes32 identityHash => bool)` and emit `Claimed(address indexed user, bytes32 indexed identityHash)`, which makes the wallet-to-hash pairing directly queryable from logs.
+
+### Never onchain
+
+- The provider account: no username, handle, account ID, or profile link.
+- Trait values: no follower count, subscription state, or other credential data.
+- OAuth tokens, or anything else Base Verify holds for the user.
+- `policyHash`: the registry recomputes it in memory during verification and never stores or emits it.
+- The user's real-world identity: `identityHash` is one-way and cannot be reversed.
+
+### What an observer can infer
+
+Your policy is public and your claims are public, so anyone can pair the two. The Coinbase One example consumer declares `provider = "coinbase"` and the condition `coinbase_one_active eq true`, so every wallet in its `Claimed` log is publicly known to have held an active Coinbase One membership at claim time. An observer cannot tell which Coinbase account, but does learn that the wallet had one.
+
+A narrower policy leaks more. Gating on `followers gte 10000` marks each claiming wallet as a large X account, while gating on `verified eq true` says much less. Your contract name and any action naming leak the same way.
+
+Because `identityHash` is scoped per contract, the same person claiming in two different contracts produces two unrelated hashes that observers cannot link. Within a single contract, every claim from that person shares one hash, which is exactly what makes the dedupe work.
+
+### Where claim history lives
+
+`verify.base.dev` surfaces a user's offchain credentials only: which providers they have verified, and the traits Base Verify stores for them. It has no view of onchain claims and cannot display, edit, or undo them.
+
+Onchain claim history lives in your contract: your storage, your events, your chain. Users and observers read it through a block explorer or your contract's public getters. If you want your users to see their own claim history, you build that view.
+
+
+ Deleting a verification at `verify.base.dev` removes the user's offchain credential and stops Base Verify from
+ signing new verifications for them. It does not reach anything already written onchain. Claims your contract has
+ already recorded stay recorded, and the transactions stay in the chain's history.
+
+
## Implementation
@@ -238,7 +284,7 @@ Exchanges a SIWE signature for a signed, short-lived onchain verification. No AP
```
- The SIWE message. Its `statement` must be exactly `Claim eligibility for a Base Verify onchain benefit.`, its `chainId` must be the chain you are claiming on (Base Sepolia `84532` during the test phase), and its `Resources` must include `eip155::`.
+ The SIWE message. Its `statement` must be exactly `Claim eligibility for a Base Verify onchain benefit.`, its `chainId` must be the chain you are claiming on (Base Sepolia `84532`, the only supported chain), and its `Resources` must include `eip155::`.
@@ -370,6 +416,7 @@ When you declare multiple conditions for a provider, **all** must be satisfied (
- Keep your policy (`provider` and `conditions`) immutable.
- Dedupe on `identityHash` in your claim path.
- Treat a successful check as proof of a unique verified identity, not of any specific account or personal data.
+- Tell your users what a claim publishes, and remember that you own any user-facing view of it. See [What goes onchain](#what-goes-onchain).
## Support
diff --git a/docs/base-account/guides/verify-social-accounts.mdx b/docs/base-account/guides/verify-social-accounts.mdx
index 3c6f9cced..bb44cfb81 100644
--- a/docs/base-account/guides/verify-social-accounts.mdx
+++ b/docs/base-account/guides/verify-social-accounts.mdx
@@ -873,6 +873,10 @@ Users can delete their verifications at any time:
- Invalidates future token generation
- Your app's stored tokens become meaningless (user can't re-verify with the same account)
+
+Deletion covers the offchain credential that Base Verify holds. It cannot reach data an app has already written elsewhere, including anything a contract recorded through [Base Verify Onchain](/apps/guides/verify-onchain). `verify.base.dev` shows offchain credentials only, so onchain claim history is not visible or reversible there.
+
+
### Caching
Cache verification results to reduce API calls: