Skip to content

Commit

Permalink
api: endpoint /chain/transactions/{height}/{index} now outputs fields…
Browse files Browse the repository at this point in the history
… as hex instead of base64
  • Loading branch information
altergui authored and p4u committed Jul 19, 2024
1 parent ef42b51 commit b46eef4
Showing 1 changed file with 42 additions and 3 deletions.
45 changes: 42 additions & 3 deletions api/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"math/big"
"reflect"

cometpool "github.com/cometbft/cometbft/mempool"
cometcoretypes "github.com/cometbft/cometbft/rpc/core/types"
Expand Down Expand Up @@ -51,16 +52,20 @@ func (a *API) sendTx(tx []byte) (*cometcoretypes.ResultBroadcastTx, error) {
}

func protoFormat(tx []byte) string {
ptx := models.Tx{}
if err := proto.Unmarshal(tx, &ptx); err != nil {
ptx := &models.Tx{}
if err := proto.Unmarshal(tx, ptx); err != nil {
return ""
}

// Convert all []byte fields to HexBytes using reflection
ptxWithHexFields := convertProtoMessageBytesFieldsToHex(ptx)

pj := protojson.MarshalOptions{
Multiline: false,
Indent: "",
EmitUnpopulated: true,
}
return pj.Format(&ptx)
return pj.Format(ptxWithHexFields)
}

// isTransactionType checks if the given transaction is of the given type.
Expand All @@ -78,6 +83,40 @@ func isTransactionType[T any](signedTxBytes []byte) (bool, error) {
return ok, nil
}

// convertProtoMessageBytesFieldsToHex converts all []byte fields in a proto.Message to HexBytes
func convertProtoMessageBytesFieldsToHex(message proto.Message) proto.Message {
tempStruct := reflect.New(reflect.TypeOf(message).Elem()).Interface()
proto.Merge(tempStruct.(proto.Message), message)
convertByteFieldsToHex(reflect.ValueOf(tempStruct))
return tempStruct.(proto.Message)
}

// convertByteFieldsToHex recursively converts all []byte fields to HexBytes using reflection
func convertByteFieldsToHex(v reflect.Value) {
if v.Kind() == reflect.Ptr {
v = v.Elem()
}

if v.Kind() != reflect.Struct {
return
}

for i := 0; i < v.NumField(); i++ {
field := v.Field(i)
fieldType := v.Type().Field(i)

if field.Kind() == reflect.Ptr && !field.IsNil() {
convertByteFieldsToHex(field)
} else if field.Kind() == reflect.Struct {
convertByteFieldsToHex(field)
} else if field.Kind() == reflect.Slice && fieldType.Type.Elem().Kind() == reflect.Uint8 {
// This is a []byte field
hexBytes := types.HexBytes(field.Bytes())
field.Set(reflect.ValueOf(hexBytes))
}
}
}

// convertKeysToCamel converts all keys in a JSON object to camelCase.
// Note that the keys are also sorted.
func convertKeysToCamel(data []byte) []byte {
Expand Down

0 comments on commit b46eef4

Please sign in to comment.