Documentation ¶
Overview ¶
Package wallet contains utilities for importing/using eth wallets.
These are used for importing accounts from various data sources. Currently, key files, seed phrases and private key hexes are supported
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Wallet ¶
type Wallet interface { // Address gets the wallets address Address() common.Address // AddressPtr gets the wallets address as a pointer AddressPtr() *common.Address // PublicKey returns this wallet's public key as an *ecdsa.PublicKey PublicKey() *ecdsa.PublicKey // PrivateKey returns this wallet's private key as an *ecdsa.PrivateKey PrivateKey() *ecdsa.PrivateKey // PublicKeyHex returns this wallet's public key in hex format, // without a leading 0x. PublicKeyHex() string // PrivateKeyHex returns this wallet's private key in hex format, // without a leading 0x. PrivateKeyHex() string // PublicKeyBytes is a helper function that returns the public key as a byte slice PublicKeyBytes() []byte // PrivateKeyBytes is a helper function that returns the private key as a byte slice PrivateKeyBytes() []byte // String is an alias for Address(). String() string }
Wallet is an EVM-compatible wallet with an ECDSA private key + public key and standard ethereum hex address.
func FromKeyFile ¶
FromKeyFile creates a wallet from a file. The wallet detects if this is a seed phrase or a private key hex and returns the appropriate wallet. An error is returned if this cannot be determined.
Currently, the default derivation path is used. This should be compatible with metamask and most wallets. It gets the first wallet in this derivation path. TODO: support json files.
func FromPrivateKey ¶
func FromPrivateKey(privKey *ecdsa.PrivateKey) (Wallet, error)
FromPrivateKey creates a new wallet from a private key.
func FromRandom ¶
FromRandom generates a new private key. Note: this should be used for testing only and has not been audited yet.
func FromSeedPhrase ¶
func FromSeedPhrase(seedPhrase string, derivationPath accounts.DerivationPath) (Wallet, error)
FromSeedPhrase gets the seed phrase for the wallet. Note: there seems to be some issue here w/ longer seed phraeses should investigate.
Example ¶
ExampleFromSeedPhrase shows an example creating a wallet from a seed phrase.
package main import ( "encoding/hex" "fmt" "github.com/Flaque/filet" "github.com/brianvoe/gofakeit/v6" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" . "github.com/stretchr/testify/assert" "github.com/synapsecns/sanguine/ethergo/mocks" "github.com/synapsecns/sanguine/ethergo/signer/wallet" "github.com/tyler-smith/go-bip39" "os" "path" "strings" ) // ExampleFromSeedPhrase shows an example creating a wallet from a seed phrase. func main() { const mnemonic = "tag volcano eight thank tide danger coast health above argue embrace heavy" testWallet, _ := wallet.FromSeedPhrase(mnemonic, accounts.DefaultBaseDerivationPath) fmt.Printf("Address: %s\n", testWallet.Address()) fmt.Printf("Public Key (From Bytes): %s\n", hex.EncodeToString(testWallet.PrivateKeyBytes())) fmt.Printf("Public Key Hex: %s\n", testWallet.PublicKeyHex()) fmt.Printf("Private Key (From Bytes): %s\n", testWallet.PrivateKeyHex()) fmt.Printf("Private Key Hex: %s\n", hex.EncodeToString(testWallet.PrivateKeyBytes())) } func (s WalletSuite) TestFromKeyFile() { for _, testCase := range s.makeKeyFileTests() { testFile := s.makeTestFile(testCase.contents, !testCase.shouldErr) testWallet, err := wallet.FromKeyFile(testFile) if testCase.shouldErr { NotNil(s.T(), err) continue } Nil(s.T(), err) Equal(s.T(), testWallet.Address(), testCase.address) } } func (s WalletSuite) TestFromRandom() { newWallet, err := wallet.FromRandom() Nil(s.T(), err) NotPanics(s.T(), func() { newWallet.Address() newWallet.PrivateKey() newWallet.PublicKey() newWallet.PrivateKeyBytes() newWallet.PublicKeyHex() newWallet.PublicKeyBytes() }) } func (s WalletSuite) makeTestFile(contents []byte, fuzz bool) (fileName string) { if fuzz { contents = fuzzContents(contents) } testFile, err := os.Create(path.Join(filet.TmpDir(s.T(), ""), fmt.Sprintf("%s.wallet", gofakeit.UUID()))) Nil(s.T(), err) defer func(testFile *os.File) { Nil(s.T(), testFile.Close()) }(testFile) _, err = testFile.Write(contents) Nil(s.T(), err) return testFile.Name() } // makeFuzzFile randomly fuzzes a byte slice (representing a file) in a way that should not break // (e.g. adding a new line at the end, spaces) in a way that does not change the contents. func fuzzContents(contents []byte) (out []byte) { fuzzSetting := gofakeit.Number(0, 3) switch fuzzSetting { case 0: contents = append(contents, []byte(" ")...) case 1: contents = append(contents, []byte("\n\r")...) case 2: contents = append(contents, []byte("\f\r")...) } return contents } type KeyFileTest struct { // address is the expected output of the address address common.Address // shouldErr determines whether an error should be expected when running the test shouldErr bool // contents of the key file contents []byte // description of what's being tested description string } func (s WalletSuite) makeKeyFileTests() (tests []KeyFileTest) { // test an hdwallet, from https://pkg.go.dev/github.com/miguelmota/go-ethereum-hdwallet#section-readme tests = append(tests, KeyFileTest{ address: common.HexToAddress("0xC49926C4124cEe1cbA0Ea94Ea31a6c12318df947"), shouldErr: false, contents: []byte("tag volcano eight thank tide danger coast health above argue embrace heavy"), description: "test the default derivation path", }) tests = append(tests, KeyFileTest{ address: common.HexToAddress("0xC49926C4124cEe1cbA0Ea94Ea31a6c12318df947"), shouldErr: false, contents: []byte("63e21d10fd50155dbba0e7d3f7431a400b84b4c2ac1ee38872f82448fe3ecfb9"), description: "test the private key as a hex", }) // fuzz tests = append(tests, KeyFileTest{ address: mocks.MockAddress(), shouldErr: true, contents: nil, description: "no file contents", }) tests = append(tests, KeyFileTest{ address: mocks.MockAddress(), shouldErr: true, contents: []byte(strings.Join(bip39.GetWordList(), " ")), description: "long word list", }) return tests }
Output: Address: 0xC49926C4124cEe1cbA0Ea94Ea31a6c12318df947 Public Key (From Bytes): 63e21d10fd50155dbba0e7d3f7431a400b84b4c2ac1ee38872f82448fe3ecfb9 Public Key Hex: 6005c86a6718f66221713a77073c41291cc3abbfcd03aa4955e9b2b50dbf7f9b6672dad0d46ade61e382f79888a73ea7899d9419becf1d6c9ec2087c1188fa18 Private Key (From Bytes): 63e21d10fd50155dbba0e7d3f7431a400b84b4c2ac1ee38872f82448fe3ecfb9 Private Key Hex: 63e21d10fd50155dbba0e7d3f7431a400b84b4c2ac1ee38872f82448fe3ecfb9