docs: bundled relay, GP_NYM production posture, connectors + deploy in README
ci / fmt / clippy / test (push) Waiting to run

Document bundled mode and GP_BUNDLED_RELAY_URL, state GP_NYM=off as a supported server-side-clearnet posture (the payer's wallet still provides privacy) rather than debugging-only, and add Connectors (WooCommerce/Medusa/REST) and Deploy sections. The README ends with the AI pair-programming credit line.
This commit is contained in:
2ro
2026-07-03 03:22:53 -04:00
parent 3fdf4a230c
commit 3d36117d7b
+55 -7
View File
@@ -41,10 +41,15 @@ carries the full merchant surface:
HTTP webhook (the WooCommerce contract), an authenticated admin dashboard + HTTP webhook (the WooCommerce contract), an authenticated admin dashboard +
JSON API, and NIP-17 DMs to the merchant / payer. JSON API, and NIP-17 DMs to the merchant / payer.
All relay traffic rides an in-process Nym mixnet tunnel (smolmix, auto-selected By default all relay traffic rides an in-process Nym mixnet tunnel (smolmix,
exit, mix-dns; `GP_NYM=off` is a debugging escape hatch only). Encryption auto-selected exit, mix-dns). `GP_NYM=off` is also a supported production
negotiates NIP-44 v3 (the NIP-17 extension, via the companion `nip44` crate) per posture, not just a debugging switch: the server then reaches relays over
recipient, with v2 as the mandatory baseline. clearnet, but the payer's Goblin Wallet still provides sender privacy over its
own mixnet and the payload stays gift-wrapped end to end. An operator who fronts
GoblinPay with their own network privacy, or who accepts server-side clearnet for
a receive-only till, can run it that way. Encryption negotiates NIP-44 v3 (the
NIP-17 extension, via the companion `nip44` crate) per recipient, with v2 as the
mandatory baseline.
## Workspace ## Workspace
@@ -73,9 +78,10 @@ Everything is environment variables, defaults are safe for local use.
| `GP_DATA_DIR` | `./gp-data` | Data directory (wallet files, encrypted seed) | | `GP_DATA_DIR` | `./gp-data` | Data directory (wallet files, encrypted seed) |
| `GP_NODE_URL` | `https://main.gri.mw` | External Grin node (read only) | | `GP_NODE_URL` | `https://main.gri.mw` | External Grin node (read only) |
| `GP_CHAIN` | `mainnet` | Grin network: `mainnet` or `testnet` | | `GP_CHAIN` | `mainnet` | Grin network: `mainnet` or `testnet` |
| `GP_RELAY_MODE` | `bundled` | `bundled` or `external` | | `GP_RELAY_MODE` | `bundled` | `bundled` (GoblinPay runs its own co-located relay) or `external` |
| `GP_RELAYS` | unset | Comma-separated relay URLs | | `GP_BUNDLED_RELAY_URL` | `ws://127.0.0.1:7777` | In `bundled` mode, the self-contained relay GoblinPay dials AND advertises in the checkout `nprofile`; set to the relay's public `wss://` URL in production |
| `GP_NYM` | `on` | Route Nostr traffic over the Nym mixnet (`on` or `off`) | | `GP_RELAYS` | unset | Extra relay URLs (comma separated): redundancy in `bundled` mode, the whole set in `external` mode |
| `GP_NYM` | `on` | Route this server's Nostr traffic over the Nym mixnet (`on`, or `off` for supported server-side clearnet) |
| `GP_INGEST` | `on` | Nostr ingest service (`off` = HTTP surface only, for debugging) | | `GP_INGEST` | `on` | Nostr ingest service (`off` = HTTP surface only, for debugging) |
| `GP_CHECKOUT_METHODS` | `nostr,slatepack` | Which payment methods the hosted `/pay/<token>` page shows: comma list of `nostr` (Goblin Wallet) and `slatepack` (`grin1`). Unset = both. Unknown tokens are ignored; an empty result falls back to both | | `GP_CHECKOUT_METHODS` | `nostr,slatepack` | Which payment methods the hosted `/pay/<token>` page shows: comma list of `nostr` (Goblin Wallet) and `slatepack` (`grin1`). Unset = both. Unknown tokens are ignored; an empty result falls back to both |
| `GP_MATCH_MODE` | `memo` | Default matching mode: `memo`, `derived`, `amount` | | `GP_MATCH_MODE` | `memo` | Default matching mode: `memo`, `derived`, `amount` |
@@ -113,6 +119,27 @@ ingest, drop `nostr` from `GP_CHECKOUT_METHODS`; if you advertise `nostr`, keep
ingest on. The connector `POST /invoice` JSON response still returns the ingest on. The connector `POST /invoice` JSON response still returns the
`nprofile` regardless of this setting, which affects only the hosted page. `nprofile` regardless of this setting, which affects only the hosted page.
### Bundled relay
`GP_RELAY_MODE=bundled` (the default) means GoblinPay runs against its own
co-located Nostr relay, so a merchant needs no third-party relay. The relay is a
stock, unmodified `nostr-rs-relay` (a small, SQLite-backed Rust relay) vendored
as the `relay` service in `deploy/docker-compose.yml` with a config file at
`deploy/relay/nostr-rs-relay.toml` (config only, no fork). It was chosen over
writing a relay from scratch: it is battle-tested, lightweight enough for a
single-merchant till, and keeps the money path off any third-party
infrastructure.
`GP_BUNDLED_RELAY_URL` is the relay's URL. It is both dialed by the server and
advertised to payers in the checkout `nprofile`, so the payer's Goblin Wallet is
told to deliver the gift-wrapped slatepack straight to the merchant's own relay.
Set it to the relay's public `wss://` URL in production (the compose file and
`deploy/Caddyfile` serve it on `relay.<GP_DOMAIN>`); the default
`ws://127.0.0.1:7777` suits local and same-host development. Any `GP_RELAYS` are
appended for redundancy and advertised alongside the bundled relay.
`GP_RELAY_MODE=external` uses only the `GP_RELAYS` set and runs no bundled relay.
### Conversion rates (optional) ### Conversion rates (optional)
A store that prices in fiat (for example cryptodrip.com prices in USD) sends A store that prices in fiat (for example cryptodrip.com prices in USD) sends
@@ -202,6 +229,27 @@ curl http://127.0.0.1:8080/health
./ci.sh # cargo fmt --check, clippy -D warnings, tests ./ci.sh # cargo fmt --check, clippy -D warnings, tests
``` ```
## Connectors
Store integrations live under `connectors/` and all speak the same
create-invoice + signed-webhook contract:
- `connectors/woocommerce` — a WordPress/WooCommerce gateway (classic + Blocks).
- `connectors/medusa` — a Medusa v2 payment-module provider.
- The generic REST connector is built in: `POST /invoice` plus the webhook.
Refunds are unsupported/manual everywhere (GoblinPay is receive-only).
## Deploy
`deploy/` holds a reproducible deployment: a hardened systemd unit
(`gp-server.service`) with `deploy/install.sh` for bare metal, and a
`docker-compose.yml` that brings up the server, the bundled relay, and an
auto-HTTPS Caddy proxy. CI (`.github` / `.gitea` workflows) runs fmt, clippy,
and tests. See `deploy/` for details.
## Credits ## Credits
GoblinPay is developed with the help of Claude (Anthropic). GoblinPay is developed with the help of Claude (Anthropic).
Built with AI pair-programming assistance (Claude)