func (c *Client) VersionAsync() FutureVersionResult {
	cmd := soterjson.NewVersionCmd()
	return c.sendCmd(cmd)
}
VersionAsync returns an instance of a type that can be used to get the result
of the RPC at some future time by invoking the Receive function on the
returned instance.

See Version for the blocking version and more details.

NOTE: This is a soterd extension ported from
github.com/decred/dcrrpcclient.
package rpcclient
import (
	"bytes"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/soteria-dag/soterd/soterjson"
	"github.com/soteria-dag/soterd/chaincfg/chainhash"
	"github.com/soteria-dag/soterd/wire"
	"github.com/soteria-dag/soterd/soterutil"
)
type FutureDebugLevelResult chan *response
func (r FutureDebugLevelResult) Receive() (string, error) {
	res, err := receiveFuture(r)
	if err != nil {
		return "", err
	}
	var result string
	err = json.Unmarshal(res, &result)
	if err != nil {
		return "", err
	}
	return result, nil
}
func (c *Client) DebugLevelAsync(levelSpec string) FutureDebugLevelResult {
	cmd := soterjson.NewDebugLevelCmd(levelSpec)
	return c.sendCmd(cmd)
}
func (c *Client) DebugLevel(levelSpec string) (string, error) {
	return c.DebugLevelAsync(levelSpec).Receive()
}
type FutureCreateEncryptedWalletResult chan *response
func (r FutureCreateEncryptedWalletResult) Receive() error {
	_, err := receiveFuture(r)
	return err
}
func (c *Client) CreateEncryptedWalletAsync(passphrase string) FutureCreateEncryptedWalletResult {
	cmd := soterjson.NewCreateEncryptedWalletCmd(passphrase)
	return c.sendCmd(cmd)
}
func (c *Client) CreateEncryptedWallet(passphrase string) error {
	return c.CreateEncryptedWalletAsync(passphrase).Receive()
}
type FutureListAddressTransactionsResult chan *response
func (r FutureListAddressTransactionsResult) Receive() ([]soterjson.ListTransactionsResult, error) {
	res, err := receiveFuture(r)
	if err != nil {
		return nil, err
	}
	var transactions []soterjson.ListTransactionsResult
	err = json.Unmarshal(res, &transactions)
	if err != nil {
		return nil, err
	}
	return transactions, nil
}
func (c *Client) ListAddressTransactionsAsync(addresses []soterutil.Address, account string) FutureListAddressTransactionsResult {
	addrs := make([]string, 0, len(addresses))
	for _, addr := range addresses {
		addrs = append(addrs, addr.EncodeAddress())
	}
	cmd := soterjson.NewListAddressTransactionsCmd(addrs, &account)
	return c.sendCmd(cmd)
}
func (c *Client) ListAddressTransactions(addresses []soterutil.Address, account string) ([]soterjson.ListTransactionsResult, error) {
	return c.ListAddressTransactionsAsync(addresses, account).Receive()
}
type FutureGetBestBlockResult chan *response
func (r FutureGetBestBlockResult) Receive() (*chainhash.Hash, int32, error) {
	res, err := receiveFuture(r)
	if err != nil {
		return nil, 0, err
	}
	var bestBlock soterjson.GetBestBlockResult
	err = json.Unmarshal(res, &bestBlock)
	if err != nil {
		return nil, 0, err
	}
	hash, err := chainhash.NewHashFromStr(bestBlock.Hash)
	if err != nil {
		return nil, 0, err
	}
	return hash, bestBlock.Height, nil
}
func (c *Client) GetBestBlockAsync() FutureGetBestBlockResult {
	cmd := soterjson.NewGetBestBlockCmd()
	return c.sendCmd(cmd)
}
func (c *Client) GetBestBlock() (*chainhash.Hash, int32, error) {
	return c.GetBestBlockAsync().Receive()
}
type FutureGetCurrentNetResult chan *response
func (r FutureGetCurrentNetResult) Receive() (wire.SoterNet, error) {
	res, err := receiveFuture(r)
	if err != nil {
		return 0, err
	}
	var net int64
	err = json.Unmarshal(res, &net)
	if err != nil {
		return 0, err
	}
	return wire.SoterNet(net), nil
}
func (c *Client) GetCurrentNetAsync() FutureGetCurrentNetResult {
	cmd := soterjson.NewGetCurrentNetCmd()
	return c.sendCmd(cmd)
}
func (c *Client) GetCurrentNet() (wire.SoterNet, error) {
	return c.GetCurrentNetAsync().Receive()
}
type FutureGetHeadersResult chan *response
func (r FutureGetHeadersResult) Receive() ([]wire.BlockHeader, error) {
	res, err := receiveFuture(r)
	if err != nil {
		return nil, err
	}
	var result []string
	err = json.Unmarshal(res, &result)
	if err != nil {
		return nil, err
	}
	headers := make([]wire.BlockHeader, len(result))
	for i, headerHex := range result {
		serialized, err := hex.DecodeString(headerHex)
		if err != nil {
			return nil, err
		}
		err = headers[i].Deserialize(bytes.NewReader(serialized))
		if err != nil {
			return nil, err
		}
	}
	return headers, nil
}
func (c *Client) GetHeadersAsync(blockLocators []chainhash.Hash, hashStop *chainhash.Hash) FutureGetHeadersResult {
	locators := make([]string, len(blockLocators))
	for i := range blockLocators {
		locators[i] = blockLocators[i].String()
	}
	hash := ""
	if hashStop != nil {
		hash = hashStop.String()
	}
	cmd := soterjson.NewGetHeadersCmd(locators, hash)
	return c.sendCmd(cmd)
}
func (c *Client) GetHeaders(blockLocators []chainhash.Hash, hashStop *chainhash.Hash) ([]wire.BlockHeader, error) {
	return c.GetHeadersAsync(blockLocators, hashStop).Receive()
}
type FutureExportWatchingWalletResult chan *response
func (r FutureExportWatchingWalletResult) Receive() ([]byte, []byte, error) {
	res, err := receiveFuture(r)
	if err != nil {
		return nil, nil, err
	}
	var obj map[string]interface{}
	err = json.Unmarshal(res, &obj)
	if err != nil {
		return nil, nil, err
	}
	base64Wallet, ok := obj["wallet"].(string)
	if !ok {
		return nil, nil, fmt.Errorf("unexpected response type for "+
			"exportwatchingwallet 'wallet' field: %T\n",
			obj["wallet"])
	}
	base64TxStore, ok := obj["tx"].(string)
	if !ok {
		return nil, nil, fmt.Errorf("unexpected response type for "+
			"exportwatchingwallet 'tx' field: %T\n",
			obj["tx"])
	}
	walletBytes, err := base64.StdEncoding.DecodeString(base64Wallet)
	if err != nil {
		return nil, nil, err
	}
	txStoreBytes, err := base64.StdEncoding.DecodeString(base64TxStore)
	if err != nil {
		return nil, nil, err
	}
	return walletBytes, txStoreBytes, nil
}
func (c *Client) ExportWatchingWalletAsync(account string) FutureExportWatchingWalletResult {
	cmd := soterjson.NewExportWatchingWalletCmd(&account, soterjson.Bool(true))
	return c.sendCmd(cmd)
}
func (c *Client) ExportWatchingWallet(account string) ([]byte, []byte, error) {
	return c.ExportWatchingWalletAsync(account).Receive()
}
type FutureSessionResult chan *response
func (r FutureSessionResult) Receive() (*soterjson.SessionResult, error) {
	res, err := receiveFuture(r)
	if err != nil {
		return nil, err
	}
	var session soterjson.SessionResult
	err = json.Unmarshal(res, &session)
	if err != nil {
		return nil, err
	}
	return &session, nil
}
func (c *Client) SessionAsync() FutureSessionResult {
	if c.config.HTTPPostMode {
		return newFutureError(ErrWebsocketsRequired)
	}
	cmd := soterjson.NewSessionCmd()
	return c.sendCmd(cmd)
}
func (c *Client) Session() (*soterjson.SessionResult, error) {
	return c.SessionAsync().Receive()
}
type FutureVersionResult chan *response
func (r FutureVersionResult) Receive() (map[string]soterjson.VersionResult,
	error) {
	res, err := receiveFuture(r)
	if err != nil {
		return nil, err
	}
	var vr map[string]soterjson.VersionResult
	err = json.Unmarshal(res, &vr)
	if err != nil {
		return nil, err
	}
	return vr, nil
}