Documentation
¶
Overview ¶
Package hdwallet is a Trust Wallet-compatible hierarchical-deterministic wallet for Go.
It generates a BIP-39 mnemonic (or imports one) and derives receive addresses for many networks using the same derivation paths and address formats Trust Wallet uses by default, so seeds are interchangeable between the two.
Secrets (the mnemonic and the derived seed) are never held as plain Go strings or long-lived byte slices. They are stored in encrypted, page-locked memguard enclaves and decrypted only for the duration of a single derivation. Always call (*HDWallet).Destroy when finished, and consider memguard.Purge on program exit.
Index ¶
- Constants
- Variables
- func ABIEncode(name string, args []ABIValue) ([]byte, error)
- func ABIEncodeParams(values []ABIValue) ([]byte, error)
- func ABIFunctionSelector(name string, types []string) []byte
- func AddressFromPublicKey(symbol Symbol, pub []byte) (string, error)
- func BuildPSBT(symbol Symbol, in *txbtc.SigningInput) ([]byte, error)
- func EIP712Hash(typedDataJSON []byte) ([]byte, error)
- func EncodeRLP(item RLPItem) []byte
- func EstimateBitcoinFee(inputs []BitcoinInputKind, outputs []BitcoinOutputKind, satPerVbyte int64) int64
- func EstimateTxVsize(inputs []BitcoinInputKind, outputs []BitcoinOutputKind) int64
- func EthereumPersonalMessageHash(message []byte) []byte
- func ExtractPSBTTx(psbtBytes []byte) ([]byte, error)
- func FinalizePSBT(psbtBytes []byte) ([]byte, error)
- func GenerateMnemonic() (string, error)
- func GenerateMnemonicWithWordCount(words int) (string, error)
- func IsValidAddress(symbol Symbol, addr string) bool
- func ParseAddress(symbol Symbol, addr string) ([]byte, error)
- func RecoverEthereumAddress(message, sig []byte) (string, error)
- func ValidateAddress(symbol Symbol, addr string) error
- func Verify(curve Curve, pub, data []byte, sig *Signature) bool
- func VerifyBitcoinMessage(address string, message []byte, sigBase64 string) bool
- func VerifyEthereumMessage(addressOrPubKey string, message, sig []byte) bool
- func VerifyEthereumTypedData(addressOrPubKey string, typedDataJSON, sig []byte) bool
- func VerifySignature(symbol Symbol, pub, data []byte, sig *Signature) (bool, error)
- func VerifySolanaMessage(address string, message []byte, sigBase58 string) bool
- type ABIValue
- type BitcoinAddressType
- type BitcoinInputKind
- type BitcoinOutputKind
- type BtcTxFields
- type BtcVin
- type BtcVout
- type Coin
- type CosmosCoin
- type CosmosMessage
- type CosmosTxFields
- type Curve
- type ERC20Call
- type EthAccessTuple
- type EthTxFields
- type EthTxType
- type HDWallet
- func FromMnemonic(mnemonic string) (*HDWallet, error)
- func FromMnemonicBuffer(buf *memguard.LockedBuffer) (*HDWallet, error)
- func FromMnemonicBufferWithPassphrase(buf, passphrase *memguard.LockedBuffer) (*HDWallet, error)
- func FromMnemonicBytes(mnemonic []byte) (*HDWallet, error)
- func FromMnemonicWithPassphrase(mnemonic, passphrase []byte) (*HDWallet, error)
- func FromPrivateKeyBuffer(buf *memguard.LockedBuffer, curve Curve) (*HDWallet, error)
- func FromPrivateKeyBytes(priv []byte, curve Curve) (*HDWallet, error)
- func FromWIF(wif []byte) (*HDWallet, error)
- func NewHDWallet() (*HDWallet, error)
- func NewHDWalletWithEntropy(bits int) (*HDWallet, error)
- func NewHDWalletWithWordCount(words int) (*HDWallet, error)
- func (w *HDWallet) AccountXPub(symbol Symbol, account uint32) (string, error)
- func (w *HDWallet) Address(symbol Symbol) (string, error)
- func (w *HDWallet) AddressAt(symbol Symbol, account, change, index uint32) (string, error)
- func (w *HDWallet) AddressIndex(symbol Symbol, index uint32) (string, error)
- func (w *HDWallet) AddressPath(symbol Symbol, path string) (string, error)
- func (w *HDWallet) AddressRange(symbol Symbol, start, count uint32) ([]string, error)
- func (w *HDWallet) AllAddresses() (map[Symbol]string, error)
- func (w *HDWallet) AllAddressesAt(index uint32) (map[Symbol]string, error)
- func (w *HDWallet) BitcoinAddress(symbol Symbol, t BitcoinAddressType, account, change, index uint32) (string, error)
- func (w *HDWallet) Destroy()
- func (w *HDWallet) Mnemonic() (*memguard.LockedBuffer, error)
- func (w *HDWallet) PrivateKey(symbol Symbol, index uint32) (*memguard.LockedBuffer, error)
- func (w *HDWallet) PrivateKeyPath(symbol Symbol, path string) (*memguard.LockedBuffer, error)
- func (w *HDWallet) PublicKey(symbol Symbol) ([]byte, error)
- func (w *HDWallet) PublicKeyAt(symbol Symbol, account, change, index uint32) ([]byte, error)
- func (w *HDWallet) PublicKeyIndex(symbol Symbol, index uint32) ([]byte, error)
- func (w *HDWallet) PublicKeyPath(symbol Symbol, path string) ([]byte, error)
- func (w *HDWallet) Sign(symbol Symbol, data []byte) (*Signature, error)
- func (w *HDWallet) SignAt(symbol Symbol, account, change, index uint32, data []byte) (*Signature, error)
- func (w *HDWallet) SignBitcoinMessage(symbol Symbol, index uint32, message []byte) (string, error)
- func (w *HDWallet) SignIndex(symbol Symbol, index uint32, data []byte) (*Signature, error)
- func (w *HDWallet) SignMessage(symbol Symbol, index uint32, message []byte) ([]byte, error)
- func (w *HDWallet) SignPSBT(symbol Symbol, index uint32, psbtBytes []byte) ([]byte, error)
- func (w *HDWallet) SignPath(symbol Symbol, path string, data []byte) (*Signature, error)
- func (w *HDWallet) SignSolanaMessage(symbol Symbol, index uint32, message []byte) (string, error)
- func (w *HDWallet) SignTransaction(symbol Symbol, index uint32, input proto.Message) (proto.Message, error)
- func (w *HDWallet) SignTypedData(symbol Symbol, index uint32, typedDataJSON []byte) ([]byte, error)
- func (w *HDWallet) WIF(symbol Symbol, index uint32) (*memguard.LockedBuffer, error)
- func (w *HDWallet) WithAccountXPrv(symbol Symbol, account uint32, fn func(xprv []byte) error) error
- func (w *HDWallet) WithMnemonic(fn func(mnemonic []byte) error) error
- func (w *HDWallet) WithPrivateKey(symbol Symbol, index uint32, fn func(priv []byte) error) error
- func (w *HDWallet) WithPrivateKeyPath(symbol Symbol, path string, fn func(priv []byte) error) error
- func (w *HDWallet) WithWIF(symbol Symbol, index uint32, fn func(wif []byte) error) error
- type RLPItem
- type Signature
- type SolanaInstruction
- type SolanaTxFields
- type Symbol
- type TronContract
- type TronTxFields
- type WatchWallet
- type XrpTxFields
Examples ¶
Constants ¶
const ( EthTxModeLegacy uint32 = 0 // EIP-155 legacy EthTxModeEIP2930 uint32 = 1 // type-1 access-list EthTxModeEIP1559 uint32 = 2 // type-2 fee market )
EVM transaction modes, selecting the serialization format produced by SignTransaction for an EVM chain. They are the values of ethereum.SigningInput.tx_mode; use them instead of bare integers.
Variables ¶
var ( // ErrABIType is returned for an unrecognized or unsupported ABI type string. ErrABIType = errors.New("hdwallet: unsupported ABI type") // ErrABIValue is returned when a Go value does not match its ABI type. ErrABIValue = errors.New("hdwallet: ABI value does not match type") // ErrABIDecode is returned when ABI-encoded input is malformed. ErrABIDecode = errors.New("hdwallet: malformed ABI encoding") )
ABI-related errors.
var ( // ErrRLPCanonical is returned when a decoded item is not in canonical form // (e.g. a leading zero in a length prefix, or a single byte < 0x80 wrapped in // a string header). Ethereum requires canonical RLP. ErrRLPCanonical = errors.New("hdwallet: non-canonical RLP encoding") // ErrRLPTruncated is returned when the input ends before a declared length. ErrRLPTruncated = errors.New("hdwallet: truncated RLP input") // ErrRLPTrailing is returned by DecodeRLP when bytes remain after one item. ErrRLPTrailing = errors.New("hdwallet: trailing bytes after RLP item") )
RLP-related errors.
var ( // ErrInvalidMnemonic is returned when a mnemonic fails BIP-39 validation. ErrInvalidMnemonic = errors.New("hdwallet: invalid mnemonic") // ErrUnsupportedCoin is returned for a symbol not in the registry. ErrUnsupportedCoin = errors.New("hdwallet: unsupported coin") // ErrDestroyed is returned by operations on a wallet whose secrets were wiped. ErrDestroyed = errors.New("hdwallet: wallet has been destroyed") // ErrInvalidDigest is returned when an ECDSA signing input is not 32 bytes. ErrInvalidDigest = errors.New("hdwallet: digest must be 32 bytes") // ErrInvalidPrivateKey is returned when an imported private key has the wrong // length or is otherwise invalid for its curve. ErrInvalidPrivateKey = errors.New("hdwallet: invalid private key") // ErrUnsupportedCurve is returned when a curve is not one of the supported // elliptic curves. ErrUnsupportedCurve = errors.New("hdwallet: unsupported curve") // ErrCurveMismatch is returned when an operation targets a coin whose curve // differs from the curve of a key-only wallet's imported private key. ErrCurveMismatch = errors.New("hdwallet: coin curve does not match imported key curve") // ErrKeyOnlyWallet is returned by mnemonic/seed-only operations (Mnemonic, // WithMnemonic, AllAddresses) on a wallet imported from a raw private key. ErrKeyOnlyWallet = errors.New("hdwallet: operation not available on a private-key-only wallet") // ErrKeyOnlyIndex is returned when a non-zero address/sign index is requested // on a key-only wallet, which has a single leaf key and no HD path. ErrKeyOnlyIndex = errors.New("hdwallet: private-key-only wallet supports only index 0") // ErrPathArity is returned by the structured account/change/index helpers // (AddressAt, SignAt, PublicKeyAt) when a coin's path template is not a // 5-element BIP-44/BIP-84 path; use the AddressPath/SignPath primitives instead. ErrPathArity = errors.New("hdwallet: coin path is not a 5-element BIP-44/84 path; use the *Path methods") // ErrExtKeyUnsupportedCurve is returned by the extended-key (xprv/xpub) and // watch-only APIs for a non-secp256k1 coin: BIP-32 extended keys and public // (non-hardened) child derivation apply only to secp256k1; the SLIP-0010 // ed25519/nist256p1 schemes support hardened derivation only. ErrExtKeyUnsupportedCurve = errors.New("hdwallet: extended keys / watch-only require a secp256k1 coin") // ErrInvalidWordCount is returned when a requested mnemonic length is not a // valid BIP-39 word count (12, 15, 18, 21, or 24) or entropy size in bits // (128, 160, 192, 224, or 256). ErrInvalidWordCount = errors.New("hdwallet: invalid mnemonic word count") )
Exported sentinel errors. Consumers can match them with errors.Is; errors that add context (e.g. the offending symbol) wrap these with %w.
var ( // ErrTxUnsupported is returned when SignTransaction is asked to sign for a // symbol whose family has no transaction builder. ErrTxUnsupported = errors.New("hdwallet: transaction signing not supported for coin") // ErrTxInput is returned when the SigningInput proto type does not match the // family selected by symbol, or a required field is missing/invalid. ErrTxInput = errors.New("hdwallet: invalid transaction signing input") )
Transaction-signing errors.
var ( // ErrEIP712 is returned for malformed typed data or unsupported types. ErrEIP712 = errors.New("hdwallet: invalid EIP-712 typed data") )
EIP-712-related errors.
var ( // ErrEthSignature is returned when an Ethereum signature is malformed. ErrEthSignature = errors.New("hdwallet: invalid ethereum signature") )
Ethereum message errors.
var ErrInvalidAddress = errors.New("hdwallet: invalid address")
ErrInvalidAddress is the base sentinel for all address-validation failures. Specific reasons (bad checksum, wrong prefix, wrong length, …) wrap it with %w, so errors.Is(err, ErrInvalidAddress) matches any validation failure while the message still describes the precise cause.
var ErrInvalidWIF = errors.New("hdwallet: invalid WIF private key")
ErrInvalidWIF is returned for a malformed WIF string or a WIF export requested for a non-secp256k1 coin.
var ErrNotRecoverable = errors.New("hdwallet: coin curve does not support recoverable signatures")
ErrNotRecoverable is returned by SignBitcoinMessage when the coin's curve is not secp256k1 (only secp256k1 produces a recoverable signature).
var ErrTxDecode = errors.New("hdwallet: malformed transaction bytes")
ErrTxDecode is returned when raw transaction bytes are malformed, truncated or otherwise not a transaction this decoder understands. The decoder never panics and never reads past the input.
Functions ¶
func ABIEncode ¶ added in v0.2.2
ABIEncode encodes a function call: selector(name,types...) || head/tail(args). The signature is formed from name and the argument types, so name must be the bare function name (e.g. "transfer"), not the full signature.
func ABIEncodeParams ¶ added in v0.2.2
ABIEncodeParams encodes a tuple of values (no selector) using the head/tail layout. This is the encoding used for the arguments of a call and for nested tuples/arrays.
func ABIFunctionSelector ¶ added in v0.2.2
ABIFunctionSelector returns the 4-byte selector for a function signature built from name and the given argument types (the canonical forms are used).
func AddressFromPublicKey ¶ added in v0.2.2
AddressFromPublicKey derives the address for symbol directly from an external public key, reusing the registry's encoder (read-only). pub must be the curve's expected public-key form: a 33-byte compressed key for secp256k1/nist256p1, or a 32-byte key for ed25519. An unknown symbol returns ErrUnsupportedCoin; a malformed key is reported by the underlying encoder.
func BuildPSBT ¶ added in v0.6.0
func BuildPSBT(symbol Symbol, in *txbtc.SigningInput) ([]byte, error)
BuildPSBT builds an unsigned PSBT (BIP-174) for symbol from in, returning the serialized packet. Coin selection (planBitcoinTx) chooses which UTXOs become inputs and computes the recipient/change outputs exactly as the direct signer would, so a subsequent SignPSBT/FinalizePSBT/ExtractPSBTTx produces the same transaction. Every chosen input must be a segwit type (P2WPKH, P2SH-P2WPKH or P2TR); a legacy P2PKH input returns ErrTxInput.
func EIP712Hash ¶ added in v0.2.2
EIP712Hash parses MetaMask-shape typed-data JSON and returns the 32-byte keccak256 digest to sign (the 0x1901-prefixed hash).
func EstimateBitcoinFee ¶ added in v0.6.0
func EstimateBitcoinFee(inputs []BitcoinInputKind, outputs []BitcoinOutputKind, satPerVbyte int64) int64
EstimateBitcoinFee returns the estimated fee (satoshis) for a transaction of the given input/output kinds at satPerVbyte sat/vbyte. It is fee-planning guidance, not a consensus value: fee = EstimateTxVsize * satPerVbyte.
func EstimateTxVsize ¶ added in v0.6.0
func EstimateTxVsize(inputs []BitcoinInputKind, outputs []BitcoinOutputKind) int64
EstimateTxVsize returns an approximate virtual size (vbytes) for a transaction spending the given input kinds to the given output kinds. It is a coarse estimate for fee planning only (not consensus-exact): per-type constants are measured against btcd's blockchain/txsizes, with a fixed overhead for the version, locktime, the input/output counts and the amortised SegWit marker/flag when any input carries a witness.
ponytail: coarse per-type constants, good enough for fee math; refine if fee-rate accuracy ever matters.
func EthereumPersonalMessageHash ¶ added in v0.2.2
EthereumPersonalMessageHash returns the 32-byte keccak256 digest that EIP-191 personal_sign signs for the given message. len(message) is rendered as its decimal ASCII representation, per the standard.
func ExtractPSBTTx ¶ added in v0.6.0
ExtractPSBTTx finalizes (if needed) and extracts the network-serialized signed transaction from a signed PSBT.
func FinalizePSBT ¶ added in v0.6.0
FinalizePSBT runs the BIP-174 Finalizer over a fully signed packet and returns the finalized serialized PSBT.
func GenerateMnemonic ¶
GenerateMnemonic returns a fresh 12-word BIP-39 mnemonic as a string.
The returned string cannot be securely wiped; for sensitive use derive a wallet with NewHDWallet (which keeps the mnemonic in protected memory) and read it back via Mnemonic or WithMnemonic only when required.
func GenerateMnemonicWithWordCount ¶ added in v0.3.1
GenerateMnemonicWithWordCount returns a fresh BIP-39 mnemonic of the given length in words (12, 15, 18, 21, or 24) as a string. Like GenerateMnemonic, the returned string cannot be securely wiped; prefer NewHDWalletWithWordCount for sensitive use. An unsupported word count returns an error wrapping ErrInvalidWordCount.
func IsValidAddress ¶ added in v0.2.2
IsValidAddress reports whether addr is a syntactically and checksum-valid address for the given network. It is a convenience wrapper over ValidateAddress.
func ParseAddress ¶ added in v0.2.2
ParseAddress decodes addr for symbol, verifies its checksum, and returns the decoded payload — e.g. the 20-byte hash160 for Bitcoin/Cosmos/Tron, the 32-byte public key for Solana/Stellar/SS58, or the 20/32-byte account identifier for EVM/Sui/Aptos. An unknown symbol returns ErrUnsupportedCoin; an invalid address returns an error wrapping ErrInvalidAddress.
func RecoverEthereumAddress ¶ added in v0.2.2
RecoverEthereumAddress recovers the EIP-55 checksummed Ethereum address that produced sig over message under EIP-191 personal_sign. It is a convenience for callers that want the signer's address rather than a boolean match.
func ValidateAddress ¶ added in v0.2.2
ValidateAddress returns nil if addr is a valid address for symbol, or a descriptive error wrapping ErrInvalidAddress (bad checksum, wrong prefix, wrong length, …) or ErrUnsupportedCoin for an unknown symbol.
func Verify ¶ added in v0.2.0
Verify reports whether sig is a valid signature of data by the public key pub on the given curve. For ECDSA curves data is the 32-byte digest that was signed; for ed25519 it is the message.
func VerifyBitcoinMessage ¶ added in v0.3.1
VerifyBitcoinMessage reports whether sigBase64 is a valid Bitcoin signed-message signature of message by the key behind a legacy P2PKH (base58check, "1"-prefix) address. It recovers the public key from the compact signature and checks its legacy address equals address.
func VerifyEthereumMessage ¶ added in v0.2.2
VerifyEthereumMessage reports whether sig (65-byte r||s||v, v in {27,28} or {0,1}) is a valid EIP-191 personal_sign signature of message by the signer identified by addressOrPubKey. addressOrPubKey may be a 0x-hex Ethereum address (20 bytes), or a hex/raw secp256k1 public key (33-byte compressed or 65-byte uncompressed). It ecrecovers the signer and compares.
func VerifyEthereumTypedData ¶ added in v0.2.2
VerifyEthereumTypedData is the EIP-712 counterpart of VerifyEthereumMessage.
func VerifySignature ¶ added in v0.8.0
VerifySignature reports whether sig is a valid signature of data by the public key pub for the coin symbol. It is the Symbol-keyed counterpart to Sign: the curve is resolved from the registry rather than supplied directly.
As with Sign/SignIndex, data is the 32-byte digest for ECDSA chains (secp256k1, nist256p1, starkex) and the raw message for ed25519 chains. A non-32-byte input for an ECDSA chain returns a wrapped ErrInvalidDigest, mirroring SignIndex; an unknown symbol returns a wrapped ErrUnsupportedCoin.
It needs no secret and so is a free function, not a wallet method.
func VerifySolanaMessage ¶ added in v0.3.1
VerifySolanaMessage reports whether sigBase58 is a valid Solana off-chain message signature for message under the given base58 account address (which is itself the 32-byte ed25519 public key).
Types ¶
type ABIValue ¶ added in v0.2.2
ABIValue is one ABI argument: Type is the canonical type string (e.g. "uint256", "address", "bytes", "uint256[]", "(address,uint256)") and Value is the Go value:
address, bytesN, bytes, string -> []byte uint*/int* -> *big.Int bool -> bool arrays, tuples -> []ABIValue (elements/fields)
type BitcoinAddressType ¶ added in v0.5.0
type BitcoinAddressType int
BitcoinAddressType selects which standard Bitcoin script/address format BitcoinAddress produces. Each maps to a BIP "purpose" derivation path.
const ( // P2PKH is a legacy pay-to-public-key-hash address (base58check, "1..."), // derived under BIP-44 (m/44'). P2PKH BitcoinAddressType = iota // P2SHP2WPKH is a nested SegWit pay-to-witness-public-key-hash wrapped in // pay-to-script-hash (base58check, "3..."), derived under BIP-49 (m/49'). P2SHP2WPKH // P2WPKH is a native SegWit v0 address (bech32, "bc1q..."), derived under // BIP-84 (m/84'). This is the registry default for BTC/LTC. P2WPKH // P2TR is a Taproot v1 key-path address (bech32m, "bc1p..."), derived under // BIP-86 (m/86'). P2TR )
func (BitcoinAddressType) String ¶ added in v0.5.0
func (t BitcoinAddressType) String() string
String returns a short human-readable name for the address type.
type BitcoinInputKind ¶ added in v0.6.0
type BitcoinInputKind int
BitcoinInputKind identifies the script type of an input being spent, for the fee/size estimator (EstimateTxVsize / EstimateBitcoinFee).
const ( // InputP2PKH is a legacy pay-to-pubkey-hash input (no witness). InputP2PKH BitcoinInputKind = iota // InputP2SHP2WPKH is a nested SegWit (BIP-49) P2SH-P2WPKH input. InputP2SHP2WPKH // InputP2WPKH is a native SegWit v0 P2WPKH input. InputP2WPKH // InputP2TR is a Taproot key-path P2TR input. InputP2TR )
type BitcoinOutputKind ¶ added in v0.6.0
type BitcoinOutputKind int
BitcoinOutputKind identifies the script type of an output, for the fee/size estimator.
const ( // OutputP2PKH is a legacy pay-to-pubkey-hash output (25-byte script). OutputP2PKH BitcoinOutputKind = iota // OutputP2SH is a pay-to-script-hash output (23-byte script). OutputP2SH // OutputP2WPKH is a native SegWit v0 P2WPKH output (22-byte script). OutputP2WPKH // OutputP2TR is a Taproot P2TR output (34-byte script). OutputP2TR )
type BtcTxFields ¶ added in v0.6.0
type BtcTxFields struct {
Version int32
Vin []BtcVin
Vout []BtcVout
LockTime uint32
HasWitness bool
}
BtcTxFields holds the decoded, display-ready fields of a Bitcoin-family transaction.
func DecodeBitcoinTx ¶ added in v0.6.0
func DecodeBitcoinTx(symbol Symbol, raw []byte) (*BtcTxFields, error)
DecodeBitcoinTx decodes a raw Bitcoin-family transaction (signed or unsigned) for symbol, whose btcAddrParams select the HRP / version bytes used to render output addresses. Malformed or truncated input returns ErrTxDecode; the function never panics and never reads past `raw`.
type BtcVin ¶ added in v0.6.0
type BtcVin struct {
TxID string // 32-byte prev txid, big-endian hex (explorer order)
Vout uint32
Sequence uint32
}
BtcVin is one decoded transaction input. TxID is rendered big-endian (the display/explorer order, reversed from the internal little-endian wire order).
type BtcVout ¶ added in v0.6.0
type BtcVout struct {
Value int64 // satoshis
ScriptHex string // scriptPubKey, hex
Address string // rendered address, empty if nonstandard
Type string // "p2pkh" / "p2sh" / "p2wpkh" / "p2tr" / "nonstandard"
}
BtcVout is one decoded transaction output. Address is the rendered destination for a recognised standard script (empty with Type "nonstandard" otherwise).
type Coin ¶
type Coin struct {
Name string
Symbol Symbol
Curve Curve
Path string
Encode func(pub []byte) (string, error)
Decimals uint8
ChainID uint64
}
Coin describes a supported network: its curve, BIP-32 derivation path, and the function that turns a derived public key into an address string. Adding a network is a single entry in the registry below.
Decimals is the number of fractional digits in the chain's native unit (e.g. 8 for Bitcoin satoshis, 18 for Ethereum wei, 6 for Cosmos uatom) and is used to format on-chain balances. ChainID is the EIP-155 numeric chain id used to build EVM transactions; it is non-zero only for EVM chains (the evmTxChains set in tx_families.go) and 0 for every non-EVM coin. Both mirror the Trust Wallet Core coins registry. The SLIP-44 coin type is NOT stored — it is derived from Path via the SLIP44 method below.
func (Coin) SLIP44 ¶ added in v0.6.0
SLIP44 returns the SLIP-44 coin type for the coin, derived from the second element of its BIP-32 Path (e.g. "m/44'/60'/0'/0/0" → 60). The hardened flag is stripped. It is computed from Path rather than stored separately so the two can never drift; a malformed path returns 0.
type CosmosCoin ¶ added in v0.8.0
CosmosCoin is one decoded { denom, amount } coin (amount is a decimal string, the on-wire Cosmos representation).
type CosmosMessage ¶ added in v0.8.0
type CosmosMessage struct {
TypeURL string
// MsgSend.
FromAddress string
ToAddress string
// MsgDelegate / MsgUndelegate / MsgWithdrawDelegatorReward.
DelegatorAddress string
ValidatorAddress string
// Amount: MsgSend carries a repeated coin set; MsgDelegate / MsgUndelegate
// carry a single coin (one element). MsgWithdrawReward carries none.
Amount []CosmosCoin
}
CosmosMessage is one decoded transaction message. TypeURL is always set; the remaining fields are populated according to the message type (only the relevant subset is non-empty).
type CosmosTxFields ¶ added in v0.8.0
type CosmosTxFields struct {
Messages []CosmosMessage
Memo string
FeeAmount []CosmosCoin
GasLimit uint64
Sequence uint64
Signatures [][]byte
}
CosmosTxFields holds the decoded, display-ready fields of a Cosmos transaction.
func DecodeCosmosTx ¶ added in v0.8.0
func DecodeCosmosTx(raw []byte) (*CosmosTxFields, error)
DecodeCosmosTx decodes a raw (broadcast) Cosmos TxRaw blob into its display fields. Malformed or truncated input returns ErrTxDecode; the function never panics.
type Curve ¶
type Curve int
Curve identifies the elliptic curve a coin derives keys on. Each curve has a distinct derivation scheme (BIP-32 for secp256k1, SLIP-0010 for the others).
const ( // Secp256k1 covers Bitcoin-style, Ethereum/EVM, Cosmos, XRP and Tron. Secp256k1 Curve = iota // Ed25519 covers Solana, Stellar, Polkadot, NEAR, Algorand, Sui, Aptos, Tezos. Ed25519 // Nist256p1 (NIST P-256) covers NEO. Nist256p1 // Ed25519Blake2bNano is the ed25519 EdDSA variant Nano uses: identical to // ed25519 except the internal 512-bit hash is BLAKE2b-512 instead of SHA-512 // (both for key expansion and the R/challenge hashes). SLIP-0010 ed25519 // derivation is used for the leaf private key. Matches Trust Wallet Core's // TWCurveED25519Blake2bNano. Ed25519Blake2bNano // Curve25519 is the public-key/signing scheme Waves uses: the leaf private // key is derived via SLIP-0010 ed25519, the public key is the X25519 // (Montgomery) point, and signing is ed25519 with the public-key sign bit // folded into S[63] (the "curve25519_sign" construction). Matches Trust // Wallet Core's TWCurveCurve25519. Curve25519 // Ed25519ExtendedCardano is BIP32-Ed25519 (CIP-1852) with 64-byte extended // private keys, as used by Cardano. The master secret comes from the Icarus // (PBKDF2-HMAC-SHA512 over the BIP-39 entropy) scheme. Matches Trust Wallet // Core's TWCurveED25519ExtendedCardano. Ed25519ExtendedCardano // Starkex is the STARK curve (StarkNet/StarkEx), EIP-2645 key derivation with // grinding, RFC-6979 deterministic ECDSA. Matches Trust Wallet Core's // TWCurveStarkex. Starkex // Sr25519 is schnorrkel/ristretto255, the native key scheme for // Polkadot/Kusama. NOTE: this is NOT part of Trust Wallet Core's curve set // (TWC uses plain ed25519 for Polkadot); it is provided here as an additional // curve for native substrate signing. Sr25519 )
type ERC20Call ¶ added in v0.6.0
type ERC20Call struct {
Method string // "transfer" or "approve"
Recipient string // "0x"-prefixed 20-byte address (the `to`/`spender`)
Amount *big.Int // the uint256 amount
}
ERC20Call is a decoded ERC-20 method call recognised in the transaction's calldata (transfer or approve). It is nil on EthTxFields unless the calldata's 4-byte selector and shape match one of those methods.
type EthAccessTuple ¶ added in v0.6.0
type EthAccessTuple struct {
Address string // "0x"-prefixed 20-byte address
StorageKeys [][]byte // each 32 bytes
}
EthAccessTuple is one decoded EIP-2930 access-list entry: the accessed address (0x-hex) and the 32-byte storage keys accessed under it.
type EthTxFields ¶ added in v0.6.0
type EthTxFields struct {
Type EthTxType
ChainID *big.Int
Nonce *big.Int
GasPrice *big.Int // legacy + 2930
MaxPriorityFeePerGas *big.Int // 1559
MaxFeePerGas *big.Int // 1559
GasLimit *big.Int
To string // "0x"-hex; empty = contract creation
Value *big.Int
Data []byte
AccessList []EthAccessTuple // 2930 + 1559
// Signature scalars (present in a signed tx). YParity is the bare recovery id
// (0/1) for typed txs; for legacy it is the raw v as a *big.Int.
V *big.Int
R *big.Int
S *big.Int
// ERC20 is set when Data decodes to a recognised ERC-20 transfer/approve call.
ERC20 *ERC20Call
}
EthTxFields holds the decoded, display-ready fields of an EVM transaction. Numeric quantities are *big.Int (nil means absent/zero); To is a "0x"-prefixed hex address, empty for contract creation. The fields populated depend on Type: MaxPriorityFeePerGas/MaxFeePerGas/AccessList are EIP-1559/2930 only, GasPrice is legacy/2930 only, ChainID is decoded for all (derived from v via EIP-155 for a legacy tx whose v >= 35; nil for a legacy tx with the pre-155 v of 27/28).
func DecodeEthereumTx ¶ added in v0.6.0
func DecodeEthereumTx(raw []byte) (*EthTxFields, error)
DecodeEthereumTx decodes a raw EVM transaction (signed or unsigned) into its display fields. It branches on the first byte: 0x02 => EIP-1559, 0x01 => EIP-2930, any byte >= 0xc0 (an RLP list prefix) => legacy. Malformed or truncated input returns ErrTxDecode; the function never panics.
type EthTxType ¶ added in v0.6.0
type EthTxType int
EthTxType identifies the EVM transaction envelope a raw blob decoded as.
type HDWallet ¶
type HDWallet struct {
// contains filtered or unexported fields
}
HDWallet is an HD wallet derived from a BIP-39 mnemonic. Its sensitive material is protected in memory; see the package documentation. All methods are safe for concurrent use.
func FromMnemonic ¶
FromMnemonic builds a wallet from an existing 12/24-word mnemonic string.
Prefer FromMnemonicBytes where possible: a Go string cannot be wiped from memory, so any mnemonic held as a string lingers until garbage-collected.
func FromMnemonicBuffer ¶
func FromMnemonicBuffer(buf *memguard.LockedBuffer) (*HDWallet, error)
FromMnemonicBuffer builds a wallet from a mnemonic held in a memguard LockedBuffer. This is the most secure entry point: the mnemonic stays in page-locked, encrypted-at-rest memory from your code all the way into the wallet's sealed enclave, with no intermediate plaintext copy on the Go heap.
The wallet takes ownership of buf and destroys it; do not use buf afterwards. Surrounding whitespace in the buffer is trimmed before use.
It uses the empty BIP-39 passphrase (Trust Wallet's default). For a passphrase-protected wallet, use FromMnemonicBufferWithPassphrase.
Example ¶
ExampleFromMnemonicBuffer shows the most secure way to import a mnemonic: the phrase lives in a page-locked, encrypted memguard buffer and is handed to the wallet without an intermediate plaintext copy. The wallet takes ownership of the buffer and destroys it.
package main
import (
"fmt"
"log"
"github.com/awnumar/memguard"
hdwallet "github.com/ranjbar-dev/hd-wallet"
)
// exampleMnemonic is the standard BIP-39 test vector mnemonic. Never hard-code a
// real mnemonic in source; this one holds no funds and is used only for docs.
const exampleMnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
func main() {
// In real code, read the mnemonic straight into protected memory (for
// example with memguard.NewBufferFromReaderUntil over stdin).
buf := memguard.NewBufferFromBytes([]byte(exampleMnemonic))
w, err := hdwallet.FromMnemonicBuffer(buf)
if err != nil {
log.Fatal(err)
}
defer w.Destroy()
addr, _ := w.Address(hdwallet.BTC)
fmt.Println(addr)
}
Output: bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu
func FromMnemonicBufferWithPassphrase ¶ added in v0.3.0
func FromMnemonicBufferWithPassphrase(buf, passphrase *memguard.LockedBuffer) (*HDWallet, error)
FromMnemonicBufferWithPassphrase is the most secure passphrase entry point: both the mnemonic and the BIP-39 passphrase are supplied in page-locked, encrypted-at-rest memguard buffers and used without an intermediate plaintext heap copy (aside from the unavoidable transient BIP-39 string conversion).
The wallet takes ownership of both buffers and destroys them; do not use either afterwards. passphrase may be nil for the empty passphrase. Surrounding whitespace in the mnemonic buffer is trimmed; the passphrase is used verbatim.
func FromMnemonicBytes ¶
FromMnemonicBytes builds a wallet from a mnemonic held in a byte slice. The slice is wiped before the function returns; callers must not reuse it.
It uses the empty BIP-39 passphrase (Trust Wallet's default). For a passphrase-protected ("hidden") wallet, use FromMnemonicWithPassphrase.
func FromMnemonicWithPassphrase ¶ added in v0.3.0
FromMnemonicWithPassphrase builds a wallet from a mnemonic and an optional BIP-39 passphrase (the "25th word"), both held in byte slices. A different passphrase derives a completely different set of addresses from the same mnemonic; the empty passphrase (nil or empty slice) matches FromMnemonicBytes and Trust Wallet's default.
Both slices are wiped before the function returns; callers must not reuse them. Like the mnemonic, the passphrase is briefly converted to a Go string internally for BIP-39 seed derivation (see the package secret-handling notes).
func FromPrivateKeyBuffer ¶ added in v0.2.2
func FromPrivateKeyBuffer(buf *memguard.LockedBuffer, curve Curve) (*HDWallet, error)
FromPrivateKeyBuffer builds a key-only wallet from a raw private key held in a memguard LockedBuffer. This is the most secure key-import entry point: the key stays in page-locked, encrypted-at-rest memory from your code all the way into the wallet's sealed enclave, with no intermediate plaintext copy on the Go heap (mirrors FromMnemonicBuffer).
The wallet takes ownership of buf and destroys it; do not use buf afterwards. See FromPrivateKeyBytes for the semantics of a key-only wallet.
func FromPrivateKeyBytes ¶ added in v0.2.2
FromPrivateKeyBytes builds a key-only wallet from a raw private key held in a byte slice. The slice is wiped before this function returns; callers must not reuse it (mirrors FromMnemonicBytes).
curve identifies the elliptic curve the key belongs to (Secp256k1, Ed25519, or Nist256p1). The resulting wallet can derive addresses, public keys, sign, and export the key for any registered coin whose curve matches; mismatched-curve coins return ErrCurveMismatch. A key-only wallet has no HD path — the imported key is the leaf — so only index 0 is valid and there is no mnemonic to read (Mnemonic/WithMnemonic/AllAddresses return ErrKeyOnlyWallet).
The key must be exactly 32 bytes and non-zero, or ErrInvalidPrivateKey is returned.
func FromWIF ¶ added in v0.3.0
FromWIF builds a key-only secp256k1 wallet from a Bitcoin WIF private key held in a byte slice. The slice is wiped before returning; callers must not reuse it. Both compressed and uncompressed mainnet (0x80) WIF are accepted, and the imported key may then be used with any secp256k1 coin.
Like the mnemonic path, the WIF is briefly converted to a Go string internally for base58 decoding (it cannot be wiped and is GC-bounded).
func NewHDWallet ¶
NewHDWallet creates a wallet with a fresh 12-word (128-bit) mnemonic. It is a convenience wrapper over NewHDWalletWithWordCount(12).
Example ¶
ExampleNewHDWallet creates a wallet with a fresh, random mnemonic and derives an address. Output is omitted because the mnemonic (and therefore the address) is random on every run.
package main
import (
"fmt"
"log"
"strings"
hdwallet "github.com/ranjbar-dev/hd-wallet"
)
func main() {
w, err := hdwallet.NewHDWallet()
if err != nil {
log.Fatal(err)
}
defer w.Destroy() // wipe the wallet's secrets when finished
addr, err := w.Address(hdwallet.ETH)
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.HasPrefix(addr, "0x"))
}
Output: true
func NewHDWalletWithEntropy ¶ added in v0.3.1
NewHDWalletWithEntropy creates a wallet with a fresh mnemonic generated from bits of BIP-39 entropy. bits must be one of 128, 160, 192, 224, or 256 (yielding 12, 15, 18, 21, or 24 words); any other value returns an error wrapping ErrInvalidWordCount.
func NewHDWalletWithWordCount ¶ added in v0.3.1
NewHDWalletWithWordCount creates a wallet with a fresh mnemonic of the given length in words. words must be one of 12, 15, 18, 21, or 24; any other value returns an error wrapping ErrInvalidWordCount.
func (*HDWallet) AccountXPub ¶ added in v0.3.0
AccountXPub returns the BIP-32 extended PUBLIC key (xpub) for symbol's account at the given index — i.e. the neutered key at m/purpose'/coin'/account'. It is public and safe to share; feed it to WatchOnlyFromXPub to derive addresses without the seed. symbol must be a secp256k1 coin.
func (*HDWallet) Address ¶
Address returns the first receive address (index 0) for a coin symbol, e.g. "BTC", "ETH", "SOL", "ATOM". Use SupportedCoins to list every symbol.
It is exactly equivalent to AddressIndex(symbol, 0).
Example ¶
ExampleHDWallet_Address derives the first receive address for several chains from a fixed mnemonic, producing deterministic, Trust Wallet-compatible addresses.
package main
import (
"fmt"
"log"
hdwallet "github.com/ranjbar-dev/hd-wallet"
)
// exampleMnemonic is the standard BIP-39 test vector mnemonic. Never hard-code a
// real mnemonic in source; this one holds no funds and is used only for docs.
const exampleMnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
func main() {
w, err := hdwallet.FromMnemonic(exampleMnemonic)
if err != nil {
log.Fatal(err)
}
defer w.Destroy()
btc, _ := w.Address(hdwallet.BTC)
eth, _ := w.Address(hdwallet.ETH)
fmt.Println(btc)
fmt.Println(eth)
}
Output: bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu 0x9858EfFD232B4033E47d90003D41EC34EcaEda94
func (*HDWallet) AddressAt ¶ added in v0.3.0
AddressAt returns the address for symbol at the given BIP-44 account, change branch, and address index, building the path "m/purpose'/coin'/account'/change/ index" from the coin's template. It requires a standard 5-element path; coins whose template has a different shape (e.g. SOL's "m/44'/501'/0'") return ErrPathArity — use AddressPath for those.
func (*HDWallet) AddressIndex ¶
AddressIndex returns the address for a coin symbol derived with the final element of the coin's BIP-32 path replaced by index, preserving that element's hardened flag (a trailing "'").
For BIP-44/BIP-84 chains whose path ends in "/0/0" (change/address_index), this varies the non-hardened receive address index — e.g. for BTC (m/84'/0'/0'/0/0), index 1 derives m/84'/0'/0'/0/1. For account-based chains whose path ends in a hardened element such as "/0'" (e.g. SOL, m/44'/501'/0'), this varies that final hardened element — index 1 derives m/44'/501'/1'.
index must be below 2^31 (0x80000000); a larger value returns an error, as does an unknown symbol (wrapping ErrUnsupportedCoin) or a destroyed wallet.
Example ¶
ExampleHDWallet_AddressIndex derives multiple receive addresses for the same chain by varying the final path index.
package main
import (
"fmt"
"log"
hdwallet "github.com/ranjbar-dev/hd-wallet"
)
// exampleMnemonic is the standard BIP-39 test vector mnemonic. Never hard-code a
// real mnemonic in source; this one holds no funds and is used only for docs.
const exampleMnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
func main() {
w, err := hdwallet.FromMnemonic(exampleMnemonic)
if err != nil {
log.Fatal(err)
}
defer w.Destroy()
first, _ := w.AddressIndex(hdwallet.BTC, 0)
second, _ := w.AddressIndex(hdwallet.BTC, 1)
fmt.Println(first)
fmt.Println(second)
}
Output: bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g
func (*HDWallet) AddressPath ¶ added in v0.3.0
AddressPath returns the address for symbol derived at the given absolute BIP-32 path (e.g. "m/44'/60'/1'/0/5"). The path's curve scheme is the coin's; only the child indices are taken from path. An invalid path or unknown symbol returns an error; a key-only wallet returns ErrKeyOnlyWallet.
func (*HDWallet) AddressRange ¶ added in v0.8.0
AddressRange derives count consecutive addresses for a single coin symbol starting at index start, varying the final element of the coin's BIP-32 path (preserving its hardened flag) exactly as AddressIndex does. The returned slice is in ascending index order: element i is the address at start+i. A count of 0 returns an empty, non-nil slice.
The seed enclave is opened exactly once and every address is derived inside that single decryption window. start+count must not exceed 2^31 (0x80000000); a larger range returns an out-of-range error, as does an unknown symbol (wrapping ErrUnsupportedCoin). It is only available on seed-based wallets; a key-only wallet (imported from a single private key) returns ErrKeyOnlyWallet.
func (*HDWallet) AllAddresses ¶
AllAddresses derives the first address (index 0) for every supported coin. It is exactly equivalent to AllAddressesAt(0).
func (*HDWallet) AllAddressesAt ¶ added in v0.3.1
AllAddressesAt derives the address at the given index for every supported coin, varying the final element of each coin's BIP-32 path (preserving its hardened flag) exactly as AddressIndex does. The seed enclave is opened exactly once and every coin is derived inside that single decryption window.
index must be below 2^31 (0x80000000); a larger value returns an error. It is only available on seed-based wallets; a key-only wallet (imported from a single private key) has no seed to enumerate over and returns ErrKeyOnlyWallet.
func (*HDWallet) BitcoinAddress ¶ added in v0.5.0
func (w *HDWallet) BitcoinAddress(symbol Symbol, t BitcoinAddressType, account, change, index uint32) (string, error)
BitcoinAddress returns the address for symbol in the given Bitcoin address type, derived at the type's standard BIP path "m/purpose'/coinType'/account'/change/index" (purpose = 44/49/84/86 for P2PKH/P2SHP2WPKH/P2WPKH/P2TR; coinType taken from the coin's registry path).
It is available for chains in btcAddrParams (BTC, LTC); any other symbol returns ErrUnsupportedCoin. account/change/index must each be below 2^31. Like the other derivation methods it is seed-only and the leaf key is wiped after use; a key-only wallet returns ErrKeyOnlyWallet.
func (*HDWallet) Destroy ¶
func (w *HDWallet) Destroy()
Destroy wipes the wallet's secret material from memory. The wallet is unusable afterwards. It is safe to call multiple times.
func (*HDWallet) Mnemonic ¶
func (w *HDWallet) Mnemonic() (*memguard.LockedBuffer, error)
Mnemonic returns the wallet's mnemonic in a page-locked buffer. This is a lower-level accessor: the caller MUST call Destroy on the returned buffer when finished with it, or the decrypted phrase lingers in memory. Prefer WithMnemonic, which wipes the decrypted copy automatically when its callback returns.
func (*HDWallet) PrivateKey ¶ added in v0.2.2
PrivateKey returns the raw leaf private key for symbol at the given address index in a page-locked, encrypted-at-rest memguard buffer. This is a lower-level accessor: the caller MUST call Destroy on the returned buffer when finished, or the decrypted key lingers in memory. Prefer WithPrivateKey, which wipes the key automatically when its callback returns (mirrors Mnemonic).
The returned buffer holds a copy taken inside the wallet's protected derivation window; the wallet's own working copy is wiped before this returns. See WithPrivateKey for the seed/key-only semantics and the key encoding.
func (*HDWallet) PrivateKeyPath ¶ added in v0.3.0
PrivateKeyPath returns the raw leaf private key for symbol derived at the given absolute BIP-32 path in a page-locked memguard buffer; the caller MUST Destroy it (mirrors PrivateKey). Prefer WithPrivateKeyPath, which wipes automatically.
func (*HDWallet) PublicKey ¶ added in v0.2.0
PublicKey returns the public key for symbol at address index 0. See PublicKeyIndex.
func (*HDWallet) PublicKeyAt ¶ added in v0.3.0
PublicKeyAt is the account/change/index counterpart of PublicKeyPath.
func (*HDWallet) PublicKeyIndex ¶ added in v0.2.0
PublicKeyIndex returns the public key derived for symbol at the given address index: the 33-byte compressed key for secp256k1/nist256p1, or the 32-byte key for ed25519. Signing callers need this to build or verify transactions.
func (*HDWallet) PublicKeyPath ¶ added in v0.3.0
PublicKeyPath returns the public key for symbol derived at the given absolute BIP-32 path: the 33-byte compressed key for secp256k1/nist256p1, or the 32-byte key for ed25519-family curves.
func (*HDWallet) Sign ¶ added in v0.2.0
Sign signs data with the key for symbol at address index 0. See SignIndex.
Example ¶
ExampleHDWallet_Sign signs a digest and verifies it with the derived public key. For ECDSA chains (BTC/ETH/…) pass the 32-byte digest your chain hashes; for ed25519 chains pass the message itself.
package main
import (
"crypto/sha256"
"fmt"
"log"
hdwallet "github.com/ranjbar-dev/hd-wallet"
)
// exampleMnemonic is the standard BIP-39 test vector mnemonic. Never hard-code a
// real mnemonic in source; this one holds no funds and is used only for docs.
const exampleMnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
func main() {
w, err := hdwallet.FromMnemonic(exampleMnemonic)
if err != nil {
log.Fatal(err)
}
defer w.Destroy()
digest := sha256.Sum256([]byte("transaction bytes to sign"))
sig, err := w.Sign(hdwallet.BTC, digest[:])
if err != nil {
log.Fatal(err)
}
pub, _ := w.PublicKey(hdwallet.BTC)
fmt.Println(hdwallet.Verify(hdwallet.Secp256k1, pub, digest[:], sig))
}
Output: true
func (*HDWallet) SignAt ¶ added in v0.3.0
func (w *HDWallet) SignAt(symbol Symbol, account, change, index uint32, data []byte) (*Signature, error)
SignAt is the account/change/index counterpart of SignPath.
func (*HDWallet) SignBitcoinMessage ¶ added in v0.3.1
SignBitcoinMessage signs message under the Bitcoin signed-message standard with the key derived for symbol at the given address index, returning the base64 compact signature. symbol must be a secp256k1 coin (e.g. BTC, LTC); the derived private key is wiped immediately after signing and never leaves the package.
The signature commits only to the message and key, so it is independent of the address format; this library derives compressed keys, so the header byte marks the key compressed (verifiers recover the compressed key / its legacy address).
func (*HDWallet) SignIndex ¶ added in v0.2.0
SignIndex signs data with the private key derived for symbol at the given address index and returns the signature.
For ECDSA chains (secp256k1, nist256p1 — e.g. BTC, ETH, ATOM, NEO) data must be the 32-byte digest the chain signs; pre-hash the message with the chain's hash function (keccak256 for Ethereum/Tron, double-SHA256 for Bitcoin, SHA-256 for Cosmos, …). For ed25519 chains (e.g. SOL, XLM, DOT) data is the message itself; the EdDSA scheme hashes internally.
The derived private key is wiped immediately after signing and never leaves the package.
func (*HDWallet) SignMessage ¶ added in v0.2.2
SignMessage signs message with EIP-191 personal_sign using the key for symbol at the given address index, returning a 65-byte r||s||v signature (v = 27/28). symbol must be a secp256k1/EVM coin (e.g. ETH); other curves return an error.
func (*HDWallet) SignPSBT ¶ added in v0.6.0
SignPSBT parses psbtBytes, signs every input controlled by the (symbol,index) key, attaches the signatures, and returns the updated serialized PSBT. The leaf key is derived under the package's seed discipline and wiped on return.
func (*HDWallet) SignPath ¶ added in v0.3.0
SignPath signs data with the key for symbol derived at the given absolute BIP-32 path. The ECDSA-vs-ed25519 input rule is identical to SignIndex (ECDSA curves want the 32-byte digest; ed25519 wants the message).
func (*HDWallet) SignSolanaMessage ¶ added in v0.3.1
SignSolanaMessage signs message with the ed25519 key derived for symbol at the given address index and returns the base58-encoded 64-byte signature.
symbol must be a Solana / ed25519 coin (e.g. SOL). The derived private key is wiped immediately after signing and never leaves the package.
func (*HDWallet) SignTransaction ¶ added in v0.2.2
func (w *HDWallet) SignTransaction(symbol Symbol, index uint32, input proto.Message) (proto.Message, error)
SignTransaction signs a transaction for symbol using the key derived at the given address index and returns a per-chain protobuf SigningOutput.
input must be the SigningInput proto for symbol's family (e.g. *ethereum.SigningInput for ETH/EVM, *tron.SigningInput for TRX, …). The returned proto.Message is the matching SigningOutput, holding the signed serialized raw-transaction bytes plus a hex/base58/base64 convenience form. No network calls are made.
The derived private key is wiped immediately after signing and never leaves the package. An unknown symbol returns ErrTxUnsupported; a wrong input type returns ErrTxInput.
func (*HDWallet) SignTypedData ¶ added in v0.2.2
SignTypedData signs the EIP-712 digest of MetaMask-shape typed-data JSON using the key for symbol at the given address index, returning a 65-byte r||s||v signature (v = 27/28).
func (*HDWallet) WIF ¶ added in v0.3.0
WIF returns the leaf key for symbol at the given address index as a Bitcoin mainnet compressed WIF in a page-locked memguard buffer; the caller MUST Destroy it. Prefer WithWIF, which wipes automatically.
func (*HDWallet) WithAccountXPrv ¶ added in v0.3.0
WithAccountXPrv runs fn with the BIP-32 extended PRIVATE key (xprv) string for symbol's account, then wipes the byte slice (mirrors WithPrivateKey/WithWIF). The xprv is a full secret — anyone holding it can derive every key under the account. The slice passed to fn must not escape fn. symbol must be secp256k1.
func (*HDWallet) WithMnemonic ¶
WithMnemonic runs fn with the plaintext mnemonic bytes and wipes the decrypted copy as soon as fn returns. The slice passed to fn must not escape fn.
Example ¶
ExampleHDWallet_WithMnemonic shows the safe pattern for reading the mnemonic back: the decrypted copy is wiped automatically when the callback returns, and the slice must not escape it.
package main
import (
"fmt"
"log"
"strings"
hdwallet "github.com/ranjbar-dev/hd-wallet"
)
// exampleMnemonic is the standard BIP-39 test vector mnemonic. Never hard-code a
// real mnemonic in source; this one holds no funds and is used only for docs.
const exampleMnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
func main() {
w, err := hdwallet.FromMnemonic(exampleMnemonic)
if err != nil {
log.Fatal(err)
}
defer w.Destroy()
err = w.WithMnemonic(func(mnemonic []byte) error {
fmt.Println(len(strings.Fields(string(mnemonic))), "words")
return nil
})
if err != nil {
log.Fatal(err)
}
}
Output: 12 words
func (*HDWallet) WithPrivateKey ¶ added in v0.2.2
WithPrivateKey runs fn with the raw leaf private key for symbol at the given address index and wipes the key as soon as fn returns. This is the safe export primitive — the key never escapes into a value the caller must remember to clear (mirrors WithMnemonic). The slice passed to fn must not escape fn.
It works for both wallet modes: seed wallets derive the key for symbol/index; key-only wallets return their imported key (curve must match symbol's curve, and index must be 0). The key is the 32-byte scalar/seed for the coin's curve.
For ECDSA chains this is the signing scalar; for ed25519 it is the 32-byte seed (not the 64-byte expanded key).
func (*HDWallet) WithPrivateKeyPath ¶ added in v0.3.0
WithPrivateKeyPath runs fn with the raw leaf private key for symbol derived at the given absolute BIP-32 path and wipes the key as soon as fn returns (mirrors WithPrivateKey). The slice passed to fn must not escape fn.
type RLPItem ¶ added in v0.2.2
RLPItem is a node in an RLP tree: exactly one of Str (a byte string, a leaf) or List (an ordered list of items) is meaningful. IsList selects which. The zero value is the empty string item (encodes to 0x80).
func DecodeRLP ¶ added in v0.2.2
DecodeRLP decodes a single, complete RLP item. It is strict: the entire input must be exactly one canonical item with no trailing bytes.
type Signature ¶ added in v0.2.0
type Signature struct {
Curve Curve
R, S []byte // ECDSA signature scalars (nil for ed25519)
RecoveryID byte // secp256k1 public-key recovery id (0 or 1)
// contains filtered or unexported fields
}
Signature is the result of signing with a derived key.
For ECDSA curves (secp256k1, nist256p1), R and S are the signature scalars and the value is available as a 64-byte R||S string, an ASN.1 DER encoding, and — for secp256k1 — a 65-byte recoverable form. For ed25519, R and S are nil and the 64-byte signature is available via Bytes.
func (*Signature) Bytes ¶ added in v0.2.0
Bytes returns the 64-byte signature: R||S for ECDSA curves, or the raw 64-byte signature for ed25519. Cosmos and Solana use this form.
func (*Signature) DER ¶ added in v0.2.0
DER returns the ASN.1 DER encoding (SEQUENCE of two INTEGERs) used by Bitcoin-family chains. It is valid for ECDSA curves; for ed25519 it returns nil.
func (*Signature) Recoverable ¶ added in v0.2.0
Recoverable returns the 65-byte [R||S||V] signature, where V is the recovery id (0 or 1), used by Ethereum/EVM chains and Tron. Callers add the chain's V offset (e.g. 27, or 35+2*chainID for EIP-155) as needed. It is only valid for secp256k1; for other curves it returns nil.
type SolanaInstruction ¶ added in v0.8.0
type SolanaInstruction struct {
ProgramIDIndex byte
ProgramID string // base58 of the referenced account key ("" if out of range)
Accounts []byte // account-key indices the instruction operates on
Data []byte // raw instruction data
// Type names a recognised instruction: "systemTransfer" or
// "tokenTransferChecked" (empty otherwise).
Type string
Lamports uint64 // systemTransfer
Amount uint64 // tokenTransferChecked
Decimals byte // tokenTransferChecked
}
SolanaInstruction is one decoded instruction. ProgramID and the decoded transfer fields are best-effort: ProgramID is empty if the program index is out of range, and Type is "" for an instruction the decoder does not recognise.
type SolanaTxFields ¶ added in v0.8.0
type SolanaTxFields struct {
Signatures [][]byte
NumRequiredSignatures byte
NumReadonlySigned byte
NumReadonlyUnsigned byte
AccountKeys []string // base58
RecentBlockhash string // base58
Instructions []SolanaInstruction
}
SolanaTxFields holds the decoded, display-ready fields of a Solana transaction.
func DecodeSolanaTx ¶ added in v0.8.0
func DecodeSolanaTx(raw []byte) (*SolanaTxFields, error)
DecodeSolanaTx decodes a raw signed Solana (legacy) transaction into its display fields. Malformed or truncated input returns ErrTxDecode; the function never panics and never reads past `raw`.
type Symbol ¶
type Symbol string
Symbol is a typed network identifier used to look up a registry entry. Use the exported constants below (hdwallet.BTC, hdwallet.ETH, …) when calling methods such as (*HDWallet).Address and AddressIndex; the typed enum gives compile-time checking and editor autocomplete instead of bare strings.
const ( // secp256k1 — Bitcoin-style UTXO chains. BTC Symbol = "BTC" LTC Symbol = "LTC" DOGE Symbol = "DOGE" BCH Symbol = "BCH" DASH Symbol = "DASH" ZEC Symbol = "ZEC" // secp256k1 — additional UTXO chains. GRS Symbol = "GRS" // Groestlcoin (segwit) DGB Symbol = "DGB" // DigiByte (segwit) BTG Symbol = "BTG" // Bitcoin Gold (segwit) SYS Symbol = "SYS" // Syscoin (segwit) VIA Symbol = "VIA" // Viacoin (segwit) QTUM Symbol = "QTUM" // Qtum (base58check P2PKH) RVN Symbol = "RVN" // Ravencoin (base58check P2PKH) KMD Symbol = "KMD" // Komodo (base58check P2PKH) FIRO Symbol = "FIRO" // Firo (base58check P2PKH) MONA Symbol = "MONA" // MonaCoin (base58check P2PKH) XVG Symbol = "XVG" // Verge (base58check P2PKH) PIVX Symbol = "PIVX" // PIVX (base58check P2PKH) NEBL Symbol = "NEBL" // Neblio (base58check P2PKH) STRAX Symbol = "STRAX" // Stratis (segwit) ZEN Symbol = "ZEN" // Horizen (base58check 2-byte) BCD Symbol = "BCD" // Bitcoin Diamond (base58check P2PKH) XEC Symbol = "XEC" // eCash (CashAddr) FLUX Symbol = "FLUX" // Flux/Zelcash (base58check 2-byte) // secp256k1 — account-based / keccak. ETH Symbol = "ETH" TRX Symbol = "TRX" XRP Symbol = "XRP" // secp256k1 — EOS-family public-key strings. EOS Symbol = "EOS" WAX Symbol = "WAX" FIO Symbol = "FIO" // secp256k1 — Filecoin (f1 base32 address). FIL Symbol = "FIL" // secp256k1 — EVM chains (same key & address format as Ethereum). BNB Symbol = "BNB" MATIC Symbol = "MATIC" AVAX Symbol = "AVAX" ARB Symbol = "ARB" OP Symbol = "OP" FTM Symbol = "FTM" BASE Symbol = "BASE" CRO Symbol = "CRO" GNO Symbol = "GNO" CELO Symbol = "CELO" // secp256k1 — additional EVM chains (Ethereum address format, EIP-55). ETC Symbol = "ETC" RONIN Symbol = "RONIN" ZKSYNC Symbol = "ZKSYNC" LINEA Symbol = "LINEA" SCROLL Symbol = "SCROLL" MANTLE Symbol = "MANTLE" BLAST Symbol = "BLAST" KAIA Symbol = "KAIA" AURORA Symbol = "AURORA" GLMR Symbol = "GLMR" MOVR Symbol = "MOVR" BOBA Symbol = "BOBA" METIS Symbol = "METIS" OPBNB Symbol = "OPBNB" POLZKEVM Symbol = "POLZKEVM" MANTA Symbol = "MANTA" RBTC Symbol = "RBTC" HECO Symbol = "HECO" OKT Symbol = "OKT" KCS Symbol = "KCS" WAN Symbol = "WAN" POA Symbol = "POA" CLO Symbol = "CLO" GO Symbol = "GO" TT Symbol = "TT" VET Symbol = "VET" IOTX Symbol = "IOTX" THETA Symbol = "THETA" NEON Symbol = "NEON" MERLIN Symbol = "MERLIN" LIGHT Symbol = "LIGHT" SONIC Symbol = "SONIC" ZENEON Symbol = "ZENEON" ZETAEVM Symbol = "ZETAEVM" // secp256k1 — Cosmos SDK chains. ATOM Symbol = "ATOM" OSMO Symbol = "OSMO" JUNO Symbol = "JUNO" TIA Symbol = "TIA" // secp256k1 — additional Cosmos SDK chains (hash160 bech32, per-chain HRP). LUNA Symbol = "LUNA" KAVA Symbol = "KAVA" SCRT Symbol = "SCRT" BAND Symbol = "BAND" RUNE Symbol = "RUNE" STARS Symbol = "STARS" AXL Symbol = "AXL" STRD Symbol = "STRD" BLD Symbol = "BLD" CRE Symbol = "CRE" KUJI Symbol = "KUJI" CMDX Symbol = "CMDX" NTRN Symbol = "NTRN" SOMM Symbol = "SOMM" FET Symbol = "FET" MARS Symbol = "MARS" UMEE Symbol = "UMEE" COREUM Symbol = "COREUM" QSR Symbol = "QSR" XPRT Symbol = "XPRT" AKT Symbol = "AKT" NOBLE Symbol = "NOBLE" SEI Symbol = "SEI" DYDX Symbol = "DYDX" BLZ Symbol = "BLZ" CRYPTOORG Symbol = "CRYPTOORG" // secp256k1 — Cosmos chains with EVM-style keys (keccak address, bech32). EVMOS Symbol = "EVMOS" INJ Symbol = "INJ" CANTO Symbol = "CANTO" ZETA Symbol = "ZETA" ONE Symbol = "ONE" // ed25519 (SLIP-0010). SOL Symbol = "SOL" XLM Symbol = "XLM" DOT Symbol = "DOT" KSM Symbol = "KSM" NEAR Symbol = "NEAR" ALGO Symbol = "ALGO" SUI Symbol = "SUI" APTOS Symbol = "APTOS" XTZ Symbol = "XTZ" // ed25519 (SLIP-0010) — additional chains. EGLD Symbol = "EGLD" // MultiversX (bech32 of pubkey) IOST Symbol = "IOST" // IOST (base58 of pubkey) HBAR Symbol = "HBAR" // Hedera (0.0.<DER-encoded pubkey hex>) ROSE Symbol = "ROSE" // Oasis (bech32 of context-hashed pubkey) KIN Symbol = "KIN" // Kin (Stellar strkey) AE Symbol = "AE" // Aeternity (ak_ base58check) // nist256p1 (SLIP-0010). NEO Symbol = "NEO" ONT Symbol = "ONT" // Ontology (same NEO-style address) // new-curve chains (SLIP-0010 ed25519 leaf key, chain-specific signing). XNO Symbol = "XNO" // Nano (ed25519-blake2b) WAVES Symbol = "WAVES" // Waves (curve25519) )
Supported network symbols. These mirror the registry below and match Trust Wallet's tickers.
func SupportedCoins ¶
func SupportedCoins() []Symbol
SupportedCoins lists the registered coin symbols in sorted order.
type TronContract ¶ added in v0.8.0
type TronContract struct {
Type int32 // 1 = TransferContract, 31 = TriggerSmartContract
TypeName string // "TransferContract" / "TriggerSmartContract" / "" (unknown)
TypeURL string // the google.protobuf.Any type_url
OwnerAddress string // base58check "T..." address
// TransferContract.
ToAddress string // base58check "T..." address
Amount int64
// TriggerSmartContract.
ContractAddress string // base58check "T..." address
Data []byte // raw call data (e.g. TRC-20 transfer calldata)
}
TronContract is one decoded contract entry. Type is the Tron ContractType enum value; the populated fields depend on it.
type TronTxFields ¶ added in v0.8.0
type TronTxFields struct {
RefBlockBytes []byte
RefBlockHash []byte
Expiration int64
Timestamp int64
FeeLimit int64 // 0 when absent
Contracts []TronContract
}
TronTxFields holds the decoded, display-ready fields of a Tron transaction's raw_data.
func DecodeTronTx ¶ added in v0.8.0
func DecodeTronTx(raw []byte) (*TronTxFields, error)
DecodeTronTx decodes a raw_data protobuf blob into its display fields. Malformed or truncated input returns ErrTxDecode; the function never panics.
type WatchWallet ¶ added in v0.3.0
type WatchWallet struct {
// contains filtered or unexported fields
}
WatchWallet derives receive/change addresses for a single account from its extended PUBLIC key (xpub) — no seed, no private keys, no signing. It is the watch-only counterpart of HDWallet for secp256k1 coins.
func WatchOnlyFromXPub ¶ added in v0.3.0
func WatchOnlyFromXPub(xpub string, symbol Symbol) (*WatchWallet, error)
WatchOnlyFromXPub builds a watch-only wallet for symbol from an account-level extended key string. Both xpub and xprv strings are accepted; an xprv is immediately neutered so the WatchWallet never holds private material. symbol must be a secp256k1 coin whose address format matches the xpub's chain.
func (*WatchWallet) Address ¶ added in v0.3.0
func (ww *WatchWallet) Address(change, index uint32) (string, error)
Address returns the address at the account's change/index branch (e.g. change=0, index=5 -> .../0/5). Both must be non-hardened (< 2^31); public derivation cannot produce hardened children.
type XrpTxFields ¶ added in v0.8.0
type XrpTxFields struct {
TransactionType uint16
TransactionName string // "Payment" for type 0
Account string // "r..." address
Destination string // "r..." address
Amount uint64 // drops
Fee uint64 // drops
Sequence uint32
Flags uint32
DestinationTag *uint32
LastLedgerSequence *uint32
SigningPubKey []byte
TxnSignature []byte
}
XrpTxFields holds the decoded, display-ready fields of an XRP Payment. DestinationTag and LastLedgerSequence are pointers so absence (the field was not on the wire) is distinguishable from a zero value.
func DecodeRippleTx ¶ added in v0.8.0
func DecodeRippleTx(raw []byte) (*XrpTxFields, error)
DecodeRippleTx decodes a serialized XRP transaction into its display fields. Malformed or truncated input returns ErrTxDecode; the function never panics and never reads past `raw`.
Source Files
¶
- address_types.go
- address_validate.go
- blake2b_personal.go
- cardano.go
- codec.go
- crypto.go
- curve25519.go
- curve_helpers.go
- derive.go
- ed25519_blake2b.go
- encoders_ed25519.go
- encoders_nist256p1.go
- encoders_secp256k1.go
- eth_abi.go
- eth_eip191.go
- eth_eip712.go
- eth_message.go
- eth_rlp.go
- extkey.go
- hdwallet.go
- message_bitcoin.go
- message_solana.go
- path.go
- privatekey.go
- registry.go
- secret.go
- sign.go
- slip10.go
- sr25519.go
- starkex.go
- tx.go
- tx_bitcoin.go
- tx_bitcoin_psbt.go
- tx_cosmos.go
- tx_decode_bitcoin.go
- tx_decode_cosmos.go
- tx_decode_ethereum.go
- tx_decode_ripple.go
- tx_decode_solana.go
- tx_decode_tron.go
- tx_ethereum.go
- tx_families.go
- tx_ripple.go
- tx_solana.go
- tx_tron.go
- tx_utxo.go
- tx_zcash.go
- wif.go
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
hdwallet
command
Command hdwallet is a small demo CLI for the hd-wallet library: it generates a fresh BIP-39 mnemonic (or imports one) and prints the receive address for every supported network.
|
Command hdwallet is a small demo CLI for the hd-wallet library: it generates a fresh BIP-39 mnemonic (or imports one) and prints the receive address for every supported network. |
|
txproto
|
|