This example (examples/keyderivation/main.go) demonstrates how to deterministically derive Nostr keypairs from a single master secret using two approaches:
- BIP32/BIP44-style derivation with
btcd/btcutil(recommended) - A simple HMAC-SHA256 scheme (for comparison/testing)
It also shows how to:
- Display the generated BIP-39 mnemonic and master/root keypair
- Derive multiple child keys and print them in both hex and NIP-19 formats (
nsec/npub) - Check whether a given public key (hex or
npub) belongs to the same master key - Create and sign a Nostr event using a derived private key via
go-nostr
Implemented in keyderivation/hdkey.go:
- Path:
m/44'/1237'/0'/0/index44'— BIP44 purpose1237'— Nostr coin type0'— account 00— external chainindex— non-hardened address index starting at 0
- Formats:
- Private/Public keys are output in hex.
- NIP-19 encodings (
nsecfor private,npubfor public) are produced withgo-nostr.
- Go 1.20+ installed
From the repository root (higher/):
# Run directly
go run ./examples/keyderivation
# Or build and run
go build -o key-derivation ./examples/keyderivation
./key-derivationBy default, the example generates a fresh 12-word BIP-39 mnemonic on each run and derives keys from it. The generated mnemonic is printed at the top of the output so you can save/reuse it.
The example now supports flags so you don't have to edit code to supply inputs:
--mnemonic— Provide a BIP-39 mnemonic directly.--mnemonic-file— Path to a file containing a BIP-39 mnemonic (one line).--start— Start index for derivation (default: 0).--count— Number of keys to derive with BIP32 (default: 3).--simple-count— Number of keys to derive with the simple HMAC method (default: 2).--check-max— Max index to scan when checking key ownership (default: 100).--event-index— Index used to sign the sample Nostr event (default: 0).--message— Content for the sample Nostr event (default: "Hello Nostr! This message was signed with a derived key.")
Examples:
# Run with a specific mnemonic string
go run ./examples/keyderivation \
--mnemonic "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" \
--start 0 --count 5 --simple-count 2 --check-max 200 --event-index 0 \
--message "Signing from index 0 with my custom message"
# Run with a mnemonic from a file
echo "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" > /tmp/m.txt
go run ./examples/keyderivation --mnemonic-file /tmp/m.txt --count 4
# Build then run with flags
go build -o key-derivation ./examples/keyderivation
./key-derivation --count 10 --simple-count 3The program walks through five steps:
- Create a deriver from a BIP-39 mnemonic (auto-generated if empty).
- Show the master/root keypair derived from the mnemonic/seed.
- Derive several child keys using BIP32 and print them (hex and
nsec/npub). - Derive a couple of keys using the simple HMAC method and print them (
nsec/npub). - Verify whether a target key belongs to the same master using both hex and
npubinputs. - Create and sign a simple Nostr text note with a derived key, then verify its signature.
Example output sections include:
- The 12-word mnemonic used
- Master keypair (hex + NIP-19)
- Derived child keys at indices 0..N
- Key-ownership checks like:
✅ Hex key abcd... found at index X: true✅ NIP-19 key npub1... found at index X: true
- A signed event with fields
ID,PubKey,Content,Sig, and signature verification status
You can pass a mnemonic without editing code by using flags. Either pass it directly:
go run ./examples/keyderivation --mnemonic "<your 12 or 24 words>"Or place it in a file and reference it:
go run ./examples/keyderivation --mnemonic-file /path/to/mnemonic.txt- Private keys are printed to stdout for demonstration. Do not use this example output in production.
- Always keep your mnemonic and private keys secret. Anyone who knows them can sign as you.
- The simple HMAC derivation is for educational comparison only. For real applications, use the BIP32/BIP44 method.
examples/keyderivation/main.go— the runnable examplekeyderivation/hdkey.go— implementation of derivation and helpers
- If you see "invalid mnemonic" after editing the code, ensure your mnemonic is valid BIP-39 words and spacing.
- If
go runfails, ensure you’re running from the repo root and that modules are downloaded:go mod download.