rpcclient: add deriveaddresses RPC command
This commit is contained in:
parent
42782bba18
commit
c693bd8bc5
5 changed files with 164 additions and 41 deletions
|
@ -80,6 +80,47 @@ func NewCreateRawTransactionCmd(inputs []TransactionInput, amounts map[string]fl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecodeRawTransactionCmd defines the decoderawtransaction JSON-RPC command.
|
||||||
|
type DecodeRawTransactionCmd struct {
|
||||||
|
HexTx string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDecodeRawTransactionCmd returns a new instance which can be used to issue
|
||||||
|
// a decoderawtransaction JSON-RPC command.
|
||||||
|
func NewDecodeRawTransactionCmd(hexTx string) *DecodeRawTransactionCmd {
|
||||||
|
return &DecodeRawTransactionCmd{
|
||||||
|
HexTx: hexTx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeScriptCmd defines the decodescript JSON-RPC command.
|
||||||
|
type DecodeScriptCmd struct {
|
||||||
|
HexScript string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDecodeScriptCmd returns a new instance which can be used to issue a
|
||||||
|
// decodescript JSON-RPC command.
|
||||||
|
func NewDecodeScriptCmd(hexScript string) *DecodeScriptCmd {
|
||||||
|
return &DecodeScriptCmd{
|
||||||
|
HexScript: hexScript,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeriveAddressesCmd defines the deriveaddresses JSON-RPC command.
|
||||||
|
type DeriveAddressesCmd struct {
|
||||||
|
Descriptor string
|
||||||
|
Range *DescriptorRange
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDeriveAddressesCmd returns a new instance which can be used to issue a
|
||||||
|
// deriveaddresses JSON-RPC command.
|
||||||
|
func NewDeriveAddressesCmd(descriptor string, descriptorRange *DescriptorRange) *DeriveAddressesCmd {
|
||||||
|
return &DeriveAddressesCmd{
|
||||||
|
Descriptor: descriptor,
|
||||||
|
Range: descriptorRange,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ChangeType defines the different output types to use for the change address
|
// ChangeType defines the different output types to use for the change address
|
||||||
// of a transaction built by the node.
|
// of a transaction built by the node.
|
||||||
type ChangeType string
|
type ChangeType string
|
||||||
|
@ -124,32 +165,6 @@ func NewFundRawTransactionCmd(serializedTx []byte, opts FundRawTransactionOpts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeRawTransactionCmd defines the decoderawtransaction JSON-RPC command.
|
|
||||||
type DecodeRawTransactionCmd struct {
|
|
||||||
HexTx string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDecodeRawTransactionCmd returns a new instance which can be used to issue
|
|
||||||
// a decoderawtransaction JSON-RPC command.
|
|
||||||
func NewDecodeRawTransactionCmd(hexTx string) *DecodeRawTransactionCmd {
|
|
||||||
return &DecodeRawTransactionCmd{
|
|
||||||
HexTx: hexTx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeScriptCmd defines the decodescript JSON-RPC command.
|
|
||||||
type DecodeScriptCmd struct {
|
|
||||||
HexScript string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDecodeScriptCmd returns a new instance which can be used to issue a
|
|
||||||
// decodescript JSON-RPC command.
|
|
||||||
func NewDecodeScriptCmd(hexScript string) *DecodeScriptCmd {
|
|
||||||
return &DecodeScriptCmd{
|
|
||||||
HexScript: hexScript,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAddedNodeInfoCmd defines the getaddednodeinfo JSON-RPC command.
|
// GetAddedNodeInfoCmd defines the getaddednodeinfo JSON-RPC command.
|
||||||
type GetAddedNodeInfoCmd struct {
|
type GetAddedNodeInfoCmd struct {
|
||||||
DNS bool
|
DNS bool
|
||||||
|
@ -467,6 +482,19 @@ func NewGetConnectionCountCmd() *GetConnectionCountCmd {
|
||||||
return &GetConnectionCountCmd{}
|
return &GetConnectionCountCmd{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDescriptorInfoCmd defines the getdescriptorinfo JSON-RPC command.
|
||||||
|
type GetDescriptorInfoCmd struct {
|
||||||
|
Descriptor string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetDescriptorInfoCmd returns a new instance which can be used to issue a
|
||||||
|
// getdescriptorinfo JSON-RPC command.
|
||||||
|
func NewGetDescriptorInfoCmd(descriptor string) *GetDescriptorInfoCmd {
|
||||||
|
return &GetDescriptorInfoCmd{
|
||||||
|
Descriptor: descriptor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetDifficultyCmd defines the getdifficulty JSON-RPC command.
|
// GetDifficultyCmd defines the getdifficulty JSON-RPC command.
|
||||||
type GetDifficultyCmd struct{}
|
type GetDifficultyCmd struct{}
|
||||||
|
|
||||||
|
@ -956,28 +984,16 @@ func NewVerifyTxOutProofCmd(proof string) *VerifyTxOutProofCmd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDescriptorInfoCmd defines the getdescriptorinfo JSON-RPC command.
|
|
||||||
type GetDescriptorInfoCmd struct {
|
|
||||||
Descriptor string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewGetDescriptorInfoCmd returns a new instance which can be used to issue a
|
|
||||||
// getdescriptorinfo JSON-RPC command.
|
|
||||||
func NewGetDescriptorInfoCmd(descriptor string) *GetDescriptorInfoCmd {
|
|
||||||
return &GetDescriptorInfoCmd{
|
|
||||||
Descriptor: descriptor,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// No special flags for commands in this file.
|
// No special flags for commands in this file.
|
||||||
flags := UsageFlag(0)
|
flags := UsageFlag(0)
|
||||||
|
|
||||||
MustRegisterCmd("addnode", (*AddNodeCmd)(nil), flags)
|
MustRegisterCmd("addnode", (*AddNodeCmd)(nil), flags)
|
||||||
MustRegisterCmd("createrawtransaction", (*CreateRawTransactionCmd)(nil), flags)
|
MustRegisterCmd("createrawtransaction", (*CreateRawTransactionCmd)(nil), flags)
|
||||||
MustRegisterCmd("fundrawtransaction", (*FundRawTransactionCmd)(nil), flags)
|
|
||||||
MustRegisterCmd("decoderawtransaction", (*DecodeRawTransactionCmd)(nil), flags)
|
MustRegisterCmd("decoderawtransaction", (*DecodeRawTransactionCmd)(nil), flags)
|
||||||
MustRegisterCmd("decodescript", (*DecodeScriptCmd)(nil), flags)
|
MustRegisterCmd("decodescript", (*DecodeScriptCmd)(nil), flags)
|
||||||
|
MustRegisterCmd("deriveaddresses", (*DeriveAddressesCmd)(nil), flags)
|
||||||
|
MustRegisterCmd("fundrawtransaction", (*FundRawTransactionCmd)(nil), flags)
|
||||||
MustRegisterCmd("getaddednodeinfo", (*GetAddedNodeInfoCmd)(nil), flags)
|
MustRegisterCmd("getaddednodeinfo", (*GetAddedNodeInfoCmd)(nil), flags)
|
||||||
MustRegisterCmd("getbestblockhash", (*GetBestBlockHashCmd)(nil), flags)
|
MustRegisterCmd("getbestblockhash", (*GetBestBlockHashCmd)(nil), flags)
|
||||||
MustRegisterCmd("getblock", (*GetBlockCmd)(nil), flags)
|
MustRegisterCmd("getblock", (*GetBlockCmd)(nil), flags)
|
||||||
|
@ -993,6 +1009,7 @@ func init() {
|
||||||
MustRegisterCmd("getchaintips", (*GetChainTipsCmd)(nil), flags)
|
MustRegisterCmd("getchaintips", (*GetChainTipsCmd)(nil), flags)
|
||||||
MustRegisterCmd("getchaintxstats", (*GetChainTxStatsCmd)(nil), flags)
|
MustRegisterCmd("getchaintxstats", (*GetChainTxStatsCmd)(nil), flags)
|
||||||
MustRegisterCmd("getconnectioncount", (*GetConnectionCountCmd)(nil), flags)
|
MustRegisterCmd("getconnectioncount", (*GetConnectionCountCmd)(nil), flags)
|
||||||
|
MustRegisterCmd("getdescriptorinfo", (*GetDescriptorInfoCmd)(nil), flags)
|
||||||
MustRegisterCmd("getdifficulty", (*GetDifficultyCmd)(nil), flags)
|
MustRegisterCmd("getdifficulty", (*GetDifficultyCmd)(nil), flags)
|
||||||
MustRegisterCmd("getgenerate", (*GetGenerateCmd)(nil), flags)
|
MustRegisterCmd("getgenerate", (*GetGenerateCmd)(nil), flags)
|
||||||
MustRegisterCmd("gethashespersec", (*GetHashesPerSecCmd)(nil), flags)
|
MustRegisterCmd("gethashespersec", (*GetHashesPerSecCmd)(nil), flags)
|
||||||
|
@ -1027,5 +1044,4 @@ func init() {
|
||||||
MustRegisterCmd("verifychain", (*VerifyChainCmd)(nil), flags)
|
MustRegisterCmd("verifychain", (*VerifyChainCmd)(nil), flags)
|
||||||
MustRegisterCmd("verifymessage", (*VerifyMessageCmd)(nil), flags)
|
MustRegisterCmd("verifymessage", (*VerifyMessageCmd)(nil), flags)
|
||||||
MustRegisterCmd("verifytxoutproof", (*VerifyTxOutProofCmd)(nil), flags)
|
MustRegisterCmd("verifytxoutproof", (*VerifyTxOutProofCmd)(nil), flags)
|
||||||
MustRegisterCmd("getdescriptorinfo", (*GetDescriptorInfoCmd)(nil), flags)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,6 +220,51 @@ func TestChainSvrCmds(t *testing.T) {
|
||||||
marshalled: `{"jsonrpc":"1.0","method":"decodescript","params":["00"],"id":1}`,
|
marshalled: `{"jsonrpc":"1.0","method":"decodescript","params":["00"],"id":1}`,
|
||||||
unmarshalled: &btcjson.DecodeScriptCmd{HexScript: "00"},
|
unmarshalled: &btcjson.DecodeScriptCmd{HexScript: "00"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "deriveaddresses no range",
|
||||||
|
newCmd: func() (interface{}, error) {
|
||||||
|
return btcjson.NewCmd("deriveaddresses", "00")
|
||||||
|
},
|
||||||
|
staticCmd: func() interface{} {
|
||||||
|
return btcjson.NewDeriveAddressesCmd("00", nil)
|
||||||
|
},
|
||||||
|
marshalled: `{"jsonrpc":"1.0","method":"deriveaddresses","params":["00"],"id":1}`,
|
||||||
|
unmarshalled: &btcjson.DeriveAddressesCmd{Descriptor: "00"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deriveaddresses int range",
|
||||||
|
newCmd: func() (interface{}, error) {
|
||||||
|
return btcjson.NewCmd(
|
||||||
|
"deriveaddresses", "00", btcjson.DescriptorRange{Value: 2})
|
||||||
|
},
|
||||||
|
staticCmd: func() interface{} {
|
||||||
|
return btcjson.NewDeriveAddressesCmd(
|
||||||
|
"00", &btcjson.DescriptorRange{Value: 2})
|
||||||
|
},
|
||||||
|
marshalled: `{"jsonrpc":"1.0","method":"deriveaddresses","params":["00",2],"id":1}`,
|
||||||
|
unmarshalled: &btcjson.DeriveAddressesCmd{
|
||||||
|
Descriptor: "00",
|
||||||
|
Range: &btcjson.DescriptorRange{Value: 2},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deriveaddresses slice range",
|
||||||
|
newCmd: func() (interface{}, error) {
|
||||||
|
return btcjson.NewCmd(
|
||||||
|
"deriveaddresses", "00",
|
||||||
|
btcjson.DescriptorRange{Value: []int{0, 2}},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
staticCmd: func() interface{} {
|
||||||
|
return btcjson.NewDeriveAddressesCmd(
|
||||||
|
"00", &btcjson.DescriptorRange{Value: []int{0, 2}})
|
||||||
|
},
|
||||||
|
marshalled: `{"jsonrpc":"1.0","method":"deriveaddresses","params":["00",[0,2]],"id":1}`,
|
||||||
|
unmarshalled: &btcjson.DeriveAddressesCmd{
|
||||||
|
Descriptor: "00",
|
||||||
|
Range: &btcjson.DescriptorRange{Value: []int{0, 2}},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "getaddednodeinfo",
|
name: "getaddednodeinfo",
|
||||||
newCmd: func() (interface{}, error) {
|
newCmd: func() (interface{}, error) {
|
||||||
|
|
|
@ -764,3 +764,6 @@ type GetDescriptorInfoResult struct {
|
||||||
IsSolvable bool `json:"issolvable"` // whether the descriptor is solvable
|
IsSolvable bool `json:"issolvable"` // whether the descriptor is solvable
|
||||||
HasPrivateKeys bool `json:"hasprivatekeys"` // whether the descriptor has at least one private key
|
HasPrivateKeys bool `json:"hasprivatekeys"` // whether the descriptor has at least one private key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeriveAddressesResult models the data from the deriveaddresses command.
|
||||||
|
type DeriveAddressesResult []string
|
||||||
|
|
|
@ -1263,6 +1263,45 @@ func (c *Client) GetBlockStats(hashOrHeight interface{}, stats *[]string) (*btcj
|
||||||
return c.GetBlockStatsAsync(hashOrHeight, stats).Receive()
|
return c.GetBlockStatsAsync(hashOrHeight, stats).Receive()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FutureDeriveAddressesResult is a future promise to deliver the result of an
|
||||||
|
// DeriveAddressesAsync RPC invocation (or an applicable error).
|
||||||
|
type FutureDeriveAddressesResult chan *response
|
||||||
|
|
||||||
|
// Receive waits for the response promised by the future and derives one or more addresses
|
||||||
|
// corresponding to the given output descriptor.
|
||||||
|
func (r FutureDeriveAddressesResult) Receive() (*btcjson.DeriveAddressesResult, error) {
|
||||||
|
res, err := receiveFuture(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var deriveAddressesResult btcjson.DeriveAddressesResult
|
||||||
|
|
||||||
|
err = json.Unmarshal(res, &deriveAddressesResult)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &deriveAddressesResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeriveAddressesAsync returns an instance of a type that can be used to get the result
|
||||||
|
// of the RPC at some future time by invoking the Receive function on the
|
||||||
|
// returned instance.
|
||||||
|
//
|
||||||
|
// See DeriveAddresses for the blocking version and more details.
|
||||||
|
func (c *Client) DeriveAddressesAsync(descriptor string, descriptorRange *btcjson.DescriptorRange) FutureDeriveAddressesResult {
|
||||||
|
cmd := btcjson.NewDeriveAddressesCmd(descriptor, descriptorRange)
|
||||||
|
return c.sendCmd(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeriveAddresses derives one or more addresses corresponding to an output
|
||||||
|
// descriptor. If a ranged descriptor is used, the end or the range
|
||||||
|
// (in [begin,end] notation) to derive must be specified.
|
||||||
|
func (c *Client) DeriveAddresses(descriptor string, descriptorRange *btcjson.DescriptorRange) (*btcjson.DeriveAddressesResult, error) {
|
||||||
|
return c.DeriveAddressesAsync(descriptor, descriptorRange).Receive()
|
||||||
|
}
|
||||||
|
|
||||||
// FutureGetDescriptorInfoResult is a future promise to deliver the result of a
|
// FutureGetDescriptorInfoResult is a future promise to deliver the result of a
|
||||||
// GetDescriptorInfoAsync RPC invocation (or an applicable error).
|
// GetDescriptorInfoAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetDescriptorInfoResult chan *response
|
type FutureGetDescriptorInfoResult chan *response
|
||||||
|
@ -1276,10 +1315,12 @@ func (r FutureGetDescriptorInfoResult) Receive() (*btcjson.GetDescriptorInfoResu
|
||||||
}
|
}
|
||||||
|
|
||||||
var descriptorInfo btcjson.GetDescriptorInfoResult
|
var descriptorInfo btcjson.GetDescriptorInfoResult
|
||||||
|
|
||||||
err = json.Unmarshal(res, &descriptorInfo)
|
err = json.Unmarshal(res, &descriptorInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &descriptorInfo, nil
|
return &descriptorInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,3 +59,21 @@ func ExampleClient_ImportMulti() {
|
||||||
fmt.Println(resp[0].Success)
|
fmt.Println(resp[0].Success)
|
||||||
// true
|
// true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleClient_DeriveAddresses() {
|
||||||
|
client, err := New(connCfg, nil)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer client.Shutdown()
|
||||||
|
|
||||||
|
addrs, err := client.DeriveAddresses(
|
||||||
|
"pkh([f34db33f/44'/0'/0']xpub6Cc939fyHvfB9pPLWd3bSyyQFvgKbwhidca49jGCM5Hz5ypEPGf9JVXB4NBuUfPgoHnMjN6oNgdC9KRqM11RZtL8QLW6rFKziNwHDYhZ6Kx/0/*)#ed7px9nu",
|
||||||
|
&btcjson.DescriptorRange{Value: []int{0, 2}})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%+v\n", addrs)
|
||||||
|
// &[14NjenDKkGGq1McUgoSkeUHJpW3rrKLbPW 1Pn6i3cvdGhqbdgNjXHfbaYfiuviPiymXj 181x1NbgGYKLeMXkDdXEAqepG75EgU8XtG]
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue