1// Copyright (c) 2014-2017 The btcsuite developers
2// Use of this source code is governed by an ISC
3// license that can be found in the LICENSE file.
4
5package rpcclient
6
7import (
8	"bytes"
9	"encoding/hex"
10	"encoding/json"
11
12	"github.com/btcsuite/btcd/btcjson"
13	"github.com/btcsuite/btcd/chaincfg/chainhash"
14	"github.com/btcsuite/btcd/wire"
15	"github.com/btcsuite/btcutil"
16)
17
18const (
19	// defaultMaxFeeRate is the default maximum fee rate in sat/KB enforced
20	// by bitcoind v0.19.0 or after for transaction broadcast.
21	defaultMaxFeeRate = btcutil.SatoshiPerBitcoin / 10
22)
23
24// SigHashType enumerates the available signature hashing types that the
25// SignRawTransaction function accepts.
26type SigHashType string
27
28// Constants used to indicate the signature hash type for SignRawTransaction.
29const (
30	// SigHashAll indicates ALL of the outputs should be signed.
31	SigHashAll SigHashType = "ALL"
32
33	// SigHashNone indicates NONE of the outputs should be signed.  This
34	// can be thought of as specifying the signer does not care where the
35	// bitcoins go.
36	SigHashNone SigHashType = "NONE"
37
38	// SigHashSingle indicates that a SINGLE output should be signed.  This
39	// can be thought of specifying the signer only cares about where ONE of
40	// the outputs goes, but not any of the others.
41	SigHashSingle SigHashType = "SINGLE"
42
43	// SigHashAllAnyoneCanPay indicates that signer does not care where the
44	// other inputs to the transaction come from, so it allows other people
45	// to add inputs.  In addition, it uses the SigHashAll signing method
46	// for outputs.
47	SigHashAllAnyoneCanPay SigHashType = "ALL|ANYONECANPAY"
48
49	// SigHashNoneAnyoneCanPay indicates that signer does not care where the
50	// other inputs to the transaction come from, so it allows other people
51	// to add inputs.  In addition, it uses the SigHashNone signing method
52	// for outputs.
53	SigHashNoneAnyoneCanPay SigHashType = "NONE|ANYONECANPAY"
54
55	// SigHashSingleAnyoneCanPay indicates that signer does not care where
56	// the other inputs to the transaction come from, so it allows other
57	// people to add inputs.  In addition, it uses the SigHashSingle signing
58	// method for outputs.
59	SigHashSingleAnyoneCanPay SigHashType = "SINGLE|ANYONECANPAY"
60)
61
62// String returns the SighHashType in human-readable form.
63func (s SigHashType) String() string {
64	return string(s)
65}
66
67// FutureGetRawTransactionResult is a future promise to deliver the result of a
68// GetRawTransactionAsync RPC invocation (or an applicable error).
69type FutureGetRawTransactionResult chan *response
70
71// Receive waits for the response promised by the future and returns a
72// transaction given its hash.
73func (r FutureGetRawTransactionResult) Receive() (*btcutil.Tx, error) {
74	res, err := receiveFuture(r)
75	if err != nil {
76		return nil, err
77	}
78
79	// Unmarshal result as a string.
80	var txHex string
81	err = json.Unmarshal(res, &txHex)
82	if err != nil {
83		return nil, err
84	}
85
86	// Decode the serialized transaction hex to raw bytes.
87	serializedTx, err := hex.DecodeString(txHex)
88	if err != nil {
89		return nil, err
90	}
91
92	// Deserialize the transaction and return it.
93	var msgTx wire.MsgTx
94	if err := msgTx.Deserialize(bytes.NewReader(serializedTx)); err != nil {
95		return nil, err
96	}
97	return btcutil.NewTx(&msgTx), nil
98}
99
100// GetRawTransactionAsync returns an instance of a type that can be used to get
101// the result of the RPC at some future time by invoking the Receive function on
102// the returned instance.
103//
104// See GetRawTransaction for the blocking version and more details.
105func (c *Client) GetRawTransactionAsync(txHash *chainhash.Hash) FutureGetRawTransactionResult {
106	hash := ""
107	if txHash != nil {
108		hash = txHash.String()
109	}
110
111	cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Int(0))
112	return c.sendCmd(cmd)
113}
114
115// GetRawTransaction returns a transaction given its hash.
116//
117// See GetRawTransactionVerbose to obtain additional information about the
118// transaction.
119func (c *Client) GetRawTransaction(txHash *chainhash.Hash) (*btcutil.Tx, error) {
120	return c.GetRawTransactionAsync(txHash).Receive()
121}
122
123// FutureGetRawTransactionVerboseResult is a future promise to deliver the
124// result of a GetRawTransactionVerboseAsync RPC invocation (or an applicable
125// error).
126type FutureGetRawTransactionVerboseResult chan *response
127
128// Receive waits for the response promised by the future and returns information
129// about a transaction given its hash.
130func (r FutureGetRawTransactionVerboseResult) Receive() (*btcjson.TxRawResult, error) {
131	res, err := receiveFuture(r)
132	if err != nil {
133		return nil, err
134	}
135
136	// Unmarshal result as a gettrawtransaction result object.
137	var rawTxResult btcjson.TxRawResult
138	err = json.Unmarshal(res, &rawTxResult)
139	if err != nil {
140		return nil, err
141	}
142
143	return &rawTxResult, nil
144}
145
146// GetRawTransactionVerboseAsync returns an instance of a type that can be used
147// to get the result of the RPC at some future time by invoking the Receive
148// function on the returned instance.
149//
150// See GetRawTransactionVerbose for the blocking version and more details.
151func (c *Client) GetRawTransactionVerboseAsync(txHash *chainhash.Hash) FutureGetRawTransactionVerboseResult {
152	hash := ""
153	if txHash != nil {
154		hash = txHash.String()
155	}
156
157	cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Int(1))
158	return c.sendCmd(cmd)
159}
160
161// GetRawTransactionVerbose returns information about a transaction given
162// its hash.
163//
164// See GetRawTransaction to obtain only the transaction already deserialized.
165func (c *Client) GetRawTransactionVerbose(txHash *chainhash.Hash) (*btcjson.TxRawResult, error) {
166	return c.GetRawTransactionVerboseAsync(txHash).Receive()
167}
168
169// FutureDecodeRawTransactionResult is a future promise to deliver the result
170// of a DecodeRawTransactionAsync RPC invocation (or an applicable error).
171type FutureDecodeRawTransactionResult chan *response
172
173// Receive waits for the response promised by the future and returns information
174// about a transaction given its serialized bytes.
175func (r FutureDecodeRawTransactionResult) Receive() (*btcjson.TxRawResult, error) {
176	res, err := receiveFuture(r)
177	if err != nil {
178		return nil, err
179	}
180
181	// Unmarshal result as a decoderawtransaction result object.
182	var rawTxResult btcjson.TxRawResult
183	err = json.Unmarshal(res, &rawTxResult)
184	if err != nil {
185		return nil, err
186	}
187
188	return &rawTxResult, nil
189}
190
191// DecodeRawTransactionAsync returns an instance of a type that can be used to
192// get the result of the RPC at some future time by invoking the Receive
193// function on the returned instance.
194//
195// See DecodeRawTransaction for the blocking version and more details.
196func (c *Client) DecodeRawTransactionAsync(serializedTx []byte) FutureDecodeRawTransactionResult {
197	txHex := hex.EncodeToString(serializedTx)
198	cmd := btcjson.NewDecodeRawTransactionCmd(txHex)
199	return c.sendCmd(cmd)
200}
201
202// DecodeRawTransaction returns information about a transaction given its
203// serialized bytes.
204func (c *Client) DecodeRawTransaction(serializedTx []byte) (*btcjson.TxRawResult, error) {
205	return c.DecodeRawTransactionAsync(serializedTx).Receive()
206}
207
208// FutureCreateRawTransactionResult is a future promise to deliver the result
209// of a CreateRawTransactionAsync RPC invocation (or an applicable error).
210type FutureCreateRawTransactionResult chan *response
211
212// Receive waits for the response promised by the future and returns a new
213// transaction spending the provided inputs and sending to the provided
214// addresses.
215func (r FutureCreateRawTransactionResult) Receive() (*wire.MsgTx, error) {
216	res, err := receiveFuture(r)
217	if err != nil {
218		return nil, err
219	}
220
221	// Unmarshal result as a string.
222	var txHex string
223	err = json.Unmarshal(res, &txHex)
224	if err != nil {
225		return nil, err
226	}
227
228	// Decode the serialized transaction hex to raw bytes.
229	serializedTx, err := hex.DecodeString(txHex)
230	if err != nil {
231		return nil, err
232	}
233
234	// Deserialize the transaction and return it.
235	var msgTx wire.MsgTx
236	// we try both the new and old encoding format
237	witnessErr := msgTx.Deserialize(bytes.NewReader(serializedTx))
238	if witnessErr != nil {
239		legacyErr := msgTx.DeserializeNoWitness(bytes.NewReader(serializedTx))
240		if legacyErr != nil {
241			return nil, legacyErr
242		}
243	}
244	return &msgTx, nil
245}
246
247// CreateRawTransactionAsync returns an instance of a type that can be used to
248// get the result of the RPC at some future time by invoking the Receive
249// function on the returned instance.
250//
251// See CreateRawTransaction for the blocking version and more details.
252func (c *Client) CreateRawTransactionAsync(inputs []btcjson.TransactionInput,
253	amounts map[btcutil.Address]btcutil.Amount, lockTime *int64) FutureCreateRawTransactionResult {
254
255	convertedAmts := make(map[string]float64, len(amounts))
256	for addr, amount := range amounts {
257		convertedAmts[addr.String()] = amount.ToBTC()
258	}
259	cmd := btcjson.NewCreateRawTransactionCmd(inputs, convertedAmts, lockTime)
260	return c.sendCmd(cmd)
261}
262
263// CreateRawTransaction returns a new transaction spending the provided inputs
264// and sending to the provided addresses.
265func (c *Client) CreateRawTransaction(inputs []btcjson.TransactionInput,
266	amounts map[btcutil.Address]btcutil.Amount, lockTime *int64) (*wire.MsgTx, error) {
267
268	return c.CreateRawTransactionAsync(inputs, amounts, lockTime).Receive()
269}
270
271// FutureSendRawTransactionResult is a future promise to deliver the result
272// of a SendRawTransactionAsync RPC invocation (or an applicable error).
273type FutureSendRawTransactionResult chan *response
274
275// Receive waits for the response promised by the future and returns the result
276// of submitting the encoded transaction to the server which then relays it to
277// the network.
278func (r FutureSendRawTransactionResult) Receive() (*chainhash.Hash, error) {
279	res, err := receiveFuture(r)
280	if err != nil {
281		return nil, err
282	}
283
284	// Unmarshal result as a string.
285	var txHashStr string
286	err = json.Unmarshal(res, &txHashStr)
287	if err != nil {
288		return nil, err
289	}
290
291	return chainhash.NewHashFromStr(txHashStr)
292}
293
294// SendRawTransactionAsync returns an instance of a type that can be used to get
295// the result of the RPC at some future time by invoking the Receive function on
296// the returned instance.
297//
298// See SendRawTransaction for the blocking version and more details.
299func (c *Client) SendRawTransactionAsync(tx *wire.MsgTx, allowHighFees bool) FutureSendRawTransactionResult {
300	txHex := ""
301	if tx != nil {
302		// Serialize the transaction and convert to hex string.
303		buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
304		if err := tx.Serialize(buf); err != nil {
305			return newFutureError(err)
306		}
307		txHex = hex.EncodeToString(buf.Bytes())
308	}
309
310	// Due to differences in the sendrawtransaction API for different
311	// backends, we'll need to inspect our version and construct the
312	// appropriate request.
313	version, err := c.BackendVersion()
314	if err != nil {
315		return newFutureError(err)
316	}
317
318	var cmd *btcjson.SendRawTransactionCmd
319	switch version {
320	// Starting from bitcoind v0.19.0, the MaxFeeRate field should be used.
321	case BitcoindPost19:
322		// Using a 0 MaxFeeRate is interpreted as a maximum fee rate not
323		// being enforced by bitcoind.
324		var maxFeeRate int32
325		if !allowHighFees {
326			maxFeeRate = defaultMaxFeeRate
327		}
328		cmd = btcjson.NewBitcoindSendRawTransactionCmd(txHex, maxFeeRate)
329
330	// Otherwise, use the AllowHighFees field.
331	default:
332		cmd = btcjson.NewSendRawTransactionCmd(txHex, &allowHighFees)
333	}
334
335	return c.sendCmd(cmd)
336}
337
338// SendRawTransaction submits the encoded transaction to the server which will
339// then relay it to the network.
340func (c *Client) SendRawTransaction(tx *wire.MsgTx, allowHighFees bool) (*chainhash.Hash, error) {
341	return c.SendRawTransactionAsync(tx, allowHighFees).Receive()
342}
343
344// FutureSignRawTransactionResult is a future promise to deliver the result
345// of one of the SignRawTransactionAsync family of RPC invocations (or an
346// applicable error).
347type FutureSignRawTransactionResult chan *response
348
349// Receive waits for the response promised by the future and returns the
350// signed transaction as well as whether or not all inputs are now signed.
351func (r FutureSignRawTransactionResult) Receive() (*wire.MsgTx, bool, error) {
352	res, err := receiveFuture(r)
353	if err != nil {
354		return nil, false, err
355	}
356
357	// Unmarshal as a signrawtransaction result.
358	var signRawTxResult btcjson.SignRawTransactionResult
359	err = json.Unmarshal(res, &signRawTxResult)
360	if err != nil {
361		return nil, false, err
362	}
363
364	// Decode the serialized transaction hex to raw bytes.
365	serializedTx, err := hex.DecodeString(signRawTxResult.Hex)
366	if err != nil {
367		return nil, false, err
368	}
369
370	// Deserialize the transaction and return it.
371	var msgTx wire.MsgTx
372	if err := msgTx.Deserialize(bytes.NewReader(serializedTx)); err != nil {
373		return nil, false, err
374	}
375
376	return &msgTx, signRawTxResult.Complete, nil
377}
378
379// SignRawTransactionAsync returns an instance of a type that can be used to get
380// the result of the RPC at some future time by invoking the Receive function on
381// the returned instance.
382//
383// See SignRawTransaction for the blocking version and more details.
384func (c *Client) SignRawTransactionAsync(tx *wire.MsgTx) FutureSignRawTransactionResult {
385	txHex := ""
386	if tx != nil {
387		// Serialize the transaction and convert to hex string.
388		buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
389		if err := tx.Serialize(buf); err != nil {
390			return newFutureError(err)
391		}
392		txHex = hex.EncodeToString(buf.Bytes())
393	}
394
395	cmd := btcjson.NewSignRawTransactionCmd(txHex, nil, nil, nil)
396	return c.sendCmd(cmd)
397}
398
399// SignRawTransaction signs inputs for the passed transaction and returns the
400// signed transaction as well as whether or not all inputs are now signed.
401//
402// This function assumes the RPC server already knows the input transactions and
403// private keys for the passed transaction which needs to be signed and uses the
404// default signature hash type.  Use one of the SignRawTransaction# variants to
405// specify that information if needed.
406func (c *Client) SignRawTransaction(tx *wire.MsgTx) (*wire.MsgTx, bool, error) {
407	return c.SignRawTransactionAsync(tx).Receive()
408}
409
410// SignRawTransaction2Async returns an instance of a type that can be used to
411// get the result of the RPC at some future time by invoking the Receive
412// function on the returned instance.
413//
414// See SignRawTransaction2 for the blocking version and more details.
415func (c *Client) SignRawTransaction2Async(tx *wire.MsgTx, inputs []btcjson.RawTxInput) FutureSignRawTransactionResult {
416	txHex := ""
417	if tx != nil {
418		// Serialize the transaction and convert to hex string.
419		buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
420		if err := tx.Serialize(buf); err != nil {
421			return newFutureError(err)
422		}
423		txHex = hex.EncodeToString(buf.Bytes())
424	}
425
426	cmd := btcjson.NewSignRawTransactionCmd(txHex, &inputs, nil, nil)
427	return c.sendCmd(cmd)
428}
429
430// SignRawTransaction2 signs inputs for the passed transaction given the list
431// of information about the input transactions needed to perform the signing
432// process.
433//
434// This only input transactions that need to be specified are ones the
435// RPC server does not already know.  Already known input transactions will be
436// merged with the specified transactions.
437//
438// See SignRawTransaction if the RPC server already knows the input
439// transactions.
440func (c *Client) SignRawTransaction2(tx *wire.MsgTx, inputs []btcjson.RawTxInput) (*wire.MsgTx, bool, error) {
441	return c.SignRawTransaction2Async(tx, inputs).Receive()
442}
443
444// SignRawTransaction3Async returns an instance of a type that can be used to
445// get the result of the RPC at some future time by invoking the Receive
446// function on the returned instance.
447//
448// See SignRawTransaction3 for the blocking version and more details.
449func (c *Client) SignRawTransaction3Async(tx *wire.MsgTx,
450	inputs []btcjson.RawTxInput,
451	privKeysWIF []string) FutureSignRawTransactionResult {
452
453	txHex := ""
454	if tx != nil {
455		// Serialize the transaction and convert to hex string.
456		buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
457		if err := tx.Serialize(buf); err != nil {
458			return newFutureError(err)
459		}
460		txHex = hex.EncodeToString(buf.Bytes())
461	}
462
463	cmd := btcjson.NewSignRawTransactionCmd(txHex, &inputs, &privKeysWIF,
464		nil)
465	return c.sendCmd(cmd)
466}
467
468// SignRawTransaction3 signs inputs for the passed transaction given the list
469// of information about extra input transactions and a list of private keys
470// needed to perform the signing process.  The private keys must be in wallet
471// import format (WIF).
472//
473// This only input transactions that need to be specified are ones the
474// RPC server does not already know.  Already known input transactions will be
475// merged with the specified transactions.  This means the list of transaction
476// inputs can be nil if the RPC server already knows them all.
477//
478// NOTE: Unlike the merging functionality of the input transactions, ONLY the
479// specified private keys will be used, so even if the server already knows some
480// of the private keys, they will NOT be used.
481//
482// See SignRawTransaction if the RPC server already knows the input
483// transactions and private keys or SignRawTransaction2 if it already knows the
484// private keys.
485func (c *Client) SignRawTransaction3(tx *wire.MsgTx,
486	inputs []btcjson.RawTxInput,
487	privKeysWIF []string) (*wire.MsgTx, bool, error) {
488
489	return c.SignRawTransaction3Async(tx, inputs, privKeysWIF).Receive()
490}
491
492// SignRawTransaction4Async returns an instance of a type that can be used to
493// get the result of the RPC at some future time by invoking the Receive
494// function on the returned instance.
495//
496// See SignRawTransaction4 for the blocking version and more details.
497func (c *Client) SignRawTransaction4Async(tx *wire.MsgTx,
498	inputs []btcjson.RawTxInput, privKeysWIF []string,
499	hashType SigHashType) FutureSignRawTransactionResult {
500
501	txHex := ""
502	if tx != nil {
503		// Serialize the transaction and convert to hex string.
504		buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
505		if err := tx.Serialize(buf); err != nil {
506			return newFutureError(err)
507		}
508		txHex = hex.EncodeToString(buf.Bytes())
509	}
510
511	cmd := btcjson.NewSignRawTransactionCmd(txHex, &inputs, &privKeysWIF,
512		btcjson.String(string(hashType)))
513	return c.sendCmd(cmd)
514}
515
516// SignRawTransaction4 signs inputs for the passed transaction using the
517// the specified signature hash type given the list of information about extra
518// input transactions and a potential list of private keys needed to perform
519// the signing process.  The private keys, if specified, must be in wallet
520// import format (WIF).
521//
522// The only input transactions that need to be specified are ones the RPC server
523// does not already know.  This means the list of transaction inputs can be nil
524// if the RPC server already knows them all.
525//
526// NOTE: Unlike the merging functionality of the input transactions, ONLY the
527// specified private keys will be used, so even if the server already knows some
528// of the private keys, they will NOT be used.  The list of private keys can be
529// nil in which case any private keys the RPC server knows will be used.
530//
531// This function should only used if a non-default signature hash type is
532// desired.  Otherwise, see SignRawTransaction if the RPC server already knows
533// the input transactions and private keys, SignRawTransaction2 if it already
534// knows the private keys, or SignRawTransaction3 if it does not know both.
535func (c *Client) SignRawTransaction4(tx *wire.MsgTx,
536	inputs []btcjson.RawTxInput, privKeysWIF []string,
537	hashType SigHashType) (*wire.MsgTx, bool, error) {
538
539	return c.SignRawTransaction4Async(tx, inputs, privKeysWIF,
540		hashType).Receive()
541}
542
543// FutureSearchRawTransactionsResult is a future promise to deliver the result
544// of the SearchRawTransactionsAsync RPC invocation (or an applicable error).
545type FutureSearchRawTransactionsResult chan *response
546
547// Receive waits for the response promised by the future and returns the
548// found raw transactions.
549func (r FutureSearchRawTransactionsResult) Receive() ([]*wire.MsgTx, error) {
550	res, err := receiveFuture(r)
551	if err != nil {
552		return nil, err
553	}
554
555	// Unmarshal as an array of strings.
556	var searchRawTxnsResult []string
557	err = json.Unmarshal(res, &searchRawTxnsResult)
558	if err != nil {
559		return nil, err
560	}
561
562	// Decode and deserialize each transaction.
563	msgTxns := make([]*wire.MsgTx, 0, len(searchRawTxnsResult))
564	for _, hexTx := range searchRawTxnsResult {
565		// Decode the serialized transaction hex to raw bytes.
566		serializedTx, err := hex.DecodeString(hexTx)
567		if err != nil {
568			return nil, err
569		}
570
571		// Deserialize the transaction and add it to the result slice.
572		var msgTx wire.MsgTx
573		err = msgTx.Deserialize(bytes.NewReader(serializedTx))
574		if err != nil {
575			return nil, err
576		}
577		msgTxns = append(msgTxns, &msgTx)
578	}
579
580	return msgTxns, nil
581}
582
583// SearchRawTransactionsAsync returns an instance of a type that can be used to
584// get the result of the RPC at some future time by invoking the Receive
585// function on the returned instance.
586//
587// See SearchRawTransactions for the blocking version and more details.
588func (c *Client) SearchRawTransactionsAsync(address btcutil.Address, skip, count int, reverse bool, filterAddrs []string) FutureSearchRawTransactionsResult {
589	addr := address.EncodeAddress()
590	verbose := btcjson.Int(0)
591	cmd := btcjson.NewSearchRawTransactionsCmd(addr, verbose, &skip, &count,
592		nil, &reverse, &filterAddrs)
593	return c.sendCmd(cmd)
594}
595
596// SearchRawTransactions returns transactions that involve the passed address.
597//
598// NOTE: Chain servers do not typically provide this capability unless it has
599// specifically been enabled.
600//
601// See SearchRawTransactionsVerbose to retrieve a list of data structures with
602// information about the transactions instead of the transactions themselves.
603func (c *Client) SearchRawTransactions(address btcutil.Address, skip, count int, reverse bool, filterAddrs []string) ([]*wire.MsgTx, error) {
604	return c.SearchRawTransactionsAsync(address, skip, count, reverse, filterAddrs).Receive()
605}
606
607// FutureSearchRawTransactionsVerboseResult is a future promise to deliver the
608// result of the SearchRawTransactionsVerboseAsync RPC invocation (or an
609// applicable error).
610type FutureSearchRawTransactionsVerboseResult chan *response
611
612// Receive waits for the response promised by the future and returns the
613// found raw transactions.
614func (r FutureSearchRawTransactionsVerboseResult) Receive() ([]*btcjson.SearchRawTransactionsResult, error) {
615	res, err := receiveFuture(r)
616	if err != nil {
617		return nil, err
618	}
619
620	// Unmarshal as an array of raw transaction results.
621	var result []*btcjson.SearchRawTransactionsResult
622	err = json.Unmarshal(res, &result)
623	if err != nil {
624		return nil, err
625	}
626
627	return result, nil
628}
629
630// SearchRawTransactionsVerboseAsync returns an instance of a type that can be
631// used to get the result of the RPC at some future time by invoking the Receive
632// function on the returned instance.
633//
634// See SearchRawTransactionsVerbose for the blocking version and more details.
635func (c *Client) SearchRawTransactionsVerboseAsync(address btcutil.Address, skip,
636	count int, includePrevOut, reverse bool, filterAddrs *[]string) FutureSearchRawTransactionsVerboseResult {
637
638	addr := address.EncodeAddress()
639	verbose := btcjson.Int(1)
640	var prevOut *int
641	if includePrevOut {
642		prevOut = btcjson.Int(1)
643	}
644	cmd := btcjson.NewSearchRawTransactionsCmd(addr, verbose, &skip, &count,
645		prevOut, &reverse, filterAddrs)
646	return c.sendCmd(cmd)
647}
648
649// SearchRawTransactionsVerbose returns a list of data structures that describe
650// transactions which involve the passed address.
651//
652// NOTE: Chain servers do not typically provide this capability unless it has
653// specifically been enabled.
654//
655// See SearchRawTransactions to retrieve a list of raw transactions instead.
656func (c *Client) SearchRawTransactionsVerbose(address btcutil.Address, skip,
657	count int, includePrevOut, reverse bool, filterAddrs []string) ([]*btcjson.SearchRawTransactionsResult, error) {
658
659	return c.SearchRawTransactionsVerboseAsync(address, skip, count,
660		includePrevOut, reverse, &filterAddrs).Receive()
661}
662
663// FutureDecodeScriptResult is a future promise to deliver the result
664// of a DecodeScriptAsync RPC invocation (or an applicable error).
665type FutureDecodeScriptResult chan *response
666
667// Receive waits for the response promised by the future and returns information
668// about a script given its serialized bytes.
669func (r FutureDecodeScriptResult) Receive() (*btcjson.DecodeScriptResult, error) {
670	res, err := receiveFuture(r)
671	if err != nil {
672		return nil, err
673	}
674
675	// Unmarshal result as a decodescript result object.
676	var decodeScriptResult btcjson.DecodeScriptResult
677	err = json.Unmarshal(res, &decodeScriptResult)
678	if err != nil {
679		return nil, err
680	}
681
682	return &decodeScriptResult, nil
683}
684
685// DecodeScriptAsync returns an instance of a type that can be used to
686// get the result of the RPC at some future time by invoking the Receive
687// function on the returned instance.
688//
689// See DecodeScript for the blocking version and more details.
690func (c *Client) DecodeScriptAsync(serializedScript []byte) FutureDecodeScriptResult {
691	scriptHex := hex.EncodeToString(serializedScript)
692	cmd := btcjson.NewDecodeScriptCmd(scriptHex)
693	return c.sendCmd(cmd)
694}
695
696// DecodeScript returns information about a script given its serialized bytes.
697func (c *Client) DecodeScript(serializedScript []byte) (*btcjson.DecodeScriptResult, error) {
698	return c.DecodeScriptAsync(serializedScript).Receive()
699}
700