From 14de08c6ace6f0a959fe86e663728b85e3d9b8ca Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 24 Feb 2021 14:56:20 +0100 Subject: [PATCH 1/2] Remove unused adr27 module --- packages/proto-signing/src/adr27.spec.ts | 239 ----------------------- packages/proto-signing/src/adr27.ts | 60 ------ 2 files changed, 299 deletions(-) delete mode 100644 packages/proto-signing/src/adr27.spec.ts delete mode 100644 packages/proto-signing/src/adr27.ts diff --git a/packages/proto-signing/src/adr27.spec.ts b/packages/proto-signing/src/adr27.spec.ts deleted file mode 100644 index 257bc9ad..00000000 --- a/packages/proto-signing/src/adr27.spec.ts +++ /dev/null @@ -1,239 +0,0 @@ -import { fromHex } from "@cosmjs/encoding"; -import Long from "long"; -import { parse } from "protobufjs"; - -import { omitDefault, omitDefaults } from "./adr27"; - -describe("adr27", () => { - describe("omitDefault", () => { - it("works for strings", () => { - expect(omitDefault("abc")).toEqual("abc"); - expect(omitDefault("")).toEqual(null); - }); - - it("works for bytes", () => { - expect(omitDefault(fromHex("ab"))).toEqual(fromHex("ab")); - expect(omitDefault(fromHex(""))).toEqual(null); - }); - - it("works for integers", () => { - expect(omitDefault(123)).toEqual(123); - expect(omitDefault(0)).toEqual(null); - }); - - it("works for floats", () => { - expect(omitDefault(1.234)).toEqual(1.234); - expect(omitDefault(0.0)).toEqual(null); - }); - - it("works for Long", () => { - // unsigned - expect(omitDefault(Long.fromNumber(123, true))).toEqual(Long.fromNumber(123, true)); - expect(omitDefault(Long.fromNumber(0, true))).toEqual(null); - - // signed - expect(omitDefault(Long.fromNumber(123, false))).toEqual(Long.fromNumber(123, false)); - expect(omitDefault(Long.fromNumber(0, false))).toEqual(null); - }); - - it("works for booleans", () => { - expect(omitDefault(true)).toEqual(true); - expect(omitDefault(false)).toEqual(null); - }); - - it("works for repeated", () => { - expect(omitDefault(["a", "b", "c"])).toEqual(["a", "b", "c"]); - expect(omitDefault([])).toEqual(null); - }); - - it("works for enums", () => { - const proto = ` - package blog; - syntax = "proto3"; - - enum Review { - UNSPECIFIED = 0; - ACCEPTED = 1; - REJECTED = 2; - }; - `; - // eslint-disable-next-line @typescript-eslint/naming-convention - const Review = parse(proto).root.lookupEnum("blog.Review"); - expect(omitDefault(Review.values["ACCEPTED"])).toEqual(Review.values["ACCEPTED"]); - expect(omitDefault(Review.values["UNSPECIFIED"])).toEqual(null); - }); - - it("works for unset", () => { - // null and undefined both represent unset in protobuf.js serialization - expect(omitDefault(undefined)).toEqual(null); - expect(omitDefault(null)).toEqual(null); - }); - }); - - describe("omitDefaults", () => { - it("works for scalars", () => { - expect(omitDefaults("abc")).toEqual("abc"); - expect(omitDefaults("")).toEqual(null); - - expect(omitDefaults(fromHex("ab"))).toEqual(fromHex("ab")); - expect(omitDefaults(fromHex(""))).toEqual(null); - - expect(omitDefaults(123)).toEqual(123); - expect(omitDefaults(0)).toEqual(null); - - expect(omitDefaults(1.234)).toEqual(1.234); - expect(omitDefaults(0.0)).toEqual(null); - - expect(omitDefaults(Long.fromNumber(123, true))).toEqual(Long.fromNumber(123, true)); - expect(omitDefaults(Long.fromNumber(0, true))).toEqual(null); - - expect(omitDefaults(Long.fromNumber(123, false))).toEqual(Long.fromNumber(123, false)); - expect(omitDefaults(Long.fromNumber(0, false))).toEqual(null); - - expect(omitDefaults(true)).toEqual(true); - expect(omitDefaults(false)).toEqual(null); - }); - - it("works for repeated", () => { - expect(omitDefaults(["a", "b", "c"])).toEqual(["a", "b", "c"]); - expect(omitDefaults([])).toEqual(null); - }); - - it("works for enums", () => { - const proto = ` - package blog; - syntax = "proto3"; - - enum Review { - UNSPECIFIED = 0; - ACCEPTED = 1; - REJECTED = 2; - }; - `; - // eslint-disable-next-line @typescript-eslint/naming-convention - const Review = parse(proto).root.lookupEnum("blog.Review"); - expect(omitDefaults(Review.values["ACCEPTED"])).toEqual(Review.values["ACCEPTED"]); - expect(omitDefaults(Review.values["UNSPECIFIED"])).toEqual(null); - }); - - it("works for unset", () => { - // null and undefined both represent unset in protobuf.js serialization - expect(omitDefaults(undefined)).toEqual(null); - expect(omitDefaults(null)).toEqual(null); - }); - - it("works for objects", () => { - // empty - expect(omitDefaults({})).toEqual({}); - - // simple - expect( - omitDefaults({ - a: "foo", - b: "", - c: 100, - d: 0, - }), - ).toEqual({ - a: "foo", - b: null, - c: 100, - d: null, - }); - - // nested - - expect( - omitDefaults({ - a: { - x: "foo", - y: "", - }, - b: { - x: { - o: 1.2, - p: false, - q: 0, - }, - }, - }), - ).toEqual({ - a: { - x: "foo", - y: null, - }, - b: { - x: { - o: 1.2, - p: null, - q: null, - }, - }, - }); - }); - - it("can be used to reproduce ADR 027 test vector", () => { - const proto = ` - // Article.proto - - package blog; - syntax = "proto3"; - - enum Type { - UNSPECIFIED = 0; - IMAGES = 1; - NEWS = 2; - }; - - enum Review { - UNSPECIFIED = 0; - ACCEPTED = 1; - REJECTED = 2; - }; - - message Article { - string title = 1; - string description = 2; - uint64 created = 3; - uint64 updated = 4; - bool public = 5; - bool promoted = 6; - Type type = 7; - Review review = 8; - repeated string comments = 9; - repeated string backlinks = 10; - }; - `; - const root = parse(proto).root; - - // eslint-disable-next-line @typescript-eslint/naming-convention - const Article = root.lookupType("blog.Article"); - // eslint-disable-next-line @typescript-eslint/naming-convention - const Type = root.lookupEnum("blog.Type"); - // eslint-disable-next-line @typescript-eslint/naming-convention - const Review = root.lookupEnum("blog.Review"); - - const expected = fromHex( - "0a1654686520776f726c64206e65656473206368616e676518e8bebec8bc2e280138024a084e696365206f6e654a095468616e6b20796f75", - ); - - const serialization = Uint8Array.from( - Article.encode( - omitDefaults({ - title: "The world needs change", - description: "", - created: 1596806111080, - updated: 0, - public: true, - promoted: false, - type: Type.values["NEWS"], - review: Review.values["UNSPECIFIED"], - comments: ["Nice one", "Thank you"], - backlinks: [], - }), - ).finish(), - ); - expect(serialization).toEqual(expected); - }); - }); -}); diff --git a/packages/proto-signing/src/adr27.ts b/packages/proto-signing/src/adr27.ts deleted file mode 100644 index 77a9f506..00000000 --- a/packages/proto-signing/src/adr27.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { isNonNullObject, isUint8Array } from "@cosmjs/utils"; -import Long from "long"; - -/** - * Converts default values to null in order to tell protobuf.js - * to not serialize them. - * - * @see https://github.com/cosmos/cosmos-sdk/pull/6979 - */ -export function omitDefault(input: T): T | null { - if (input === undefined || input === null) return null; - - if (typeof input === "number" || typeof input === "boolean" || typeof input === "string") { - return input || null; - } - - if (Long.isLong(input)) { - return !input.isZero() ? input : null; - } - - if (Array.isArray(input) || isUint8Array(input)) { - return input.length ? input : null; - } - - throw new Error("Input type not supported"); -} - -/** - * Walks through a potentially nested object and calls omitDefault on each element. - */ -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export function omitDefaults(input: any): any { - // Unset - if (input === undefined || input === null) return null; - - // Protobuf element - if ( - typeof input === "number" || - typeof input === "boolean" || - typeof input === "string" || - Long.isLong(input) || - Array.isArray(input) || - isUint8Array(input) - ) { - return omitDefault(input); - } - - // Object - if (isNonNullObject(input)) { - return Object.entries(input).reduce( - (accumulator, [key, value]) => ({ - ...accumulator, - [key]: omitDefaults(value), - }), - {}, - ); - } - - throw new Error(`Input type not supported: ${typeof input}`); -} From 02d612ccffd89ceabe4f7abcb9a0f379db78936a Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 24 Feb 2021 14:57:21 +0100 Subject: [PATCH 2/2] Remove obsolete demo files --- packages/proto-signing/src/demo.json | 12 -- packages/proto-signing/src/demo.proto.ts | 12 -- packages/proto-signing/src/demo.spec.ts | 150 ----------------------- packages/proto-signing/src/demo.ts | 8 -- 4 files changed, 182 deletions(-) delete mode 100644 packages/proto-signing/src/demo.json delete mode 100644 packages/proto-signing/src/demo.proto.ts delete mode 100644 packages/proto-signing/src/demo.spec.ts delete mode 100644 packages/proto-signing/src/demo.ts diff --git a/packages/proto-signing/src/demo.json b/packages/proto-signing/src/demo.json deleted file mode 100644 index b9b01c24..00000000 --- a/packages/proto-signing/src/demo.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "nested": { - "MsgDemo": { - "fields": { - "example": { - "type": "string", - "id": 1 - } - } - } - } -} diff --git a/packages/proto-signing/src/demo.proto.ts b/packages/proto-signing/src/demo.proto.ts deleted file mode 100644 index a0050a05..00000000 --- a/packages/proto-signing/src/demo.proto.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Without this TS infers this is a string literal. -// eslint-disable-next-line @typescript-eslint/no-inferrable-types -const proto: string = ` -syntax = "proto3"; -package demo; - -message MsgDemo { - string example = 1; -} -`; - -export default proto; diff --git a/packages/proto-signing/src/demo.spec.ts b/packages/proto-signing/src/demo.spec.ts deleted file mode 100644 index 18ceff46..00000000 --- a/packages/proto-signing/src/demo.spec.ts +++ /dev/null @@ -1,150 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -import { assert } from "@cosmjs/utils"; -import Long from "long"; -import protobuf from "protobufjs"; - -import { MsgSend } from "./codec/cosmos/bank/v1beta1/tx"; -import { Coin } from "./codec/cosmos/base/v1beta1/coin"; -import { TxBody } from "./codec/cosmos/tx/v1beta1/tx"; -import { Any } from "./codec/google/protobuf/any"; -import reflectionRoot from "./demo"; -import demoJson from "./demo.json"; -import demoProto from "./demo.proto"; - -type MsgDemo = { - readonly example: string; -}; - -function getTypeName(typeUrl: string): string { - const parts = typeUrl.split("."); - return parts[parts.length - 1]; -} - -describe("protobuf demo", () => { - it("works with generated static code", () => { - const coin = Coin.fromPartial({ - denom: "ucosm", - amount: "1234567890", - }); - const msgSend = MsgSend.fromPartial({ - fromAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", - toAddress: "cosmos1qypqxpq9qcrsszg2pvxq6rs0zqg3yyc5lzv7xu", - amount: [coin], - }); - const msgSendBytes = MsgSend.encode(msgSend).finish(); - const msgSendWrapped = Any.fromPartial({ - typeUrl: "/cosmos.bank.v1beta1.MsgSend", - value: msgSendBytes, - }); - const txBody = TxBody.fromPartial({ - messages: [msgSendWrapped], - memo: "Some memo", - timeoutHeight: Long.fromNumber(9999), - extensionOptions: [], - }); - const txBodyBytes = TxBody.encode(txBody).finish(); - - // Deserialization - const txBodyDecoded = TxBody.decode(txBodyBytes); - const msg = txBodyDecoded.messages[0]; - assert(msg.value); - const msgSendDecoded = MsgSend.decode(msg.value); - - // fromAddress and toAddress are now Buffers - expect(msgSendDecoded.fromAddress).toEqual(msgSend.fromAddress); - expect(msgSendDecoded.toAddress).toEqual(msgSend.toAddress); - expect(msgSendDecoded.amount).toEqual(msgSend.amount); - }); - - it("works with dynamically loaded proto files", () => { - const { root } = protobuf.parse(demoProto); - const typeUrl = "/demo.MsgDemo"; - const encoder = root.lookupType(getTypeName(typeUrl)); - const msgDemo = (encoder.create({ - example: "Some example text", - }) as unknown) as MsgDemo; - const msgDemoBytes = encoder.encode(msgDemo).finish(); - const msgDemoWrapped = Any.fromPartial({ - typeUrl: typeUrl, - value: msgDemoBytes, - }); - const txBody = TxBody.fromPartial({ - messages: [msgDemoWrapped], - memo: "Some memo", - timeoutHeight: Long.fromNumber(9999), - extensionOptions: [], - }); - const txBodyBytes = TxBody.encode(txBody).finish(); - - // Deserialization - const txBodyDecoded = TxBody.decode(txBodyBytes); - const msg = txBodyDecoded.messages[0]; - assert(msg.typeUrl); - assert(msg.value); - - const decoder = root.lookupType(getTypeName(msg.typeUrl)); - const msgDemoDecoded = (decoder.decode(msg.value) as unknown) as MsgDemo; - expect(msgDemoDecoded.example).toEqual(msgDemo.example); - }); - - it("works with dynamically loaded json files", () => { - const root = protobuf.Root.fromJSON(demoJson); - const typeUrl = "/demo.MsgDemo"; - const encoder = root.lookupType(getTypeName(typeUrl)); - const msgDemo = (encoder.create({ - example: "Some example text", - }) as unknown) as MsgDemo; - const msgDemoBytes = encoder.encode(msgDemo).finish(); - const msgDemoWrapped = Any.fromPartial({ - typeUrl: typeUrl, - value: msgDemoBytes, - }); - const txBody = TxBody.fromPartial({ - messages: [msgDemoWrapped], - memo: "Some memo", - timeoutHeight: Long.fromNumber(9999), - extensionOptions: [], - }); - const txBodyBytes = TxBody.encode(txBody).finish(); - - // Deserialization - const txBodyDecoded = TxBody.decode(txBodyBytes); - const msg = txBodyDecoded.messages[0]; - assert(msg.typeUrl); - assert(msg.value); - - const decoder = root.lookupType(getTypeName(msg.typeUrl)); - const msgDemoDecoded = (decoder.decode(msg.value) as unknown) as MsgDemo; - expect(msgDemoDecoded.example).toEqual(msgDemo.example); - }); - - it("works with reflection", () => { - const typeUrl = "/demo.MsgDemo"; - const encoder = reflectionRoot.lookupType(getTypeName(typeUrl)); - const msgDemo = (encoder.create({ - example: "Some example text", - }) as unknown) as MsgDemo; - const msgDemoBytes = encoder.encode(msgDemo).finish(); - const msgDemoWrapped = Any.fromPartial({ - typeUrl: typeUrl, - value: msgDemoBytes, - }); - const txBody = TxBody.fromPartial({ - messages: [msgDemoWrapped], - memo: "Some memo", - timeoutHeight: Long.fromNumber(9999), - extensionOptions: [], - }); - const txBodyBytes = TxBody.encode(txBody).finish(); - - // Deserialization - const txBodyDecoded = TxBody.decode(txBodyBytes); - const msg = txBodyDecoded.messages[0]; - assert(msg.typeUrl); - assert(msg.value); - - const decoder = reflectionRoot.lookupType(getTypeName(msg.typeUrl)); - const msgDemoDecoded = (decoder.decode(msg.value) as unknown) as MsgDemo; - expect(msgDemoDecoded.example).toEqual(msgDemo.example); - }); -}); diff --git a/packages/proto-signing/src/demo.ts b/packages/proto-signing/src/demo.ts deleted file mode 100644 index b794b415..00000000 --- a/packages/proto-signing/src/demo.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -import { Field, Root, Type } from "protobufjs"; - -export const MsgDemo = new Type("MsgDemo").add(new Field("example", 1, "string")); - -const root = new Root().define("demo").add(MsgDemo); - -export default root;