mirror of
https://github.com/LBRYFoundation/lbcwallet.git
synced 2025-08-23 17:47:29 +00:00
Implement the getaccountaddress RPC command.
This commit is contained in:
parent
fa699ef4a5
commit
ac79a59c90
3 changed files with 116 additions and 1 deletions
47
account.go
47
account.go
|
@ -130,6 +130,31 @@ func (a *Account) Rollback(height int32, hash *btcwire.ShaHash) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddressUsed returns whether there are any recorded transactions spending to
|
||||||
|
// a given address. Assumming correct TxStore usage, this will return true iff
|
||||||
|
// there are any transactions with outputs to this address in the blockchain or
|
||||||
|
// the btcd mempool.
|
||||||
|
func (a *Account) AddressUsed(pkHash []byte) bool {
|
||||||
|
// This can be optimized by recording this data as it is read when
|
||||||
|
// opening an account, and keeping it up to date each time a new
|
||||||
|
// received tx arrives.
|
||||||
|
|
||||||
|
a.TxStore.RLock()
|
||||||
|
defer a.TxStore.RUnlock()
|
||||||
|
|
||||||
|
for i := range a.TxStore.s {
|
||||||
|
rtx, ok := a.TxStore.s[i].(*tx.RecvTx)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if bytes.Equal(rtx.ReceiverHash, pkHash) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// CalculateBalance sums the amounts of all unspent transaction
|
// CalculateBalance sums the amounts of all unspent transaction
|
||||||
// outputs to addresses of a wallet and returns the balance as a
|
// outputs to addresses of a wallet and returns the balance as a
|
||||||
// float64.
|
// float64.
|
||||||
|
@ -190,6 +215,28 @@ func (a *Account) CalculateAddressBalance(pubkeyHash []byte, confirms int) float
|
||||||
return float64(bal) / float64(btcutil.SatoshiPerBitcoin)
|
return float64(bal) / float64(btcutil.SatoshiPerBitcoin)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CurrentAddress gets the most recently requested Bitcoin payment address
|
||||||
|
// from an account. If the address has already been used (there is at least
|
||||||
|
// one transaction spending to it in the blockchain or btcd mempool), the next
|
||||||
|
// chained address is returned.
|
||||||
|
func (a *Account) CurrentAddress() (string, error) {
|
||||||
|
a.mtx.RLock()
|
||||||
|
addr, err := a.Wallet.LastChainedAddress()
|
||||||
|
a.mtx.RUnlock()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get next chained address if the last one has already been used.
|
||||||
|
pkHash, _, _ := btcutil.DecodeAddress(addr)
|
||||||
|
if a.AddressUsed(pkHash) {
|
||||||
|
addr, err = a.NewAddress()
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr, err
|
||||||
|
}
|
||||||
|
|
||||||
// ListTransactions returns a slice of maps with details about a recorded
|
// ListTransactions returns a slice of maps with details about a recorded
|
||||||
// transaction. This is intended to be used for listtransactions RPC
|
// transaction. This is intended to be used for listtransactions RPC
|
||||||
// replies.
|
// replies.
|
||||||
|
|
50
cmdmgr.go
50
cmdmgr.go
|
@ -44,6 +44,7 @@ var rpcHandlers = map[string]cmdHandler{
|
||||||
// Standard bitcoind methods (implemented)
|
// Standard bitcoind methods (implemented)
|
||||||
"dumpprivkey": DumpPrivKey,
|
"dumpprivkey": DumpPrivKey,
|
||||||
"getaccount": GetAccount,
|
"getaccount": GetAccount,
|
||||||
|
"getaccountaddress": GetAccountAddress,
|
||||||
"getaddressesbyaccount": GetAddressesByAccount,
|
"getaddressesbyaccount": GetAddressesByAccount,
|
||||||
"getbalance": GetBalance,
|
"getbalance": GetBalance,
|
||||||
"getnewaddress": GetNewAddress,
|
"getnewaddress": GetNewAddress,
|
||||||
|
@ -61,7 +62,6 @@ var rpcHandlers = map[string]cmdHandler{
|
||||||
"backupwallet": Unimplemented,
|
"backupwallet": Unimplemented,
|
||||||
"createmultisig": Unimplemented,
|
"createmultisig": Unimplemented,
|
||||||
"dumpwallet": Unimplemented,
|
"dumpwallet": Unimplemented,
|
||||||
"getaccountaddress": Unimplemented,
|
|
||||||
"getrawchangeaddress": Unimplemented,
|
"getrawchangeaddress": Unimplemented,
|
||||||
"getreceivedbyaccount": Unimplemented,
|
"getreceivedbyaccount": Unimplemented,
|
||||||
"getreceivedbyaddress": Unimplemented,
|
"getreceivedbyaddress": Unimplemented,
|
||||||
|
@ -369,6 +369,54 @@ func GetAccount(frontend chan []byte, icmd btcjson.Cmd) {
|
||||||
ReplySuccess(frontend, cmd.Id(), aname)
|
ReplySuccess(frontend, cmd.Id(), aname)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAccountAddress replies to a getaccountaddress request with the most
|
||||||
|
// recently-created chained address that has not yet been used (does not yet
|
||||||
|
// appear in the blockchain, or any tx that has arrived in the btcd mempool).
|
||||||
|
// If the most recently-requested address has been used, a new address (the
|
||||||
|
// next chained address in the keypool) is used. This can fail if the keypool
|
||||||
|
// runs out (and will return btcjson.ErrWalletKeypoolRanOut if that happens).
|
||||||
|
func GetAccountAddress(frontend chan []byte, icmd btcjson.Cmd) {
|
||||||
|
// Type assert icmd to access parameters.
|
||||||
|
cmd, ok := icmd.(*btcjson.GetAccountAddressCmd)
|
||||||
|
if !ok {
|
||||||
|
ReplyError(frontend, icmd.Id(), &btcjson.ErrInternal)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup account for this request.
|
||||||
|
a, err := accountstore.Account(cmd.Account)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
break
|
||||||
|
|
||||||
|
case ErrAcctNotExist:
|
||||||
|
ReplyError(frontend, cmd.Id(),
|
||||||
|
&btcjson.ErrWalletInvalidAccountName)
|
||||||
|
|
||||||
|
default: // all other non-nil errors
|
||||||
|
e := &btcjson.Error{
|
||||||
|
Code: btcjson.ErrWallet.Code,
|
||||||
|
Message: err.Error(),
|
||||||
|
}
|
||||||
|
ReplyError(frontend, cmd.Id(), e)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch addr, err := a.CurrentAddress(); err {
|
||||||
|
case nil:
|
||||||
|
ReplySuccess(frontend, cmd.Id(), addr)
|
||||||
|
|
||||||
|
case wallet.ErrWalletLocked:
|
||||||
|
ReplyError(frontend, cmd.Id(), &btcjson.ErrWalletKeypoolRanOut)
|
||||||
|
|
||||||
|
default: // all other non-nil errors
|
||||||
|
e := &btcjson.Error{
|
||||||
|
Code: btcjson.ErrWallet.Code,
|
||||||
|
Message: err.Error(),
|
||||||
|
}
|
||||||
|
ReplyError(frontend, cmd.Id(), e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetAddressBalance replies to a getaddressbalance extension request
|
// GetAddressBalance replies to a getaddressbalance extension request
|
||||||
// by replying with the current balance (sum of unspent transaction
|
// by replying with the current balance (sum of unspent transaction
|
||||||
// output amounts) for a single address.
|
// output amounts) for a single address.
|
||||||
|
|
|
@ -851,6 +851,26 @@ func (w *Wallet) NextChainedAddress(bs *BlockStamp) (string, error) {
|
||||||
return addr.paymentAddress(w.net)
|
return addr.paymentAddress(w.net)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LastChainedAddress returns the most recently requested chained
|
||||||
|
// address from calling NextChainedAddress, or the root address if
|
||||||
|
// no chained addresses have been requested.
|
||||||
|
func (w *Wallet) LastChainedAddress() (string, error) {
|
||||||
|
// Lookup pubkey hash for last used chained address.
|
||||||
|
pkHash, ok := w.chainIdxMap[w.highestUsed]
|
||||||
|
if !ok {
|
||||||
|
return "", errors.New("chain index references unknown address")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup address with this pubkey hash.
|
||||||
|
addr, ok := w.addrMap[pkHash]
|
||||||
|
if !ok {
|
||||||
|
return "", errors.New("cannot find address by pubkey hash")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and return payment address from serialized pubkey.
|
||||||
|
return addr.paymentAddress(w.net)
|
||||||
|
}
|
||||||
|
|
||||||
// extendKeypool grows the keypool by n addresses.
|
// extendKeypool grows the keypool by n addresses.
|
||||||
func (w *Wallet) extendKeypool(n uint, aeskey []byte, bs *BlockStamp) error {
|
func (w *Wallet) extendKeypool(n uint, aeskey []byte, bs *BlockStamp) error {
|
||||||
// Get last chained address. New chained addresses will be
|
// Get last chained address. New chained addresses will be
|
||||||
|
|
Loading…
Add table
Reference in a new issue