seedify

package module
v1.17.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 16, 2026 License: MIT Imports: 26 Imported by: 0

README

seedify

Go Reference Build Lint

Generate deterministic BIP-39 seed phrases from Ed25519 SSH keys, and derive wallet addresses for 20+ blockchain networks.

seedify is both a Go library for programmatic use and a CLI tool for interactive use.

Features

  • Generate BIP-39 mnemonic phrases (12, 15, 18, 21, or 24 words) from Ed25519 keys
  • Generate 16-word Polyseed phrases for Monero
  • Derive wallet addresses and keys for 20+ chains from a single mnemonic
  • Deterministic output -- same key always produces the same phrase
  • Optional seed passphrase for additional entropy
  • Brave Sync 25th-word support
Supported Chains
Chain Address Type Derivation
Bitcoin Legacy P2PKH, SegWit P2SH-P2WPKH, Native SegWit P2WPKH, Silent Payments, Multisig (1-of-1) BIP44/49/84/48/47
Nostr npub/nsec NIP-06 (m/44'/1237'/0'/0/0)
Monero Primary + subaddresses Polyseed
Ethereum EVM address BIP44 (m/44'/60'/0'/0/0)
Solana Ed25519 address BIP44 (m/44'/501'/0'/0')
Tron Base58Check address BIP44 (m/44'/195'/0'/0/0)
Litecoin Native SegWit BIP84
Dogecoin P2PKH BIP44
Zcash Transparent t-addr BIP44
Cosmos Bech32 (cosmos1...) BIP44 (m/44'/118'/0'/0/0)
Noble Bech32 (noble1...) BIP44 (m/44'/118'/0'/0/0)
Stellar StrKey (G...) BIP44 (m/44'/148'/0')
Ripple Base58 (r...) BIP44 (m/44'/144'/0'/0/0)
Sui Hex (0x...) BIP44 (m/44'/784'/0'/0'/0')
Arbitrum, Avalanche, Base, BNB Chain, Cronos, Optimism, Polygon Same as Ethereum BIP44 (m/44'/60'/0'/0/0)

Install

As a Go Library
go get github.com/complex-gh/seedify@latest
As a CLI Tool

Homebrew (macOS/Linux):

brew install complex-gh/tap/seedify

Go install:

go install github.com/complex-gh/seedify/cmd/seedify@latest

Docker:

docker run --rm -v ~/.ssh:/root/.ssh:ro ghcr.io/complex-gh/seedify /root/.ssh/id_ed25519

Binary releases: download from the Releases page.

Library Usage

Generate a Mnemonic from an Ed25519 Key
package main

import (
	"crypto/ed25519"
	"fmt"
	"log"

	"github.com/complex-gh/seedify"
)

func main() {
	// Given an Ed25519 private key (e.g. parsed from an SSH key file):
	var key ed25519.PrivateKey // = ...

	// Generate a 24-word BIP-39 mnemonic
	mnemonic, err := seedify.ToMnemonicWithLength(&key, 24, "", false, 0)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(mnemonic)
}
Mnemonic Generation
// 12-word BIP-39
m12, _ := seedify.ToMnemonicWithLength(&key, 12, "", false, 0)

// 16-word Polyseed (with birthday timestamp for Monero)
m16, _ := seedify.ToMnemonicWithLength(&key, 16, "", false, seedify.PolyseedDefaultBirthday)

// 24-word BIP-39 with additional seed passphrase
m24, _ := seedify.ToMnemonicWithLength(&key, 24, "my-extra-entropy", false, 0)

// 24-word with a custom prefix (generates different words)
mPfx, _ := seedify.ToMnemonicWithPrefix(&key, 24, "", "wallet", 0)

// Brave Sync 25-word phrase (24 words + daily rotating 25th word)
brave, _ := seedify.ToMnemonicWithBraveSync(&key, "")

// Get the Brave Sync 25th word for today
word, _ := seedify.BraveSync25thWord()

Valid word counts: 12, 15, 16 (Polyseed), 18, 21, 24.

Derive Nostr Keys (NIP-06)
// From a BIP-39 mnemonic -- returns npub, nsec, hex pubkey, hex privkey
keys, err := seedify.DeriveNostrKeysWithHex(mnemonic, "")
fmt.Println(keys.Npub)       // npub1...
fmt.Println(keys.Nsec)       // nsec1...
fmt.Println(keys.PubKeyHex)  // 64-char hex
fmt.Println(keys.PrivKeyHex) // 64-char hex

// Simpler variant returning only npub/nsec strings
npub, nsec, err := seedify.DeriveNostrKeys(mnemonic, "")

// Directly from an Ed25519 key (no mnemonic needed)
npub, nsec, err := seedify.DeriveNostrKeysFromEd25519(&key)
Derive Bitcoin Addresses and Keys
// Single addresses
legacy, _  := seedify.DeriveBitcoinAddress(mnemonic, "")              // 1...  (P2PKH, BIP44)
segwit, _  := seedify.DeriveBitcoinAddressSegwit(mnemonic, "")        // 3...  (P2SH-P2WPKH, BIP49)
native, _  := seedify.DeriveBitcoinAddressNativeSegwit(mnemonic, "")  // bc1q... (P2WPKH, BIP84)
sp, _      := seedify.DeriveSilentPaymentAddress(mnemonic, "")        // sp1...

// Address + WIF private key
legacyKeys, _ := seedify.DeriveBitcoinLegacyKeys(mnemonic, "")
fmt.Println(legacyKeys.Address)    // 1...
fmt.Println(legacyKeys.PrivateWIF) // 5... or K.../L...

segwitKeys, _      := seedify.DeriveBitcoinSegwitKeys(mnemonic, "")
nativeSegwitKeys, _ := seedify.DeriveBitcoinNativeSegwitKeys(mnemonic, "")

// Extended keys (xpub/xprv, ypub/yprv, zpub/zprv)
masterExt, _ := seedify.DeriveBitcoinMasterExtendedKeys(mnemonic, "")
legacyExt, _ := seedify.DeriveBitcoinLegacyExtendedKeys(mnemonic, "")
segwitExt, _ := seedify.DeriveBitcoinSegwitExtendedKeys(mnemonic, "")
nativeExt, _ := seedify.DeriveBitcoinNativeSegwitExtendedKeys(mnemonic, "")

// Master fingerprint (4-byte hex)
fingerprint, _ := seedify.DeriveBitcoinMasterFingerprint(mnemonic, "")

// Multisig 1-of-1 keys
msLegacy, _ := seedify.DeriveBitcoinMultisigLegacyKeys(mnemonic, "")
msSegwit, _ := seedify.DeriveBitcoinMultisigSegwitKeys(mnemonic, "")
msNative, _ := seedify.DeriveBitcoinMultisigNativeSegwitKeys(mnemonic, "")

// Multisig extended keys (Ypub/Yprv, Zpub/Zprv with xpub/xprv equivalents)
msLegacyExt, _ := seedify.DeriveBitcoinMultisigLegacyExtendedKeys(mnemonic, "")
msSegwitExt, _ := seedify.DeriveBitcoinMultisigSegwitExtendedKeys(mnemonic, "")
msNativeExt, _ := seedify.DeriveBitcoinMultisigNativeSegwitExtendedKeys(mnemonic, "")

// PayNym / BIP-47 payment code
paynym, _ := seedify.DerivePayNym(mnemonic, "")
fmt.Println(paynym.PaymentCode)         // PM8T...
fmt.Println(paynym.NotificationAddress) // 1...
Derive Other Chain Addresses
eth, _     := seedify.DeriveEthereumAddress(mnemonic, "")  // 0x...
sol, _     := seedify.DeriveSolanaAddress(mnemonic, "")     // Base58
tron, _    := seedify.DeriveTronAddress(mnemonic, "")       // T...
ltc, _     := seedify.DeriveLitecoinAddress(mnemonic, "")   // ltc1...
doge, _    := seedify.DeriveDogecoinAddress(mnemonic, "")   // D...
zec, _     := seedify.DeriveZcashAddress(mnemonic, "")      // t1...
xrp, _     := seedify.DeriveRippleAddress(mnemonic, "")     // r...
cosmos, _  := seedify.DeriveCosmosAddress(mnemonic, "")     // cosmos1...
noble, _   := seedify.DeriveNobleAddress(mnemonic, "")      // noble1...
xlm, _     := seedify.DeriveStellarAddress(mnemonic, "")    // G...
sui, _     := seedify.DeriveSuiAddress(mnemonic, "")        // 0x...

EVM-compatible chains (Arbitrum, Avalanche, Base, BNB Chain, Cronos, Optimism, Polygon) share the same address as Ethereum -- call DeriveEthereumAddress.

Derive Monero Addresses (from Polyseed)
// Generate a 16-word Polyseed mnemonic first
polyseed, _ := seedify.ToMnemonicWithLength(&key, 16, "", false, seedify.PolyseedDefaultBirthday)

// Primary address
addr, _ := seedify.DeriveMoneroAddress(polyseed) // 4...

// Subaddress at a specific index
sub, _ := seedify.DeriveMoneroSubaddressAtIndex(polyseed, 1) // 8...

// Primary + multiple subaddresses in one call
keys, _ := seedify.DeriveMoneroKeys(polyseed, 5)
fmt.Println(keys.PrimaryAddress) // 4...
fmt.Println(keys.Subaddresses)   // [8..., 8..., 8..., 8..., 8...]

API Reference

The full API documentation is available on pkg.go.dev.

Constants
Constant Description
PolyseedDefaultBirthday Default Polyseed birthday (1 Jan 2026 00:00 UTC). Use for deterministic 16-word output. Pass 0 for current time.
Types
Type Fields Description
NostrKeys Npub, Nsec, PubKeyHex, PrivKeyHex Nostr key pair in bech32 and hex formats
BitcoinKeys Address, PrivateWIF Bitcoin address with its WIF-encoded private key
BitcoinExtendedKeys ExtendedPublicKey, ExtendedPrivateKey Account-level extended keys (xpub/xprv, ypub/yprv, zpub/zprv)
BitcoinMultisigExtendedKeys ExtendedPublicKey, ExtendedPrivateKey, StandardPublicKey, StandardPrivateKey Multisig extended keys in both specific (Ypub/Zpub) and standard (xpub) formats
PayNymKeys PaymentCode, NotificationAddress BIP-47 payment code and notification address
MoneroKeys PrimaryAddress, Subaddresses Monero primary address and subaddresses
Functions
Mnemonic Generation
Function Description
ToMnemonicWithLength(key, wordCount, seedPassphrase, brave, birthday) Generate a mnemonic of the given word count (12/15/16/18/21/24)
ToMnemonicWithPrefix(key, wordCount, seedPassphrase, prefix, birthday) Generate a mnemonic with a custom prefix for domain separation
ToMnemonicWithBraveSync(key, seedPassphrase) Generate a 25-word Brave Sync phrase
BraveSync25thWord() Get today's Brave Sync 25th word
BraveSync25thWordForDate(date) Get the Brave Sync 25th word for a specific date
Nostr (NIP-06)
Function Description
DeriveNostrKeysWithHex(mnemonic, bip39Passphrase) Derive full Nostr key set (npub, nsec, hex) from mnemonic
DeriveNostrKeys(mnemonic, bip39Passphrase) Derive npub/nsec strings from mnemonic
DeriveNostrKeysFromEd25519(key) Derive npub/nsec directly from an Ed25519 key
Bitcoin
Function Description
DeriveBitcoinAddress(mnemonic, passphrase) Legacy P2PKH address (BIP44)
DeriveBitcoinAddressSegwit(mnemonic, passphrase) SegWit P2SH-P2WPKH address (BIP49)
DeriveBitcoinAddressNativeSegwit(mnemonic, passphrase) Native SegWit P2WPKH address (BIP84)
DeriveBitcoinAddressNativeSegwitAtIndex(mnemonic, passphrase, index) Native SegWit address at a specific index
DeriveSilentPaymentAddress(mnemonic, passphrase) BIP-352 Silent Payment address
DeriveBitcoinLegacyKeys(mnemonic, passphrase) Legacy address + WIF key
DeriveBitcoinSegwitKeys(mnemonic, passphrase) SegWit address + WIF key
DeriveBitcoinNativeSegwitKeys(mnemonic, passphrase) Native SegWit address + WIF key
DeriveBitcoinMasterFingerprint(mnemonic, passphrase) 4-byte master fingerprint (hex)
DeriveBitcoinMasterExtendedKeys(mnemonic, passphrase) Master xpub/xprv at path m
DeriveBitcoinLegacyExtendedKeys(mnemonic, passphrase) Account xpub/xprv (BIP44)
DeriveBitcoinSegwitExtendedKeys(mnemonic, passphrase) Account ypub/yprv (BIP49)
DeriveBitcoinNativeSegwitExtendedKeys(mnemonic, passphrase) Account zpub/zprv (BIP84)
DeriveBitcoinMultisigLegacyKeys(mnemonic, passphrase) Multisig legacy address + WIF (BIP48)
DeriveBitcoinMultisigSegwitKeys(mnemonic, passphrase) Multisig SegWit address + WIF (BIP48)
DeriveBitcoinMultisigNativeSegwitKeys(mnemonic, passphrase) Multisig native SegWit address + WIF (BIP48)
DeriveBitcoinMultisigLegacyExtendedKeys(mnemonic, passphrase) Multisig legacy xpub/xprv (BIP48)
DeriveBitcoinMultisigSegwitExtendedKeys(mnemonic, passphrase) Multisig SegWit Ypub/Yprv + xpub/xprv (BIP48)
DeriveBitcoinMultisigNativeSegwitExtendedKeys(mnemonic, passphrase) Multisig native SegWit Zpub/Zprv + xpub/xprv (BIP48)
DerivePayNym(mnemonic, passphrase) BIP-47 PayNym payment code + notification address
Monero
Function Description
DeriveMoneroAddress(mnemonic) Primary Monero address from a 16-word Polyseed
DeriveMoneroSubaddressAtIndex(mnemonic, index) Monero subaddress at a given index
DeriveMoneroKeys(mnemonic, numSubaddresses) Primary address + N subaddresses
Other Chains
Function Description
DeriveEthereumAddress(mnemonic, passphrase) Ethereum / EVM address
DeriveSolanaAddress(mnemonic, passphrase) Solana address
DeriveTronAddress(mnemonic, passphrase) Tron address
DeriveLitecoinAddress(mnemonic, passphrase) Litecoin native SegWit address
DeriveDogecoinAddress(mnemonic, passphrase) Dogecoin address
DeriveZcashAddress(mnemonic, passphrase) Zcash transparent address
DeriveRippleAddress(mnemonic, passphrase) Ripple (XRP) address
DeriveCosmosAddress(mnemonic, passphrase) Cosmos address
DeriveNobleAddress(mnemonic, passphrase) Noble address
DeriveStellarAddress(mnemonic, passphrase) Stellar address
DeriveSuiAddress(mnemonic, passphrase) Sui address

CLI Usage

seedify <key-path> [flags]
seedify ~/.ssh/id_ed25519
seedify ~/.ssh/id_ed25519 --words 12
seedify ~/.ssh/id_ed25519 --words 12,24
seedify ~/.ssh/id_ed25519 --nostr
seedify ~/.ssh/id_ed25519 --btc --eth --sol
seedify ~/.ssh/id_ed25519 --full
seedify ~/.ssh/id_ed25519 --brave
seedify ~/.ssh/id_ed25519 --xmr --polyseed-year 2025
cat ~/.ssh/id_ed25519 | seedify --words 18
Flags
Flag Description
-w, --words Word counts to generate, comma-separated (12,15,16,18,21,24)
--seed-passphrase Combine with SSH key seed for additional entropy
--brave Generate 25-word Brave Sync phrase
--full Print all word counts and all chain derivations
--nostr Derive Nostr keys (npub/nsec)
--btc Derive Bitcoin addresses
--eth Derive Ethereum address
--zec Derive Zcash address
--sol Derive Solana address
--tron Derive Tron address
--xmr Derive Monero address from Polyseed
--zenprofile Output public keys and addresses as DNS JSON
--publish Publish NIP-78 event to relays (with --zenprofile)
--polyseed-year Override Polyseed birthday year (default: current year)
-l, --language Mnemonic language (default: en)
Security Tip

Add a leading space before the command to prevent it from being saved in your shell history:

 seedify ~/.ssh/id_ed25519

Most shells (bash, zsh) ignore commands that start with a space when HISTCONTROL=ignorespace or HIST_IGNORE_SPACE is set.

Security Considerations

  • Password-protected keys only: The CLI requires SSH keys to be password-protected. Unprotected keys are rejected.
  • One-way derivation: Seed phrases cannot be used to recover the original SSH key. The derivation is intentionally irreversible.
  • Deterministic output: The same key + passphrase always produces the same mnemonic. This means the mnemonic is only as secure as the SSH key and passphrase.
  • Seed passphrase: Use --seed-passphrase (CLI) or the seedPassphrase parameter (library) to add entropy beyond the SSH key alone. Different passphrases produce completely different mnemonics.

License

MIT -- Copyright (c) 2025-2026 complex (complex@ft.hn)

Documentation

Overview

Package seedify provides functions to create seed phrases deterministically from an SSH key. This package does not provide functionality to recover the original SSH key from the seed phrase.

The purpose of seedify is to generate seed phrases of various lengths (12, 15, 16, 18, 21, or 24 words) from an ed25519 private key. These phrases can be used for various purposes.

Index

Examples

Constants

View Source
const (

	// PolyseedDefaultBirthday is the default polyseed birthday (1 Jan 2026 00:00 UTC).
	// Using a fixed timestamp ensures deterministic mnemonic output.
	// Pass 0 to use the current time (non-deterministic).
	PolyseedDefaultBirthday = uint64(1767225600)
)

Constants for mnemonic generation.

Variables

This section is empty.

Functions

func BraveSync25thWord

func BraveSync25thWord() (string, error)

BraveSync25thWord returns the 25th word for Brave Sync based on the current date. The 25th word changes daily and is calculated from the epoch date "Tue, 10 May 2022 00:00:00 GMT". The number of days since the epoch is used as an index into the BIP39 English word list.

This function replicates the logic from the JavaScript implementation at https://alexeybarabash.github.io/25th-brave-sync-word/

Returns an error if the current date is before the epoch date or if the calculated index is out of bounds for the BIP39 word list.

func BraveSync25thWordForDate

func BraveSync25thWordForDate(date time.Time) (string, error)

BraveSync25thWordForDate returns the 25th word for Brave Sync for a specific date. This allows you to get the 25th word for any date, not just today.

The date parameter should be in UTC. The number of days since the epoch "Tue, 10 May 2022 00:00:00 GMT" is used as an index into the BIP39 English word list.

Returns an error if the provided date is before the epoch date or if the calculated index is out of bounds for the BIP39 word list.

func DeriveBitcoinAddress

func DeriveBitcoinAddress(mnemonic string, bip39Passphrase string) (string, error)

DeriveBitcoinAddress derives a Bitcoin address from a BIP39 mnemonic phrase. The function follows BIP44 standard with derivation path m/44'/0'/0'/0/0. It returns a P2PKH address (starts with "1") for Bitcoin mainnet.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Bitcoin P2PKH address
  • error: Any error that occurred during derivation

func DeriveBitcoinAddressNativeSegwit

func DeriveBitcoinAddressNativeSegwit(mnemonic string, bip39Passphrase string) (string, error)

DeriveBitcoinAddressNativeSegwit derives a P2WPKH (Native SegWit) Bitcoin address. The function follows BIP84 standard with derivation path m/84'/0'/0'/0/0. It returns a Bech32 address (starts with "bc1q") for Bitcoin mainnet.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Bitcoin P2WPKH address (starts with "bc1q")
  • error: Any error that occurred during derivation
Example
package main

import (
	"crypto/ed25519"
	"fmt"

	"github.com/complex-gh/seedify"
)

// testKey returns a deterministic Ed25519 key for examples.
// In real usage this would come from an SSH key file.
func testKey() ed25519.PrivateKey {
	seed := make([]byte, ed25519.SeedSize)
	for i := range seed {
		seed[i] = byte(i + 1)
	}
	return ed25519.NewKeyFromSeed(seed)
}

func main() {
	key := testKey()

	mnemonic, _ := seedify.ToMnemonicWithLength(&key, 24, "", false, 0)

	addr, err := seedify.DeriveBitcoinAddressNativeSegwit(mnemonic, "")
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println("starts with bc1q:", addr[:4] == "bc1q")
}

func DeriveBitcoinAddressNativeSegwitAtIndex

func DeriveBitcoinAddressNativeSegwitAtIndex(mnemonic string, bip39Passphrase string, addressIndex uint32) (string, error)

DeriveBitcoinAddressNativeSegwitAtIndex derives a P2WPKH address at the given address index. Path: m/84'/0'/0'/0/{addressIndex}. Index 1-19 is typically used for DNS output.

func DeriveBitcoinAddressSegwit

func DeriveBitcoinAddressSegwit(mnemonic string, bip39Passphrase string) (string, error)

DeriveBitcoinAddressSegwit derives a P2SH-P2WPKH (Nested SegWit) Bitcoin address. The function follows BIP49 standard with derivation path m/49'/0'/0'/0/0. It returns a P2SH-wrapped SegWit address (starts with "3") for Bitcoin mainnet.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Bitcoin P2SH-P2WPKH address (starts with "3")
  • error: Any error that occurred during derivation

func DeriveBitcoinMasterFingerprint

func DeriveBitcoinMasterFingerprint(mnemonic string, bip39Passphrase string) (string, error)

DeriveBitcoinMasterFingerprint derives the master key fingerprint from a BIP39 mnemonic. The fingerprint is the first 4 bytes of HASH160(compressed_master_public_key), encoded as a lowercase hex string (8 characters). This is commonly used in wallet descriptors and PSBTs (e.g., [d219d86d/48'/0'/0'/2']xpub...).

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • fingerprint: The 4-byte master fingerprint as a lowercase hex string
  • error: Any error that occurred during derivation

func DeriveCosmosAddress

func DeriveCosmosAddress(mnemonic string, bip39Passphrase string) (string, error)

DeriveCosmosAddress derives a Cosmos (ATOM) address from a BIP39 mnemonic. The function follows BIP44 standard with derivation path m/44'/118'/0'/0/0. It returns a Bech32 address with the "cosmos" prefix (starts with "cosmos1").

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Cosmos address (starts with "cosmos1")
  • error: Any error that occurred during derivation

func DeriveDogecoinAddress

func DeriveDogecoinAddress(mnemonic string, bip39Passphrase string) (string, error)

DeriveDogecoinAddress derives a Dogecoin P2PKH address from a BIP39 mnemonic. The function follows BIP44 standard with derivation path m/44'/3'/0'/0/0. It returns a Base58Check address (starts with "D") for Dogecoin mainnet.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Dogecoin P2PKH address (starts with "D")
  • error: Any error that occurred during derivation

func DeriveEthereumAddress

func DeriveEthereumAddress(mnemonic string, bip39Passphrase string) (string, error)

DeriveEthereumAddress derives an Ethereum address from a BIP39 mnemonic phrase. The function follows BIP44 standard with derivation path m/44'/60'/0'/0/0. It returns a checksummed Ethereum address (starts with "0x").

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Ethereum address with 0x prefix
  • error: Any error that occurred during derivation
Example
package main

import (
	"crypto/ed25519"
	"fmt"

	"github.com/complex-gh/seedify"
)

// testKey returns a deterministic Ed25519 key for examples.
// In real usage this would come from an SSH key file.
func testKey() ed25519.PrivateKey {
	seed := make([]byte, ed25519.SeedSize)
	for i := range seed {
		seed[i] = byte(i + 1)
	}
	return ed25519.NewKeyFromSeed(seed)
}

func main() {
	key := testKey()

	mnemonic, _ := seedify.ToMnemonicWithLength(&key, 24, "", false, 0)

	addr, err := seedify.DeriveEthereumAddress(mnemonic, "")
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println("starts with 0x:", addr[:2] == "0x")
	fmt.Println("length:", len(addr))
}

func DeriveLitecoinAddress

func DeriveLitecoinAddress(mnemonic string, bip39Passphrase string) (string, error)

DeriveLitecoinAddress derives a Litecoin native SegWit (P2WPKH) address from a BIP39 mnemonic. The function follows BIP84 standard with derivation path m/84'/2'/0'/0/0. It returns a Bech32 address (starts with "ltc1") for Litecoin mainnet.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Litecoin P2WPKH address (starts with "ltc1")
  • error: Any error that occurred during derivation

func DeriveMoneroAddress

func DeriveMoneroAddress(mnemonic string) (string, error)

DeriveMoneroAddress derives a Monero address from a polyseed mnemonic phrase. The function decodes the polyseed to extract the seed bytes, then derives the Monero spend and view keys from it.

Parameters:

  • mnemonic: A valid 16-word polyseed mnemonic phrase

Returns:

  • address: The Monero primary address (starts with "4")
  • error: Any error that occurred during derivation

func DeriveMoneroSubaddressAtIndex

func DeriveMoneroSubaddressAtIndex(mnemonic string, index uint32) (string, error)

DeriveMoneroSubaddressAtIndex derives a Monero receiving subaddress at the given index. Index 0 maps to subaddress (0,1), index 1 to (0,2), etc. Valid range: 0-19 for DNS output.

func DeriveNobleAddress

func DeriveNobleAddress(mnemonic string, bip39Passphrase string) (string, error)

DeriveNobleAddress derives a Noble address from a BIP39 mnemonic. Noble uses the same key derivation as Cosmos (coin type 118) but with "noble" bech32 prefix.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Noble address (starts with "noble1")
  • error: Any error that occurred during derivation

func DeriveNostrKeys

func DeriveNostrKeys(mnemonic string, bip39Passphrase string) (npub string, nsec string, err error)

DeriveNostrKeys derives Nostr keys (npub/nsec) from a BIP39 mnemonic phrase. The function follows NIP-06 standard: it converts the mnemonic to a BIP39 seed, then uses BIP32 hierarchical derivation with path m/44'/1237'/0'/0/0 to derive the Nostr private key. The keys are encoded to npub/nsec format using bech32.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • npub: The Nostr public key in bech32 format (starts with "npub1")
  • nsec: The Nostr private key in bech32 format (starts with "nsec1")
  • error: Any error that occurred during derivation

func DeriveNostrKeysFromEd25519

func DeriveNostrKeysFromEd25519(key *ed25519.PrivateKey) (npub string, nsec string, err error)

DeriveNostrKeysFromEd25519 derives Nostr keys (npub/nsec) directly from an Ed25519 private key. This function is used to derive Nostr keys from SSH keys without going through seed phrases.

Parameters:

  • key: An Ed25519 private key (e.g., from an SSH key)

Returns:

  • npub: The Nostr public key in bech32 format (starts with "npub1")
  • nsec: The Nostr private key in bech32 format (starts with "nsec1")
  • error: Any error that occurred during derivation

func DeriveRippleAddress

func DeriveRippleAddress(mnemonic string, bip39Passphrase string) (string, error)

DeriveRippleAddress derives an XRP Ledger address from a BIP39 mnemonic. The function follows BIP44 standard with derivation path m/44'/144'/0'/0/0. It returns a Ripple Base58Check address (starts with "r").

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The XRP address (starts with "r")
  • error: Any error that occurred during derivation

func DeriveSilentPaymentAddress

func DeriveSilentPaymentAddress(mnemonic string, bip39Passphrase string) (string, error)

DeriveSilentPaymentAddress derives a BIP 352 Silent Payment (sp1) address from a BIP39 mnemonic. The function follows BIP 352 derivation paths:

  • scan key: m/352'/0'/0'/1'/0
  • spend key: m/352'/0'/0'/0'/0

It returns a bech32m-encoded address (starts with "sp1") for Bitcoin mainnet. Silent Payments are privacy-preserving static addresses: each payment appears on-chain as a unique Taproot address, making it impossible for observers to link payments.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Bitcoin Silent Payment address (starts with "sp1")
  • error: Any error that occurred during derivation

func DeriveSolanaAddress

func DeriveSolanaAddress(mnemonic string, bip39Passphrase string) (string, error)

DeriveSolanaAddress derives a Solana address from a BIP39 mnemonic phrase. The function follows SLIP-0010/BIP44 standard with derivation path m/44'/501'/0'/0'. Solana uses Ed25519 keys, so all path components are hardened. It returns a Base58-encoded public key as the Solana address.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Solana address (Base58-encoded public key)
  • error: Any error that occurred during derivation

func DeriveStellarAddress

func DeriveStellarAddress(mnemonic string, bip39Passphrase string) (string, error)

DeriveStellarAddress derives a Stellar (XLM) address from a BIP39 mnemonic. The function follows SEP-0005 standard with derivation path m/44'/148'/0' using SLIP-0010 Ed25519 derivation. It returns a StrKey-encoded public key (starts with "G").

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Stellar address (starts with "G")
  • error: Any error that occurred during derivation

func DeriveSuiAddress

func DeriveSuiAddress(mnemonic string, bip39Passphrase string) (string, error)

DeriveSuiAddress derives a Sui address from a BIP39 mnemonic. The function follows SLIP-0010 Ed25519 derivation with path m/44'/784'/0'/0'/0'. It returns an address formatted as "0x" + hex(Blake2b-256(0x00 || pubkey)).

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Sui address (starts with "0x")
  • error: Any error that occurred during derivation

func DeriveTronAddress

func DeriveTronAddress(mnemonic string, bip39Passphrase string) (string, error)

DeriveTronAddress derives a Tron address from a BIP39 mnemonic phrase. The function follows BIP44 standard with derivation path m/44'/195'/0'/0/0. Tron uses the same secp256k1 key derivation and Keccak256 address computation as Ethereum, but encodes the address using Base58Check with a 0x41 prefix instead of hex with a 0x prefix. The resulting address starts with "T".

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Tron address (Base58Check-encoded, starts with "T")
  • error: Any error that occurred during derivation

func DeriveZcashAddress

func DeriveZcashAddress(mnemonic string, bip39Passphrase string) (string, error)

DeriveZcashAddress derives a Zcash transparent P2PKH (t1) address from a BIP39 mnemonic. The function follows BIP44 standard with derivation path m/44'/133'/0'/0/0 (coin type 133 = Zcash per SLIP-0044). It returns a Base58Check address (starts with "t1") for Zcash mainnet.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • address: The Zcash transparent P2PKH address (starts with "t1")
  • error: Any error that occurred during derivation

func ToMnemonicWithBraveSync

func ToMnemonicWithBraveSync(key *ed25519.PrivateKey, seedPassphrase string) (string, error)

ToMnemonicWithBraveSync generates a 24-word mnemonic with the "brave" prefix and appends the 25th word from Brave Sync. This creates a 25-word phrase suitable for use with Brave Sync.

The function generates 24 words using the same logic as ToMnemonicWithLength with the brave flag set, then appends the current day's 25th word from Brave Sync.

func ToMnemonicWithLength

func ToMnemonicWithLength(key *ed25519.PrivateKey, wordCount int, seedPassphrase string, brave bool, birthday uint64) (string, error)

ToMnemonicWithLength takes an ed25519 private key and returns a mnemonic phrase of the specified word count. This is an auxiliary utility function. The generated phrases cannot be used with FromMnemonic to recover the original key if the word count is less than 24.

If seedPassphrase is provided (non-empty), it will be combined with the SSH key seed to add additional entropy: ENTROPY(seed-passphrase) + ENTROPY(ssh-key).

The word count is prepended to the entropy to ensure different word counts generate completely different words, not just truncated versions of the same phrase. Exception: For 24 words (when brave is false), the raw seed is used directly without prepending word count or hashing.

If brave is true, the hash of "brave" is prepended to the entropy (similar to word count) to generate a different set of words.

birthday is a Unix timestamp used as the polyseed creation date for 16-word mnemonics. Use PolyseedEpoch for deterministic output, or 0 for the current time. This parameter is ignored for non-polyseed word counts.

Valid word counts are: 12, 15, 16, 18, 21, or 24. The entropy size is determined by the word count:

  • 12 words = 128 bits (16 bytes) - BIP39
  • 15 words = 160 bits (20 bytes) - BIP39
  • 16 words = 150 bits (19 bytes) - Polyseed format
  • 18 words = 192 bits (24 bytes) - BIP39
  • 21 words = 224 bits (28 bytes) - BIP39
  • 24 words = 256 bits (32 bytes) - BIP39
Example
package main

import (
	"crypto/ed25519"
	"fmt"

	"github.com/complex-gh/seedify"
)

// testKey returns a deterministic Ed25519 key for examples.
// In real usage this would come from an SSH key file.
func testKey() ed25519.PrivateKey {
	seed := make([]byte, ed25519.SeedSize)
	for i := range seed {
		seed[i] = byte(i + 1)
	}
	return ed25519.NewKeyFromSeed(seed)
}

func main() {
	key := testKey()

	mnemonic, err := seedify.ToMnemonicWithLength(&key, 12, "", false, 0)
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println("word count: 12")
	fmt.Println("mnemonic:", mnemonic)
	// Output is deterministic but depends on the key bytes,
	// so we just verify it ran without error.
}
Example (Polyseed)
package main

import (
	"crypto/ed25519"
	"fmt"

	"github.com/complex-gh/seedify"
)

// testKey returns a deterministic Ed25519 key for examples.
// In real usage this would come from an SSH key file.
func testKey() ed25519.PrivateKey {
	seed := make([]byte, ed25519.SeedSize)
	for i := range seed {
		seed[i] = byte(i + 1)
	}
	return ed25519.NewKeyFromSeed(seed)
}

func main() {
	key := testKey()

	mnemonic, err := seedify.ToMnemonicWithLength(&key, 16, "", false, seedify.PolyseedDefaultBirthday)
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println("word count: 16")
	fmt.Println("mnemonic:", mnemonic)
}
Example (TwentyFourWords)
package main

import (
	"crypto/ed25519"
	"fmt"

	"github.com/complex-gh/seedify"
)

// testKey returns a deterministic Ed25519 key for examples.
// In real usage this would come from an SSH key file.
func testKey() ed25519.PrivateKey {
	seed := make([]byte, ed25519.SeedSize)
	for i := range seed {
		seed[i] = byte(i + 1)
	}
	return ed25519.NewKeyFromSeed(seed)
}

func main() {
	key := testKey()

	mnemonic, err := seedify.ToMnemonicWithLength(&key, 24, "", false, 0)
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println("word count: 24")
	fmt.Println("mnemonic:", mnemonic)
}
Example (WithSeedPassphrase)
package main

import (
	"crypto/ed25519"
	"fmt"

	"github.com/complex-gh/seedify"
)

// testKey returns a deterministic Ed25519 key for examples.
// In real usage this would come from an SSH key file.
func testKey() ed25519.PrivateKey {
	seed := make([]byte, ed25519.SeedSize)
	for i := range seed {
		seed[i] = byte(i + 1)
	}
	return ed25519.NewKeyFromSeed(seed)
}

func main() {
	key := testKey()

	m1, _ := seedify.ToMnemonicWithLength(&key, 24, "", false, 0)
	m2, _ := seedify.ToMnemonicWithLength(&key, 24, "my-secret", false, 0)

	// Different passphrases produce different mnemonics from the same key.
	fmt.Println("same mnemonic:", m1 == m2)
}
Output:
same mnemonic: false

func ToMnemonicWithPrefix

func ToMnemonicWithPrefix(key *ed25519.PrivateKey, wordCount int, seedPassphrase string, prefix string, birthday uint64) (string, error)

ToMnemonicWithPrefix takes an ed25519 private key and returns a mnemonic phrase of the specified word count. It is a generalization of ToMnemonicWithLength that accepts an arbitrary prefix string instead of a boolean brave flag.

If prefix is non-empty, the hash of the prefix string is prepended to the entropy (similar to how the word count is prepended) to generate a completely different set of words. This allows generating distinct seed phrases for different applications (e.g., "brave" for Brave Sync, "wallet" for Brave Wallet).

If seedPassphrase is provided (non-empty), it will be combined with the SSH key seed to add additional entropy: ENTROPY(seed-passphrase) + ENTROPY(ssh-key).

The word count is prepended to the entropy to ensure different word counts generate completely different words, not just truncated versions of the same phrase. Exception: For 24 words (when prefix is empty), the raw seed is used directly without prepending word count or hashing.

birthday is a Unix timestamp used as the polyseed creation date for 16-word mnemonics. Use PolyseedEpoch for deterministic output, or 0 for the current time. This parameter is ignored for non-polyseed word counts.

Valid word counts are: 12, 15, 16, 18, 21, or 24. The entropy size is determined by the word count:

  • 12 words = 128 bits (16 bytes) - BIP39
  • 15 words = 160 bits (20 bytes) - BIP39
  • 16 words = 150 bits (19 bytes) - Polyseed format
  • 18 words = 192 bits (24 bytes) - BIP39
  • 21 words = 224 bits (28 bytes) - BIP39
  • 24 words = 256 bits (32 bytes) - BIP39

Types

type BitcoinExtendedKeys

type BitcoinExtendedKeys struct {
	ExtendedPublicKey  string
	ExtendedPrivateKey string
}

BitcoinExtendedKeys contains the extended public and private keys at the account level.

func DeriveBitcoinLegacyExtendedKeys

func DeriveBitcoinLegacyExtendedKeys(mnemonic string, bip39Passphrase string) (*BitcoinExtendedKeys, error)

DeriveBitcoinLegacyExtendedKeys derives the extended public and private keys for BIP44 Legacy. Returns xpub and xprv at the account level (m/44'/0'/0').

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • BitcoinExtendedKeys: The xpub and xprv at account level
  • error: Any error that occurred during derivation

func DeriveBitcoinMasterExtendedKeys

func DeriveBitcoinMasterExtendedKeys(mnemonic string, bip39Passphrase string) (*BitcoinExtendedKeys, error)

DeriveBitcoinMasterExtendedKeys derives the master extended public and private keys. Returns xpub and xprv at the master level (m). This is the root of the HD wallet tree, before any BIP44/49/84 derivation.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • BitcoinExtendedKeys: The xpub and xprv at master level
  • error: Any error that occurred during derivation

func DeriveBitcoinMultisigLegacyExtendedKeys

func DeriveBitcoinMultisigLegacyExtendedKeys(mnemonic string, bip39Passphrase string) (*BitcoinExtendedKeys, error)

DeriveBitcoinMultisigLegacyExtendedKeys derives extended keys for BIP48 Legacy multisig. Returns xpub and xprv at the account/script level (m/48'/0'/0'/0').

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • BitcoinExtendedKeys: The xpub and xprv at account level
  • error: Any error that occurred during derivation

func DeriveBitcoinNativeSegwitExtendedKeys

func DeriveBitcoinNativeSegwitExtendedKeys(mnemonic string, bip39Passphrase string) (*BitcoinExtendedKeys, error)

DeriveBitcoinNativeSegwitExtendedKeys derives the extended public and private keys for BIP84 Native SegWit. Returns zpub and zprv at the account level (m/84'/0'/0').

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • BitcoinExtendedKeys: The zpub and zprv at account level
  • error: Any error that occurred during derivation

func DeriveBitcoinSegwitExtendedKeys

func DeriveBitcoinSegwitExtendedKeys(mnemonic string, bip39Passphrase string) (*BitcoinExtendedKeys, error)

DeriveBitcoinSegwitExtendedKeys derives the extended public and private keys for BIP49 SegWit. Returns ypub and yprv at the account level (m/49'/0'/0').

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • BitcoinExtendedKeys: The ypub and yprv at account level
  • error: Any error that occurred during derivation

type BitcoinKeys

type BitcoinKeys struct {
	Address    string
	PrivateWIF string
}

BitcoinKeys contains the address and private key (WIF) for a Bitcoin derivation.

func DeriveBitcoinLegacyKeys

func DeriveBitcoinLegacyKeys(mnemonic string, bip39Passphrase string) (*BitcoinKeys, error)

DeriveBitcoinLegacyKeys derives a Bitcoin Legacy P2PKH address and its WIF private key. The function follows BIP44 standard with derivation path m/44'/0'/0'/0/0.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • BitcoinKeys: The address and WIF-encoded private key
  • error: Any error that occurred during derivation

func DeriveBitcoinMultisigLegacyKeys

func DeriveBitcoinMultisigLegacyKeys(mnemonic string, bip39Passphrase string) (*BitcoinKeys, error)

DeriveBitcoinMultisigLegacyKeys derives a 1-of-1 multisig P2SH address and its WIF private key. The function follows BIP48 standard with derivation path m/48'/0'/0'/0'/0/0. Script type 0' indicates P2SH (legacy multisig).

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • BitcoinKeys: The P2SH multisig address and WIF-encoded private key
  • error: Any error that occurred during derivation

func DeriveBitcoinMultisigNativeSegwitKeys

func DeriveBitcoinMultisigNativeSegwitKeys(mnemonic string, bip39Passphrase string) (*BitcoinKeys, error)

DeriveBitcoinMultisigNativeSegwitKeys derives a 1-of-1 multisig P2WSH address and its WIF private key. The function follows BIP48 standard with derivation path m/48'/0'/0'/2'/0/0. Script type 2' indicates P2WSH (native SegWit multisig).

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • BitcoinKeys: The P2WSH multisig address and WIF-encoded private key
  • error: Any error that occurred during derivation

func DeriveBitcoinMultisigSegwitKeys

func DeriveBitcoinMultisigSegwitKeys(mnemonic string, bip39Passphrase string) (*BitcoinKeys, error)

DeriveBitcoinMultisigSegwitKeys derives a 1-of-1 multisig P2SH-P2WSH address and its WIF private key. The function follows BIP48 standard with derivation path m/48'/0'/0'/1'/0/0. Script type 1' indicates P2SH-P2WSH (nested SegWit multisig).

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • BitcoinKeys: The P2SH-P2WSH multisig address and WIF-encoded private key
  • error: Any error that occurred during derivation

func DeriveBitcoinNativeSegwitKeys

func DeriveBitcoinNativeSegwitKeys(mnemonic string, bip39Passphrase string) (*BitcoinKeys, error)

DeriveBitcoinNativeSegwitKeys derives a Bitcoin Native SegWit P2WPKH address and its WIF private key. The function follows BIP84 standard with derivation path m/84'/0'/0'/0/0.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • BitcoinKeys: The address and WIF-encoded private key
  • error: Any error that occurred during derivation

func DeriveBitcoinSegwitKeys

func DeriveBitcoinSegwitKeys(mnemonic string, bip39Passphrase string) (*BitcoinKeys, error)

DeriveBitcoinSegwitKeys derives a Bitcoin SegWit P2SH-P2WPKH address and its WIF private key. The function follows BIP49 standard with derivation path m/49'/0'/0'/0/0.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • BitcoinKeys: The address and WIF-encoded private key
  • error: Any error that occurred during derivation

type BitcoinMultisigExtendedKeys

type BitcoinMultisigExtendedKeys struct {
	// ExtendedPublicKey is the specific format (e.g., Ypub or Zpub)
	ExtendedPublicKey string
	// ExtendedPrivateKey is the specific format (e.g., Yprv or Zprv)
	ExtendedPrivateKey string
	// StandardPublicKey is the standard xpub format
	StandardPublicKey string
	// StandardPrivateKey is the standard xprv format
	StandardPrivateKey string
}

BitcoinMultisigExtendedKeys contains both the specific format (Ypub/Yprv or Zpub/Zprv) and the standard format (xpub/xprv) for multisig extended keys. The standard keys are nested conceptually below the specific keys.

func DeriveBitcoinMultisigNativeSegwitExtendedKeys

func DeriveBitcoinMultisigNativeSegwitExtendedKeys(mnemonic string, bip39Passphrase string) (*BitcoinMultisigExtendedKeys, error)

DeriveBitcoinMultisigNativeSegwitExtendedKeys derives extended keys for BIP48 Native SegWit multisig. Returns Zpub/Zprv (SLIP-132 format) and xpub/xprv (standard format) at the account/script level (m/48'/0'/0'/2'). Uppercase Z indicates multisig P2WSH.

The standard xpub/xprv keys are provided as nested alternatives to the specific Zpub/Zprv format:

Zprv ...
|_ xprv ...

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • BitcoinMultisigExtendedKeys: The Zpub/Zprv and xpub/xprv at account level
  • error: Any error that occurred during derivation

func DeriveBitcoinMultisigSegwitExtendedKeys

func DeriveBitcoinMultisigSegwitExtendedKeys(mnemonic string, bip39Passphrase string) (*BitcoinMultisigExtendedKeys, error)

DeriveBitcoinMultisigSegwitExtendedKeys derives extended keys for BIP48 SegWit multisig. Returns Ypub/Yprv (SLIP-132 format) and xpub/xprv (standard format) at the account/script level (m/48'/0'/0'/1'). Uppercase Y indicates multisig P2SH-P2WSH.

The standard xpub/xprv keys are provided as nested alternatives to the specific Ypub/Yprv format:

Yprv ...
|_ xprv ...

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • BitcoinMultisigExtendedKeys: The Ypub/Yprv and xpub/xprv at account level
  • error: Any error that occurred during derivation

type MoneroKeys

type MoneroKeys struct {
	// PrimaryAddress is the main Monero address (starts with "4")
	PrimaryAddress string
	// Subaddresses is a list of subaddresses (start with "8")
	// Index 0 is subaddress (0,1), index 1 is (0,2), etc.
	Subaddresses []string
}

MoneroKeys contains the primary address and subaddresses derived from a polyseed.

func DeriveMoneroKeys

func DeriveMoneroKeys(mnemonic string, numSubaddresses int) (*MoneroKeys, error)

DeriveMoneroKeys derives a Monero primary address and subaddresses from a polyseed mnemonic. The function decodes the polyseed to extract the seed bytes, then derives the Monero spend and view keys, and generates the requested number of subaddresses.

Parameters:

  • mnemonic: A valid 16-word polyseed mnemonic phrase
  • numSubaddresses: Number of subaddresses to generate (0 for none)

Returns:

  • MoneroKeys: Contains the primary address and subaddresses
  • error: Any error that occurred during derivation
Example
package main

import (
	"crypto/ed25519"
	"fmt"

	"github.com/complex-gh/seedify"
)

// testKey returns a deterministic Ed25519 key for examples.
// In real usage this would come from an SSH key file.
func testKey() ed25519.PrivateKey {
	seed := make([]byte, ed25519.SeedSize)
	for i := range seed {
		seed[i] = byte(i + 1)
	}
	return ed25519.NewKeyFromSeed(seed)
}

func main() {
	key := testKey()

	polyseed, err := seedify.ToMnemonicWithLength(&key, 16, "", false, seedify.PolyseedDefaultBirthday)
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	keys, err := seedify.DeriveMoneroKeys(polyseed, 3)
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println("primary starts with 4:", keys.PrimaryAddress[:1] == "4")
	fmt.Println("subaddress count:", len(keys.Subaddresses))
}

type NostrKeys

type NostrKeys struct {
	// Npub is the public key in bech32 format (starts with "npub1")
	Npub string
	// Nsec is the private key in bech32 format (starts with "nsec1")
	Nsec string
	// PubKeyHex is the raw public key in hexadecimal format (64 characters)
	PubKeyHex string
	// PrivKeyHex is the raw private key in hexadecimal format (64 characters)
	PrivKeyHex string
}

NostrKeys contains all Nostr key formats derived from a mnemonic.

func DeriveNostrKeysWithHex

func DeriveNostrKeysWithHex(mnemonic string, bip39Passphrase string) (*NostrKeys, error)

DeriveNostrKeysWithHex derives Nostr keys from a BIP39 mnemonic phrase. Returns keys in both bech32 (npub/nsec) and hexadecimal formats. The function follows NIP-06 standard: it converts the mnemonic to a BIP39 seed, then uses BIP32 hierarchical derivation with path m/44'/1237'/0'/0/0 to derive the Nostr private key.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • NostrKeys: Contains npub, nsec, pubKeyHex, and privKeyHex
  • error: Any error that occurred during derivation
Example
package main

import (
	"crypto/ed25519"
	"fmt"

	"github.com/complex-gh/seedify"
)

// testKey returns a deterministic Ed25519 key for examples.
// In real usage this would come from an SSH key file.
func testKey() ed25519.PrivateKey {
	seed := make([]byte, ed25519.SeedSize)
	for i := range seed {
		seed[i] = byte(i + 1)
	}
	return ed25519.NewKeyFromSeed(seed)
}

func main() {
	key := testKey()

	mnemonic, err := seedify.ToMnemonicWithLength(&key, 24, "", false, 0)
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	nostrKeys, err := seedify.DeriveNostrKeysWithHex(mnemonic, "")
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println("npub:", nostrKeys.Npub[:10]+"...")
	fmt.Println("nsec:", nostrKeys.Nsec[:10]+"...")
	fmt.Println("pubkey hex length:", len(nostrKeys.PubKeyHex))
	fmt.Println("privkey hex length:", len(nostrKeys.PrivKeyHex))
}

type PayNymKeys

type PayNymKeys struct {
	// PaymentCode is the Base58Check-encoded BIP47 payment code (starts with "PM8T").
	PaymentCode string
	// NotificationAddress is the P2PKH address for receiving notification transactions.
	NotificationAddress string
}

PayNymKeys contains the BIP47 payment code (PayNym) and notification address. The payment code is derived from m/47'/0'/0'; the notification address from m/47'/0'/0'/0.

func DerivePayNym

func DerivePayNym(mnemonic string, bip39Passphrase string) (*PayNymKeys, error)

DerivePayNym derives a BIP47 payment code (PayNym) and notification address from a BIP39 mnemonic. The function follows BIP47 with derivation path m/47'/0'/0' for the payment code and m/47'/0'/0'/0 for the notification address. Uses version 1 payment code format.

Parameters:

  • mnemonic: A valid BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
  • bip39Passphrase: Optional BIP39 passphrase (empty string if not used)

Returns:

  • PayNymKeys: The payment code and notification address
  • error: Any error that occurred during derivation
Example
package main

import (
	"crypto/ed25519"
	"fmt"

	"github.com/complex-gh/seedify"
)

// testKey returns a deterministic Ed25519 key for examples.
// In real usage this would come from an SSH key file.
func testKey() ed25519.PrivateKey {
	seed := make([]byte, ed25519.SeedSize)
	for i := range seed {
		seed[i] = byte(i + 1)
	}
	return ed25519.NewKeyFromSeed(seed)
}

func main() {
	key := testKey()

	mnemonic, _ := seedify.ToMnemonicWithLength(&key, 24, "", false, 0)

	paynym, err := seedify.DerivePayNym(mnemonic, "")
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println("payment code prefix:", paynym.PaymentCode[:4])
}

Directories

Path Synopsis
cmd
seedify command
Package main provides the seedify CLI tool for generating seed phrases from SSH keys.
Package main provides the seedify CLI tool for generating seed phrases from SSH keys.
scripts
derive_zcash command
derive_zcash derives a Zcash transparent (t1) address from a BIP39 mnemonic for testing.
derive_zcash derives a Zcash transparent (t1) address from a BIP39 mnemonic for testing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL