Documentation
¶
Overview ¶
Package wallet provides BIP-39/BIP-32 key derivation and go-ethereum v3 keystore helpers shared by `polycli heimdall wallet` (keystore management) and `polycli heimdall tx/mktx/send/estimate` (signing).
The helpers here were previously duplicated between cmd/heimdall/wallet/ and cmd/heimdall/tx/msgs/ — this package consolidates them so both call sites stay in lockstep when we adjust keystore precedence, derivation defaults, or decryption semantics.
Index ¶
- Constants
- Variables
- func AddressFromKeystoreFile(path string) (common.Address, error)
- func DecryptKeystoreAccount(acc accounts.Account, password string) (*ecdsa.PrivateKey, error)
- func DeriveFromMnemonic(mnemonic, passphrase, path string, index uint32) (*ecdsa.PrivateKey, string, common.Address, error)
- func FindAccount(ks *keystore.KeyStore, identifier string) (accounts.Account, error)
- func NewKeyStore(dir string) *keystore.KeyStore
- func ParseDerivationPath(path string) ([]uint32, error)
- func ResolveKeystoreDir(override string, createDefault bool) (string, error)
Constants ¶
const DefaultDerivationPath = "m/44'/60'/0'/0/0"
DefaultDerivationPath is the standard Ethereum BIP-44 path at index 0. Matches `cast wallet new-mnemonic` and most hardware wallet defaults.
Variables ¶
var ErrAccountExists = errors.New("account already exists in keystore")
ErrAccountExists is returned when an import would overwrite an existing key for the same address.
Functions ¶
func AddressFromKeystoreFile ¶
AddressFromKeystoreFile reads a v3 JSON keystore from path and returns the address it encodes. Works for keystores that include the `address` field at the top level (go-ethereum + foundry do).
func DecryptKeystoreAccount ¶
DecryptKeystoreAccount loads the raw JSON for acc and decrypts it with password, returning the raw ECDSA private key. It is the lower level of ks.Unlock; we need the key material directly for signing utilities that are not part of the keystore's own signing surface.
func DeriveFromMnemonic ¶
func DeriveFromMnemonic(mnemonic, passphrase, path string, index uint32) (*ecdsa.PrivateKey, string, common.Address, error)
DeriveFromMnemonic returns the ECDSA private key, effective derivation path, and Ethereum address for mnemonic at the given path / index.
If path is empty it is built from DefaultDerivationPath with the final component replaced by index. If path is non-empty, index is ignored — this matches `cast wallet` semantics where an explicit path overrides --mnemonic-index.
func FindAccount ¶
FindAccount resolves a CLI identifier to a keystore account. Supported identifier forms:
- `0x`-prefixed address
- path to a keystore JSON file (UTC-- / .json)
- decimal index into ks.Accounts() (for `--account 0` style use)
The index form is what the tx/mktx/send paths call "account by position"; the wallet package does not currently expose that surface, but supporting it here costs nothing.
func NewKeyStore ¶
NewKeyStore returns a KeyStore rooted at dir using light scrypt parameters. LightScryptN/P gives the cast-compatible "fast enough on a laptop" encryption — matches the Foundry default.
func ParseDerivationPath ¶
ParseDerivationPath turns a path like "m/44'/60'/0'/0/0" into the list of BIP-32 child indices. Hardened components are marked with a trailing apostrophe (') and offset by bip32.FirstHardenedChild.
func ResolveKeystoreDir ¶
ResolveKeystoreDir returns the keystore directory to use per the precedence rule:
- override (from --keystore-dir flag), if non-empty
- ETH_KEYSTORE environment variable
- ~/.foundry/keystores, if it already exists (honour existing cast users without migration)
- ~/.polycli/keystores (the default)
createDefault controls whether step 4 creates the fallback directory on demand. Keystore-management commands (`wallet new`, `wallet import`) pass true so the default is materialised the first time an operator uses it. Signing commands (`mktx`, `send`, `estimate`) pass false: they shouldn't silently create a keystore dir just because an operator typo'd an address, and they should surface a clear "account not found" error instead.
The returned path is absolute and logged at debug so operators can see why a given path was chosen.
Types ¶
This section is empty.