2013-10-09 03:18:49 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2013-12-26 06:17:03 +01:00
|
|
|
"bytes"
|
2013-10-28 17:45:44 +01:00
|
|
|
"encoding/json"
|
2013-10-09 03:18:49 +02:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"github.com/conformal/btcjson"
|
2014-01-27 21:19:39 +01:00
|
|
|
"github.com/conformal/btcutil"
|
2013-10-17 01:19:26 +02:00
|
|
|
"github.com/conformal/go-flags"
|
2013-10-09 03:18:49 +02:00
|
|
|
"github.com/davecgh/go-spew/spew"
|
2013-11-07 17:25:11 +01:00
|
|
|
"io/ioutil"
|
2013-10-17 01:19:26 +02:00
|
|
|
"os"
|
2013-10-22 17:56:56 +02:00
|
|
|
"sort"
|
2013-10-09 03:18:49 +02:00
|
|
|
"strconv"
|
|
|
|
)
|
|
|
|
|
2013-10-22 05:56:02 +02:00
|
|
|
// conversionHandler is a handler that is used to convert parameters from the
|
|
|
|
// command line to a specific type. This is needed since the btcjson API
|
|
|
|
// expects certain types for various parameters.
|
|
|
|
type conversionHandler func(string) (interface{}, error)
|
|
|
|
|
|
|
|
// displayHandler is a handler that takes an interface and displays it to
|
|
|
|
// standard out. It is used by the handler data to type assert replies and
|
|
|
|
// show them formatted as desired.
|
|
|
|
type displayHandler func(interface{}) error
|
|
|
|
|
|
|
|
// handlerData contains information about how a command should be handled.
|
|
|
|
type handlerData struct {
|
|
|
|
requiredArgs int
|
|
|
|
optionalArgs int
|
|
|
|
displayHandler displayHandler
|
|
|
|
conversionHandlers []conversionHandler
|
2013-10-28 17:45:44 +01:00
|
|
|
makeCmd func([]interface{}) (btcjson.Cmd, error)
|
2013-10-22 17:56:56 +02:00
|
|
|
usage string
|
2013-10-22 05:56:02 +02:00
|
|
|
}
|
|
|
|
|
2013-11-20 03:35:49 +01:00
|
|
|
// Errors used in the various handlers.
|
2013-10-09 03:18:49 +02:00
|
|
|
var (
|
2013-10-22 05:56:02 +02:00
|
|
|
ErrNoData = errors.New("No data returned.")
|
|
|
|
ErrNoDisplayHandler = errors.New("No display handler specified.")
|
|
|
|
ErrUsage = errors.New("btcctl usage") // Real usage is shown.
|
2013-10-09 03:18:49 +02:00
|
|
|
)
|
|
|
|
|
2013-10-22 17:56:56 +02:00
|
|
|
// commandHandlers is a map of commands and associated handler data that is used
|
|
|
|
// to validate correctness and perform the command.
|
2013-10-22 05:56:02 +02:00
|
|
|
var commandHandlers = map[string]*handlerData{
|
2014-01-27 21:19:39 +01:00
|
|
|
"addnode": &handlerData{2, 0, displayJSONDump, nil, makeAddNode, "<ip> <add/remove/onetry>"},
|
|
|
|
"createrawtransaction": &handlerData{2, 0, displayGeneric, nil, makeCreateRawTransaction, "\"[{\"txid\":\"id\",\"vout\":n},...]\" \"{\"address\":amount,...}\""},
|
|
|
|
"debuglevel": &handlerData{1, 0, displayGeneric, nil, makeDebugLevel, "<levelspec>"},
|
|
|
|
"decoderawtransaction": &handlerData{1, 0, displayJSONDump, nil, makeDecodeRawTransaction, "<txhash>"},
|
|
|
|
"decodescript": &handlerData{1, 0, displayJSONDump, nil, makeDecodeScript, "<hex>"},
|
|
|
|
"dumpprivkey": &handlerData{1, 0, displayGeneric, nil, makeDumpPrivKey, "<bitcoinaddress>"},
|
|
|
|
"getaccount": &handlerData{1, 0, displayGeneric, nil, makeGetAccount, "<address>"},
|
|
|
|
"getaccountaddress": &handlerData{1, 0, displayGeneric, nil, makeGetAccountAddress, "<account>"},
|
|
|
|
"getaddednodeinfo": &handlerData{1, 1, displayJSONDump, []conversionHandler{toBool, nil}, makeGetAddedNodeInfo, "<dns> [node]"},
|
|
|
|
"getaddressesbyaccount": &handlerData{1, 0, displayJSONDump, nil, makeGetAddressesByAccount, "[account]"},
|
|
|
|
"getbalance": &handlerData{0, 2, displayGeneric, []conversionHandler{nil, toInt}, makeGetBalance, "[account] [minconf=1]"},
|
|
|
|
"getbestblockhash": &handlerData{0, 0, displayGeneric, nil, makeGetBestBlockHash, ""},
|
|
|
|
"getblock": &handlerData{1, 2, displayJSONDump, []conversionHandler{nil, toBool, toBool}, makeGetBlock, "<blockhash>"},
|
|
|
|
"getblockcount": &handlerData{0, 0, displayGeneric, nil, makeGetBlockCount, ""},
|
|
|
|
"getblockhash": &handlerData{1, 0, displayGeneric, []conversionHandler{toInt64}, makeGetBlockHash, "<blocknumber>"},
|
|
|
|
"getblocktemplate": &handlerData{0, 1, displayJSONDump, nil, makeGetBlockTemplate, "[jsonrequestobject]"},
|
|
|
|
"getconnectioncount": &handlerData{0, 0, displayGeneric, nil, makeGetConnectionCount, ""},
|
|
|
|
"getdifficulty": &handlerData{0, 0, displayFloat64, nil, makeGetDifficulty, ""},
|
|
|
|
"getgenerate": &handlerData{0, 0, displayGeneric, nil, makeGetGenerate, ""},
|
|
|
|
"gethashespersec": &handlerData{0, 0, displayGeneric, nil, makeGetHashesPerSec, ""},
|
2014-01-29 02:24:30 +01:00
|
|
|
"getinfo": &handlerData{0, 0, displayJSONDump, nil, makeGetInfo, ""},
|
2014-01-27 21:19:39 +01:00
|
|
|
"getnewaddress": &handlerData{0, 1, displayGeneric, nil, makeGetNewAddress, "[account]"},
|
|
|
|
"getpeerinfo": &handlerData{0, 0, displayJSONDump, nil, makeGetPeerInfo, ""},
|
2014-01-30 18:19:04 +01:00
|
|
|
"getrawchangeaddress": &handlerData{0, 0, displayGeneric, nil, makeGetRawChangeAddress, ""},
|
2014-01-27 21:19:39 +01:00
|
|
|
"getrawmempool": &handlerData{0, 1, displayJSONDump, []conversionHandler{toBool}, makeGetRawMempool, "[verbose=false]"},
|
2014-01-30 03:21:58 +01:00
|
|
|
"getrawtransaction": &handlerData{1, 1, displayJSONDump, []conversionHandler{nil, toInt}, makeGetRawTransaction, "<txhash> [verbose=0]"},
|
2014-01-30 18:08:50 +01:00
|
|
|
"getreceivedbyaccount": &handlerData{1, 1, displayGeneric, []conversionHandler{nil, toInt}, makeGetReceivedByAccount, "<account> [minconf=1]"},
|
|
|
|
"getreceivedbyaddress": &handlerData{1, 1, displayGeneric, []conversionHandler{nil, toInt}, makeGetReceivedByAddress, "<address> [minconf=1]"},
|
2014-01-30 18:23:38 +01:00
|
|
|
"gettxoutsetinfo": &handlerData{0, 0, displayJSONDump, nil, makeGetTxOutSetInfo, ""},
|
2014-01-27 21:19:39 +01:00
|
|
|
"getwork": &handlerData{0, 1, displayJSONDump, nil, makeGetWork, "[jsonrequestobject]"},
|
|
|
|
"help": &handlerData{0, 1, displayGeneric, nil, makeHelp, "[commandName]"},
|
|
|
|
"importprivkey": &handlerData{1, 2, displayGeneric, []conversionHandler{nil, nil, toBool}, makeImportPrivKey, "<wifprivkey> [label] [rescan=true]"},
|
2014-01-28 03:11:59 +01:00
|
|
|
"keypoolrefill": &handlerData{0, 1, displayGeneric, []conversionHandler{toInt}, makeKeyPoolRefill, "[newsize]"},
|
2014-01-28 03:05:27 +01:00
|
|
|
"listaccounts": &handlerData{0, 1, displayJSONDump, []conversionHandler{toInt}, makeListAccounts, "[minconf=1]"},
|
2014-01-30 18:29:21 +01:00
|
|
|
"listaddressgroupings": &handlerData{0, 0, displayJSONDump, nil, makeListAddressGroupings, ""},
|
2014-01-30 19:10:43 +01:00
|
|
|
"listreceivedbyaccount": &handlerData{0, 2, displayJSONDump, []conversionHandler{toInt, toBool}, makeListReceivedByAccount, "[minconf] [includeempty]"},
|
|
|
|
"listreceivedbyaddress": &handlerData{0, 2, displayJSONDump, []conversionHandler{toInt, toBool}, makeListReceivedByAddress, "[minconf] [includeempty]"},
|
2014-01-30 18:31:56 +01:00
|
|
|
"listlockunspent": &handlerData{0, 0, displayJSONDump, nil, makeListLockUnspent, ""},
|
2014-01-27 18:42:56 +01:00
|
|
|
"listsinceblock": &handlerData{0, 2, displayJSONDump, []conversionHandler{nil, toInt}, makeListSinceBlock, "[blockhash] [minconf=10]"},
|
2014-01-27 21:19:39 +01:00
|
|
|
"listtransactions": &handlerData{0, 3, displayJSONDump, []conversionHandler{nil, toInt, toInt}, makeListTransactions, "[account] [count=10] [from=0]"},
|
2014-01-30 18:59:26 +01:00
|
|
|
"listunspent": &handlerData{0, 3, displayJSONDump, []conversionHandler{toInt, toInt, nil}, makeListUnspent, "[minconf=1] [maxconf=9999999] [jsonaddressarray]"},
|
2014-01-27 21:19:39 +01:00
|
|
|
"ping": &handlerData{0, 0, displayGeneric, nil, makePing, ""},
|
|
|
|
"sendfrom": &handlerData{3, 3, displayGeneric, []conversionHandler{nil, nil, toSatoshi, toInt, nil, nil},
|
|
|
|
makeSendFrom, "<account> <address> <amount> [minconf=1] [comment] [comment-to]"},
|
2014-01-27 21:57:44 +01:00
|
|
|
"sendmany": &handlerData{2, 2, displayGeneric, []conversionHandler{nil, nil, toInt, nil}, makeSendMany, "<account> <{\"address\":amount,...}> [minconf=1] [comment]"},
|
2014-01-27 19:39:01 +01:00
|
|
|
"sendrawtransaction": &handlerData{1, 0, displayGeneric, nil, makeSendRawTransaction, "<hextx>"},
|
2014-01-27 22:31:48 +01:00
|
|
|
"settxfee": &handlerData{1, 0, displayGeneric, []conversionHandler{toSatoshi}, makeSetTxFee, "<amount>"},
|
2014-01-27 19:39:01 +01:00
|
|
|
"stop": &handlerData{0, 0, displayGeneric, nil, makeStop, ""},
|
|
|
|
"submitblock": &handlerData{1, 1, displayGeneric, nil, makeSubmitBlock, "<hexdata> [jsonparametersobject]"},
|
2014-01-30 19:14:28 +01:00
|
|
|
"validateaddress": &handlerData{1, 0, displayJSONDump, nil, makeValidateAddress, "<address>"},
|
2014-01-27 19:39:01 +01:00
|
|
|
"verifychain": &handlerData{0, 2, displayJSONDump, []conversionHandler{toInt, toInt}, makeVerifyChain, "[level] [numblocks]"},
|
2014-01-27 19:44:31 +01:00
|
|
|
"walletlock": &handlerData{0, 0, displayGeneric, nil, makeWalletLock, ""},
|
2014-01-27 19:39:01 +01:00
|
|
|
"walletpassphrase": &handlerData{1, 1, displayGeneric, []conversionHandler{nil, toInt64}, makeWalletPassphrase, "<passphrase> [timeout]"},
|
|
|
|
"walletpassphrasechange": &handlerData{2, 0, displayGeneric, nil, makeWalletPassphraseChange, "<oldpassphrase> <newpassphrase>"},
|
2013-10-22 05:56:02 +02:00
|
|
|
}
|
2013-10-17 01:19:26 +02:00
|
|
|
|
2014-01-27 21:19:39 +01:00
|
|
|
// toSatoshi attempts to convert the passed string to a satoshi amount returned
|
|
|
|
// as an int64. It returns the int64 packed into an interface so it can be used
|
|
|
|
// in the calls which expect interfaces. An error will be returned if the string
|
|
|
|
// can't be converted first to a float64.
|
|
|
|
func toSatoshi(val string) (interface{}, error) {
|
|
|
|
idx, err := strconv.ParseFloat(val, 64)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return int64(float64(btcutil.SatoshiPerBitcoin) * idx), nil
|
|
|
|
}
|
|
|
|
|
2013-10-22 07:38:51 +02:00
|
|
|
// toInt attempts to convert the passed string to an integer. It returns the
|
|
|
|
// integer packed into an interface so it can be used in the calls which expect
|
2013-10-22 05:56:02 +02:00
|
|
|
// interfaces. An error will be returned if the string can't be converted to an
|
|
|
|
// integer.
|
|
|
|
func toInt(val string) (interface{}, error) {
|
|
|
|
idx, err := strconv.Atoi(val)
|
2013-10-17 01:19:26 +02:00
|
|
|
if err != nil {
|
2013-10-22 05:56:02 +02:00
|
|
|
return nil, err
|
2013-10-17 01:19:26 +02:00
|
|
|
}
|
2013-10-09 03:18:49 +02:00
|
|
|
|
2013-10-22 05:56:02 +02:00
|
|
|
return idx, nil
|
|
|
|
}
|
2013-10-09 03:18:49 +02:00
|
|
|
|
2013-11-08 00:07:26 +01:00
|
|
|
// toInt64 attempts to convert the passed string to an int64. It returns the
|
|
|
|
// integer packed into an interface so it can be used in the calls which expect
|
|
|
|
// interfaces. An error will be returned if the string can't be converted to an
|
|
|
|
// integer.
|
|
|
|
func toInt64(val string) (interface{}, error) {
|
|
|
|
idx, err := strconv.ParseInt(val, 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return idx, nil
|
|
|
|
}
|
|
|
|
|
2013-11-18 20:51:31 +01:00
|
|
|
// toBool attempts to convert the passed string to a bool. It returns the
|
|
|
|
// bool packed into the empty interface so it can be used in the calls which
|
|
|
|
// accept interfaces. An error will be returned if the string can't be
|
|
|
|
// converted to a bool.
|
|
|
|
func toBool(val string) (interface{}, error) {
|
|
|
|
return strconv.ParseBool(val)
|
|
|
|
}
|
|
|
|
|
2013-10-22 05:56:02 +02:00
|
|
|
// displayGeneric is a displayHandler that simply displays the passed interface
|
|
|
|
// using fmt.Println.
|
|
|
|
func displayGeneric(reply interface{}) error {
|
|
|
|
fmt.Println(reply)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// displayFloat64 is a displayHandler that ensures the concrete type of the
|
|
|
|
// passed interface is a float64 and displays it using fmt.Println. An error
|
|
|
|
// is returned if a float64 is not passed.
|
|
|
|
func displayFloat64(reply interface{}) error {
|
|
|
|
if val, ok := reply.(float64); ok {
|
2013-12-26 00:47:56 +01:00
|
|
|
fmt.Printf("%f\n", val)
|
2013-10-22 05:56:02 +02:00
|
|
|
return nil
|
2013-10-09 03:18:49 +02:00
|
|
|
}
|
2013-10-22 05:56:02 +02:00
|
|
|
|
|
|
|
return fmt.Errorf("reply type is not a float64: %v", spew.Sdump(reply))
|
|
|
|
}
|
|
|
|
|
|
|
|
// displaySpewDump is a displayHandler that simply uses spew.Dump to display the
|
|
|
|
// passed interface.
|
|
|
|
func displaySpewDump(reply interface{}) error {
|
|
|
|
spew.Dump(reply)
|
|
|
|
return nil
|
2013-10-09 03:18:49 +02:00
|
|
|
}
|
|
|
|
|
2013-12-26 06:17:03 +01:00
|
|
|
// displayJSONDump is a displayHandler that uses json.Indent to display the
|
|
|
|
// passed interface.
|
|
|
|
func displayJSONDump(reply interface{}) error {
|
|
|
|
marshaledBytes, err := json.Marshal(reply)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var buf bytes.Buffer
|
|
|
|
err = json.Indent(&buf, marshaledBytes, "", "\t")
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
fmt.Println(buf.String())
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-01-23 20:21:41 +01:00
|
|
|
// makeAddNode generates the cmd structure for addnode commands.
|
2013-10-28 17:45:44 +01:00
|
|
|
func makeAddNode(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewAddNodeCmd("btcctl", args[0].(string),
|
|
|
|
args[1].(string))
|
|
|
|
}
|
|
|
|
|
2014-01-02 20:48:06 +01:00
|
|
|
// makeCreateRawTransaction generates the cmd structure for createrawtransaction
|
2014-01-23 20:21:41 +01:00
|
|
|
// commands.
|
2014-01-02 20:48:06 +01:00
|
|
|
func makeCreateRawTransaction(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
// First unmarshal the JSON provided by the parameters into interfaces.
|
|
|
|
var iinputs, iamounts interface{}
|
|
|
|
err := json.Unmarshal([]byte(args[0].(string)), &iinputs)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
err = json.Unmarshal([]byte(args[1].(string)), &iamounts)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate and convert the interfaces to concrete types.
|
|
|
|
inputs, amounts, err := btcjson.ConvertCreateRawTxParams(iinputs,
|
|
|
|
iamounts)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return btcjson.NewCreateRawTransactionCmd("btcctl", inputs, amounts)
|
|
|
|
}
|
|
|
|
|
2013-11-22 17:46:56 +01:00
|
|
|
// makeDebugLevel generates the cmd structure for debuglevel commands.
|
|
|
|
func makeDebugLevel(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewDebugLevelCmd("btcctl", args[0].(string))
|
|
|
|
}
|
|
|
|
|
2013-10-28 17:45:44 +01:00
|
|
|
// makeDecodeRawTransaction generates the cmd structure for
|
2014-01-23 20:21:41 +01:00
|
|
|
// decoderawtransaction commands.
|
2013-10-28 17:45:44 +01:00
|
|
|
func makeDecodeRawTransaction(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewDecodeRawTransactionCmd("btcctl", args[0].(string))
|
|
|
|
}
|
|
|
|
|
2014-01-23 20:21:41 +01:00
|
|
|
// makeDecodeScript generates the cmd structure for decodescript commands.
|
2014-01-04 06:30:08 +01:00
|
|
|
func makeDecodeScript(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewDecodeScriptCmd("btcctl", args[0].(string))
|
|
|
|
}
|
|
|
|
|
2013-11-20 04:35:52 +01:00
|
|
|
// makeDumpPrivKey generates the cmd structure for
|
|
|
|
// dumpprivkey commands.
|
|
|
|
func makeDumpPrivKey(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewDumpPrivKeyCmd("btcctl", args[0].(string))
|
|
|
|
}
|
|
|
|
|
2013-12-30 22:31:47 +01:00
|
|
|
// makeGetAccount generates the cmd structure for
|
2013-12-30 22:32:25 +01:00
|
|
|
// getaccount commands.
|
2013-12-30 22:31:47 +01:00
|
|
|
func makeGetAccount(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetAccountCmd("btcctl", args[0].(string))
|
|
|
|
}
|
|
|
|
|
2013-12-31 19:11:01 +01:00
|
|
|
// makeGetAccountAddress generates the cmd structure for
|
|
|
|
// getaccountaddress commands.
|
|
|
|
func makeGetAccountAddress(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetAccountAddressCmd("btcctl", args[0].(string))
|
|
|
|
}
|
|
|
|
|
2014-01-24 21:10:13 +01:00
|
|
|
// makeGetAddedNodeInfo generates the cmd structure for
|
|
|
|
// getaccountaddress commands.
|
|
|
|
func makeGetAddedNodeInfo(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
// Create the getaddednodeinfo command with defaults for the optional
|
|
|
|
// parameters.
|
|
|
|
cmd, err := btcjson.NewGetAddedNodeInfoCmd("btcctl", args[0].(bool))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Override the optional parameter if it was specified.
|
|
|
|
if len(args) > 1 {
|
|
|
|
cmd.Node = args[1].(string)
|
|
|
|
}
|
|
|
|
|
|
|
|
return cmd, nil
|
|
|
|
}
|
|
|
|
|
2014-01-27 19:32:36 +01:00
|
|
|
// makeGetAddressesByAccount generates the cmd structure for
|
|
|
|
// getaddressesbyaccount commands.
|
|
|
|
func makeGetAddressesByAccount(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetAddressesByAccountCmd("btcctl", args[0].(string))
|
|
|
|
}
|
|
|
|
|
2013-11-22 19:10:14 +01:00
|
|
|
// makeGetBalance generates the cmd structure for
|
|
|
|
// getbalance commands.
|
|
|
|
func makeGetBalance(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
optargs := make([]interface{}, 0, 2)
|
|
|
|
if len(args) > 0 {
|
|
|
|
optargs = append(optargs, args[0].(string))
|
|
|
|
}
|
|
|
|
if len(args) > 1 {
|
|
|
|
optargs = append(optargs, args[1].(int))
|
|
|
|
}
|
|
|
|
|
|
|
|
return btcjson.NewGetBalanceCmd("btcctl", optargs...)
|
|
|
|
}
|
|
|
|
|
2013-10-28 17:45:44 +01:00
|
|
|
// makeGetBestBlockHash generates the cmd structure for
|
2014-01-23 20:21:41 +01:00
|
|
|
// makebestblockhash commands.
|
2013-10-28 17:45:44 +01:00
|
|
|
func makeGetBestBlockHash(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetBestBlockHashCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
2014-01-23 20:21:41 +01:00
|
|
|
// makeGetBlock generates the cmd structure for getblock commands.
|
2013-10-28 17:45:44 +01:00
|
|
|
func makeGetBlock(args []interface{}) (btcjson.Cmd, error) {
|
2013-12-26 18:19:32 +01:00
|
|
|
// Create the getblock command with defaults for the optional
|
|
|
|
// parameters.
|
|
|
|
getBlockCmd, err := btcjson.NewGetBlockCmd("btcctl", args[0].(string))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Override the optional parameters if they were specified.
|
|
|
|
if len(args) > 1 {
|
|
|
|
getBlockCmd.Verbose = args[1].(bool)
|
|
|
|
}
|
|
|
|
if len(args) > 2 {
|
|
|
|
getBlockCmd.VerboseTx = args[2].(bool)
|
|
|
|
}
|
|
|
|
|
|
|
|
return getBlockCmd, nil
|
2013-10-28 17:45:44 +01:00
|
|
|
}
|
|
|
|
|
2014-01-23 20:21:41 +01:00
|
|
|
// makeGetBlockCount generates the cmd structure for getblockcount commands.
|
2013-10-28 17:45:44 +01:00
|
|
|
func makeGetBlockCount(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetBlockCountCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
2014-01-23 20:21:41 +01:00
|
|
|
// makeGetBlockHash generates the cmd structure for getblockhash commands.
|
2013-10-28 17:45:44 +01:00
|
|
|
func makeGetBlockHash(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetBlockHashCmd("btcctl", args[0].(int64))
|
|
|
|
}
|
|
|
|
|
2014-01-23 19:44:28 +01:00
|
|
|
// makeGetBlockTemplate generates the cmd structure for getblocktemplate commands.
|
|
|
|
func makeGetBlockTemplate(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
cmd, err := btcjson.NewGetBlockTemplateCmd("btcctl")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if len(args) == 1 {
|
|
|
|
err = cmd.UnmarshalJSON([]byte(args[0].(string)))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cmd, nil
|
|
|
|
}
|
|
|
|
|
2013-10-28 17:45:44 +01:00
|
|
|
// makeGetConnectionCount generates the cmd structure for
|
2014-01-23 20:21:41 +01:00
|
|
|
// getconnectioncount commands.
|
2013-10-28 17:45:44 +01:00
|
|
|
func makeGetConnectionCount(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetConnectionCountCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
|
|
|
// makeGetDifficulty generates the cmd structure for
|
2014-01-23 20:21:41 +01:00
|
|
|
// getdifficulty commands.
|
2013-10-28 17:45:44 +01:00
|
|
|
func makeGetDifficulty(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetDifficultyCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
|
|
|
// makeGetGenerate generates the cmd structure for
|
2014-01-23 20:21:41 +01:00
|
|
|
// getgenerate commands.
|
2013-10-28 17:45:44 +01:00
|
|
|
func makeGetGenerate(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetGenerateCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
2014-01-23 20:21:41 +01:00
|
|
|
// makeGetHashesPerSec generates the cmd structure for gethashespersec commands.
|
2013-12-26 02:13:14 +01:00
|
|
|
func makeGetHashesPerSec(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetHashesPerSecCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
2014-01-29 02:24:30 +01:00
|
|
|
// makeGetInfo generates the cmd structure for getinfo commands.
|
|
|
|
func makeGetInfo(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetInfoCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
2014-01-27 18:35:20 +01:00
|
|
|
// makeGetNewAddress generates the cmd structure for getnewaddress commands.
|
|
|
|
func makeGetNewAddress(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
var account string
|
|
|
|
if len(args) > 0 {
|
|
|
|
account = args[0].(string)
|
|
|
|
}
|
|
|
|
return btcjson.NewGetNewAddressCmd("btcctl", account)
|
|
|
|
}
|
|
|
|
|
2013-10-28 17:45:44 +01:00
|
|
|
// makePeerInfo generates the cmd structure for
|
2014-01-23 20:21:41 +01:00
|
|
|
// getpeerinfo commands.
|
2013-10-28 17:45:44 +01:00
|
|
|
func makeGetPeerInfo(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetPeerInfoCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
2014-01-30 18:19:04 +01:00
|
|
|
// makeGetRawChangeAddress generates the cmd structure for getrawchangeaddress commands.
|
|
|
|
func makeGetRawChangeAddress(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetRawChangeAddressCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
2013-10-28 17:45:44 +01:00
|
|
|
// makeRawMempool generates the cmd structure for
|
2014-01-23 20:21:41 +01:00
|
|
|
// getrawmempool commands.
|
2013-10-28 17:45:44 +01:00
|
|
|
func makeGetRawMempool(args []interface{}) (btcjson.Cmd, error) {
|
2013-12-11 18:32:16 +01:00
|
|
|
opt := make([]bool, 0, 1)
|
|
|
|
if len(args) > 0 {
|
|
|
|
opt = append(opt, args[0].(bool))
|
|
|
|
}
|
|
|
|
return btcjson.NewGetRawMempoolCmd("btcctl", opt...)
|
2013-10-28 17:45:44 +01:00
|
|
|
}
|
|
|
|
|
2014-01-30 18:08:50 +01:00
|
|
|
// makeGetReceivedByAccount generates the cmd structure for
|
|
|
|
// getreceivedbyaccount commands.
|
|
|
|
func makeGetReceivedByAccount(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
opt := make([]int, 0, 1)
|
|
|
|
if len(args) > 1 {
|
|
|
|
opt = append(opt, args[1].(int))
|
|
|
|
}
|
|
|
|
return btcjson.NewGetReceivedByAccountCmd("btcctl", args[0].(string), opt...)
|
|
|
|
}
|
|
|
|
|
|
|
|
// makeGetReceivedByAddress generates the cmd structure for
|
|
|
|
// getreceivedbyaddress commands.
|
|
|
|
func makeGetReceivedByAddress(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
opt := make([]int, 0, 1)
|
|
|
|
if len(args) > 1 {
|
|
|
|
opt = append(opt, args[1].(int))
|
|
|
|
}
|
|
|
|
return btcjson.NewGetReceivedByAddressCmd("btcctl", args[0].(string), opt...)
|
|
|
|
}
|
|
|
|
|
2014-01-30 18:23:38 +01:00
|
|
|
// makeGetTxOutSetInfo generates the cmd structure for gettxoutsetinfo commands.
|
|
|
|
func makeGetTxOutSetInfo(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewGetTxOutSetInfoCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
2014-01-23 21:57:15 +01:00
|
|
|
func makeGetWork(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
cmd, err := btcjson.NewGetWorkCmd("btcctl")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if len(args) == 1 {
|
|
|
|
err = cmd.UnmarshalJSON([]byte(args[0].(string)))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cmd, nil
|
|
|
|
}
|
|
|
|
|
2014-01-16 15:45:17 +01:00
|
|
|
func makeHelp(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
opt := make([]string, 0, 1)
|
|
|
|
if len(args) > 0 {
|
|
|
|
opt = append(opt, args[0].(string))
|
|
|
|
}
|
|
|
|
return btcjson.NewHelpCmd("btcctl", opt...)
|
|
|
|
}
|
|
|
|
|
2013-10-28 17:45:44 +01:00
|
|
|
// makeRawTransaction generates the cmd structure for
|
2014-01-23 20:21:41 +01:00
|
|
|
// getrawtransaction commands.
|
2013-10-28 17:45:44 +01:00
|
|
|
func makeGetRawTransaction(args []interface{}) (btcjson.Cmd, error) {
|
2014-01-30 03:21:58 +01:00
|
|
|
opt := make([]int, 0, 1)
|
2013-11-14 19:19:20 +01:00
|
|
|
if len(args) > 1 {
|
2014-01-30 03:21:58 +01:00
|
|
|
opt = append(opt, args[1].(int))
|
2013-11-14 19:19:20 +01:00
|
|
|
}
|
2013-10-28 17:45:44 +01:00
|
|
|
|
2013-12-11 18:33:24 +01:00
|
|
|
return btcjson.NewGetRawTransactionCmd("btcctl", args[0].(string), opt...)
|
2013-10-28 17:45:44 +01:00
|
|
|
}
|
|
|
|
|
2013-11-18 20:51:31 +01:00
|
|
|
// makeImportPrivKey generates the cmd structure for
|
|
|
|
// importprivkey commands.
|
|
|
|
func makeImportPrivKey(args []interface{}) (btcjson.Cmd, error) {
|
2013-11-20 17:12:00 +01:00
|
|
|
var optargs = make([]interface{}, 0, 2)
|
2013-11-18 20:51:31 +01:00
|
|
|
if len(args) > 1 {
|
2013-11-20 17:12:00 +01:00
|
|
|
optargs = append(optargs, args[1].(string))
|
2013-11-18 20:51:31 +01:00
|
|
|
}
|
|
|
|
if len(args) > 2 {
|
2013-11-20 17:12:00 +01:00
|
|
|
optargs = append(optargs, args[2].(bool))
|
2013-11-18 20:51:31 +01:00
|
|
|
}
|
|
|
|
|
2013-11-20 17:12:00 +01:00
|
|
|
return btcjson.NewImportPrivKeyCmd("btcctl", args[0].(string), optargs...)
|
2013-11-18 20:51:31 +01:00
|
|
|
}
|
|
|
|
|
2014-01-28 03:11:59 +01:00
|
|
|
// makeKeyPoolRefill generates the cmd structure for keypoolrefill commands.
|
|
|
|
func makeKeyPoolRefill(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
var optargs = make([]uint, 0, 1)
|
|
|
|
if len(args) > 0 {
|
|
|
|
optargs = append(optargs, uint(args[0].(int)))
|
|
|
|
}
|
|
|
|
|
|
|
|
return btcjson.NewKeyPoolRefillCmd("btcctl", optargs...)
|
|
|
|
}
|
|
|
|
|
2014-01-28 03:05:27 +01:00
|
|
|
// makeListAccounts generates the cmd structure for listaccounts commands.
|
|
|
|
func makeListAccounts(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
var optargs = make([]int, 0, 1)
|
|
|
|
if len(args) > 0 {
|
|
|
|
optargs = append(optargs, args[0].(int))
|
|
|
|
}
|
|
|
|
return btcjson.NewListAccountsCmd("btcctl", optargs...)
|
|
|
|
}
|
|
|
|
|
2014-01-30 18:29:21 +01:00
|
|
|
// makeListAddressGroupings generates the cmd structure for listaddressgroupings commands.
|
|
|
|
func makeListAddressGroupings(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewListAddressGroupingsCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
2014-01-30 19:10:43 +01:00
|
|
|
// makeListReceivedByAccount generates the cmd structure for listreceivedbyaccount commands.
|
|
|
|
func makeListReceivedByAccount(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
var optargs = make([]interface{}, 0, 2)
|
|
|
|
if len(args) > 0 {
|
|
|
|
optargs = append(optargs, args[0].(int))
|
|
|
|
}
|
|
|
|
if len(args) > 1 {
|
|
|
|
optargs = append(optargs, args[1].(bool))
|
|
|
|
}
|
|
|
|
return btcjson.NewListReceivedByAccountCmd("btcctl", optargs...)
|
|
|
|
}
|
|
|
|
|
|
|
|
// makeListReceivedByAddress generates the cmd structure for listreceivedbyaddress commands.
|
|
|
|
func makeListReceivedByAddress(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
var optargs = make([]interface{}, 0, 2)
|
|
|
|
if len(args) > 0 {
|
|
|
|
optargs = append(optargs, args[0].(int))
|
|
|
|
}
|
|
|
|
if len(args) > 1 {
|
|
|
|
optargs = append(optargs, args[1].(bool))
|
|
|
|
}
|
|
|
|
return btcjson.NewListReceivedByAddressCmd("btcctl", optargs...)
|
|
|
|
}
|
|
|
|
|
2014-01-30 18:31:56 +01:00
|
|
|
// makeListLockUnspent generates the cmd structure for listlockunspent commands.
|
|
|
|
func makeListLockUnspent(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewListLockUnspentCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
2014-01-27 18:42:56 +01:00
|
|
|
// makeListSinceBlock generates the cmd structure for
|
|
|
|
// listsinceblock commands.
|
|
|
|
func makeListSinceBlock(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
var optargs = make([]interface{}, 0, 2)
|
|
|
|
if len(args) > 0 {
|
|
|
|
optargs = append(optargs, args[0].(string))
|
|
|
|
}
|
|
|
|
if len(args) > 1 {
|
|
|
|
optargs = append(optargs, args[1].(int))
|
|
|
|
}
|
|
|
|
|
|
|
|
return btcjson.NewListSinceBlockCmd("btcctl", optargs...)
|
|
|
|
}
|
|
|
|
|
2013-11-22 19:12:53 +01:00
|
|
|
// makeListTransactions generates the cmd structure for
|
|
|
|
// listtransactions commands.
|
|
|
|
func makeListTransactions(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
var optargs = make([]interface{}, 0, 3)
|
2013-11-26 22:21:19 +01:00
|
|
|
if len(args) > 0 {
|
2013-11-22 19:12:53 +01:00
|
|
|
optargs = append(optargs, args[0].(string))
|
|
|
|
}
|
2013-11-26 22:21:19 +01:00
|
|
|
if len(args) > 1 {
|
2013-11-22 19:12:53 +01:00
|
|
|
optargs = append(optargs, args[1].(int))
|
|
|
|
}
|
2013-11-26 22:21:19 +01:00
|
|
|
if len(args) > 2 {
|
2013-11-22 19:12:53 +01:00
|
|
|
optargs = append(optargs, args[2].(int))
|
|
|
|
}
|
|
|
|
|
|
|
|
return btcjson.NewListTransactionsCmd("btcctl", optargs...)
|
|
|
|
}
|
|
|
|
|
2014-01-30 18:59:26 +01:00
|
|
|
// makeListUnspent generates the cmd structure for listunspent commands.
|
|
|
|
func makeListUnspent(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
var optargs = make([]interface{}, 0, 3)
|
|
|
|
if len(args) > 0 {
|
|
|
|
optargs = append(optargs, args[0].(int))
|
|
|
|
}
|
|
|
|
if len(args) > 1 {
|
|
|
|
optargs = append(optargs, args[1].(int))
|
|
|
|
}
|
|
|
|
if len(args) > 2 {
|
|
|
|
var addrs []string
|
|
|
|
err := json.Unmarshal([]byte(args[2].(string)), &addrs)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
optargs = append(optargs, addrs)
|
|
|
|
}
|
|
|
|
return btcjson.NewListUnspentCmd("btcctl", optargs...)
|
|
|
|
}
|
|
|
|
|
2014-01-21 16:03:15 +01:00
|
|
|
// makePing generates the cmd structure for ping commands.
|
|
|
|
func makePing(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewPingCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
2014-01-27 21:19:39 +01:00
|
|
|
// makeSendFrom generates the cmd structure for sendfrom commands.
|
|
|
|
func makeSendFrom(args []interface{}) (btcjson.Cmd, error) {
|
2014-01-28 03:31:33 +01:00
|
|
|
var optargs = make([]interface{}, 0, 3)
|
2014-01-27 21:19:39 +01:00
|
|
|
if len(args) > 3 {
|
2014-01-28 03:31:33 +01:00
|
|
|
optargs = append(optargs, args[3].(int))
|
2014-01-27 21:19:39 +01:00
|
|
|
}
|
|
|
|
if len(args) > 4 {
|
2014-01-28 03:31:33 +01:00
|
|
|
optargs = append(optargs, args[4].(string))
|
2014-01-27 21:19:39 +01:00
|
|
|
}
|
|
|
|
if len(args) > 5 {
|
2014-01-28 03:31:33 +01:00
|
|
|
optargs = append(optargs, args[5].(string))
|
2014-01-27 21:19:39 +01:00
|
|
|
}
|
2014-01-28 03:31:33 +01:00
|
|
|
return btcjson.NewSendFromCmd("btcctl", args[0].(string),
|
|
|
|
args[1].(string), args[2].(int64), optargs...)
|
2014-01-27 21:19:39 +01:00
|
|
|
}
|
|
|
|
|
2014-01-27 21:57:44 +01:00
|
|
|
// makeSendMany generates the cmd structure for sendmany commands.
|
|
|
|
func makeSendMany(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
origPairs := make(map[string]float64)
|
|
|
|
err := json.Unmarshal([]byte(args[1].(string)), &origPairs)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
pairs := make(map[string]int64)
|
|
|
|
for addr, value := range origPairs {
|
|
|
|
pairs[addr] = int64(float64(btcutil.SatoshiPerBitcoin) * value)
|
|
|
|
}
|
|
|
|
|
2014-01-28 03:31:33 +01:00
|
|
|
var optargs = make([]interface{}, 0, 2)
|
2014-01-27 21:57:44 +01:00
|
|
|
if len(args) > 2 {
|
2014-01-28 03:31:33 +01:00
|
|
|
optargs = append(optargs, args[2].(int))
|
2014-01-27 21:57:44 +01:00
|
|
|
}
|
|
|
|
if len(args) > 3 {
|
2014-01-28 03:31:33 +01:00
|
|
|
optargs = append(optargs, args[3].(string))
|
2014-01-27 21:57:44 +01:00
|
|
|
}
|
2014-01-28 03:31:33 +01:00
|
|
|
return btcjson.NewSendManyCmd("btcctl", args[0].(string), pairs, optargs...)
|
2014-01-27 21:57:44 +01:00
|
|
|
}
|
|
|
|
|
2014-01-06 17:50:02 +01:00
|
|
|
// makeSendRawTransaction generates the cmd structure for sendrawtransaction
|
|
|
|
// commands.
|
|
|
|
func makeSendRawTransaction(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewSendRawTransactionCmd("btcctl", args[0].(string))
|
|
|
|
}
|
|
|
|
|
2014-01-27 22:31:48 +01:00
|
|
|
// makeSetTxFee generates the cmd structure for settxfee commands.
|
|
|
|
func makeSetTxFee(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewSetTxFeeCmd("btcctl", args[0].(int64))
|
|
|
|
}
|
|
|
|
|
2014-01-23 20:21:41 +01:00
|
|
|
// makeStop generates the cmd structure for stop commands.
|
2013-10-28 17:45:44 +01:00
|
|
|
func makeStop(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewStopCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
2014-01-15 16:01:12 +01:00
|
|
|
// makeSubmitBlock generates the cmd structure for submitblock commands.
|
|
|
|
func makeSubmitBlock(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
opts := &btcjson.SubmitBlockOptions{}
|
|
|
|
if len(args) == 2 {
|
|
|
|
opts.WorkId = args[1].(string)
|
|
|
|
}
|
|
|
|
|
|
|
|
return btcjson.NewSubmitBlockCmd("btcctl", args[0].(string), opts)
|
|
|
|
}
|
|
|
|
|
2014-01-30 19:14:28 +01:00
|
|
|
// makeValidateAddress generates the cmd structure for validateaddress commands.
|
|
|
|
func makeValidateAddress(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewValidateAddressCmd("btcctl", args[0].(string))
|
|
|
|
}
|
|
|
|
|
2014-01-23 20:21:41 +01:00
|
|
|
// makeVerifyChain generates the cmd structure for verifychain commands.
|
2013-11-12 17:39:10 +01:00
|
|
|
func makeVerifyChain(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
iargs := make([]int32, 0, 2)
|
|
|
|
for _, i := range args {
|
|
|
|
iargs = append(iargs, int32(i.(int)))
|
|
|
|
}
|
|
|
|
return btcjson.NewVerifyChainCmd("btcctl", iargs...)
|
|
|
|
}
|
|
|
|
|
2014-01-27 19:44:31 +01:00
|
|
|
// makeWalletLock generates the cmd structure for walletlock commands.
|
|
|
|
func makeWalletLock(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewWalletLockCmd("btcctl")
|
|
|
|
}
|
|
|
|
|
2014-01-27 18:49:54 +01:00
|
|
|
// makeWalletPassphrase generates the cmd structure for walletpassphrase commands.
|
|
|
|
func makeWalletPassphrase(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
timeout := int64(60)
|
|
|
|
if len(args) > 1 {
|
|
|
|
timeout = args[1].(int64)
|
|
|
|
}
|
|
|
|
return btcjson.NewWalletPassphraseCmd("btcctl", args[0].(string), timeout)
|
|
|
|
}
|
|
|
|
|
2014-01-27 19:39:01 +01:00
|
|
|
// makeWalletPassphraseChange generates the cmd structure for
|
|
|
|
// walletpassphrasechange commands.
|
|
|
|
func makeWalletPassphraseChange(args []interface{}) (btcjson.Cmd, error) {
|
|
|
|
return btcjson.NewWalletPassphraseChangeCmd("btcctl", args[0].(string),
|
|
|
|
args[1].(string))
|
|
|
|
}
|
|
|
|
|
2013-10-22 05:56:02 +02:00
|
|
|
// send sends a JSON-RPC command to the specified RPC server and examines the
|
|
|
|
// results for various error conditions. It either returns a valid result or
|
|
|
|
// an appropriate error.
|
2013-10-17 01:19:26 +02:00
|
|
|
func send(cfg *config, msg []byte) (interface{}, error) {
|
2013-11-07 17:25:11 +01:00
|
|
|
var reply btcjson.Reply
|
|
|
|
var err error
|
2013-11-27 02:13:31 +01:00
|
|
|
if cfg.NoTls || (cfg.RPCCert == "" && !cfg.TlsSkipVerify) {
|
|
|
|
reply, err = btcjson.RpcCommand(cfg.RPCUser, cfg.RPCPassword,
|
|
|
|
cfg.RPCServer, msg)
|
|
|
|
} else {
|
2013-11-07 17:25:11 +01:00
|
|
|
var pem []byte
|
2013-11-20 03:35:49 +01:00
|
|
|
if cfg.RPCCert != "" {
|
|
|
|
pem, err = ioutil.ReadFile(cfg.RPCCert)
|
2013-11-07 17:25:11 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
2013-11-20 03:35:49 +01:00
|
|
|
reply, err = btcjson.TlsRpcCommand(cfg.RPCUser,
|
|
|
|
cfg.RPCPassword, cfg.RPCServer, msg, pem,
|
2013-11-07 17:25:11 +01:00
|
|
|
cfg.TlsSkipVerify)
|
|
|
|
}
|
2013-10-09 03:18:49 +02:00
|
|
|
if err != nil {
|
2013-10-21 18:59:07 +02:00
|
|
|
return nil, err
|
|
|
|
}
|
2013-10-22 05:56:02 +02:00
|
|
|
|
2013-10-21 18:59:07 +02:00
|
|
|
if reply.Error != nil {
|
|
|
|
return nil, reply.Error
|
2013-10-09 03:18:49 +02:00
|
|
|
}
|
2013-10-22 05:56:02 +02:00
|
|
|
|
2013-10-09 03:18:49 +02:00
|
|
|
if reply.Result == nil {
|
2013-10-22 05:56:02 +02:00
|
|
|
return nil, ErrNoData
|
2013-10-09 03:18:49 +02:00
|
|
|
}
|
2013-10-22 05:56:02 +02:00
|
|
|
|
2013-10-09 03:18:49 +02:00
|
|
|
return reply.Result, nil
|
|
|
|
}
|
|
|
|
|
2013-10-22 05:56:02 +02:00
|
|
|
// sendCommand creates a JSON-RPC command using the passed command and arguments
|
|
|
|
// and then sends it. A prefix is added to any errors that occur indicating
|
|
|
|
// what step failed.
|
2013-10-28 17:45:44 +01:00
|
|
|
func sendCommand(cfg *config, command btcjson.Cmd) (interface{}, error) {
|
|
|
|
msg, err := json.Marshal(command)
|
2013-10-22 05:56:02 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("CreateMessage: %v", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
reply, err := send(cfg, msg)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("RpcCommand: %v", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
return reply, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// commandHandler handles commands provided via the cli using the specific
|
|
|
|
// handler data to instruct the handler what to do.
|
|
|
|
func commandHandler(cfg *config, command string, data *handlerData, args []string) error {
|
|
|
|
// Ensure the number of arguments are the expected value.
|
|
|
|
if len(args) < data.requiredArgs {
|
|
|
|
return ErrUsage
|
|
|
|
}
|
|
|
|
if len(args) > data.requiredArgs+data.optionalArgs {
|
|
|
|
return ErrUsage
|
|
|
|
}
|
|
|
|
|
2013-10-22 07:38:51 +02:00
|
|
|
// Ensure there is a display handler.
|
|
|
|
if data.displayHandler == nil {
|
|
|
|
return ErrNoDisplayHandler
|
|
|
|
}
|
|
|
|
|
2013-10-22 05:56:02 +02:00
|
|
|
// Ensure the number of conversion handlers is valid if any are
|
|
|
|
// specified.
|
|
|
|
convHandlers := data.conversionHandlers
|
|
|
|
if convHandlers != nil && len(convHandlers) < len(args) {
|
|
|
|
return fmt.Errorf("The number of conversion handlers is invalid.")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert input parameters per the conversion handlers.
|
|
|
|
iargs := make([]interface{}, len(args))
|
|
|
|
for i, arg := range args {
|
|
|
|
iargs[i] = arg
|
|
|
|
}
|
|
|
|
for i := range iargs {
|
2013-10-22 06:03:11 +02:00
|
|
|
if convHandlers != nil {
|
|
|
|
converter := convHandlers[i]
|
|
|
|
if converter != nil {
|
|
|
|
convertedArg, err := converter(args[i])
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
iargs[i] = convertedArg
|
2013-10-22 05:56:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-10-28 17:45:44 +01:00
|
|
|
cmd, err := data.makeCmd(iargs)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2013-10-22 05:56:02 +02:00
|
|
|
|
|
|
|
// Create and send the appropriate JSON-RPC command.
|
2013-10-28 17:45:44 +01:00
|
|
|
reply, err := sendCommand(cfg, cmd)
|
2013-10-22 05:56:02 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2013-10-22 07:38:51 +02:00
|
|
|
// Display the results of the JSON-RPC command using the provided
|
|
|
|
// display handler.
|
2013-10-22 05:56:02 +02:00
|
|
|
err = data.displayHandler(reply)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// usage displays the command usage.
|
2013-10-17 01:19:26 +02:00
|
|
|
func usage(parser *flags.Parser) {
|
|
|
|
parser.WriteHelp(os.Stderr)
|
2013-10-22 17:56:56 +02:00
|
|
|
|
|
|
|
// Extract usage information for each command from the command handler
|
|
|
|
// data and sort by command name.
|
|
|
|
fmt.Fprintf(os.Stderr, "\nCommands:\n")
|
|
|
|
usageStrings := make([]string, 0, len(commandHandlers))
|
|
|
|
for command, data := range commandHandlers {
|
|
|
|
usage := command
|
|
|
|
if len(data.usage) > 0 {
|
|
|
|
usage += " " + data.usage
|
|
|
|
}
|
|
|
|
usageStrings = append(usageStrings, usage)
|
|
|
|
}
|
|
|
|
sort.Sort(sort.StringSlice(usageStrings))
|
|
|
|
for _, usage := range usageStrings {
|
|
|
|
fmt.Fprintf(os.Stderr, "\t%s\n", usage)
|
|
|
|
}
|
2013-10-22 05:56:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
2013-11-19 21:38:58 +01:00
|
|
|
parser, cfg, args, err := loadConfig()
|
2013-10-22 05:56:02 +02:00
|
|
|
if err != nil {
|
2013-11-19 20:44:52 +01:00
|
|
|
usage(parser)
|
2013-10-22 17:01:13 +02:00
|
|
|
os.Exit(1)
|
2013-10-22 05:56:02 +02:00
|
|
|
}
|
2013-11-19 20:44:52 +01:00
|
|
|
if len(args) < 1 {
|
2013-10-22 05:56:02 +02:00
|
|
|
usage(parser)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Display usage if the command is not supported.
|
|
|
|
data, exists := commandHandlers[args[0]]
|
|
|
|
if !exists {
|
|
|
|
fmt.Fprintf(os.Stderr, "Unrecognized command: %s\n", args[0])
|
|
|
|
usage(parser)
|
2013-10-22 17:01:13 +02:00
|
|
|
os.Exit(1)
|
2013-10-22 05:56:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Execute the command.
|
2013-11-19 21:38:58 +01:00
|
|
|
err = commandHandler(cfg, args[0], data, args[1:])
|
2013-10-22 05:56:02 +02:00
|
|
|
if err != nil {
|
|
|
|
if err == ErrUsage {
|
|
|
|
usage(parser)
|
2013-10-22 17:01:13 +02:00
|
|
|
os.Exit(1)
|
2013-10-22 05:56:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
2013-10-22 17:01:13 +02:00
|
|
|
os.Exit(1)
|
2013-10-22 05:56:02 +02:00
|
|
|
}
|
2013-10-09 03:18:49 +02:00
|
|
|
}
|