Update RPCs to support multi-scope multi-account [WIP] #26
17 changed files with 1002 additions and 1097 deletions
|
@ -31,26 +31,18 @@ type BlockFilterer struct {
|
|||
// Params specifies the chain params of the current network.
|
||||
Params *chaincfg.Params
|
||||
|
||||
// ExReverseFilter holds a reverse index mapping an external address to
|
||||
// ReverseFilter holds a reverse index mapping an external address to
|
||||
// the scoped index from which it was derived.
|
||||
ExReverseFilter map[string]waddrmgr.ScopedIndex
|
||||
|
||||
// InReverseFilter holds a reverse index mapping an internal address to
|
||||
// the scoped index from which it was derived.
|
||||
InReverseFilter map[string]waddrmgr.ScopedIndex
|
||||
ReverseFilter map[string]waddrmgr.ScopedIndex
|
||||
|
||||
// WathcedOutPoints is a global set of outpoints being tracked by the
|
||||
// wallet. This allows the block filterer to check for spends from an
|
||||
// outpoint we own.
|
||||
WatchedOutPoints map[wire.OutPoint]btcutil.Address
|
||||
|
||||
// FoundExternal is a two-layer map recording the scope and index of
|
||||
// FoundAddresses is a two-layer map recording the scope and index of
|
||||
// external addresses found in a single block.
|
||||
FoundExternal map[waddrmgr.KeyScope]map[uint32]struct{}
|
||||
|
||||
// FoundInternal is a two-layer map recording the scope and index of
|
||||
// internal addresses found in a single block.
|
||||
FoundInternal map[waddrmgr.KeyScope]map[uint32]struct{}
|
||||
FoundAddresses map[waddrmgr.ScopedIndex]struct{}
|
||||
|
||||
// FoundOutPoints is a set of outpoints found in a single block whose
|
||||
// address belongs to the wallet.
|
||||
|
@ -71,31 +63,20 @@ func NewBlockFilterer(params *chaincfg.Params,
|
|||
|
||||
// Construct a reverse index by address string for the requested
|
||||
// external addresses.
|
||||
nExAddrs := len(req.ExternalAddrs)
|
||||
exReverseFilter := make(map[string]waddrmgr.ScopedIndex, nExAddrs)
|
||||
for scopedIndex, addr := range req.ExternalAddrs {
|
||||
exReverseFilter[addr.EncodeAddress()] = scopedIndex
|
||||
nAddrs := len(req.Addresses)
|
||||
reverseFilter := make(map[string]waddrmgr.ScopedIndex, nAddrs)
|
||||
for scopedIndex, addr := range req.Addresses {
|
||||
reverseFilter[addr.EncodeAddress()] = scopedIndex
|
||||
}
|
||||
|
||||
// Construct a reverse index by address string for the requested
|
||||
// internal addresses.
|
||||
nInAddrs := len(req.InternalAddrs)
|
||||
inReverseFilter := make(map[string]waddrmgr.ScopedIndex, nInAddrs)
|
||||
for scopedIndex, addr := range req.InternalAddrs {
|
||||
inReverseFilter[addr.EncodeAddress()] = scopedIndex
|
||||
}
|
||||
|
||||
foundExternal := make(map[waddrmgr.KeyScope]map[uint32]struct{})
|
||||
foundInternal := make(map[waddrmgr.KeyScope]map[uint32]struct{})
|
||||
foundAddresses := make(map[waddrmgr.ScopedIndex]struct{})
|
||||
foundOutPoints := make(map[wire.OutPoint]btcutil.Address)
|
||||
|
||||
return &BlockFilterer{
|
||||
Params: params,
|
||||
ExReverseFilter: exReverseFilter,
|
||||
InReverseFilter: inReverseFilter,
|
||||
ReverseFilter: reverseFilter,
|
||||
WatchedOutPoints: req.WatchedOutPoints,
|
||||
FoundExternal: foundExternal,
|
||||
FoundInternal: foundInternal,
|
||||
FoundAddresses: foundAddresses,
|
||||
FoundOutPoints: foundOutPoints,
|
||||
}
|
||||
}
|
||||
|
@ -183,12 +164,8 @@ func (bf *BlockFilterer) FilterOutputAddrs(addrs []btcutil.Address) bool {
|
|||
var isRelevant bool
|
||||
for _, addr := range addrs {
|
||||
addrStr := addr.EncodeAddress()
|
||||
if scopedIndex, ok := bf.ExReverseFilter[addrStr]; ok {
|
||||
bf.foundExternal(scopedIndex)
|
||||
isRelevant = true
|
||||
}
|
||||
if scopedIndex, ok := bf.InReverseFilter[addrStr]; ok {
|
||||
bf.foundInternal(scopedIndex)
|
||||
if scopedIndex, ok := bf.ReverseFilter[addrStr]; ok {
|
||||
bf.found(scopedIndex)
|
||||
isRelevant = true
|
||||
}
|
||||
}
|
||||
|
@ -196,22 +173,9 @@ func (bf *BlockFilterer) FilterOutputAddrs(addrs []btcutil.Address) bool {
|
|||
return isRelevant
|
||||
}
|
||||
|
||||
// foundExternal marks the scoped index as found within the block filterer's
|
||||
// found marks the scoped index as found within the block filterer's
|
||||
// FoundExternal map. If this the first index found for a particular scope, the
|
||||
// scope's second layer map will be initialized before marking the index.
|
||||
func (bf *BlockFilterer) foundExternal(scopedIndex waddrmgr.ScopedIndex) {
|
||||
if _, ok := bf.FoundExternal[scopedIndex.Scope]; !ok {
|
||||
bf.FoundExternal[scopedIndex.Scope] = make(map[uint32]struct{})
|
||||
}
|
||||
bf.FoundExternal[scopedIndex.Scope][scopedIndex.Index] = struct{}{}
|
||||
}
|
||||
|
||||
// foundInternal marks the scoped index as found within the block filterer's
|
||||
// FoundInternal map. If this the first index found for a particular scope, the
|
||||
// scope's second layer map will be initialized before marking the index.
|
||||
func (bf *BlockFilterer) foundInternal(scopedIndex waddrmgr.ScopedIndex) {
|
||||
if _, ok := bf.FoundInternal[scopedIndex.Scope]; !ok {
|
||||
bf.FoundInternal[scopedIndex.Scope] = make(map[uint32]struct{})
|
||||
}
|
||||
bf.FoundInternal[scopedIndex.Scope][scopedIndex.Index] = struct{}{}
|
||||
func (bf *BlockFilterer) found(scopedIndex waddrmgr.ScopedIndex) {
|
||||
bf.FoundAddresses[scopedIndex] = struct{}{}
|
||||
}
|
||||
|
|
|
@ -75,8 +75,7 @@ type (
|
|||
// is also included to monitor for spends.
|
||||
FilterBlocksRequest struct {
|
||||
Blocks []wtxmgr.BlockMeta
|
||||
ExternalAddrs map[waddrmgr.ScopedIndex]btcutil.Address
|
||||
InternalAddrs map[waddrmgr.ScopedIndex]btcutil.Address
|
||||
Addresses map[waddrmgr.ScopedIndex]btcutil.Address
|
||||
WatchedOutPoints map[wire.OutPoint]btcutil.Address
|
||||
}
|
||||
|
||||
|
@ -88,12 +87,11 @@ type (
|
|||
// caller can reinitiate a request for the subsequent block after
|
||||
// updating the addresses of interest.
|
||||
FilterBlocksResponse struct {
|
||||
BatchIndex uint32
|
||||
BlockMeta wtxmgr.BlockMeta
|
||||
FoundExternalAddrs map[waddrmgr.KeyScope]map[uint32]struct{}
|
||||
FoundInternalAddrs map[waddrmgr.KeyScope]map[uint32]struct{}
|
||||
FoundOutPoints map[wire.OutPoint]btcutil.Address
|
||||
RelevantTxns []*wire.MsgTx
|
||||
BatchIndex uint32
|
||||
BlockMeta wtxmgr.BlockMeta
|
||||
FoundAddresses map[waddrmgr.ScopedIndex]struct{}
|
||||
FoundOutPoints map[wire.OutPoint]btcutil.Address
|
||||
RelevantTxns []*wire.MsgTx
|
||||
}
|
||||
|
||||
// BlockDisconnected is a notifcation that the block described by the
|
||||
|
|
|
@ -12,22 +12,12 @@ func buildFilterBlocksWatchList(req *FilterBlocksRequest) ([][]byte, error) {
|
|||
// Construct a watch list containing the script addresses of all
|
||||
// internal and external addresses that were requested, in addition to
|
||||
// the set of outpoints currently being watched.
|
||||
watchListSize := len(req.ExternalAddrs) +
|
||||
len(req.InternalAddrs) +
|
||||
watchListSize := len(req.Addresses) +
|
||||
len(req.WatchedOutPoints)
|
||||
|
||||
watchList := make([][]byte, 0, watchListSize)
|
||||
|
||||
for _, addr := range req.ExternalAddrs {
|
||||
p2shAddr, err := txscript.PayToAddrScript(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
watchList = append(watchList, p2shAddr)
|
||||
}
|
||||
|
||||
for _, addr := range req.InternalAddrs {
|
||||
for _, addr := range req.Addresses {
|
||||
p2shAddr, err := txscript.PayToAddrScript(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
11
chain/rpc.go
11
chain/rpc.go
|
@ -270,12 +270,11 @@ func (c *RPCClient) FilterBlocks(
|
|||
// `BatchIndex` is returned so that the caller can compute the
|
||||
// *next* block from which to begin again.
|
||||
resp := &FilterBlocksResponse{
|
||||
BatchIndex: uint32(i),
|
||||
BlockMeta: blk,
|
||||
FoundExternalAddrs: blockFilterer.FoundExternal,
|
||||
FoundInternalAddrs: blockFilterer.FoundInternal,
|
||||
FoundOutPoints: blockFilterer.FoundOutPoints,
|
||||
RelevantTxns: blockFilterer.RelevantTxns,
|
||||
BatchIndex: uint32(i),
|
||||
BlockMeta: blk,
|
||||
FoundAddresses: blockFilterer.FoundAddresses,
|
||||
FoundOutPoints: blockFilterer.FoundOutPoints,
|
||||
RelevantTxns: blockFilterer.RelevantTxns,
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
|
|
10
go.mod
10
go.mod
|
@ -4,18 +4,15 @@ require (
|
|||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/jessevdk/go-flags v1.5.0
|
||||
github.com/jrick/logrotate v1.0.0
|
||||
github.com/lbryio/lbcd v0.22.102
|
||||
github.com/lbryio/lbcutil v1.0.202-rc3
|
||||
github.com/lbryio/lbcd v0.22.115
|
||||
github.com/lbryio/lbcutil v1.0.202
|
||||
github.com/lightningnetwork/lnd/clock v1.1.0
|
||||
github.com/stretchr/testify v1.7.1
|
||||
go.etcd.io/bbolt v1.3.6
|
||||
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898
|
||||
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2
|
||||
golang.org/x/tools v0.1.10
|
||||
google.golang.org/grpc v1.46.2
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -43,10 +40,7 @@ require (
|
|||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
||||
golang.org/x/term v0.0.0-20220411215600-e5f449aeb171 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220524023933-508584e28198 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
)
|
||||
|
||||
|
|
43
go.sum
43
go.sum
|
@ -1,5 +1,4 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
|
@ -17,7 +16,6 @@ github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqR
|
|||
github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
|
||||
|
@ -33,10 +31,6 @@ github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
|||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4=
|
||||
github.com/cockroachdb/datadriven v1.0.1-0.20211007161720-b558070c3be0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4=
|
||||
github.com/cockroachdb/datadriven v1.0.1-0.20220214170620-9913f5bc19b7/go.mod h1:hi0MtSY3AYDQNDi83kDkMH5/yqM/CsIrsOITkSoH7KI=
|
||||
|
@ -74,9 +68,7 @@ github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZi
|
|||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
|
||||
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
|
||||
|
@ -89,7 +81,6 @@ github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TB
|
|||
github.com/getsentry/sentry-go v0.13.0 h1:20dgTiUSfxRB/EhMPtxcL9ZEbM1ZdR+W/7f7NWD+xWo=
|
||||
github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0=
|
||||
github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
|
||||
|
@ -121,9 +112,7 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
|||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
|
@ -135,7 +124,6 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
|||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
|
@ -144,7 +132,6 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
|
@ -200,10 +187,10 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
|||
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
|
||||
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/lbryio/lbcd v0.22.102 h1:UaJ0Tpurf6y5ROqTRLXR0e1RxzdWEPRkCt6XOoRk7Mc=
|
||||
github.com/lbryio/lbcd v0.22.102/go.mod h1:iwOnc+syXOeMsAqjHHjMWktni+cg28xOXIY/lN+YIWE=
|
||||
github.com/lbryio/lbcutil v1.0.202-rc3 h1:J7zYnIj3iN/ndPYKqMKBukLaLM1GhCEaiaMOYIMdUCU=
|
||||
github.com/lbryio/lbcutil v1.0.202-rc3/go.mod h1:LGPtVBBzh4cFXfLFb8ginlFcbA2QwumLNFd0yk/as2o=
|
||||
github.com/lbryio/lbcd v0.22.115 h1:C8Jy9UYeU5rONfxKZHwgDoEdCpJVWcLf+kCJLx7UiHU=
|
||||
github.com/lbryio/lbcd v0.22.115/go.mod h1:YZ2Vi4khEheO7hllkWhDdScXmHhXCBzK4xIQcVDcozs=
|
||||
github.com/lbryio/lbcutil v1.0.202 h1:L0aRMs2bdCUAicD8Xe4NmUEvevDDea3qkIpCSACnftI=
|
||||
github.com/lbryio/lbcutil v1.0.202/go.mod h1:LGPtVBBzh4cFXfLFb8ginlFcbA2QwumLNFd0yk/as2o=
|
||||
github.com/lightningnetwork/lnd/clock v1.1.0 h1:/yfVAwtPmdx45aQBoXQImeY7sOIEr7IXlImRMBOZ7GQ=
|
||||
github.com/lightningnetwork/lnd/clock v1.1.0/go.mod h1:KnQudQ6w0IAMZi1SgvecLZQZ43ra2vpDNj7H/aasemg=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
|
@ -247,7 +234,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
|
||||
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
|
||||
|
@ -298,7 +284,6 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
|||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
@ -332,7 +317,6 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
|
@ -343,18 +327,13 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 h1:NWy5+hlRbC7HK+PmcXVUmW1IMyFce7to56IUvhUFm7Y=
|
||||
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -380,7 +359,6 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -402,7 +380,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -432,23 +409,15 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
|||
google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
|
||||
google.golang.org/genproto v0.0.0-20220524023933-508584e28198 h1:a1g7i05I2vUwq5eYrmxBJy6rPbw/yo7WzzwPJmcC0P4=
|
||||
google.golang.org/genproto v0.0.0-20220524023933-508584e28198/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
|
||||
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ=
|
||||
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
@ -460,9 +429,6 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
|
|||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
|
@ -475,7 +441,6 @@ gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
@ -10,79 +10,82 @@ package rpchelp
|
|||
var helpDescsEnUS = map[string]string{
|
||||
// AddMultisigAddressCmd help.
|
||||
"addmultisigaddress--synopsis": "Generates and imports a multisig address and redeeming script to the 'imported' account.",
|
||||
"addmultisigaddress-account": "DEPRECATED -- Unused (all imported addresses belong to the imported account)",
|
||||
"addmultisigaddress-keys": "Pubkeys and/or pay-to-pubkey-hash addresses to partially control the multisig address",
|
||||
"addmultisigaddress-nrequired": "The number of signatures required to redeem outputs paid to this address",
|
||||
"addmultisigaddress--result0": "The imported pay-to-script-hash address",
|
||||
"addmultisigaddress-account": "DEPRECATED -- Unused (all imported addresses belong to the imported account).",
|
||||
"addmultisigaddress-keys": "Pubkeys and/or pay-to-pubkey-hash addresses to partially control the multisig address.",
|
||||
"addmultisigaddress-nrequired": "The number of signatures required to redeem outputs paid to this address.",
|
||||
"addmultisigaddress--result0": "The imported pay-to-script-hash address.",
|
||||
|
||||
// CreateMultisigCmd help.
|
||||
"createmultisig--synopsis": "Generate a multisig address and redeem script.",
|
||||
"createmultisig-keys": "Pubkeys and/or pay-to-pubkey-hash addresses to partially control the multisig address",
|
||||
"createmultisig-nrequired": "The number of signatures required to redeem outputs paid to this address",
|
||||
"createmultisig-keys": "Pubkeys and/or pay-to-pubkey-hash addresses to partially control the multisig address.",
|
||||
"createmultisig-nrequired": "The number of signatures required to redeem outputs paid to this address.",
|
||||
|
||||
// CreateMultisigResult help.
|
||||
"createmultisigresult-address": "The generated pay-to-script-hash address",
|
||||
"createmultisigresult-redeemScript": "The script required to redeem outputs paid to the multisig address",
|
||||
"createmultisigresult-address": "The generated pay-to-script-hash address.",
|
||||
"createmultisigresult-redeemScript": "The script required to redeem outputs paid to the multisig address.",
|
||||
|
||||
// CreateNewAccountCmd help.
|
||||
"createnewaccount--synopsis": "Creates a new account.",
|
||||
"createnewaccount-account": "Account name.",
|
||||
|
||||
// DumpPrivKeyCmd help.
|
||||
"dumpprivkey--synopsis": "Returns the private key in WIF encoding that controls some wallet address.",
|
||||
"dumpprivkey-address": "The address to return a private key for",
|
||||
"dumpprivkey--result0": "The WIF-encoded private key",
|
||||
"dumpprivkey-address": "The address to return a private key for.",
|
||||
"dumpprivkey--result0": "The WIF-encoded private key.",
|
||||
|
||||
// ExportWatchingWalletCmd help.
|
||||
"exportwatchingwallet--synopsis": "Creates and returns a duplicate of the wallet database without any private keys to be used as a watching-only wallet.",
|
||||
"exportwatchingwallet-account": "Unused (must be unset or \"*\").",
|
||||
"exportwatchingwallet-download": "Unused.",
|
||||
"exportwatchingwallet--result0": "The watching-only database encoded as a base64 string.",
|
||||
|
||||
// GetAccountCmd help.
|
||||
"getaccount--synopsis": "DEPRECATED -- Lookup the account name that some wallet address belongs to.",
|
||||
"getaccount-address": "The address to query the account for",
|
||||
"getaccount--result0": "The name of the account that 'address' belongs to",
|
||||
"getaccount--synopsis": "Lookup the account name that some wallet address belongs to.",
|
||||
"getaccount-address": "The address to query the account for.",
|
||||
"getaccount--result0": "The name of the account that 'address' belongs to.",
|
||||
|
||||
// GetAccountAddressCmd help.
|
||||
"getaccountaddress--synopsis": "DEPRECATED -- Returns the most recent external payment address for an account that has not been seen publicly.\n" +
|
||||
"getaccountaddress--synopsis": "Returns the most recent external payment address for an account that has not been seen publicly.\n" +
|
||||
"A new address is generated for the account if the most recently generated address has been seen on the blockchain or in mempool.",
|
||||
"getaccountaddress-account": "The account of the returned address",
|
||||
"getaccountaddress--result0": "The unused address for 'account'",
|
||||
"getaccountaddress-account": "The account of the returned address. Defaults to 'default'",
|
||||
"getaccountaddress-addresstype": "Address type. Must be one of 'legacy', 'p2sh-segwit', or 'bech32'. Default to 'legacy'.",
|
||||
"getaccountaddress--result0": "The unused address for 'account'.",
|
||||
|
||||
// GetAddressesByAccountCmd help.
|
||||
"getaddressesbyaccount--synopsis": "DEPRECATED -- Returns all addresses strings controlled by a single account.",
|
||||
"getaddressesbyaccount-account": "Account name to fetch addresses for",
|
||||
"getaddressesbyaccount--result0": "All addresses controlled by 'account'",
|
||||
"getaddressesbyaccount--synopsis": "Returns all addresses controlled by a single account.",
|
||||
"getaddressesbyaccount-account": "Account name to fetch addresses for. Defaults to 'default'",
|
||||
"getaddressesbyaccount-addresstype": "Address type filter. Must be one of 'legacy', 'p2sh-segwit', 'bech32', or '*'. Defaults to '*'.",
|
||||
"getaddressesbyaccount--result0": "All addresses controlled by 'account' filtered by 'addresstype'.",
|
||||
|
||||
// GetBalanceCmd help.
|
||||
"getbalance--synopsis": "Calculates and returns the balance of one or all accounts.",
|
||||
"getbalance-minconf": "Minimum number of block confirmations required before an unspent output's value is included in the balance",
|
||||
"getbalance-account": "DEPRECATED -- The account name to query the balance for, or \"*\" to consider all accounts (default=\"*\")",
|
||||
"getbalance--condition0": "account != \"*\"",
|
||||
"getbalance--condition1": "account = \"*\"",
|
||||
"getbalance--result0": "The balance of 'account' valued in bitcoin",
|
||||
"getbalance--result1": "The balance of all accounts valued in bitcoin",
|
||||
"getbalance-minconf": "Minimum number of block confirmations required before an unspent output's value is included in the balance.",
|
||||
"getbalance-account": "Account name or '*' for all accounts to query the balance for. Default to 'default'.",
|
||||
"getbalance-addresstype": "Address type filter. Must be one of 'legacy', 'p2sh-segwit', 'bech32', or '*'. Default to '*'.",
|
||||
"getbalance--result0": "The balance valued in LBC.",
|
||||
|
||||
// GetBestBlockCmd help.
|
||||
"getbestblock--synopsis": "Returns the hash and height of the newest block in the best chain that wallet has finished syncing with.",
|
||||
|
||||
// GetBestBlockResult help.
|
||||
"getbestblockresult-hash": "The hash of the block.",
|
||||
"getbestblockresult-height": "The blockchain height of the block.",
|
||||
|
||||
// GetBestBlockHashCmd help.
|
||||
"getbestblockhash--synopsis": "Returns the hash of the newest block in the best chain that wallet has finished syncing with.",
|
||||
"getbestblockhash--result0": "The hash of the most recent synced-to block",
|
||||
"getbestblockhash--result0": "The hash of the most recent synced-to block.",
|
||||
|
||||
// GetBlockCountCmd help.
|
||||
"getblockcount--synopsis": "Returns the blockchain height of the newest block in the best chain that wallet has finished syncing with.",
|
||||
"getblockcount--result0": "The blockchain height of the most recent synced-to block",
|
||||
"getblockcount--result0": "The blockchain height of the most recent synced-to block.",
|
||||
|
||||
// GetInfoCmd help.
|
||||
"getinfo--synopsis": "Returns a JSON object containing various state info.",
|
||||
|
||||
// InfoWalletResult help.
|
||||
"infowalletresult-version": "The version of the server",
|
||||
"infowalletresult-protocolversion": "The latest supported protocol version",
|
||||
"infowalletresult-blocks": "The number of blocks processed",
|
||||
"infowalletresult-timeoffset": "The time offset",
|
||||
"infowalletresult-connections": "The number of connected peers",
|
||||
"infowalletresult-proxy": "The proxy used by the server",
|
||||
"infowalletresult-difficulty": "The current target difficulty",
|
||||
"infowalletresult-testnet": "Whether or not server is using testnet",
|
||||
"infowalletresult-relayfee": "The minimum relay fee for non-free transactions in LBC/KB",
|
||||
"infowalletresult-errors": "Any current errors",
|
||||
"infowalletresult-paytxfee": "The increment used each time more fee is required for an authored transaction",
|
||||
"infowalletresult-balance": "The non-staked balance of all accounts calculated with one block confirmation",
|
||||
"infowalletresult-staked": "The staked balance of all accounts calculated with one block confirmation",
|
||||
"infowalletresult-walletversion": "The version of the address manager database",
|
||||
"infowalletresult-unlocked_until": "Unset",
|
||||
"infowalletresult-keypoolsize": "Unset",
|
||||
"infowalletresult-keypoololdest": "Unset",
|
||||
// GetUnconfirmedBalanceCmd help.
|
||||
"getunconfirmedbalance--synopsis": "Calculates the unspent output value of all unmined transaction outputs.",
|
||||
"getunconfirmedbalance-account": "The account name to query the unconfirmed balance for. Default to 'default'.",
|
||||
"getunconfirmedbalance--result0": "Total amount of all unmined unspent outputs of the account valued in LBC.",
|
||||
|
||||
// GetAddressInfoCmd help.
|
||||
"getaddressinfo--synopsis": "Generates and returns a new payment address.",
|
||||
|
@ -95,7 +98,7 @@ var helpDescsEnUS = map[string]string{
|
|||
"getaddressinforesult-timestamp": "The creation time of the key, if available, expressed in UNIX epoch time.",
|
||||
"getaddressinforesult-hdkeypath": "The HD keypath, if the key is HD and available.",
|
||||
"getaddressinforesult-hdseedid": "The Hash160 of the HD seed.",
|
||||
"getaddressinforesult-address": "The address validated",
|
||||
"getaddressinforesult-address": "The address validatedi.",
|
||||
"getaddressinforesult-scriptPubKey": "The hex-encoded scriptPubKey generated by the address.",
|
||||
"getaddressinforesult-desc": "A descriptor for spending coins sent to this address (only when solvable).",
|
||||
"getaddressinforesult-isscript": "If the key is a script.",
|
||||
|
@ -111,7 +114,7 @@ var helpDescsEnUS = map[string]string{
|
|||
"getaddressinforesult-iscompressed": "If the pubkey is compressed.",
|
||||
"getaddressinforesult-hdmasterfingerprint": "The fingerprint of the master key.",
|
||||
"getaddressinforesult-labels": "Array of labels associated with the address. Currently limited to one label but returned.",
|
||||
"embeddedaddressinfo-address": "The address validated",
|
||||
"embeddedaddressinfo-address": "The address validated.",
|
||||
"embeddedaddressinfo-scriptPubKey": "The hex-encoded scriptPubKey generated by the address.",
|
||||
"embeddedaddressinfo-desc": "A descriptor for spending coins sent to this address (only when solvable).",
|
||||
"embeddedaddressinfo-isscript": "If the key is a script.",
|
||||
|
@ -130,249 +133,287 @@ var helpDescsEnUS = map[string]string{
|
|||
|
||||
// GetNewAddressCmd help.
|
||||
"getnewaddress--synopsis": "Generates and returns a new payment address.",
|
||||
"getnewaddress-account": "DEPRECATED -- Account name the new address will belong to (default=\"default\")",
|
||||
"getnewaddress-addresstype": "Address type. Must be one of legacy / p2pkh, p2sh-p2wpkh / p2sh-p2wkh / p2sh-segwit, or p2wpkh / p2wkh / bech32",
|
||||
"getnewaddress--result0": "The payment address",
|
||||
"getnewaddress-account": "Account name the new address will belong to. Defaults to 'default'.",
|
||||
"getnewaddress-addresstype": "Address type. Must be one of 'legacy', 'p2sh-segwit', or 'bech32'. Default to 'legacy'.",
|
||||
"getnewaddress--result0": "The payment address.",
|
||||
|
||||
// GetRawChangeAddressCmd help.
|
||||
"getrawchangeaddress--synopsis": "Generates and returns a new internal payment address for use as a change address in raw transactions.",
|
||||
"getrawchangeaddress-account": "Account name the new internal address will belong to (default=\"default\")",
|
||||
"getrawchangeaddress--result0": "The internal payment address",
|
||||
"getrawchangeaddress--synopsis": "Generates and returns a new internal payment address for use as a change address in raw transactions.",
|
||||
"getrawchangeaddress-account": "Account name the new internal address will belong to. Defaults to 'default'.",
|
||||
"getrawchangeaddress-addresstype": "Address type. Must be one of 'legacy', 'p2sh-segwit', or 'bech32'. Default to 'legacy'.",
|
||||
"getrawchangeaddress--result0": "The internal payment address.",
|
||||
|
||||
// GetReceivedByAccountCmd help.
|
||||
"getreceivedbyaccount--synopsis": "DEPRECATED -- Returns the total amount received by addresses of some account, including spent outputs.",
|
||||
"getreceivedbyaccount-account": "Account name to query total received amount for",
|
||||
"getreceivedbyaccount-minconf": "Minimum number of block confirmations required before an output's value is included in the total",
|
||||
"getreceivedbyaccount--result0": "The total received amount valued in bitcoin",
|
||||
"getreceivedbyaccount--synopsis": "Returns the total amount received by addresses of some account, including spent outputs.",
|
||||
"getreceivedbyaccount-account": "Account name to query total received amount for. Defaults to 'default'",
|
||||
"getreceivedbyaccount-minconf": "Minimum number of block confirmations required before an output's value is included in the total. Defaults to 0",
|
||||
"getreceivedbyaccount--result0": "The total received amount valued in LBC.",
|
||||
|
||||
// GetReceivedByAddressCmd help.
|
||||
"getreceivedbyaddress--synopsis": "Returns the total amount received by a single address, including spent outputs.",
|
||||
"getreceivedbyaddress-address": "Payment address which received outputs to include in total",
|
||||
"getreceivedbyaddress-minconf": "Minimum number of block confirmations required before an output's value is included in the total",
|
||||
"getreceivedbyaddress--result0": "The total received amount valued in bitcoin",
|
||||
"getreceivedbyaddress-address": "Payment address which received outputs to include in total.",
|
||||
"getreceivedbyaddress-minconf": "Minimum number of block confirmations required before an output's value is included in the total. Defaults to 1",
|
||||
"getreceivedbyaddress--result0": "The total received amount valued in LBC.",
|
||||
|
||||
// GetTransactionCmd help.
|
||||
"gettransaction--synopsis": "Returns a JSON object with details regarding a transaction relevant to this wallet.",
|
||||
"gettransaction-txid": "Hash of the transaction to query",
|
||||
"gettransaction-includewatchonly": "Also consider transactions involving watched addresses",
|
||||
"gettransaction-txid": "Hash of the transaction to query.",
|
||||
"gettransaction-includewatchonly": "Also consider transactions involving watched addresses.",
|
||||
|
||||
// GetTransactionResult help.
|
||||
"gettransactionresult-amount": "The total amount this transaction credits to the wallet, valued in LBC.",
|
||||
"gettransactionresult-fee": "The total input value minus the total output value, or 0 if 'txid' is not a sent transaction.",
|
||||
"gettransactionresult-confirmations": "The number of block confirmations of the transaction.",
|
||||
"gettransactionresult-generated": "Only present if transaction only input is a coinbase one.",
|
||||
"gettransactionresult-blockhash": "The hash of the block this transaction is mined in, or the empty string if unmined.",
|
||||
"gettransactionresult-blockindex": "Unset.",
|
||||
"gettransactionresult-blocktime": "The Unix time of the block header this transaction is mined in, or 0 if unmined.",
|
||||
"gettransactionresult-txid": "The transaction hash.",
|
||||
"gettransactionresult-walletconflicts": "Unset.",
|
||||
"gettransactionresult-time": "The earliest Unix time this transaction was known to exist.",
|
||||
"gettransactionresult-timereceived": "The earliest Unix time this transaction was known to exist.",
|
||||
"gettransactionresult-details": "Additional details for each recorded wallet credit and debit.",
|
||||
"gettransactionresult-hex": "The transaction encoded as a hexadecimal string.",
|
||||
|
||||
// GetTransactionDetailsResult help.
|
||||
"gettransactiondetailsresult-account": "The account pertaining to this transaction.",
|
||||
"gettransactiondetailsresult-address": "The address an output was paid to, or the empty string if the output is nonstandard or this detail is regarding a transaction input.",
|
||||
"gettransactiondetailsresult-category": `The kind of detail: "send" for sent transactions, "immature" for immature coinbase outputs, "generate" for mature coinbase outputs, or "recv" for all other received outputs.`,
|
||||
"gettransactiondetailsresult-amount": "The amount of a received output.",
|
||||
"gettransactiondetailsresult-fee": "The included fee for a sent transaction.",
|
||||
"gettransactiondetailsresult-vout": "The transaction output index.",
|
||||
"gettransactiondetailsresult-involveswatchonly": "Unset.",
|
||||
|
||||
// HelpCmd help.
|
||||
"help--synopsis": "Returns a list of all commands or help for a specified command.",
|
||||
"help-command": "The command to retrieve help for",
|
||||
"help--condition0": "no command provided",
|
||||
"help--condition1": "command specified",
|
||||
"help--result0": "List of commands",
|
||||
"help--result1": "Help for specified command",
|
||||
|
||||
// GetTransactionResult help.
|
||||
"gettransactionresult-amount": "The total amount this transaction credits to the wallet, valued in bitcoin",
|
||||
"gettransactionresult-fee": "The total input value minus the total output value, or 0 if 'txid' is not a sent transaction",
|
||||
"gettransactionresult-confirmations": "The number of block confirmations of the transaction",
|
||||
"gettransactionresult-blockhash": "The hash of the block this transaction is mined in, or the empty string if unmined",
|
||||
"gettransactionresult-blockindex": "Unset",
|
||||
"gettransactionresult-blocktime": "The Unix time of the block header this transaction is mined in, or 0 if unmined",
|
||||
"gettransactionresult-txid": "The transaction hash",
|
||||
"gettransactionresult-walletconflicts": "Unset",
|
||||
"gettransactionresult-time": "The earliest Unix time this transaction was known to exist",
|
||||
"gettransactionresult-timereceived": "The earliest Unix time this transaction was known to exist",
|
||||
"gettransactionresult-details": "Additional details for each recorded wallet credit and debit",
|
||||
"gettransactionresult-hex": "The transaction encoded as a hexadecimal string",
|
||||
|
||||
// GetTransactionDetailsResult help.
|
||||
"gettransactiondetailsresult-account": "DEPRECATED -- Unset",
|
||||
"gettransactiondetailsresult-address": "The address an output was paid to, or the empty string if the output is nonstandard or this detail is regarding a transaction input",
|
||||
"gettransactiondetailsresult-category": `The kind of detail: "send" for sent transactions, "immature" for immature coinbase outputs, "generate" for mature coinbase outputs, or "recv" for all other received outputs`,
|
||||
"gettransactiondetailsresult-amount": "The amount of a received output",
|
||||
"gettransactiondetailsresult-fee": "The included fee for a sent transaction",
|
||||
"gettransactiondetailsresult-vout": "The transaction output index",
|
||||
"gettransactiondetailsresult-involveswatchonly": "Unset",
|
||||
"help-command": "The command to retrieve help for.",
|
||||
"help--condition0": "no command provided.",
|
||||
"help--condition1": "command specified.",
|
||||
"help--result0": "List of commands.",
|
||||
"help--result1": "Help for specified command.",
|
||||
|
||||
// ImportPrivKeyCmd help.
|
||||
"importprivkey--synopsis": "Imports a WIF-encoded private key to the 'imported' account.",
|
||||
"importprivkey-privkey": "The WIF-encoded private key",
|
||||
"importprivkey-label": "Unused (must be unset or 'imported')",
|
||||
"importprivkey-rescan": "Rescan the blockchain (since the genesis block) for outputs controlled by the imported key",
|
||||
"importprivkey-privkey": "The WIF-encoded private key.",
|
||||
"importprivkey-label": "Unused (must be unset or 'imported').",
|
||||
"importprivkey-rescan": "Rescan the blockchain (since the genesis block) for outputs controlled by the imported key.",
|
||||
|
||||
// InfoWalletResult help.
|
||||
"infowalletresult-version": "The version of the server.",
|
||||
"infowalletresult-protocolversion": "The latest supported protocol version.",
|
||||
"infowalletresult-blocks": "The number of blocks processed.",
|
||||
"infowalletresult-timeoffset": "The time offset.",
|
||||
"infowalletresult-connections": "The number of connected peers.",
|
||||
"infowalletresult-proxy": "The proxy used by the server.",
|
||||
"infowalletresult-difficulty": "The current target difficulty.",
|
||||
"infowalletresult-testnet": "Whether or not server is using testnet.",
|
||||
"infowalletresult-relayfee": "The minimum relay fee for non-free transactions in LBC/KB.",
|
||||
"infowalletresult-errors": "Any current errors.",
|
||||
"infowalletresult-paytxfee": "The increment used each time more fee is required for an authored transaction.",
|
||||
"infowalletresult-balance": "The non-staked balance of all accounts calculated with one block confirmation.",
|
||||
"infowalletresult-staked": "The staked balance of all accounts calculated with one block confirmation.",
|
||||
"infowalletresult-walletversion": "The version of the address manager database.",
|
||||
"infowalletresult-unlocked_until": "Unset.",
|
||||
"infowalletresult-keypoolsize": "Unset.",
|
||||
"infowalletresult-keypoololdest": "Unset.",
|
||||
|
||||
// KeypoolRefillCmd help.
|
||||
"keypoolrefill--synopsis": "DEPRECATED -- This request does nothing since no keypool is maintained.",
|
||||
"keypoolrefill-newsize": "Unused",
|
||||
"keypoolrefill-newsize": "Unused.",
|
||||
|
||||
// ListAccountsCmd help.
|
||||
"listaccounts--synopsis": "DEPRECATED -- Returns a JSON object of all accounts and their balances.",
|
||||
"listaccounts-minconf": "Minimum number of block confirmations required before an unspent output's value is included in the balance",
|
||||
"listaccounts--result0--desc": "JSON object with account names as keys and bitcoin amounts as values",
|
||||
"listaccounts--result0--key": "The account name",
|
||||
"listaccounts--result0--value": "The account balance valued in bitcoin",
|
||||
"listaccounts--synopsis": "Returns a JSON object of all accounts and their balances.",
|
||||
"listaccounts-minconf": "Minimum number of block confirmations required before an unspent output's value is included in the balance.",
|
||||
"listaccounts-addresstype": "Address type filter. Must be one of 'legacy', 'p2sh-segwit', 'bech32', or '*'. Defaults to '*'.",
|
||||
"listaccounts--result0--desc": "JSON object with account names as keys and LBC amounts as values.",
|
||||
"listaccounts--result0--key": "Account name",
|
||||
"listaccounts--result0--value": "Total balance and each scope respectively, valued in LBC.",
|
||||
|
||||
// ListAddressTransactionsCmd help.
|
||||
"listaddresstransactions--synopsis": "Returns a JSON array of objects containing verbose details for wallet transactions pertaining some addresses.",
|
||||
"listaddresstransactions-addresses": "Addresses to filter transaction results by.",
|
||||
"listaddresstransactions-account": "Account to filter transactions results by. Defaults to 'default'.",
|
||||
|
||||
// ListAllTransactionsCmd help.
|
||||
"listalltransactions--synopsis": "Returns a JSON array of objects in the same format as 'listtransactions' without limiting the number of returned objects.",
|
||||
"listalltransactions-account": "Account to filter transactions results by. Defaults to 'default'.",
|
||||
|
||||
// ListLockUnspentCmd help.
|
||||
"listlockunspent--synopsis": "Returns a JSON array of outpoints marked as locked (with lockunspent) for this wallet session.",
|
||||
|
||||
// TransactionInput help.
|
||||
"transactioninput-txid": "The transaction hash of the referenced output",
|
||||
"transactioninput-vout": "The output index of the referenced output",
|
||||
"transactioninput-txid": "The transaction hash of the referenced output.",
|
||||
"transactioninput-vout": "The output index of the referenced output.",
|
||||
|
||||
// ListReceivedByAccountCmd help.
|
||||
"listreceivedbyaccount--synopsis": "DEPRECATED -- Returns a JSON array of objects listing all accounts and the total amount received by each account.",
|
||||
"listreceivedbyaccount-minconf": "Minimum number of block confirmations required before a transaction is considered",
|
||||
"listreceivedbyaccount-includeempty": "Unused",
|
||||
"listreceivedbyaccount-includewatchonly": "Unused",
|
||||
"listreceivedbyaccount--synopsis": "Returns a JSON array of objects listing all accounts and the total amount received by each account.",
|
||||
"listreceivedbyaccount-minconf": "Minimum number of block confirmations required before a transaction is considered.",
|
||||
"listreceivedbyaccount-includeempty": "Unused.",
|
||||
"listreceivedbyaccount-includewatchonly": "Unused.",
|
||||
|
||||
// ListReceivedByAccountResult help.
|
||||
"listreceivedbyaccountresult-account": "The name of the account",
|
||||
"listreceivedbyaccountresult-amount": "Total amount received by payment addresses of the account valued in bitcoin",
|
||||
"listreceivedbyaccountresult-confirmations": "Number of block confirmations of the most recent transaction relevant to the account",
|
||||
"listreceivedbyaccountresult-account": "Account name.",
|
||||
"listreceivedbyaccountresult-amount": "Total amount received by payment addresses of the account valued in LBC.",
|
||||
"listreceivedbyaccountresult-confirmations": "Number of block confirmations of the most recent transaction relevant to the account.",
|
||||
|
||||
// ListReceivedByAddressCmd help.
|
||||
"listreceivedbyaddress--synopsis": "Returns a JSON array of objects listing wallet payment addresses and their total received amounts.",
|
||||
"listreceivedbyaddress-minconf": "Minimum number of block confirmations required before a transaction is considered",
|
||||
"listreceivedbyaddress-includeempty": "Unused",
|
||||
"listreceivedbyaddress-includewatchonly": "Unused",
|
||||
"listreceivedbyaddress-minconf": "Minimum number of block confirmations required before a transaction is considered.",
|
||||
"listreceivedbyaddress-includeempty": "Unused.",
|
||||
"listreceivedbyaddress-includewatchonly": "Unused.",
|
||||
|
||||
// ListReceivedByAddressResult help.
|
||||
"listreceivedbyaddressresult-account": "DEPRECATED -- Unset",
|
||||
"listreceivedbyaddressresult-address": "The payment address",
|
||||
"listreceivedbyaddressresult-amount": "Total amount received by the payment address valued in bitcoin",
|
||||
"listreceivedbyaddressresult-confirmations": "Number of block confirmations of the most recent transaction relevant to the address",
|
||||
"listreceivedbyaddressresult-txids": "Transaction hashes of all transactions involving this address",
|
||||
"listreceivedbyaddressresult-involvesWatchonly": "Unset",
|
||||
"listreceivedbyaddressresult-address": "The payment address.",
|
||||
"listreceivedbyaddressresult-amount": "Total amount received by the payment address valued in LBC.",
|
||||
"listreceivedbyaddressresult-confirmations": "Number of block confirmations of the most recent transaction relevant to the address.",
|
||||
"listreceivedbyaddressresult-txids": "Transaction hashes of all transactions involving this address.",
|
||||
"listreceivedbyaddressresult-involvesWatchonly": "Unset.",
|
||||
|
||||
// ListSinceBlockCmd help.
|
||||
"listsinceblock--synopsis": "Returns a JSON array of objects listing details of all wallet transactions after some block.",
|
||||
"listsinceblock-blockhash": "Hash of the parent block of the first block to consider transactions from, or unset to list all transactions",
|
||||
"listsinceblock-targetconfirmations": "Minimum number of block confirmations of the last block in the result object. Must be 1 or greater. Note: The transactions array in the result object is not affected by this parameter",
|
||||
"listsinceblock-includewatchonly": "Unused",
|
||||
"listsinceblock--condition0": "blockhash specified",
|
||||
"listsinceblock--condition1": "no blockhash specified",
|
||||
"listsinceblock--result0": "Lists all transactions, including unmined transactions, since the specified block",
|
||||
"listsinceblock--result1": "Lists all transactions since the genesis block",
|
||||
"listsinceblock-blockhash": "Hash of the parent block of the first block to consider transactions from, or unset to list all transactions.",
|
||||
"listsinceblock-targetconfirmations": "Minimum number of block confirmations of the last block in the result object. Must be 1 or greater. Note: The transactions array in the result object is not affected by this parameter.",
|
||||
"listsinceblock-includewatchonly": "Unused.",
|
||||
"listsinceblock--condition0": "blockhash specified.",
|
||||
"listsinceblock--condition1": "no blockhash specified.",
|
||||
"listsinceblock--result0": "Lists all transactions, including unmined transactions, since the specified block.",
|
||||
"listsinceblock--result1": "Lists all transactions since the genesis block.",
|
||||
|
||||
// ListSinceBlockResult help.
|
||||
"listsinceblockresult-transactions": "JSON array of objects containing verbose details of the each transaction",
|
||||
"listsinceblockresult-lastblock": "Hash of the latest-synced block to be used in later calls to listsinceblock",
|
||||
|
||||
// ListTransactionsResult help.
|
||||
"listtransactionsresult-account": "DEPRECATED -- Unset",
|
||||
"listtransactionsresult-address": "Payment address for a transaction output",
|
||||
"listtransactionsresult-category": `The kind of transaction: "send" for sent transactions, "immature" for immature coinbase outputs, "generate" for mature coinbase outputs, or "recv" for all other received outputs. Note: A single output may be included multiple times under different categories`,
|
||||
"listtransactionsresult-amount": "The value of the transaction output valued in bitcoin",
|
||||
"listtransactionsresult-fee": "The total input value minus the total output value for sent transactions",
|
||||
"listtransactionsresult-confirmations": "The number of block confirmations of the transaction",
|
||||
"listtransactionsresult-generated": "Whether the transaction output is a coinbase output",
|
||||
"listtransactionsresult-blockhash": "The hash of the block this transaction is mined in, or the empty string if unmined",
|
||||
"listtransactionsresult-blockheight": "The block height containing the transaction.",
|
||||
"listtransactionsresult-blockindex": "Unset",
|
||||
"listtransactionsresult-blocktime": "The Unix time of the block header this transaction is mined in, or 0 if unmined",
|
||||
"listtransactionsresult-label": "A comment for the address/transaction, if any",
|
||||
"listtransactionsresult-txid": "The hash of the transaction",
|
||||
"listtransactionsresult-vout": "The transaction output index",
|
||||
"listtransactionsresult-walletconflicts": "Unset",
|
||||
"listtransactionsresult-time": "The earliest Unix time this transaction was known to exist",
|
||||
"listtransactionsresult-timereceived": "The earliest Unix time this transaction was known to exist",
|
||||
"listtransactionsresult-involveswatchonly": "Unset",
|
||||
"listtransactionsresult-comment": "Unset",
|
||||
"listtransactionsresult-otheraccount": "Unset",
|
||||
"listtransactionsresult-trusted": "Unset",
|
||||
"listtransactionsresult-bip125-replaceable": "Unset",
|
||||
"listtransactionsresult-abandoned": "Unset",
|
||||
"listsinceblockresult-transactions": "JSON array of objects containing verbose details of the each transaction.",
|
||||
"listsinceblockresult-lastblock": "Hash of the latest-synced block to be used in later calls to listsinceblock.",
|
||||
|
||||
// ListTransactionsCmd help.
|
||||
"listtransactions--synopsis": "Returns a JSON array of objects containing verbose details for wallet transactions.",
|
||||
"listtransactions-account": "DEPRECATED -- Unused (must be unset, \"default\" or \"*\")",
|
||||
"listtransactions-count": "Maximum number of transactions to create results from",
|
||||
"listtransactions-from": "Number of transactions to skip before results are created",
|
||||
"listtransactions-includewatchonly": "Unused",
|
||||
"listtransactions-account": "Account to filter transactions results by. Defaults to 'default'.",
|
||||
"listtransactions-count": "Maximum number of transactions to create results from. Defaults to 10",
|
||||
"listtransactions-from": "Number of transactions to skip before results are created.",
|
||||
"listtransactions-includewatchonly": "Unused.",
|
||||
|
||||
// ListTransactionsResult help.
|
||||
"listtransactionsresult-account": "The account name associated with the transaction.",
|
||||
"listtransactionsresult-address": "Payment address for a transaction output.",
|
||||
"listtransactionsresult-category": `The kind of transaction: "send" for sent transactions, "immature" for immature coinbase outputs, "generate" for mature coinbase outputs, or "recv" for all other received outputs. Note: A single output may be included multiple times under different categories`,
|
||||
"listtransactionsresult-amount": "The value of the transaction output valued in LBC.",
|
||||
"listtransactionsresult-fee": "The total input value minus the total output value for sent transactions.",
|
||||
"listtransactionsresult-confirmations": "The number of block confirmations of the transaction.",
|
||||
"listtransactionsresult-generated": "Whether the transaction output is a coinbase output.",
|
||||
"listtransactionsresult-blockhash": "The hash of the block this transaction is mined in, or the empty string if unmined.",
|
||||
"listtransactionsresult-blockheight": "The block height containing the transaction.",
|
||||
"listtransactionsresult-blockindex": "Unset.",
|
||||
"listtransactionsresult-blocktime": "The Unix time of the block header this transaction is mined in, or 0 if unmined.",
|
||||
"listtransactionsresult-label": "A comment for the address/transaction, if any.",
|
||||
"listtransactionsresult-txid": "The hash of the transaction.",
|
||||
"listtransactionsresult-vout": "The transaction output index.",
|
||||
"listtransactionsresult-walletconflicts": "Unset.",
|
||||
"listtransactionsresult-time": "The earliest Unix time this transaction was known to exist.",
|
||||
"listtransactionsresult-timereceived": "The earliest Unix time this transaction was known to exist.",
|
||||
"listtransactionsresult-involveswatchonly": "Unset.",
|
||||
"listtransactionsresult-comment": "Unset.",
|
||||
"listtransactionsresult-otheraccount": "Unset.",
|
||||
"listtransactionsresult-trusted": "Unset.",
|
||||
"listtransactionsresult-bip125-replaceable": "Unset.",
|
||||
"listtransactionsresult-abandoned": "Unset.",
|
||||
|
||||
// ListUnspentCmd help.
|
||||
"listunspent--synopsis": "Returns a JSON array of objects representing unlocked unspent outputs controlled by wallet keys.",
|
||||
"listunspent-minconf": "Minimum number of block confirmations required before a transaction output is considered",
|
||||
"listunspent-maxconf": "Maximum number of block confirmations required before a transaction output is excluded",
|
||||
"listunspent-addresses": "If set, limits the returned details to unspent outputs received by any of these payment addresses",
|
||||
"listunspent-minconf": "Minimum number of block confirmations required before a transaction output is considered.",
|
||||
"listunspent-maxconf": "Maximum number of block confirmations required before a transaction output is excluded.",
|
||||
"listunspent-addresses": "If set, limits the returned details to unspent outputs received by any of these payment addresses.",
|
||||
|
||||
// ListUnspentResult help.
|
||||
"listunspentresult-txid": "The transaction hash of the referenced output",
|
||||
"listunspentresult-vout": "The output index of the referenced output",
|
||||
"listunspentresult-address": "The payment address that received the output",
|
||||
"listunspentresult-account": "The account associated with the receiving payment address",
|
||||
"listunspentresult-scriptPubKey": "The output script encoded as a hexadecimal string",
|
||||
"listunspentresult-redeemScript": "Unset",
|
||||
"listunspentresult-amount": "The amount of the output valued in bitcoin",
|
||||
"listunspentresult-confirmations": "The number of block confirmations of the transaction",
|
||||
"listunspentresult-solvable": "Whether the output is solvable",
|
||||
"listunspentresult-spendable": "Whether the output is entirely controlled by wallet keys/scripts (false for partially controlled multisig outputs or outputs to watch-only addresses)",
|
||||
"listunspentresult-isstake": "Whether the output is staked",
|
||||
"listunspentresult-txid": "The transaction hash of the referenced output.",
|
||||
"listunspentresult-vout": "The output index of the referenced output.",
|
||||
"listunspentresult-address": "The payment address that received the output.",
|
||||
"listunspentresult-account": "The account associated with the receiving payment address.",
|
||||
"listunspentresult-scriptPubKey": "The output script encoded as a hexadecimal string.",
|
||||
"listunspentresult-redeemScript": "Unset.",
|
||||
"listunspentresult-amount": "The amount of the output valued in LBC.",
|
||||
"listunspentresult-confirmations": "The number of block confirmations of the transaction.",
|
||||
"listunspentresult-solvable": "Whether the output is solvable.",
|
||||
"listunspentresult-spendable": "Whether the output is entirely controlled by wallet keys/scripts (false for partially controlled multisig outputs or outputs to watch-only addresses).",
|
||||
"listunspentresult-isstake": "Whether the output is staked.",
|
||||
|
||||
// LockUnspentCmd help.
|
||||
"lockunspent--synopsis": "Locks or unlocks an unspent output.\n" +
|
||||
"Locked outputs are not chosen for transaction inputs of authored transactions and are not included in 'listunspent' results.\n" +
|
||||
"Locked outputs are volatile and are not saved across wallet restarts.\n" +
|
||||
"If unlock is true and no transaction outputs are specified, all locked outputs are marked unlocked.",
|
||||
"lockunspent-unlock": "True to unlock outputs, false to lock",
|
||||
"lockunspent-transactions": "Transaction outputs to lock or unlock",
|
||||
"lockunspent--result0": "The boolean 'true'",
|
||||
"lockunspent-unlock": "True to unlock outputs, false to lock.",
|
||||
"lockunspent-transactions": "Transaction outputs to lock or unlock.",
|
||||
"lockunspent--result0": "The boolean 'true'.",
|
||||
|
||||
// RenameAccountCmd help.
|
||||
"renameaccount--synopsis": "Renames an account.",
|
||||
"renameaccount-oldaccount": "The old account name to rename.",
|
||||
"renameaccount-newaccount": "The new name for the account.",
|
||||
|
||||
// SendFromCmd help.
|
||||
"sendfrom--synopsis": "DEPRECATED -- Authors, signs, and sends a transaction that outputs some amount to a payment address.\n" +
|
||||
"sendfrom--synopsis": "Authors, signs, and sends a transaction that outputs some amount to a payment address.\n" +
|
||||
"A change output is automatically included to send extra output value back to the original account.",
|
||||
"sendfrom-fromaccount": "Account to pick unspent outputs from",
|
||||
"sendfrom-toaddress": "Address to pay",
|
||||
"sendfrom-amount": "Amount to send to the payment address valued in bitcoin",
|
||||
"sendfrom-minconf": "Minimum number of block confirmations required before a transaction output is eligible to be spent",
|
||||
"sendfrom-comment": "Unused",
|
||||
"sendfrom-commentto": "Unused",
|
||||
"sendfrom--result0": "The transaction hash of the sent transaction",
|
||||
"sendfrom-fromaccount": "Account to pick unspent outputs from.",
|
||||
"sendfrom-toaddress": "Address to pay.",
|
||||
"sendfrom-amount": "Amount to send to the payment address valued in LBC.",
|
||||
"sendfrom-minconf": "Minimum number of block confirmations required before a transaction output is eligible to be spent.",
|
||||
"sendfrom-addresstype": "Address type filter for UTXOs to spent from. Must be one of 'legacy', 'p2sh-segwit', 'bech32', or '*'. Defaults to '*'.",
|
||||
"sendfrom-comment": "Unused.",
|
||||
"sendfrom-commentto": "Unused.",
|
||||
"sendfrom--result0": "The transaction hash of the sent transaction.",
|
||||
|
||||
// SendManyCmd help.
|
||||
"sendmany--synopsis": "Authors, signs, and sends a transaction that outputs to many payment addresses.\n" +
|
||||
"A change output is automatically included to send extra output value back to the original account.",
|
||||
"sendmany-fromaccount": "DEPRECATED -- Account to pick unspent outputs from",
|
||||
"sendmany-amounts": "Pairs of payment addresses and the output amount to pay each",
|
||||
"sendmany-amounts--desc": "JSON object using payment addresses as keys and output amounts valued in bitcoin to send to each address",
|
||||
"sendmany-amounts--key": "Address to pay",
|
||||
"sendmany-amounts--value": "Amount to send to the payment address valued in bitcoin",
|
||||
"sendmany-minconf": "Minimum number of block confirmations required before a transaction output is eligible to be spent",
|
||||
"sendmany-comment": "Unused",
|
||||
"sendmany--result0": "The transaction hash of the sent transaction",
|
||||
"sendmany-fromaccount": "Account to pick unspent outputs from.",
|
||||
"sendmany-amounts": "Pairs of payment addresses and the output amount to pay each.",
|
||||
"sendmany-amounts--desc": "JSON object using payment addresses as keys and output amounts valued in LBC to send to each address.",
|
||||
"sendmany-amounts--key": "Address to pay.",
|
||||
"sendmany-amounts--value": "Amount to send to the payment address valued in LBC.",
|
||||
"sendmany-minconf": "Minimum number of block confirmations required before a transaction output is eligible to be spent.",
|
||||
"sendmany-addresstype": "Address type filter for UTXOs to spent from. Must be one of 'legacy', 'p2sh-segwit', 'bech32', or '*'. Defaults to '*'.",
|
||||
"sendmany-comment": "Unused.",
|
||||
"sendmany--result0": "The transaction hash of the sent transaction.",
|
||||
|
||||
// SendToAddressCmd help.
|
||||
"sendtoaddress--synopsis": "Authors, signs, and sends a transaction that outputs some amount to a payment address.\n" +
|
||||
"Unlike sendfrom, outputs are always chosen from the default account.\n" +
|
||||
"A change output is automatically included to send extra output value back to the original account.",
|
||||
"sendtoaddress-address": "Address to pay",
|
||||
"sendtoaddress-amount": "Amount to send to the payment address valued in bitcoin",
|
||||
"sendtoaddress-comment": "Unused",
|
||||
"sendtoaddress-commentto": "Unused",
|
||||
"sendtoaddress--result0": "The transaction hash of the sent transaction",
|
||||
"sendtoaddress-address": "Address to pay.",
|
||||
"sendtoaddress-amount": "Amount to send to the payment address valued in LBC.",
|
||||
"sendtoaddress-addresstype": "Address type filter for UTXOs to spent from. Must be one of 'legacy', 'p2sh-segwit', 'bech32', or '*'. Defaults to '*'.",
|
||||
"sendtoaddress-comment": "Unused.",
|
||||
"sendtoaddress-commentto": "Unused.",
|
||||
"sendtoaddress--result0": "The transaction hash of the sent transaction.",
|
||||
|
||||
// SetTxFeeCmd help.
|
||||
"settxfee--synopsis": "Modify the increment used each time more fee is required for an authored transaction.",
|
||||
"settxfee-amount": "The new fee increment valued in bitcoin",
|
||||
"settxfee--result0": "The boolean 'true'",
|
||||
"settxfee-amount": "The new fee increment valued in LBC.",
|
||||
"settxfee--result0": "The boolean 'true'.",
|
||||
|
||||
// SignMessageCmd help.
|
||||
"signmessage--synopsis": "Signs a message using the private key of a payment address.",
|
||||
"signmessage-address": "Payment address of private key used to sign the message with",
|
||||
"signmessage-message": "Message to sign",
|
||||
"signmessage--result0": "The signed message encoded as a base64 string",
|
||||
"signmessage-address": "Payment address of private key used to sign the message with.",
|
||||
"signmessage-message": "Message to sign.",
|
||||
"signmessage--result0": "The signed message encoded as a base64 string.",
|
||||
|
||||
// SignRawTransactionCmd help.
|
||||
"signrawtransaction--synopsis": "Signs transaction inputs using private keys from this wallet and request.\n" +
|
||||
"The valid flags options are ALL, NONE, SINGLE, ALL|ANYONECANPAY, NONE|ANYONECANPAY, and SINGLE|ANYONECANPAY.",
|
||||
"signrawtransaction-rawtx": "Unsigned or partially unsigned transaction to sign encoded as a hexadecimal string",
|
||||
"signrawtransaction-inputs": "Additional data regarding inputs that this wallet may not be tracking",
|
||||
"signrawtransaction-privkeys": "Additional WIF-encoded private keys to use when creating signatures",
|
||||
"signrawtransaction-flags": "Sighash flags",
|
||||
"signrawtransaction-rawtx": "Unsigned or partially unsigned transaction to sign encoded as a hexadecimal string.",
|
||||
"signrawtransaction-inputs": "Additional data regarding inputs that this wallet may not be tracking.",
|
||||
"signrawtransaction-privkeys": "Additional WIF-encoded private keys to use when creating signatures.",
|
||||
"signrawtransaction-flags": "Sighash flags.",
|
||||
|
||||
// SignRawTransactionResult help.
|
||||
"signrawtransactionresult-hex": "The resulting transaction encoded as a hexadecimal string",
|
||||
"signrawtransactionresult-complete": "Whether all input signatures have been created",
|
||||
"signrawtransactionresult-errors": "Script verification errors (if exists)",
|
||||
"signrawtransactionresult-hex": "The resulting transaction encoded as a hexadecimal string.",
|
||||
"signrawtransactionresult-complete": "Whether all input signatures have been created.",
|
||||
"signrawtransactionresult-errors": "Script verification errors (if exists).",
|
||||
|
||||
// SignRawTransactionError help.
|
||||
"signrawtransactionerror-error": "Verification or signing error related to the input",
|
||||
"signrawtransactionerror-sequence": "Script sequence number",
|
||||
"signrawtransactionerror-scriptSig": "The hex-encoded signature script",
|
||||
"signrawtransactionerror-txid": "The transaction hash of the referenced previous output",
|
||||
"signrawtransactionerror-vout": "The output index of the referenced previous output",
|
||||
"signrawtransactionerror-error": "Verification or signing error related to the input.",
|
||||
"signrawtransactionerror-sequence": "Script sequence number.",
|
||||
"signrawtransactionerror-scriptSig": "The hex-encoded signature script.",
|
||||
"signrawtransactionerror-txid": "The transaction hash of the referenced previous output.",
|
||||
"signrawtransactionerror-vout": "The output index of the referenced previous output.",
|
||||
|
||||
// ValidateAddressCmd help.
|
||||
"validateaddress--synopsis": "Verify that an address is valid.\n" +
|
||||
|
@ -381,74 +422,43 @@ var helpDescsEnUS = map[string]string{
|
|||
"The following fields are only valid when address has an associated public key: pubkey, iscompressed.\n" +
|
||||
"The following fields are only valid when address is a pay-to-script-hash address: addresses, hex, and script.\n" +
|
||||
"If the address is a multisig address controlled by this wallet, the multisig fields will be left unset if the wallet is locked since the redeem script cannot be decrypted.",
|
||||
"validateaddress-address": "Address to validate",
|
||||
"validateaddress-address": "Address to validate.",
|
||||
|
||||
// ValidateAddressWalletResult help.
|
||||
"validateaddresswalletresult-isvalid": "Whether or not the address is valid",
|
||||
"validateaddresswalletresult-address": "The payment address (only when isvalid is true)",
|
||||
"validateaddresswalletresult-ismine": "Whether this address is controlled by the wallet (only when isvalid is true)",
|
||||
"validateaddresswalletresult-iswatchonly": "Unset",
|
||||
"validateaddresswalletresult-isscript": "Whether the payment address is a pay-to-script-hash address (only when isvalid is true)",
|
||||
"validateaddresswalletresult-pubkey": "The associated public key of the payment address, if any (only when isvalid is true)",
|
||||
"validateaddresswalletresult-iscompressed": "Whether the address was created by hashing a compressed public key, if any (only when isvalid is true)",
|
||||
"validateaddresswalletresult-account": "The account this payment address belongs to (only when isvalid is true)",
|
||||
"validateaddresswalletresult-addresses": "All associated payment addresses of the script if address is a multisig address (only when isvalid is true)",
|
||||
"validateaddresswalletresult-hex": "The redeem script ",
|
||||
"validateaddresswalletresult-script": "The class of redeem script for a multisig address",
|
||||
"validateaddresswalletresult-sigsrequired": "The number of required signatures to redeem outputs to the multisig address",
|
||||
"validateaddresswalletresult-isvalid": "Whether or not the address is valid.",
|
||||
"validateaddresswalletresult-address": "The payment address (only when isvalid is true).",
|
||||
"validateaddresswalletresult-ismine": "Whether this address is controlled by the wallet (only when isvalid is true).",
|
||||
"validateaddresswalletresult-iswatchonly": "Unset.",
|
||||
"validateaddresswalletresult-isscript": "Whether the payment address is a pay-to-script-hash address (only when isvalid is true).",
|
||||
"validateaddresswalletresult-pubkey": "The associated public key of the payment address, if any (only when isvalid is true).",
|
||||
"validateaddresswalletresult-iscompressed": "Whether the address was created by hashing a compressed public key, if any (only when isvalid is true).",
|
||||
"validateaddresswalletresult-account": "The account this payment address belongs to (only when isvalid is true).",
|
||||
"validateaddresswalletresult-addresses": "All associated payment addresses of the script if address is a multisig address (only when isvalid is true).",
|
||||
"validateaddresswalletresult-hex": "The redeem script .",
|
||||
"validateaddresswalletresult-script": "The class of redeem script for a multisig address.",
|
||||
"validateaddresswalletresult-sigsrequired": "The number of required signatures to redeem outputs to the multisig address.",
|
||||
|
||||
// VerifyMessageCmd help.
|
||||
"verifymessage--synopsis": "Verify a message was signed with the associated private key of some address.",
|
||||
"verifymessage-address": "Address used to sign message",
|
||||
"verifymessage-signature": "The signature to verify",
|
||||
"verifymessage-message": "The message to verify",
|
||||
"verifymessage--result0": "Whether the message was signed with the private key of 'address'",
|
||||
"verifymessage-address": "Address used to sign message.",
|
||||
"verifymessage-signature": "The signature to verify.",
|
||||
"verifymessage-message": "The message to verify.",
|
||||
"verifymessage--result0": "Whether the message was signed with the private key of 'address'.",
|
||||
|
||||
// WalletIsLockedCmd help.
|
||||
"walletislocked--synopsis": "Returns whether or not the wallet is locked.",
|
||||
"walletislocked--result0": "Whether the wallet is locked.",
|
||||
|
||||
// WalletLockCmd help.
|
||||
"walletlock--synopsis": "Lock the wallet.",
|
||||
|
||||
// WalletPassphraseCmd help.
|
||||
"walletpassphrase--synopsis": "Unlock the wallet.",
|
||||
"walletpassphrase-passphrase": "The wallet passphrase",
|
||||
"walletpassphrase-timeout": "The number of seconds to wait before the wallet automatically locks",
|
||||
"walletpassphrase-passphrase": "The wallet passphrase.",
|
||||
"walletpassphrase-timeout": "The number of seconds to wait before the wallet automatically locks.",
|
||||
|
||||
// WalletPassphraseChangeCmd help.
|
||||
"walletpassphrasechange--synopsis": "Change the wallet passphrase.",
|
||||
"walletpassphrasechange-oldpassphrase": "The old wallet passphrase",
|
||||
"walletpassphrasechange-newpassphrase": "The new wallet passphrase",
|
||||
|
||||
// CreateNewAccountCmd help.
|
||||
"createnewaccount--synopsis": "Creates a new account.\n" +
|
||||
"The wallet must be unlocked for this request to succeed.",
|
||||
"createnewaccount-account": "Name of the new account",
|
||||
|
||||
// GetBestBlockCmd help.
|
||||
"getbestblock--synopsis": "Returns the hash and height of the newest block in the best chain that wallet has finished syncing with.",
|
||||
|
||||
// GetBestBlockResult help.
|
||||
"getbestblockresult-hash": "The hash of the block",
|
||||
"getbestblockresult-height": "The blockchain height of the block",
|
||||
|
||||
// GetUnconfirmedBalanceCmd help.
|
||||
"getunconfirmedbalance--synopsis": "Calculates the unspent output value of all unmined transaction outputs for an account.",
|
||||
"getunconfirmedbalance-account": "The account to query the unconfirmed balance for (default=\"default\")",
|
||||
"getunconfirmedbalance--result0": "Total amount of all unmined unspent outputs of the account valued in bitcoin.",
|
||||
|
||||
// ListAddressTransactionsCmd help.
|
||||
"listaddresstransactions--synopsis": "Returns a JSON array of objects containing verbose details for wallet transactions pertaining some addresses.",
|
||||
"listaddresstransactions-addresses": "Addresses to filter transaction results by",
|
||||
"listaddresstransactions-account": "Unused (must be unset or \"*\")",
|
||||
|
||||
// ListAllTransactionsCmd help.
|
||||
"listalltransactions--synopsis": "Returns a JSON array of objects in the same format as 'listtransactions' without limiting the number of returned objects.",
|
||||
"listalltransactions-account": "Unused (must be unset or \"*\")",
|
||||
|
||||
// RenameAccountCmd help.
|
||||
"renameaccount--synopsis": "Renames an account.",
|
||||
"renameaccount-oldaccount": "The old account name to rename",
|
||||
"renameaccount-newaccount": "The new name for the account",
|
||||
|
||||
// WalletIsLockedCmd help.
|
||||
"walletislocked--synopsis": "Returns whether or not the wallet is locked.",
|
||||
"walletislocked--result0": "Whether the wallet is locked",
|
||||
"walletpassphrasechange-oldpassphrase": "The old wallet passphrase.",
|
||||
"walletpassphrasechange-newpassphrase": "The new wallet passphrase.",
|
||||
}
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
|
||||
package rpchelp
|
||||
|
||||
import "github.com/lbryio/lbcd/btcjson"
|
||||
import (
|
||||
"github.com/lbryio/lbcd/btcjson"
|
||||
)
|
||||
|
||||
// Common return types.
|
||||
var (
|
||||
|
@ -31,7 +33,7 @@ var Methods = []struct {
|
|||
{"getaccountaddress", returnsString},
|
||||
{"getaddressesbyaccount", returnsStringArray},
|
||||
{"getaddressinfo", []interface{}{(*btcjson.GetAddressInfoResult)(nil)}},
|
||||
{"getbalance", append(returnsNumber, returnsNumber[0])},
|
||||
{"getbalance", returnsNumber},
|
||||
{"getbestblockhash", returnsString},
|
||||
{"getblockcount", returnsNumber},
|
||||
{"getinfo", []interface{}{(*btcjson.InfoWalletResult)(nil)}},
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/lbryio/lbcd/blockchain"
|
||||
"github.com/lbryio/lbcd/btcec"
|
||||
"github.com/lbryio/lbcd/btcjson"
|
||||
"github.com/lbryio/lbcd/chaincfg"
|
||||
|
@ -394,16 +395,25 @@ func dumpPrivKey(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
|
||||
// getAddressesByAccount handles a getaddressesbyaccount request by returning
|
||||
// all addresses for an account, or an error if the requested account does
|
||||
// not exist.
|
||||
func getAddressesByAccount(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
// not exist. If addresstype is also specified, only those address types are
|
||||
// returned.
|
||||
func getAddressesByAccount(icmd interface{}, w *wallet.Wallet) (
|
||||
interface{}, error) {
|
||||
|
||||
cmd := icmd.(*btcjson.GetAddressesByAccountCmd)
|
||||
|
||||
account, err := w.AccountNumber(waddrmgr.KeyScopeBIP0044, cmd.Account)
|
||||
account, err := w.AccountNumber(*cmd.Account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addrs, err := w.AccountAddresses(account)
|
||||
// Use specified scope, if provided.
|
||||
scope, err := lookupKeyScope(cmd.AddressType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addrs, err := w.AccountAddresses(account, scope)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -412,6 +422,7 @@ func getAddressesByAccount(icmd interface{}, w *wallet.Wallet) (interface{}, err
|
|||
for i, a := range addrs {
|
||||
addrStrs[i] = a.EncodeAddress()
|
||||
}
|
||||
|
||||
return addrStrs, nil
|
||||
}
|
||||
|
||||
|
@ -572,30 +583,22 @@ func getAddressInfo(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
func getBalance(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
cmd := icmd.(*btcjson.GetBalanceCmd)
|
||||
|
||||
var balance btcutil.Amount
|
||||
var err error
|
||||
accountName := "*"
|
||||
if cmd.Account != nil {
|
||||
accountName = *cmd.Account
|
||||
if *cmd.Account == "*" {
|
||||
balance, _, err := w.CalculateBalance(int32(*cmd.MinConf))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return balance.ToBTC(), nil
|
||||
}
|
||||
if accountName == "*" {
|
||||
balance, _, err = w.CalculateBalance(int32(*cmd.MinConf))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
var account uint32
|
||||
account, err = w.AccountNumber(waddrmgr.KeyScopeBIP0044, accountName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bals, err := w.CalculateAccountBalances(account, int32(*cmd.MinConf))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
balance = bals.Spendable
|
||||
|
||||
account, err := w.AccountNumber(*cmd.Account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return balance.ToBTC(), nil
|
||||
|
||||
bals, err := w.CalculateAccountBalances(account, int32(*cmd.MinConf))
|
||||
|
||||
return bals.Spendable.ToBTC(), err
|
||||
}
|
||||
|
||||
// getBestBlock handles a getbestblock request by returning a JSON object
|
||||
|
@ -689,7 +692,7 @@ func getAccount(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
return nil, &ErrAddressNotInWallet
|
||||
}
|
||||
|
||||
acctName, err := w.AccountName(waddrmgr.KeyScopeBIP0044, account)
|
||||
acctName, err := w.AccountName(account)
|
||||
if err != nil {
|
||||
return nil, &ErrAccountNameNotFound
|
||||
}
|
||||
|
@ -705,16 +708,22 @@ func getAccount(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
func getAccountAddress(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
cmd := icmd.(*btcjson.GetAccountAddressCmd)
|
||||
|
||||
account, err := w.AccountNumber(waddrmgr.KeyScopeBIP0044, cmd.Account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addr, err := w.CurrentAddress(account, waddrmgr.KeyScopeBIP0044)
|
||||
account, err := w.AccountNumber(*cmd.Account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return addr.EncodeAddress(), err
|
||||
scope, err := lookupKeyScope(cmd.AddressType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr, err := w.CurrentAddress(account, *scope)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return addr.EncodeAddress(), nil
|
||||
}
|
||||
|
||||
// getUnconfirmedBalance handles a getunconfirmedbalance extension request
|
||||
|
@ -722,14 +731,11 @@ func getAccountAddress(icmd interface{}, w *wallet.Wallet) (interface{}, error)
|
|||
func getUnconfirmedBalance(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
cmd := icmd.(*btcjson.GetUnconfirmedBalanceCmd)
|
||||
|
||||
acctName := defaultAccountName
|
||||
if cmd.Account != nil {
|
||||
acctName = *cmd.Account
|
||||
}
|
||||
account, err := w.AccountNumber(waddrmgr.KeyScopeBIP0044, acctName)
|
||||
account, err := w.AccountNumber(*cmd.Account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bals, err := w.CalculateAccountBalances(account, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -787,6 +793,7 @@ func keypoolRefill(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
// returning a new account. If the last account has no transaction history
|
||||
// as per BIP 0044 a new account cannot be created so an error will be returned.
|
||||
func createNewAccount(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
|
||||
cmd := icmd.(*btcjson.CreateNewAccountCmd)
|
||||
|
||||
// The wildcard * is reserved by the rpc server with the special meaning
|
||||
|
@ -795,7 +802,11 @@ func createNewAccount(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
return nil, &ErrReservedAccountName
|
||||
}
|
||||
|
||||
_, err := w.NextAccount(waddrmgr.KeyScopeBIP0044, cmd.Account)
|
||||
fn := func(scope waddrmgr.KeyScope) error {
|
||||
_, err := w.NextAccount(scope, cmd.Account)
|
||||
return err
|
||||
}
|
||||
err := forEachKeyScope(fn)
|
||||
if waddrmgr.IsError(err, waddrmgr.ErrLocked) {
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCWalletUnlockNeeded,
|
||||
|
@ -803,12 +814,14 @@ func createNewAccount(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
"Enter the wallet passphrase with walletpassphrase to unlock",
|
||||
}
|
||||
}
|
||||
return nil, err
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// renameAccount handles a renameaccount request by renaming an account.
|
||||
// If the account does not exist an appropriate error will be returned.
|
||||
func renameAccount(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
|
||||
cmd := icmd.(*btcjson.RenameAccountCmd)
|
||||
|
||||
// The wildcard * is reserved by the rpc server with the special meaning
|
||||
|
@ -818,11 +831,18 @@ func renameAccount(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
}
|
||||
|
||||
// Check that given account exists
|
||||
account, err := w.AccountNumber(waddrmgr.KeyScopeBIP0044, cmd.OldAccount)
|
||||
account, err := w.AccountNumber(cmd.OldAccount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, w.RenameAccount(waddrmgr.KeyScopeBIP0044, account, cmd.NewAccount)
|
||||
|
||||
// Interate over all key scopes and rename the account.
|
||||
fn := func(scope waddrmgr.KeyScope) error {
|
||||
return w.RenameAccount(scope, account, cmd.NewAccount)
|
||||
}
|
||||
err = forEachKeyScope(fn)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func lookupKeyScope(kind *string) (*waddrmgr.KeyScope, error) {
|
||||
|
@ -855,17 +875,17 @@ func getNewAddress(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
acctName = *cmd.Account
|
||||
}
|
||||
|
||||
keyScope, err := lookupKeyScope(cmd.AddressType)
|
||||
account, err := w.AccountNumber(acctName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
account, err := w.AccountNumber(*keyScope, acctName)
|
||||
scope, err := lookupKeyScope(cmd.AddressType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr, err := w.NewAddress(account, *keyScope)
|
||||
addr, err := w.NewAddress(account, *scope)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -880,17 +900,24 @@ func getNewAddress(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
// Note: bitcoind allows specifying the account as an optional parameter,
|
||||
// but ignores the parameter.
|
||||
func getRawChangeAddress(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
|
||||
cmd := icmd.(*btcjson.GetRawChangeAddressCmd)
|
||||
|
||||
acctName := defaultAccountName
|
||||
if cmd.Account != nil {
|
||||
acctName = *cmd.Account
|
||||
}
|
||||
account, err := w.AccountNumber(waddrmgr.KeyScopeBIP0044, acctName)
|
||||
account, err := w.AccountNumber(*cmd.Account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addr, err := w.NewChangeAddress(account, waddrmgr.KeyScopeBIP0044)
|
||||
|
||||
// Use specified scope, if provided.
|
||||
scope, err := lookupKeyScope(cmd.AddressType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if scope == nil {
|
||||
scope = &waddrmgr.DefaultKeyScope
|
||||
}
|
||||
|
||||
addr, err := w.NewChangeAddress(account, *scope)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -902,27 +929,38 @@ func getRawChangeAddress(icmd interface{}, w *wallet.Wallet) (interface{}, error
|
|||
// getReceivedByAccount handles a getreceivedbyaccount request by returning
|
||||
// the total amount received by addresses of an account.
|
||||
func getReceivedByAccount(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
|
||||
cmd := icmd.(*btcjson.GetReceivedByAccountCmd)
|
||||
|
||||
account, err := w.AccountNumber(waddrmgr.KeyScopeBIP0044, cmd.Account)
|
||||
account, err := w.AccountNumber(*cmd.Account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: This is more inefficient that it could be, but the entire
|
||||
// algorithm is already dominated by reading every transaction in the
|
||||
// wallet's history.
|
||||
results, err := w.TotalReceivedForAccounts(
|
||||
waddrmgr.KeyScopeBIP0044, int32(*cmd.MinConf),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
totalReceived := 0.0
|
||||
|
||||
var results []wallet.AccountTotalReceivedResult
|
||||
|
||||
fn := func(scope waddrmgr.KeyScope) error {
|
||||
|
||||
results, err = w.TotalReceivedForAccounts(
|
||||
scope, int32(*cmd.MinConf))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
acctIndex := int(account)
|
||||
if account == waddrmgr.ImportedAddrAccount {
|
||||
acctIndex = len(results) - 1
|
||||
}
|
||||
|
||||
totalReceived += results[acctIndex].TotalReceived.ToBTC()
|
||||
|
||||
return nil
|
||||
}
|
||||
acctIndex := int(account)
|
||||
if account == waddrmgr.ImportedAddrAccount {
|
||||
acctIndex = len(results) - 1
|
||||
}
|
||||
return results[acctIndex].TotalReceived.ToBTC(), nil
|
||||
err = forEachKeyScope(fn)
|
||||
|
||||
return totalReceived, err
|
||||
}
|
||||
|
||||
// getReceivedByAddress handles a getreceivedbyaddress request by returning
|
||||
|
@ -974,15 +1012,13 @@ func getTransaction(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: Add a "generated" field to this result type. "generated":true
|
||||
// is only added if the transaction is a coinbase.
|
||||
ret := btcjson.GetTransactionResult{
|
||||
TxID: cmd.Txid,
|
||||
Hex: hex.EncodeToString(txBuf.Bytes()),
|
||||
Time: details.Received.Unix(),
|
||||
TimeReceived: details.Received.Unix(),
|
||||
WalletConflicts: []string{}, // Not saved
|
||||
//Generated: blockchain.IsCoinBaseTx(&details.MsgTx),
|
||||
Generated: blockchain.IsCoinBaseTx(&details.MsgTx),
|
||||
}
|
||||
|
||||
if details.Block.Height != -1 {
|
||||
|
@ -1057,7 +1093,7 @@ func getTransaction(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
address = addr.EncodeAddress()
|
||||
account, err := w.AccountOfAddress(addr)
|
||||
if err == nil {
|
||||
name, err := w.AccountName(waddrmgr.KeyScopeBIP0044, account)
|
||||
name, err := w.AccountName(account)
|
||||
if err == nil {
|
||||
accountName = name
|
||||
}
|
||||
|
@ -1205,16 +1241,40 @@ func help(icmd interface{}, _ *wallet.Wallet, chainClient *chain.RPCClient) (int
|
|||
func listAccounts(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
cmd := icmd.(*btcjson.ListAccountsCmd)
|
||||
|
||||
accountBalances := map[string]float64{}
|
||||
results, err := w.AccountBalances(waddrmgr.KeyScopeBIP0044, int32(*cmd.MinConf))
|
||||
accountBalances := map[string]map[string]float64{}
|
||||
|
||||
fn := func(scope waddrmgr.KeyScope) error {
|
||||
results, err := w.AccountBalances(scope, int32(*cmd.MinConf))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, result := range results {
|
||||
if accountBalances[result.AccountName] == nil {
|
||||
accountBalances[result.AccountName] = map[string]float64{}
|
||||
}
|
||||
accountBalances[result.AccountName][scope.String()] += result.AccountBalance.ToBTC()
|
||||
accountBalances[result.AccountName]["total"] += result.AccountBalance.ToBTC()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
scope, err := lookupKeyScope(cmd.AddressType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, result := range results {
|
||||
accountBalances[result.AccountName] = result.AccountBalance.ToBTC()
|
||||
|
||||
if scope != nil {
|
||||
err = fn(*scope)
|
||||
} else {
|
||||
err = forEachKeyScope(fn)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Return the map. This will be marshaled into a JSON object.
|
||||
return accountBalances, nil
|
||||
return accountBalances, err
|
||||
}
|
||||
|
||||
// listLockUnspent handles a listlockunspent request by returning an slice of
|
||||
|
@ -1239,21 +1299,42 @@ func listLockUnspent(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
func listReceivedByAccount(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
cmd := icmd.(*btcjson.ListReceivedByAccountCmd)
|
||||
|
||||
results, err := w.TotalReceivedForAccounts(
|
||||
waddrmgr.KeyScopeBIP0044, int32(*cmd.MinConf),
|
||||
)
|
||||
accounts := map[uint32]*wallet.AccountTotalReceivedResult{}
|
||||
err := forEachKeyScope(func(scope waddrmgr.KeyScope) error {
|
||||
results, err := w.TotalReceivedForAccounts(
|
||||
scope, int32(*cmd.MinConf),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, result := range results {
|
||||
account := accounts[result.AccountNumber]
|
||||
if account == nil {
|
||||
dup := result
|
||||
account = &dup
|
||||
accounts[result.AccountNumber] = account
|
||||
}
|
||||
account.TotalReceived += result.TotalReceived
|
||||
if account.LastConfirmation < result.LastConfirmation {
|
||||
account.LastConfirmation = result.LastConfirmation
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
jsonResults := make([]btcjson.ListReceivedByAccountResult, 0, len(results))
|
||||
for _, result := range results {
|
||||
jsonResults = append(jsonResults, btcjson.ListReceivedByAccountResult{
|
||||
Account: result.AccountName,
|
||||
Amount: result.TotalReceived.ToBTC(),
|
||||
Confirmations: uint64(result.LastConfirmation),
|
||||
})
|
||||
jsonResults := make([]btcjson.ListReceivedByAccountResult, 0, len(accounts))
|
||||
for _, account := range accounts {
|
||||
jsonResult := btcjson.ListReceivedByAccountResult{
|
||||
Account: account.AccountName,
|
||||
Amount: account.TotalReceived.ToBTC(),
|
||||
Confirmations: uint64(account.LastConfirmation),
|
||||
}
|
||||
jsonResults = append(jsonResults, jsonResult)
|
||||
}
|
||||
|
||||
return jsonResults, nil
|
||||
}
|
||||
|
||||
|
@ -1353,7 +1434,6 @@ func listReceivedByAddress(icmd interface{}, w *wallet.Wallet) (interface{}, err
|
|||
Amount: addrData.amount.ToBTC(),
|
||||
Confirmations: uint64(addrData.confirmations),
|
||||
TxIDs: addrData.tx,
|
||||
Account: addrData.account,
|
||||
}
|
||||
idx++
|
||||
}
|
||||
|
@ -1386,7 +1466,7 @@ func listSinceBlock(icmd interface{}, w *wallet.Wallet, chainClient *chain.RPCCl
|
|||
start = int32(block.Height) + 1
|
||||
}
|
||||
|
||||
txInfoList, err := w.ListSinceBlock(start, -1, syncBlock.Height)
|
||||
txInfoList, err := w.ListSinceBlock("*", start, -1, syncBlock.Height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1407,23 +1487,10 @@ func listSinceBlock(icmd interface{}, w *wallet.Wallet, chainClient *chain.RPCCl
|
|||
// listTransactions handles a listtransactions request by returning an
|
||||
// array of maps with details of sent and recevied wallet transactions.
|
||||
func listTransactions(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
|
||||
cmd := icmd.(*btcjson.ListTransactionsCmd)
|
||||
|
||||
// TODO: ListTransactions does not currently understand the difference
|
||||
// between transactions pertaining to one account from another. This
|
||||
// will be resolved when wtxmgr is combined with the waddrmgr namespace.
|
||||
|
||||
if cmd.Account != nil && *cmd.Account != "*" && *cmd.Account != "default" {
|
||||
// For now, don't bother trying to continue if the user
|
||||
// specified an account, since this can't be (easily or
|
||||
// efficiently) calculated.
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCWallet,
|
||||
Message: "Transactions are not yet grouped by account",
|
||||
}
|
||||
}
|
||||
|
||||
return w.ListTransactions(*cmd.From, *cmd.Count)
|
||||
return w.ListTransactions(*cmd.Account, *cmd.From, *cmd.Count)
|
||||
}
|
||||
|
||||
// listAddressTransactions handles a listaddresstransactions request by
|
||||
|
@ -1434,13 +1501,6 @@ func listTransactions(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
func listAddressTransactions(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
cmd := icmd.(*btcjson.ListAddressTransactionsCmd)
|
||||
|
||||
if cmd.Account != nil && *cmd.Account != "*" {
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCInvalidParameter,
|
||||
Message: "Listing transactions for addresses may only be done for all accounts",
|
||||
}
|
||||
}
|
||||
|
||||
// Decode addresses.
|
||||
hash160Map := make(map[string]struct{})
|
||||
for _, addrStr := range cmd.Addresses {
|
||||
|
@ -1451,7 +1511,7 @@ func listAddressTransactions(icmd interface{}, w *wallet.Wallet) (interface{}, e
|
|||
hash160Map[string(addr.ScriptAddress())] = struct{}{}
|
||||
}
|
||||
|
||||
return w.ListAddressTransactions(hash160Map)
|
||||
return w.ListAddressTransactions(*cmd.Account, hash160Map)
|
||||
}
|
||||
|
||||
// listAllTransactions handles a listalltransactions request by returning
|
||||
|
@ -1459,16 +1519,10 @@ func listAddressTransactions(icmd interface{}, w *wallet.Wallet) (interface{}, e
|
|||
// similar to ListTransactions, except it takes only a single optional
|
||||
// argument for the account name and replies with all transactions.
|
||||
func listAllTransactions(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
|
||||
cmd := icmd.(*btcjson.ListAllTransactionsCmd)
|
||||
|
||||
if cmd.Account != nil && *cmd.Account != "*" {
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCInvalidParameter,
|
||||
Message: "Listing all transactions may only be done for all accounts",
|
||||
}
|
||||
}
|
||||
|
||||
return w.ListAllTransactions()
|
||||
return w.ListAllTransactions(*cmd.Account)
|
||||
}
|
||||
|
||||
// listUnspent handles the listunspent command.
|
||||
|
@ -1535,7 +1589,7 @@ func makeOutputs(pairs map[string]btcutil.Amount, chainParams *chaincfg.Params)
|
|||
// It returns the transaction hash in string format upon success
|
||||
// All errors are returned in btcjson.RPCError format
|
||||
func sendPairs(w *wallet.Wallet, amounts map[string]btcutil.Amount,
|
||||
keyScope waddrmgr.KeyScope, account uint32, minconf int32,
|
||||
keyScope *waddrmgr.KeyScope, account uint32, minconf int32,
|
||||
feeSatPerKb btcutil.Amount) (string, error) {
|
||||
|
||||
outputs, err := makeOutputs(amounts, w.ChainParams())
|
||||
|
@ -1543,7 +1597,7 @@ func sendPairs(w *wallet.Wallet, amounts map[string]btcutil.Amount,
|
|||
return "", err
|
||||
}
|
||||
tx, err := w.SendOutputs(
|
||||
outputs, &keyScope, account, minconf, feeSatPerKb,
|
||||
outputs, keyScope, account, minconf, feeSatPerKb,
|
||||
wallet.CoinSelectionLargest, "",
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -1577,7 +1631,9 @@ func isNilOrEmpty(s *string) bool {
|
|||
// address. Leftover inputs not sent to the payment address or a fee for
|
||||
// the miner are sent back to a new address in the wallet. Upon success,
|
||||
// the TxID for the created transaction is returned.
|
||||
func sendFrom(icmd interface{}, w *wallet.Wallet, chainClient *chain.RPCClient) (interface{}, error) {
|
||||
func sendFrom(icmd interface{}, w *wallet.Wallet,
|
||||
chainClient *chain.RPCClient) (interface{}, error) {
|
||||
|
||||
cmd := icmd.(*btcjson.SendFromCmd)
|
||||
|
||||
// Transaction comments are not yet supported. Error instead of
|
||||
|
@ -1589,9 +1645,7 @@ func sendFrom(icmd interface{}, w *wallet.Wallet, chainClient *chain.RPCClient)
|
|||
}
|
||||
}
|
||||
|
||||
account, err := w.AccountNumber(
|
||||
waddrmgr.KeyScopeBIP0044, cmd.FromAccount,
|
||||
)
|
||||
account, err := w.AccountNumber(cmd.FromAccount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1604,6 +1658,7 @@ func sendFrom(icmd interface{}, w *wallet.Wallet, chainClient *chain.RPCClient)
|
|||
if minConf < 0 {
|
||||
return nil, ErrNeedPositiveMinconf
|
||||
}
|
||||
|
||||
// Create map of address and amount pairs.
|
||||
amt, err := btcutil.NewAmount(cmd.Amount)
|
||||
if err != nil {
|
||||
|
@ -1613,7 +1668,13 @@ func sendFrom(icmd interface{}, w *wallet.Wallet, chainClient *chain.RPCClient)
|
|||
cmd.ToAddress: amt,
|
||||
}
|
||||
|
||||
return sendPairs(w, pairs, waddrmgr.KeyScopeBIP0044, account, minConf,
|
||||
// Use specified scope, if provided.
|
||||
scope, err := lookupKeyScope(cmd.AddressType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return sendPairs(w, pairs, scope, account, minConf,
|
||||
txrules.DefaultRelayFeePerKb)
|
||||
}
|
||||
|
||||
|
@ -1623,6 +1684,7 @@ func sendFrom(icmd interface{}, w *wallet.Wallet, chainClient *chain.RPCClient)
|
|||
// or a fee for the miner are sent back to a new address in the wallet.
|
||||
// Upon success, the TxID for the created transaction is returned.
|
||||
func sendMany(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
||||
|
||||
cmd := icmd.(*btcjson.SendManyCmd)
|
||||
|
||||
// Transaction comments are not yet supported. Error instead of
|
||||
|
@ -1634,7 +1696,7 @@ func sendMany(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
}
|
||||
}
|
||||
|
||||
account, err := w.AccountNumber(waddrmgr.KeyScopeBIP0044, cmd.FromAccount)
|
||||
account, err := w.AccountNumber(cmd.FromAccount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1645,6 +1707,12 @@ func sendMany(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
return nil, ErrNeedPositiveMinconf
|
||||
}
|
||||
|
||||
// Use specified scope, if provided.
|
||||
scope, err := lookupKeyScope(cmd.AddressType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Recreate address/amount pairs, using dcrutil.Amount.
|
||||
pairs := make(map[string]btcutil.Amount, len(cmd.Amounts))
|
||||
for k, v := range cmd.Amounts {
|
||||
|
@ -1655,7 +1723,7 @@ func sendMany(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
pairs[k] = amt
|
||||
}
|
||||
|
||||
return sendPairs(w, pairs, waddrmgr.KeyScopeBIP0044, account, minConf, txrules.DefaultRelayFeePerKb)
|
||||
return sendPairs(w, pairs, scope, account, minConf, txrules.DefaultRelayFeePerKb)
|
||||
}
|
||||
|
||||
// sendToAddress handles a sendtoaddress RPC request by creating a new
|
||||
|
@ -1690,8 +1758,14 @@ func sendToAddress(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
cmd.Address: amt,
|
||||
}
|
||||
|
||||
// Use specified scope, if provided.
|
||||
scope, err := lookupKeyScope(cmd.AddressType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// sendtoaddress always spends from the default account, this matches bitcoind
|
||||
return sendPairs(w, pairs, waddrmgr.KeyScopeBIP0044, waddrmgr.DefaultAccountNum, 1,
|
||||
return sendPairs(w, pairs, scope, waddrmgr.DefaultAccountNum, 1,
|
||||
txrules.DefaultRelayFeePerKb)
|
||||
}
|
||||
|
||||
|
@ -1946,9 +2020,7 @@ func validateAddress(icmd interface{}, w *wallet.Wallet) (interface{}, error) {
|
|||
// The address lookup was successful which means there is further
|
||||
// information about it available and it is "mine".
|
||||
result.IsMine = true
|
||||
acctName, err := w.AccountName(
|
||||
waddrmgr.KeyScopeBIP0044, ainfo.InternalAccount(),
|
||||
)
|
||||
acctName, err := w.AccountName(ainfo.InternalAccount())
|
||||
if err != nil {
|
||||
return nil, &ErrAccountNameNotFound
|
||||
}
|
||||
|
@ -2110,3 +2182,17 @@ func decodeHexStr(hexStr string) ([]byte, error) {
|
|||
}
|
||||
return decoded, nil
|
||||
}
|
||||
|
||||
// forEachKeyScope calls the given function with each default key scopes
|
||||
// breaking early on error.
|
||||
func forEachKeyScope(fn func(scope waddrmgr.KeyScope) error) error {
|
||||
|
||||
for _, scope := range waddrmgr.DefaultKeyScopes {
|
||||
err := fn(scope)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -4,51 +4,51 @@ package legacyrpc
|
|||
|
||||
func helpDescsEnUS() map[string]string {
|
||||
return map[string]string{
|
||||
"addmultisigaddress": "addmultisigaddress nrequired [\"key\",...] (\"account\")\n\nGenerates and imports a multisig address and redeeming script to the 'imported' account.\n\nArguments:\n1. nrequired (numeric, required) The number of signatures required to redeem outputs paid to this address\n2. keys (array of string, required) Pubkeys and/or pay-to-pubkey-hash addresses to partially control the multisig address\n3. account (string, optional) DEPRECATED -- Unused (all imported addresses belong to the imported account)\n\nResult:\n\"value\" (string) The imported pay-to-script-hash address\n",
|
||||
"createmultisig": "createmultisig nrequired [\"key\",...]\n\nGenerate a multisig address and redeem script.\n\nArguments:\n1. nrequired (numeric, required) The number of signatures required to redeem outputs paid to this address\n2. keys (array of string, required) Pubkeys and/or pay-to-pubkey-hash addresses to partially control the multisig address\n\nResult:\n{\n \"address\": \"value\", (string) The generated pay-to-script-hash address\n \"redeemScript\": \"value\", (string) The script required to redeem outputs paid to the multisig address\n} \n",
|
||||
"dumpprivkey": "dumpprivkey \"address\"\n\nReturns the private key in WIF encoding that controls some wallet address.\n\nArguments:\n1. address (string, required) The address to return a private key for\n\nResult:\n\"value\" (string) The WIF-encoded private key\n",
|
||||
"getaccount": "getaccount \"address\"\n\nDEPRECATED -- Lookup the account name that some wallet address belongs to.\n\nArguments:\n1. address (string, required) The address to query the account for\n\nResult:\n\"value\" (string) The name of the account that 'address' belongs to\n",
|
||||
"getaccountaddress": "getaccountaddress \"account\"\n\nDEPRECATED -- Returns the most recent external payment address for an account that has not been seen publicly.\nA new address is generated for the account if the most recently generated address has been seen on the blockchain or in mempool.\n\nArguments:\n1. account (string, required) The account of the returned address\n\nResult:\n\"value\" (string) The unused address for 'account'\n",
|
||||
"getaddressesbyaccount": "getaddressesbyaccount \"account\"\n\nDEPRECATED -- Returns all addresses strings controlled by a single account.\n\nArguments:\n1. account (string, required) Account name to fetch addresses for\n\nResult:\n[\"value\",...] (array of string) All addresses controlled by 'account'\n",
|
||||
"getaddressinfo": "getaddressinfo \"address\"\n\nGenerates and returns a new payment address.\n\nArguments:\n1. address (string, required) The address to get the information of.\n\nResult:\n{\n \"address\": \"value\", (string) The address validated\n \"scriptPubKey\": \"value\", (string) The hex-encoded scriptPubKey generated by the address.\n \"desc\": \"value\", (string) A descriptor for spending coins sent to this address (only when solvable).\n \"isscript\": true|false, (boolean) If the key is a script.\n \"ischange\": true|false, (boolean) If the address was used for change output.\n \"iswitness\": true|false, (boolean) If the address is a witness address.\n \"witness_version\": n, (numeric) The version number of the witness program.\n \"witness_program\": \"value\", (string) The hex value of the witness program.\n \"script\": n, (numeric) The output script type. Only if isscript is true and the redeemscript is known. Possible types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash, witness_v0_scripthash, witness_unknown.\n \"hex\": \"value\", (string) The redeemscript for the p2sh address.\n \"pubkeys\": [\"value\",...], (array of string) The hex value of the raw public key for single-key addresses (possibly embedded in P2SH or P2WSH).\n \"sigsrequired\": n, (numeric) The number of signatures required to spend multisig output (only if script is multisig).\n \"pubkey\": \"value\", (string) Array of pubkeys associated with the known redeemscript (only if script is multisig).\n \"iscompressed\": true|false, (boolean) If the pubkey is compressed.\n \"hdmasterfingerprint\": \"value\", (string) The fingerprint of the master key.\n \"labels\": [\"value\",...], (array of string) Array of labels associated with the address. Currently limited to one label but returned.\n \"ismine\": true|false, (boolean) If the address is yours.\n \"iswatchonly\": true|false, (boolean) If the address is watchonly.\n \"timestamp\": n, (numeric) The creation time of the key, if available, expressed in UNIX epoch time.\n \"hdkeypath\": \"value\", (string) The HD keypath, if the key is HD and available.\n \"hdseedid\": \"value\", (string) The Hash160 of the HD seed.\n \"embedded\": { (object) Information about the address embedded in P2SH or P2WSH, if relevant and known.\n \"address\": \"value\", (string) The address validated\n \"scriptPubKey\": \"value\", (string) The hex-encoded scriptPubKey generated by the address.\n \"desc\": \"value\", (string) A descriptor for spending coins sent to this address (only when solvable).\n \"isscript\": true|false, (boolean) If the key is a script.\n \"ischange\": true|false, (boolean) If the address was used for change output.\n \"iswitness\": true|false, (boolean) If the address is a witness address.\n \"witness_version\": n, (numeric) The version number of the witness program.\n \"witness_program\": \"value\", (string) The hex value of the witness program.\n \"script\": n, (numeric) The output script type. Only if isscript is true and the redeemscript is known. Possible types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash, witness_v0_scripthash, witness_unknown.\n \"hex\": \"value\", (string) The redeemscript for the p2sh address.\n \"pubkeys\": [\"value\",...], (array of string) The hex value of the raw public key for single-key addresses (possibly embedded in P2SH or P2WSH).\n \"sigsrequired\": n, (numeric) The number of signatures required to spend multisig output (only if script is multisig).\n \"pubkey\": \"value\", (string) Array of pubkeys associated with the known redeemscript (only if script is multisig).\n \"iscompressed\": true|false, (boolean) If the pubkey is compressed.\n \"hdmasterfingerprint\": \"value\", (string) The fingerprint of the master key.\n \"labels\": [\"value\",...], (array of string) Array of labels associated with the address. Currently limited to one label but returned.\n }, \n} \n",
|
||||
"getbalance": "getbalance (\"account\" minconf=1)\n\nCalculates and returns the balance of one or all accounts.\n\nArguments:\n1. account (string, optional) DEPRECATED -- The account name to query the balance for, or \"*\" to consider all accounts (default=\"*\")\n2. minconf (numeric, optional, default=1) Minimum number of block confirmations required before an unspent output's value is included in the balance\n\nResult (account != \"*\"):\nn.nnn (numeric) The balance of 'account' valued in bitcoin\n\nResult (account = \"*\"):\nn.nnn (numeric) The balance of all accounts valued in bitcoin\n",
|
||||
"getbestblockhash": "getbestblockhash\n\nReturns the hash of the newest block in the best chain that wallet has finished syncing with.\n\nArguments:\nNone\n\nResult:\n\"value\" (string) The hash of the most recent synced-to block\n",
|
||||
"getblockcount": "getblockcount\n\nReturns the blockchain height of the newest block in the best chain that wallet has finished syncing with.\n\nArguments:\nNone\n\nResult:\nn.nnn (numeric) The blockchain height of the most recent synced-to block\n",
|
||||
"getinfo": "getinfo\n\nReturns a JSON object containing various state info.\n\nArguments:\nNone\n\nResult:\n{\n \"version\": n, (numeric) The version of the server\n \"protocolversion\": n, (numeric) The latest supported protocol version\n \"walletversion\": n, (numeric) The version of the address manager database\n \"balance\": n.nnn, (numeric) The non-staked balance of all accounts calculated with one block confirmation\n \"blocks\": n, (numeric) The number of blocks processed\n \"timeoffset\": n, (numeric) The time offset\n \"connections\": n, (numeric) The number of connected peers\n \"proxy\": \"value\", (string) The proxy used by the server\n \"difficulty\": n.nnn, (numeric) The current target difficulty\n \"testnet\": true|false, (boolean) Whether or not server is using testnet\n \"keypoololdest\": n, (numeric) Unset\n \"keypoolsize\": n, (numeric) Unset\n \"unlocked_until\": n, (numeric) Unset\n \"paytxfee\": n.nnn, (numeric) The increment used each time more fee is required for an authored transaction\n \"relayfee\": n.nnn, (numeric) The minimum relay fee for non-free transactions in LBC/KB\n \"errors\": \"value\", (string) Any current errors\n \"staked\": n.nnn, (numeric) The staked balance of all accounts calculated with one block confirmation\n} \n",
|
||||
"getnewaddress": "getnewaddress (\"account\" \"addresstype\")\n\nGenerates and returns a new payment address.\n\nArguments:\n1. account (string, optional) DEPRECATED -- Account name the new address will belong to (default=\"default\")\n2. addresstype (string, optional) Address type. Must be one of legacy / p2pkh, p2sh-p2wpkh / p2sh-p2wkh / p2sh-segwit, or p2wpkh / p2wkh / bech32\n\nResult:\n\"value\" (string) The payment address\n",
|
||||
"getrawchangeaddress": "getrawchangeaddress (\"account\")\n\nGenerates and returns a new internal payment address for use as a change address in raw transactions.\n\nArguments:\n1. account (string, optional) Account name the new internal address will belong to (default=\"default\")\n\nResult:\n\"value\" (string) The internal payment address\n",
|
||||
"getreceivedbyaccount": "getreceivedbyaccount \"account\" (minconf=1)\n\nDEPRECATED -- Returns the total amount received by addresses of some account, including spent outputs.\n\nArguments:\n1. account (string, required) Account name to query total received amount for\n2. minconf (numeric, optional, default=1) Minimum number of block confirmations required before an output's value is included in the total\n\nResult:\nn.nnn (numeric) The total received amount valued in bitcoin\n",
|
||||
"getreceivedbyaddress": "getreceivedbyaddress \"address\" (minconf=1)\n\nReturns the total amount received by a single address, including spent outputs.\n\nArguments:\n1. address (string, required) Payment address which received outputs to include in total\n2. minconf (numeric, optional, default=1) Minimum number of block confirmations required before an output's value is included in the total\n\nResult:\nn.nnn (numeric) The total received amount valued in bitcoin\n",
|
||||
"gettransaction": "gettransaction \"txid\" (includewatchonly=false)\n\nReturns a JSON object with details regarding a transaction relevant to this wallet.\n\nArguments:\n1. txid (string, required) Hash of the transaction to query\n2. includewatchonly (boolean, optional, default=false) Also consider transactions involving watched addresses\n\nResult:\n{\n \"amount\": n.nnn, (numeric) The total amount this transaction credits to the wallet, valued in bitcoin\n \"fee\": n.nnn, (numeric) The total input value minus the total output value, or 0 if 'txid' is not a sent transaction\n \"confirmations\": n, (numeric) The number of block confirmations of the transaction\n \"blockhash\": \"value\", (string) The hash of the block this transaction is mined in, or the empty string if unmined\n \"blockindex\": n, (numeric) Unset\n \"blocktime\": n, (numeric) The Unix time of the block header this transaction is mined in, or 0 if unmined\n \"txid\": \"value\", (string) The transaction hash\n \"walletconflicts\": [\"value\",...], (array of string) Unset\n \"time\": n, (numeric) The earliest Unix time this transaction was known to exist\n \"timereceived\": n, (numeric) The earliest Unix time this transaction was known to exist\n \"details\": [{ (array of object) Additional details for each recorded wallet credit and debit\n \"account\": \"value\", (string) DEPRECATED -- Unset\n \"address\": \"value\", (string) The address an output was paid to, or the empty string if the output is nonstandard or this detail is regarding a transaction input\n \"amount\": n.nnn, (numeric) The amount of a received output\n \"category\": \"value\", (string) The kind of detail: \"send\" for sent transactions, \"immature\" for immature coinbase outputs, \"generate\" for mature coinbase outputs, or \"recv\" for all other received outputs\n \"involveswatchonly\": true|false, (boolean) Unset\n \"fee\": n.nnn, (numeric) The included fee for a sent transaction\n \"vout\": n, (numeric) The transaction output index\n },...], \n \"hex\": \"value\", (string) The transaction encoded as a hexadecimal string\n} \n",
|
||||
"help": "help (\"command\")\n\nReturns a list of all commands or help for a specified command.\n\nArguments:\n1. command (string, optional) The command to retrieve help for\n\nResult (no command provided):\n\"value\" (string) List of commands\n\nResult (command specified):\n\"value\" (string) Help for specified command\n",
|
||||
"importprivkey": "importprivkey \"privkey\" (\"label\" rescan=true)\n\nImports a WIF-encoded private key to the 'imported' account.\n\nArguments:\n1. privkey (string, required) The WIF-encoded private key\n2. label (string, optional) Unused (must be unset or 'imported')\n3. rescan (boolean, optional, default=true) Rescan the blockchain (since the genesis block) for outputs controlled by the imported key\n\nResult:\nNothing\n",
|
||||
"keypoolrefill": "keypoolrefill (newsize=100)\n\nDEPRECATED -- This request does nothing since no keypool is maintained.\n\nArguments:\n1. newsize (numeric, optional, default=100) Unused\n\nResult:\nNothing\n",
|
||||
"listaccounts": "listaccounts (minconf=1)\n\nDEPRECATED -- Returns a JSON object of all accounts and their balances.\n\nArguments:\n1. minconf (numeric, optional, default=1) Minimum number of block confirmations required before an unspent output's value is included in the balance\n\nResult:\n{\n \"The account name\": The account balance valued in bitcoin, (object) JSON object with account names as keys and bitcoin amounts as values\n ...\n}\n",
|
||||
"listlockunspent": "listlockunspent\n\nReturns a JSON array of outpoints marked as locked (with lockunspent) for this wallet session.\n\nArguments:\nNone\n\nResult:\n[{\n \"txid\": \"value\", (string) The transaction hash of the referenced output\n \"vout\": n, (numeric) The output index of the referenced output\n},...]\n",
|
||||
"listreceivedbyaccount": "listreceivedbyaccount (minconf=1 includeempty=false includewatchonly=false)\n\nDEPRECATED -- Returns a JSON array of objects listing all accounts and the total amount received by each account.\n\nArguments:\n1. minconf (numeric, optional, default=1) Minimum number of block confirmations required before a transaction is considered\n2. includeempty (boolean, optional, default=false) Unused\n3. includewatchonly (boolean, optional, default=false) Unused\n\nResult:\n[{\n \"account\": \"value\", (string) The name of the account\n \"amount\": n.nnn, (numeric) Total amount received by payment addresses of the account valued in bitcoin\n \"confirmations\": n, (numeric) Number of block confirmations of the most recent transaction relevant to the account\n},...]\n",
|
||||
"listreceivedbyaddress": "listreceivedbyaddress (minconf=1 includeempty=false includewatchonly=false)\n\nReturns a JSON array of objects listing wallet payment addresses and their total received amounts.\n\nArguments:\n1. minconf (numeric, optional, default=1) Minimum number of block confirmations required before a transaction is considered\n2. includeempty (boolean, optional, default=false) Unused\n3. includewatchonly (boolean, optional, default=false) Unused\n\nResult:\n[{\n \"account\": \"value\", (string) DEPRECATED -- Unset\n \"address\": \"value\", (string) The payment address\n \"amount\": n.nnn, (numeric) Total amount received by the payment address valued in bitcoin\n \"confirmations\": n, (numeric) Number of block confirmations of the most recent transaction relevant to the address\n \"txids\": [\"value\",...], (array of string) Transaction hashes of all transactions involving this address\n \"involvesWatchonly\": true|false, (boolean) Unset\n},...]\n",
|
||||
"listsinceblock": "listsinceblock (\"blockhash\" targetconfirmations=1 includewatchonly=false)\n\nReturns a JSON array of objects listing details of all wallet transactions after some block.\n\nArguments:\n1. blockhash (string, optional) Hash of the parent block of the first block to consider transactions from, or unset to list all transactions\n2. targetconfirmations (numeric, optional, default=1) Minimum number of block confirmations of the last block in the result object. Must be 1 or greater. Note: The transactions array in the result object is not affected by this parameter\n3. includewatchonly (boolean, optional, default=false) Unused\n\nResult:\n{\n \"transactions\": [{ (array of object) JSON array of objects containing verbose details of the each transaction\n \"abandoned\": true|false, (boolean) Unset\n \"account\": \"value\", (string) DEPRECATED -- Unset\n \"address\": \"value\", (string) Payment address for a transaction output\n \"amount\": n.nnn, (numeric) The value of the transaction output valued in bitcoin\n \"bip125-replaceable\": \"value\", (string) Unset\n \"blockhash\": \"value\", (string) The hash of the block this transaction is mined in, or the empty string if unmined\n \"blockheight\": n, (numeric) The block height containing the transaction.\n \"blockindex\": n, (numeric) Unset\n \"blocktime\": n, (numeric) The Unix time of the block header this transaction is mined in, or 0 if unmined\n \"category\": \"value\", (string) The kind of transaction: \"send\" for sent transactions, \"immature\" for immature coinbase outputs, \"generate\" for mature coinbase outputs, or \"recv\" for all other received outputs. Note: A single output may be included multiple times under different categories\n \"confirmations\": n, (numeric) The number of block confirmations of the transaction\n \"fee\": n.nnn, (numeric) The total input value minus the total output value for sent transactions\n \"generated\": true|false, (boolean) Whether the transaction output is a coinbase output\n \"involveswatchonly\": true|false, (boolean) Unset\n \"label\": \"value\", (string) A comment for the address/transaction, if any\n \"time\": n, (numeric) The earliest Unix time this transaction was known to exist\n \"timereceived\": n, (numeric) The earliest Unix time this transaction was known to exist\n \"trusted\": true|false, (boolean) Unset\n \"txid\": \"value\", (string) The hash of the transaction\n \"vout\": n, (numeric) The transaction output index\n \"walletconflicts\": [\"value\",...], (array of string) Unset\n \"comment\": \"value\", (string) Unset\n \"otheraccount\": \"value\", (string) Unset\n },...], \n \"lastblock\": \"value\", (string) Hash of the latest-synced block to be used in later calls to listsinceblock\n} \n",
|
||||
"listtransactions": "listtransactions (\"account\" count=10 from=0 includewatchonly=false)\n\nReturns a JSON array of objects containing verbose details for wallet transactions.\n\nArguments:\n1. account (string, optional) DEPRECATED -- Unused (must be unset, \"default\" or \"*\")\n2. count (numeric, optional, default=10) Maximum number of transactions to create results from\n3. from (numeric, optional, default=0) Number of transactions to skip before results are created\n4. includewatchonly (boolean, optional, default=false) Unused\n\nResult:\n[{\n \"abandoned\": true|false, (boolean) Unset\n \"account\": \"value\", (string) DEPRECATED -- Unset\n \"address\": \"value\", (string) Payment address for a transaction output\n \"amount\": n.nnn, (numeric) The value of the transaction output valued in bitcoin\n \"bip125-replaceable\": \"value\", (string) Unset\n \"blockhash\": \"value\", (string) The hash of the block this transaction is mined in, or the empty string if unmined\n \"blockheight\": n, (numeric) The block height containing the transaction.\n \"blockindex\": n, (numeric) Unset\n \"blocktime\": n, (numeric) The Unix time of the block header this transaction is mined in, or 0 if unmined\n \"category\": \"value\", (string) The kind of transaction: \"send\" for sent transactions, \"immature\" for immature coinbase outputs, \"generate\" for mature coinbase outputs, or \"recv\" for all other received outputs. Note: A single output may be included multiple times under different categories\n \"confirmations\": n, (numeric) The number of block confirmations of the transaction\n \"fee\": n.nnn, (numeric) The total input value minus the total output value for sent transactions\n \"generated\": true|false, (boolean) Whether the transaction output is a coinbase output\n \"involveswatchonly\": true|false, (boolean) Unset\n \"label\": \"value\", (string) A comment for the address/transaction, if any\n \"time\": n, (numeric) The earliest Unix time this transaction was known to exist\n \"timereceived\": n, (numeric) The earliest Unix time this transaction was known to exist\n \"trusted\": true|false, (boolean) Unset\n \"txid\": \"value\", (string) The hash of the transaction\n \"vout\": n, (numeric) The transaction output index\n \"walletconflicts\": [\"value\",...], (array of string) Unset\n \"comment\": \"value\", (string) Unset\n \"otheraccount\": \"value\", (string) Unset\n},...]\n",
|
||||
"listunspent": "listunspent (minconf=1 maxconf=9999999 [\"address\",...])\n\nReturns a JSON array of objects representing unlocked unspent outputs controlled by wallet keys.\n\nArguments:\n1. minconf (numeric, optional, default=1) Minimum number of block confirmations required before a transaction output is considered\n2. maxconf (numeric, optional, default=9999999) Maximum number of block confirmations required before a transaction output is excluded\n3. addresses (array of string, optional) If set, limits the returned details to unspent outputs received by any of these payment addresses\n\nResult:\n{\n \"txid\": \"value\", (string) The transaction hash of the referenced output\n \"vout\": n, (numeric) The output index of the referenced output\n \"address\": \"value\", (string) The payment address that received the output\n \"account\": \"value\", (string) The account associated with the receiving payment address\n \"scriptPubKey\": \"value\", (string) The output script encoded as a hexadecimal string\n \"redeemScript\": \"value\", (string) Unset\n \"amount\": n.nnn, (numeric) The amount of the output valued in bitcoin\n \"confirmations\": n, (numeric) The number of block confirmations of the transaction\n \"solvable\": true|false, (boolean) Whether the output is solvable\n \"spendable\": true|false, (boolean) Whether the output is entirely controlled by wallet keys/scripts (false for partially controlled multisig outputs or outputs to watch-only addresses)\n \"isstake\": true|false, (boolean) Whether the output is staked\n} \n",
|
||||
"lockunspent": "lockunspent unlock [{\"txid\":\"value\",\"vout\":n},...]\n\nLocks or unlocks an unspent output.\nLocked outputs are not chosen for transaction inputs of authored transactions and are not included in 'listunspent' results.\nLocked outputs are volatile and are not saved across wallet restarts.\nIf unlock is true and no transaction outputs are specified, all locked outputs are marked unlocked.\n\nArguments:\n1. unlock (boolean, required) True to unlock outputs, false to lock\n2. transactions (array of object, required) Transaction outputs to lock or unlock\n[{\n \"txid\": \"value\", (string) The transaction hash of the referenced output\n \"vout\": n, (numeric) The output index of the referenced output\n},...]\n\nResult:\ntrue|false (boolean) The boolean 'true'\n",
|
||||
"sendfrom": "sendfrom \"fromaccount\" \"toaddress\" amount (minconf=1 \"comment\" \"commentto\")\n\nDEPRECATED -- Authors, signs, and sends a transaction that outputs some amount to a payment address.\nA change output is automatically included to send extra output value back to the original account.\n\nArguments:\n1. fromaccount (string, required) Account to pick unspent outputs from\n2. toaddress (string, required) Address to pay\n3. amount (numeric, required) Amount to send to the payment address valued in bitcoin\n4. minconf (numeric, optional, default=1) Minimum number of block confirmations required before a transaction output is eligible to be spent\n5. comment (string, optional) Unused\n6. commentto (string, optional) Unused\n\nResult:\n\"value\" (string) The transaction hash of the sent transaction\n",
|
||||
"sendmany": "sendmany \"fromaccount\" {\"address\":amount,...} (minconf=1 \"comment\")\n\nAuthors, signs, and sends a transaction that outputs to many payment addresses.\nA change output is automatically included to send extra output value back to the original account.\n\nArguments:\n1. fromaccount (string, required) DEPRECATED -- Account to pick unspent outputs from\n2. amounts (object, required) Pairs of payment addresses and the output amount to pay each\n{\n \"Address to pay\": Amount to send to the payment address valued in bitcoin, (object) JSON object using payment addresses as keys and output amounts valued in bitcoin to send to each address\n ...\n}\n3. minconf (numeric, optional, default=1) Minimum number of block confirmations required before a transaction output is eligible to be spent\n4. comment (string, optional) Unused\n\nResult:\n\"value\" (string) The transaction hash of the sent transaction\n",
|
||||
"sendtoaddress": "sendtoaddress \"address\" amount (\"comment\" \"commentto\")\n\nAuthors, signs, and sends a transaction that outputs some amount to a payment address.\nUnlike sendfrom, outputs are always chosen from the default account.\nA change output is automatically included to send extra output value back to the original account.\n\nArguments:\n1. address (string, required) Address to pay\n2. amount (numeric, required) Amount to send to the payment address valued in bitcoin\n3. comment (string, optional) Unused\n4. commentto (string, optional) Unused\n\nResult:\n\"value\" (string) The transaction hash of the sent transaction\n",
|
||||
"settxfee": "settxfee amount\n\nModify the increment used each time more fee is required for an authored transaction.\n\nArguments:\n1. amount (numeric, required) The new fee increment valued in bitcoin\n\nResult:\ntrue|false (boolean) The boolean 'true'\n",
|
||||
"signmessage": "signmessage \"address\" \"message\"\n\nSigns a message using the private key of a payment address.\n\nArguments:\n1. address (string, required) Payment address of private key used to sign the message with\n2. message (string, required) Message to sign\n\nResult:\n\"value\" (string) The signed message encoded as a base64 string\n",
|
||||
"signrawtransaction": "signrawtransaction \"rawtx\" ([{\"txid\":\"value\",\"vout\":n,\"scriptpubkey\":\"value\",\"redeemscript\":\"value\"},...] [\"privkey\",...] flags=\"ALL\")\n\nSigns transaction inputs using private keys from this wallet and request.\nThe valid flags options are ALL, NONE, SINGLE, ALL|ANYONECANPAY, NONE|ANYONECANPAY, and SINGLE|ANYONECANPAY.\n\nArguments:\n1. rawtx (string, required) Unsigned or partially unsigned transaction to sign encoded as a hexadecimal string\n2. inputs (array of object, optional) Additional data regarding inputs that this wallet may not be tracking\n3. privkeys (array of string, optional) Additional WIF-encoded private keys to use when creating signatures\n4. flags (string, optional, default=\"ALL\") Sighash flags\n\nResult:\n{\n \"hex\": \"value\", (string) The resulting transaction encoded as a hexadecimal string\n \"complete\": true|false, (boolean) Whether all input signatures have been created\n \"errors\": [{ (array of object) Script verification errors (if exists)\n \"txid\": \"value\", (string) The transaction hash of the referenced previous output\n \"vout\": n, (numeric) The output index of the referenced previous output\n \"scriptSig\": \"value\", (string) The hex-encoded signature script\n \"sequence\": n, (numeric) Script sequence number\n \"error\": \"value\", (string) Verification or signing error related to the input\n },...], \n} \n",
|
||||
"validateaddress": "validateaddress \"address\"\n\nVerify that an address is valid.\nExtra details are returned if the address is controlled by this wallet.\nThe following fields are valid only when the address is controlled by this wallet (ismine=true): isscript, pubkey, iscompressed, account, addresses, hex, script, and sigsrequired.\nThe following fields are only valid when address has an associated public key: pubkey, iscompressed.\nThe following fields are only valid when address is a pay-to-script-hash address: addresses, hex, and script.\nIf the address is a multisig address controlled by this wallet, the multisig fields will be left unset if the wallet is locked since the redeem script cannot be decrypted.\n\nArguments:\n1. address (string, required) Address to validate\n\nResult:\n{\n \"isvalid\": true|false, (boolean) Whether or not the address is valid\n \"address\": \"value\", (string) The payment address (only when isvalid is true)\n \"ismine\": true|false, (boolean) Whether this address is controlled by the wallet (only when isvalid is true)\n \"iswatchonly\": true|false, (boolean) Unset\n \"isscript\": true|false, (boolean) Whether the payment address is a pay-to-script-hash address (only when isvalid is true)\n \"pubkey\": \"value\", (string) The associated public key of the payment address, if any (only when isvalid is true)\n \"iscompressed\": true|false, (boolean) Whether the address was created by hashing a compressed public key, if any (only when isvalid is true)\n \"account\": \"value\", (string) The account this payment address belongs to (only when isvalid is true)\n \"addresses\": [\"value\",...], (array of string) All associated payment addresses of the script if address is a multisig address (only when isvalid is true)\n \"hex\": \"value\", (string) The redeem script \n \"script\": \"value\", (string) The class of redeem script for a multisig address\n \"sigsrequired\": n, (numeric) The number of required signatures to redeem outputs to the multisig address\n} \n",
|
||||
"verifymessage": "verifymessage \"address\" \"signature\" \"message\"\n\nVerify a message was signed with the associated private key of some address.\n\nArguments:\n1. address (string, required) Address used to sign message\n2. signature (string, required) The signature to verify\n3. message (string, required) The message to verify\n\nResult:\ntrue|false (boolean) Whether the message was signed with the private key of 'address'\n",
|
||||
"addmultisigaddress": "addmultisigaddress nrequired [\"key\",...] (\"account\")\n\nGenerates and imports a multisig address and redeeming script to the 'imported' account.\n\nArguments:\n1. nrequired (numeric, required) The number of signatures required to redeem outputs paid to this address.\n2. keys (array of string, required) Pubkeys and/or pay-to-pubkey-hash addresses to partially control the multisig address.\n3. account (string, optional) DEPRECATED -- Unused (all imported addresses belong to the imported account).\n\nResult:\n\"value\" (string) The imported pay-to-script-hash address.\n",
|
||||
"createmultisig": "createmultisig nrequired [\"key\",...]\n\nGenerate a multisig address and redeem script.\n\nArguments:\n1. nrequired (numeric, required) The number of signatures required to redeem outputs paid to this address.\n2. keys (array of string, required) Pubkeys and/or pay-to-pubkey-hash addresses to partially control the multisig address.\n\nResult:\n{\n \"address\": \"value\", (string) The generated pay-to-script-hash address.\n \"redeemScript\": \"value\", (string) The script required to redeem outputs paid to the multisig address.\n} \n",
|
||||
"dumpprivkey": "dumpprivkey \"address\"\n\nReturns the private key in WIF encoding that controls some wallet address.\n\nArguments:\n1. address (string, required) The address to return a private key for.\n\nResult:\n\"value\" (string) The WIF-encoded private key.\n",
|
||||
"getaccount": "getaccount \"address\"\n\nLookup the account name that some wallet address belongs to.\n\nArguments:\n1. address (string, required) The address to query the account for.\n\nResult:\n\"value\" (string) The name of the account that 'address' belongs to.\n",
|
||||
"getaccountaddress": "getaccountaddress (account=\"default\" addresstype=\"legacy\")\n\nReturns the most recent external payment address for an account that has not been seen publicly.\nA new address is generated for the account if the most recently generated address has been seen on the blockchain or in mempool.\n\nArguments:\n1. account (string, optional, default=\"default\") The account of the returned address. Defaults to 'default'\n2. addresstype (string, optional, default=\"legacy\") Address type. Must be one of 'legacy', 'p2sh-segwit', or 'bech32'. Default to 'legacy'.\n\nResult:\n\"value\" (string) The unused address for 'account'.\n",
|
||||
"getaddressesbyaccount": "getaddressesbyaccount (account=\"default\" addresstype=\"*\")\n\nReturns all addresses controlled by a single account.\n\nArguments:\n1. account (string, optional, default=\"default\") Account name to fetch addresses for. Defaults to 'default'\n2. addresstype (string, optional, default=\"*\") Address type filter. Must be one of 'legacy', 'p2sh-segwit', 'bech32', or '*'. Defaults to '*'.\n\nResult:\n[\"value\",...] (array of string) All addresses controlled by 'account' filtered by 'addresstype'.\n",
|
||||
"getaddressinfo": "getaddressinfo \"address\"\n\nGenerates and returns a new payment address.\n\nArguments:\n1. address (string, required) The address to get the information of.\n\nResult:\n{\n \"address\": \"value\", (string) The address validatedi.\n \"scriptPubKey\": \"value\", (string) The hex-encoded scriptPubKey generated by the address.\n \"desc\": \"value\", (string) A descriptor for spending coins sent to this address (only when solvable).\n \"isscript\": true|false, (boolean) If the key is a script.\n \"ischange\": true|false, (boolean) If the address was used for change output.\n \"iswitness\": true|false, (boolean) If the address is a witness address.\n \"witness_version\": n, (numeric) The version number of the witness program.\n \"witness_program\": \"value\", (string) The hex value of the witness program.\n \"script\": n, (numeric) The output script type. Only if isscript is true and the redeemscript is known. Possible types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash, witness_v0_scripthash, witness_unknown.\n \"hex\": \"value\", (string) The redeemscript for the p2sh address.\n \"pubkeys\": [\"value\",...], (array of string) The hex value of the raw public key for single-key addresses (possibly embedded in P2SH or P2WSH).\n \"sigsrequired\": n, (numeric) The number of signatures required to spend multisig output (only if script is multisig).\n \"pubkey\": \"value\", (string) Array of pubkeys associated with the known redeemscript (only if script is multisig).\n \"iscompressed\": true|false, (boolean) If the pubkey is compressed.\n \"hdmasterfingerprint\": \"value\", (string) The fingerprint of the master key.\n \"labels\": [\"value\",...], (array of string) Array of labels associated with the address. Currently limited to one label but returned.\n \"ismine\": true|false, (boolean) If the address is yours.\n \"iswatchonly\": true|false, (boolean) If the address is watchonly.\n \"timestamp\": n, (numeric) The creation time of the key, if available, expressed in UNIX epoch time.\n \"hdkeypath\": \"value\", (string) The HD keypath, if the key is HD and available.\n \"hdseedid\": \"value\", (string) The Hash160 of the HD seed.\n \"embedded\": { (object) Information about the address embedded in P2SH or P2WSH, if relevant and known.\n \"address\": \"value\", (string) The address validated.\n \"scriptPubKey\": \"value\", (string) The hex-encoded scriptPubKey generated by the address.\n \"desc\": \"value\", (string) A descriptor for spending coins sent to this address (only when solvable).\n \"isscript\": true|false, (boolean) If the key is a script.\n \"ischange\": true|false, (boolean) If the address was used for change output.\n \"iswitness\": true|false, (boolean) If the address is a witness address.\n \"witness_version\": n, (numeric) The version number of the witness program.\n \"witness_program\": \"value\", (string) The hex value of the witness program.\n \"script\": n, (numeric) The output script type. Only if isscript is true and the redeemscript is known. Possible types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash, witness_v0_scripthash, witness_unknown.\n \"hex\": \"value\", (string) The redeemscript for the p2sh address.\n \"pubkeys\": [\"value\",...], (array of string) The hex value of the raw public key for single-key addresses (possibly embedded in P2SH or P2WSH).\n \"sigsrequired\": n, (numeric) The number of signatures required to spend multisig output (only if script is multisig).\n \"pubkey\": \"value\", (string) Array of pubkeys associated with the known redeemscript (only if script is multisig).\n \"iscompressed\": true|false, (boolean) If the pubkey is compressed.\n \"hdmasterfingerprint\": \"value\", (string) The fingerprint of the master key.\n \"labels\": [\"value\",...], (array of string) Array of labels associated with the address. Currently limited to one label but returned.\n }, \n} \n",
|
||||
"getbalance": "getbalance (account=\"default\" minconf=1 addresstype=\"*\")\n\nCalculates and returns the balance of one or all accounts.\n\nArguments:\n1. account (string, optional, default=\"default\") Account name or '*' for all accounts to query the balance for. Default to 'default'.\n2. minconf (numeric, optional, default=1) Minimum number of block confirmations required before an unspent output's value is included in the balance.\n3. addresstype (string, optional, default=\"*\") Address type filter. Must be one of 'legacy', 'p2sh-segwit', 'bech32', or '*'. Default to '*'.\n\nResult:\nn.nnn (numeric) The balance valued in LBC.\n",
|
||||
"getbestblockhash": "getbestblockhash\n\nReturns the hash of the newest block in the best chain that wallet has finished syncing with.\n\nArguments:\nNone\n\nResult:\n\"value\" (string) The hash of the most recent synced-to block.\n",
|
||||
"getblockcount": "getblockcount\n\nReturns the blockchain height of the newest block in the best chain that wallet has finished syncing with.\n\nArguments:\nNone\n\nResult:\nn.nnn (numeric) The blockchain height of the most recent synced-to block.\n",
|
||||
"getinfo": "getinfo\n\nReturns a JSON object containing various state info.\n\nArguments:\nNone\n\nResult:\n{\n \"version\": n, (numeric) The version of the server.\n \"protocolversion\": n, (numeric) The latest supported protocol version.\n \"walletversion\": n, (numeric) The version of the address manager database.\n \"balance\": n.nnn, (numeric) The non-staked balance of all accounts calculated with one block confirmation.\n \"blocks\": n, (numeric) The number of blocks processed.\n \"timeoffset\": n, (numeric) The time offset.\n \"connections\": n, (numeric) The number of connected peers.\n \"proxy\": \"value\", (string) The proxy used by the server.\n \"difficulty\": n.nnn, (numeric) The current target difficulty.\n \"testnet\": true|false, (boolean) Whether or not server is using testnet.\n \"keypoololdest\": n, (numeric) Unset.\n \"keypoolsize\": n, (numeric) Unset.\n \"unlocked_until\": n, (numeric) Unset.\n \"paytxfee\": n.nnn, (numeric) The increment used each time more fee is required for an authored transaction.\n \"relayfee\": n.nnn, (numeric) The minimum relay fee for non-free transactions in LBC/KB.\n \"errors\": \"value\", (string) Any current errors.\n \"staked\": n.nnn, (numeric) The staked balance of all accounts calculated with one block confirmation.\n} \n",
|
||||
"getnewaddress": "getnewaddress (account=\"default\" addresstype=\"legacy\")\n\nGenerates and returns a new payment address.\n\nArguments:\n1. account (string, optional, default=\"default\") Account name the new address will belong to. Defaults to 'default'.\n2. addresstype (string, optional, default=\"legacy\") Address type. Must be one of 'legacy', 'p2sh-segwit', or 'bech32'. Default to 'legacy'.\n\nResult:\n\"value\" (string) The payment address.\n",
|
||||
"getrawchangeaddress": "getrawchangeaddress (account=\"default\" addresstype=\"legacy\")\n\nGenerates and returns a new internal payment address for use as a change address in raw transactions.\n\nArguments:\n1. account (string, optional, default=\"default\") Account name the new internal address will belong to. Defaults to 'default'.\n2. addresstype (string, optional, default=\"legacy\") Address type. Must be one of 'legacy', 'p2sh-segwit', or 'bech32'. Default to 'legacy'.\n\nResult:\n\"value\" (string) The internal payment address.\n",
|
||||
"getreceivedbyaccount": "getreceivedbyaccount (account=\"default\" minconf=1)\n\nReturns the total amount received by addresses of some account, including spent outputs.\n\nArguments:\n1. account (string, optional, default=\"default\") Account name to query total received amount for. Defaults to 'default'\n2. minconf (numeric, optional, default=1) Minimum number of block confirmations required before an output's value is included in the total. Defaults to 0\n\nResult:\nn.nnn (numeric) The total received amount valued in LBC.\n",
|
||||
"getreceivedbyaddress": "getreceivedbyaddress \"address\" (minconf=1)\n\nReturns the total amount received by a single address, including spent outputs.\n\nArguments:\n1. address (string, required) Payment address which received outputs to include in total.\n2. minconf (numeric, optional, default=1) Minimum number of block confirmations required before an output's value is included in the total. Defaults to 1\n\nResult:\nn.nnn (numeric) The total received amount valued in LBC.\n",
|
||||
"gettransaction": "gettransaction \"txid\" (includewatchonly=false)\n\nReturns a JSON object with details regarding a transaction relevant to this wallet.\n\nArguments:\n1. txid (string, required) Hash of the transaction to query.\n2. includewatchonly (boolean, optional, default=false) Also consider transactions involving watched addresses.\n\nResult:\n{\n \"amount\": n.nnn, (numeric) The total amount this transaction credits to the wallet, valued in LBC.\n \"fee\": n.nnn, (numeric) The total input value minus the total output value, or 0 if 'txid' is not a sent transaction.\n \"confirmations\": n, (numeric) The number of block confirmations of the transaction.\n \"blockhash\": \"value\", (string) The hash of the block this transaction is mined in, or the empty string if unmined.\n \"blockindex\": n, (numeric) Unset.\n \"blocktime\": n, (numeric) The Unix time of the block header this transaction is mined in, or 0 if unmined.\n \"txid\": \"value\", (string) The transaction hash.\n \"walletconflicts\": [\"value\",...], (array of string) Unset.\n \"time\": n, (numeric) The earliest Unix time this transaction was known to exist.\n \"timereceived\": n, (numeric) The earliest Unix time this transaction was known to exist.\n \"details\": [{ (array of object) Additional details for each recorded wallet credit and debit.\n \"account\": \"value\", (string) The account pertaining to this transaction.\n \"address\": \"value\", (string) The address an output was paid to, or the empty string if the output is nonstandard or this detail is regarding a transaction input.\n \"amount\": n.nnn, (numeric) The amount of a received output.\n \"category\": \"value\", (string) The kind of detail: \"send\" for sent transactions, \"immature\" for immature coinbase outputs, \"generate\" for mature coinbase outputs, or \"recv\" for all other received outputs.\n \"involveswatchonly\": true|false, (boolean) Unset.\n \"fee\": n.nnn, (numeric) The included fee for a sent transaction.\n \"vout\": n, (numeric) The transaction output index.\n },...], \n \"hex\": \"value\", (string) The transaction encoded as a hexadecimal string.\n \"generated\": true|false, (boolean) Only present if transaction only input is a coinbase one.\n} \n",
|
||||
"help": "help (\"command\")\n\nReturns a list of all commands or help for a specified command.\n\nArguments:\n1. command (string, optional) The command to retrieve help for.\n\nResult (no command provided.):\n\"value\" (string) List of commands.\n\nResult (command specified.):\n\"value\" (string) Help for specified command.\n",
|
||||
"importprivkey": "importprivkey \"privkey\" (\"label\" rescan=true)\n\nImports a WIF-encoded private key to the 'imported' account.\n\nArguments:\n1. privkey (string, required) The WIF-encoded private key.\n2. label (string, optional) Unused (must be unset or 'imported').\n3. rescan (boolean, optional, default=true) Rescan the blockchain (since the genesis block) for outputs controlled by the imported key.\n\nResult:\nNothing\n",
|
||||
"keypoolrefill": "keypoolrefill (newsize=100)\n\nDEPRECATED -- This request does nothing since no keypool is maintained.\n\nArguments:\n1. newsize (numeric, optional, default=100) Unused.\n\nResult:\nNothing\n",
|
||||
"listaccounts": "listaccounts (minconf=1 addresstype=\"*\")\n\nReturns a JSON object of all accounts and their balances.\n\nArguments:\n1. minconf (numeric, optional, default=1) Minimum number of block confirmations required before an unspent output's value is included in the balance.\n2. addresstype (string, optional, default=\"*\") Address type filter. Must be one of 'legacy', 'p2sh-segwit', 'bech32', or '*'. Defaults to '*'.\n\nResult:\n{\n \"Account name\": Total balance and each scope respectively, valued in LBC., (object) JSON object with account names as keys and LBC amounts as values.\n ...\n}\n",
|
||||
"listlockunspent": "listlockunspent\n\nReturns a JSON array of outpoints marked as locked (with lockunspent) for this wallet session.\n\nArguments:\nNone\n\nResult:\n[{\n \"txid\": \"value\", (string) The transaction hash of the referenced output.\n \"vout\": n, (numeric) The output index of the referenced output.\n},...]\n",
|
||||
"listreceivedbyaccount": "listreceivedbyaccount (minconf=1 includeempty=false includewatchonly=false)\n\nReturns a JSON array of objects listing all accounts and the total amount received by each account.\n\nArguments:\n1. minconf (numeric, optional, default=1) Minimum number of block confirmations required before a transaction is considered.\n2. includeempty (boolean, optional, default=false) Unused.\n3. includewatchonly (boolean, optional, default=false) Unused.\n\nResult:\n[{\n \"account\": \"value\", (string) Account name.\n \"amount\": n.nnn, (numeric) Total amount received by payment addresses of the account valued in LBC.\n \"confirmations\": n, (numeric) Number of block confirmations of the most recent transaction relevant to the account.\n},...]\n",
|
||||
"listreceivedbyaddress": "listreceivedbyaddress (minconf=1 includeempty=false includewatchonly=false)\n\nReturns a JSON array of objects listing wallet payment addresses and their total received amounts.\n\nArguments:\n1. minconf (numeric, optional, default=1) Minimum number of block confirmations required before a transaction is considered.\n2. includeempty (boolean, optional, default=false) Unused.\n3. includewatchonly (boolean, optional, default=false) Unused.\n\nResult:\n[{\n \"address\": \"value\", (string) The payment address.\n \"amount\": n.nnn, (numeric) Total amount received by the payment address valued in LBC.\n \"confirmations\": n, (numeric) Number of block confirmations of the most recent transaction relevant to the address.\n \"txids\": [\"value\",...], (array of string) Transaction hashes of all transactions involving this address.\n \"involvesWatchonly\": true|false, (boolean) Unset.\n},...]\n",
|
||||
"listsinceblock": "listsinceblock (\"blockhash\" targetconfirmations=1 includewatchonly=false)\n\nReturns a JSON array of objects listing details of all wallet transactions after some block.\n\nArguments:\n1. blockhash (string, optional) Hash of the parent block of the first block to consider transactions from, or unset to list all transactions.\n2. targetconfirmations (numeric, optional, default=1) Minimum number of block confirmations of the last block in the result object. Must be 1 or greater. Note: The transactions array in the result object is not affected by this parameter.\n3. includewatchonly (boolean, optional, default=false) Unused.\n\nResult:\n{\n \"transactions\": [{ (array of object) JSON array of objects containing verbose details of the each transaction.\n \"abandoned\": true|false, (boolean) Unset.\n \"account\": \"value\", (string) The account name associated with the transaction.\n \"address\": \"value\", (string) Payment address for a transaction output.\n \"amount\": n.nnn, (numeric) The value of the transaction output valued in LBC.\n \"bip125-replaceable\": \"value\", (string) Unset.\n \"blockhash\": \"value\", (string) The hash of the block this transaction is mined in, or the empty string if unmined.\n \"blockheight\": n, (numeric) The block height containing the transaction.\n \"blockindex\": n, (numeric) Unset.\n \"blocktime\": n, (numeric) The Unix time of the block header this transaction is mined in, or 0 if unmined.\n \"category\": \"value\", (string) The kind of transaction: \"send\" for sent transactions, \"immature\" for immature coinbase outputs, \"generate\" for mature coinbase outputs, or \"recv\" for all other received outputs. Note: A single output may be included multiple times under different categories\n \"confirmations\": n, (numeric) The number of block confirmations of the transaction.\n \"fee\": n.nnn, (numeric) The total input value minus the total output value for sent transactions.\n \"generated\": true|false, (boolean) Whether the transaction output is a coinbase output.\n \"involveswatchonly\": true|false, (boolean) Unset.\n \"label\": \"value\", (string) A comment for the address/transaction, if any.\n \"time\": n, (numeric) The earliest Unix time this transaction was known to exist.\n \"timereceived\": n, (numeric) The earliest Unix time this transaction was known to exist.\n \"trusted\": true|false, (boolean) Unset.\n \"txid\": \"value\", (string) The hash of the transaction.\n \"vout\": n, (numeric) The transaction output index.\n \"walletconflicts\": [\"value\",...], (array of string) Unset.\n \"comment\": \"value\", (string) Unset.\n \"otheraccount\": \"value\", (string) Unset.\n },...], \n \"lastblock\": \"value\", (string) Hash of the latest-synced block to be used in later calls to listsinceblock.\n} \n",
|
||||
"listtransactions": "listtransactions (account=\"default\" count=10 from=0 includewatchonly=false)\n\nReturns a JSON array of objects containing verbose details for wallet transactions.\n\nArguments:\n1. account (string, optional, default=\"default\") Account to filter transactions results by. Defaults to 'default'.\n2. count (numeric, optional, default=10) Maximum number of transactions to create results from. Defaults to 10\n3. from (numeric, optional, default=0) Number of transactions to skip before results are created.\n4. includewatchonly (boolean, optional, default=false) Unused.\n\nResult:\n[{\n \"abandoned\": true|false, (boolean) Unset.\n \"account\": \"value\", (string) The account name associated with the transaction.\n \"address\": \"value\", (string) Payment address for a transaction output.\n \"amount\": n.nnn, (numeric) The value of the transaction output valued in LBC.\n \"bip125-replaceable\": \"value\", (string) Unset.\n \"blockhash\": \"value\", (string) The hash of the block this transaction is mined in, or the empty string if unmined.\n \"blockheight\": n, (numeric) The block height containing the transaction.\n \"blockindex\": n, (numeric) Unset.\n \"blocktime\": n, (numeric) The Unix time of the block header this transaction is mined in, or 0 if unmined.\n \"category\": \"value\", (string) The kind of transaction: \"send\" for sent transactions, \"immature\" for immature coinbase outputs, \"generate\" for mature coinbase outputs, or \"recv\" for all other received outputs. Note: A single output may be included multiple times under different categories\n \"confirmations\": n, (numeric) The number of block confirmations of the transaction.\n \"fee\": n.nnn, (numeric) The total input value minus the total output value for sent transactions.\n \"generated\": true|false, (boolean) Whether the transaction output is a coinbase output.\n \"involveswatchonly\": true|false, (boolean) Unset.\n \"label\": \"value\", (string) A comment for the address/transaction, if any.\n \"time\": n, (numeric) The earliest Unix time this transaction was known to exist.\n \"timereceived\": n, (numeric) The earliest Unix time this transaction was known to exist.\n \"trusted\": true|false, (boolean) Unset.\n \"txid\": \"value\", (string) The hash of the transaction.\n \"vout\": n, (numeric) The transaction output index.\n \"walletconflicts\": [\"value\",...], (array of string) Unset.\n \"comment\": \"value\", (string) Unset.\n \"otheraccount\": \"value\", (string) Unset.\n},...]\n",
|
||||
"listunspent": "listunspent (minconf=1 maxconf=9999999 [\"address\",...])\n\nReturns a JSON array of objects representing unlocked unspent outputs controlled by wallet keys.\n\nArguments:\n1. minconf (numeric, optional, default=1) Minimum number of block confirmations required before a transaction output is considered.\n2. maxconf (numeric, optional, default=9999999) Maximum number of block confirmations required before a transaction output is excluded.\n3. addresses (array of string, optional) If set, limits the returned details to unspent outputs received by any of these payment addresses.\n\nResult:\n{\n \"txid\": \"value\", (string) The transaction hash of the referenced output.\n \"vout\": n, (numeric) The output index of the referenced output.\n \"address\": \"value\", (string) The payment address that received the output.\n \"account\": \"value\", (string) The account associated with the receiving payment address.\n \"scriptPubKey\": \"value\", (string) The output script encoded as a hexadecimal string.\n \"redeemScript\": \"value\", (string) Unset.\n \"amount\": n.nnn, (numeric) The amount of the output valued in LBC.\n \"confirmations\": n, (numeric) The number of block confirmations of the transaction.\n \"solvable\": true|false, (boolean) Whether the output is solvable.\n \"spendable\": true|false, (boolean) Whether the output is entirely controlled by wallet keys/scripts (false for partially controlled multisig outputs or outputs to watch-only addresses).\n \"isstake\": true|false, (boolean) Whether the output is staked.\n} \n",
|
||||
"lockunspent": "lockunspent unlock [{\"txid\":\"value\",\"vout\":n},...]\n\nLocks or unlocks an unspent output.\nLocked outputs are not chosen for transaction inputs of authored transactions and are not included in 'listunspent' results.\nLocked outputs are volatile and are not saved across wallet restarts.\nIf unlock is true and no transaction outputs are specified, all locked outputs are marked unlocked.\n\nArguments:\n1. unlock (boolean, required) True to unlock outputs, false to lock.\n2. transactions (array of object, required) Transaction outputs to lock or unlock.\n[{\n \"txid\": \"value\", (string) The transaction hash of the referenced output.\n \"vout\": n, (numeric) The output index of the referenced output.\n},...]\n\nResult:\ntrue|false (boolean) The boolean 'true'.\n",
|
||||
"sendfrom": "sendfrom \"fromaccount\" \"toaddress\" amount (minconf=1 addresstype=\"*\" \"comment\" \"commentto\")\n\nAuthors, signs, and sends a transaction that outputs some amount to a payment address.\nA change output is automatically included to send extra output value back to the original account.\n\nArguments:\n1. fromaccount (string, required) Account to pick unspent outputs from.\n2. toaddress (string, required) Address to pay.\n3. amount (numeric, required) Amount to send to the payment address valued in LBC.\n4. minconf (numeric, optional, default=1) Minimum number of block confirmations required before a transaction output is eligible to be spent.\n5. addresstype (string, optional, default=\"*\") Address type filter for UTXOs to spent from. Must be one of 'legacy', 'p2sh-segwit', 'bech32', or '*'. Defaults to '*'.\n6. comment (string, optional) Unused.\n7. commentto (string, optional) Unused.\n\nResult:\n\"value\" (string) The transaction hash of the sent transaction.\n",
|
||||
"sendmany": "sendmany \"fromaccount\" {\"address\":amount,...} (minconf=1 addresstype=\"*\" \"comment\")\n\nAuthors, signs, and sends a transaction that outputs to many payment addresses.\nA change output is automatically included to send extra output value back to the original account.\n\nArguments:\n1. fromaccount (string, required) Account to pick unspent outputs from.\n2. amounts (object, required) Pairs of payment addresses and the output amount to pay each.\n{\n \"Address to pay.\": Amount to send to the payment address valued in LBC., (object) JSON object using payment addresses as keys and output amounts valued in LBC to send to each address.\n ...\n}\n3. minconf (numeric, optional, default=1) Minimum number of block confirmations required before a transaction output is eligible to be spent.\n4. addresstype (string, optional, default=\"*\") Address type filter for UTXOs to spent from. Must be one of 'legacy', 'p2sh-segwit', 'bech32', or '*'. Defaults to '*'.\n5. comment (string, optional) Unused.\n\nResult:\n\"value\" (string) The transaction hash of the sent transaction.\n",
|
||||
"sendtoaddress": "sendtoaddress \"address\" amount (addresstype=\"*\" \"comment\" \"commentto\")\n\nAuthors, signs, and sends a transaction that outputs some amount to a payment address.\nUnlike sendfrom, outputs are always chosen from the default account.\nA change output is automatically included to send extra output value back to the original account.\n\nArguments:\n1. address (string, required) Address to pay.\n2. amount (numeric, required) Amount to send to the payment address valued in LBC.\n3. addresstype (string, optional, default=\"*\") Address type filter for UTXOs to spent from. Must be one of 'legacy', 'p2sh-segwit', 'bech32', or '*'. Defaults to '*'.\n4. comment (string, optional) Unused.\n5. commentto (string, optional) Unused.\n\nResult:\n\"value\" (string) The transaction hash of the sent transaction.\n",
|
||||
"settxfee": "settxfee amount\n\nModify the increment used each time more fee is required for an authored transaction.\n\nArguments:\n1. amount (numeric, required) The new fee increment valued in LBC.\n\nResult:\ntrue|false (boolean) The boolean 'true'.\n",
|
||||
"signmessage": "signmessage \"address\" \"message\"\n\nSigns a message using the private key of a payment address.\n\nArguments:\n1. address (string, required) Payment address of private key used to sign the message with.\n2. message (string, required) Message to sign.\n\nResult:\n\"value\" (string) The signed message encoded as a base64 string.\n",
|
||||
"signrawtransaction": "signrawtransaction \"rawtx\" ([{\"txid\":\"value\",\"vout\":n,\"scriptpubkey\":\"value\",\"redeemscript\":\"value\"},...] [\"privkey\",...] flags=\"ALL\")\n\nSigns transaction inputs using private keys from this wallet and request.\nThe valid flags options are ALL, NONE, SINGLE, ALL|ANYONECANPAY, NONE|ANYONECANPAY, and SINGLE|ANYONECANPAY.\n\nArguments:\n1. rawtx (string, required) Unsigned or partially unsigned transaction to sign encoded as a hexadecimal string.\n2. inputs (array of object, optional) Additional data regarding inputs that this wallet may not be tracking.\n3. privkeys (array of string, optional) Additional WIF-encoded private keys to use when creating signatures.\n4. flags (string, optional, default=\"ALL\") Sighash flags.\n\nResult:\n{\n \"hex\": \"value\", (string) The resulting transaction encoded as a hexadecimal string.\n \"complete\": true|false, (boolean) Whether all input signatures have been created.\n \"errors\": [{ (array of object) Script verification errors (if exists).\n \"txid\": \"value\", (string) The transaction hash of the referenced previous output.\n \"vout\": n, (numeric) The output index of the referenced previous output.\n \"scriptSig\": \"value\", (string) The hex-encoded signature script.\n \"sequence\": n, (numeric) Script sequence number.\n \"error\": \"value\", (string) Verification or signing error related to the input.\n },...], \n} \n",
|
||||
"validateaddress": "validateaddress \"address\"\n\nVerify that an address is valid.\nExtra details are returned if the address is controlled by this wallet.\nThe following fields are valid only when the address is controlled by this wallet (ismine=true): isscript, pubkey, iscompressed, account, addresses, hex, script, and sigsrequired.\nThe following fields are only valid when address has an associated public key: pubkey, iscompressed.\nThe following fields are only valid when address is a pay-to-script-hash address: addresses, hex, and script.\nIf the address is a multisig address controlled by this wallet, the multisig fields will be left unset if the wallet is locked since the redeem script cannot be decrypted.\n\nArguments:\n1. address (string, required) Address to validate.\n\nResult:\n{\n \"isvalid\": true|false, (boolean) Whether or not the address is valid.\n \"address\": \"value\", (string) The payment address (only when isvalid is true).\n \"ismine\": true|false, (boolean) Whether this address is controlled by the wallet (only when isvalid is true).\n \"iswatchonly\": true|false, (boolean) Unset.\n \"isscript\": true|false, (boolean) Whether the payment address is a pay-to-script-hash address (only when isvalid is true).\n \"pubkey\": \"value\", (string) The associated public key of the payment address, if any (only when isvalid is true).\n \"iscompressed\": true|false, (boolean) Whether the address was created by hashing a compressed public key, if any (only when isvalid is true).\n \"account\": \"value\", (string) The account this payment address belongs to (only when isvalid is true).\n \"addresses\": [\"value\",...], (array of string) All associated payment addresses of the script if address is a multisig address (only when isvalid is true).\n \"hex\": \"value\", (string) The redeem script .\n \"script\": \"value\", (string) The class of redeem script for a multisig address.\n \"sigsrequired\": n, (numeric) The number of required signatures to redeem outputs to the multisig address.\n} \n",
|
||||
"verifymessage": "verifymessage \"address\" \"signature\" \"message\"\n\nVerify a message was signed with the associated private key of some address.\n\nArguments:\n1. address (string, required) Address used to sign message.\n2. signature (string, required) The signature to verify.\n3. message (string, required) The message to verify.\n\nResult:\ntrue|false (boolean) Whether the message was signed with the private key of 'address'.\n",
|
||||
"walletlock": "walletlock\n\nLock the wallet.\n\nArguments:\nNone\n\nResult:\nNothing\n",
|
||||
"walletpassphrase": "walletpassphrase \"passphrase\" timeout\n\nUnlock the wallet.\n\nArguments:\n1. passphrase (string, required) The wallet passphrase\n2. timeout (numeric, required) The number of seconds to wait before the wallet automatically locks\n\nResult:\nNothing\n",
|
||||
"walletpassphrasechange": "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n\nChange the wallet passphrase.\n\nArguments:\n1. oldpassphrase (string, required) The old wallet passphrase\n2. newpassphrase (string, required) The new wallet passphrase\n\nResult:\nNothing\n",
|
||||
"createnewaccount": "createnewaccount \"account\"\n\nCreates a new account.\nThe wallet must be unlocked for this request to succeed.\n\nArguments:\n1. account (string, required) Name of the new account\n\nResult:\nNothing\n",
|
||||
"getbestblock": "getbestblock\n\nReturns the hash and height of the newest block in the best chain that wallet has finished syncing with.\n\nArguments:\nNone\n\nResult:\n{\n \"hash\": \"value\", (string) The hash of the block\n \"height\": n, (numeric) The blockchain height of the block\n} \n",
|
||||
"getunconfirmedbalance": "getunconfirmedbalance (\"account\")\n\nCalculates the unspent output value of all unmined transaction outputs for an account.\n\nArguments:\n1. account (string, optional) The account to query the unconfirmed balance for (default=\"default\")\n\nResult:\nn.nnn (numeric) Total amount of all unmined unspent outputs of the account valued in bitcoin.\n",
|
||||
"listaddresstransactions": "listaddresstransactions [\"address\",...] (\"account\")\n\nReturns a JSON array of objects containing verbose details for wallet transactions pertaining some addresses.\n\nArguments:\n1. addresses (array of string, required) Addresses to filter transaction results by\n2. account (string, optional) Unused (must be unset or \"*\")\n\nResult:\n[{\n \"abandoned\": true|false, (boolean) Unset\n \"account\": \"value\", (string) DEPRECATED -- Unset\n \"address\": \"value\", (string) Payment address for a transaction output\n \"amount\": n.nnn, (numeric) The value of the transaction output valued in bitcoin\n \"bip125-replaceable\": \"value\", (string) Unset\n \"blockhash\": \"value\", (string) The hash of the block this transaction is mined in, or the empty string if unmined\n \"blockheight\": n, (numeric) The block height containing the transaction.\n \"blockindex\": n, (numeric) Unset\n \"blocktime\": n, (numeric) The Unix time of the block header this transaction is mined in, or 0 if unmined\n \"category\": \"value\", (string) The kind of transaction: \"send\" for sent transactions, \"immature\" for immature coinbase outputs, \"generate\" for mature coinbase outputs, or \"recv\" for all other received outputs. Note: A single output may be included multiple times under different categories\n \"confirmations\": n, (numeric) The number of block confirmations of the transaction\n \"fee\": n.nnn, (numeric) The total input value minus the total output value for sent transactions\n \"generated\": true|false, (boolean) Whether the transaction output is a coinbase output\n \"involveswatchonly\": true|false, (boolean) Unset\n \"label\": \"value\", (string) A comment for the address/transaction, if any\n \"time\": n, (numeric) The earliest Unix time this transaction was known to exist\n \"timereceived\": n, (numeric) The earliest Unix time this transaction was known to exist\n \"trusted\": true|false, (boolean) Unset\n \"txid\": \"value\", (string) The hash of the transaction\n \"vout\": n, (numeric) The transaction output index\n \"walletconflicts\": [\"value\",...], (array of string) Unset\n \"comment\": \"value\", (string) Unset\n \"otheraccount\": \"value\", (string) Unset\n},...]\n",
|
||||
"listalltransactions": "listalltransactions (\"account\")\n\nReturns a JSON array of objects in the same format as 'listtransactions' without limiting the number of returned objects.\n\nArguments:\n1. account (string, optional) Unused (must be unset or \"*\")\n\nResult:\n[{\n \"abandoned\": true|false, (boolean) Unset\n \"account\": \"value\", (string) DEPRECATED -- Unset\n \"address\": \"value\", (string) Payment address for a transaction output\n \"amount\": n.nnn, (numeric) The value of the transaction output valued in bitcoin\n \"bip125-replaceable\": \"value\", (string) Unset\n \"blockhash\": \"value\", (string) The hash of the block this transaction is mined in, or the empty string if unmined\n \"blockheight\": n, (numeric) The block height containing the transaction.\n \"blockindex\": n, (numeric) Unset\n \"blocktime\": n, (numeric) The Unix time of the block header this transaction is mined in, or 0 if unmined\n \"category\": \"value\", (string) The kind of transaction: \"send\" for sent transactions, \"immature\" for immature coinbase outputs, \"generate\" for mature coinbase outputs, or \"recv\" for all other received outputs. Note: A single output may be included multiple times under different categories\n \"confirmations\": n, (numeric) The number of block confirmations of the transaction\n \"fee\": n.nnn, (numeric) The total input value minus the total output value for sent transactions\n \"generated\": true|false, (boolean) Whether the transaction output is a coinbase output\n \"involveswatchonly\": true|false, (boolean) Unset\n \"label\": \"value\", (string) A comment for the address/transaction, if any\n \"time\": n, (numeric) The earliest Unix time this transaction was known to exist\n \"timereceived\": n, (numeric) The earliest Unix time this transaction was known to exist\n \"trusted\": true|false, (boolean) Unset\n \"txid\": \"value\", (string) The hash of the transaction\n \"vout\": n, (numeric) The transaction output index\n \"walletconflicts\": [\"value\",...], (array of string) Unset\n \"comment\": \"value\", (string) Unset\n \"otheraccount\": \"value\", (string) Unset\n},...]\n",
|
||||
"renameaccount": "renameaccount \"oldaccount\" \"newaccount\"\n\nRenames an account.\n\nArguments:\n1. oldaccount (string, required) The old account name to rename\n2. newaccount (string, required) The new name for the account\n\nResult:\nNothing\n",
|
||||
"walletislocked": "walletislocked\n\nReturns whether or not the wallet is locked.\n\nArguments:\nNone\n\nResult:\ntrue|false (boolean) Whether the wallet is locked\n",
|
||||
"walletpassphrase": "walletpassphrase \"passphrase\" timeout\n\nUnlock the wallet.\n\nArguments:\n1. passphrase (string, required) The wallet passphrase.\n2. timeout (numeric, required) The number of seconds to wait before the wallet automatically locks.\n\nResult:\nNothing\n",
|
||||
"walletpassphrasechange": "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n\nChange the wallet passphrase.\n\nArguments:\n1. oldpassphrase (string, required) The old wallet passphrase.\n2. newpassphrase (string, required) The new wallet passphrase.\n\nResult:\nNothing\n",
|
||||
"createnewaccount": "createnewaccount \"account\"\n\nCreates a new account.\n\nArguments:\n1. account (string, required) Account name.\n\nResult:\nNothing\n",
|
||||
"getbestblock": "getbestblock\n\nReturns the hash and height of the newest block in the best chain that wallet has finished syncing with.\n\nArguments:\nNone\n\nResult:\n{\n \"hash\": \"value\", (string) The hash of the block.\n \"height\": n, (numeric) The blockchain height of the block.\n} \n",
|
||||
"getunconfirmedbalance": "getunconfirmedbalance (account=\"default\")\n\nCalculates the unspent output value of all unmined transaction outputs.\n\nArguments:\n1. account (string, optional, default=\"default\") The account name to query the unconfirmed balance for. Default to 'default'.\n\nResult:\nn.nnn (numeric) Total amount of all unmined unspent outputs of the account valued in LBC.\n",
|
||||
"listaddresstransactions": "listaddresstransactions [\"address\",...] (account=\"default\")\n\nReturns a JSON array of objects containing verbose details for wallet transactions pertaining some addresses.\n\nArguments:\n1. addresses (array of string, required) Addresses to filter transaction results by.\n2. account (string, optional, default=\"default\") Account to filter transactions results by. Defaults to 'default'.\n\nResult:\n[{\n \"abandoned\": true|false, (boolean) Unset.\n \"account\": \"value\", (string) The account name associated with the transaction.\n \"address\": \"value\", (string) Payment address for a transaction output.\n \"amount\": n.nnn, (numeric) The value of the transaction output valued in LBC.\n \"bip125-replaceable\": \"value\", (string) Unset.\n \"blockhash\": \"value\", (string) The hash of the block this transaction is mined in, or the empty string if unmined.\n \"blockheight\": n, (numeric) The block height containing the transaction.\n \"blockindex\": n, (numeric) Unset.\n \"blocktime\": n, (numeric) The Unix time of the block header this transaction is mined in, or 0 if unmined.\n \"category\": \"value\", (string) The kind of transaction: \"send\" for sent transactions, \"immature\" for immature coinbase outputs, \"generate\" for mature coinbase outputs, or \"recv\" for all other received outputs. Note: A single output may be included multiple times under different categories\n \"confirmations\": n, (numeric) The number of block confirmations of the transaction.\n \"fee\": n.nnn, (numeric) The total input value minus the total output value for sent transactions.\n \"generated\": true|false, (boolean) Whether the transaction output is a coinbase output.\n \"involveswatchonly\": true|false, (boolean) Unset.\n \"label\": \"value\", (string) A comment for the address/transaction, if any.\n \"time\": n, (numeric) The earliest Unix time this transaction was known to exist.\n \"timereceived\": n, (numeric) The earliest Unix time this transaction was known to exist.\n \"trusted\": true|false, (boolean) Unset.\n \"txid\": \"value\", (string) The hash of the transaction.\n \"vout\": n, (numeric) The transaction output index.\n \"walletconflicts\": [\"value\",...], (array of string) Unset.\n \"comment\": \"value\", (string) Unset.\n \"otheraccount\": \"value\", (string) Unset.\n},...]\n",
|
||||
"listalltransactions": "listalltransactions (account=\"default\")\n\nReturns a JSON array of objects in the same format as 'listtransactions' without limiting the number of returned objects.\n\nArguments:\n1. account (string, optional, default=\"default\") Account to filter transactions results by. Defaults to 'default'.\n\nResult:\n[{\n \"abandoned\": true|false, (boolean) Unset.\n \"account\": \"value\", (string) The account name associated with the transaction.\n \"address\": \"value\", (string) Payment address for a transaction output.\n \"amount\": n.nnn, (numeric) The value of the transaction output valued in LBC.\n \"bip125-replaceable\": \"value\", (string) Unset.\n \"blockhash\": \"value\", (string) The hash of the block this transaction is mined in, or the empty string if unmined.\n \"blockheight\": n, (numeric) The block height containing the transaction.\n \"blockindex\": n, (numeric) Unset.\n \"blocktime\": n, (numeric) The Unix time of the block header this transaction is mined in, or 0 if unmined.\n \"category\": \"value\", (string) The kind of transaction: \"send\" for sent transactions, \"immature\" for immature coinbase outputs, \"generate\" for mature coinbase outputs, or \"recv\" for all other received outputs. Note: A single output may be included multiple times under different categories\n \"confirmations\": n, (numeric) The number of block confirmations of the transaction.\n \"fee\": n.nnn, (numeric) The total input value minus the total output value for sent transactions.\n \"generated\": true|false, (boolean) Whether the transaction output is a coinbase output.\n \"involveswatchonly\": true|false, (boolean) Unset.\n \"label\": \"value\", (string) A comment for the address/transaction, if any.\n \"time\": n, (numeric) The earliest Unix time this transaction was known to exist.\n \"timereceived\": n, (numeric) The earliest Unix time this transaction was known to exist.\n \"trusted\": true|false, (boolean) Unset.\n \"txid\": \"value\", (string) The hash of the transaction.\n \"vout\": n, (numeric) The transaction output index.\n \"walletconflicts\": [\"value\",...], (array of string) Unset.\n \"comment\": \"value\", (string) Unset.\n \"otheraccount\": \"value\", (string) Unset.\n},...]\n",
|
||||
"renameaccount": "renameaccount \"oldaccount\" \"newaccount\"\n\nRenames an account.\n\nArguments:\n1. oldaccount (string, required) The old account name to rename.\n2. newaccount (string, required) The new name for the account.\n\nResult:\nNothing\n",
|
||||
"walletislocked": "walletislocked\n\nReturns whether or not the wallet is locked.\n\nArguments:\nNone\n\nResult:\ntrue|false (boolean) Whether the wallet is locked.\n",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,4 +56,4 @@ var localeHelpDescs = map[string]func() map[string]string{
|
|||
"en_US": helpDescsEnUS,
|
||||
}
|
||||
|
||||
var requestUsages = "addmultisigaddress nrequired [\"key\",...] (\"account\")\ncreatemultisig nrequired [\"key\",...]\ndumpprivkey \"address\"\ngetaccount \"address\"\ngetaccountaddress \"account\"\ngetaddressesbyaccount \"account\"\ngetaddressinfo \"address\"\ngetbalance (\"account\" minconf=1)\ngetbestblockhash\ngetblockcount\ngetinfo\ngetnewaddress (\"account\" \"addresstype\")\ngetrawchangeaddress (\"account\")\ngetreceivedbyaccount \"account\" (minconf=1)\ngetreceivedbyaddress \"address\" (minconf=1)\ngettransaction \"txid\" (includewatchonly=false)\nhelp (\"command\")\nimportprivkey \"privkey\" (\"label\" rescan=true)\nkeypoolrefill (newsize=100)\nlistaccounts (minconf=1)\nlistlockunspent\nlistreceivedbyaccount (minconf=1 includeempty=false includewatchonly=false)\nlistreceivedbyaddress (minconf=1 includeempty=false includewatchonly=false)\nlistsinceblock (\"blockhash\" targetconfirmations=1 includewatchonly=false)\nlisttransactions (\"account\" count=10 from=0 includewatchonly=false)\nlistunspent (minconf=1 maxconf=9999999 [\"address\",...])\nlockunspent unlock [{\"txid\":\"value\",\"vout\":n},...]\nsendfrom \"fromaccount\" \"toaddress\" amount (minconf=1 \"comment\" \"commentto\")\nsendmany \"fromaccount\" {\"address\":amount,...} (minconf=1 \"comment\")\nsendtoaddress \"address\" amount (\"comment\" \"commentto\")\nsettxfee amount\nsignmessage \"address\" \"message\"\nsignrawtransaction \"rawtx\" ([{\"txid\":\"value\",\"vout\":n,\"scriptpubkey\":\"value\",\"redeemscript\":\"value\"},...] [\"privkey\",...] flags=\"ALL\")\nvalidateaddress \"address\"\nverifymessage \"address\" \"signature\" \"message\"\nwalletlock\nwalletpassphrase \"passphrase\" timeout\nwalletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\ncreatenewaccount \"account\"\ngetbestblock\ngetunconfirmedbalance (\"account\")\nlistaddresstransactions [\"address\",...] (\"account\")\nlistalltransactions (\"account\")\nrenameaccount \"oldaccount\" \"newaccount\"\nwalletislocked"
|
||||
var requestUsages = "addmultisigaddress nrequired [\"key\",...] (\"account\")\ncreatemultisig nrequired [\"key\",...]\ndumpprivkey \"address\"\ngetaccount \"address\"\ngetaccountaddress (account=\"default\" addresstype=\"legacy\")\ngetaddressesbyaccount (account=\"default\" addresstype=\"*\")\ngetaddressinfo \"address\"\ngetbalance (account=\"default\" minconf=1 addresstype=\"*\")\ngetbestblockhash\ngetblockcount\ngetinfo\ngetnewaddress (account=\"default\" addresstype=\"legacy\")\ngetrawchangeaddress (account=\"default\" addresstype=\"legacy\")\ngetreceivedbyaccount (account=\"default\" minconf=1)\ngetreceivedbyaddress \"address\" (minconf=1)\ngettransaction \"txid\" (includewatchonly=false)\nhelp (\"command\")\nimportprivkey \"privkey\" (\"label\" rescan=true)\nkeypoolrefill (newsize=100)\nlistaccounts (minconf=1 addresstype=\"*\")\nlistlockunspent\nlistreceivedbyaccount (minconf=1 includeempty=false includewatchonly=false)\nlistreceivedbyaddress (minconf=1 includeempty=false includewatchonly=false)\nlistsinceblock (\"blockhash\" targetconfirmations=1 includewatchonly=false)\nlisttransactions (account=\"default\" count=10 from=0 includewatchonly=false)\nlistunspent (minconf=1 maxconf=9999999 [\"address\",...])\nlockunspent unlock [{\"txid\":\"value\",\"vout\":n},...]\nsendfrom \"fromaccount\" \"toaddress\" amount (minconf=1 addresstype=\"*\" \"comment\" \"commentto\")\nsendmany \"fromaccount\" {\"address\":amount,...} (minconf=1 addresstype=\"*\" \"comment\")\nsendtoaddress \"address\" amount (addresstype=\"*\" \"comment\" \"commentto\")\nsettxfee amount\nsignmessage \"address\" \"message\"\nsignrawtransaction \"rawtx\" ([{\"txid\":\"value\",\"vout\":n,\"scriptpubkey\":\"value\",\"redeemscript\":\"value\"},...] [\"privkey\",...] flags=\"ALL\")\nvalidateaddress \"address\"\nverifymessage \"address\" \"signature\" \"message\"\nwalletlock\nwalletpassphrase \"passphrase\" timeout\nwalletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\ncreatenewaccount \"account\"\ngetbestblock\ngetunconfirmedbalance (account=\"default\")\nlistaddresstransactions [\"address\",...] (account=\"default\")\nlistalltransactions (account=\"default\")\nrenameaccount \"oldaccount\" \"newaccount\"\nwalletislocked"
|
||||
|
|
|
@ -42,6 +42,9 @@ const (
|
|||
// ImportedAddrAccountName is the name of the imported account.
|
||||
ImportedAddrAccountName = "imported"
|
||||
|
||||
// AccountGapLimit is used for account discovery defined in BIP0044
|
||||
AccountGapLimit = 20
|
||||
|
||||
// DefaultAccountNum is the number of the default account.
|
||||
DefaultAccountNum = 0
|
||||
|
||||
|
@ -156,13 +159,8 @@ type accountInfo struct {
|
|||
|
||||
// The external branch is used for all addresses which are intended for
|
||||
// external use.
|
||||
nextExternalIndex uint32
|
||||
lastExternalAddr ManagedAddress
|
||||
|
||||
// The internal branch is used for all adddresses which are only
|
||||
// intended for internal wallet use such as change addresses.
|
||||
nextInternalIndex uint32
|
||||
lastInternalAddr ManagedAddress
|
||||
nextIndex [2]uint32
|
||||
lastAddr [2]ManagedAddress
|
||||
|
||||
// addrSchema serves as a way for an account to override its
|
||||
// corresponding address schema with a custom one.
|
||||
|
@ -1532,7 +1530,7 @@ func createManagerKeyScope(ns walletdb.ReadWriteBucket,
|
|||
|
||||
// Derive the account key for the first account according our
|
||||
// BIP0044-like derivation.
|
||||
acctKeyPriv, err := deriveAccountKey(coinTypeKeyPriv, 0)
|
||||
acctKeyPriv, err := deriveAccountKey(coinTypeKeyPriv, DefaultAccountNum)
|
||||
if err != nil {
|
||||
// The seed is unusable if the any of the children in the
|
||||
// required hierarchy can't be derived due to invalid child.
|
||||
|
|
|
@ -334,8 +334,8 @@ func testExternalAddresses(tc *testContext) bool {
|
|||
err := walletdb.Update(tc.db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
var err error
|
||||
addrs, err = tc.manager.NextExternalAddresses(
|
||||
ns, tc.internalAccount, 5,
|
||||
addrs, err = tc.manager.NextAddresses(
|
||||
ns, tc.internalAccount, ExternalBranch, 5,
|
||||
)
|
||||
return err
|
||||
})
|
||||
|
@ -371,8 +371,8 @@ func testExternalAddresses(tc *testContext) bool {
|
|||
err := walletdb.View(tc.db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
var err error
|
||||
lastAddr, err = tc.manager.LastExternalAddress(
|
||||
ns, tc.internalAccount,
|
||||
lastAddr, err = tc.manager.LastAddress(
|
||||
ns, tc.internalAccount, ExternalBranch,
|
||||
)
|
||||
return err
|
||||
})
|
||||
|
@ -478,8 +478,8 @@ func testInternalAddresses(tc *testContext) bool {
|
|||
err := walletdb.Update(tc.db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
var err error
|
||||
addrs, err = tc.manager.NextInternalAddresses(
|
||||
ns, tc.internalAccount, 5,
|
||||
addrs, err = tc.manager.NextAddresses(
|
||||
ns, tc.internalAccount, InternalBranch, 5,
|
||||
)
|
||||
return err
|
||||
})
|
||||
|
@ -515,8 +515,8 @@ func testInternalAddresses(tc *testContext) bool {
|
|||
err := walletdb.View(tc.db, func(tx walletdb.ReadTx) error {
|
||||
ns := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
var err error
|
||||
lastAddr, err = tc.manager.LastInternalAddress(
|
||||
ns, tc.internalAccount,
|
||||
lastAddr, err = tc.manager.LastAddress(
|
||||
ns, tc.internalAccount, InternalBranch,
|
||||
)
|
||||
return err
|
||||
})
|
||||
|
@ -2032,8 +2032,8 @@ func TestScopedKeyManagerManagement(t *testing.T) {
|
|||
t.Fatalf("unable to fetch scope %v: %v", scope, err)
|
||||
}
|
||||
|
||||
externalAddr, err := sMgr.NextExternalAddresses(
|
||||
ns, DefaultAccountNum, 1,
|
||||
externalAddr, err := sMgr.NextAddresses(
|
||||
ns, DefaultAccountNum, ExternalBranch, 1,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to derive external addr: %v", err)
|
||||
|
@ -2047,8 +2047,8 @@ func TestScopedKeyManagerManagement(t *testing.T) {
|
|||
ScopeAddrMap[scope].ExternalAddrType)
|
||||
}
|
||||
|
||||
internalAddr, err := sMgr.NextInternalAddresses(
|
||||
ns, DefaultAccountNum, 1,
|
||||
internalAddr, err := sMgr.NextAddresses(
|
||||
ns, DefaultAccountNum, InternalBranch, 1,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to derive internal addr: %v", err)
|
||||
|
@ -2106,15 +2106,15 @@ func TestScopedKeyManagerManagement(t *testing.T) {
|
|||
|
||||
// We'll now create a new external address to ensure we
|
||||
// retrieve the proper type.
|
||||
externalAddr, err = scopedMgr.NextExternalAddresses(
|
||||
ns, DefaultAccountNum, 1,
|
||||
externalAddr, err = scopedMgr.NextAddresses(
|
||||
ns, DefaultAccountNum, ExternalBranch, 1,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to derive external addr: %v", err)
|
||||
}
|
||||
|
||||
internalAddr, err = scopedMgr.NextInternalAddresses(
|
||||
ns, DefaultAccountNum, 1,
|
||||
internalAddr, err = scopedMgr.NextAddresses(
|
||||
ns, DefaultAccountNum, InternalBranch, 1,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to derive internal addr: %v", err)
|
||||
|
@ -2177,8 +2177,8 @@ func TestScopedKeyManagerManagement(t *testing.T) {
|
|||
err = walletdb.Update(db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
|
||||
lastAddr, err = scopedMgr.LastExternalAddress(
|
||||
ns, DefaultAccountNum,
|
||||
lastAddr, err = scopedMgr.LastAddress(
|
||||
ns, DefaultAccountNum, ExternalBranch,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -2384,8 +2384,8 @@ func testNewRawAccount(t *testing.T, _ *Manager, db walletdb.DB,
|
|||
err := walletdb.Update(db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
|
||||
addrs, err := scopedMgr.NextExternalAddresses(
|
||||
ns, accountNum, 1,
|
||||
addrs, err := scopedMgr.NextAddresses(
|
||||
ns, accountNum, ExternalBranch, 1,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -116,11 +116,15 @@ type KeyScope struct {
|
|||
// identify a particular child key, when the account and branch can be inferred
|
||||
// from context.
|
||||
type ScopedIndex struct {
|
||||
// Scope is the BIP44 account' used to derive the child key.
|
||||
Scope KeyScope
|
||||
Scope KeyScope
|
||||
Account uint32
|
||||
Branch uint32
|
||||
Index uint32
|
||||
}
|
||||
|
||||
// Index is the BIP44 address_index used to derive the child key.
|
||||
Index uint32
|
||||
func (i ScopedIndex) String() string {
|
||||
return fmt.Sprintf("%s/%d'/%d/%d",
|
||||
i.Scope, i.Account, i.Branch, i.Index)
|
||||
}
|
||||
|
||||
// String returns a human readable version describing the keypath encapsulated
|
||||
|
@ -164,6 +168,9 @@ var (
|
|||
Coin: 140,
|
||||
}
|
||||
|
||||
// Set Default Scope to BIP0044 (legacy address type).
|
||||
DefaultKeyScope = KeyScopeBIP0044
|
||||
|
||||
// DefaultKeyScopes is the set of default key scopes that will be
|
||||
// created by the root manager upon initial creation.
|
||||
DefaultKeyScopes = []KeyScope{
|
||||
|
@ -401,11 +408,13 @@ func (s *ScopedKeyManager) loadAccountInfo(ns walletdb.ReadBucket,
|
|||
switch row := rowInterface.(type) {
|
||||
case *dbDefaultAccountRow:
|
||||
acctInfo = &accountInfo{
|
||||
acctName: row.name,
|
||||
acctType: row.acctType,
|
||||
acctKeyEncrypted: row.privKeyEncrypted,
|
||||
nextExternalIndex: row.nextExternalIndex,
|
||||
nextInternalIndex: row.nextInternalIndex,
|
||||
acctName: row.name,
|
||||
acctType: row.acctType,
|
||||
acctKeyEncrypted: row.privKeyEncrypted,
|
||||
nextIndex: [2]uint32{
|
||||
row.nextExternalIndex,
|
||||
row.nextInternalIndex,
|
||||
},
|
||||
}
|
||||
|
||||
// Use the crypto public key to decrypt the account public
|
||||
|
@ -437,49 +446,30 @@ func (s *ScopedKeyManager) loadAccountInfo(ns walletdb.ReadBucket,
|
|||
return nil, managerError(ErrDatabase, str, nil)
|
||||
}
|
||||
|
||||
// Derive and cache the managed address for the last external address.
|
||||
branch, index := ExternalBranch, acctInfo.nextExternalIndex
|
||||
if index > 0 {
|
||||
index--
|
||||
}
|
||||
lastExtAddrPath := DerivationPath{
|
||||
InternalAccount: account,
|
||||
Account: acctInfo.acctKeyPub.ChildIndex(),
|
||||
Branch: branch,
|
||||
Index: index,
|
||||
MasterKeyFingerprint: acctInfo.masterKeyFingerprint,
|
||||
}
|
||||
lastExtKey, err := s.deriveKey(acctInfo, branch, index, hasPrivateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lastExtAddr, err := s.keyToManaged(lastExtKey, lastExtAddrPath, acctInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
acctInfo.lastExternalAddr = lastExtAddr
|
||||
for branch := 0; branch < 2; branch++ {
|
||||
|
||||
// Derive and cache the managed address for the last internal address.
|
||||
branch, index = InternalBranch, acctInfo.nextInternalIndex
|
||||
if index > 0 {
|
||||
index--
|
||||
// Derive and cache the managed address for the last external address.
|
||||
index := acctInfo.nextIndex[branch]
|
||||
if index > 0 {
|
||||
index--
|
||||
}
|
||||
lastAddrPath := DerivationPath{
|
||||
InternalAccount: account,
|
||||
Account: acctInfo.acctKeyPub.ChildIndex(),
|
||||
Branch: uint32(branch),
|
||||
Index: index,
|
||||
MasterKeyFingerprint: acctInfo.masterKeyFingerprint,
|
||||
}
|
||||
lastKey, err := s.deriveKey(acctInfo, uint32(branch), index, hasPrivateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lastAddr, err := s.keyToManaged(lastKey, lastAddrPath, acctInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
acctInfo.lastAddr[branch] = lastAddr
|
||||
}
|
||||
lastIntAddrPath := DerivationPath{
|
||||
InternalAccount: account,
|
||||
Account: acctInfo.acctKeyPub.ChildIndex(),
|
||||
Branch: branch,
|
||||
Index: index,
|
||||
MasterKeyFingerprint: acctInfo.masterKeyFingerprint,
|
||||
}
|
||||
lastIntKey, err := s.deriveKey(acctInfo, branch, index, hasPrivateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lastIntAddr, err := s.keyToManaged(lastIntKey, lastIntAddrPath, acctInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
acctInfo.lastInternalAddr = lastIntAddr
|
||||
|
||||
// Add it to the cache and return it when everything is successful.
|
||||
s.acctInfo[account] = acctInfo
|
||||
|
@ -516,8 +506,8 @@ func (s *ScopedKeyManager) AccountProperties(ns walletdb.ReadBucket,
|
|||
return nil, err
|
||||
}
|
||||
props.AccountName = acctInfo.acctName
|
||||
props.ExternalKeyCount = acctInfo.nextExternalIndex
|
||||
props.InternalKeyCount = acctInfo.nextInternalIndex
|
||||
props.ExternalKeyCount = acctInfo.nextIndex[ExternalBranch]
|
||||
props.InternalKeyCount = acctInfo.nextIndex[InternalBranch]
|
||||
props.AccountPubKey = acctInfo.acctKeyPub
|
||||
props.MasterKeyFingerprint = acctInfo.masterKeyFingerprint
|
||||
props.AddrSchema = acctInfo.addrSchema
|
||||
|
@ -642,6 +632,14 @@ func (s *ScopedKeyManager) DeriveFromKeyPathCache(
|
|||
return privKey, nil
|
||||
}
|
||||
|
||||
func (s *ScopedKeyManager) DeriveFromExtKeys(kp DerivationPath,
|
||||
derivedKey *hdkeychain.ExtendedKey,
|
||||
addrType AddressType) (ManagedAddress, error) {
|
||||
return newManagedAddressFromExtKey(
|
||||
s, kp, derivedKey, addrType,
|
||||
)
|
||||
}
|
||||
|
||||
// DeriveFromKeyPath attempts to derive a maximal child key (under the BIP0044
|
||||
// scheme) from a given key path. If key derivation isn't possible, then an
|
||||
// error will be returned.
|
||||
|
@ -938,7 +936,7 @@ func (s *ScopedKeyManager) accountAddrType(acctInfo *accountInfo,
|
|||
//
|
||||
// This function MUST be called with the manager lock held for writes.
|
||||
func (s *ScopedKeyManager) nextAddresses(ns walletdb.ReadWriteBucket,
|
||||
account uint32, numAddresses uint32, internal bool) ([]ManagedAddress, error) {
|
||||
account uint32, branch uint32, numAddresses uint32) ([]ManagedAddress, error) {
|
||||
|
||||
// The next address can only be generated for accounts that have
|
||||
// already been created.
|
||||
|
@ -956,16 +954,12 @@ func (s *ScopedKeyManager) nextAddresses(ns walletdb.ReadWriteBucket,
|
|||
|
||||
// Choose the branch key and index depending on whether or not this is
|
||||
// an internal address.
|
||||
branchNum, nextIndex := ExternalBranch, acctInfo.nextExternalIndex
|
||||
if internal {
|
||||
branchNum = InternalBranch
|
||||
nextIndex = acctInfo.nextInternalIndex
|
||||
}
|
||||
nextIndex := acctInfo.nextIndex[branch]
|
||||
|
||||
// Choose the appropriate type of address to derive since it's possible
|
||||
// for a watch-only account to have a different schema from the
|
||||
// manager's.
|
||||
addrType := s.accountAddrType(acctInfo, internal)
|
||||
addrType := s.accountAddrType(acctInfo, branch == InternalBranch)
|
||||
|
||||
// Ensure the requested number of addresses doesn't exceed the maximum
|
||||
// allowed for this account.
|
||||
|
@ -978,10 +972,9 @@ func (s *ScopedKeyManager) nextAddresses(ns walletdb.ReadWriteBucket,
|
|||
}
|
||||
|
||||
// Derive the appropriate branch key and ensure it is zeroed when done.
|
||||
branchKey, err := acctKey.Derive(branchNum)
|
||||
branchKey, err := acctKey.Derive(branch)
|
||||
if err != nil {
|
||||
str := fmt.Sprintf("failed to derive extended key branch %d",
|
||||
branchNum)
|
||||
str := fmt.Sprintf("failed to derive extended key branch %d", branch)
|
||||
return nil, managerError(ErrKeyChain, str, err)
|
||||
}
|
||||
defer branchKey.Zero() // Ensure branch key is zeroed when done.
|
||||
|
@ -1021,7 +1014,7 @@ func (s *ScopedKeyManager) nextAddresses(ns walletdb.ReadWriteBucket,
|
|||
derivationPath := DerivationPath{
|
||||
InternalAccount: account,
|
||||
Account: acctKey.ChildIndex(),
|
||||
Branch: branchNum,
|
||||
Branch: branch,
|
||||
Index: nextIndex - 1,
|
||||
}
|
||||
|
||||
|
@ -1035,15 +1028,13 @@ func (s *ScopedKeyManager) nextAddresses(ns walletdb.ReadWriteBucket,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if internal {
|
||||
addr.internal = true
|
||||
}
|
||||
addr.internal = branch == InternalBranch
|
||||
managedAddr := addr
|
||||
nextKey.Zero()
|
||||
|
||||
info := unlockDeriveInfo{
|
||||
managedAddr: managedAddr,
|
||||
branch: branchNum,
|
||||
branch: branch,
|
||||
index: nextIndex - 1,
|
||||
}
|
||||
addressInfo = append(addressInfo, &info)
|
||||
|
@ -1113,13 +1104,8 @@ func (s *ScopedKeyManager) nextAddresses(ns walletdb.ReadWriteBucket,
|
|||
|
||||
// Set the last address and next address for tracking.
|
||||
ma := addressInfo[len(addressInfo)-1].managedAddr
|
||||
if internal {
|
||||
acctInfo.nextInternalIndex = nextIndex
|
||||
acctInfo.lastInternalAddr = ma
|
||||
} else {
|
||||
acctInfo.nextExternalIndex = nextIndex
|
||||
acctInfo.lastExternalAddr = ma
|
||||
}
|
||||
acctInfo.nextIndex[branch] = nextIndex
|
||||
acctInfo.lastAddr[branch] = ma
|
||||
}
|
||||
ns.Tx().OnCommit(onCommit)
|
||||
|
||||
|
@ -1134,11 +1120,28 @@ func (s *ScopedKeyManager) nextAddresses(ns walletdb.ReadWriteBucket,
|
|||
//
|
||||
// This function MUST be called with the manager lock held for writes.
|
||||
func (s *ScopedKeyManager) extendAddresses(ns walletdb.ReadWriteBucket,
|
||||
account uint32, lastIndex uint32, internal bool) error {
|
||||
account uint32, branch uint32, lastIndex uint32) error {
|
||||
|
||||
// The next address can only be generated for accounts that have
|
||||
// already been created.
|
||||
acctInfo, err := s.loadAccountInfo(ns, account)
|
||||
if err != nil {
|
||||
err = s.newAccount(ns, account, fmt.Sprintf("act:%v", account))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for gapAccount := account - 1; gapAccount >= 0; gapAccount-- {
|
||||
_, err = s.loadAccountInfo(ns, gapAccount)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
err = s.newAccount(ns, gapAccount, fmt.Sprintf("act:%v", gapAccount))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
acctInfo, err = s.loadAccountInfo(ns, account)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1152,16 +1155,12 @@ func (s *ScopedKeyManager) extendAddresses(ns walletdb.ReadWriteBucket,
|
|||
|
||||
// Choose the branch key and index depending on whether or not this is
|
||||
// an internal address.
|
||||
branchNum, nextIndex := ExternalBranch, acctInfo.nextExternalIndex
|
||||
if internal {
|
||||
branchNum = InternalBranch
|
||||
nextIndex = acctInfo.nextInternalIndex
|
||||
}
|
||||
nextIndex := acctInfo.nextIndex[branch]
|
||||
|
||||
// Choose the appropriate type of address to derive since it's possible
|
||||
// for a watch-only account to have a different schema from the
|
||||
// manager's.
|
||||
addrType := s.accountAddrType(acctInfo, internal)
|
||||
addrType := s.accountAddrType(acctInfo, branch == InternalBranch)
|
||||
|
||||
// If the last index requested is already lower than the next index, we
|
||||
// can return early.
|
||||
|
@ -1179,10 +1178,10 @@ func (s *ScopedKeyManager) extendAddresses(ns walletdb.ReadWriteBucket,
|
|||
}
|
||||
|
||||
// Derive the appropriate branch key and ensure it is zeroed when done.
|
||||
branchKey, err := acctKey.Derive(branchNum)
|
||||
branchKey, err := acctKey.Derive(branch)
|
||||
if err != nil {
|
||||
str := fmt.Sprintf("failed to derive extended key branch %d",
|
||||
branchNum)
|
||||
branch)
|
||||
return managerError(ErrKeyChain, str, err)
|
||||
}
|
||||
defer branchKey.Zero() // Ensure branch key is zeroed when done.
|
||||
|
@ -1224,7 +1223,7 @@ func (s *ScopedKeyManager) extendAddresses(ns walletdb.ReadWriteBucket,
|
|||
derivationPath := DerivationPath{
|
||||
InternalAccount: account,
|
||||
Account: acctInfo.acctKeyPub.ChildIndex(),
|
||||
Branch: branchNum,
|
||||
Branch: branch,
|
||||
Index: nextIndex - 1,
|
||||
}
|
||||
|
||||
|
@ -1238,15 +1237,13 @@ func (s *ScopedKeyManager) extendAddresses(ns walletdb.ReadWriteBucket,
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if internal {
|
||||
addr.internal = true
|
||||
}
|
||||
addr.internal = branch == InternalBranch
|
||||
managedAddr := addr
|
||||
nextKey.Zero()
|
||||
|
||||
info := unlockDeriveInfo{
|
||||
managedAddr: managedAddr,
|
||||
branch: branchNum,
|
||||
branch: branch,
|
||||
index: nextIndex - 1,
|
||||
}
|
||||
addressInfo = append(addressInfo, &info)
|
||||
|
@ -1302,21 +1299,16 @@ func (s *ScopedKeyManager) extendAddresses(ns walletdb.ReadWriteBucket,
|
|||
|
||||
// Set the last address and next address for tracking.
|
||||
ma := addressInfo[len(addressInfo)-1].managedAddr
|
||||
if internal {
|
||||
acctInfo.nextInternalIndex = nextIndex
|
||||
acctInfo.lastInternalAddr = ma
|
||||
} else {
|
||||
acctInfo.nextExternalIndex = nextIndex
|
||||
acctInfo.lastExternalAddr = ma
|
||||
}
|
||||
acctInfo.nextIndex[branch] = nextIndex
|
||||
acctInfo.lastAddr[branch] = ma
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NextExternalAddresses returns the specified number of next chained addresses
|
||||
// NextAddresses returns the specified number of next chained addresses
|
||||
// that are intended for external use from the address manager.
|
||||
func (s *ScopedKeyManager) NextExternalAddresses(ns walletdb.ReadWriteBucket,
|
||||
account uint32, numAddresses uint32) ([]ManagedAddress, error) {
|
||||
func (s *ScopedKeyManager) NextAddresses(ns walletdb.ReadWriteBucket,
|
||||
account uint32, branch uint32, numAddresses uint32) ([]ManagedAddress, error) {
|
||||
|
||||
// Enforce maximum account number.
|
||||
if account > MaxAccountNum {
|
||||
|
@ -1327,32 +1319,15 @@ func (s *ScopedKeyManager) NextExternalAddresses(ns walletdb.ReadWriteBucket,
|
|||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
|
||||
return s.nextAddresses(ns, account, numAddresses, false)
|
||||
}
|
||||
|
||||
// NextInternalAddresses returns the specified number of next chained addresses
|
||||
// that are intended for internal use such as change from the address manager.
|
||||
func (s *ScopedKeyManager) NextInternalAddresses(ns walletdb.ReadWriteBucket,
|
||||
account uint32, numAddresses uint32) ([]ManagedAddress, error) {
|
||||
|
||||
// Enforce maximum account number.
|
||||
if account > MaxAccountNum {
|
||||
err := managerError(ErrAccountNumTooHigh, errAcctTooHigh, nil)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
|
||||
return s.nextAddresses(ns, account, numAddresses, true)
|
||||
return s.nextAddresses(ns, account, branch, numAddresses)
|
||||
}
|
||||
|
||||
// ExtendExternalAddresses ensures that all valid external keys through
|
||||
// lastIndex are derived and stored in the wallet. This is used to ensure that
|
||||
// wallet's persistent state catches up to a external child that was found
|
||||
// during recovery.
|
||||
func (s *ScopedKeyManager) ExtendExternalAddresses(ns walletdb.ReadWriteBucket,
|
||||
account uint32, lastIndex uint32) error {
|
||||
func (s *ScopedKeyManager) ExtendAddresses(ns walletdb.ReadWriteBucket,
|
||||
account uint32, branch uint32, lastIndex uint32) error {
|
||||
|
||||
if account > MaxAccountNum {
|
||||
err := managerError(ErrAccountNumTooHigh, errAcctTooHigh, nil)
|
||||
|
@ -1362,28 +1337,10 @@ func (s *ScopedKeyManager) ExtendExternalAddresses(ns walletdb.ReadWriteBucket,
|
|||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
|
||||
return s.extendAddresses(ns, account, lastIndex, false)
|
||||
return s.extendAddresses(ns, account, branch, lastIndex)
|
||||
}
|
||||
|
||||
// ExtendInternalAddresses ensures that all valid internal keys through
|
||||
// lastIndex are derived and stored in the wallet. This is used to ensure that
|
||||
// wallet's persistent state catches up to an internal child that was found
|
||||
// during recovery.
|
||||
func (s *ScopedKeyManager) ExtendInternalAddresses(ns walletdb.ReadWriteBucket,
|
||||
account uint32, lastIndex uint32) error {
|
||||
|
||||
if account > MaxAccountNum {
|
||||
err := managerError(ErrAccountNumTooHigh, errAcctTooHigh, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
|
||||
return s.extendAddresses(ns, account, lastIndex, true)
|
||||
}
|
||||
|
||||
// LastExternalAddress returns the most recently requested chained external
|
||||
// LastAddress returns the most recently requested chained external
|
||||
// address from calling NextExternalAddress for the given account. The first
|
||||
// external address for the account will be returned if none have been
|
||||
// previously requested.
|
||||
|
@ -1391,8 +1348,8 @@ func (s *ScopedKeyManager) ExtendInternalAddresses(ns walletdb.ReadWriteBucket,
|
|||
// This function will return an error if the provided account number is greater
|
||||
// than the MaxAccountNum constant or there is no account information for the
|
||||
// passed account. Any other errors returned are generally unexpected.
|
||||
func (s *ScopedKeyManager) LastExternalAddress(ns walletdb.ReadBucket,
|
||||
account uint32) (ManagedAddress, error) {
|
||||
func (s *ScopedKeyManager) LastAddress(ns walletdb.ReadBucket,
|
||||
account, branch uint32) (ManagedAddress, error) {
|
||||
|
||||
// Enforce maximum account number.
|
||||
if account > MaxAccountNum {
|
||||
|
@ -1410,47 +1367,13 @@ func (s *ScopedKeyManager) LastExternalAddress(ns walletdb.ReadBucket,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if acctInfo.nextExternalIndex > 0 {
|
||||
return acctInfo.lastExternalAddr, nil
|
||||
if acctInfo.nextIndex[branch] > 0 {
|
||||
return acctInfo.lastAddr[branch], nil
|
||||
}
|
||||
|
||||
return nil, managerError(ErrAddressNotFound, "no previous external address", nil)
|
||||
}
|
||||
|
||||
// LastInternalAddress returns the most recently requested chained internal
|
||||
// address from calling NextInternalAddress for the given account. The first
|
||||
// internal address for the account will be returned if none have been
|
||||
// previously requested.
|
||||
//
|
||||
// This function will return an error if the provided account number is greater
|
||||
// than the MaxAccountNum constant or there is no account information for the
|
||||
// passed account. Any other errors returned are generally unexpected.
|
||||
func (s *ScopedKeyManager) LastInternalAddress(ns walletdb.ReadBucket,
|
||||
account uint32) (ManagedAddress, error) {
|
||||
|
||||
// Enforce maximum account number.
|
||||
if account > MaxAccountNum {
|
||||
err := managerError(ErrAccountNumTooHigh, errAcctTooHigh, nil)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
|
||||
// Load account information for the passed account. It is typically
|
||||
// cached, but if not it will be loaded from the database.
|
||||
acctInfo, err := s.loadAccountInfo(ns, account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if acctInfo.nextInternalIndex > 0 {
|
||||
return acctInfo.lastInternalAddr, nil
|
||||
}
|
||||
|
||||
return nil, managerError(ErrAddressNotFound, "no previous internal address", nil)
|
||||
}
|
||||
|
||||
// NewRawAccount creates a new account for the scoped manager. This method
|
||||
// differs from the NewAccount method in that this method takes the account
|
||||
// number *directly*, rather than taking a string name for the account, then
|
||||
|
@ -1581,10 +1504,42 @@ func (s *ScopedKeyManager) newAccount(ns walletdb.ReadWriteBucket,
|
|||
return err
|
||||
}
|
||||
|
||||
lastAccount, err := fetchLastAccount(ns, &s.scope)
|
||||
if account < lastAccount {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Save last account metadata
|
||||
return putLastAccount(ns, &s.scope, account)
|
||||
}
|
||||
|
||||
func (s *ScopedKeyManager) DeriveAccountKey(ns walletdb.ReadWriteBucket,
|
||||
account uint32) (*hdkeychain.ExtendedKey, error) {
|
||||
|
||||
_, coinTypePrivEnc, err := fetchCoinTypeKeys(ns, &s.scope)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Decrypt the cointype key.
|
||||
serializedKeyPriv, err := s.rootManager.cryptoKeyPriv.Decrypt(coinTypePrivEnc)
|
||||
if err != nil {
|
||||
str := fmt.Sprintf("failed to decrypt cointype serialized private key")
|
||||
return nil, managerError(ErrLocked, str, err)
|
||||
}
|
||||
defer zero.Bytes(serializedKeyPriv)
|
||||
|
||||
coinTypeKeyPriv, err := hdkeychain.NewKeyFromString(string(serializedKeyPriv))
|
||||
if err != nil {
|
||||
str := fmt.Sprintf("failed to create cointype extended private key")
|
||||
return nil, managerError(ErrKeyChain, str, err)
|
||||
}
|
||||
defer coinTypeKeyPriv.Zero()
|
||||
|
||||
// Derive the account key using the cointype key
|
||||
return deriveAccountKey(coinTypeKeyPriv, account)
|
||||
}
|
||||
|
||||
// RenameAccount renames an account stored in the manager based on the given
|
||||
// account number with the given name. If an account with the same name
|
||||
// already exists, ErrDuplicateAccount will be returned.
|
||||
|
|
|
@ -83,7 +83,7 @@ func TestTxToOutputsDryRun(t *testing.T) {
|
|||
}
|
||||
change := dryRunTx.Tx.TxOut[dryRunTx.ChangeIndex]
|
||||
|
||||
addresses, err := w.AccountAddresses(0)
|
||||
addresses, err := w.AccountAddresses(0, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get addresses: %v", err)
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ func TestTxToOutputsDryRun(t *testing.T) {
|
|||
}
|
||||
change2 := dryRunTx2.Tx.TxOut[dryRunTx2.ChangeIndex]
|
||||
|
||||
addresses, err = w.AccountAddresses(0)
|
||||
addresses, err = w.AccountAddresses(0, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get addresses: %v", err)
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ func TestTxToOutputsDryRun(t *testing.T) {
|
|||
}
|
||||
change3 := tx.Tx.TxOut[tx.ChangeIndex]
|
||||
|
||||
addresses, err = w.AccountAddresses(0)
|
||||
addresses, err = w.AccountAddresses(0, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get addresses: %v", err)
|
||||
}
|
||||
|
|
|
@ -326,14 +326,14 @@ func (w *Wallet) ImportAccountDryRun(name string,
|
|||
// attempt, we'll want to invalidate the cache for it.
|
||||
defer manager.InvalidateAccountCache(accountProps.AccountNumber)
|
||||
|
||||
externalAddrs, err = manager.NextExternalAddresses(
|
||||
ns, accountProps.AccountNumber, numAddrs,
|
||||
externalAddrs, err = manager.NextAddresses(
|
||||
ns, accountProps.AccountNumber, waddrmgr.ExternalBranch, numAddrs,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
internalAddrs, err = manager.NextInternalAddresses(
|
||||
ns, accountProps.AccountNumber, numAddrs,
|
||||
internalAddrs, err = manager.NextAddresses(
|
||||
ns, accountProps.AccountNumber, waddrmgr.InternalBranch, numAddrs,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -63,66 +63,45 @@ func (rm *RecoveryManager) Resurrect(ns walletdb.ReadBucket,
|
|||
// First, for each scope that we are recovering, rederive all of the
|
||||
// addresses up to the last found address known to each branch.
|
||||
for keyScope, scopedMgr := range scopedMgrs {
|
||||
// Load the current account properties for this scope, using the
|
||||
// the default account number.
|
||||
// TODO(conner): rescan for all created accounts if we allow
|
||||
// users to use non-default address
|
||||
|
||||
scopeState := rm.state.StateForScope(keyScope)
|
||||
acctProperties, err := scopedMgr.AccountProperties(
|
||||
ns, waddrmgr.DefaultAccountNum,
|
||||
)
|
||||
|
||||
lastAccount, err := scopedMgr.LastAccount(ns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Fetch the external key count, which bounds the indexes we
|
||||
// will need to rederive.
|
||||
externalCount := acctProperties.ExternalKeyCount
|
||||
|
||||
// Walk through all indexes through the last external key,
|
||||
// deriving each address and adding it to the external branch
|
||||
// recovery state's set of addresses to look for.
|
||||
for i := uint32(0); i < externalCount; i++ {
|
||||
keyPath := externalKeyPath(i)
|
||||
addr, err := scopedMgr.DeriveFromKeyPath(ns, keyPath)
|
||||
if err != nil && err != hdkeychain.ErrInvalidChild {
|
||||
for accountIndex, accountState := range scopeState[:lastAccount+1] {
|
||||
log.Infof("Resurrecting addresses for key scope %v, account %v", keyScope, accountIndex)
|
||||
acctProperties, err := scopedMgr.AccountProperties(ns,
|
||||
uint32(accountIndex))
|
||||
if err != nil {
|
||||
return err
|
||||
} else if err == hdkeychain.ErrInvalidChild {
|
||||
scopeState.ExternalBranch.MarkInvalidChild(i)
|
||||
continue
|
||||
}
|
||||
|
||||
scopeState.ExternalBranch.AddAddr(i, addr.Address())
|
||||
}
|
||||
|
||||
// Fetch the internal key count, which bounds the indexes we
|
||||
// will need to rederive.
|
||||
internalCount := acctProperties.InternalKeyCount
|
||||
|
||||
// Walk through all indexes through the last internal key,
|
||||
// deriving each address and adding it to the internal branch
|
||||
// recovery state's set of addresses to look for.
|
||||
for i := uint32(0); i < internalCount; i++ {
|
||||
keyPath := internalKeyPath(i)
|
||||
addr, err := scopedMgr.DeriveFromKeyPath(ns, keyPath)
|
||||
if err != nil && err != hdkeychain.ErrInvalidChild {
|
||||
return err
|
||||
} else if err == hdkeychain.ErrInvalidChild {
|
||||
scopeState.InternalBranch.MarkInvalidChild(i)
|
||||
continue
|
||||
// Fetch the key count, which bounds the indexes we
|
||||
// will need to rederive.
|
||||
counts := []uint32{
|
||||
acctProperties.ExternalKeyCount,
|
||||
acctProperties.InternalKeyCount,
|
||||
}
|
||||
|
||||
scopeState.InternalBranch.AddAddr(i, addr.Address())
|
||||
}
|
||||
|
||||
// The key counts will point to the next key that can be
|
||||
// derived, so we subtract one to point to last known key. If
|
||||
// the key count is zero, then no addresses have been found.
|
||||
if externalCount > 0 {
|
||||
scopeState.ExternalBranch.ReportFound(externalCount - 1)
|
||||
}
|
||||
if internalCount > 0 {
|
||||
scopeState.InternalBranch.ReportFound(internalCount - 1)
|
||||
for branchIndex, branchState := range accountState {
|
||||
// Walk through all indexes through the last key,
|
||||
// deriving each address and adding it to the branch
|
||||
// recovery state's set of addresses to look for.
|
||||
for addrIndex := uint32(0); addrIndex < counts[branchIndex]; addrIndex++ {
|
||||
keyPath := keyPath(uint32(accountIndex), uint32(branchIndex), addrIndex)
|
||||
addr, err := scopedMgr.DeriveFromKeyPath(ns, keyPath)
|
||||
if err != nil && err != hdkeychain.ErrInvalidChild {
|
||||
return err
|
||||
} else if err == hdkeychain.ErrInvalidChild {
|
||||
branchState.MarkInvalidChild(addrIndex)
|
||||
continue
|
||||
}
|
||||
branchState.AddAddr(addrIndex, addr.Address())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,7 +181,7 @@ type RecoveryState struct {
|
|||
|
||||
// scopes maintains a map of each requested key scope to its active
|
||||
// RecoveryState.
|
||||
scopes map[waddrmgr.KeyScope]*ScopeRecoveryState
|
||||
scopes map[waddrmgr.KeyScope]ScopeRecoveryState
|
||||
|
||||
// watchedOutPoints contains the set of all outpoints known to the
|
||||
// wallet. This is updated iteratively as new outpoints are found during
|
||||
|
@ -214,7 +193,7 @@ type RecoveryState struct {
|
|||
// recoveryWindow. Each RecoveryState that is subsequently initialized for a
|
||||
// particular key scope will receive the same recoveryWindow.
|
||||
func NewRecoveryState(recoveryWindow uint32) *RecoveryState {
|
||||
scopes := make(map[waddrmgr.KeyScope]*ScopeRecoveryState)
|
||||
scopes := make(map[waddrmgr.KeyScope]ScopeRecoveryState)
|
||||
|
||||
return &RecoveryState{
|
||||
recoveryWindow: recoveryWindow,
|
||||
|
@ -227,18 +206,21 @@ func NewRecoveryState(recoveryWindow uint32) *RecoveryState {
|
|||
// does not already exist, a new one will be generated with the RecoveryState's
|
||||
// recoveryWindow.
|
||||
func (rs *RecoveryState) StateForScope(
|
||||
keyScope waddrmgr.KeyScope) *ScopeRecoveryState {
|
||||
keyScope waddrmgr.KeyScope) ScopeRecoveryState {
|
||||
|
||||
// If the account recovery state already exists, return it.
|
||||
if scopeState, ok := rs.scopes[keyScope]; ok {
|
||||
return scopeState
|
||||
scopeState, ok := rs.scopes[keyScope]
|
||||
if !ok {
|
||||
for i := 0; i < waddrmgr.AccountGapLimit; i++ {
|
||||
accountState := []*BranchRecoveryState{
|
||||
NewBranchRecoveryState(rs.recoveryWindow),
|
||||
NewBranchRecoveryState(rs.recoveryWindow),
|
||||
}
|
||||
scopeState = append(scopeState, accountState)
|
||||
}
|
||||
rs.scopes[keyScope] = scopeState
|
||||
}
|
||||
|
||||
// Otherwise, initialize the recovery state for this scope with the
|
||||
// chosen recovery window.
|
||||
rs.scopes[keyScope] = NewScopeRecoveryState(rs.recoveryWindow)
|
||||
|
||||
return rs.scopes[keyScope]
|
||||
return scopeState
|
||||
}
|
||||
|
||||
// WatchedOutPoints returns the global set of outpoints that are known to belong
|
||||
|
@ -256,26 +238,11 @@ func (rs *RecoveryState) AddWatchedOutPoint(outPoint *wire.OutPoint,
|
|||
}
|
||||
|
||||
// ScopeRecoveryState is used to manage the recovery of addresses generated
|
||||
// under a particular BIP32 account. Each account tracks both an external and
|
||||
// internal branch recovery state, both of which use the same recovery window.
|
||||
type ScopeRecoveryState struct {
|
||||
// ExternalBranch is the recovery state of addresses generated for
|
||||
// external use, i.e. receiving addresses.
|
||||
ExternalBranch *BranchRecoveryState
|
||||
// under a BIP32 accounts. Each account tracks both an external and internal
|
||||
// branch recovery state, both of which use the same recovery window.
|
||||
type ScopeRecoveryState []AccountRecoveryState
|
||||
|
||||
// InternalBranch is the recovery state of addresses generated for
|
||||
// internal use, i.e. change addresses.
|
||||
InternalBranch *BranchRecoveryState
|
||||
}
|
||||
|
||||
// NewScopeRecoveryState initializes an ScopeRecoveryState with the chosen
|
||||
// recovery window.
|
||||
func NewScopeRecoveryState(recoveryWindow uint32) *ScopeRecoveryState {
|
||||
return &ScopeRecoveryState{
|
||||
ExternalBranch: NewBranchRecoveryState(recoveryWindow),
|
||||
InternalBranch: NewBranchRecoveryState(recoveryWindow),
|
||||
}
|
||||
}
|
||||
type AccountRecoveryState []*BranchRecoveryState
|
||||
|
||||
// BranchRecoveryState maintains the required state in-order to properly
|
||||
// recover addresses derived from a particular account's internal or external
|
||||
|
|
453
wallet/wallet.go
453
wallet/wallet.go
|
@ -26,6 +26,7 @@ import (
|
|||
btcutil "github.com/lbryio/lbcutil"
|
||||
"github.com/lbryio/lbcutil/hdkeychain"
|
||||
"github.com/lbryio/lbcwallet/chain"
|
||||
"github.com/lbryio/lbcwallet/internal/prompt"
|
||||
"github.com/lbryio/lbcwallet/waddrmgr"
|
||||
"github.com/lbryio/lbcwallet/wallet/txauthor"
|
||||
"github.com/lbryio/lbcwallet/wallet/txrules"
|
||||
|
@ -666,16 +667,13 @@ func (w *Wallet) recovery(chainClient chain.Interface,
|
|||
w.recoveryWindow, recoveryBatchSize, w.chainParams,
|
||||
)
|
||||
|
||||
// In the event that this recovery is being resumed, we will need to
|
||||
// repopulate all found addresses from the database. Ideally, for basic
|
||||
// recovery, we would only do so for the default scopes, but due to a
|
||||
// bug in which the wallet would create change addresses outside of the
|
||||
// default scopes, it's necessary to attempt all registered key scopes.
|
||||
scopedMgrs := make(map[waddrmgr.KeyScope]*waddrmgr.ScopedKeyManager)
|
||||
for _, scopedMgr := range w.Manager.ActiveScopedKeyManagers() {
|
||||
scopedMgrs[scopedMgr.Scope()] = scopedMgr
|
||||
}
|
||||
|
||||
err := walletdb.View(w.db, func(tx walletdb.ReadTx) error {
|
||||
var credits []wtxmgr.Credit
|
||||
txMgrNS := tx.ReadBucket(wtxmgrNamespaceKey)
|
||||
credits, err := w.TxStore.UnspentOutputs(txMgrNS)
|
||||
if err != nil {
|
||||
|
@ -704,6 +702,18 @@ func (w *Wallet) recovery(chainClient chain.Interface,
|
|||
// NOTE: We purposefully don't update our best height since we assume
|
||||
// that a wallet rescan will be performed from the wallet's tip, which
|
||||
// will be of bestHeight after completing the recovery process.
|
||||
|
||||
pass, err := prompt.ProvidePrivPassphrase()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = w.Unlock(pass, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.Lock()
|
||||
|
||||
var blocks []*waddrmgr.BlockStamp
|
||||
startHeight := w.Manager.SyncedTo().Height + 1
|
||||
for height := startHeight; height <= bestHeight; height++ {
|
||||
|
@ -735,35 +745,43 @@ func (w *Wallet) recovery(chainClient chain.Interface,
|
|||
// the recovery batch size, so we can proceed to commit our
|
||||
// state to disk.
|
||||
recoveryBatch := recoveryMgr.BlockBatch()
|
||||
if len(recoveryBatch) == recoveryBatchSize || height == bestHeight {
|
||||
err := walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
for _, block := range blocks {
|
||||
err := w.Manager.SetSyncedTo(ns, block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return w.recoverScopedAddresses(
|
||||
chainClient, tx, ns, recoveryBatch,
|
||||
recoveryMgr.State(), scopedMgrs,
|
||||
)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(recoveryBatch) > 0 {
|
||||
log.Infof("Recovered addresses from blocks "+
|
||||
"%d-%d", recoveryBatch[0].Height,
|
||||
recoveryBatch[len(recoveryBatch)-1].Height)
|
||||
}
|
||||
|
||||
// Clear the batch of all processed blocks to reuse the
|
||||
// same memory for future batches.
|
||||
blocks = blocks[:0]
|
||||
recoveryMgr.ResetBlockBatch()
|
||||
if len(recoveryBatch) != recoveryBatchSize && height != bestHeight {
|
||||
continue
|
||||
}
|
||||
|
||||
err = walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error {
|
||||
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
for _, block := range blocks {
|
||||
err = w.Manager.SetSyncedTo(ns, block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for scope, scopedMgr := range scopedMgrs {
|
||||
scopeState := recoveryMgr.State().StateForScope(scope)
|
||||
err = expandScopeHorizons(ns, scopedMgr, scopeState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return w.recoverScopedAddresses(chainClient, tx, ns,
|
||||
recoveryBatch, recoveryMgr.State(), scopedMgrs,
|
||||
)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(recoveryBatch) > 0 {
|
||||
log.Infof("Recovered addresses from blocks "+
|
||||
"%d-%d", recoveryBatch[0].Height,
|
||||
recoveryBatch[len(recoveryBatch)-1].Height)
|
||||
}
|
||||
|
||||
// Clear the batch of all processed blocks to reuse the
|
||||
// same memory for future batches.
|
||||
blocks = blocks[:0]
|
||||
recoveryMgr.ResetBlockBatch()
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -795,16 +813,8 @@ func (w *Wallet) recoverScopedAddresses(
|
|||
return nil
|
||||
}
|
||||
|
||||
log.Infof("Scanning %d blocks for recoverable addresses", len(batch))
|
||||
|
||||
expandHorizons:
|
||||
for scope, scopedMgr := range scopedMgrs {
|
||||
scopeState := recoveryState.StateForScope(scope)
|
||||
err := expandScopeHorizons(ns, scopedMgr, scopeState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
log.Infof("Scanning %d blocks for recoverable addresses", len(batch))
|
||||
|
||||
// With the internal and external horizons properly expanded, we now
|
||||
// construct the filter blocks request. The request includes the range
|
||||
|
@ -887,89 +897,60 @@ expandHorizons:
|
|||
// persistent state of the wallet. If any invalid child keys are detected, the
|
||||
// horizon will be properly extended such that our lookahead always includes the
|
||||
// proper number of valid child keys.
|
||||
func expandScopeHorizons(ns walletdb.ReadWriteBucket,
|
||||
func expandScopeHorizons(
|
||||
ns walletdb.ReadWriteBucket,
|
||||
scopedMgr *waddrmgr.ScopedKeyManager,
|
||||
scopeState *ScopeRecoveryState) error {
|
||||
scopeState ScopeRecoveryState) error {
|
||||
|
||||
// Compute the current external horizon and the number of addresses we
|
||||
// must derive to ensure we maintain a sufficient recovery window for
|
||||
// the external branch.
|
||||
exHorizon, exWindow := scopeState.ExternalBranch.ExtendHorizon()
|
||||
count, childIndex := uint32(0), exHorizon
|
||||
for count < exWindow {
|
||||
keyPath := externalKeyPath(childIndex)
|
||||
addr, err := scopedMgr.DeriveFromKeyPath(ns, keyPath)
|
||||
switch {
|
||||
case err == hdkeychain.ErrInvalidChild:
|
||||
// Record the existence of an invalid child with the
|
||||
// external branch's recovery state. This also
|
||||
// increments the branch's horizon so that it accounts
|
||||
// for this skipped child index.
|
||||
scopeState.ExternalBranch.MarkInvalidChild(childIndex)
|
||||
childIndex++
|
||||
continue
|
||||
|
||||
case err != nil:
|
||||
for accountIndex, accountState := range scopeState {
|
||||
acctKey, err := scopedMgr.DeriveAccountKey(ns, uint32(accountIndex))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for branchIndex, branchState := range accountState {
|
||||
exHorizon, exWindow := branchState.ExtendHorizon()
|
||||
count, addrIndex := uint32(0), exHorizon
|
||||
|
||||
// Register the newly generated external address and child index
|
||||
// with the external branch recovery state.
|
||||
scopeState.ExternalBranch.AddAddr(childIndex, addr.Address())
|
||||
branchKey, err := acctKey.Derive(uint32(branchIndex))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
childIndex++
|
||||
count++
|
||||
}
|
||||
for count < exWindow {
|
||||
kp := keyPath(uint32(accountIndex), uint32(branchIndex), addrIndex)
|
||||
indexKey, err := branchKey.Derive(addrIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addrType := waddrmgr.ScopeAddrMap[scopedMgr.Scope()].ExternalAddrType
|
||||
addr, err := scopedMgr.DeriveFromExtKeys(kp, indexKey, addrType)
|
||||
switch {
|
||||
case err == hdkeychain.ErrInvalidChild:
|
||||
branchState.MarkInvalidChild(addrIndex)
|
||||
addrIndex++
|
||||
continue
|
||||
|
||||
// Compute the current internal horizon and the number of addresses we
|
||||
// must derive to ensure we maintain a sufficient recovery window for
|
||||
// the internal branch.
|
||||
inHorizon, inWindow := scopeState.InternalBranch.ExtendHorizon()
|
||||
count, childIndex = 0, inHorizon
|
||||
for count < inWindow {
|
||||
keyPath := internalKeyPath(childIndex)
|
||||
addr, err := scopedMgr.DeriveFromKeyPath(ns, keyPath)
|
||||
switch {
|
||||
case err == hdkeychain.ErrInvalidChild:
|
||||
// Record the existence of an invalid child with the
|
||||
// internal branch's recovery state. This also
|
||||
// increments the branch's horizon so that it accounts
|
||||
// for this skipped child index.
|
||||
scopeState.InternalBranch.MarkInvalidChild(childIndex)
|
||||
childIndex++
|
||||
continue
|
||||
case err != nil:
|
||||
return err
|
||||
}
|
||||
|
||||
case err != nil:
|
||||
return err
|
||||
branchState.AddAddr(addrIndex, addr.Address())
|
||||
|
||||
addrIndex++
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
// Register the newly generated internal address and child index
|
||||
// with the internal branch recovery state.
|
||||
scopeState.InternalBranch.AddAddr(childIndex, addr.Address())
|
||||
|
||||
childIndex++
|
||||
count++
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// externalKeyPath returns the relative external derivation path /0/0/index.
|
||||
func externalKeyPath(index uint32) waddrmgr.DerivationPath {
|
||||
// keyPath returns the relative derivation path /account/branch/index.
|
||||
func keyPath(account, branch, index uint32) waddrmgr.DerivationPath {
|
||||
return waddrmgr.DerivationPath{
|
||||
InternalAccount: waddrmgr.DefaultAccountNum,
|
||||
Account: waddrmgr.DefaultAccountNum,
|
||||
Branch: waddrmgr.ExternalBranch,
|
||||
Index: index,
|
||||
}
|
||||
}
|
||||
|
||||
// internalKeyPath returns the relative internal derivation path /0/1/index.
|
||||
func internalKeyPath(index uint32) waddrmgr.DerivationPath {
|
||||
return waddrmgr.DerivationPath{
|
||||
InternalAccount: waddrmgr.DefaultAccountNum,
|
||||
Account: waddrmgr.DefaultAccountNum,
|
||||
Branch: waddrmgr.InternalBranch,
|
||||
InternalAccount: account,
|
||||
Account: account,
|
||||
Branch: branch,
|
||||
Index: index,
|
||||
}
|
||||
}
|
||||
|
@ -982,28 +963,26 @@ func newFilterBlocksRequest(batch []wtxmgr.BlockMeta,
|
|||
|
||||
filterReq := &chain.FilterBlocksRequest{
|
||||
Blocks: batch,
|
||||
ExternalAddrs: make(map[waddrmgr.ScopedIndex]btcutil.Address),
|
||||
InternalAddrs: make(map[waddrmgr.ScopedIndex]btcutil.Address),
|
||||
Addresses: make(map[waddrmgr.ScopedIndex]btcutil.Address),
|
||||
WatchedOutPoints: recoveryState.WatchedOutPoints(),
|
||||
}
|
||||
|
||||
// Populate the external and internal addresses by merging the addresses
|
||||
// sets belong to all currently tracked scopes.
|
||||
// Populate the addresses by merging the addresses sets belong to all
|
||||
// currently tracked scopes.
|
||||
for scope := range scopedMgrs {
|
||||
scopeState := recoveryState.StateForScope(scope)
|
||||
for index, addr := range scopeState.ExternalBranch.Addrs() {
|
||||
scopedIndex := waddrmgr.ScopedIndex{
|
||||
Scope: scope,
|
||||
Index: index,
|
||||
for accountIndex, accountState := range scopeState {
|
||||
for branchIndex, branchState := range accountState {
|
||||
for addrIndex, addr := range branchState.Addrs() {
|
||||
scopedIndex := waddrmgr.ScopedIndex{
|
||||
Scope: scope,
|
||||
Account: uint32(accountIndex),
|
||||
Branch: uint32(branchIndex),
|
||||
Index: addrIndex,
|
||||
}
|
||||
filterReq.Addresses[scopedIndex] = addr
|
||||
}
|
||||
}
|
||||
filterReq.ExternalAddrs[scopedIndex] = addr
|
||||
}
|
||||
for index, addr := range scopeState.InternalBranch.Addrs() {
|
||||
scopedIndex := waddrmgr.ScopedIndex{
|
||||
Scope: scope,
|
||||
Index: index,
|
||||
}
|
||||
filterReq.InternalAddrs[scopedIndex] = addr
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1018,85 +997,63 @@ func extendFoundAddresses(ns walletdb.ReadWriteBucket,
|
|||
scopedMgrs map[waddrmgr.KeyScope]*waddrmgr.ScopedKeyManager,
|
||||
recoveryState *RecoveryState) error {
|
||||
|
||||
// Mark all recovered external addresses as used. This will be done only
|
||||
// for scopes that reported a non-zero number of external addresses in
|
||||
// this block.
|
||||
for scope, indexes := range filterResp.FoundExternalAddrs {
|
||||
// First, report all external child indexes found for this
|
||||
// scope. This ensures that the external last-found index will
|
||||
// be updated to include the maximum child index seen thus far.
|
||||
scopeState := recoveryState.StateForScope(scope)
|
||||
for index := range indexes {
|
||||
scopeState.ExternalBranch.ReportFound(index)
|
||||
}
|
||||
|
||||
scopedMgr := scopedMgrs[scope]
|
||||
|
||||
// Mark all recovered addresses as used. This will be done only for
|
||||
// scopes that reported a non-zero number of addresses in this block.
|
||||
for index := range filterResp.FoundAddresses {
|
||||
scopedMgr := scopedMgrs[index.Scope]
|
||||
// First, report all child indexes found for this scope. This
|
||||
// ensures that the last-found index will be updated to include
|
||||
// the maximum child index seen thus far.
|
||||
scopeState := recoveryState.StateForScope(index.Scope)
|
||||
branchState := scopeState[index.Account][index.Branch]
|
||||
branchState.ReportFound(index.Index)
|
||||
// Now, with all found addresses reported, derive and extend all
|
||||
// external addresses up to and including the current last found
|
||||
// index for this scope.
|
||||
exNextUnfound := scopeState.ExternalBranch.NextUnfound()
|
||||
nextFound := branchState.NextUnfound()
|
||||
|
||||
exLastFound := exNextUnfound
|
||||
if exLastFound > 0 {
|
||||
exLastFound--
|
||||
lastFound := nextFound
|
||||
if lastFound > 0 {
|
||||
lastFound--
|
||||
}
|
||||
|
||||
err := scopedMgr.ExtendExternalAddresses(
|
||||
ns, waddrmgr.DefaultAccountNum, exLastFound,
|
||||
err := scopedMgr.ExtendAddresses(
|
||||
ns, index.Account, index.Branch, lastFound,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Finally, with the scope's addresses extended, we mark used
|
||||
// the external addresses that were found in the block and
|
||||
// belong to this scope.
|
||||
for index := range indexes {
|
||||
addr := scopeState.ExternalBranch.GetAddr(index)
|
||||
err := scopedMgr.MarkUsed(ns, addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// the addresses that were found in the block and belong to
|
||||
// this scope.
|
||||
addr := branchState.GetAddr(index.Index)
|
||||
err = scopedMgr.MarkUsed(ns, addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Mark all recovered internal addresses as used. This will be done only
|
||||
// for scopes that reported a non-zero number of internal addresses in
|
||||
// this block.
|
||||
for scope, indexes := range filterResp.FoundInternalAddrs {
|
||||
// First, report all internal child indexes found for this
|
||||
// scope. This ensures that the internal last-found index will
|
||||
// be updated to include the maximum child index seen thus far.
|
||||
scopeState := recoveryState.StateForScope(scope)
|
||||
for index := range indexes {
|
||||
scopeState.InternalBranch.ReportFound(index)
|
||||
}
|
||||
|
||||
scopedMgr := scopedMgrs[scope]
|
||||
|
||||
// Now, with all found addresses reported, derive and extend all
|
||||
// internal addresses up to and including the current last found
|
||||
// index for this scope.
|
||||
inNextUnfound := scopeState.InternalBranch.NextUnfound()
|
||||
|
||||
inLastFound := inNextUnfound
|
||||
if inLastFound > 0 {
|
||||
inLastFound--
|
||||
}
|
||||
err := scopedMgr.ExtendInternalAddresses(
|
||||
ns, waddrmgr.DefaultAccountNum, inLastFound,
|
||||
)
|
||||
var lastAccount uint32
|
||||
for _, scopedMgr := range scopedMgrs {
|
||||
account, err := scopedMgr.LastAccount(ns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if lastAccount < account {
|
||||
lastAccount = account
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, with the scope's addresses extended, we mark used
|
||||
// the internal addresses that were found in the blockand belong
|
||||
// to this scope.
|
||||
for index := range indexes {
|
||||
addr := scopeState.InternalBranch.GetAddr(index)
|
||||
err := scopedMgr.MarkUsed(ns, addr)
|
||||
// Make sure all scopes are extended to the same account.
|
||||
for _, s := range scopedMgrs {
|
||||
for gapAccount := lastAccount; gapAccount >= 0; gapAccount-- {
|
||||
_, err := s.AccountProperties(ns, gapAccount)
|
||||
// If the account exists, we can stop extending.
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
err = s.NewRawAccount(ns, gapAccount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1112,23 +1069,12 @@ func logFilterBlocksResp(block wtxmgr.BlockMeta,
|
|||
resp *chain.FilterBlocksResponse) {
|
||||
|
||||
// Log the number of external addresses found in this block.
|
||||
var nFoundExternal int
|
||||
for _, indexes := range resp.FoundExternalAddrs {
|
||||
nFoundExternal += len(indexes)
|
||||
}
|
||||
if nFoundExternal > 0 {
|
||||
log.Infof("Recovered %d external addrs at height=%d hash=%v",
|
||||
nFoundExternal, block.Height, block.Hash)
|
||||
}
|
||||
var nFoundAddresses int
|
||||
nFoundAddresses += len(resp.FoundAddresses)
|
||||
|
||||
// Log the number of internal addresses found in this block.
|
||||
var nFoundInternal int
|
||||
for _, indexes := range resp.FoundInternalAddrs {
|
||||
nFoundInternal += len(indexes)
|
||||
}
|
||||
if nFoundInternal > 0 {
|
||||
log.Infof("Recovered %d internal addrs at height=%d hash=%v",
|
||||
nFoundInternal, block.Height, block.Hash)
|
||||
if nFoundAddresses > 0 {
|
||||
log.Infof("Recovered %d addrs at height=%d hash=%v",
|
||||
nFoundAddresses, block.Height, block.Hash)
|
||||
}
|
||||
|
||||
// Log the number of outpoints found in this block.
|
||||
|
@ -1461,13 +1407,32 @@ func (w *Wallet) ChangePassphrases(publicOld, publicNew, privateOld,
|
|||
|
||||
// AccountAddresses returns the addresses for every created address for an
|
||||
// account.
|
||||
func (w *Wallet) AccountAddresses(account uint32) (addrs []btcutil.Address, err error) {
|
||||
func (w *Wallet) AccountAddresses(account uint32, scope *waddrmgr.KeyScope) (
|
||||
addrs []btcutil.Address, err error) {
|
||||
|
||||
// By default, append all addresses under this account.
|
||||
fn := func(maddr waddrmgr.ManagedAddress) error {
|
||||
addrs = append(addrs, maddr.Address())
|
||||
return nil
|
||||
}
|
||||
|
||||
// If scope is set, append only those have the address type under
|
||||
// this scope.
|
||||
if scope != nil {
|
||||
addrSchema := waddrmgr.ScopeAddrMap[*scope]
|
||||
|
||||
fn = func(maddr waddrmgr.ManagedAddress) error {
|
||||
if maddr.AddrType() == addrSchema.InternalAddrType ||
|
||||
maddr.AddrType() == addrSchema.ExternalAddrType {
|
||||
addrs = append(addrs, maddr.Address())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
err = walletdb.View(w.db, func(tx walletdb.ReadTx) error {
|
||||
addrmgrNs := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
return w.Manager.ForEachAccountAddress(addrmgrNs, account, func(maddr waddrmgr.ManagedAddress) error {
|
||||
addrs = append(addrs, maddr.Address())
|
||||
return nil
|
||||
})
|
||||
return w.Manager.ForEachAccountAddress(addrmgrNs, account, fn)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -1568,7 +1533,7 @@ func (w *Wallet) CurrentAddress(account uint32, scope waddrmgr.KeyScope) (btcuti
|
|||
)
|
||||
err = walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error {
|
||||
addrmgrNs := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||
maddr, err := manager.LastExternalAddress(addrmgrNs, account)
|
||||
maddr, err := manager.LastAddress(addrmgrNs, account, waddrmgr.ExternalBranch)
|
||||
if err != nil {
|
||||
// If no address exists yet, create the first external
|
||||
// address.
|
||||
|
@ -1743,7 +1708,12 @@ func (w *Wallet) AddressInfo(a btcutil.Address) (waddrmgr.ManagedAddress, error)
|
|||
|
||||
// AccountNumber returns the account number for an account name under a
|
||||
// particular key scope.
|
||||
func (w *Wallet) AccountNumber(scope waddrmgr.KeyScope, accountName string) (uint32, error) {
|
||||
func (w *Wallet) AccountNumber(accountName string) (uint32, error) {
|
||||
// By design, the same account number is shared across all scopes.
|
||||
return w.accountNumber(waddrmgr.DefaultKeyScope, accountName)
|
||||
}
|
||||
|
||||
func (w *Wallet) accountNumber(scope waddrmgr.KeyScope, accountName string) (uint32, error) {
|
||||
manager, err := w.Manager.FetchScopedKeyManager(scope)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
@ -1752,7 +1722,6 @@ func (w *Wallet) AccountNumber(scope waddrmgr.KeyScope, accountName string) (uin
|
|||
var account uint32
|
||||
err = walletdb.View(w.db, func(tx walletdb.ReadTx) error {
|
||||
addrmgrNs := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
var err error
|
||||
account, err = manager.LookupAccount(addrmgrNs, accountName)
|
||||
return err
|
||||
})
|
||||
|
@ -1760,7 +1729,12 @@ func (w *Wallet) AccountNumber(scope waddrmgr.KeyScope, accountName string) (uin
|
|||
}
|
||||
|
||||
// AccountName returns the name of an account.
|
||||
func (w *Wallet) AccountName(scope waddrmgr.KeyScope, accountNumber uint32) (string, error) {
|
||||
func (w *Wallet) AccountName(accountNumber uint32) (string, error) {
|
||||
// By design, the same account name is shared across all scopes.
|
||||
return w.accountName(waddrmgr.DefaultKeyScope, accountNumber)
|
||||
}
|
||||
|
||||
func (w *Wallet) accountName(scope waddrmgr.KeyScope, accountNumber uint32) (string, error) {
|
||||
manager, err := w.Manager.FetchScopedKeyManager(scope)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -1769,7 +1743,6 @@ func (w *Wallet) AccountName(scope waddrmgr.KeyScope, accountNumber uint32) (str
|
|||
var accountName string
|
||||
err = walletdb.View(w.db, func(tx walletdb.ReadTx) error {
|
||||
addrmgrNs := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
var err error
|
||||
accountName, err = manager.AccountName(addrmgrNs, accountNumber)
|
||||
return err
|
||||
})
|
||||
|
@ -1943,7 +1916,8 @@ func RecvCategory(details *wtxmgr.TxDetails, syncHeight int32, net *chaincfg.Par
|
|||
// for a listtransactions RPC.
|
||||
//
|
||||
// TODO: This should be moved to the legacyrpc package.
|
||||
func listTransactions(tx walletdb.ReadTx, details *wtxmgr.TxDetails, addrMgr *waddrmgr.Manager,
|
||||
func listTransactions(accountName string, tx walletdb.ReadTx,
|
||||
details *wtxmgr.TxDetails, addrMgr *waddrmgr.Manager,
|
||||
syncHeight int32, net *chaincfg.Params) []btcjson.ListTransactionsResult {
|
||||
|
||||
addrmgrNs := tx.ReadBucket(waddrmgrNamespaceKey)
|
||||
|
@ -2004,19 +1978,22 @@ outputs:
|
|||
}
|
||||
|
||||
var address string
|
||||
var accountName string
|
||||
var name string
|
||||
_, addrs, _, _ := txscript.ExtractPkScriptAddrs(output.PkScript, net)
|
||||
if len(addrs) == 1 {
|
||||
addr := addrs[0]
|
||||
address = addr.EncodeAddress()
|
||||
mgr, account, err := addrMgr.AddrAccount(addrmgrNs, addrs[0])
|
||||
if err == nil {
|
||||
accountName, err = mgr.AccountName(addrmgrNs, account)
|
||||
name, err = mgr.AccountName(addrmgrNs, account)
|
||||
if err != nil {
|
||||
accountName = ""
|
||||
name = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
if accountName != "*" && accountName != name {
|
||||
continue
|
||||
}
|
||||
|
||||
amountF64 := btcutil.Amount(output.Value).ToBTC()
|
||||
result := btcjson.ListTransactionsResult{
|
||||
|
@ -2025,7 +2002,7 @@ outputs:
|
|||
// BlockIndex
|
||||
//
|
||||
// Fields set below:
|
||||
// Account (only for non-"send" categories)
|
||||
// Account
|
||||
// Category
|
||||
// Amount
|
||||
// Fee
|
||||
|
@ -2052,13 +2029,14 @@ outputs:
|
|||
// with debits are grouped under the send category.
|
||||
|
||||
if send || spentCredit {
|
||||
result.Account = name
|
||||
result.Category = "send"
|
||||
result.Amount = -amountF64
|
||||
result.Fee = &feeF64
|
||||
results = append(results, result)
|
||||
}
|
||||
if isCredit {
|
||||
result.Account = accountName
|
||||
result.Account = name
|
||||
result.Category = recvCat
|
||||
result.Amount = amountF64
|
||||
result.Fee = nil
|
||||
|
@ -2071,7 +2049,7 @@ outputs:
|
|||
// ListSinceBlock returns a slice of objects with details about transactions
|
||||
// since the given block. If the block is -1 then all transactions are included.
|
||||
// This is intended to be used for listsinceblock RPC replies.
|
||||
func (w *Wallet) ListSinceBlock(start, end, syncHeight int32) ([]btcjson.ListTransactionsResult, error) {
|
||||
func (w *Wallet) ListSinceBlock(accountName string, start, end, syncHeight int32) ([]btcjson.ListTransactionsResult, error) {
|
||||
txList := []btcjson.ListTransactionsResult{}
|
||||
err := walletdb.View(w.db, func(tx walletdb.ReadTx) error {
|
||||
txmgrNs := tx.ReadBucket(wtxmgrNamespaceKey)
|
||||
|
@ -2081,8 +2059,8 @@ func (w *Wallet) ListSinceBlock(start, end, syncHeight int32) ([]btcjson.ListTra
|
|||
detail := detail
|
||||
|
||||
jsonResults := listTransactions(
|
||||
tx, &detail, w.Manager, syncHeight,
|
||||
w.chainParams,
|
||||
accountName, tx, &detail, w.Manager,
|
||||
syncHeight, w.chainParams,
|
||||
)
|
||||
txList = append(txList, jsonResults...)
|
||||
}
|
||||
|
@ -2097,7 +2075,7 @@ func (w *Wallet) ListSinceBlock(start, end, syncHeight int32) ([]btcjson.ListTra
|
|||
// ListTransactions returns a slice of objects with details about a recorded
|
||||
// transaction. This is intended to be used for listtransactions RPC
|
||||
// replies.
|
||||
func (w *Wallet) ListTransactions(from, count int) ([]btcjson.ListTransactionsResult, error) {
|
||||
func (w *Wallet) ListTransactions(accountName string, from, count int) ([]btcjson.ListTransactionsResult, error) {
|
||||
txList := []btcjson.ListTransactionsResult{}
|
||||
|
||||
err := walletdb.View(w.db, func(tx walletdb.ReadTx) error {
|
||||
|
@ -2110,7 +2088,6 @@ func (w *Wallet) ListTransactions(from, count int) ([]btcjson.ListTransactionsRe
|
|||
// Need to skip the first from transactions, and after those, only
|
||||
// include the next count transactions.
|
||||
skipped := 0
|
||||
n := 0
|
||||
rangeFn := func(details []wtxmgr.TxDetails) (bool, error) {
|
||||
|
||||
for _, detail := range details {
|
||||
|
@ -2119,18 +2096,16 @@ func (w *Wallet) ListTransactions(from, count int) ([]btcjson.ListTransactionsRe
|
|||
continue
|
||||
}
|
||||
|
||||
n++
|
||||
if n > count {
|
||||
if len(txList) >= count {
|
||||
txList = txList[:count]
|
||||
return true, nil
|
||||
}
|
||||
|
||||
jsonResults := listTransactions(tx, &detail,
|
||||
w.Manager, syncBlock.Height, w.chainParams)
|
||||
txList = append(txList, jsonResults...)
|
||||
jsonResults := listTransactions(accountName,
|
||||
tx, &detail, w.Manager,
|
||||
syncBlock.Height, w.chainParams)
|
||||
|
||||
if len(jsonResults) > 0 {
|
||||
n++
|
||||
}
|
||||
txList = append(txList, jsonResults...)
|
||||
}
|
||||
|
||||
return false, nil
|
||||
|
@ -2151,7 +2126,7 @@ func (w *Wallet) ListTransactions(from, count int) ([]btcjson.ListTransactionsRe
|
|||
// ListAddressTransactions returns a slice of objects with details about
|
||||
// recorded transactions to or from any address belonging to a set. This is
|
||||
// intended to be used for listaddresstransactions RPC replies.
|
||||
func (w *Wallet) ListAddressTransactions(pkHashes map[string]struct{}) ([]btcjson.ListTransactionsResult, error) {
|
||||
func (w *Wallet) ListAddressTransactions(accountName string, pkHashes map[string]struct{}) ([]btcjson.ListTransactionsResult, error) {
|
||||
txList := []btcjson.ListTransactionsResult{}
|
||||
err := walletdb.View(w.db, func(tx walletdb.ReadTx) error {
|
||||
txmgrNs := tx.ReadBucket(wtxmgrNamespaceKey)
|
||||
|
@ -2180,8 +2155,9 @@ func (w *Wallet) ListAddressTransactions(pkHashes map[string]struct{}) ([]btcjso
|
|||
continue
|
||||
}
|
||||
|
||||
jsonResults := listTransactions(tx, detail,
|
||||
w.Manager, syncBlock.Height, w.chainParams)
|
||||
jsonResults := listTransactions(accountName,
|
||||
tx, detail, w.Manager,
|
||||
syncBlock.Height, w.chainParams)
|
||||
txList = append(txList, jsonResults...)
|
||||
continue loopDetails
|
||||
}
|
||||
|
@ -2197,7 +2173,7 @@ func (w *Wallet) ListAddressTransactions(pkHashes map[string]struct{}) ([]btcjso
|
|||
// ListAllTransactions returns a slice of objects with details about a recorded
|
||||
// transaction. This is intended to be used for listalltransactions RPC
|
||||
// replies.
|
||||
func (w *Wallet) ListAllTransactions() ([]btcjson.ListTransactionsResult, error) {
|
||||
func (w *Wallet) ListAllTransactions(accountName string) ([]btcjson.ListTransactionsResult, error) {
|
||||
txList := []btcjson.ListTransactionsResult{}
|
||||
err := walletdb.View(w.db, func(tx walletdb.ReadTx) error {
|
||||
txmgrNs := tx.ReadBucket(wtxmgrNamespaceKey)
|
||||
|
@ -2212,7 +2188,8 @@ func (w *Wallet) ListAllTransactions() ([]btcjson.ListTransactionsResult, error)
|
|||
// unsorted, but it will process mined transactions in the
|
||||
// reverse order they were marked mined.
|
||||
for i := len(details) - 1; i >= 0; i-- {
|
||||
jsonResults := listTransactions(tx, &details[i], w.Manager,
|
||||
jsonResults := listTransactions(accountName,
|
||||
tx, &details[i], w.Manager,
|
||||
syncBlock.Height, w.chainParams)
|
||||
txList = append(txList, jsonResults...)
|
||||
}
|
||||
|
@ -2954,7 +2931,7 @@ func (w *Wallet) newAddress(addrmgrNs walletdb.ReadWriteBucket, account uint32,
|
|||
}
|
||||
|
||||
// Get next address from wallet.
|
||||
addrs, err := manager.NextExternalAddresses(addrmgrNs, account, 1)
|
||||
addrs, err := manager.NextAddresses(addrmgrNs, account, waddrmgr.ExternalBranch, 1)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -3012,7 +2989,7 @@ func (w *Wallet) newChangeAddress(addrmgrNs walletdb.ReadWriteBucket,
|
|||
}
|
||||
|
||||
// Get next chained change address from wallet for account.
|
||||
addrs, err := manager.NextInternalAddresses(addrmgrNs, account, 1)
|
||||
addrs, err := manager.NextAddresses(addrmgrNs, account, waddrmgr.InternalBranch, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue