Pool Party is a Go library for generating deterministic BIP39/BIP44 address pools for multiple coins.
This branch modernizes the project for current Go toolchains:
- Go module target:
go 1.26.4 - Standard BIP32 derivation via
hdkeychain.Derive - BIP39 seed normalization with UTF-8 NFKD
- Public address-only API that does not expose private keys
- Tests for deterministic vectors, invalid ranges, global network mutation, secret redaction, and public address generation
See CHANGELOG.md before upgrading an existing wallet flow. This pass changes BIP32 derivation to the current standard behavior and normalizes BIP39 seed inputs with Unicode NFKD.
go get github.com/Pantani/pool-partyUse GeneratePublicAddressPool when you only need public addresses. It returns no private key, WIF, extended key, master key, seed, mnemonic, or passphrase fields.
package main
import (
"fmt"
"log"
poolparty "github.com/Pantani/pool-party"
"github.com/Pantani/pool-party/bip44"
)
func main() {
pool := poolparty.NewPoolWithSecret(
bip44.Ethereum,
"rent slogan lemon nerve soup annual depend shift olympic similar bounce wait often fury slush fish crazy bring police level economy crush can energy",
"",
)
addresses, err := pool.GeneratePublicAddressPool(0, 3)
if err != nil {
log.Fatal(err)
}
for _, address := range addresses {
fmt.Printf("%d %s\n", address.Index, address.Address)
}
}GeneratePrivateAddressPool and bip44.GeneratePrivateWallets return private key material. Use them only when you explicitly need exportable private keys.
addresses, err := pool.GeneratePrivateAddressPool(0, 1)
if err != nil {
log.Fatal(err)
}
fmt.Println(addresses[0].Address)
fmt.Println(addresses[0].Privkey) // secret: store and log with careDo not log mnemonics, passphrases, private keys, WIF strings, xprv values, or full wallet/account structs. Pool.String redacts mnemonic and passphrase, but callers should still treat the object as sensitive.
pool := poolparty.NewPool(bip44.Bitcoin)
if err := pool.GenerateMnemonic(256, "optional-passphrase"); err != nil {
log.Fatal(err)
}
addresses, err := pool.GeneratePublicAddressPool(0, 10)
if err != nil {
log.Fatal(err)
}
fmt.Println(addresses[0].Address)- Ethereum
- Energi
- Bitcoin
- Litecoin
- Dash
- Dogecoin
Pool Party derives receive addresses with:
m/44'/coin_type'/0'/0/index
The modernized implementation uses github.com/btcsuite/btcd/btcutil/hdkeychain.ExtendedKey.Derive, which follows the standard BIP32 behavior. Older btcsuite Child behavior was renamed upstream to DeriveNonStandard because it was affected by btcsuite issue #172. This means some address vectors can differ from old Pool Party releases that used Child.
bip39.NewSeed normalizes both the mnemonic and optional password with Unicode NFKD before PBKDF2, matching BIP39. This is the right path for new wallets.
Older Pool Party releases did not normalize these inputs. Users with only ASCII mnemonics and passphrases are unaffected because ASCII is unchanged by NFKD. Users who created wallets with non-ASCII characters, such as accents or combining marks, should try both derivation paths during recovery:
standardSeed := bip39.NewSeed(mnemonic, passphrase)
legacySeed := bip39.NewSeedLegacy(mnemonic, passphrase)Use the seed that reproduces the known address history, then migrate operational tooling to NewSeed for new wallets.
bip39.SetWordList accepts only well-formed BIP39 word lists: exactly 2048 unique non-empty words. It returns bip39.ErrWordListInvalid and leaves the active word list unchanged when validation fails.
go test -mod=readonly ./...
go vet ./...
go list -m -u allUse rtk before commands in this workspace:
rtk go test -mod=readonly ./...
rtk go vet ./...This library performs deterministic key derivation locally. It does not encrypt secrets, manage secure storage, wipe memory, or broadcast transactions. Applications using it are responsible for secure mnemonic/private-key lifecycle management.
See docs/AUDIT.md and docs/MODERNIZATION_PLAN.md for the current audit and maintenance plan.