Skip to content

Commit 7ee3115

Browse files
feat(x/tx): add aminoNameAsTypeURL option in aminojson encoder (backport #21712) (#21798)
Co-authored-by: Julien Robert <julien@rbrt.fr>
1 parent f812291 commit 7ee3115

4 files changed

Lines changed: 90 additions & 7 deletions

File tree

x/tx/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ Since v0.13.0, x/tx follows Cosmos SDK semver: https://github.com/cosmos/cosmos-
3333

3434
## [Unreleased]
3535

36+
## [v0.13.5](https://github.com/cosmos/cosmos-sdk/releases/tag/x/tx/v0.13.5) - 2024-09-18
37+
38+
### Improvements
39+
40+
* [#21712](https://github.com/cosmos/cosmos-sdk/pull/21712) Add `AminoNameAsTypeURL` option to Amino JSON encoder.
41+
3642
## [v0.13.4](https://github.com/cosmos/cosmos-sdk/releases/tag/x/tx/v0.13.4) - 2024-08-02
3743

3844
### Improvements

x/tx/signing/aminojson/json_marshal.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ type EncoderOptions struct {
3232
// EnumAsString when set will encode enums as strings instead of integers.
3333
// Caution: Enabling this option produce different sign bytes.
3434
EnumAsString bool
35+
// AminoNameAsTypeURL when set will use the amino name as the type URL in the JSON output.
36+
// It is useful when using the Amino JSON encoder for non Amino purposes,
37+
// such as JSON RPC.
38+
AminoNameAsTypeURL bool
3539
// TypeResolver is used to resolve protobuf message types by TypeURL when marshaling any packed messages.
3640
TypeResolver signing.TypeResolver
3741
// FileResolver is used to resolve protobuf file descriptors TypeURL when TypeResolver fails.
@@ -50,6 +54,7 @@ type Encoder struct {
5054
doNotSortFields bool
5155
indent string
5256
enumsAsString bool
57+
aminoNameAsTypeURL bool
5358
}
5459

5560
// NewEncoder returns a new Encoder capable of serializing protobuf messages to JSON using the Amino JSON encoding
@@ -80,11 +85,12 @@ func NewEncoder(options EncoderOptions) Encoder {
8085
"google.protobuf.Duration": marshalDuration,
8186
"google.protobuf.Any": marshalAny,
8287
},
83-
fileResolver: options.FileResolver,
84-
typeResolver: options.TypeResolver,
85-
doNotSortFields: options.DoNotSortFields,
86-
indent: options.Indent,
87-
enumsAsString: options.EnumAsString,
88+
fileResolver: options.FileResolver,
89+
typeResolver: options.TypeResolver,
90+
doNotSortFields: options.DoNotSortFields,
91+
indent: options.Indent,
92+
enumsAsString: options.EnumAsString,
93+
aminoNameAsTypeURL: options.AminoNameAsTypeURL,
8894
}
8995
return enc
9096
}
@@ -187,9 +193,17 @@ func (enc Encoder) beginMarshal(msg protoreflect.Message, writer io.Writer, isAn
187193
)
188194

189195
if isAny {
190-
name, named = getMessageAminoNameAny(msg), true
196+
if enc.aminoNameAsTypeURL {
197+
name, named = getMessageTypeURL(msg), true
198+
} else {
199+
name, named = getMessageAminoNameAny(msg), true
200+
}
191201
} else {
192202
name, named = getMessageAminoName(msg)
203+
if enc.aminoNameAsTypeURL {
204+
// do not override named
205+
name = getMessageTypeURL(msg)
206+
}
193207
}
194208

195209
if named {

x/tx/signing/aminojson/json_marshal_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,62 @@ func TestEnumAsString(t *testing.T) {
355355
}
356356
}`, string(bz))
357357
}
358+
359+
func TestAminoNameAsTypeURL(t *testing.T) {
360+
encoder := aminojson.NewEncoder(aminojson.EncoderOptions{Indent: " ", AminoNameAsTypeURL: true})
361+
362+
msg := &testpb.ABitOfEverything{
363+
Message: &testpb.NestedMessage{
364+
Foo: "test",
365+
Bar: 0, // this is the default value and should be omitted from output
366+
},
367+
Enum: testpb.AnEnum_ONE,
368+
Repeated: []int32{3, -7, 2, 6, 4},
369+
Str: `abcxyz"foo"def`,
370+
Bool: true,
371+
Bytes: []byte{0, 1, 2, 3},
372+
I32: -15,
373+
F32: 1001,
374+
U32: 1200,
375+
Si32: -376,
376+
Sf32: -1000,
377+
I64: 14578294827584932,
378+
F64: 9572348124213523654,
379+
U64: 4759492485,
380+
Si64: -59268425823934,
381+
Sf64: -659101379604211154,
382+
}
383+
384+
bz, err := encoder.Marshal(msg)
385+
require.NoError(t, err)
386+
fmt.Println(string(bz))
387+
require.Equal(t, `{
388+
"type": "/testpb.ABitOfEverything",
389+
"value": {
390+
"bool": true,
391+
"bytes": "AAECAw==",
392+
"enum": 1,
393+
"f32": 1001,
394+
"f64": "9572348124213523654",
395+
"i32": -15,
396+
"i64": "14578294827584932",
397+
"message": {
398+
"foo": "test"
399+
},
400+
"repeated": [
401+
3,
402+
-7,
403+
2,
404+
6,
405+
4
406+
],
407+
"sf32": -1000,
408+
"sf64": "-659101379604211154",
409+
"si32": -376,
410+
"si64": "-59268425823934",
411+
"str": "abcxyz\"foo\"def",
412+
"u32": 1200,
413+
"u64": "4759492485"
414+
}
415+
}`, string(bz))
416+
}

x/tx/signing/aminojson/options.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,18 @@ func getMessageAminoName(msg protoreflect.Message) (string, bool) {
2525

2626
// getMessageAminoName returns the amino name of a message if it has been set by the `amino.name` option.
2727
// If the message does not have an amino name, then it returns the msg url.
28-
// If it cannot get the msg url, then it returns false.
2928
func getMessageAminoNameAny(msg protoreflect.Message) string {
3029
messageOptions := msg.Descriptor().Options()
3130
if proto.HasExtension(messageOptions, amino.E_Name) {
3231
name := proto.GetExtension(messageOptions, amino.E_Name)
3332
return name.(string)
3433
}
3534

35+
return getMessageTypeURL(msg)
36+
}
37+
38+
// getMessageTypeURL returns the msg url.
39+
func getMessageTypeURL(msg protoreflect.Message) string {
3640
msgURL := "/" + string(msg.Descriptor().FullName())
3741
if msgURL != "/" {
3842
return msgURL

0 commit comments

Comments
 (0)