diff --git a/btcjson/chainsvrcmds.go b/btcjson/chainsvrcmds.go index aa1d4415da..48921d41ed 100644 --- a/btcjson/chainsvrcmds.go +++ b/btcjson/chainsvrcmds.go @@ -48,6 +48,23 @@ func NewAddNodeCmd(addr string, subCmd AddNodeSubCmd) *AddNodeCmd { } } +// ConvertToPsbtCmd defines the converttopsbt JSON-RPC command. +type ConvertToPsbtCmd struct { + Psbt string + PermitSigData *bool + IsWitness *bool +} + +// NewConvertToPsbtCmd returns a new instance which can be used to issue a +// converttopsbt JSON-RPC command. +func NewConvertToPsbtCmd(psbt string, permitSigData, isWitness *bool) *ConvertToPsbtCmd { + return &ConvertToPsbtCmd{ + Psbt: psbt, + PermitSigData: permitSigData, + IsWitness: isWitness, + } +} + // TransactionInput represents the inputs to a transaction. Specifically a // transaction hash and output number pair. type TransactionInput struct { @@ -1047,6 +1064,7 @@ func init() { flags := UsageFlag(0) MustRegisterCmd("addnode", (*AddNodeCmd)(nil), flags) + MustRegisterCmd("converttopsbt", (*ConvertToPsbtCmd)(nil), flags) MustRegisterCmd("createrawtransaction", (*CreateRawTransactionCmd)(nil), flags) MustRegisterCmd("decoderawtransaction", (*DecodeRawTransactionCmd)(nil), flags) MustRegisterCmd("decodescript", (*DecodeScriptCmd)(nil), flags) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index ff5d56908b..7229d82422 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -146,6 +146,11 @@ type DecodeScriptResult struct { P2sh string `json:"p2sh,omitempty"` } +// ConvertToPsbtResult models the data returned from the converttopsbt command. +type ConvertToPsbtResult struct { + Psbt string `json:"psbt"` +} + // GetAddedNodeInfoResultAddr models the data of the addresses portion of the // getaddednodeinfo command. type GetAddedNodeInfoResultAddr struct { diff --git a/rpcclient/rawtransactions.go b/rpcclient/rawtransactions.go index 1df6195220..8380ef533d 100644 --- a/rpcclient/rawtransactions.go +++ b/rpcclient/rawtransactions.go @@ -882,3 +882,48 @@ func (c *Client) DecodeScriptAsync(serializedScript []byte) FutureDecodeScriptRe func (c *Client) DecodeScript(serializedScript []byte) (*btcjson.DecodeScriptResult, error) { return c.DecodeScriptAsync(serializedScript).Receive() } + +// FutureConvertToPsbtResult is a future promise to deliver the result of a +// ConvertToPsbt RPC invocation (or an applicable error). +type FutureConvertToPsbtResult chan *Response + +func (r FutureConvertToPsbtResult) Receive() (*btcjson.ConvertToPsbtResult, error) { + res, err := ReceiveFuture(r) + if err != nil { + return nil, err + } + + // Unmarshal result as a convertpsbt result object. + var convertToPsbtResult btcjson.ConvertToPsbtResult + err = json.Unmarshal(res, &convertToPsbtResult) + if err != nil { + return nil, err + } + + return &convertToPsbtResult, nil +} + +// ConvertToPsbtAsync 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 ConvertToPsbt for the blocking version and more details. +func (c *Client) ConvertToPsbtAsync(tx *wire.MsgTx, permitSigData *bool, isWitness *bool) FutureConvertToPsbtResult { + txHex := "" + if tx != nil { + // Serialize the transaction and convert to hex string. + buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize())) + if err := tx.Serialize(buf); err != nil { + return newFutureError(err) + } + txHex = hex.EncodeToString(buf.Bytes()) + } + + cmd := btcjson.NewConvertToPsbtCmd(txHex, permitSigData, isWitness) + return c.SendCmd(cmd) +} + +// ConvertToPsbt returns a PSBT version of the transaction given. +func (c *Client) ConvertToPsbt(tx *wire.MsgTx, permitSigData *bool, isWitness *bool) (*btcjson.ConvertToPsbtResult, error) { + return c.ConvertToPsbtAsync(tx, permitSigData, isWitness).Receive() +}