Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Environment Variables

Portal reads ~/.portal-rest/config.toml and overrides any value with environment variables using the format PORTAL__<SECTION>__<KEY> (double underscore separator).

Config and env

  • Config file: ~/.portal-rest/config.toml. Full example: crates/portal-rest/example.config.toml.
  • Override: PORTAL__<SECTION>__<KEY>=value. Example: PORTAL__AUTH__AUTH_TOKEN=secret.
  • Data: wallet data (when ln_backend=breez) is stored under ~/.portal-rest/breez.

All settings

Core

Config keyEnv varRequiredDefaultDescription
info.listen_portPORTAL__INFO__LISTEN_PORTNo3000HTTP port.
auth.auth_tokenPORTAL__AUTH__AUTH_TOKENYesBearer token for API access.
nostr.private_keyPORTAL__NOSTR__PRIVATE_KEYYesNostr private key (64 hex chars).
nostr.relaysPORTAL__NOSTR__RELAYSNowss://relay.nostr.net, wss://relay.damus.io, wss://relay.getportal.ccComma-separated relay URLs.
nostr.subkey_proofPORTAL__NOSTR__SUBKEY_PROOFNoSubkey delegation proof.

Database

Config keyEnv varRequiredDefaultDescription
database.pathPORTAL__DATABASE__PATHNoportal-rest.dbSQLite file path. Relative paths resolve under ~/.portal-rest/.

Wallet

Config keyEnv varRequiredDefaultDescription
wallet.ln_backendPORTAL__WALLET__LN_BACKENDNononenone, nwc, or breez.
wallet.nwc.urlPORTAL__WALLET__NWC__URLIf ln_backend=nwcNWC connection URL.
wallet.breez.api_keyPORTAL__WALLET__BREEZ__API_KEYIf ln_backend=breezBreez API key.
wallet.breez.mnemonicPORTAL__WALLET__BREEZ__MNEMONICIf ln_backend=breezBreez wallet mnemonic.

Webhooks

Webhooks are an alternative to polling — the daemon will POST events to your endpoint as they arrive.

Config keyEnv varRequiredDefaultDescription
webhook.urlPORTAL__WEBHOOK__URLNoURL to receive webhook events.
webhook.secretPORTAL__WEBHOOK__SECRETNoShared secret for HMAC-SHA256 signatures (X-Portal-Signature header).

When webhook.secret is set, each request includes an X-Portal-Signature header with the HMAC-SHA256 signature of the body. Verify it to authenticate incoming webhooks:

import hmac, hashlib

def verify(secret: str, body: bytes, signature: str) -> bool:
    expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

Profile

Publish your service's Nostr profile at startup. All fields are optional — omit the section to skip.

Config keyEnv varRequiredDefaultDescription
profile.namePORTAL__PROFILE__NAMENoUsername (no spaces).
profile.display_namePORTAL__PROFILE__DISPLAY_NAMENoDisplay name.
profile.picturePORTAL__PROFILE__PICTURENoAvatar URL.
profile.nip05PORTAL__PROFILE__NIP05NoNIP-05 verified identifier.

Minimal setup

PORTAL__AUTH__AUTH_TOKEN=dev-token \
PORTAL__NOSTR__PRIVATE_KEY=your-64-char-hex-key \
portal-rest

Generate a token: openssl rand -hex 32
Convert nsec to hex: nak decode nsec1...

With Docker

docker run -d -p 3000:3000 \
  -e PORTAL__AUTH__AUTH_TOKEN=my-secret-token \
  -e PORTAL__NOSTR__PRIVATE_KEY=your-nostr-private-key-hex \
  getportal/sdk-daemon:0.4.0

Or use a .env file: docker run --env-file .env .... Don't commit .env.

Troubleshooting

ProblemFix
401 UnauthorizedToken must match PORTAL__AUTH__AUTH_TOKEN.
Invalid Nostr keyMust be 64 hex chars. Convert nsec: nak decode nsec1....
Relays not connectingUse wss:// URLs; e.g. wss://relay.damus.io.
DB path errorUse an absolute path or ensure ~/.portal-rest/ exists.