Repository navigation
Chat: require holding 10 XCP to post - #59
Merged
Merged
Conversation
Signing in is free, so a ban or the per-author cooldown only bound an identity that cost nothing to replace. Posting now requires the wallet to hold at least 10 XCP: its confirmed balance plus XCP it has paid into launches that are still minting, which is escrowed rather than spent. The web route checks before publishing and reports an unreadable balance as unavailable, never as a pass or a refusal. Verdicts are cached per isolate: ten minutes for a holder, one minute for a wallet under the bar. Configured chat admins are exempt. The chat identity read tells the composer whether the wallet qualifies, so a wallet under the bar sees "Must hold 10 XCP to chat." instead of a message box; reopening chat re-checks after a top-up. Logged-out visitors still see "Connect a wallet to chat." Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LkjKD3QZivr3Qr2cKdjfbz
A post refused for the minimum now marks the shared identity instead of a composer-local flag, so reopening chat re-checks and a top-up clears it in one place. holdsMinimum is a required field, documented as display only: the server checks every post. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LkjKD3QZivr3Qr2cKdjfbz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Signing in is free, so bans and the per-author cooldown only bound identities that cost nothing to replace. Someone in chat was demonstrating exactly that ("rotating identity" to evade bans and rate limits). Posting now requires the wallet to hold at least 10 XCP. Nothing is spent.
What counts
Confirmed XCP balance plus XCP the wallet has paid into launches that are still minting (escrowed, not gone). XCP in open DEX orders does not count. Addresses in
CHAT_ADMIN_ADDRESSESare exempt.Enforcement (server-side only)
apps/web/src/lib/chat-eligibility.ts(new):holdsChatMinimum(address). Verdicts are cached per isolate: 10 minutes for a holder (so the same 10 XCP moved between wallets unlocks them slowly) and 1 minute for a wallet under the bar (so a top-up is picked up soon after it confirms).POST /api/chatchecks before publishing, using the address from the signed session cookie. Under the minimum returns403 insufficient_xcp. An unreadable balance falls through as503 unavailable: never a pass, never a false refusal.GET /api/chataddsholdsMinimum(true/false/null) for display only.fetchAssetBalanceOrThrow(Counterparty) andfetchMintingXcpPaid(our index,/v2/mints/by/:source, paged to exhaustion) both throw on failure rather than reading as zero.UX
*.status.json), with a translator note that it means holding, not paying.Testing
tests/chat-eligibility.test.ts: 10 XCP inclusive, escrow counted, cache TTLs, failures throw and aren't cached.tests/chat-route.test.ts: refusal before the room, unreadable balance → 503, admin exempt, GETholdsMinimum.tests/chat-panel.test.tsx: message shown and Send blocked; refusal on send keeps the draft; reopen after top-up re-enables posting.[](200), so it reads as 0 rather than as an error.Deploy
Web only (
npm run deploy:web). No API, schema or config changes.🤖 Generated with Claude Code
https://claude.ai/code/session_01LkjKD3QZivr3Qr2cKdjfbz
Generated by Claude Code