github.com/palcoin-project/palcd@v1.0.0/rpcclient/extensions.go (about) 1 // Copyright (c) 2014-2017 The btcsuite developers 2 // Copyright (c) 2015-2017 The Decred developers 3 // Use of this source code is governed by an ISC 4 // license that can be found in the LICENSE file. 5 6 package rpcclient 7 8 import ( 9 "bytes" 10 "encoding/base64" 11 "encoding/hex" 12 "encoding/json" 13 "fmt" 14 15 "github.com/palcoin-project/palcd/btcjson" 16 "github.com/palcoin-project/palcd/chaincfg/chainhash" 17 "github.com/palcoin-project/palcd/wire" 18 "github.com/palcoin-project/palcutil" 19 ) 20 21 // FutureDebugLevelResult is a future promise to deliver the result of a 22 // DebugLevelAsync RPC invocation (or an applicable error). 23 type FutureDebugLevelResult chan *response 24 25 // Receive waits for the response promised by the future and returns the result 26 // of setting the debug logging level to the passed level specification or the 27 // list of of the available subsystems for the special keyword 'show'. 28 func (r FutureDebugLevelResult) Receive() (string, error) { 29 res, err := receiveFuture(r) 30 if err != nil { 31 return "", err 32 } 33 34 // Unmashal the result as a string. 35 var result string 36 err = json.Unmarshal(res, &result) 37 if err != nil { 38 return "", err 39 } 40 return result, nil 41 } 42 43 // DebugLevelAsync returns an instance of a type that can be used to get the 44 // result of the RPC at some future time by invoking the Receive function on 45 // the returned instance. 46 // 47 // See DebugLevel for the blocking version and more details. 48 // 49 // NOTE: This is a btcd extension. 50 func (c *Client) DebugLevelAsync(levelSpec string) FutureDebugLevelResult { 51 cmd := btcjson.NewDebugLevelCmd(levelSpec) 52 return c.sendCmd(cmd) 53 } 54 55 // DebugLevel dynamically sets the debug logging level to the passed level 56 // specification. 57 // 58 // The levelspec can be either a debug level or of the form: 59 // <subsystem>=<level>,<subsystem2>=<level2>,... 60 // 61 // Additionally, the special keyword 'show' can be used to get a list of the 62 // available subsystems. 63 // 64 // NOTE: This is a btcd extension. 65 func (c *Client) DebugLevel(levelSpec string) (string, error) { 66 return c.DebugLevelAsync(levelSpec).Receive() 67 } 68 69 // FutureCreateEncryptedWalletResult is a future promise to deliver the error 70 // result of a CreateEncryptedWalletAsync RPC invocation. 71 type FutureCreateEncryptedWalletResult chan *response 72 73 // Receive waits for and returns the error response promised by the future. 74 func (r FutureCreateEncryptedWalletResult) Receive() error { 75 _, err := receiveFuture(r) 76 return err 77 } 78 79 // CreateEncryptedWalletAsync returns an instance of a type that can be used to 80 // get the result of the RPC at some future time by invoking the Receive 81 // function on the returned instance. 82 // 83 // See CreateEncryptedWallet for the blocking version and more details. 84 // 85 // NOTE: This is a btcwallet extension. 86 func (c *Client) CreateEncryptedWalletAsync(passphrase string) FutureCreateEncryptedWalletResult { 87 cmd := btcjson.NewCreateEncryptedWalletCmd(passphrase) 88 return c.sendCmd(cmd) 89 } 90 91 // CreateEncryptedWallet requests the creation of an encrypted wallet. Wallets 92 // managed by btcwallet are only written to disk with encrypted private keys, 93 // and generating wallets on the fly is impossible as it requires user input for 94 // the encryption passphrase. This RPC specifies the passphrase and instructs 95 // the wallet creation. This may error if a wallet is already opened, or the 96 // new wallet cannot be written to disk. 97 // 98 // NOTE: This is a btcwallet extension. 99 func (c *Client) CreateEncryptedWallet(passphrase string) error { 100 return c.CreateEncryptedWalletAsync(passphrase).Receive() 101 } 102 103 // FutureListAddressTransactionsResult is a future promise to deliver the result 104 // of a ListAddressTransactionsAsync RPC invocation (or an applicable error). 105 type FutureListAddressTransactionsResult chan *response 106 107 // Receive waits for the response promised by the future and returns information 108 // about all transactions associated with the provided addresses. 109 func (r FutureListAddressTransactionsResult) Receive() ([]btcjson.ListTransactionsResult, error) { 110 res, err := receiveFuture(r) 111 if err != nil { 112 return nil, err 113 } 114 115 // Unmarshal the result as an array of listtransactions objects. 116 var transactions []btcjson.ListTransactionsResult 117 err = json.Unmarshal(res, &transactions) 118 if err != nil { 119 return nil, err 120 } 121 return transactions, nil 122 } 123 124 // ListAddressTransactionsAsync returns an instance of a type that can be used 125 // to get the result of the RPC at some future time by invoking the Receive 126 // function on the returned instance. 127 // 128 // See ListAddressTransactions for the blocking version and more details. 129 // 130 // NOTE: This is a btcd extension. 131 func (c *Client) ListAddressTransactionsAsync(addresses []palcutil.Address, account string) FutureListAddressTransactionsResult { 132 // Convert addresses to strings. 133 addrs := make([]string, 0, len(addresses)) 134 for _, addr := range addresses { 135 addrs = append(addrs, addr.EncodeAddress()) 136 } 137 cmd := btcjson.NewListAddressTransactionsCmd(addrs, &account) 138 return c.sendCmd(cmd) 139 } 140 141 // ListAddressTransactions returns information about all transactions associated 142 // with the provided addresses. 143 // 144 // NOTE: This is a btcwallet extension. 145 func (c *Client) ListAddressTransactions(addresses []palcutil.Address, account string) ([]btcjson.ListTransactionsResult, error) { 146 return c.ListAddressTransactionsAsync(addresses, account).Receive() 147 } 148 149 // FutureGetBestBlockResult is a future promise to deliver the result of a 150 // GetBestBlockAsync RPC invocation (or an applicable error). 151 type FutureGetBestBlockResult chan *response 152 153 // Receive waits for the response promised by the future and returns the hash 154 // and height of the block in the longest (best) chain. 155 func (r FutureGetBestBlockResult) Receive() (*chainhash.Hash, int32, error) { 156 res, err := receiveFuture(r) 157 if err != nil { 158 return nil, 0, err 159 } 160 161 // Unmarshal result as a getbestblock result object. 162 var bestBlock btcjson.GetBestBlockResult 163 err = json.Unmarshal(res, &bestBlock) 164 if err != nil { 165 return nil, 0, err 166 } 167 168 // Convert to hash from string. 169 hash, err := chainhash.NewHashFromStr(bestBlock.Hash) 170 if err != nil { 171 return nil, 0, err 172 } 173 174 return hash, bestBlock.Height, nil 175 } 176 177 // GetBestBlockAsync returns an instance of a type that can be used to get the 178 // result of the RPC at some future time by invoking the Receive function on the 179 // returned instance. 180 // 181 // See GetBestBlock for the blocking version and more details. 182 // 183 // NOTE: This is a btcd extension. 184 func (c *Client) GetBestBlockAsync() FutureGetBestBlockResult { 185 cmd := btcjson.NewGetBestBlockCmd() 186 return c.sendCmd(cmd) 187 } 188 189 // GetBestBlock returns the hash and height of the block in the longest (best) 190 // chain. 191 // 192 // NOTE: This is a btcd extension. 193 func (c *Client) GetBestBlock() (*chainhash.Hash, int32, error) { 194 return c.GetBestBlockAsync().Receive() 195 } 196 197 // FutureGetCurrentNetResult is a future promise to deliver the result of a 198 // GetCurrentNetAsync RPC invocation (or an applicable error). 199 type FutureGetCurrentNetResult chan *response 200 201 // Receive waits for the response promised by the future and returns the network 202 // the server is running on. 203 func (r FutureGetCurrentNetResult) Receive() (wire.BitcoinNet, error) { 204 res, err := receiveFuture(r) 205 if err != nil { 206 return 0, err 207 } 208 209 // Unmarshal result as an int64. 210 var net int64 211 err = json.Unmarshal(res, &net) 212 if err != nil { 213 return 0, err 214 } 215 216 return wire.BitcoinNet(net), nil 217 } 218 219 // GetCurrentNetAsync returns an instance of a type that can be used to get the 220 // result of the RPC at some future time by invoking the Receive function on the 221 // returned instance. 222 // 223 // See GetCurrentNet for the blocking version and more details. 224 // 225 // NOTE: This is a btcd extension. 226 func (c *Client) GetCurrentNetAsync() FutureGetCurrentNetResult { 227 cmd := btcjson.NewGetCurrentNetCmd() 228 return c.sendCmd(cmd) 229 } 230 231 // GetCurrentNet returns the network the server is running on. 232 // 233 // NOTE: This is a btcd extension. 234 func (c *Client) GetCurrentNet() (wire.BitcoinNet, error) { 235 return c.GetCurrentNetAsync().Receive() 236 } 237 238 // FutureGetHeadersResult is a future promise to deliver the result of a 239 // getheaders RPC invocation (or an applicable error). 240 // 241 // NOTE: This is a btcsuite extension ported from 242 // github.com/decred/dcrrpcclient. 243 type FutureGetHeadersResult chan *response 244 245 // Receive waits for the response promised by the future and returns the 246 // getheaders result. 247 // 248 // NOTE: This is a btcsuite extension ported from 249 // github.com/decred/dcrrpcclient. 250 func (r FutureGetHeadersResult) Receive() ([]wire.BlockHeader, error) { 251 res, err := receiveFuture(r) 252 if err != nil { 253 return nil, err 254 } 255 256 // Unmarshal result as a slice of strings. 257 var result []string 258 err = json.Unmarshal(res, &result) 259 if err != nil { 260 return nil, err 261 } 262 263 // Deserialize the []string into []wire.BlockHeader. 264 headers := make([]wire.BlockHeader, len(result)) 265 for i, headerHex := range result { 266 serialized, err := hex.DecodeString(headerHex) 267 if err != nil { 268 return nil, err 269 } 270 err = headers[i].Deserialize(bytes.NewReader(serialized)) 271 if err != nil { 272 return nil, err 273 } 274 } 275 return headers, nil 276 } 277 278 // GetHeadersAsync returns an instance of a type that can be used to get the result 279 // of the RPC at some future time by invoking the Receive function on the returned instance. 280 // 281 // See GetHeaders for the blocking version and more details. 282 // 283 // NOTE: This is a btcsuite extension ported from 284 // github.com/decred/dcrrpcclient. 285 func (c *Client) GetHeadersAsync(blockLocators []chainhash.Hash, hashStop *chainhash.Hash) FutureGetHeadersResult { 286 locators := make([]string, len(blockLocators)) 287 for i := range blockLocators { 288 locators[i] = blockLocators[i].String() 289 } 290 hash := "" 291 if hashStop != nil { 292 hash = hashStop.String() 293 } 294 cmd := btcjson.NewGetHeadersCmd(locators, hash) 295 return c.sendCmd(cmd) 296 } 297 298 // GetHeaders mimics the wire protocol getheaders and headers messages by 299 // returning all headers on the main chain after the first known block in the 300 // locators, up until a block hash matches hashStop. 301 // 302 // NOTE: This is a btcsuite extension ported from 303 // github.com/decred/dcrrpcclient. 304 func (c *Client) GetHeaders(blockLocators []chainhash.Hash, hashStop *chainhash.Hash) ([]wire.BlockHeader, error) { 305 return c.GetHeadersAsync(blockLocators, hashStop).Receive() 306 } 307 308 // FutureExportWatchingWalletResult is a future promise to deliver the result of 309 // an ExportWatchingWalletAsync RPC invocation (or an applicable error). 310 type FutureExportWatchingWalletResult chan *response 311 312 // Receive waits for the response promised by the future and returns the 313 // exported wallet. 314 func (r FutureExportWatchingWalletResult) Receive() ([]byte, []byte, error) { 315 res, err := receiveFuture(r) 316 if err != nil { 317 return nil, nil, err 318 } 319 320 // Unmarshal result as a JSON object. 321 var obj map[string]interface{} 322 err = json.Unmarshal(res, &obj) 323 if err != nil { 324 return nil, nil, err 325 } 326 327 // Check for the wallet and tx string fields in the object. 328 base64Wallet, ok := obj["wallet"].(string) 329 if !ok { 330 return nil, nil, fmt.Errorf("unexpected response type for "+ 331 "exportwatchingwallet 'wallet' field: %T\n", 332 obj["wallet"]) 333 } 334 base64TxStore, ok := obj["tx"].(string) 335 if !ok { 336 return nil, nil, fmt.Errorf("unexpected response type for "+ 337 "exportwatchingwallet 'tx' field: %T\n", 338 obj["tx"]) 339 } 340 341 walletBytes, err := base64.StdEncoding.DecodeString(base64Wallet) 342 if err != nil { 343 return nil, nil, err 344 } 345 346 txStoreBytes, err := base64.StdEncoding.DecodeString(base64TxStore) 347 if err != nil { 348 return nil, nil, err 349 } 350 351 return walletBytes, txStoreBytes, nil 352 353 } 354 355 // ExportWatchingWalletAsync returns an instance of a type that can be used to 356 // get the result of the RPC at some future time by invoking the Receive 357 // function on the returned instance. 358 // 359 // See ExportWatchingWallet for the blocking version and more details. 360 // 361 // NOTE: This is a btcwallet extension. 362 func (c *Client) ExportWatchingWalletAsync(account string) FutureExportWatchingWalletResult { 363 cmd := btcjson.NewExportWatchingWalletCmd(&account, btcjson.Bool(true)) 364 return c.sendCmd(cmd) 365 } 366 367 // ExportWatchingWallet returns the raw bytes for a watching-only version of 368 // wallet.bin and tx.bin, respectively, for the specified account that can be 369 // used by btcwallet to enable a wallet which does not have the private keys 370 // necessary to spend funds. 371 // 372 // NOTE: This is a btcwallet extension. 373 func (c *Client) ExportWatchingWallet(account string) ([]byte, []byte, error) { 374 return c.ExportWatchingWalletAsync(account).Receive() 375 } 376 377 // FutureSessionResult is a future promise to deliver the result of a 378 // SessionAsync RPC invocation (or an applicable error). 379 type FutureSessionResult chan *response 380 381 // Receive waits for the response promised by the future and returns the 382 // session result. 383 func (r FutureSessionResult) Receive() (*btcjson.SessionResult, error) { 384 res, err := receiveFuture(r) 385 if err != nil { 386 return nil, err 387 } 388 389 // Unmarshal result as a session result object. 390 var session btcjson.SessionResult 391 err = json.Unmarshal(res, &session) 392 if err != nil { 393 return nil, err 394 } 395 396 return &session, nil 397 } 398 399 // SessionAsync returns an instance of a type that can be used to get the result 400 // of the RPC at some future time by invoking the Receive function on the 401 // returned instance. 402 // 403 // See Session for the blocking version and more details. 404 // 405 // NOTE: This is a btcsuite extension. 406 func (c *Client) SessionAsync() FutureSessionResult { 407 // Not supported in HTTP POST mode. 408 if c.config.HTTPPostMode { 409 return newFutureError(ErrWebsocketsRequired) 410 } 411 412 cmd := btcjson.NewSessionCmd() 413 return c.sendCmd(cmd) 414 } 415 416 // Session returns details regarding a websocket client's current connection. 417 // 418 // This RPC requires the client to be running in websocket mode. 419 // 420 // NOTE: This is a btcsuite extension. 421 func (c *Client) Session() (*btcjson.SessionResult, error) { 422 return c.SessionAsync().Receive() 423 } 424 425 // FutureVersionResult is a future promise to deliver the result of a version 426 // RPC invocation (or an applicable error). 427 // 428 // NOTE: This is a btcsuite extension ported from 429 // github.com/decred/dcrrpcclient. 430 type FutureVersionResult chan *response 431 432 // Receive waits for the response promised by the future and returns the version 433 // result. 434 // 435 // NOTE: This is a btcsuite extension ported from 436 // github.com/decred/dcrrpcclient. 437 func (r FutureVersionResult) Receive() (map[string]btcjson.VersionResult, 438 error) { 439 res, err := receiveFuture(r) 440 if err != nil { 441 return nil, err 442 } 443 444 // Unmarshal result as a version result object. 445 var vr map[string]btcjson.VersionResult 446 err = json.Unmarshal(res, &vr) 447 if err != nil { 448 return nil, err 449 } 450 451 return vr, nil 452 } 453 454 // VersionAsync returns an instance of a type that can be used to get the result 455 // of the RPC at some future time by invoking the Receive function on the 456 // returned instance. 457 // 458 // See Version for the blocking version and more details. 459 // 460 // NOTE: This is a btcsuite extension ported from 461 // github.com/decred/dcrrpcclient. 462 func (c *Client) VersionAsync() FutureVersionResult { 463 cmd := btcjson.NewVersionCmd() 464 return c.sendCmd(cmd) 465 } 466 467 // Version returns information about the server's JSON-RPC API versions. 468 // 469 // NOTE: This is a btcsuite extension ported from 470 // github.com/decred/dcrrpcclient. 471 func (c *Client) Version() (map[string]btcjson.VersionResult, error) { 472 return c.VersionAsync().Receive() 473 }