From a5d2fc50d0e1c564b8e5e1f00c8ddeaad6a56ea6 Mon Sep 17 00:00:00 2001 From: jeronimoalbi <894299+jeronimoalbi@users.noreply.github.com> Date: Tue, 19 Aug 2025 15:45:15 +0200 Subject: [PATCH 1/2] chore: change proto generate script to apply compatiblity patch --- scripts/amino-json-compatibility.patch | 164 +++++++++++++++++++++++++ scripts/generate.sh | 14 +++ 2 files changed, 178 insertions(+) create mode 100644 scripts/amino-json-compatibility.patch diff --git a/scripts/amino-json-compatibility.patch b/scripts/amino-json-compatibility.patch new file mode 100644 index 0000000..b1d8e8a --- /dev/null +++ b/scripts/amino-json-compatibility.patch @@ -0,0 +1,164 @@ +diff --git a/src/proto/gno/vm.ts b/src/proto/gno/vm.ts +index 79f24a4..bed60a0 100644 +--- a/src/proto/gno/vm.ts ++++ b/src/proto/gno/vm.ts +@@ -42,7 +42,7 @@ export interface MsgAddPackage { + /** the amount of funds to be deposited at deployment, if any ("") */ + send: string; + /** the amount of funds to put down for the storage fee, if any ("") */ +- max_deposit: string; ++ max_deposit?: string; + } + + /** +@@ -72,9 +72,9 @@ export interface MemPackage { + /** the associated package gno source */ + files: MemFile[]; + /** the (user defined) package type */ +- type?: Any | undefined; ++ type?: Any | null; + /** the (user defined) extra information */ +- info?: Any | undefined; ++ info?: Any | null; + } + + /** +@@ -221,7 +221,7 @@ export const MsgCall: MessageFns = { + if (message.send !== undefined) { + obj.send = message.send; + } +- if (message.max_deposit !== undefined) { ++ if (message.max_deposit !== undefined && message.max_deposit !== '') { + obj.max_deposit = message.max_deposit; + } + if (message.pkg_path !== undefined) { +@@ -254,7 +254,7 @@ export const MsgCall: MessageFns = { + }; + + function createBaseMsgAddPackage(): MsgAddPackage { +- return { creator: '', package: undefined, send: '', max_deposit: '' }; ++ return { creator: '', package: undefined, send: '', max_deposit: undefined }; + } + + export const MsgAddPackage: MessageFns = { +@@ -271,7 +271,7 @@ export const MsgAddPackage: MessageFns = { + if (message.send !== '') { + writer.uint32(26).string(message.send); + } +- if (message.max_deposit !== '') { ++ if (message.max_deposit !== '' && message.max_deposit !== undefined) { + writer.uint32(34).string(message.max_deposit); + } + return writer; +@@ -313,8 +313,10 @@ export const MsgAddPackage: MessageFns = { + if (tag !== 34) { + break; + } +- +- message.max_deposit = reader.string(); ++ const max_deposit = reader.string(); ++ if (max_deposit !== '') { ++ message.max_deposit = max_deposit; ++ } + continue; + } + } +@@ -335,7 +337,7 @@ export const MsgAddPackage: MessageFns = { + send: isSet(object.send) ? globalThis.String(object.send) : '', + max_deposit: isSet(object.max_deposit) + ? globalThis.String(object.max_deposit) +- : '', ++ : undefined, + }; + }, + +@@ -371,7 +373,7 @@ export const MsgAddPackage: MessageFns = { + ? MemPackage.fromPartial(object.package) + : undefined; + message.send = object.send ?? ''; +- message.max_deposit = object.max_deposit ?? ''; ++ message.max_deposit = object.max_deposit ?? undefined; + return message; + }, + }; +@@ -496,7 +498,7 @@ export const MsgRun: MessageFns = { + }; + + function createBaseMemPackage(): MemPackage { +- return { name: '', path: '', files: [], type: undefined, info: undefined }; ++ return { name: '', path: '', files: [], type: null, info: null }; + } + + export const MemPackage: MessageFns = { +@@ -513,10 +515,10 @@ export const MemPackage: MessageFns = { + for (const v of message.files) { + MemFile.encode(v!, writer.uint32(26).fork()).join(); + } +- if (message.type !== undefined) { ++ if (message.type !== undefined && message.type !== null) { + Any.encode(message.type, writer.uint32(34).fork()).join(); + } +- if (message.info !== undefined) { ++ if (message.info !== undefined && message.info !== null) { + Any.encode(message.info, writer.uint32(42).fork()).join(); + } + return writer; +@@ -556,6 +558,7 @@ export const MemPackage: MessageFns = { + } + case 4: { + if (tag !== 34) { ++ message.type = null; + break; + } + +@@ -564,6 +567,7 @@ export const MemPackage: MessageFns = { + } + case 5: { + if (tag !== 42) { ++ message.info = null; + break; + } + +@@ -586,8 +590,8 @@ export const MemPackage: MessageFns = { + files: globalThis.Array.isArray(object?.files) + ? object.files.map((e: any) => MemFile.fromJSON(e)) + : [], +- type: isSet(object.type) ? Any.fromJSON(object.type) : undefined, +- info: isSet(object.info) ? Any.fromJSON(object.info) : undefined, ++ type: isSet(object.type) ? Any.fromJSON(object.type) : null, ++ info: isSet(object.info) ? Any.fromJSON(object.info) : null, + }; + }, + +@@ -602,11 +606,15 @@ export const MemPackage: MessageFns = { + if (message.files?.length) { + obj.files = message.files.map((e) => MemFile.toJSON(e)); + } +- if (message.type !== undefined) { ++ if (message.type !== undefined && message.type !== null) { + obj.type = Any.toJSON(message.type); ++ } else { ++ obj.type = null; + } +- if (message.info !== undefined) { ++ if (message.info !== undefined && message.info !== null) { + obj.info = Any.toJSON(message.info); ++ } else { ++ obj.info = null; + } + return obj; + }, +@@ -624,11 +632,11 @@ export const MemPackage: MessageFns = { + message.type = + object.type !== undefined && object.type !== null + ? Any.fromPartial(object.type) +- : undefined; ++ : null; + message.info = + object.info !== undefined && object.info !== null + ? Any.fromPartial(object.info) +- : undefined; ++ : null; + return message; + }, + }; diff --git a/scripts/generate.sh b/scripts/generate.sh index c94b6e3..75b5b25 100755 --- a/scripts/generate.sh +++ b/scripts/generate.sh @@ -15,3 +15,17 @@ for x in ${FILES}; do --ts_proto_opt="esModuleInterop=true,forceLong=long,useOptionals=messages,useDate=false,snakeToCamel=false,emitDefaultValues=json-methods" \ ${x} done + +# Apply amino JSON compatibility changes to patch proto generated files. +# Patch fixes two issues: +# - Empty `max_deposit` is represented in JSON as an empty string in proto while omitted completely in Amino JSON +# - Empty `google.protobuf.Any` fields are omitted in proto JSON while explicitly set to null in Amino JSON +# +# See: https://github.com/gnolang/gno-js-client/pull/184 +# +# This is a short term solution that potentially requires maintaining the patch updated. +if [ $? -eq 0 ]; then + # First prettify generated code to allow the patch to be applied + ./node_modules/.bin/prettier --write ${OUT_DIR}/gno/vm.ts && \ + git apply ./scripts/amino-json-compatibility.patch +fi From b2f3008f2cd95ec3f1b1ba980a0d6b3997cefb06 Mon Sep 17 00:00:00 2001 From: jeronimoalbi <894299+jeronimoalbi@users.noreply.github.com> Date: Thu, 28 Aug 2025 11:15:52 +0200 Subject: [PATCH 2/2] feat: update compatibility patch to include changes from #46 --- scripts/amino-json-compatibility.patch | 95 ++++++++++++++++++++++---- scripts/generate.sh | 7 +- 2 files changed, 86 insertions(+), 16 deletions(-) diff --git a/scripts/amino-json-compatibility.patch b/scripts/amino-json-compatibility.patch index b1d8e8a..69800df 100644 --- a/scripts/amino-json-compatibility.patch +++ b/scripts/amino-json-compatibility.patch @@ -1,7 +1,16 @@ diff --git a/src/proto/gno/vm.ts b/src/proto/gno/vm.ts -index 79f24a4..bed60a0 100644 +index 8fdde9e..781e570 100644 --- a/src/proto/gno/vm.ts +++ b/src/proto/gno/vm.ts +@@ -27,7 +27,7 @@ export interface MsgCall { + /** the function name being invoked */ + func: string; + /** the function arguments */ +- args: string[]; ++ args: string[] | null; + } + + /** @@ -42,7 +42,7 @@ export interface MsgAddPackage { /** the amount of funds to be deposited at deployment, if any ("") */ send: string; @@ -23,7 +32,49 @@ index 79f24a4..bed60a0 100644 } /** -@@ -221,7 +221,7 @@ export const MsgCall: MessageFns = { +@@ -95,7 +95,7 @@ function createBaseMsgCall(): MsgCall { + max_deposit: '', + pkg_path: '', + func: '', +- args: [], ++ args: null, + }; + } + +@@ -119,8 +119,10 @@ export const MsgCall: MessageFns = { + if (message.func !== '') { + writer.uint32(42).string(message.func); + } +- for (const v of message.args) { +- writer.uint32(50).string(v!); ++ if (message.args) { ++ for (const v of message.args) { ++ writer.uint32(50).string(v!); ++ } + } + return writer; + }, +@@ -178,6 +180,10 @@ export const MsgCall: MessageFns = { + break; + } + ++ if (!message.args) { ++ message.args = []; ++ } ++ + message.args.push(reader.string()); + continue; + } +@@ -203,7 +209,7 @@ export const MsgCall: MessageFns = { + func: isSet(object.func) ? globalThis.String(object.func) : '', + args: globalThis.Array.isArray(object?.args) + ? object.args.map((e: any) => globalThis.String(e)) +- : [], ++ : null, + }; + }, + +@@ -215,7 +221,7 @@ export const MsgCall: MessageFns = { if (message.send !== undefined) { obj.send = message.send; } @@ -32,7 +83,23 @@ index 79f24a4..bed60a0 100644 obj.max_deposit = message.max_deposit; } if (message.pkg_path !== undefined) { -@@ -254,7 +254,7 @@ export const MsgCall: MessageFns = { +@@ -226,6 +232,8 @@ export const MsgCall: MessageFns = { + } + if (message.args?.length) { + obj.args = message.args; ++ } else { ++ obj.args = null; + } + return obj; + }, +@@ -240,13 +248,13 @@ export const MsgCall: MessageFns = { + message.max_deposit = object.max_deposit ?? ''; + message.pkg_path = object.pkg_path ?? ''; + message.func = object.func ?? ''; +- message.args = object.args?.map((e) => e) || []; ++ message.args = object.args?.map((e) => e) || null; + return message; + }, }; function createBaseMsgAddPackage(): MsgAddPackage { @@ -41,7 +108,7 @@ index 79f24a4..bed60a0 100644 } export const MsgAddPackage: MessageFns = { -@@ -271,7 +271,7 @@ export const MsgAddPackage: MessageFns = { +@@ -263,7 +271,7 @@ export const MsgAddPackage: MessageFns = { if (message.send !== '') { writer.uint32(26).string(message.send); } @@ -50,7 +117,7 @@ index 79f24a4..bed60a0 100644 writer.uint32(34).string(message.max_deposit); } return writer; -@@ -313,8 +313,10 @@ export const MsgAddPackage: MessageFns = { +@@ -305,8 +313,10 @@ export const MsgAddPackage: MessageFns = { if (tag !== 34) { break; } @@ -63,7 +130,7 @@ index 79f24a4..bed60a0 100644 continue; } } -@@ -335,7 +337,7 @@ export const MsgAddPackage: MessageFns = { +@@ -327,7 +337,7 @@ export const MsgAddPackage: MessageFns = { send: isSet(object.send) ? globalThis.String(object.send) : '', max_deposit: isSet(object.max_deposit) ? globalThis.String(object.max_deposit) @@ -72,7 +139,7 @@ index 79f24a4..bed60a0 100644 }; }, -@@ -371,7 +373,7 @@ export const MsgAddPackage: MessageFns = { +@@ -363,7 +373,7 @@ export const MsgAddPackage: MessageFns = { ? MemPackage.fromPartial(object.package) : undefined; message.send = object.send ?? ''; @@ -81,7 +148,7 @@ index 79f24a4..bed60a0 100644 return message; }, }; -@@ -496,7 +498,7 @@ export const MsgRun: MessageFns = { +@@ -488,7 +498,7 @@ export const MsgRun: MessageFns = { }; function createBaseMemPackage(): MemPackage { @@ -90,7 +157,7 @@ index 79f24a4..bed60a0 100644 } export const MemPackage: MessageFns = { -@@ -513,10 +515,10 @@ export const MemPackage: MessageFns = { +@@ -505,10 +515,10 @@ export const MemPackage: MessageFns = { for (const v of message.files) { MemFile.encode(v!, writer.uint32(26).fork()).join(); } @@ -103,7 +170,7 @@ index 79f24a4..bed60a0 100644 Any.encode(message.info, writer.uint32(42).fork()).join(); } return writer; -@@ -556,6 +558,7 @@ export const MemPackage: MessageFns = { +@@ -548,6 +558,7 @@ export const MemPackage: MessageFns = { } case 4: { if (tag !== 34) { @@ -111,7 +178,7 @@ index 79f24a4..bed60a0 100644 break; } -@@ -564,6 +567,7 @@ export const MemPackage: MessageFns = { +@@ -556,6 +567,7 @@ export const MemPackage: MessageFns = { } case 5: { if (tag !== 42) { @@ -119,7 +186,7 @@ index 79f24a4..bed60a0 100644 break; } -@@ -586,8 +590,8 @@ export const MemPackage: MessageFns = { +@@ -578,8 +590,8 @@ export const MemPackage: MessageFns = { files: globalThis.Array.isArray(object?.files) ? object.files.map((e: any) => MemFile.fromJSON(e)) : [], @@ -130,7 +197,7 @@ index 79f24a4..bed60a0 100644 }; }, -@@ -602,11 +606,15 @@ export const MemPackage: MessageFns = { +@@ -594,11 +606,15 @@ export const MemPackage: MessageFns = { if (message.files?.length) { obj.files = message.files.map((e) => MemFile.toJSON(e)); } @@ -148,7 +215,7 @@ index 79f24a4..bed60a0 100644 } return obj; }, -@@ -624,11 +632,11 @@ export const MemPackage: MessageFns = { +@@ -616,11 +632,11 @@ export const MemPackage: MessageFns = { message.type = object.type !== undefined && object.type !== null ? Any.fromPartial(object.type) diff --git a/scripts/generate.sh b/scripts/generate.sh index 75b5b25..54f1584 100755 --- a/scripts/generate.sh +++ b/scripts/generate.sh @@ -2,6 +2,7 @@ PROTO_PATH=./proto OUT_DIR=./src/proto +PRETTIER=./node_modules/.bin/prettier FILES=$(find proto -type f -name "*.proto") @@ -21,11 +22,13 @@ done # - Empty `max_deposit` is represented in JSON as an empty string in proto while omitted completely in Amino JSON # - Empty `google.protobuf.Any` fields are omitted in proto JSON while explicitly set to null in Amino JSON # -# See: https://github.com/gnolang/gno-js-client/pull/184 +# See: +# https://github.com/gnolang/gno-js-client/pull/184 +# https://github.com/gnolang/gno-js-client/pull/46 # # This is a short term solution that potentially requires maintaining the patch updated. if [ $? -eq 0 ]; then # First prettify generated code to allow the patch to be applied - ./node_modules/.bin/prettier --write ${OUT_DIR}/gno/vm.ts && \ + ${PRETTIER} --write ${OUT_DIR}/gno/bank.ts ${OUT_DIR}/gno/vm.ts && \ git apply ./scripts/amino-json-compatibility.patch fi