diff --git a/account.go b/account.go index 66fa187..6be7ada 100644 --- a/account.go +++ b/account.go @@ -711,11 +711,17 @@ func (a *Account) TotalReceived(confirms int) (float64, error) { // confirmed checks whether a transaction at height txHeight has met // minconf confirmations for a blockchain at height curHeight. func confirmed(minconf int, txHeight, curHeight int32) bool { - if minconf == 0 { - return true - } - if txHeight != -1 && int(curHeight-txHeight+1) >= minconf { - return true - } - return false + return confirms(txHeight, curHeight) >= int32(minconf) +} + +// confirms returns the number of confirmations for a transaction in a +// block at height txHeight (or -1 for an unconfirmed tx) given the chain +// height curHeight. +func confirms(txHeight, curHeight int32) int32 { + switch { + case txHeight == -1, txHeight > curHeight: + return 0 + default: + return curHeight - txHeight + 1 + } } diff --git a/acctmgr.go b/acctmgr.go index 4de791e..0ee3c71 100644 --- a/acctmgr.go +++ b/acctmgr.go @@ -18,6 +18,7 @@ package main import ( "container/list" + "encoding/hex" "errors" "fmt" "github.com/conformal/btcutil" @@ -574,19 +575,55 @@ func (am *AccountManager) GetTransaction(txsha *btcwire.ShaHash) []accountTx { // transaction an empty array will be returned. func (am *AccountManager) ListUnspent(minconf, maxconf int, addresses map[string]bool) ([]map[string]interface{}, error) { + bs, err := GetCurBlock() if err != nil { return nil, err } + filter := len(addresses) != 0 + infos := []map[string]interface{}{} for _, a := range am.AllAccounts() { - for _, record := range a.TxStore.UnspentOutputs() { - info := record.TxInfo(a.name, bs.Height, cfg.Net())[0] + for _, rtx := range a.TxStore.UnspentOutputs() { + confs := confirms(rtx.Height(), bs.Height) + switch { + case int(confs) < minconf, int(confs) > maxconf: + continue + } + + _, addrs, _, _ := rtx.Addresses(cfg.Net()) + if filter { + for _, addr := range addrs { + _, ok := addresses[addr.EncodeAddress()] + if ok { + goto include + } + } + continue + } + include: + outpoint := rtx.OutPoint() + info := map[string]interface{}{ + "txid": outpoint.Hash.String(), + "vout": float64(outpoint.Index), + "account": a.Name(), + "scriptPubKey": hex.EncodeToString(rtx.PkScript()), + "amount": float64(rtx.Value()) / 1e8, + "confirmations": float64(confs), + } + + // BUG: this should be a JSON array so that all + // addresses can be included, or removed (and the + // caller extracts addresses from the pkScript). + if len(addrs) > 0 { + info["address"] = addrs[0].EncodeAddress() + } + infos = append(infos, info) } - } + return infos, nil }