The GoblinPay processor
Summary. nostr-rs-relay already has a pay-to-relay framework with a
PaymentProcessortrait andaccountandinvoicetables, built for Lightning. floonet-rs adds a GoblinPay implementation of the same trait, so relays can be paid in GRIN instead.
What upstream provides
Upstream’s pay_to_relay model (nostr-rs-relay/src/payment/mod.rs) defines a PaymentProcessor trait with LNBits and CLN implementations, plus account and invoice tables tracking who has paid. floonet-rs keeps that skeleton and swaps the money.
What the GoblinPay processor does
The src/payment/goblinpay.rs implementation covers the trait’s lifecycle against a GoblinPay server:
- Create invoice. Ask GoblinPay for an invoice for the configured amount (
FLOONET_NAME_PRICE_GRINfor names, or the write-access price). GoblinPay returns the payment details the client needs, including the pay-page URL. - Confirm. Poll GoblinPay’s REST API for payment status. Confirmation is on-chain, with a Grin payment proof, so a confirmed invoice means real money moved. An invoice moves
open->paid(the payment landed) ->confirmed(its kernel reached GoblinPay’s house standard ofGP_CONFIRMATIONSon-chain confirmations, default 10); the paid gate and name registration only act onconfirmed. The status API exposes bothconfirmationsandconfirmations_required. - Record. Mark the invoice paid; the admission module’s paid gate and the name authority’s registration path both read that record. Lookups are cached with a TTL.
Enforcement points
- Paid writes (
FLOONET_PAY_MODE=write): the admission chain rejects events from pubkeys without a confirmed payment. - Paid names (
FLOONET_PAY_MODE=name):POST /api/v1/registeris refused until the quoted invoice confirms. Names get a dedicatedname_claimstable rather than overloadingaccount, while reusing the upstreaminvoicetable for the money side.
Payment UX
How a user pays a GoblinPay invoice is up to the operator’s GoblinPay configuration; the relay does not care which path they take, it only ever asks GoblinPay “is this invoice confirmed”.
- Goblin Wallet (Nostr). The default: the user scans the pay page’s checkout code and the payment auto-receives over Nostr.
- Optional grin1 / Tor rail. If the operator turns on GoblinPay’s grin1 rail (
GP_GRIN1_RAIL, off by default), the pay page also offers a Grin rail so a user can pay from any Grin wallet over Tor, not just Goblin Wallet. Goblin stays the default tab. - Manual paste-back. On either rail, a wallet that cannot deliver its slatepack automatically can paste it into the pay page and GoblinPay finishes the exchange server-side.
Config
[goblinpay]
pay_mode = "name" # or "write"
url = "https://pay.example.com"
Plus FLOONET_GOBLINPAY_TOKEN in the environment. Setting a paid pay_mode wires upstream’s [pay_to_relay] to the GoblinPay processor automatically. Full table in the config keys reference, full walkthrough in Configuration.