github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/accounts/keystore/keystore_wallet.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package keystore 13 14 import ( 15 "math/big" 16 17 sberex "github.com/Sberex/go-sberex" 18 "github.com/Sberex/go-sberex/accounts" 19 "github.com/Sberex/go-sberex/core/types" 20 ) 21 22 // keystoreWallet implements the accounts.Wallet interface for the original 23 // keystore. 24 type keystoreWallet struct { 25 account accounts.Account // Single account contained in this wallet 26 keystore *KeyStore // Keystore where the account originates from 27 } 28 29 // URL implements accounts.Wallet, returning the URL of the account within. 30 func (w *keystoreWallet) URL() accounts.URL { 31 return w.account.URL 32 } 33 34 // Status implements accounts.Wallet, returning whether the account held by the 35 // keystore wallet is unlocked or not. 36 func (w *keystoreWallet) Status() (string, error) { 37 w.keystore.mu.RLock() 38 defer w.keystore.mu.RUnlock() 39 40 if _, ok := w.keystore.unlocked[w.account.Address]; ok { 41 return "Unlocked", nil 42 } 43 return "Locked", nil 44 } 45 46 // Open implements accounts.Wallet, but is a noop for plain wallets since there 47 // is no connection or decryption step necessary to access the list of accounts. 48 func (w *keystoreWallet) Open(passphrase string) error { return nil } 49 50 // Close implements accounts.Wallet, but is a noop for plain wallets since is no 51 // meaningful open operation. 52 func (w *keystoreWallet) Close() error { return nil } 53 54 // Accounts implements accounts.Wallet, returning an account list consisting of 55 // a single account that the plain kestore wallet contains. 56 func (w *keystoreWallet) Accounts() []accounts.Account { 57 return []accounts.Account{w.account} 58 } 59 60 // Contains implements accounts.Wallet, returning whether a particular account is 61 // or is not wrapped by this wallet instance. 62 func (w *keystoreWallet) Contains(account accounts.Account) bool { 63 return account.Address == w.account.Address && (account.URL == (accounts.URL{}) || account.URL == w.account.URL) 64 } 65 66 // Derive implements accounts.Wallet, but is a noop for plain wallets since there 67 // is no notion of hierarchical account derivation for plain keystore accounts. 68 func (w *keystoreWallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) { 69 return accounts.Account{}, accounts.ErrNotSupported 70 } 71 72 // SelfDerive implements accounts.Wallet, but is a noop for plain wallets since 73 // there is no notion of hierarchical account derivation for plain keystore accounts. 74 func (w *keystoreWallet) SelfDerive(base accounts.DerivationPath, chain sberex.ChainStateReader) {} 75 76 // SignHash implements accounts.Wallet, attempting to sign the given hash with 77 // the given account. If the wallet does not wrap this particular account, an 78 // error is returned to avoid account leakage (even though in theory we may be 79 // able to sign via our shared keystore backend). 80 func (w *keystoreWallet) SignHash(account accounts.Account, hash []byte) ([]byte, error) { 81 // Make sure the requested account is contained within 82 if account.Address != w.account.Address { 83 return nil, accounts.ErrUnknownAccount 84 } 85 if account.URL != (accounts.URL{}) && account.URL != w.account.URL { 86 return nil, accounts.ErrUnknownAccount 87 } 88 // Account seems valid, request the keystore to sign 89 return w.keystore.SignHash(account, hash) 90 } 91 92 // SignTx implements accounts.Wallet, attempting to sign the given transaction 93 // with the given account. If the wallet does not wrap this particular account, 94 // an error is returned to avoid account leakage (even though in theory we may 95 // be able to sign via our shared keystore backend). 96 func (w *keystoreWallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { 97 // Make sure the requested account is contained within 98 if account.Address != w.account.Address { 99 return nil, accounts.ErrUnknownAccount 100 } 101 if account.URL != (accounts.URL{}) && account.URL != w.account.URL { 102 return nil, accounts.ErrUnknownAccount 103 } 104 // Account seems valid, request the keystore to sign 105 return w.keystore.SignTx(account, tx, chainID) 106 } 107 108 // SignHashWithPassphrase implements accounts.Wallet, attempting to sign the 109 // given hash with the given account using passphrase as extra authentication. 110 func (w *keystoreWallet) SignHashWithPassphrase(account accounts.Account, passphrase string, hash []byte) ([]byte, error) { 111 // Make sure the requested account is contained within 112 if account.Address != w.account.Address { 113 return nil, accounts.ErrUnknownAccount 114 } 115 if account.URL != (accounts.URL{}) && account.URL != w.account.URL { 116 return nil, accounts.ErrUnknownAccount 117 } 118 // Account seems valid, request the keystore to sign 119 return w.keystore.SignHashWithPassphrase(account, passphrase, hash) 120 } 121 122 // SignTxWithPassphrase implements accounts.Wallet, attempting to sign the given 123 // transaction with the given account using passphrase as extra authentication. 124 func (w *keystoreWallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { 125 // Make sure the requested account is contained within 126 if account.Address != w.account.Address { 127 return nil, accounts.ErrUnknownAccount 128 } 129 if account.URL != (accounts.URL{}) && account.URL != w.account.URL { 130 return nil, accounts.ErrUnknownAccount 131 } 132 // Account seems valid, request the keystore to sign 133 return w.keystore.SignTxWithPassphrase(account, passphrase, tx, chainID) 134 }