walletsvrcmds_test.go raw

   1  package btcjson_test
   2  
   3  import (
   4  	"bytes"
   5  	"encoding/json"
   6  	"fmt"
   7  	"reflect"
   8  	"testing"
   9  	
  10  	"github.com/p9c/p9/pkg/btcjson"
  11  )
  12  
  13  // TestWalletSvrCmds tests all of the wallet server commands marshal and unmarshal into valid results include handling
  14  // of optional fields being omitted in the marshalled command, while optional fields with defaults have the default
  15  // assigned on unmarshalled commands.
  16  func TestWalletSvrCmds(t *testing.T) {
  17  	t.Parallel()
  18  	testID := 1
  19  	tests := []struct {
  20  		name         string
  21  		newCmd       func() (interface{}, error)
  22  		staticCmd    func() interface{}
  23  		marshalled   string
  24  		unmarshalled interface{}
  25  	}{
  26  		{
  27  			name: "addmultisigaddress",
  28  			newCmd: func() (interface{}, error) {
  29  				return btcjson.NewCmd("addmultisigaddress", 2, []string{"031234", "035678"})
  30  			},
  31  			staticCmd: func() interface{} {
  32  				keys := []string{"031234", "035678"}
  33  				return btcjson.NewAddMultisigAddressCmd(2, keys, nil)
  34  			},
  35  			marshalled: `{"jsonrpc":"1.0","method":"addmultisigaddress","netparams":[2,["031234","035678"]],"id":1}`,
  36  			unmarshalled: &btcjson.AddMultisigAddressCmd{
  37  				NRequired: 2,
  38  				Keys:      []string{"031234", "035678"},
  39  				Account:   nil,
  40  			},
  41  		},
  42  		{
  43  			name: "addmultisigaddress optional",
  44  			newCmd: func() (interface{}, error) {
  45  				return btcjson.NewCmd("addmultisigaddress", 2, []string{"031234", "035678"}, "test")
  46  			},
  47  			staticCmd: func() interface{} {
  48  				keys := []string{"031234", "035678"}
  49  				return btcjson.NewAddMultisigAddressCmd(2, keys, btcjson.String("test"))
  50  			},
  51  			marshalled: `{"jsonrpc":"1.0","method":"addmultisigaddress","netparams":[2,["031234","035678"],"test"],"id":1}`,
  52  			unmarshalled: &btcjson.AddMultisigAddressCmd{
  53  				NRequired: 2,
  54  				Keys:      []string{"031234", "035678"},
  55  				Account:   btcjson.String("test"),
  56  			},
  57  		},
  58  		{
  59  			name: "addwitnessaddress",
  60  			newCmd: func() (interface{}, error) {
  61  				return btcjson.NewCmd("addwitnessaddress", "1address")
  62  			},
  63  			staticCmd: func() interface{} {
  64  				return btcjson.NewAddWitnessAddressCmd("1address")
  65  			},
  66  			marshalled: `{"jsonrpc":"1.0","method":"addwitnessaddress","netparams":["1address"],"id":1}`,
  67  			unmarshalled: &btcjson.AddWitnessAddressCmd{
  68  				Address: "1address",
  69  			},
  70  		},
  71  		{
  72  			name: "createmultisig",
  73  			newCmd: func() (interface{}, error) {
  74  				return btcjson.NewCmd("createmultisig", 2, []string{"031234", "035678"})
  75  			},
  76  			staticCmd: func() interface{} {
  77  				keys := []string{"031234", "035678"}
  78  				return btcjson.NewCreateMultisigCmd(2, keys)
  79  			},
  80  			marshalled: `{"jsonrpc":"1.0","method":"createmultisig","netparams":[2,["031234","035678"]],"id":1}`,
  81  			unmarshalled: &btcjson.CreateMultisigCmd{
  82  				NRequired: 2,
  83  				Keys:      []string{"031234", "035678"},
  84  			},
  85  		},
  86  		{
  87  			name: "dumpprivkey",
  88  			newCmd: func() (interface{}, error) {
  89  				return btcjson.NewCmd("dumpprivkey", "1Address")
  90  			},
  91  			staticCmd: func() interface{} {
  92  				return btcjson.NewDumpPrivKeyCmd("1Address")
  93  			},
  94  			marshalled: `{"jsonrpc":"1.0","method":"dumpprivkey","netparams":["1Address"],"id":1}`,
  95  			unmarshalled: &btcjson.DumpPrivKeyCmd{
  96  				Address: "1Address",
  97  			},
  98  		},
  99  		{
 100  			name: "encryptwallet",
 101  			newCmd: func() (interface{}, error) {
 102  				return btcjson.NewCmd("encryptwallet", "pass")
 103  			},
 104  			staticCmd: func() interface{} {
 105  				return btcjson.NewEncryptWalletCmd("pass")
 106  			},
 107  			marshalled: `{"jsonrpc":"1.0","method":"encryptwallet","netparams":["pass"],"id":1}`,
 108  			unmarshalled: &btcjson.EncryptWalletCmd{
 109  				Passphrase: "pass",
 110  			},
 111  		},
 112  		{
 113  			name: "estimatefee",
 114  			newCmd: func() (interface{}, error) {
 115  				return btcjson.NewCmd("estimatefee", 6)
 116  			},
 117  			staticCmd: func() interface{} {
 118  				return btcjson.NewEstimateFeeCmd(6)
 119  			},
 120  			marshalled: `{"jsonrpc":"1.0","method":"estimatefee","netparams":[6],"id":1}`,
 121  			unmarshalled: &btcjson.EstimateFeeCmd{
 122  				NumBlocks: 6,
 123  			},
 124  		},
 125  		{
 126  			name: "estimatepriority",
 127  			newCmd: func() (interface{}, error) {
 128  				return btcjson.NewCmd("estimatepriority", 6)
 129  			},
 130  			staticCmd: func() interface{} {
 131  				return btcjson.NewEstimatePriorityCmd(6)
 132  			},
 133  			marshalled: `{"jsonrpc":"1.0","method":"estimatepriority","netparams":[6],"id":1}`,
 134  			unmarshalled: &btcjson.EstimatePriorityCmd{
 135  				NumBlocks: 6,
 136  			},
 137  		},
 138  		{
 139  			name: "getaccount",
 140  			newCmd: func() (interface{}, error) {
 141  				return btcjson.NewCmd("getaccount", "1Address")
 142  			},
 143  			staticCmd: func() interface{} {
 144  				return btcjson.NewGetAccountCmd("1Address")
 145  			},
 146  			marshalled: `{"jsonrpc":"1.0","method":"getaccount","netparams":["1Address"],"id":1}`,
 147  			unmarshalled: &btcjson.GetAccountCmd{
 148  				Address: "1Address",
 149  			},
 150  		},
 151  		{
 152  			name: "getaccountaddress",
 153  			newCmd: func() (interface{}, error) {
 154  				return btcjson.NewCmd("getaccountaddress", "acct")
 155  			},
 156  			staticCmd: func() interface{} {
 157  				return btcjson.NewGetAccountAddressCmd("acct")
 158  			},
 159  			marshalled: `{"jsonrpc":"1.0","method":"getaccountaddress","netparams":["acct"],"id":1}`,
 160  			unmarshalled: &btcjson.GetAccountAddressCmd{
 161  				Account: "acct",
 162  			},
 163  		},
 164  		{
 165  			name: "getaddressesbyaccount",
 166  			newCmd: func() (interface{}, error) {
 167  				return btcjson.NewCmd("getaddressesbyaccount", "acct")
 168  			},
 169  			staticCmd: func() interface{} {
 170  				return btcjson.NewGetAddressesByAccountCmd("acct")
 171  			},
 172  			marshalled: `{"jsonrpc":"1.0","method":"getaddressesbyaccount","netparams":["acct"],"id":1}`,
 173  			unmarshalled: &btcjson.GetAddressesByAccountCmd{
 174  				Account: "acct",
 175  			},
 176  		},
 177  		{
 178  			name: "getbalance",
 179  			newCmd: func() (interface{}, error) {
 180  				return btcjson.NewCmd("getbalance")
 181  			},
 182  			staticCmd: func() interface{} {
 183  				return btcjson.NewGetBalanceCmd(nil, nil)
 184  			},
 185  			marshalled: `{"jsonrpc":"1.0","method":"getbalance","netparams":[],"id":1}`,
 186  			unmarshalled: &btcjson.GetBalanceCmd{
 187  				Account: nil,
 188  				MinConf: btcjson.Int(1),
 189  			},
 190  		},
 191  		{
 192  			name: "getbalance optional1",
 193  			newCmd: func() (interface{}, error) {
 194  				return btcjson.NewCmd("getbalance", "acct")
 195  			},
 196  			staticCmd: func() interface{} {
 197  				return btcjson.NewGetBalanceCmd(btcjson.String("acct"), nil)
 198  			},
 199  			marshalled: `{"jsonrpc":"1.0","method":"getbalance","netparams":["acct"],"id":1}`,
 200  			unmarshalled: &btcjson.GetBalanceCmd{
 201  				Account: btcjson.String("acct"),
 202  				MinConf: btcjson.Int(1),
 203  			},
 204  		},
 205  		{
 206  			name: "getbalance optional2",
 207  			newCmd: func() (interface{}, error) {
 208  				return btcjson.NewCmd("getbalance", "acct", 6)
 209  			},
 210  			staticCmd: func() interface{} {
 211  				return btcjson.NewGetBalanceCmd(btcjson.String("acct"), btcjson.Int(6))
 212  			},
 213  			marshalled: `{"jsonrpc":"1.0","method":"getbalance","netparams":["acct",6],"id":1}`,
 214  			unmarshalled: &btcjson.GetBalanceCmd{
 215  				Account: btcjson.String("acct"),
 216  				MinConf: btcjson.Int(6),
 217  			},
 218  		},
 219  		{
 220  			name: "getnewaddress",
 221  			newCmd: func() (interface{}, error) {
 222  				return btcjson.NewCmd("getnewaddress")
 223  			},
 224  			staticCmd: func() interface{} {
 225  				return btcjson.NewGetNewAddressCmd(nil)
 226  			},
 227  			marshalled: `{"jsonrpc":"1.0","method":"getnewaddress","netparams":[],"id":1}`,
 228  			unmarshalled: &btcjson.GetNewAddressCmd{
 229  				Account: nil,
 230  			},
 231  		},
 232  		{
 233  			name: "getnewaddress optional",
 234  			newCmd: func() (interface{}, error) {
 235  				return btcjson.NewCmd("getnewaddress", "acct")
 236  			},
 237  			staticCmd: func() interface{} {
 238  				return btcjson.NewGetNewAddressCmd(btcjson.String("acct"))
 239  			},
 240  			marshalled: `{"jsonrpc":"1.0","method":"getnewaddress","netparams":["acct"],"id":1}`,
 241  			unmarshalled: &btcjson.GetNewAddressCmd{
 242  				Account: btcjson.String("acct"),
 243  			},
 244  		},
 245  		{
 246  			name: "getrawchangeaddress",
 247  			newCmd: func() (interface{}, error) {
 248  				return btcjson.NewCmd("getrawchangeaddress")
 249  			},
 250  			staticCmd: func() interface{} {
 251  				return btcjson.NewGetRawChangeAddressCmd(nil)
 252  			},
 253  			marshalled: `{"jsonrpc":"1.0","method":"getrawchangeaddress","netparams":[],"id":1}`,
 254  			unmarshalled: &btcjson.GetRawChangeAddressCmd{
 255  				Account: nil,
 256  			},
 257  		},
 258  		{
 259  			name: "getrawchangeaddress optional",
 260  			newCmd: func() (interface{}, error) {
 261  				return btcjson.NewCmd("getrawchangeaddress", "acct")
 262  			},
 263  			staticCmd: func() interface{} {
 264  				return btcjson.NewGetRawChangeAddressCmd(btcjson.String("acct"))
 265  			},
 266  			marshalled: `{"jsonrpc":"1.0","method":"getrawchangeaddress","netparams":["acct"],"id":1}`,
 267  			unmarshalled: &btcjson.GetRawChangeAddressCmd{
 268  				Account: btcjson.String("acct"),
 269  			},
 270  		},
 271  		{
 272  			name: "getreceivedbyaccount",
 273  			newCmd: func() (interface{}, error) {
 274  				return btcjson.NewCmd("getreceivedbyaccount", "acct")
 275  			},
 276  			staticCmd: func() interface{} {
 277  				return btcjson.NewGetReceivedByAccountCmd("acct", nil)
 278  			},
 279  			marshalled: `{"jsonrpc":"1.0","method":"getreceivedbyaccount","netparams":["acct"],"id":1}`,
 280  			unmarshalled: &btcjson.GetReceivedByAccountCmd{
 281  				Account: "acct",
 282  				MinConf: btcjson.Int(1),
 283  			},
 284  		},
 285  		{
 286  			name: "getreceivedbyaccount optional",
 287  			newCmd: func() (interface{}, error) {
 288  				return btcjson.NewCmd("getreceivedbyaccount", "acct", 6)
 289  			},
 290  			staticCmd: func() interface{} {
 291  				return btcjson.NewGetReceivedByAccountCmd("acct", btcjson.Int(6))
 292  			},
 293  			marshalled: `{"jsonrpc":"1.0","method":"getreceivedbyaccount","netparams":["acct",6],"id":1}`,
 294  			unmarshalled: &btcjson.GetReceivedByAccountCmd{
 295  				Account: "acct",
 296  				MinConf: btcjson.Int(6),
 297  			},
 298  		},
 299  		{
 300  			name: "getreceivedbyaddress",
 301  			newCmd: func() (interface{}, error) {
 302  				return btcjson.NewCmd("getreceivedbyaddress", "1Address")
 303  			},
 304  			staticCmd: func() interface{} {
 305  				return btcjson.NewGetReceivedByAddressCmd("1Address", nil)
 306  			},
 307  			marshalled: `{"jsonrpc":"1.0","method":"getreceivedbyaddress","netparams":["1Address"],"id":1}`,
 308  			unmarshalled: &btcjson.GetReceivedByAddressCmd{
 309  				Address: "1Address",
 310  				MinConf: btcjson.Int(1),
 311  			},
 312  		},
 313  		{
 314  			name: "getreceivedbyaddress optional",
 315  			newCmd: func() (interface{}, error) {
 316  				return btcjson.NewCmd("getreceivedbyaddress", "1Address", 6)
 317  			},
 318  			staticCmd: func() interface{} {
 319  				return btcjson.NewGetReceivedByAddressCmd("1Address", btcjson.Int(6))
 320  			},
 321  			marshalled: `{"jsonrpc":"1.0","method":"getreceivedbyaddress","netparams":["1Address",6],"id":1}`,
 322  			unmarshalled: &btcjson.GetReceivedByAddressCmd{
 323  				Address: "1Address",
 324  				MinConf: btcjson.Int(6),
 325  			},
 326  		},
 327  		{
 328  			name: "gettransaction",
 329  			newCmd: func() (interface{}, error) {
 330  				return btcjson.NewCmd("gettransaction", "123")
 331  			},
 332  			staticCmd: func() interface{} {
 333  				return btcjson.NewGetTransactionCmd("123", nil)
 334  			},
 335  			marshalled: `{"jsonrpc":"1.0","method":"gettransaction","netparams":["123"],"id":1}`,
 336  			unmarshalled: &btcjson.GetTransactionCmd{
 337  				Txid:             "123",
 338  				IncludeWatchOnly: btcjson.Bool(false),
 339  			},
 340  		},
 341  		{
 342  			name: "gettransaction optional",
 343  			newCmd: func() (interface{}, error) {
 344  				return btcjson.NewCmd("gettransaction", "123", true)
 345  			},
 346  			staticCmd: func() interface{} {
 347  				return btcjson.NewGetTransactionCmd("123", btcjson.Bool(true))
 348  			},
 349  			marshalled: `{"jsonrpc":"1.0","method":"gettransaction","netparams":["123",true],"id":1}`,
 350  			unmarshalled: &btcjson.GetTransactionCmd{
 351  				Txid:             "123",
 352  				IncludeWatchOnly: btcjson.Bool(true),
 353  			},
 354  		},
 355  		{
 356  			name: "getwalletinfo",
 357  			newCmd: func() (interface{}, error) {
 358  				return btcjson.NewCmd("getwalletinfo")
 359  			},
 360  			staticCmd: func() interface{} {
 361  				return btcjson.NewGetWalletInfoCmd()
 362  			},
 363  			marshalled:   `{"jsonrpc":"1.0","method":"getwalletinfo","netparams":[],"id":1}`,
 364  			unmarshalled: &btcjson.GetWalletInfoCmd{},
 365  		},
 366  		{
 367  			name: "importprivkey",
 368  			newCmd: func() (interface{}, error) {
 369  				return btcjson.NewCmd("importprivkey", "abc")
 370  			},
 371  			staticCmd: func() interface{} {
 372  				return btcjson.NewImportPrivKeyCmd("abc", nil, nil)
 373  			},
 374  			marshalled: `{"jsonrpc":"1.0","method":"importprivkey","netparams":["abc"],"id":1}`,
 375  			unmarshalled: &btcjson.ImportPrivKeyCmd{
 376  				PrivKey: "abc",
 377  				Label:   nil,
 378  				Rescan:  btcjson.Bool(true),
 379  			},
 380  		},
 381  		{
 382  			name: "importprivkey optional1",
 383  			newCmd: func() (interface{}, error) {
 384  				return btcjson.NewCmd("importprivkey", "abc", "label")
 385  			},
 386  			staticCmd: func() interface{} {
 387  				return btcjson.NewImportPrivKeyCmd("abc", btcjson.String("label"), nil)
 388  			},
 389  			marshalled: `{"jsonrpc":"1.0","method":"importprivkey","netparams":["abc","label"],"id":1}`,
 390  			unmarshalled: &btcjson.ImportPrivKeyCmd{
 391  				PrivKey: "abc",
 392  				Label:   btcjson.String("label"),
 393  				Rescan:  btcjson.Bool(true),
 394  			},
 395  		},
 396  		{
 397  			name: "importprivkey optional2",
 398  			newCmd: func() (interface{}, error) {
 399  				return btcjson.NewCmd("importprivkey", "abc", "label", false)
 400  			},
 401  			staticCmd: func() interface{} {
 402  				return btcjson.NewImportPrivKeyCmd("abc", btcjson.String("label"), btcjson.Bool(false))
 403  			},
 404  			marshalled: `{"jsonrpc":"1.0","method":"importprivkey","netparams":["abc","label",false],"id":1}`,
 405  			unmarshalled: &btcjson.ImportPrivKeyCmd{
 406  				PrivKey: "abc",
 407  				Label:   btcjson.String("label"),
 408  				Rescan:  btcjson.Bool(false),
 409  			},
 410  		},
 411  		{
 412  			name: "keypoolrefill",
 413  			newCmd: func() (interface{}, error) {
 414  				return btcjson.NewCmd("keypoolrefill")
 415  			},
 416  			staticCmd: func() interface{} {
 417  				return btcjson.NewKeyPoolRefillCmd(nil)
 418  			},
 419  			marshalled: `{"jsonrpc":"1.0","method":"keypoolrefill","netparams":[],"id":1}`,
 420  			unmarshalled: &btcjson.KeyPoolRefillCmd{
 421  				NewSize: btcjson.Uint(100),
 422  			},
 423  		},
 424  		{
 425  			name: "keypoolrefill optional",
 426  			newCmd: func() (interface{}, error) {
 427  				return btcjson.NewCmd("keypoolrefill", 200)
 428  			},
 429  			staticCmd: func() interface{} {
 430  				return btcjson.NewKeyPoolRefillCmd(btcjson.Uint(200))
 431  			},
 432  			marshalled: `{"jsonrpc":"1.0","method":"keypoolrefill","netparams":[200],"id":1}`,
 433  			unmarshalled: &btcjson.KeyPoolRefillCmd{
 434  				NewSize: btcjson.Uint(200),
 435  			},
 436  		},
 437  		{
 438  			name: "listaccounts",
 439  			newCmd: func() (interface{}, error) {
 440  				return btcjson.NewCmd("listaccounts")
 441  			},
 442  			staticCmd: func() interface{} {
 443  				return btcjson.NewListAccountsCmd(nil)
 444  			},
 445  			marshalled: `{"jsonrpc":"1.0","method":"listaccounts","netparams":[],"id":1}`,
 446  			unmarshalled: &btcjson.ListAccountsCmd{
 447  				MinConf: btcjson.Int(1),
 448  			},
 449  		},
 450  		{
 451  			name: "listaccounts optional",
 452  			newCmd: func() (interface{}, error) {
 453  				return btcjson.NewCmd("listaccounts", 6)
 454  			},
 455  			staticCmd: func() interface{} {
 456  				return btcjson.NewListAccountsCmd(btcjson.Int(6))
 457  			},
 458  			marshalled: `{"jsonrpc":"1.0","method":"listaccounts","netparams":[6],"id":1}`,
 459  			unmarshalled: &btcjson.ListAccountsCmd{
 460  				MinConf: btcjson.Int(6),
 461  			},
 462  		},
 463  		{
 464  			name: "listaddressgroupings",
 465  			newCmd: func() (interface{}, error) {
 466  				return btcjson.NewCmd("listaddressgroupings")
 467  			},
 468  			staticCmd: func() interface{} {
 469  				return btcjson.NewListAddressGroupingsCmd()
 470  			},
 471  			marshalled:   `{"jsonrpc":"1.0","method":"listaddressgroupings","netparams":[],"id":1}`,
 472  			unmarshalled: &btcjson.ListAddressGroupingsCmd{},
 473  		},
 474  		{
 475  			name: "listlockunspent",
 476  			newCmd: func() (interface{}, error) {
 477  				return btcjson.NewCmd("listlockunspent")
 478  			},
 479  			staticCmd: func() interface{} {
 480  				return btcjson.NewListLockUnspentCmd()
 481  			},
 482  			marshalled:   `{"jsonrpc":"1.0","method":"listlockunspent","netparams":[],"id":1}`,
 483  			unmarshalled: &btcjson.ListLockUnspentCmd{},
 484  		},
 485  		{
 486  			name: "listreceivedbyaccount",
 487  			newCmd: func() (interface{}, error) {
 488  				return btcjson.NewCmd("listreceivedbyaccount")
 489  			},
 490  			staticCmd: func() interface{} {
 491  				return btcjson.NewListReceivedByAccountCmd(nil, nil, nil)
 492  			},
 493  			marshalled: `{"jsonrpc":"1.0","method":"listreceivedbyaccount","netparams":[],"id":1}`,
 494  			unmarshalled: &btcjson.ListReceivedByAccountCmd{
 495  				MinConf:          btcjson.Int(1),
 496  				IncludeEmpty:     btcjson.Bool(false),
 497  				IncludeWatchOnly: btcjson.Bool(false),
 498  			},
 499  		},
 500  		{
 501  			name: "listreceivedbyaccount optional1",
 502  			newCmd: func() (interface{}, error) {
 503  				return btcjson.NewCmd("listreceivedbyaccount", 6)
 504  			},
 505  			staticCmd: func() interface{} {
 506  				return btcjson.NewListReceivedByAccountCmd(btcjson.Int(6), nil, nil)
 507  			},
 508  			marshalled: `{"jsonrpc":"1.0","method":"listreceivedbyaccount","netparams":[6],"id":1}`,
 509  			unmarshalled: &btcjson.ListReceivedByAccountCmd{
 510  				MinConf:          btcjson.Int(6),
 511  				IncludeEmpty:     btcjson.Bool(false),
 512  				IncludeWatchOnly: btcjson.Bool(false),
 513  			},
 514  		},
 515  		{
 516  			name: "listreceivedbyaccount optional2",
 517  			newCmd: func() (interface{}, error) {
 518  				return btcjson.NewCmd("listreceivedbyaccount", 6, true)
 519  			},
 520  			staticCmd: func() interface{} {
 521  				return btcjson.NewListReceivedByAccountCmd(btcjson.Int(6), btcjson.Bool(true), nil)
 522  			},
 523  			marshalled: `{"jsonrpc":"1.0","method":"listreceivedbyaccount","netparams":[6,true],"id":1}`,
 524  			unmarshalled: &btcjson.ListReceivedByAccountCmd{
 525  				MinConf:          btcjson.Int(6),
 526  				IncludeEmpty:     btcjson.Bool(true),
 527  				IncludeWatchOnly: btcjson.Bool(false),
 528  			},
 529  		},
 530  		{
 531  			name: "listreceivedbyaccount optional3",
 532  			newCmd: func() (interface{}, error) {
 533  				return btcjson.NewCmd("listreceivedbyaccount", 6, true, false)
 534  			},
 535  			staticCmd: func() interface{} {
 536  				return btcjson.NewListReceivedByAccountCmd(btcjson.Int(6), btcjson.Bool(true), btcjson.Bool(false))
 537  			},
 538  			marshalled: `{"jsonrpc":"1.0","method":"listreceivedbyaccount","netparams":[6,true,false],"id":1}`,
 539  			unmarshalled: &btcjson.ListReceivedByAccountCmd{
 540  				MinConf:          btcjson.Int(6),
 541  				IncludeEmpty:     btcjson.Bool(true),
 542  				IncludeWatchOnly: btcjson.Bool(false),
 543  			},
 544  		},
 545  		{
 546  			name: "listreceivedbyaddress",
 547  			newCmd: func() (interface{}, error) {
 548  				return btcjson.NewCmd("listreceivedbyaddress")
 549  			},
 550  			staticCmd: func() interface{} {
 551  				return btcjson.NewListReceivedByAddressCmd(nil, nil, nil)
 552  			},
 553  			marshalled: `{"jsonrpc":"1.0","method":"listreceivedbyaddress","netparams":[],"id":1}`,
 554  			unmarshalled: &btcjson.ListReceivedByAddressCmd{
 555  				MinConf:          btcjson.Int(1),
 556  				IncludeEmpty:     btcjson.Bool(false),
 557  				IncludeWatchOnly: btcjson.Bool(false),
 558  			},
 559  		},
 560  		{
 561  			name: "listreceivedbyaddress optional1",
 562  			newCmd: func() (interface{}, error) {
 563  				return btcjson.NewCmd("listreceivedbyaddress", 6)
 564  			},
 565  			staticCmd: func() interface{} {
 566  				return btcjson.NewListReceivedByAddressCmd(btcjson.Int(6), nil, nil)
 567  			},
 568  			marshalled: `{"jsonrpc":"1.0","method":"listreceivedbyaddress","netparams":[6],"id":1}`,
 569  			unmarshalled: &btcjson.ListReceivedByAddressCmd{
 570  				MinConf:          btcjson.Int(6),
 571  				IncludeEmpty:     btcjson.Bool(false),
 572  				IncludeWatchOnly: btcjson.Bool(false),
 573  			},
 574  		},
 575  		{
 576  			name: "listreceivedbyaddress optional2",
 577  			newCmd: func() (interface{}, error) {
 578  				return btcjson.NewCmd("listreceivedbyaddress", 6, true)
 579  			},
 580  			staticCmd: func() interface{} {
 581  				return btcjson.NewListReceivedByAddressCmd(btcjson.Int(6), btcjson.Bool(true), nil)
 582  			},
 583  			marshalled: `{"jsonrpc":"1.0","method":"listreceivedbyaddress","netparams":[6,true],"id":1}`,
 584  			unmarshalled: &btcjson.ListReceivedByAddressCmd{
 585  				MinConf:          btcjson.Int(6),
 586  				IncludeEmpty:     btcjson.Bool(true),
 587  				IncludeWatchOnly: btcjson.Bool(false),
 588  			},
 589  		},
 590  		{
 591  			name: "listreceivedbyaddress optional3",
 592  			newCmd: func() (interface{}, error) {
 593  				return btcjson.NewCmd("listreceivedbyaddress", 6, true, false)
 594  			},
 595  			staticCmd: func() interface{} {
 596  				return btcjson.NewListReceivedByAddressCmd(btcjson.Int(6), btcjson.Bool(true), btcjson.Bool(false))
 597  			},
 598  			marshalled: `{"jsonrpc":"1.0","method":"listreceivedbyaddress","netparams":[6,true,false],"id":1}`,
 599  			unmarshalled: &btcjson.ListReceivedByAddressCmd{
 600  				MinConf:          btcjson.Int(6),
 601  				IncludeEmpty:     btcjson.Bool(true),
 602  				IncludeWatchOnly: btcjson.Bool(false),
 603  			},
 604  		},
 605  		{
 606  			name: "listsinceblock",
 607  			newCmd: func() (interface{}, error) {
 608  				return btcjson.NewCmd("listsinceblock")
 609  			},
 610  			staticCmd: func() interface{} {
 611  				return btcjson.NewListSinceBlockCmd(nil, nil, nil)
 612  			},
 613  			marshalled: `{"jsonrpc":"1.0","method":"listsinceblock","netparams":[],"id":1}`,
 614  			unmarshalled: &btcjson.ListSinceBlockCmd{
 615  				BlockHash:           nil,
 616  				TargetConfirmations: btcjson.Int(1),
 617  				IncludeWatchOnly:    btcjson.Bool(false),
 618  			},
 619  		},
 620  		{
 621  			name: "listsinceblock optional1",
 622  			newCmd: func() (interface{}, error) {
 623  				return btcjson.NewCmd("listsinceblock", "123")
 624  			},
 625  			staticCmd: func() interface{} {
 626  				return btcjson.NewListSinceBlockCmd(btcjson.String("123"), nil, nil)
 627  			},
 628  			marshalled: `{"jsonrpc":"1.0","method":"listsinceblock","netparams":["123"],"id":1}`,
 629  			unmarshalled: &btcjson.ListSinceBlockCmd{
 630  				BlockHash:           btcjson.String("123"),
 631  				TargetConfirmations: btcjson.Int(1),
 632  				IncludeWatchOnly:    btcjson.Bool(false),
 633  			},
 634  		},
 635  		{
 636  			name: "listsinceblock optional2",
 637  			newCmd: func() (interface{}, error) {
 638  				return btcjson.NewCmd("listsinceblock", "123", 6)
 639  			},
 640  			staticCmd: func() interface{} {
 641  				return btcjson.NewListSinceBlockCmd(btcjson.String("123"), btcjson.Int(6), nil)
 642  			},
 643  			marshalled: `{"jsonrpc":"1.0","method":"listsinceblock","netparams":["123",6],"id":1}`,
 644  			unmarshalled: &btcjson.ListSinceBlockCmd{
 645  				BlockHash:           btcjson.String("123"),
 646  				TargetConfirmations: btcjson.Int(6),
 647  				IncludeWatchOnly:    btcjson.Bool(false),
 648  			},
 649  		},
 650  		{
 651  			name: "listsinceblock optional3",
 652  			newCmd: func() (interface{}, error) {
 653  				return btcjson.NewCmd("listsinceblock", "123", 6, true)
 654  			},
 655  			staticCmd: func() interface{} {
 656  				return btcjson.NewListSinceBlockCmd(btcjson.String("123"), btcjson.Int(6), btcjson.Bool(true))
 657  			},
 658  			marshalled: `{"jsonrpc":"1.0","method":"listsinceblock","netparams":["123",6,true],"id":1}`,
 659  			unmarshalled: &btcjson.ListSinceBlockCmd{
 660  				BlockHash:           btcjson.String("123"),
 661  				TargetConfirmations: btcjson.Int(6),
 662  				IncludeWatchOnly:    btcjson.Bool(true),
 663  			},
 664  		},
 665  		{
 666  			name: "listtransactions",
 667  			newCmd: func() (interface{}, error) {
 668  				return btcjson.NewCmd("listtransactions")
 669  			},
 670  			staticCmd: func() interface{} {
 671  				return btcjson.NewListTransactionsCmd(nil, nil, nil, nil)
 672  			},
 673  			marshalled: `{"jsonrpc":"1.0","method":"listtransactions","netparams":[],"id":1}`,
 674  			unmarshalled: &btcjson.ListTransactionsCmd{
 675  				Account:          nil,
 676  				Count:            btcjson.Int(10),
 677  				From:             btcjson.Int(0),
 678  				IncludeWatchOnly: btcjson.Bool(false),
 679  			},
 680  		},
 681  		{
 682  			name: "listtransactions optional1",
 683  			newCmd: func() (interface{}, error) {
 684  				return btcjson.NewCmd("listtransactions", "acct")
 685  			},
 686  			staticCmd: func() interface{} {
 687  				return btcjson.NewListTransactionsCmd(btcjson.String("acct"), nil, nil, nil)
 688  			},
 689  			marshalled: `{"jsonrpc":"1.0","method":"listtransactions","netparams":["acct"],"id":1}`,
 690  			unmarshalled: &btcjson.ListTransactionsCmd{
 691  				Account:          btcjson.String("acct"),
 692  				Count:            btcjson.Int(10),
 693  				From:             btcjson.Int(0),
 694  				IncludeWatchOnly: btcjson.Bool(false),
 695  			},
 696  		},
 697  		{
 698  			name: "listtransactions optional2",
 699  			newCmd: func() (interface{}, error) {
 700  				return btcjson.NewCmd("listtransactions", "acct", 20)
 701  			},
 702  			staticCmd: func() interface{} {
 703  				return btcjson.NewListTransactionsCmd(btcjson.String("acct"), btcjson.Int(20), nil, nil)
 704  			},
 705  			marshalled: `{"jsonrpc":"1.0","method":"listtransactions","netparams":["acct",20],"id":1}`,
 706  			unmarshalled: &btcjson.ListTransactionsCmd{
 707  				Account:          btcjson.String("acct"),
 708  				Count:            btcjson.Int(20),
 709  				From:             btcjson.Int(0),
 710  				IncludeWatchOnly: btcjson.Bool(false),
 711  			},
 712  		},
 713  		{
 714  			name: "listtransactions optional3",
 715  			newCmd: func() (interface{}, error) {
 716  				return btcjson.NewCmd("listtransactions", "acct", 20, 1)
 717  			},
 718  			staticCmd: func() interface{} {
 719  				return btcjson.NewListTransactionsCmd(btcjson.String("acct"), btcjson.Int(20),
 720  					btcjson.Int(1), nil,
 721  				)
 722  			},
 723  			marshalled: `{"jsonrpc":"1.0","method":"listtransactions","netparams":["acct",20,1],"id":1}`,
 724  			unmarshalled: &btcjson.ListTransactionsCmd{
 725  				Account:          btcjson.String("acct"),
 726  				Count:            btcjson.Int(20),
 727  				From:             btcjson.Int(1),
 728  				IncludeWatchOnly: btcjson.Bool(false),
 729  			},
 730  		},
 731  		{
 732  			name: "listtransactions optional4",
 733  			newCmd: func() (interface{}, error) {
 734  				return btcjson.NewCmd("listtransactions", "acct", 20, 1, true)
 735  			},
 736  			staticCmd: func() interface{} {
 737  				return btcjson.NewListTransactionsCmd(btcjson.String("acct"), btcjson.Int(20),
 738  					btcjson.Int(1), btcjson.Bool(true),
 739  				)
 740  			},
 741  			marshalled: `{"jsonrpc":"1.0","method":"listtransactions","netparams":["acct",20,1,true],"id":1}`,
 742  			unmarshalled: &btcjson.ListTransactionsCmd{
 743  				Account:          btcjson.String("acct"),
 744  				Count:            btcjson.Int(20),
 745  				From:             btcjson.Int(1),
 746  				IncludeWatchOnly: btcjson.Bool(true),
 747  			},
 748  		},
 749  		{
 750  			name: "listunspent",
 751  			newCmd: func() (interface{}, error) {
 752  				return btcjson.NewCmd("listunspent")
 753  			},
 754  			staticCmd: func() interface{} {
 755  				return btcjson.NewListUnspentCmd(nil, nil, nil)
 756  			},
 757  			marshalled: `{"jsonrpc":"1.0","method":"listunspent","netparams":[],"id":1}`,
 758  			unmarshalled: &btcjson.ListUnspentCmd{
 759  				MinConf:   btcjson.Int(1),
 760  				MaxConf:   btcjson.Int(9999999),
 761  				Addresses: nil,
 762  			},
 763  		},
 764  		{
 765  			name: "listunspent optional1",
 766  			newCmd: func() (interface{}, error) {
 767  				return btcjson.NewCmd("listunspent", 6)
 768  			},
 769  			staticCmd: func() interface{} {
 770  				return btcjson.NewListUnspentCmd(btcjson.Int(6), nil, nil)
 771  			},
 772  			marshalled: `{"jsonrpc":"1.0","method":"listunspent","netparams":[6],"id":1}`,
 773  			unmarshalled: &btcjson.ListUnspentCmd{
 774  				MinConf:   btcjson.Int(6),
 775  				MaxConf:   btcjson.Int(9999999),
 776  				Addresses: nil,
 777  			},
 778  		},
 779  		{
 780  			name: "listunspent optional2",
 781  			newCmd: func() (interface{}, error) {
 782  				return btcjson.NewCmd("listunspent", 6, 100)
 783  			},
 784  			staticCmd: func() interface{} {
 785  				return btcjson.NewListUnspentCmd(btcjson.Int(6), btcjson.Int(100), nil)
 786  			},
 787  			marshalled: `{"jsonrpc":"1.0","method":"listunspent","netparams":[6,100],"id":1}`,
 788  			unmarshalled: &btcjson.ListUnspentCmd{
 789  				MinConf:   btcjson.Int(6),
 790  				MaxConf:   btcjson.Int(100),
 791  				Addresses: nil,
 792  			},
 793  		},
 794  		{
 795  			name: "listunspent optional3",
 796  			newCmd: func() (interface{}, error) {
 797  				return btcjson.NewCmd("listunspent", 6, 100, []string{"1Address", "1Address2"})
 798  			},
 799  			staticCmd: func() interface{} {
 800  				return btcjson.NewListUnspentCmd(btcjson.Int(6), btcjson.Int(100),
 801  					&[]string{"1Address", "1Address2"},
 802  				)
 803  			},
 804  			marshalled: `{"jsonrpc":"1.0","method":"listunspent","netparams":[6,100,["1Address","1Address2"]],"id":1}`,
 805  			unmarshalled: &btcjson.ListUnspentCmd{
 806  				MinConf:   btcjson.Int(6),
 807  				MaxConf:   btcjson.Int(100),
 808  				Addresses: &[]string{"1Address", "1Address2"},
 809  			},
 810  		},
 811  		{
 812  			name: "lockunspent",
 813  			newCmd: func() (interface{}, error) {
 814  				return btcjson.NewCmd("lockunspent", true, `[{"txid":"123","vout":1}]`)
 815  			},
 816  			staticCmd: func() interface{} {
 817  				txInputs := []btcjson.TransactionInput{
 818  					{Txid: "123", Vout: 1},
 819  				}
 820  				return btcjson.NewLockUnspentCmd(true, txInputs)
 821  			},
 822  			marshalled: `{"jsonrpc":"1.0","method":"lockunspent","netparams":[true,[{"txid":"123","vout":1}]],"id":1}`,
 823  			unmarshalled: &btcjson.LockUnspentCmd{
 824  				Unlock: true,
 825  				Transactions: []btcjson.TransactionInput{
 826  					{Txid: "123", Vout: 1},
 827  				},
 828  			},
 829  		},
 830  		{
 831  			name: "move",
 832  			newCmd: func() (interface{}, error) {
 833  				return btcjson.NewCmd("move", "from", "to", 0.5)
 834  			},
 835  			staticCmd: func() interface{} {
 836  				return btcjson.NewMoveCmd("from", "to", 0.5, nil, nil)
 837  			},
 838  			marshalled: `{"jsonrpc":"1.0","method":"move","netparams":["from","to",0.5],"id":1}`,
 839  			unmarshalled: &btcjson.MoveCmd{
 840  				FromAccount: "from",
 841  				ToAccount:   "to",
 842  				Amount:      0.5,
 843  				MinConf:     btcjson.Int(1),
 844  				Comment:     nil,
 845  			},
 846  		},
 847  		{
 848  			name: "move optional1",
 849  			newCmd: func() (interface{}, error) {
 850  				return btcjson.NewCmd("move", "from", "to", 0.5, 6)
 851  			},
 852  			staticCmd: func() interface{} {
 853  				return btcjson.NewMoveCmd("from", "to", 0.5, btcjson.Int(6), nil)
 854  			},
 855  			marshalled: `{"jsonrpc":"1.0","method":"move","netparams":["from","to",0.5,6],"id":1}`,
 856  			unmarshalled: &btcjson.MoveCmd{
 857  				FromAccount: "from",
 858  				ToAccount:   "to",
 859  				Amount:      0.5,
 860  				MinConf:     btcjson.Int(6),
 861  				Comment:     nil,
 862  			},
 863  		},
 864  		{
 865  			name: "move optional2",
 866  			newCmd: func() (interface{}, error) {
 867  				return btcjson.NewCmd("move", "from", "to", 0.5, 6, "comment")
 868  			},
 869  			staticCmd: func() interface{} {
 870  				return btcjson.NewMoveCmd("from", "to", 0.5, btcjson.Int(6), btcjson.String("comment"))
 871  			},
 872  			marshalled: `{"jsonrpc":"1.0","method":"move","netparams":["from","to",0.5,6,"comment"],"id":1}`,
 873  			unmarshalled: &btcjson.MoveCmd{
 874  				FromAccount: "from",
 875  				ToAccount:   "to",
 876  				Amount:      0.5,
 877  				MinConf:     btcjson.Int(6),
 878  				Comment:     btcjson.String("comment"),
 879  			},
 880  		},
 881  		{
 882  			name: "sendfrom",
 883  			newCmd: func() (interface{}, error) {
 884  				return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5)
 885  			},
 886  			staticCmd: func() interface{} {
 887  				return btcjson.NewSendFromCmd("from", "1Address", 0.5, nil, nil, nil)
 888  			},
 889  			marshalled: `{"jsonrpc":"1.0","method":"sendfrom","netparams":["from","1Address",0.5],"id":1}`,
 890  			unmarshalled: &btcjson.SendFromCmd{
 891  				FromAccount: "from",
 892  				ToAddress:   "1Address",
 893  				Amount:      0.5,
 894  				MinConf:     btcjson.Int(1),
 895  				Comment:     nil,
 896  				CommentTo:   nil,
 897  			},
 898  		},
 899  		{
 900  			name: "sendfrom optional1",
 901  			newCmd: func() (interface{}, error) {
 902  				return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6)
 903  			},
 904  			staticCmd: func() interface{} {
 905  				return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6), nil, nil)
 906  			},
 907  			marshalled: `{"jsonrpc":"1.0","method":"sendfrom","netparams":["from","1Address",0.5,6],"id":1}`,
 908  			unmarshalled: &btcjson.SendFromCmd{
 909  				FromAccount: "from",
 910  				ToAddress:   "1Address",
 911  				Amount:      0.5,
 912  				MinConf:     btcjson.Int(6),
 913  				Comment:     nil,
 914  				CommentTo:   nil,
 915  			},
 916  		},
 917  		{
 918  			name: "sendfrom optional2",
 919  			newCmd: func() (interface{}, error) {
 920  				return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6, "comment")
 921  			},
 922  			staticCmd: func() interface{} {
 923  				return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6),
 924  					btcjson.String("comment"), nil,
 925  				)
 926  			},
 927  			marshalled: `{"jsonrpc":"1.0","method":"sendfrom","netparams":["from","1Address",0.5,6,"comment"],"id":1}`,
 928  			unmarshalled: &btcjson.SendFromCmd{
 929  				FromAccount: "from",
 930  				ToAddress:   "1Address",
 931  				Amount:      0.5,
 932  				MinConf:     btcjson.Int(6),
 933  				Comment:     btcjson.String("comment"),
 934  				CommentTo:   nil,
 935  			},
 936  		},
 937  		{
 938  			name: "sendfrom optional3",
 939  			newCmd: func() (interface{}, error) {
 940  				return btcjson.NewCmd("sendfrom", "from", "1Address", 0.5, 6, "comment", "commentto")
 941  			},
 942  			staticCmd: func() interface{} {
 943  				return btcjson.NewSendFromCmd("from", "1Address", 0.5, btcjson.Int(6),
 944  					btcjson.String("comment"), btcjson.String("commentto"),
 945  				)
 946  			},
 947  			marshalled: `{"jsonrpc":"1.0","method":"sendfrom","netparams":["from","1Address",0.5,6,"comment","commentto"],"id":1}`,
 948  			unmarshalled: &btcjson.SendFromCmd{
 949  				FromAccount: "from",
 950  				ToAddress:   "1Address",
 951  				Amount:      0.5,
 952  				MinConf:     btcjson.Int(6),
 953  				Comment:     btcjson.String("comment"),
 954  				CommentTo:   btcjson.String("commentto"),
 955  			},
 956  		},
 957  		{
 958  			name: "sendmany",
 959  			newCmd: func() (interface{}, error) {
 960  				return btcjson.NewCmd("sendmany", "from", `{"1Address":0.5}`)
 961  			},
 962  			staticCmd: func() interface{} {
 963  				amounts := map[string]float64{"1Address": 0.5}
 964  				return btcjson.NewSendManyCmd("from", amounts, nil, nil)
 965  			},
 966  			marshalled: `{"jsonrpc":"1.0","method":"sendmany","netparams":["from",{"1Address":0.5}],"id":1}`,
 967  			unmarshalled: &btcjson.SendManyCmd{
 968  				FromAccount: "from",
 969  				Amounts:     map[string]float64{"1Address": 0.5},
 970  				MinConf:     btcjson.Int(1),
 971  				Comment:     nil,
 972  			},
 973  		},
 974  		{
 975  			name: "sendmany optional1",
 976  			newCmd: func() (interface{}, error) {
 977  				return btcjson.NewCmd("sendmany", "from", `{"1Address":0.5}`, 6)
 978  			},
 979  			staticCmd: func() interface{} {
 980  				amounts := map[string]float64{"1Address": 0.5}
 981  				return btcjson.NewSendManyCmd("from", amounts, btcjson.Int(6), nil)
 982  			},
 983  			marshalled: `{"jsonrpc":"1.0","method":"sendmany","netparams":["from",{"1Address":0.5},6],"id":1}`,
 984  			unmarshalled: &btcjson.SendManyCmd{
 985  				FromAccount: "from",
 986  				Amounts:     map[string]float64{"1Address": 0.5},
 987  				MinConf:     btcjson.Int(6),
 988  				Comment:     nil,
 989  			},
 990  		},
 991  		{
 992  			name: "sendmany optional2",
 993  			newCmd: func() (interface{}, error) {
 994  				return btcjson.NewCmd("sendmany", "from", `{"1Address":0.5}`, 6, "comment")
 995  			},
 996  			staticCmd: func() interface{} {
 997  				amounts := map[string]float64{"1Address": 0.5}
 998  				return btcjson.NewSendManyCmd("from", amounts, btcjson.Int(6), btcjson.String("comment"))
 999  			},
1000  			marshalled: `{"jsonrpc":"1.0","method":"sendmany","netparams":["from",{"1Address":0.5},6,"comment"],"id":1}`,
1001  			unmarshalled: &btcjson.SendManyCmd{
1002  				FromAccount: "from",
1003  				Amounts:     map[string]float64{"1Address": 0.5},
1004  				MinConf:     btcjson.Int(6),
1005  				Comment:     btcjson.String("comment"),
1006  			},
1007  		},
1008  		{
1009  			name: "sendtoaddress",
1010  			newCmd: func() (interface{}, error) {
1011  				return btcjson.NewCmd("sendtoaddress", "1Address", 0.5)
1012  			},
1013  			staticCmd: func() interface{} {
1014  				return btcjson.NewSendToAddressCmd("1Address", 0.5, nil, nil)
1015  			},
1016  			marshalled: `{"jsonrpc":"1.0","method":"sendtoaddress","netparams":["1Address",0.5],"id":1}`,
1017  			unmarshalled: &btcjson.SendToAddressCmd{
1018  				Address:   "1Address",
1019  				Amount:    0.5,
1020  				Comment:   nil,
1021  				CommentTo: nil,
1022  			},
1023  		},
1024  		{
1025  			name: "sendtoaddress optional1",
1026  			newCmd: func() (interface{}, error) {
1027  				return btcjson.NewCmd("sendtoaddress", "1Address", 0.5, "comment", "commentto")
1028  			},
1029  			staticCmd: func() interface{} {
1030  				return btcjson.NewSendToAddressCmd("1Address", 0.5, btcjson.String("comment"),
1031  					btcjson.String("commentto"),
1032  				)
1033  			},
1034  			marshalled: `{"jsonrpc":"1.0","method":"sendtoaddress","netparams":["1Address",0.5,"comment","commentto"],"id":1}`,
1035  			unmarshalled: &btcjson.SendToAddressCmd{
1036  				Address:   "1Address",
1037  				Amount:    0.5,
1038  				Comment:   btcjson.String("comment"),
1039  				CommentTo: btcjson.String("commentto"),
1040  			},
1041  		},
1042  		{
1043  			name: "setaccount",
1044  			newCmd: func() (interface{}, error) {
1045  				return btcjson.NewCmd("setaccount", "1Address", "acct")
1046  			},
1047  			staticCmd: func() interface{} {
1048  				return btcjson.NewSetAccountCmd("1Address", "acct")
1049  			},
1050  			marshalled: `{"jsonrpc":"1.0","method":"setaccount","netparams":["1Address","acct"],"id":1}`,
1051  			unmarshalled: &btcjson.SetAccountCmd{
1052  				Address: "1Address",
1053  				Account: "acct",
1054  			},
1055  		},
1056  		{
1057  			name: "settxfee",
1058  			newCmd: func() (interface{}, error) {
1059  				return btcjson.NewCmd("settxfee", 0.0001)
1060  			},
1061  			staticCmd: func() interface{} {
1062  				return btcjson.NewSetTxFeeCmd(0.0001)
1063  			},
1064  			marshalled: `{"jsonrpc":"1.0","method":"settxfee","netparams":[0.0001],"id":1}`,
1065  			unmarshalled: &btcjson.SetTxFeeCmd{
1066  				Amount: 0.0001,
1067  			},
1068  		},
1069  		{
1070  			name: "signmessage",
1071  			newCmd: func() (interface{}, error) {
1072  				return btcjson.NewCmd("signmessage", "1Address", "message")
1073  			},
1074  			staticCmd: func() interface{} {
1075  				return btcjson.NewSignMessageCmd("1Address", "message")
1076  			},
1077  			marshalled: `{"jsonrpc":"1.0","method":"signmessage","netparams":["1Address","message"],"id":1}`,
1078  			unmarshalled: &btcjson.SignMessageCmd{
1079  				Address: "1Address",
1080  				Message: "message",
1081  			},
1082  		},
1083  		{
1084  			name: "signrawtransaction",
1085  			newCmd: func() (interface{}, error) {
1086  				return btcjson.NewCmd("signrawtransaction", "001122")
1087  			},
1088  			staticCmd: func() interface{} {
1089  				return btcjson.NewSignRawTransactionCmd("001122", nil, nil, nil)
1090  			},
1091  			marshalled: `{"jsonrpc":"1.0","method":"signrawtransaction","netparams":["001122"],"id":1}`,
1092  			unmarshalled: &btcjson.SignRawTransactionCmd{
1093  				RawTx:    "001122",
1094  				Inputs:   nil,
1095  				PrivKeys: nil,
1096  				Flags:    btcjson.String("ALL"),
1097  			},
1098  		},
1099  		{
1100  			name: "signrawtransaction optional1",
1101  			newCmd: func() (interface{}, error) {
1102  				return btcjson.NewCmd("signrawtransaction", "001122",
1103  					`[{"txid":"123","vout":1,"scriptPubKey":"00","redeemScript":"01"}]`,
1104  				)
1105  			},
1106  			staticCmd: func() interface{} {
1107  				txInputs := []btcjson.RawTxInput{
1108  					{
1109  						Txid:         "123",
1110  						Vout:         1,
1111  						ScriptPubKey: "00",
1112  						RedeemScript: "01",
1113  					},
1114  				}
1115  				return btcjson.NewSignRawTransactionCmd("001122", &txInputs, nil, nil)
1116  			},
1117  			marshalled: `{"jsonrpc":"1.0","method":"signrawtransaction","netparams":["001122",[{"txid":"123","vout":1,"scriptPubKey":"00","redeemScript":"01"}]],"id":1}`,
1118  			unmarshalled: &btcjson.SignRawTransactionCmd{
1119  				RawTx: "001122",
1120  				Inputs: &[]btcjson.RawTxInput{
1121  					{
1122  						Txid:         "123",
1123  						Vout:         1,
1124  						ScriptPubKey: "00",
1125  						RedeemScript: "01",
1126  					},
1127  				},
1128  				PrivKeys: nil,
1129  				Flags:    btcjson.String("ALL"),
1130  			},
1131  		},
1132  		{
1133  			name: "signrawtransaction optional2",
1134  			newCmd: func() (interface{}, error) {
1135  				return btcjson.NewCmd("signrawtransaction", "001122", `[]`, `["abc"]`)
1136  			},
1137  			staticCmd: func() interface{} {
1138  				txInputs := []btcjson.RawTxInput{}
1139  				privKeys := []string{"abc"}
1140  				return btcjson.NewSignRawTransactionCmd("001122", &txInputs, &privKeys, nil)
1141  			},
1142  			marshalled: `{"jsonrpc":"1.0","method":"signrawtransaction","netparams":["001122",[],["abc"]],"id":1}`,
1143  			unmarshalled: &btcjson.SignRawTransactionCmd{
1144  				RawTx:    "001122",
1145  				Inputs:   &[]btcjson.RawTxInput{},
1146  				PrivKeys: &[]string{"abc"},
1147  				Flags:    btcjson.String("ALL"),
1148  			},
1149  		},
1150  		{
1151  			name: "signrawtransaction optional3",
1152  			newCmd: func() (interface{}, error) {
1153  				return btcjson.NewCmd("signrawtransaction", "001122", `[]`, `[]`, "ALL")
1154  			},
1155  			staticCmd: func() interface{} {
1156  				txInputs := []btcjson.RawTxInput{}
1157  				privKeys := []string{}
1158  				return btcjson.NewSignRawTransactionCmd("001122", &txInputs, &privKeys,
1159  					btcjson.String("ALL"),
1160  				)
1161  			},
1162  			marshalled: `{"jsonrpc":"1.0","method":"signrawtransaction","netparams":["001122",[],[],"ALL"],"id":1}`,
1163  			unmarshalled: &btcjson.SignRawTransactionCmd{
1164  				RawTx:    "001122",
1165  				Inputs:   &[]btcjson.RawTxInput{},
1166  				PrivKeys: &[]string{},
1167  				Flags:    btcjson.String("ALL"),
1168  			},
1169  		},
1170  		{
1171  			name: "walletlock",
1172  			newCmd: func() (interface{}, error) {
1173  				return btcjson.NewCmd("walletlock")
1174  			},
1175  			staticCmd: func() interface{} {
1176  				return btcjson.NewWalletLockCmd()
1177  			},
1178  			marshalled:   `{"jsonrpc":"1.0","method":"walletlock","netparams":[],"id":1}`,
1179  			unmarshalled: &btcjson.WalletLockCmd{},
1180  		},
1181  		{
1182  			name: "walletpassphrase",
1183  			newCmd: func() (interface{}, error) {
1184  				return btcjson.NewCmd("walletpassphrase", "pass", 60)
1185  			},
1186  			staticCmd: func() interface{} {
1187  				return btcjson.NewWalletPassphraseCmd("pass", 60)
1188  			},
1189  			marshalled: `{"jsonrpc":"1.0","method":"walletpassphrase","netparams":["pass",60],"id":1}`,
1190  			unmarshalled: &btcjson.WalletPassphraseCmd{
1191  				Passphrase: "pass",
1192  				Timeout:    60,
1193  			},
1194  		},
1195  		{
1196  			name: "walletpassphrasechange",
1197  			newCmd: func() (interface{}, error) {
1198  				return btcjson.NewCmd("walletpassphrasechange", "old", "new")
1199  			},
1200  			staticCmd: func() interface{} {
1201  				return btcjson.NewWalletPassphraseChangeCmd("old", "new")
1202  			},
1203  			marshalled: `{"jsonrpc":"1.0","method":"walletpassphrasechange","netparams":["old","new"],"id":1}`,
1204  			unmarshalled: &btcjson.WalletPassphraseChangeCmd{
1205  				OldPassphrase: "old",
1206  				NewPassphrase: "new",
1207  			},
1208  		},
1209  	}
1210  	t.Logf("Running %d tests", len(tests))
1211  	for i, test := range tests {
1212  		// Marshal the command as created by the new static command creation function.
1213  		marshalled, e := btcjson.MarshalCmd(testID, test.staticCmd())
1214  		if e != nil {
1215  			t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i, test.name, e)
1216  			continue
1217  		}
1218  		if !bytes.Equal(marshalled, []byte(test.marshalled)) {
1219  			t.Errorf("Test #%d (%s) unexpected marshalled data - "+
1220  				"got %s, want %s", i, test.name, marshalled,
1221  				test.marshalled,
1222  			)
1223  			continue
1224  		}
1225  		// Ensure the command is created without error via the generic new command creation function.
1226  		cmd, e := test.newCmd()
1227  		if e != nil {
1228  			t.Errorf("Test #%d (%s) unexpected NewCmd error: %v ",
1229  				i, test.name, e,
1230  			)
1231  		}
1232  		// Marshal the command as created by the generic new command creation function.
1233  		marshalled, e = btcjson.MarshalCmd(testID, cmd)
1234  		if e != nil {
1235  			t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i,
1236  				test.name, e,
1237  			)
1238  			continue
1239  		}
1240  		if !bytes.Equal(marshalled, []byte(test.marshalled)) {
1241  			t.Errorf("Test #%d (%s) unexpected marshalled data - "+
1242  				"got %s, want %s", i, test.name, marshalled,
1243  				test.marshalled,
1244  			)
1245  			continue
1246  		}
1247  		var request btcjson.Request
1248  		if e = json.Unmarshal(marshalled, &request); E.Chk(e) {
1249  			t.Errorf("Test #%d (%s) unexpected error while "+
1250  				"unmarshalling JSON-RPC request: %v", i,
1251  				test.name, e,
1252  			)
1253  			continue
1254  		}
1255  		cmd, e = btcjson.UnmarshalCmd(&request)
1256  		if e != nil {
1257  			t.Errorf("UnmarshalCmd #%d (%s) unexpected error: %v", i,
1258  				test.name, e,
1259  			)
1260  			continue
1261  		}
1262  		if !reflect.DeepEqual(cmd, test.unmarshalled) {
1263  			t.Errorf("Test #%d (%s) unexpected unmarshalled command "+
1264  				"- got %s, want %s", i, test.name,
1265  				fmt.Sprintf("(%T) %+[1]v", cmd),
1266  				fmt.Sprintf("(%T) %+[1]v\n", test.unmarshalled),
1267  			)
1268  			continue
1269  		}
1270  	}
1271  }
1272