From fba3e6ff030fb1236e11b1b0c1a145e3fa752e71 Mon Sep 17 00:00:00 2001 From: 2ro <17595647+2ro@users.noreply.github.com> Date: Sun, 5 Jul 2026 01:02:30 -0400 Subject: [PATCH] deploy: wizard-first install, drop GP_MNEMONIC from the unit, plugin zip + port fix - gp-server.service: drop the GP_MNEMONIC credential from the default unit (the seed lives only encrypted at rest + the operator's written backup); keep GP_WALLET_PASSWORD_FILE via LoadCredential. A commented first-boot-only bootstrap remains for the no-wizard path. - install.sh: end by offering to run `gp-server setup` (no longer pre-writes the env file, which would block the wizard's re-run guard). - package-woocommerce.sh: build goblinpay-woocommerce.zip (single top-level folder) as a release artifact. - WooCommerce plugin: fix the default server URL port (8192 -> 8080) to match the server's default bind; same fix in the connector README/INSTALL. --- connectors/woocommerce/INSTALL.md | 2 +- connectors/woocommerce/README.md | 2 +- .../woocommerce/goblinpay-woocommerce.php | 4 +- deploy/gp-server.service | 38 +++++++---- deploy/install.sh | 66 ++++++++++++------- deploy/package-woocommerce.sh | 45 +++++++++++++ 6 files changed, 114 insertions(+), 43 deletions(-) create mode 100755 deploy/package-woocommerce.sh diff --git a/connectors/woocommerce/INSTALL.md b/connectors/woocommerce/INSTALL.md index d5966d4..6409a53 100644 --- a/connectors/woocommerce/INSTALL.md +++ b/connectors/woocommerce/INSTALL.md @@ -29,7 +29,7 @@ Plugins screen. Open WooCommerce, then Settings, then Payments, then GoblinPay (Grin), and set: - GoblinPay URL: the base URL of your GoblinPay server, for example - `http://127.0.0.1:8192` when GoblinPay runs on the same host. No trailing + `http://127.0.0.1:8080` when GoblinPay runs on the same host. No trailing slash. - API Token: the GoblinPay create-invoice bearer token (`GP_API_TOKEN`). - Webhook Secret: the shared HMAC secret (`GP_WEBHOOK_SECRET`). diff --git a/connectors/woocommerce/README.md b/connectors/woocommerce/README.md index b2c959f..d6f6c84 100644 --- a/connectors/woocommerce/README.md +++ b/connectors/woocommerce/README.md @@ -33,7 +33,7 @@ node exposed to the store, no wallet RPC. Open WooCommerce, then Settings, then Payments, then GoblinPay (Grin). - GoblinPay URL: base URL of your GoblinPay server, for example - `http://127.0.0.1:8192`. No trailing slash. + `http://127.0.0.1:8080`. No trailing slash. - API Token: the GoblinPay create-invoice bearer token (`GP_API_TOKEN` on the server). - Webhook Secret: the shared HMAC secret (`GP_WEBHOOK_SECRET` on the server). diff --git a/connectors/woocommerce/goblinpay-woocommerce.php b/connectors/woocommerce/goblinpay-woocommerce.php index 40b98a8..8de9eac 100644 --- a/connectors/woocommerce/goblinpay-woocommerce.php +++ b/connectors/woocommerce/goblinpay-woocommerce.php @@ -132,8 +132,8 @@ add_action('plugins_loaded', function () { 'gp_url' => array( 'title' => __('GoblinPay URL', 'goblinpay-woocommerce'), 'type' => 'text', - 'default' => 'http://127.0.0.1:8192', - 'placeholder' => 'http://127.0.0.1:8192', + 'default' => 'http://127.0.0.1:8080', + 'placeholder' => 'http://127.0.0.1:8080', 'desc_tip' => true, 'description' => __('Base URL of your GoblinPay server (no trailing slash).', 'goblinpay-woocommerce'), ), diff --git a/deploy/gp-server.service b/deploy/gp-server.service index 08e8697..be1149b 100644 --- a/deploy/gp-server.service +++ b/deploy/gp-server.service @@ -1,17 +1,23 @@ # Hardened systemd unit for the GoblinPay server on bare metal. # -# Install (or just run deploy/install.sh): -# sudo install -m0755 target/release/gp-server /usr/local/bin/ -# sudo install -m0640 deploy/.env.example /etc/goblinpay.env # then EDIT it +# The recommended path is the setup wizard, which writes everything this unit +# reads (the env file and the 0400 wallet-password credential) and creates the +# encrypted wallet for you: # sudo install -m0644 deploy/gp-server.service /etc/systemd/system/ -# sudo mkdir -p /etc/goblinpay/secrets # 0400 secret files +# sudo gp-server setup # writes /etc/goblinpay.env + the secret file # sudo systemctl daemon-reload && sudo systemctl enable --now gp-server # -# Unlike goblin-nip05d, this service holds MONEY secrets (the Grin seed and the -# wallet password) and a wallet data directory. The seed and password are passed -# as systemd credentials (read by PID1 as root, exposed read-only to the dynamic -# service user) rather than left world-readable, and the config supports the -# `*_FILE` mounted-secret variants for exactly this. +# Unlike goblin-nip05d, this service holds a MONEY secret (the wallet password, +# which decrypts the Grin seed at rest) and a wallet data directory. The +# password is passed as a systemd credential (read by PID1 as root, exposed +# read-only to the dynamic service user) rather than left world-readable. +# +# The Grin SEED is deliberately NOT a service credential: the wizard consumes it +# once at setup to create the encrypted wallet, after which the wallet opens +# with the password alone (init-once). The seed then lives only encrypted at +# rest in the data dir and in the operator's written backup, never in this +# service's environment. (To bootstrap a wallet WITHOUT the wizard, set +# GP_MNEMONIC_FILE for the first boot only, then remove it.) [Unit] Description=GoblinPay — self-hostable, receive-only Grin payment server @@ -28,13 +34,17 @@ DynamicUser=yes # as root, so a 0640 root:root file is fine even under DynamicUser. EnvironmentFile=/etc/goblinpay.env -# Money/identity secrets as credentials: the source files stay root-owned 0400; -# systemd exposes copies under $CREDENTIALS_DIRECTORY (%d), readable by the -# dynamic service user. Point the wallet at them via the *_FILE variants. -LoadCredential=gp_mnemonic:/etc/goblinpay/secrets/mnemonic +# The wallet password as a credential: the source file stays root-owned 0400 +# (the wizard writes it there); systemd exposes a copy under +# $CREDENTIALS_DIRECTORY (%d), readable by the dynamic service user. The wallet +# is pointed at it via the *_FILE variant. This overrides any GP_WALLET_PASSWORD_FILE +# in the env file above, so the service always reads the credential copy. LoadCredential=gp_wallet_password:/etc/goblinpay/secrets/wallet_password -Environment=GP_MNEMONIC_FILE=%d/gp_mnemonic Environment=GP_WALLET_PASSWORD_FILE=%d/gp_wallet_password +# First-boot-only seed bootstrap WITHOUT the wizard (remove after the wallet +# exists). The wizard makes this unnecessary. +#LoadCredential=gp_mnemonic:/etc/goblinpay/secrets/mnemonic +#Environment=GP_MNEMONIC_FILE=%d/gp_mnemonic # Optional: a NIP-49 encrypted Nostr identity (else a random one is generated # and persisted under the data dir on first start). Uncomment with its file: #LoadCredential=gp_ncryptsec:/etc/goblinpay/secrets/ncryptsec diff --git a/deploy/install.sh b/deploy/install.sh index 78c1c0e..805f6b6 100755 --- a/deploy/install.sh +++ b/deploy/install.sh @@ -3,20 +3,18 @@ # - builds the release binary (gp-server only; never the goblin-tree dev crate) # - installs it to /usr/local/bin # - creates the managed state dir and the 0700 secrets dir -# - installs an env file from deploy/.env.example (if absent) # - installs and enables the hardened systemd unit +# - offers to run the setup wizard (`gp-server setup`), which writes the env +# file + the wallet-password credential and creates the encrypted wallet # -# Re-runnable: it never overwrites an existing /etc/goblinpay.env. +# Re-runnable: it installs the binary/unit idempotently and never overwrites an +# existing /etc/goblinpay.env (the wizard has its own --reconfigure guard). # Requires: a Rust toolchain (cargo) and root (sudo) for the install steps. # # BUILD PREREQUISITE: gp-server's Nostr path depends on the sibling crate # nip44/ (see crates/gp-nostr/Cargo.toml). It must sit next to this # repo, exactly as on the deploy host. `-p gp-server` deliberately excludes the # gp-goblin-sender dev crate, which needs the (absent) goblin wallet tree. -# -# After it finishes, edit /etc/goblinpay.env and drop the secret files into -# /etc/goblinpay/secrets (mnemonic, wallet_password), then: -# sudo systemctl restart gp-server set -euo pipefail @@ -47,13 +45,6 @@ $SUDO install -d -m0700 "$STATE_DIR" say "Creating secrets directory $SECRETS_DIR (0700)" $SUDO install -d -m0700 "$SECRETS_DIR" -if [[ -f "$ENV_FILE" ]]; then - say "Env file $ENV_FILE already exists — leaving it untouched" -else - say "Installing env file to $ENV_FILE (EDIT IT: domain, node, tokens)" - $SUDO install -m0640 "$REPO_DIR/deploy/.env.example" "$ENV_FILE" -fi - say "Installing systemd unit to $UNIT" $SUDO install -m0644 "$REPO_DIR/deploy/gp-server.service" "$UNIT" @@ -61,17 +52,42 @@ say "Reloading systemd and enabling the service" $SUDO systemctl daemon-reload $SUDO systemctl enable gp-server -cat <\033[0m Run the setup wizard now? [Y/n] ')" reply || reply="" + case "${reply:-y}" in + [Nn]*) run_setup=no ;; + *) run_setup=yes ;; + esac +fi + +if [[ "$run_setup" == yes ]]; then + $SUDO gp-server setup + echo + echo "When you are ready: $SUDO systemctl start gp-server" +else + cat < a single top-level goblinpay-woocommerce/ +# +# The shop owner's WooCommerce step is then just Upload Plugin -> Activate -> +# paste the three values the setup wizard printed. No self-zipping, no code +# change to the plugin. +# +# Usage: deploy/package-woocommerce.sh [OUT_DIR] +# OUT_DIR defaults to ./dist. The zip is written to OUT_DIR/goblinpay-woocommerce.zip. +# +# Run it from a release workflow or by hand; it needs only `zip`. + +set -euo pipefail + +REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +SRC="$REPO_DIR/connectors/woocommerce" +SLUG="goblinpay-woocommerce" +OUT_DIR="${1:-$REPO_DIR/dist}" +ZIP="$OUT_DIR/$SLUG.zip" + +if ! command -v zip >/dev/null 2>&1; then + echo "error: 'zip' is required but not installed" >&2 + exit 1 +fi +if [[ ! -f "$SRC/$SLUG.php" ]]; then + echo "error: plugin entrypoint $SRC/$SLUG.php not found" >&2 + exit 1 +fi + +STAGE="$(mktemp -d)" +trap 'rm -rf "$STAGE"' EXIT + +# Stage the plugin under its slug folder so the zip has one top-level dir (what +# WordPress expects). Ship the plugin code + its install/readme docs; exclude +# nothing else lives here. +mkdir -p "$STAGE/$SLUG" +cp -a "$SRC/." "$STAGE/$SLUG/" + +mkdir -p "$OUT_DIR" +rm -f "$ZIP" +( cd "$STAGE" && zip -r -q -X "$ZIP" "$SLUG" ) + +echo "Wrote $ZIP" +unzip -l "$ZIP" 2>/dev/null | sed 's/^/ /' || true