ThunderHub
Accounts

YAML accounts

Define ThunderHub accounts in a YAML file — schema, credential resolution, encryption, and env-var substitution.

YAML accounts are the original login mode. ThunderHub reads a config file at ACCOUNT_CONFIG_PATH on boot, builds a gRPC connection for each entry, and shows them on the login screen. Each account has its own password (or shares a master password).

Pointing ThunderHub at the file

Set the path via environment variable:

ACCOUNT_CONFIG_PATH='/path/to/thubConfig.yaml'

In Docker, mount the file in and point ACCOUNT_CONFIG_PATH at the in-container location:

docker run -d \
  -e ACCOUNT_CONFIG_PATH=/data/thubConfig.yaml \
  -v $(pwd)/thubConfig.yaml:/data/thubConfig.yaml:ro \
  ...

Minimal config

masterPassword: 'your-secure-password'
accounts:
  - name: 'My Node'
    serverUrl: '127.0.0.1:10009'
    macaroonPath: '/lnd/admin.macaroon'
    certificatePath: '/lnd/tls.cert'

Log in with your-secure-password and pick My Node from the list.

Schema

Top level

FieldTypeNotes
masterPasswordstringOptional. Used when an account has no password. Hashed in place on first boot.
defaultNetworkstringmainnet (default), testnet, testnet4, signet, or regtest. Used by lndDir shorthand.
accountsarrayOne or more account entries (see below).

Other top-level booleans (backupsEnabled, healthCheckPingEnabled, onchainPushEnabled, etc.) are documented in YAML schema reference.

Per-account fields

FieldTypeRequired?Description
namestringDisplay name on the login screen.
serverUrlstringhost:port of the gRPC endpoint. Use 10009 for LND/litd, 443 for Voltage.
typestringDefaults to lndlnd or litd. Set litd to expose Taproot Assets in the UI.
macaroonstringOne of these credential sources is needed for LND/litdHex-encoded macaroon (or AES-encrypted string if encrypted: true).
macaroonPathstringPath to a binary *.macaroon file. Hex on disk if encrypted: true.
lndDirstringPath to a full LND data dir. Resolves tls.cert and admin.macaroon automatically.
litDirstringPath to a litd data dir. Resolves tls.cert and lit.macaroon.
certificatestringOptionalInline PEM-encoded TLS cert.
certificatePathstringOptionalPath to a PEM TLS cert file.
networkstringOptionalOverride the top-level defaultNetwork for this account.
passwordstringOptionalPer-account password. If absent, ThunderHub uses masterPassword. Hashed in place on first boot.
encryptedbooleanOptionalIf true, treat macaroon as a CryptoJS AES-encrypted string and decrypt with the login password.
twofaSecretstringOptionalTOTP secret. ThunderHub writes this when you enable 2FA in the UI.
authTokenstringOptionalBearer token for non-gRPC providers.

For LND/litd accounts, at least one of macaroon, macaroonPath, lndDir, or litDir must be set. Without it, the account is skipped at startup.

Examples

Local LND

masterPassword: 'your-secure-password'
accounts:
  - name: 'Local LND'
    serverUrl: '127.0.0.1:10009'
    macaroonPath: '/home/me/.lnd/data/chain/bitcoin/mainnet/admin.macaroon'
    certificatePath: '/home/me/.lnd/tls.cert'

LND data-dir shorthand

masterPassword: 'your-secure-password'
defaultNetwork: 'mainnet'
accounts:
  - name: 'My Node'
    serverUrl: 'url:port'
    lndDir: '/home/me/.lnd'
  - name: 'Testnet Node'
    serverUrl: 'url:port'
    lndDir: '/home/me/.lnd-testnet'
    network: 'testnet'

lndDir resolves:

  • Certificate → <lndDir>/tls.cert
  • Macaroon → <lndDir>/data/chain/bitcoin/<network>/admin.macaroon

litDir resolves <litDir>/tls.cert and <litDir>/<network>/lit.macaroon.

lndDir / litDir only work when the files are readable from where ThunderHub runs — not for nodes on remote hosts. Use macaroon / cert strings or macaroonPath / certificatePath instead for remote nodes.

Voltage (litd over HTTPS)

masterPassword: 'your-secure-password'
accounts:
  - name: 'Voltage Mainnet'
    type: litd
    serverUrl: '<node-name>.m.voltageapp.io:443'
    macaroonPath: '/data/voltage/superadmin.macaroon'

No certificatePath — Voltage uses a CA-signed cert. Full walkthrough: Voltage.

Inline hex credentials

accounts:
  - name: 'Inline Credentials'
    serverUrl: 'remote.example.com:10009'
    macaroon: '0201036c6e6402...'
    certificate: |
      -----BEGIN CERTIFICATE-----
      MIIB6jCC...
      -----END CERTIFICATE-----

Encrypted macaroon

Encrypt a macaroon once with CryptoJS AES (any JS REPL or quick script):

const encrypted = CryptoJS.AES.encrypt(
  'HEX or Base64 encoded macaroon',
  'secret passphrase'
).toString();

Then:

accounts:
  - name: 'Encrypted Account'
    serverUrl: 'url:port'
    macaroon: 'U2FsdGVkX19...' # CryptoJS-encrypted string
    encrypted: true

At login, use the same passphrase that encrypted the macaroon — ThunderHub decrypts it in memory only.

Encrypted accounts only work in a production build (NODE_ENV=production). The dev server clears decrypted state on every restart and the login will fail.

Environment variable substitution

Account fields can reference up to four placeholder env vars:

accounts:
  - name: '${YML_ENV_1}'
    serverUrl: '${YML_ENV_2}'
    macaroon: '${YML_ENV_3}'
    certificate: '${YML_ENV_4}'

Set them in .env.local:

YML_ENV_1='My Node'
YML_ENV_2='bps.example.com:443'
YML_ENV_3='0201036c6e64...'

Substitution only happens inside accounts[] — not for top-level fields like masterPassword.

Password handling

On first boot, ThunderHub bcrypt-hashes any cleartext masterPassword / password in the YAML and rewrites the file with the hashed values. So if you check this file into git, the cleartext password is gone after the first run. Keep your own backup of the cleartext until you've verified login works.

You can also force a single master password from outside the file:

MASTER_PASSWORD_OVERRIDE='secretPasswordForAllAccounts'

The override is hashed at boot and used for every account that doesn't have its own password. See Security for more on encrypted macaroons, 2FA, and password rotation.

Remote LND access

To connect to LND on another host, expose its gRPC port and add the external address to lnd.conf so the TLS cert covers it:

# By IP address
tlsextraip=<external-ip>
rpclisten=0.0.0.0:10009

# Or by domain
tlsextradomain=node.example.com
rpclisten=0.0.0.0:10009

Restart LND to regenerate the cert, then copy the new tls.cert and macaroon to the host that runs ThunderHub.