-
Notifications
You must be signed in to change notification settings - Fork 2
Websocket JSON RPC API
-
Overview
-
Authentication
2.1. Overview
2.2. HTTP Basic Access Authentication
2.3. JSON-RPC Authenticate Command
-
Extension Requests
3.1. Extension Request Overview
3.2. Extension Request Details
-
Notifications
4.1. Notification Overview
4.2. Notification Details
-
Example Go Applications
5.1. Rescan and blockconnected
-
Example node.js Code
6.1. Using notifyblocks to be Notified of Block Connects and Disconnects
btcd websocket RPC, like standard RPC, is performed using requests and responses following the JSON-RPC specification. All implemented standard RPC requests are also available for use by websocket connections, with the only difference being that all requests and responses are sent asynchronously. Please reference the [JSON-RPC API](JSON RPC API) for documentation on btcd standard command support.
In addition to the standard API, an extension API has been developed that is exclusive to clients using websockets. In its current state, this API attempts to cover features found missing in the standard API during the development of btcwallet.
The extension API should be considered a work in progress, incomplete, and susceptible to changes (both additions and removals).
### 2. Authentication **2.1 Authentication Overview**The following authentication details are needed before establishing a connection to a btcd websocket RPC server:
- rpcuser is the username that the btcd RPC server is configured with
- rpcpass is the password that the btcd RPC server is configured with
-
rpccert is the the PEM-encoded X.509 certificate (public key) that the btcd server is configured with. It is automatically generated by btcd and placed in the btcd home directory (which is typically
%LOCALAPPDATA%\Btcd
on Windows and~/.btcd
on POSIX-like OSes)
NOTE: As mentioned above, btcd is secure by default which means the RPC server is not running unless configured with a rpcuser and rpcpass and uses TLS authentication for all connections. TODO: Insert link to documentation for configuring the RPC server here.
Armed with these details, you can choose one of two, mutually exclusive, methods.
**2.2 HTTP Basic Access Authentication**The btcd RPC server uses HTTP basic access authentication with the rpcuser and rpcpass detailed above. When a websocket connection is established with the Authorization header, it will be used to validate your credentials. If the supplied credentials are invalid, you will be disconnected immediately upon making the connection. When the credentials are valid, your websocket is marked authenticated and all commands are available with no further action needed.
This is the preferred authentication method as it is typically much easier to simply set your authentication information in the HTTP headers before establishing the connection.
**2.3 JSON-RPC Authenticate Command**While the HTTP basic access authentication method is the preferred method, the ability to set HTTP headers from websockets is not always available. In that case, you will need to use the authenticate JSON-RPC method.
The authenticate command must be the first command sent after connecting to the websocket. Sending any other commands before authenticating, supplying invalid credentials, or attempting to authenticate again when already authenticated will cause the websocket to be closed immediately.
### 3. Extension Requests **3.1 Extension Request Overview**The following is an overview of the RPC extension requests available to websocket connections. Click the method name for further details such as parameter and return information.
# | Method | Description |
---|---|---|
1 | authenticate | Authenticate the connection against the username and passphrase configured for the RPC server. NOTE: This is only required if an HTTP Authorization header is not being used. |
2 | getbestblock | Get block height and hash of best block in the main chain. |
3 | getcurrentnet | Get bitcoin network btcd is running on. |
4 | notifyblocks | Send notifications when a block is connected or disconnected from the best chain. |
5 | notifynewtxs | Send notifications when a txout spends to an address. |
6 | notifyspent | Send notification when a txout is spent. |
7 | rescan | Rescan blockchain for transactions to addresses. |
8 | notifyallnewtxs | Send notifications for all new transactions |
Method | authenticate |
Parameters | 1. username (string, required) 2. passphrase (string, required) |
Description | Authenticate the connection against the username and password configured for the RPC server. Invoking any other method before authenticating with this command will close the connection. NOTE: This is only required if an HTTP Authorization header is not being used. |
Returns | Success: Nothing Failure: Nothing (websocket disconnected) |
Return to Request Overview |
Method | getbestblock |
Parameters | None |
Description | Get block height and hash of best block in the main chain. |
Returns |
{ (json object) "hash": "data", (string) the hex-encoded bytes of the best block hash "height": n (numeric) the block height of the best block }
|
Return to Request Overview |
Method | getcurrentnet |
Parameters | None |
Description | Get bitcoin network btcd is running on. |
Returns | numeric |
Example Return |
3652501241 (mainnet)118034699 (testnet3) |
Return to Request Overview |
Method | notifyblocks |
Notifications | blockconnected and blockdisconnected |
Parameters | None |
Description | Request notifications for whenever a block is connected or disconnected from the main (best) chain. |
Returns | Nothing |
Return to Request Overview |
Method | notifynewtxs |
Notifications | recvtx and redeemingtx |
Parameters | 1. Addresses (JSON array, required)[ (json array of strings) "bitcoinaddress", (string) the bitcoin address ... ]
|
Description | Send a recvtx notification when a transaction added to mempool or appears in a newly-attached block contains a txout pkScript sending to any of the passed addresses. Matching outpoints are automatically registered for redeemingtx notifications. |
Returns | Nothing |
Return to Request Overview |
Method | notifyspent |
Notifications | redeemingtx |
Parameters | 1. TxSha (string, required) the hex-encoded bytes of the outpoint transaction hash 2. Index (numeric, required) the txout index of the outpoint |
Description | Send a redeemingtx notification when a transaction spending the outpoint appears in mempool (if relayed to this btcd instance) and when such a transaction first appears in a newly-attached block. |
Returns | Nothing |
Return to Request Overview |
Method | rescan |
Notifications | recvtx and redeemingtx |
Parameters | 1. BeginBlock (numeric, required) block height to begin rescanning from 2. Addresses (JSON object, required) { (JSON object) "bitcoinaddress": null, ... } 3. EndBlock (numeric, option) height of final block to rescan |
Description | Rescan blockchain for transactions to addresses, starting at block height BeginBlock and ending at height EndBlock. If EndBlock is omitted, the rescan continues through the best block in the main chain. Rescan results are sent as recvtx and redeemingtx notifications. This call returns once the rescan completes. |
Returns | Nothing |
Return to Request Overview |
Method | notifyallnewtxs |
Notifications | alltx or allverbosetx |
Parameters | 1. verbose (boolean, optional, default=false) - specifies which type of notification to receive. If verbose is true, then the caller receives allverbosetx, otherwise the caller receives alltx |
Description | Send either an alltx or an allverbosetx notification when a new transaction is accepted. |
Returns | Nothing |
Return to Request Overview |
btcd uses standard JSON-RPC notifications to notify clients of changes, rather than requiring clients to poll btcd for updates. JSON-RPC notifications are a subset of requests, but do not contain an ID. The notification type is categorized by the method
field, and additional details are sent as a JSON array in the params
field.
The following is an overview of the JSON-RPC notifications used for websocket connections. Click the method name for further details of the context(s) in which they are sent and their parameters.
# | Method | Description |
---|---|---|
1 | blockconnected | Block connected to the main chain. |
2 | blockdisconnected | Block disconnected from the main chain. |
3 | recvtx | Processed a transaction output spending to a wallet address. |
4 | redeemingtx | Processed a transaction that spends a registered outpoint. |
5 | alltx | Received a new transaction after requesting simple notifications of all new transactions. |
6 | allverbosetx | Received a new transaction after requesting verbose notifications of all new transactions. |
Method | blockconnected |
Request | notifyblocks |
Parameters | 1. BlockHash (string) hex-encoded bytes of the attached block hash 2. BlockHeight (numeric) height of the attached block |
Description | Notifies when a block has been added to the main chain. Notification is sent to all connected clients. |
Example | Example blockconnected notification for mainnet block 280330 (newlines added for readability):{ "jsonrpc": "1.0", "method": "blockconnected", "params": [ "000000000000000004cbdfe387f4df44b914e464ca79838a8ab777b3214dbffd", 280330 ], "id": null }
|
Return to Notification Overview |
Method | blockdisconnected |
Request | notifyblocks |
Parameters | 1. BlockHash (string) hex-encoded bytes of the disconnected block hash 2. BlockHeight (numeric) height of the disconnected block |
Description | Notifies when a block has been removed from the main chain. Notification is sent to all connected clients. |
Example | Example blockdisconnected notification for mainnet block 280330 (newlines added for readability):{ "jsonrpc": "1.0", "method": "blockdisconnected", "params": [ "000000000000000004cbdfe387f4df44b914e464ca79838a8ab777b3214dbffd", 280330 ], "id": null }
|
Return to Notification Overview |
Method | recvtx |
Request | rescan or notifynewtxs |
Parameters | 1. Transaction (string) full transaction encoded as a hex string 2. Block details (object, optional) details about a block and the index of the transaction within a block, if the transaction is mined |
Description | Notifies a client when a transaction is processed that contains at least a single output with a pkScript sending to a requested address. If multiple outputs send to requested addresses, a single notification is sent. If a mempool (unmined) transaction is processed, the block details object (second parameter) is excluded. |
Example | Example recvtx notification for mainnet transaction 61d3696de4c888730cbe06b0ad8ecb6d72d6108e893895aa9bc067bd7eba3fad when processed by mempool (newlines added for readability):{ "jsonrpc": "1.0", "method": "recvtx", "params": [ "010000000114d9ff358894c486b4ae11c2a8cf7851b1df64c53d2e511278eff17c22fb737300000000..." ], "id": null } The recvtx notification for the same txout, after the transaction was mined into block 276425: { "jsonrpc": "1.0", "method": "recvtx", "params": [ "010000000114d9ff358894c486b4ae11c2a8cf7851b1df64c53d2e511278eff17c22fb737300000000...", { "height": 276425, "hash": "000000000000000325474bb799b9e591f965ca4461b72cb7012b808db92bb2fc", "index": 684, "time": 1387737310 } ], "id": null }
|
Return to Notification Overview |
Method | redeemingtx |
Requests | notifyspent and rescan |
Parameters | 1. Transaction (string) full transaction encoded as a hex string 2. Block details (object, optional) details about a block and the index of the transaction within a block, if the transaction is mined |
Description | Notifies a client when an registered outpoint is spent by a transaction accepted to mempool and/or mined into a block. |
Example | Example redeemingtx notification for mainnet outpoint 61d3696de4c888730cbe06b0ad8ecb6d72d6108e893895aa9bc067bd7eba3fad:0 after being spent by transaction 4ad0c16ac973ff675dec1f3e5f1273f1c45be2a63554343f21b70240a1e43ece (newlines added for readability):{ "jsonrpc": "1.0", "method": "redeemingtx", "params": [ "0100000003ad3fba7ebd67c09baa9538898e10d6726dcb8eadb006be0c7388c8e46d69d3610000000..." ], "id": null } The redeemingtx notification for the same txout, after the spending transaction was mined into block 279143: { "jsonrpc": "1.0", "method": "recvtx", "params": [ "0100000003ad3fba7ebd67c09baa9538898e10d6726dcb8eadb006be0c7388c8e46d69d3610000000...", { "height": 279143, "hash": "00000000000000017188b968a371bab95aa43522665353b646e41865abae02a4", "index": 6, "time": 1389115004 } ], "id": null }
|
Return to Notification Overview |
Method | alltx |
Request | notifyallnewtx |
Parameters | 1. TxSha (string) hex-encoded bytes of the transaction hash 2. Amount (numeric) sum of the value of all the transaction outpoints |
Description | Notifies when a new transaction has been accepted and the client has requested standard transaction details. |
Example | Example alltx notification for mainnet transaction id "16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261" (newlines added for readability):{ "jsonrpc": "1.0", "method": "alltx", "params": [ "16c54c9d02fe570b9d41b518c0daefae81cc05c69bbe842058e84c6ed5826261", 55838384 ], "id": null }
|
Return to Notification Overview |
Method | allverbosetx |
Request | notifyallnewtx |
Parameters | 1. RawTx (json object) the transaction as a json object (see getrawtransaction json object details) |
Description | Notifies when a new transaction has been accepted and the client has requested verbose transaction details. |
Example | Example allverbosetx notification (newlines added for readability):{ "jsonrpc": "1.0", "method": "allverbosetx", "params": [ { "hex": "01000000010000000000000000000000000000000000000000000000000000000000000000f...", "txid": "90743aad855880e517270550d2a881627d84db5265142fd1e7fb7add38b08be9", "version": 1, "locktime": 0, "vin": [ For coinbase transactions: { (json object) "coinbase": "03708203062f503253482f04066d605108f800080100000ea2122f6f7a636f696e4065757374726174756d2f", "sequence": 0, } For non-coinbase transactions: { "txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04", "vout": 0, "scriptSig": { "asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...", "hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...", } "sequence": 4294967295, } ], "vout": [ { "value": 25.1394, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 ea132286328cfc819457b9dec386c4b5c84faa5c OP_EQUALVERIFY OP_CHECKSIG", "hex": "76a914ea132286328cfc819457b9dec386c4b5c84faa5c88ac", "reqSigs": 1, "type": "pubkeyhash" "addresses": [ "1NLg3QJMsMQGM5KEUaEu5ADDmKQSLHwmyh", ] } ] } ], "id": null }
|
Return to Notification Overview |
The following Go application shows how to open a btcd websocket connection and send/receive messages to/from btcd. Notifications are requested for connected and disconnected blocks, and a rescan request is created for a single address. Notification handlers are set up for the processedtx (sent as a rescan result), blockconnected, and blockdisconnected notifications.
package main
import (
"code.google.com/p/go.net/websocket"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"encoding/hex"
"fmt"
"github.com/conformal/btcjson"
"github.com/conformal/btcutil"
"github.com/conformal/btcws"
"io/ioutil"
"log"
)
func main() {
// Read certificates for TLS connection.
certs, err := ioutil.ReadFile("/path/to/btcd/appdata/rpc.cert")
if err != nil {
log.Fatal(err)
}
// Open websocket connection to mainnet btcd.
ws, err := BtcdWS("localhost:8334", certs, "user", "pass")
if err != nil {
log.Fatal(err)
}
// Receive replies/notifications from btcd and send across
// a channel to handle from another goroutine.
marshaledReplies := make(chan string)
go func() {
for {
var s string
err := websocket.Message.Receive(ws, &s)
if err != nil {
log.Fatalf("cannot receive btcd message: %v", err)
}
marshaledReplies <- s
}
}()
// Send commands received from a channel to btcd.
sendCmd := make(chan btcjson.Cmd)
go func() {
for cmd := range sendCmd {
mcmd, err := cmd.MarshalJSON()
if err != nil {
log.Printf("cannot marshal request: %v", err)
continue
}
err = websocket.Message.Send(ws, mcmd)
if err != nil {
log.Printf("cannot send request: %v", err)
continue
}
log.Printf("sent %v request with id %v\n", cmd.Method(), cmd.Id())
}
}()
// Marshal and send a request for blockconnected and blockdisconnected
// notifications.
blockCmd := btcws.NewNotifyBlocksCmd(0)
sendCmd <- blockCmd
// Marshal and send a rescan request (starting at block height 276000)
// for a single address.
addrs := map[string]struct{}{
"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH": struct{}{},
}
rescanCmd, err := btcws.NewRescanCmd(1, 276000, addrs)
if err == nil {
sendCmd <- rescanCmd
}
// Wait for and handle btcd notifications.
for {
reply := <-marshaledReplies
// Try unmarshaling as a notification. btcjson.Cmds
// with no IDs are notifications.
if n, err := btcjson.ParseMarshaledCmd([]byte(reply)); err == nil {
if n.Id() != nil {
log.Printf("received a request")
continue
}
switch cn := n.(type) {
case *btcws.BlockConnectedNtfn:
log.Printf("block %v (height %v) connected to chain", cn.Hash, cn.Height)
case *btcws.BlockDisconnectedNtfn:
log.Printf("block %v (height %v) disconnected from chain", cn.Hash, cn.Height)
case *btcws.RecvTxNtfn: // from a rescan request
if cn.Block == nil {
continue
}
serializedTx, err := hex.DecodeString(cn.HexTx)
if err != nil {
log.Printf("cannot parse transaction hex: %v", err)
}
tx, err := btcutil.NewTxFromBytes(serializedTx)
if err != nil {
log.Printf("cannot parse transaction: %v", err)
continue
}
log.Printf("rescanned block %v includes tx %v sending to a registered address",
cn.Block.Hash, tx.Sha())
case *btcws.RedeemingTxNtfn: // from a rescan request
if cn.Block == nil {
continue
}
serializedTx, err := hex.DecodeString(cn.HexTx)
if err != nil {
log.Printf("cannot parse transaction hex: %v", err)
}
tx, err := btcutil.NewTxFromBytes(serializedTx)
if err != nil {
log.Printf("cannot parse transaction: %v", err)
continue
}
log.Printf("rescanned block %v includes tx %v spending a registered outpoint",
cn.Block.Hash, tx.Sha())
}
}
// Should be a response. Real code would unmashal as one,
// check the id, and pass to a handler specific for the
// expected result.
}
}
// BtcdWS opens a websocket connection to a btcd instance.
func BtcdWS(connect string, certificates []byte, user, pass string) (*websocket.Conn, error) {
url := fmt.Sprintf("wss://%s/ws", connect)
config, err := websocket.NewConfig(url, "https://localhost/")
if err != nil {
return nil, err
}
// btcd uses a self-signed TLS certifiate which is used as the CA.
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(certificates)
config.TlsConfig = &tls.Config{
RootCAs: pool,
MinVersion: tls.VersionTLS12,
}
// btcd requires basic authorization, so set the Authorization header.
login := user + ":" + pass
auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login))
config.Header.Add("Authorization", auth)
// Dial connection.
return websocket.DialConfig(config)
}
Example output:
2014/03/05 11:34:38 sent notifyblocks request with id 0
2014/03/05 11:34:38 sent rescan request with id 1
2014/03/05 11:34:44 rescanned block 000000000000000325474bb799b9e591f965ca4461b72cb7012b808db92bb2fc includes tx 61d3696de4c888730cbe06b0ad8ecb6d72d6108e893895aa9bc067bd7eba3fad sending to a registered address
2014/03/05 11:35:23 rescanned block 00000000000000017188b968a371bab95aa43522665353b646e41865abae02a4 includes tx 4ad0c16ac973ff675dec1f3e5f1273f1c45be2a63554343f21b70240a1e43ece spending a registered outpoint
2014/03/05 11:38:05 block 0000000000000000a421dd7fe41f8a75e3d32b85b6c5cd45af15b1338991110a (height 289059) connected to chain
The following is example node.js code which uses ws (can be installed with npm install ws
) to connect with a btcd instance, issues notifyblocks to register for blockconnected and blockdisconnected notifications, and displays all incoming messages.
var fs = require('fs');
var WebSocket = require('ws');
// Load the certificate for the TLS connection which is automatically
// generated by btcd when it starts the RPC server and doesn't already
// have one.
var cert = fs.readFileSync('/path/to/btcd/appdata/rpc.cert');
var user = "yourusername";
var password = "yourpassword";
// Initiate the websocket connection. The btcd generated certificate acts as
// its own certificate authority, so it needs to be specified in the 'ca' array
// for the certificate to properly validate.
var ws = new WebSocket('wss://127.0.0.1:8334/ws', {
headers: {
'Authorization': 'Basic '+new Buffer(user+':'+password).toString('base64')
},
cert: cert,
ca: [cert]
});
ws.on('open', function() {
console.log('CONNECTED');
// Send a JSON-RPC command to be notified when blocks are connected and
// disconnected from the chain.
ws.send('{"jsonrpc":"1.0","id":"0","method":"notifyblocks","params":[]}');
});
ws.on('message', function(data, flags) {
console.log(data);
});
ws.on('error', function(derp) {
console.log('ERROR:' + derp);
})
ws.on('close', function(data) {
console.log('DISCONNECTED');
})