example_test.go raw

   1  package btcjson_test
   2  
   3  import (
   4  	"encoding/json"
   5  	"fmt"
   6  	
   7  	"github.com/p9c/p9/pkg/btcjson"
   8  )
   9  
  10  // This example demonstrates how to create and marshal a command into a JSON-RPC request.
  11  func ExampleMarshalCmd() {
  12  	// Create a new getblock command.  Notice the nil parameter indicates to use the default parameter for that fields.  This is a common pattern used in all of the New<Foo>Cmd functions in this package for optional fields.  Also, notice the call to json.Bool which is a convenience function for creating a pointer out of a primitive for optional parameters.
  13  	blockHash := "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
  14  	gbCmd := btcjson.NewGetBlockCmd(blockHash, btcjson.Bool(false), nil)
  15  	// Marshal the command to the format suitable for sending to the RPC server.  Typically the client would increment the id here which is request so the response can be identified.
  16  	id := 1
  17  	marshalledBytes, e := btcjson.MarshalCmd(id, gbCmd)
  18  	if e != nil {
  19  		btcjson.E.Ln(e)
  20  		return
  21  	}
  22  	// Display the marshalled command.  Ordinarily this would be sent across the wire to the RPC server, but for this example, just display it.
  23  	fmt.Printf("%s\n", marshalledBytes)
  24  	// Output: {"jsonrpc":"1.0","method":"getblock","netparams":["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",false],"id":1}
  25  }
  26  
  27  // This example demonstrates how to unmarshal a JSON-RPC request and then unmarshal the concrete request into a concrete command.
  28  func ExampleUnmarshalCmd() {
  29  	// Ordinarily this would be read from the wire, but for this example, it is hard coded here for clarity.
  30  	data := []byte(`{"jsonrpc":"1.0","method":"getblock","netparams":["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",false],"id":1}`)
  31  	// Unmarshal the raw bytes from the wire into a JSON-RPC request.
  32  	var request btcjson.Request
  33  	if e := json.Unmarshal(data, &request); E.Chk(e) {
  34  		btcjson.E.Ln(e)
  35  		return
  36  	}
  37  	// Typically there isn't any need to examine the request fields directly like this as the caller already knows what response to expect based on the command it sent.  However, this is done here to demonstrate why the unmarshal process is two steps.
  38  	if request.ID == nil {
  39  		btcjson.E.Ln("Unexpected notification")
  40  		return
  41  	}
  42  	if request.Method != "getblock" {
  43  		btcjson.E.Ln("Unexpected method")
  44  		return
  45  	}
  46  	// Unmarshal the request into a concrete command.
  47  	cmd, e := btcjson.UnmarshalCmd(&request)
  48  	if e != nil {
  49  		btcjson.E.Ln(e)
  50  		return
  51  	}
  52  	// Type assert the command to the appropriate type.
  53  	gbCmd, ok := cmd.(*btcjson.GetBlockCmd)
  54  	if !ok {
  55  		E.F("Incorrect command type: %T\n", cmd)
  56  		return
  57  	}
  58  	// Display the fields in the concrete command.
  59  	fmt.Println("Hash:", gbCmd.Hash)
  60  	fmt.Println("Verbose:", *gbCmd.Verbose)
  61  	fmt.Println("VerboseTx:", *gbCmd.VerboseTx)
  62  	// Output:
  63  	// Hash: 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
  64  	// Verbose: false
  65  	// VerboseTx: false
  66  }
  67  
  68  // This example demonstrates how to marshal a JSON-RPC response.
  69  func ExampleMarshalResponse() {
  70  	// Marshal a new JSON-RPC response.  For example, this is a response to a getblockheight request.
  71  	marshalledBytes, e := btcjson.MarshalResponse(1, 350001, nil)
  72  	if e != nil {
  73  		btcjson.E.Ln(e)
  74  		return
  75  	}
  76  	// Display the marshalled response.  Ordinarily this would be sent across the wire to the RPC client, but for this example, just display it.
  77  	fmt.Printf("%s\n", marshalledBytes)
  78  	// Output: {"result":350001,"error":null,"id":1}
  79  }
  80  
  81  // This example demonstrates how to unmarshal a JSON-RPC response and then unmarshal the result field in the response to a concrete type.
  82  func Example_unmarshalResponse() {
  83  	// Ordinarily this would be read from the wire, but for this example, it is hard coded here for clarity.  This is an example response to a getblockheight request.
  84  	data := []byte(`{"result":350001,"error":null,"id":1}`)
  85  	// Unmarshal the raw bytes from the wire into a JSON-RPC response.
  86  	var response btcjson.Response
  87  	if e := json.Unmarshal(data, &response); E.Chk(e) {
  88  		btcjson.E.Ln("Malformed JSON-RPC response:", e)
  89  		return
  90  	}
  91  	// Chk the response for an error from the server.  For example, the server might return an error if an invalid/unknown block hash is requested.
  92  	if response.Error != nil {
  93  		btcjson.E.Ln(response.Error)
  94  		return
  95  	}
  96  	// Unmarshal the result into the expected type for the response.
  97  	var blockHeight int32
  98  	if e := json.Unmarshal(response.Result, &blockHeight); E.Chk(e) {
  99  		E.F("Unexpected result type: %T\n", response.Result)
 100  		return
 101  	}
 102  	fmt.Println("Block height:", blockHeight)
 103  	// Output: Block height: 350001
 104  }
 105