parent
99c986e21f
commit
7ec4e96c6b
1 changed files with 99 additions and 1 deletions
100
rpcserver.go
100
rpcserver.go
|
@ -104,6 +104,7 @@ var rpcHandlers = map[string]cmdHandler{
|
||||||
"importprivkey": ImportPrivKey,
|
"importprivkey": ImportPrivKey,
|
||||||
"keypoolrefill": KeypoolRefill,
|
"keypoolrefill": KeypoolRefill,
|
||||||
"listaccounts": ListAccounts,
|
"listaccounts": ListAccounts,
|
||||||
|
"listreceivedbyaddress": ListReceivedByAddress,
|
||||||
"listsinceblock": ListSinceBlock,
|
"listsinceblock": ListSinceBlock,
|
||||||
"listtransactions": ListTransactions,
|
"listtransactions": ListTransactions,
|
||||||
"listunspent": ListUnspent,
|
"listunspent": ListUnspent,
|
||||||
|
@ -131,7 +132,6 @@ var rpcHandlers = map[string]cmdHandler{
|
||||||
"listaddressgroupings": Unimplemented,
|
"listaddressgroupings": Unimplemented,
|
||||||
"listlockunspent": Unimplemented,
|
"listlockunspent": Unimplemented,
|
||||||
"listreceivedbyaccount": Unimplemented,
|
"listreceivedbyaccount": Unimplemented,
|
||||||
"listreceivedbyaddress": Unimplemented,
|
|
||||||
"lockunspent": Unimplemented,
|
"lockunspent": Unimplemented,
|
||||||
"move": Unimplemented,
|
"move": Unimplemented,
|
||||||
"setaccount": Unimplemented,
|
"setaccount": Unimplemented,
|
||||||
|
@ -972,6 +972,104 @@ func ListAccounts(icmd btcjson.Cmd) (interface{}, error) {
|
||||||
return AcctMgr.ListAccounts(cmd.MinConf), nil
|
return AcctMgr.ListAccounts(cmd.MinConf), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListReceivedByAddress handles a listreceivedbyaddress request by returning
|
||||||
|
// a slice of objects, each one containing:
|
||||||
|
// "account": the account of the receiving address;
|
||||||
|
// "address": the receiving address;
|
||||||
|
// "amount": total amount received by the address;
|
||||||
|
// "confirmations": number of confirmations of the most recent transaction.
|
||||||
|
// It takes two parameters:
|
||||||
|
// "minconf": minimum number of confirmations to consider a transaction -
|
||||||
|
// default: one;
|
||||||
|
// "includeempty": whether or not to include addresses that have no transactions -
|
||||||
|
// default: false.
|
||||||
|
func ListReceivedByAddress(icmd btcjson.Cmd) (interface{}, error) {
|
||||||
|
cmd, ok := icmd.(*btcjson.ListReceivedByAddressCmd)
|
||||||
|
if !ok {
|
||||||
|
return nil, btcjson.ErrInternal
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intermediate data for each address.
|
||||||
|
type AddrData struct {
|
||||||
|
// Associated account.
|
||||||
|
account *Account
|
||||||
|
// Total amount received.
|
||||||
|
amount btcutil.Amount
|
||||||
|
// Number of confirmations of the last transaction.
|
||||||
|
confirmations int32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intermediate data for all addresses.
|
||||||
|
allAddrData := make(map[string]AddrData)
|
||||||
|
|
||||||
|
bs, err := GetCurBlock()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, account := range AcctMgr.AllAccounts() {
|
||||||
|
if cmd.IncludeEmpty {
|
||||||
|
// Create an AddrData entry for each active address in the account.
|
||||||
|
// Otherwise we'll just get addresses from transactions later.
|
||||||
|
for _, address := range account.SortedActivePaymentAddresses() {
|
||||||
|
// There might be duplicates, just overwrite them.
|
||||||
|
allAddrData[address] = AddrData{account: account}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, record := range account.TxStore.Records() {
|
||||||
|
for _, credit := range record.Credits() {
|
||||||
|
confirmations := credit.Confirmations(bs.Height)
|
||||||
|
if !credit.Confirmed(cmd.MinConf, bs.Height) {
|
||||||
|
// Not enough confirmations, skip the current block.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_, addresses, _, err := credit.Addresses(activeNet.Params)
|
||||||
|
if err != nil {
|
||||||
|
// Unusable address, skip it.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, address := range addresses {
|
||||||
|
addrStr := address.EncodeAddress()
|
||||||
|
addrData, ok := allAddrData[addrStr]
|
||||||
|
if ok {
|
||||||
|
// Address already present, check account consistency.
|
||||||
|
if addrData.account != account {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"Address %v in both account %v and account %v",
|
||||||
|
addrStr, addrData.account.name, account.name)
|
||||||
|
}
|
||||||
|
addrData.amount += credit.Amount()
|
||||||
|
// Always overwrite confirmations with newer ones.
|
||||||
|
addrData.confirmations = confirmations
|
||||||
|
} else {
|
||||||
|
addrData = AddrData{
|
||||||
|
account: account,
|
||||||
|
amount: credit.Amount(),
|
||||||
|
confirmations: confirmations,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allAddrData[addrStr] = addrData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Massage address data into output format.
|
||||||
|
numAddresses := len(allAddrData)
|
||||||
|
ret := make([]btcjson.ListReceivedByAddressResult, numAddresses, numAddresses)
|
||||||
|
idx := 0
|
||||||
|
for address, addrData := range allAddrData {
|
||||||
|
ret[idx] = btcjson.ListReceivedByAddressResult{
|
||||||
|
Account: addrData.account.name,
|
||||||
|
Address: address,
|
||||||
|
Amount: addrData.amount.ToUnit(btcutil.AmountBTC),
|
||||||
|
Confirmations: uint64(addrData.confirmations),
|
||||||
|
}
|
||||||
|
idx++
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ListSinceBlock handles a listsinceblock request by returning an array of maps
|
// ListSinceBlock handles a listsinceblock request by returning an array of maps
|
||||||
// with details of sent and received wallet transactions since the given block.
|
// with details of sent and received wallet transactions since the given block.
|
||||||
func ListSinceBlock(icmd btcjson.Cmd) (interface{}, error) {
|
func ListSinceBlock(icmd btcjson.Cmd) (interface{}, error) {
|
||||||
|
|
Loading…
Reference in a new issue