Skip to content

Commit

Permalink
Add rpclient implementation of getdescriptorinfo RPC
Browse files Browse the repository at this point in the history
  • Loading branch information
onyb authored and jcvernaleo committed Aug 31, 2020
1 parent 70a0132 commit efae8e9
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 0 deletions.
14 changes: 14 additions & 0 deletions btcjson/chainsvrcmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,19 @@ 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() {
// No special flags for commands in this file.
flags := UsageFlag(0)
Expand Down Expand Up @@ -937,4 +950,5 @@ func init() {
MustRegisterCmd("verifychain", (*VerifyChainCmd)(nil), flags)
MustRegisterCmd("verifymessage", (*VerifyMessageCmd)(nil), flags)
MustRegisterCmd("verifytxoutproof", (*VerifyTxOutProofCmd)(nil), flags)
MustRegisterCmd("getdescriptorinfo", (*GetDescriptorInfoCmd)(nil), flags)
}
11 changes: 11 additions & 0 deletions btcjson/chainsvrcmds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1302,6 +1302,17 @@ func TestChainSvrCmds(t *testing.T) {
Proof: "test",
},
},
{
name: "getdescriptorinfo",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("getdescriptorinfo", "123")
},
staticCmd: func() interface{} {
return btcjson.NewGetDescriptorInfoCmd("123")
},
marshalled: `{"jsonrpc":"1.0","method":"getdescriptorinfo","params":["123"],"id":1}`,
unmarshalled: &btcjson.GetDescriptorInfoCmd{Descriptor: "123"},
},
}

t.Logf("Running %d tests", len(tests))
Expand Down
9 changes: 9 additions & 0 deletions btcjson/chainsvrresults.go
Original file line number Diff line number Diff line change
Expand Up @@ -730,3 +730,12 @@ func (f *FundRawTransactionResult) UnmarshalJSON(data []byte) error {
f.ChangePosition = rawRes.ChangePosition
return nil
}

// GetDescriptorInfoResult models the data from the getdescriptorinfo command.
type GetDescriptorInfoResult struct {
Descriptor string `json:"descriptor"` // descriptor in canonical form, without private keys
Checksum string `json:"checksum"` // checksum for the input descriptor
IsRange bool `json:"isrange"` // whether the descriptor is ranged
IsSolvable bool `json:"issolvable"` // whether the descriptor is solvable
HasPrivateKeys bool `json:"hasprivatekeys"` // whether the descriptor has at least one private key
}
41 changes: 41 additions & 0 deletions rpcclient/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1224,3 +1224,44 @@ func (c *Client) GetBlockStatsAsync(hashOrHeight interface{}, stats *[]string) F
func (c *Client) GetBlockStats(hashOrHeight interface{}, stats *[]string) (*btcjson.GetBlockStatsResult, error) {
return c.GetBlockStatsAsync(hashOrHeight, stats).Receive()
}

// FutureGetDescriptorInfoResult is a future promise to deliver the result of a
// GetDescriptorInfoAsync RPC invocation (or an applicable error).
type FutureGetDescriptorInfoResult chan *response

// Receive waits for the response promised by the future and returns the analysed
// info of the descriptor.
func (r FutureGetDescriptorInfoResult) Receive() (*btcjson.GetDescriptorInfoResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}

var descriptorInfo btcjson.GetDescriptorInfoResult
err = json.Unmarshal(res, &descriptorInfo)
if err != nil {
return nil, err
}
return &descriptorInfo, nil
}

// GetDescriptorInfoAsync 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 GetDescriptorInfo for the blocking version and more details.
func (c *Client) GetDescriptorInfoAsync(descriptor string) FutureGetDescriptorInfoResult {
cmd := btcjson.NewGetDescriptorInfoCmd(descriptor)
return c.sendCmd(cmd)
}

// GetDescriptorInfo returns the analysed info of a descriptor string, by invoking the
// getdescriptorinfo RPC.
//
// Use this function to analyse a descriptor string, or compute the checksum
// for a descriptor without one.
//
// See btcjson.GetDescriptorInfoResult for details about the result.
func (c *Client) GetDescriptorInfo(descriptor string) (*btcjson.GetDescriptorInfoResult, error) {
return c.GetDescriptorInfoAsync(descriptor).Receive()
}
31 changes: 31 additions & 0 deletions rpcclient/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package rpcclient

import (
"fmt"
)

func ExampleClient_GetDescriptorInfo() {
connCfg := &ConnConfig{
Host: "localhost:8332",
User: "yourrpcuser",
Pass: "yourrpcpass",
HTTPPostMode: true,
DisableTLS: true,
}
client, err := New(connCfg, nil)
if err != nil {
log.Error(err)
return
}
defer client.Shutdown()

descriptorInfo, err := client.GetDescriptorInfo(
"wpkh([d34db33f/84h/0h/0h]0279be667ef9dcbbac55a06295Ce870b07029Bfcdb2dce28d959f2815b16f81798)")
if err != nil {
log.Error(err)
return
}

fmt.Printf("%+v\n", descriptorInfo)
// &{Descriptor:wpkh([d34db33f/84'/0'/0']0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)#n9g43y4k Checksum:qwlqgth7 IsRange:false IsSolvable:true HasPrivateKeys:false}
}

0 comments on commit efae8e9

Please sign in to comment.