Skip to content

Add ecash payment, Cashu wallet, and admin UI#3

Merged
nisfeb merged 1 commit into
masterfrom
feature/ecash
Mar 13, 2026
Merged

Add ecash payment, Cashu wallet, and admin UI#3
nisfeb merged 1 commit into
masterfrom
feature/ecash

Conversation

@nisfeb
Copy link
Copy Markdown
Contributor

@nisfeb nisfeb commented Mar 13, 2026

Summary

  • Ecash payment support: maintainers can require sats-per-PR, committers load wallets via Lightning from a Cashu mint, tokens are automatically selected and included in commit signatures
  • NUT-03 swap verification: the maintainer's ship swaps incoming tokens at the mint during verify-commit to confirm their value before passing CI — no blind trust
  • Sail admin UI: server-rendered panel at /vitriol/admin split into committer (wallet, mint config, load sats) and maintainer (payment toggle, price, ban list, ecash pubkey) sections, plus a landing page at /vitriol

What changed

Agent (desk/app/vitriol.hoon)

  • State-6 with wallet, mint URL, keyset cache, sats-per-pr price, pending mints, pending verifications
  • Curve25519 encryption keypair generation for future DH ecash exchange
  • Committer wallet flow: configure mint → request Lightning invoice (NUT-04) → poll via Behn timers → mint tokens → store proofs
  • /sign accepts sats_required, selects proofs from wallet (≥ required, ≤ 110%), deducts from wallet
  • /verify-commit parses incoming ecash tokens, initiates NUT-03 swap at the mint, returns verify_id for async polling
  • /verify-status/{id} polling endpoint for CI to await swap completion
  • /sats-per-pr endpoint exposes maintainer's price
  • Tokens accepted even when payment not required
  • All endpoints behind Eyre auth (403 otherwise)

Cashu library (desk/lib/cashu.hoon)

  • Full BDHKE implementation (NUT-00) with secp256k1 via fo modular arithmetic
  • NUT-03 swap, NUT-04 mint via Lightning, NUT-05 melt
  • Hash-to-curve, point compression/decompression, keyset parsing, amount splitting

Admin UI (desk/lib/vitriol-ui.hoon)

  • Sail pages with dark theme
  • Committer section: wallet balance, mint URL, load sats form
  • Maintainer section: payment toggle, sats-per-PR price input, ecash pubkey display, ban list with add/remove
  • Landing page with endpoint reference

Types (desk/sur/vitriol.hoon)

  • cashu-proof, pending-mint-quote, pending-verify

Hook (hooks/groundwire-sign)

  • Fetches maintainer's sats-per-pr price
  • Passes sats_required to /sign
  • Includes ecash-amount and ecash-tokens in signature block
  • Handles error responses (insufficient balance, etc.)

Other

  • sys.kelvin: supports both 408 and 409
  • install.sh: updated docs for maintainer ecash flow
  • README.md: comprehensive rewrite

Token flow

committer                    maintainer                   cashu mint
    |                            |                            |
 load sats               set sats-per-pr                     |
 via Lightning           in admin panel                      |
    |                            |                            |
 git commit ──────> hook fetches price ──────────────────>   |
    |               from /sats-per-pr                        |
    |                            |                            |
 /sign selects      verify-commit receives                   |
 tokens from        tokens + mint URL                        |
 wallet (≤110%)          |                                   |
    |               NUT-03 swap ──────────────────────> validates
    |               (blind, send, unblind)              & signs
    |                            |                       new proofs
    |               swap succeeds ────────────────────>  |
    |               → tokens stored in wallet            |
    |               → CI returns verified                |

Test plan

  • Set mint URL in admin panel, load sats via Lightning invoice
  • Verify wallet balance updates after payment
  • Set sats-per-pr price in maintainer admin
  • Sign a commit with sats_required — tokens selected and deducted
  • Verify token selection respects 110% cap
  • Submit tokens via verify-commit — NUT-03 swap succeeds
  • Poll verify-status until verified
  • Test with payment not required but tokens included (should accept)
  • Test insufficient balance error
  • Verify all endpoints return 403 without auth cookie
  • Confirm ban list blocks verification even with valid signature
  • Test state migration from state-4/5 to state-6

🤖 Generated with Claude Code

@github-actions
Copy link
Copy Markdown

Groundwire Verification Failed

This PR will not be reviewed because commits are not signed by a recognized Groundwire ID.

UNSIGNED 0b8e7ab3

Why?

This repository requires contributors to prove ownership of an onchain Groundwire identity.
Commit signatures are cryptographically verified against the signer's on-chain networking key.

How to fix this

  1. Get a Groundwire IDgroundwire.network/get-started
  2. Install commit signing./hooks/install.sh <your-ship-url>
  3. Re-sign your commitsgit rebase --exec "true" HEAD~N (after configuring signing)

This repository is protected by Groundwire for GitHub.

Adds optional ecash token payment support to vitriol. Maintainers can
require sats-per-PR and committers load their wallet via Lightning.
Tokens are NUT-03 swapped at the mint during verification to confirm
value before the CI check passes.

Agent (desk/app/vitriol.hoon):
- State-6: adds mint URL, wallet (map of mint→proofs), keyset cache,
  sats-per-pr price, pending mints, and pending verifications
- Curve25519 encryption keypair for future DH ecash exchange
- Committer wallet: configure mint, request Lightning invoice (NUT-04),
  poll for payment via Behn timers, mint tokens, store proofs
- Sign endpoint: accepts sats_required, selects proofs from wallet
  (>= required, <= 110% to avoid overpaying), deducts from wallet
- Verify endpoint: parses incoming ecash tokens, initiates NUT-03 swap
  at the mint to verify value, returns verify_id for async polling
- Verify-status polling endpoint for CI to await swap completion
- Ban list with set/unban via admin forms and JSON API
- Maintainer can set sats-per-pr price via admin UI
- All endpoints require Eyre authentication (403 otherwise)
- Tokens accepted even when payment not required (free money)

Cashu library (desk/lib/cashu.hoon):
- Full BDHKE implementation (NUT-00) with secp256k1 curve operations
- NUT-03 swap (blind, unblind, request/response builders)
- NUT-04 mint via Lightning (quote, poll, token generation)
- NUT-05 melt to Lightning (quote, execute)
- Hash-to-curve, point compression/decompression, keyset parsing

Admin UI (desk/lib/vitriol-ui.hoon):
- Sail admin panel split into Committer and Maintainer sections
- Committer: wallet balance, mint URL config, load sats via Lightning
- Maintainer: payment toggle, sats-per-PR price, ecash pubkey, ban list
- Landing page at /vitriol with app description and endpoint reference
- Dark theme with consistent styling

Types (desk/sur/vitriol.hoon):
- cashu-proof: amount, keyset id, secret, signature
- pending-mint-quote: tracks Lightning invoice→token flow
- pending-verify: tracks NUT-03 swap verification of incoming tokens

Hook (hooks/groundwire-sign):
- Fetches maintainer's sats-per-pr price from /vitriol/sats-per-pr
- Passes sats_required to committer's /sign endpoint
- Includes ecash-amount and ecash-tokens in signature block
- Error handling for insufficient balance

Other:
- sys.kelvin: support both kelvin 408 and 409
- install.sh: updated docs for ecash/maintainer flow
- README.md: comprehensive rewrite covering ecash architecture,
  contributor/maintainer setup, token verification, and security

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@nisfeb nisfeb merged commit 34f2e9f into master Mar 13, 2026
1 check passed
@nisfeb nisfeb deleted the feature/ecash branch March 13, 2026 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant