wallet

package
v0.0.0-...-d29d52d Latest Latest
Warning

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

Go to latest
Published: Feb 9, 2021 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const (
	CryptoTypeSha256Xor              = CryptoType("sha256-xor")
	CryptoTypeScryptChacha20poly1305 = CryptoType("scrypt-chacha20poly1305")
)

Crypto types

View Source
const (
	// WalletExt  wallet file extension
	WalletExt = "wlt"

	// WalletTimestampFormat  wallet timestamp layout
	WalletTimestampFormat = "2006_01_02"

	// CoinTypeSkycoin skycoin type
	CoinTypeSkycoin CoinType = "skycoin"
	// CoinTypeBitcoin bitcoin type
	CoinTypeBitcoin CoinType = "bitcoin"
)
View Source
const (
	// HoursSelectionTypeManual is used to specify manual hours selection in advanced spend
	HoursSelectionTypeManual = "manual"
	// HoursSelectionTypeAuto is used to specify automatic hours selection in advanced spend
	HoursSelectionTypeAuto = "auto"

	// HoursSelectionModeShare will distribute coin hours equally amongst destinations
	HoursSelectionModeShare = "share"
)
View Source
const NotesExtension = "nts"

NotesExtension file extension of notes

Variables

View Source
var (
	// Version represents the current wallet version
	Version = "0.2"

	// ErrInsufficientBalance is returned if a wallet does not have enough balance for a spend
	ErrInsufficientBalance = NewError(errors.New("balance is not sufficient"))
	// ErrInsufficientHours is returned if a wallet does not have enough hours for a spend with requested hours
	ErrInsufficientHours = NewError(errors.New("hours are not sufficient"))
	// ErrZeroSpend is returned if a transaction is trying to spend 0 coins
	ErrZeroSpend = NewError(errors.New("zero spend amount"))
	// ErrSpendingUnconfirmed is returned if caller attempts to spend unconfirmed outputs
	ErrSpendingUnconfirmed = NewError(errors.New("please spend after your pending transaction is confirmed"))
	// ErrInvalidEncryptedField is returned if a wallet's Meta.encrypted value is invalid.
	ErrInvalidEncryptedField = NewError(errors.New(`encrypted field value is not valid, must be "true", "false" or ""`))
	// ErrWalletEncrypted is returned when trying to generate addresses or sign tx in encrypted wallet
	ErrWalletEncrypted = NewError(errors.New("wallet is encrypted"))
	// ErrWalletNotEncrypted is returned when trying to decrypt unencrypted wallet
	ErrWalletNotEncrypted = NewError(errors.New("wallet is not encrypted"))
	// ErrMissingPassword is returned when trying to create wallet with encryption, but password is not provided.
	ErrMissingPassword = NewError(errors.New("missing password"))
	// ErrMissingEncrypt is returned when trying to create wallet with password, but options.Encrypt is not set.
	ErrMissingEncrypt = NewError(errors.New("missing encrypt"))
	// ErrInvalidPassword is returned if decrypts secrets failed
	ErrInvalidPassword = NewError(errors.New("invalid password"))
	// ErrMissingSeed is returned when trying to create wallet without a seed
	ErrMissingSeed = NewError(errors.New("missing seed"))
	// ErrMissingAuthenticated is returned if try to decrypt a scrypt chacha20poly1305 encrypted wallet, and find no authenticated metadata.
	ErrMissingAuthenticated = NewError(errors.New("missing authenticated metadata"))
	// ErrWrongCryptoType is returned when decrypting wallet with wrong crypto method
	ErrWrongCryptoType = NewError(errors.New("wrong crypto type"))
	// ErrWalletNotExist is returned if a wallet does not exist
	ErrWalletNotExist = NewError(errors.New("wallet doesn't exist"))
	// ErrSeedUsed is returned if a wallet already exists with the same seed
	ErrSeedUsed = NewError(errors.New("a wallet already exists with this seed"))
	// ErrWalletAPIDisabled is returned when trying to do wallet actions while the EnableWalletAPI option is false
	ErrWalletAPIDisabled = NewError(errors.New("wallet api is disabled"))
	// ErrSeedAPIDisabled is returned when trying to get seed of wallet while the EnableWalletAPI or EnableSeedAPI is false
	ErrSeedAPIDisabled = NewError(errors.New("wallet seed api is disabled"))
	// ErrWalletNameConflict represents the wallet name conflict error
	ErrWalletNameConflict = NewError(errors.New("wallet name would conflict with existing wallet, renaming"))
	// ErrInvalidHoursSelectionMode for invalid HoursSelection mode values
	ErrInvalidHoursSelectionMode = NewError(errors.New("invalid hours selection mode"))
	// ErrInvalidHoursSelectionType for invalid HoursSelection type values
	ErrInvalidHoursSelectionType = NewError(errors.New("invalid hours selection type"))
	// ErrUnknownAddress is returned if an address is not found in a wallet
	ErrUnknownAddress = NewError(errors.New("address not found in wallet"))
	// ErrUnknownUxOut is returned if a uxout is not owned by any address in a wallet
	ErrUnknownUxOut = NewError(errors.New("uxout is not owned by any address in the wallet"))
	// ErrNoUnspents is returned if a wallet has no unspents to spend
	ErrNoUnspents = NewError(errors.New("no unspents to spend"))
)

Functions

func CreateNoteFileIfNotExist

func CreateNoteFileIfNotExist(dir string)

CreateNoteFileIfNotExist creates note file if not exist

func DistributeCoinHoursProportional

func DistributeCoinHoursProportional(coins []uint64, hours uint64) ([]uint64, error)

DistributeCoinHoursProportional distributes hours amongst coins proportional to the coins amount

func DistributeSpendHours

func DistributeSpendHours(inputHours, nAddrs uint64, haveChange bool) (uint64, []uint64, uint64)

DistributeSpendHours calculates how many coin hours to transfer to the change address and how many to transfer to each of the other destination addresses. Input hours are split by BurnFactor (rounded down) to meet the fee requirement. The remaining hours are split in half, one half goes to the change address and the other half goes to the destination addresses. If the remaining hours are an odd number, the change address gets the extra hour. If the amount assigned to the destination addresses is not perfectly divisible by the number of destination addresses, the extra hours are distributed to some of these addresses. Returns the number of hours to send to the change address, an array of length nAddrs with the hours to give to each destination address, and a sum of these values.

func NewError

func NewError(err error) error

NewError creates an Error

func NewNotesFilename

func NewNotesFilename() string

NewNotesFilename check for collisions and retry if failure

func NotesFileExist

func NotesFileExist(dir string) (bool, error)

NotesFileExist checks if there're notes exist

Types

type AddressBalance

type AddressBalance map[string]BalancePair

AddressBalance represents a map of address balances

type Balance

type Balance struct {
	Coins uint64 `json:"coins"`
	Hours uint64 `json:"hours"`
}

Balance is consisted of Coins and Hours

func NewBalance

func NewBalance(coins, hours uint64) Balance

NewBalance creates balance

func NewBalanceFromUxOut

func NewBalanceFromUxOut(headTime uint64, ux *coin.UxOut) (Balance, error)

NewBalanceFromUxOut creates Balance from UxOut

func (Balance) Add

func (bal Balance) Add(other Balance) (Balance, error)

Add adds two Balances

func (Balance) Equals

func (bal Balance) Equals(other Balance) bool

Equals compares two Balances

func (Balance) IsZero

func (bal Balance) IsZero() bool

IsZero returns true if the Balance is empty (both coins and hours)

func (Balance) Sub

func (bal Balance) Sub(other Balance) Balance

Sub subtracts other from self and returns the new Balance. Will panic if other is greater than balance, because Coins and Hours are unsigned.

type BalanceGetter

type BalanceGetter interface {
	GetBalanceOfAddrs(addrs []cipher.Address) ([]BalancePair, error)
}

BalanceGetter interface for getting the balance of given addresses

type BalancePair

type BalancePair struct {
	Confirmed Balance `json:"confirmed"`
	Predicted Balance `json:"predicted"` //do "pending"
}

BalancePair records the confirmed and predicted balance

type CoinType

type CoinType string

CoinType represents the wallet coin type

type Config

type Config struct {
	WalletDir       string
	CryptoType      CryptoType
	EnableWalletAPI bool
	EnableSeedAPI   bool
}

Config wallet service config

type CreateTransactionParams

type CreateTransactionParams struct {
	IgnoreUnconfirmed bool
	HoursSelection    HoursSelection
	Wallet            CreateTransactionWalletParams
	ChangeAddress     *cipher.Address
	To                []coin.TransactionOutput
}

CreateTransactionParams defines control parameters for transaction construction

func (CreateTransactionParams) Validate

func (c CreateTransactionParams) Validate() error

Validate validates CreateTransactionParams

type CreateTransactionWalletParams

type CreateTransactionWalletParams struct {
	ID        string
	UxOuts    []cipher.SHA256
	Addresses []cipher.Address
	Password  []byte
}

CreateTransactionWalletParams defines a wallet to spend from and optionally which addresses in the wallet

type CryptoType

type CryptoType string

CryptoType represents the type of crypto name

func CryptoTypeFromString

func CryptoTypeFromString(s string) (CryptoType, error)

CryptoTypeFromString converts string to CryptoType

type Entry

type Entry struct {
	Address cipher.Address
	Public  cipher.PubKey
	Secret  cipher.SecKey
}

Entry represents the wallet entry

func (*Entry) Verify

func (we *Entry) Verify() error

Verify checks that the public key is derivable from the secret key, and that the public key is associated with the address

func (*Entry) VerifyPublic

func (we *Entry) VerifyPublic() error

VerifyPublic checks that the public key is associated with the address

type Error

type Error struct {
	// contains filtered or unexported fields
}

Error wraps wallet related errors

type HoursSelection

type HoursSelection struct {
	Type        string
	Mode        string
	ShareFactor *decimal.Decimal
}

HoursSelection defines options for hours distribution

type Note

type Note struct {
	TxID  string
	Value string
}

Note note struct

type Notes

type Notes []Note

Notes array of notes

func LoadNotes

func LoadNotes(dir string) (Notes, error)

LoadNotes loads notes from given dir

func (*Notes) Save

func (notes *Notes) Save(dir string, fileName string) error

Save persists notes to disk

func (*Notes) SaveNote

func (notes *Notes) SaveNote(dir string, note Note) error

SaveNote save new note

func (Notes) ToReadable

func (notes Notes) ToReadable() ReadableNotes

ToReadable converts Notes to readable notes

type Options

type Options struct {
	Coin       CoinType   // coin type, skycoin, bitcoin, etc.
	Label      string     // wallet label.
	Seed       string     // wallet seed.
	Encrypt    bool       // whether the wallet need to be encrypted.
	Password   []byte     // password that would be used for encryption, and would only be used when 'Encrypt' is true.
	CryptoType CryptoType // wallet encryption type, scrypt-chacha20poly1305 or sha256-xor.
	ScanN      uint64     // number of addresses that're going to be scanned
}

Options options that could be used when creating a wallet

type ReadableEntries

type ReadableEntries []ReadableEntry

ReadableEntries array of ReadableEntry

type ReadableEntry

type ReadableEntry struct {
	Address string `json:"address"`
	Public  string `json:"public_key"`
	Secret  string `json:"secret_key"`
}

ReadableEntry wallet entry with json tags

func GetBitcoinWalletEntry

func GetBitcoinWalletEntry(pub cipher.PubKey, sec cipher.SecKey) ReadableEntry

GetBitcoinWalletEntry returns a ReadableEntry in Bitcoin format

func GetSkycoinWalletEntry

func GetSkycoinWalletEntry(pub cipher.PubKey, sec cipher.SecKey) ReadableEntry

GetSkycoinWalletEntry returns a ReadableEntry in Skycoin format

func LoadReadableEntry

func LoadReadableEntry(filename string) (ReadableEntry, error)

LoadReadableEntry load readable wallet entry from given file

func NewReadableEntry

func NewReadableEntry(w Entry) ReadableEntry

NewReadableEntry creates readable wallet entry

func NewReadableEntryFromPubkey

func NewReadableEntryFromPubkey(pub string) ReadableEntry

NewReadableEntryFromPubkey creates a ReadableWalletEntry given a pubkey hex string. The Secret field is left empty.

func (*ReadableEntry) Save

func (re *ReadableEntry) Save(filename string) error

Save persists to disk

type ReadableNote

type ReadableNote struct {
	TransactionID string `json:"transaction_id"`
	ActualNote    string `json:"note_val"`
}

ReadableNote readable note struct

func NewReadableNote

func NewReadableNote(note Note) ReadableNote

NewReadableNote creates readable note

type ReadableNotes

type ReadableNotes []ReadableNote

ReadableNotes readable notes

func LoadReadableNotes

func LoadReadableNotes(filename string) (*ReadableNotes, error)

LoadReadableNotes loads readable notes from given file

func NewReadableNotesFromNotes

func NewReadableNotesFromNotes(w Notes) ReadableNotes

NewReadableNotesFromNotes creates readable notes from notes

func (*ReadableNotes) Load

func (rns *ReadableNotes) Load(filename string) error

Load loads readable notes from given file

func (*ReadableNotes) Save

func (rns *ReadableNotes) Save(filename string) error

Save persists readable notes to disk

func (ReadableNotes) ToNotes

func (rns ReadableNotes) ToNotes() ([]Note, error)

ToNotes converts from readable notes to Notes

type ReadableWallet

type ReadableWallet struct {
	Meta    map[string]string `json:"meta"`
	Entries ReadableEntries   `json:"entries"`
}

ReadableWallet used for [de]serialization of a Wallet

func CreateAddresses

func CreateAddresses(coinType CoinType, seed string, genCount int, hideSecretKey bool) (*ReadableWallet, error)

CreateAddresses genCount addresses deterministically from seed. coinType is either CoinTypeBitcoin or CoinTypeSkycoin. hideSecretKey will hide the secret key from the output.

func LoadReadableWallet

func LoadReadableWallet(filename string) (*ReadableWallet, error)

LoadReadableWallet loads a ReadableWallet from disk

func NewReadableWallet

func NewReadableWallet(w *Wallet) *ReadableWallet

NewReadableWallet creates readable wallet

func (*ReadableWallet) Erase

func (rw *ReadableWallet) Erase()

Erase remove sensitive data

func (*ReadableWallet) Load

func (rw *ReadableWallet) Load(filename string) error

Load loads from filename

func (*ReadableWallet) Save

func (rw *ReadableWallet) Save(filename string) error

Save saves to filename

func (*ReadableWallet) ToWallet

func (rw *ReadableWallet) ToWallet() (*Wallet, error)

ToWallet convert readable wallet to Wallet

type Service

type Service struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

Service wallet service struct

func NewService

func NewService(c Config) (*Service, error)

NewService new wallet service

func (*Service) CreateAndSignTransaction

func (serv *Service) CreateAndSignTransaction(wltID string, password []byte, auxs coin.AddressUxOuts, headTime, coins uint64, dest cipher.Address) (*coin.Transaction, error)

CreateAndSignTransaction creates and signs a transaction from wallet. Set the password as nil if the wallet is not encrypted, otherwise the password must be provided

func (*Service) CreateAndSignTransactionAdvanced

func (serv *Service) CreateAndSignTransactionAdvanced(params CreateTransactionParams, auxs coin.AddressUxOuts, headTime uint64) (*coin.Transaction, []UxBalance, error)

CreateAndSignTransactionAdvanced creates and signs a transaction based upon CreateTransactionParams. Set the password as nil if the wallet is not encrypted, otherwise the password must be provided

func (*Service) CreateWallet

func (serv *Service) CreateWallet(wltName string, options Options, bg BalanceGetter) (*Wallet, error)

CreateWallet creates a wallet with the given wallet file name and options. A address will be automatically generated by default.

func (*Service) DecryptWallet

func (serv *Service) DecryptWallet(wltID string, password []byte) (*Wallet, error)

DecryptWallet decrypts wallet with password

func (*Service) EncryptWallet

func (serv *Service) EncryptWallet(wltID string, password []byte) (*Wallet, error)

EncryptWallet encrypts wallet with password

func (*Service) GetAddresses

func (serv *Service) GetAddresses(wltID string) ([]cipher.Address, error)

GetAddresses returns all addresses in given wallet

func (*Service) GetWallet

func (serv *Service) GetWallet(wltID string) (*Wallet, error)

GetWallet returns wallet by id

func (*Service) GetWalletSeed

func (serv *Service) GetWalletSeed(wltID string, password []byte) (string, error)

GetWalletSeed returns seed of encrypted wallet of given wallet id Returns ErrWalletNotEncrypted if it's not encrypted

func (*Service) GetWallets

func (serv *Service) GetWallets() (Wallets, error)

GetWallets returns all wallet clones

func (*Service) NewAddresses

func (serv *Service) NewAddresses(wltID string, password []byte, num uint64) ([]cipher.Address, error)

NewAddresses generate address entries in given wallet, return nil if wallet does not exist. Set password as nil if the wallet is not encrypted, otherwise the password must be provided.

func (*Service) ReloadWallets

func (serv *Service) ReloadWallets() error

ReloadWallets reload wallets

func (*Service) Remove

func (serv *Service) Remove(wltID string) error

Remove removes wallet of given wallet id from the service

func (*Service) UpdateWalletLabel

func (serv *Service) UpdateWalletLabel(wltID, label string) error

UpdateWalletLabel updates the wallet label

func (*Service) ViewWallet

func (serv *Service) ViewWallet(w *Wallet, password []byte, f func(w *Wallet) error) error

ViewWallet will unlock a wallet for viewing if necessary, and call f

type UxBalance

type UxBalance struct {
	Hash           cipher.SHA256
	BkSeq          uint64
	Time           uint64
	Address        cipher.Address
	Coins          uint64
	InitialHours   uint64
	Hours          uint64
	SrcTransaction cipher.SHA256
}

UxBalance is an intermediate representation of a UxOut for sorting and spend choosing

func ChooseSpends

func ChooseSpends(uxa []UxBalance, coins, hours uint64, sortStrategy func([]UxBalance)) ([]UxBalance, error)

ChooseSpends chooses uxouts from a list of uxouts. It first chooses the uxout with the most number of coins that has nonzero coinhours. It then chooses uxouts with zero coinhours, ordered by sortStrategy It then chooses remaining uxouts with nonzero coinhours, ordered by sortStrategy

func ChooseSpendsMaximizeUxOuts

func ChooseSpendsMaximizeUxOuts(uxa []UxBalance, coins, hours uint64) ([]UxBalance, error)

ChooseSpendsMaximizeUxOuts chooses uxout spends to satisfy an amount, using the most number of uxouts See the pros and cons of ChooseSpendsMinimizeUxOuts. This should be the default mode, because this keeps the unconfirmed pool smaller which will allow the network to scale better.

func ChooseSpendsMinimizeUxOuts

func ChooseSpendsMinimizeUxOuts(uxa []UxBalance, coins, hours uint64) ([]UxBalance, error)

ChooseSpendsMinimizeUxOuts chooses uxout spends to satisfy an amount, using the least number of uxouts

-- PRO: Allows more frequent spending, less waiting for confirmations, useful for exchanges.
-- PRO: When transaction is volume is higher, transactions are prioritized by fee/size. Minimizing uxouts minimizes size.
-- CON: Would make the unconfirmed pool grow larger.

Users with high transaction frequency will want to use this so that they will not need to wait as frequently for unconfirmed spends to complete before sending more. Alternatively, or in addition to this, they should batch sends into single transactions.

func NewUxBalance

func NewUxBalance(headTime uint64, ux coin.UxOut) (UxBalance, error)

NewUxBalance converts coin.UxOut to UxBalance. headTime is required to calculate coin hours.

func NewUxBalances

func NewUxBalances(headTime uint64, uxa coin.UxArray) ([]UxBalance, error)

NewUxBalances converts coin.UxArray to []UxBalance. headTime is required to calculate coin hours.

type Validator

type Validator interface {
	// checks if any of the given addresses has unconfirmed spending transactions
	HasUnconfirmedSpendTx(addr []cipher.Address) (bool, error)
}

Validator validate if the wallet be able to create spending transaction

type Wallet

type Wallet struct {
	Meta    map[string]string
	Entries []Entry
}

Wallet is consisted of meta and entries. Meta field records items that are not deterministic, like filename, lable, wallet type, secrets, etc. Entries field stores the address entries that are deterministically generated from seed. For wallet encryption

func Load

func Load(wltFile string) (*Wallet, error)

Load loads wallet from a given file

func NewWallet

func NewWallet(wltName string, opts Options) (*Wallet, error)

NewWallet creates wallet without scanning addresses

func NewWalletScanAhead

func NewWalletScanAhead(wltName string, opts Options, bg BalanceGetter) (*Wallet, error)

NewWalletScanAhead creates wallet and scan ahead N addresses

func (*Wallet) AddEntry

func (w *Wallet) AddEntry(entry Entry) error

AddEntry adds new entry

func (*Wallet) CreateAndSignTransaction

func (w *Wallet) CreateAndSignTransaction(auxs coin.AddressUxOuts, headTime, coins uint64, dest cipher.Address) (*coin.Transaction, error)

CreateAndSignTransaction Creates a Transaction spending coins and hours from wallet

func (*Wallet) CreateAndSignTransactionAdvanced

func (w *Wallet) CreateAndSignTransactionAdvanced(params CreateTransactionParams, auxs coin.AddressUxOuts, headTime uint64) (*coin.Transaction, []UxBalance, error)

CreateAndSignTransactionAdvanced creates and signs a transaction based upon CreateTransactionParams. Set the password as nil if the wallet is not encrypted, otherwise the password must be provided. NOTE: Caller must ensure that auxs correspond to params.Wallet.Addresses and params.Wallet.UxOuts options

func (*Wallet) Filename

func (w *Wallet) Filename() string

Filename gets the wallet filename

func (*Wallet) GenerateAddresses

func (w *Wallet) GenerateAddresses(num uint64) ([]cipher.Address, error)

GenerateAddresses generates addresses

func (*Wallet) GetAddresses

func (w *Wallet) GetAddresses() []cipher.Address

GetAddresses returns all addresses in wallet

func (*Wallet) GetEntry

func (w *Wallet) GetEntry(a cipher.Address) (Entry, bool)

GetEntry returns entry of given address

func (*Wallet) GuardUpdate

func (w *Wallet) GuardUpdate(password []byte, fn func(w *Wallet) error) error

GuardUpdate executes a function within the context of a read-wirte managed decrypted wallet. Returns ErrWalletNotEncrypted if wallet is not encrypted.

func (*Wallet) GuardView

func (w *Wallet) GuardView(password []byte, f func(w *Wallet) error) error

GuardView executes a function within the context of a read-only managed decrypted wallet. Returns ErrWalletNotEncrypted if wallet is not encrypted.

func (*Wallet) IsEncrypted

func (w *Wallet) IsEncrypted() bool

IsEncrypted checks whether the wallet is encrypted.

func (*Wallet) Label

func (w *Wallet) Label() string

Label gets the wallet label

func (*Wallet) Lock

func (w *Wallet) Lock(password []byte, cryptoType CryptoType) error

Lock encrypts the wallet with the given password and specific crypto type

func (*Wallet) Save

func (w *Wallet) Save(dir string) error

Save saves the wallet to given dir

func (*Wallet) ScanAddresses

func (w *Wallet) ScanAddresses(scanN uint64, bg BalanceGetter) error

ScanAddresses scans ahead N addresses to find one with none-zero coins.

func (*Wallet) Type

func (w *Wallet) Type() string

Type gets the wallet type

func (*Wallet) Unlock

func (w *Wallet) Unlock(password []byte) (*Wallet, error)

Unlock decrypts the wallet into a temporary decrypted copy of the wallet Returns error if the decryption fails The temporary decrypted wallet should be erased from memory when done.

func (*Wallet) Validate

func (w *Wallet) Validate() error

Validate validates the wallet

func (*Wallet) Version

func (w *Wallet) Version() string

Version gets the wallet version

type Wallets

type Wallets map[string]*Wallet

Wallets wallets map

func LoadWallets

func LoadWallets(dir string) (Wallets, error)

LoadWallets Loads all wallets contained in wallet dir. If any regular file in wallet dir fails to load, loading is aborted and error returned. Only files with extension WalletExt are considered.

func (Wallets) ToReadable

func (wlts Wallets) ToReadable() []*ReadableWallet

ToReadable converts Wallets to *ReadableWallet array

Jump to

Keyboard shortcuts

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