github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/rpc/jsonrpc/client/decode.go (about) 1 package client 2 3 import ( 4 "encoding/json" 5 "fmt" 6 7 tmjson "github.com/ari-anchor/sei-tendermint/libs/json" 8 rpctypes "github.com/ari-anchor/sei-tendermint/rpc/jsonrpc/types" 9 ) 10 11 func unmarshalResponseBytes(responseBytes []byte, expectedID string, result interface{}) error { 12 // Read response. If rpc/core/types is imported, the result will unmarshal 13 // into the correct type. 14 var response rpctypes.RPCResponse 15 if err := tmjson.Unmarshal(responseBytes, &response); err != nil { 16 return fmt.Errorf("unmarshaling response test: %w, bytes: %d", err, len(responseBytes)) 17 } 18 19 if response.Error != nil { 20 return response.Error 21 } 22 23 if got := response.ID(); got != expectedID { 24 return fmt.Errorf("got response ID %q, wanted %q", got, expectedID) 25 } 26 27 // Unmarshal the RawMessage into the result. 28 if err := tmjson.Unmarshal(response.Result, result); err != nil { 29 return fmt.Errorf("error unmarshaling result: %w", err) 30 } 31 return nil 32 } 33 34 func unmarshalResponseBytesArray(responseBytes []byte, expectedIDs []string, results []interface{}) error { 35 var responses []rpctypes.RPCResponse 36 if err := json.Unmarshal(responseBytes, &responses); err != nil { 37 return fmt.Errorf("unmarshaling responses: %w", err) 38 } else if len(responses) != len(results) { 39 return fmt.Errorf("got %d results, wanted %d", len(responses), len(results)) 40 } 41 42 // Intersect IDs from responses with expectedIDs. 43 ids := make([]string, len(responses)) 44 for i, resp := range responses { 45 ids[i] = resp.ID() 46 } 47 if err := validateResponseIDs(ids, expectedIDs); err != nil { 48 return fmt.Errorf("wrong IDs: %w", err) 49 } 50 51 for i, resp := range responses { 52 if err := json.Unmarshal(resp.Result, results[i]); err != nil { 53 return fmt.Errorf("unmarshaling result %d: %w", i, err) 54 } 55 } 56 return nil 57 } 58 59 func validateResponseIDs(ids, expectedIDs []string) error { 60 m := make(map[string]struct{}, len(expectedIDs)) 61 for _, id := range expectedIDs { 62 m[id] = struct{}{} 63 } 64 65 for i, id := range ids { 66 if _, ok := m[id]; !ok { 67 return fmt.Errorf("unexpected response ID %d: %q", i, id) 68 } 69 } 70 return nil 71 }