github.com/cerberus-wallet/blockbook@v0.3.2/bchain/coins/btc/codec.go (about)

     1  package btc
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"reflect"
     7  )
     8  
     9  // RPCMarshaler is used for marshalling requests to Bitcoin Type RPC interfaces
    10  type RPCMarshaler interface {
    11  	Marshal(v interface{}) ([]byte, error)
    12  }
    13  
    14  // JSONMarshalerV2 is used for marshalling requests to newer Bitcoin Type RPC interfaces
    15  type JSONMarshalerV2 struct{}
    16  
    17  // Marshal converts struct passed by parameter to JSON
    18  func (JSONMarshalerV2) Marshal(v interface{}) ([]byte, error) {
    19  	d, err := json.Marshal(v)
    20  	if err != nil {
    21  		return nil, err
    22  	}
    23  	return d, nil
    24  }
    25  
    26  // ErrInvalidValue is error returned by JSONMarshalerV1.Marshal if the passed structure contains invalid value
    27  var ErrInvalidValue = errors.New("Invalid value to marshal")
    28  
    29  // JSONMarshalerV1 is used for marshalling requests to legacy Bitcoin Type RPC interfaces
    30  type JSONMarshalerV1 struct{}
    31  
    32  // Marshal converts struct passed by parameter to JSON
    33  func (JSONMarshalerV1) Marshal(v interface{}) ([]byte, error) {
    34  	u := cmdUntypedParams{}
    35  
    36  	switch v := v.(type) {
    37  	case *CmdGetBlock:
    38  		var t bool
    39  		if v.Params.Verbosity > 0 {
    40  			t = true
    41  		}
    42  		u.Method = v.Method
    43  		u.Params = append(u.Params, v.Params.BlockHash)
    44  		u.Params = append(u.Params, t)
    45  	case *CmdGetRawTransaction:
    46  		var n int
    47  		if v.Params.Verbose {
    48  			n = 1
    49  		}
    50  		u.Method = v.Method
    51  		u.Params = append(u.Params, v.Params.Txid)
    52  		u.Params = append(u.Params, n)
    53  	default:
    54  		{
    55  			v := reflect.ValueOf(v).Elem()
    56  
    57  			f := v.FieldByName("Method")
    58  			if !f.IsValid() || f.Kind() != reflect.String {
    59  				return nil, ErrInvalidValue
    60  			}
    61  			u.Method = f.String()
    62  
    63  			f = v.FieldByName("Params")
    64  			if f.IsValid() {
    65  				var arr []interface{}
    66  				switch f.Kind() {
    67  				case reflect.Slice:
    68  					arr = make([]interface{}, f.Len())
    69  					for i := 0; i < f.Len(); i++ {
    70  						arr[i] = f.Index(i).Interface()
    71  					}
    72  				case reflect.Struct:
    73  					arr = make([]interface{}, f.NumField())
    74  					for i := 0; i < f.NumField(); i++ {
    75  						arr[i] = f.Field(i).Interface()
    76  					}
    77  				default:
    78  					return nil, ErrInvalidValue
    79  				}
    80  				u.Params = arr
    81  			}
    82  		}
    83  	}
    84  
    85  	d, err := json.Marshal(u)
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  
    90  	return d, nil
    91  }
    92  
    93  type cmdUntypedParams struct {
    94  	Method string        `json:"method"`
    95  	Params []interface{} `json:"params,omitempty"`
    96  }