go-eth-wallet

command module
v0.0.0-...-308b279 Latest Latest
Warning

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

Go to latest
Published: Oct 3, 2023 License: Apache-2.0 Imports: 13 Imported by: 0

README

go-eth-wallet

Go library to provide access to Ethereum 2 wallets with advanced features.

** Please note that this library uses standards that are not yet final, and as such may result in changes that alter public and private keys. Do not use this library for production use just yet **

Table of Contents

Install

go-eth2-wallet is a standard Go module which can be installed with:

go get github.com/alex-necsoiuu/go-eth-wallet/

Usage

Before using go-eth2-wallet it is important to understand the concepts behind it.

An account is the container for private keys. Each account is named, and contains information about the derivation of the private key: either the key itself, or information that can be passed to a third-party system to identify the key (e.g. for a hardware wallet). An account may or may not have a passphrase depending on the information stored within it.

A wallet is the container for accounts. Each wallet is named, and contains information about how to create new accounts: one wallet might create accounts by generating random keys, another might use a seed phrase to create accounts by a deterministic method. A wallet may or may not have a passphrase depending on the information stored within it.

A store is a storage system for wallets and accounts. The store allows access to wallets and accounts regardless of where they are. Stores can be local, for example on the filesystem, or remote, for example on Amazon's S3 storage. Stores have their own configuration, which may or may not include account IDs and passwords. Stores can be encrypted with a passphrase, in which case all data written to the store is encrypted prior to being written; this increases security where there are concerns about others accessing the data.

An overview of the architecture as laid out above is shown below, showing an application interacting with multiple local and remote stores:

Overview

And to recap: an application can access one or more stores. Each store contains a number of wallets, and each wallet contains a number of accounts.

The Ethereum 2 wallet is designed to be highly modular: additional stores and wallets can be added, allowing for the ability to upgrade features as required. This module hides the complexity that comes with that modularity and provides a simple unified API to handle all common (and not-so-common) wallet operations.

Stores

The following stores are available:

  • filesystem: this stores wallets and accounts on the local filesystem.
  • s3: this stores wallets and accounts on Amazon S3.
  • scratch: this stores wallets and accounts in memory.

Please refer to the documentation for each store to understand its functionality and available options.

Wallets

The following wallet types are available:

  • nd: this is a traditional non-deterministic wallet where private keys are generated randomly and have no relationship to each other.
  • hd: this is a hierarchical deterministic wallet where private keys are generated based on a seed phrase and path.
  • distributed: this is a wallet whose accounts form part of a distributed composite.

Please refer to the documentation for each wallet type to understand its functionality and available options.

Examples
Opening an existing wallet from the default store
import (
    e2wallet "github.com/alex-necsoiu/go-eth-wallet"
)

func main() {
    wallet, err := e2wallet.OpenWallet("my wallet")
    if err != nil {
        panic(err)
    }

    ...
}
Creating a new wallet on the default store
import (
    e2wallet "github.com/alex-necsoiu/go-eth-wallet"
)

func main() {
    wallet, err := e2wallet.CreateWallet("my wallet")
    if err != nil {
        panic(err)
    }

    ...
}
Creating a new wallet on the Amazon S3 store
import (
    e2wallet "github.com/alex-necsoiu/go-eth-wallet"
    s3 "github.com/alex-necsoiu/go-eth-wallet/store-s3"
)

func main() {
    s3Store, err := s3.New(s3.WithPassphrase([]byte("store secret")))
    if err != nil {
        panic(err)
    }
    err = e2wallet.UseStore(s3Store)
    if err != nil {
        panic(err)
    }
    wallet, err := e2wallet.CreateWallet("my wallet")

    ...
}
List all wallets, and all accounts in each wallet
import (
    "fmt"

    e2wallet "github.com/alex-necsoiu/go-eth-wallet/wallet"
)

func main() {
    for wallet := range e2wallet.Wallets() {
        fmt.Printf("Found wallet %s\n", wallet.Name())
        for account := range wallet.Accounts() {
            fmt.Printf("Wallet %s has account %s\n", wallet.Name(), account.Name())
        }
    }
}
Creating an account in an existing wallet
import (
    e2wallet "github.com/alex-necsoiu/go-eth-wallet/wallet"
)

func main() {
    wallet, err := e2wallet.OpenWallet("my wallet")
    if err != nil {
        panic(err)
    }

    err = wallet.Unlock([]byte("wallet passphrase"))
    if err != nil {
        panic(err)
    }
    // Always immediately defer locking the wallet to ensure it does not remain unlocked outside of the function.
    defer wallet.Lock()

    account, err := wallet.CreateAccount("primary account", []byte("secret passphrase"))
    if err != nil {
        panic(err)
    }
    // Wallet should be locked as soon as unlocked operations have finished; it is safe to explicitly call wallet.Lock() as well
    // as defer it as per above.
    wallet.Lock()

    ...
}
Signing data and verifying signatures
import (
    "errors"

    e2wallet "github.com/alex-necsoiu/go-eth-wallet/wallet"
)

func main() {
    wallet, err := e2wallet.OpenWallet("my wallet")
    if err != nil {
        panic(err)
    }
    account, err := wallet.AccountByName("primary account")
    if err != nil {
        panic(err)
    }

    err = account.Unlock([]byte("my secret passphrase"))
    if err != nil {
        panic(err)
    }
    // Always immediately defer locking the wallet to ensure it does not remain unlocked outside of the function.
    defer account.Lock()

    signature, err := account.Sign([]byte("some data to sign"))
    if err != nil {
        panic(err)
    }
    // Wallet should be locked as soon as unlocked operations have finished; it is safe to explicitly call wallet.Lock() as well
    // as defer it as per above.
    account.Lock()
    
    verified := signature.Verify([]byte("some data to sign"), account.PublicKey())
    if !verified {
        panic(errors.New("failed to verify signature"))
    }

    ...
}

Maintainers

Alex Necsoiu: @alex-necsoiu.

Contribute

Contributions welcome. Please check out the issues.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
Package filesystem is an Ethereum wallet store on a local filesystem.
Package filesystem is an Ethereum wallet store on a local filesystem.
Package indexer provides an indexing system between names and UUIDs.
Package indexer provides an indexing system between names and UUIDs.
Package nd is a non-deterministic wallet, where each key is created from random bytes.
Package nd is a non-deterministic wallet, where each key is created from random bytes.
Package scratch provides an in-memory store.
Package scratch provides an in-memory store.
Package types provides generic types for the Ethereum consensus system.
Package types provides generic types for the Ethereum consensus system.

Jump to

Keyboard shortcuts

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