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
|
||||
// of a transaction built by the node.
|
||||
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.
|
||||
type GetAddedNodeInfoCmd struct {
|
||||
DNS bool
|
||||
|
@ -467,6 +482,19 @@ func NewGetConnectionCountCmd() *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.
|
||||
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() {
|
||||
// No special flags for commands in this file.
|
||||
flags := UsageFlag(0)
|
||||
|
||||
MustRegisterCmd("addnode", (*AddNodeCmd)(nil), flags)
|
||||
MustRegisterCmd("createrawtransaction", (*CreateRawTransactionCmd)(nil), flags)
|
||||
MustRegisterCmd("fundrawtransaction", (*FundRawTransactionCmd)(nil), flags)
|
||||
MustRegisterCmd("decoderawtransaction", (*DecodeRawTransactionCmd)(nil), flags)
|
||||
MustRegisterCmd("decodescript", (*DecodeScriptCmd)(nil), flags)
|
||||
MustRegisterCmd("deriveaddresses", (*DeriveAddressesCmd)(nil), flags)
|
||||
MustRegisterCmd("fundrawtransaction", (*FundRawTransactionCmd)(nil), flags)
|
||||
MustRegisterCmd("getaddednodeinfo", (*GetAddedNodeInfoCmd)(nil), flags)
|
||||
MustRegisterCmd("getbestblockhash", (*GetBestBlockHashCmd)(nil), flags)
|
||||
MustRegisterCmd("getblock", (*GetBlockCmd)(nil), flags)
|
||||
|
@ -993,6 +1009,7 @@ func init() {
|
|||
MustRegisterCmd("getchaintips", (*GetChainTipsCmd)(nil), flags)
|
||||
MustRegisterCmd("getchaintxstats", (*GetChainTxStatsCmd)(nil), flags)
|
||||
MustRegisterCmd("getconnectioncount", (*GetConnectionCountCmd)(nil), flags)
|
||||
MustRegisterCmd("getdescriptorinfo", (*GetDescriptorInfoCmd)(nil), flags)
|
||||
MustRegisterCmd("getdifficulty", (*GetDifficultyCmd)(nil), flags)
|
||||
MustRegisterCmd("getgenerate", (*GetGenerateCmd)(nil), flags)
|
||||
MustRegisterCmd("gethashespersec", (*GetHashesPerSecCmd)(nil), flags)
|
||||
|
@ -1027,5 +1044,4 @@ func init() {
|
|||
MustRegisterCmd("verifychain", (*VerifyChainCmd)(nil), flags)
|
||||
MustRegisterCmd("verifymessage", (*VerifyMessageCmd)(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}`,
|
||||
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",
|
||||
newCmd: func() (interface{}, error) {
|
||||
|
|
|
@ -764,3 +764,6 @@ type GetDescriptorInfoResult struct {
|
|||
IsSolvable bool `json:"issolvable"` // whether the descriptor is solvable
|
||||
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()
|
||||
}
|
||||
|
||||
// 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
|
||||
// GetDescriptorInfoAsync RPC invocation (or an applicable error).
|
||||
type FutureGetDescriptorInfoResult chan *response
|
||||
|
@ -1276,10 +1315,12 @@ func (r FutureGetDescriptorInfoResult) Receive() (*btcjson.GetDescriptorInfoResu
|
|||
}
|
||||
|
||||
var descriptorInfo btcjson.GetDescriptorInfoResult
|
||||
|
||||
err = json.Unmarshal(res, &descriptorInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &descriptorInfo, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -59,3 +59,21 @@ func ExampleClient_ImportMulti() {
|
|||
fmt.Println(resp[0].Success)
|
||||
// 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…
Reference in a new issue