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 }