From d69f6041b867567462734f784d4d3ce4731dc7a6 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 30 Sep 2020 10:13:42 +0200 Subject: [PATCH] Change API to sort+serialize --- packages/launchpad/src/encoding.spec.ts | 57 +++++++++++-------------- packages/launchpad/src/encoding.ts | 24 ++++++----- packages/launchpad/types/encoding.d.ts | 3 +- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/packages/launchpad/src/encoding.spec.ts b/packages/launchpad/src/encoding.spec.ts index 8fc85df6..1ac93c9c 100644 --- a/packages/launchpad/src/encoding.spec.ts +++ b/packages/launchpad/src/encoding.spec.ts @@ -1,55 +1,50 @@ -import { sortJson } from "./encoding"; +import { sortedJsonStringify } from "./encoding"; describe("encoding", () => { - describe("sortJson", () => { + describe("sortedJsonStringify", () => { it("leaves non-objects unchanged", () => { - expect(sortJson(true)).toEqual(true); - expect(sortJson(false)).toEqual(false); - expect(sortJson("aabbccdd")).toEqual("aabbccdd"); - expect(sortJson(75)).toEqual(75); - expect(sortJson(null)).toEqual(null); - expect(sortJson([5, 6, 7, 1])).toEqual([5, 6, 7, 1]); - expect(sortJson([5, ["a", "b"], true, null, 1])).toEqual([5, ["a", "b"], true, null, 1]); + expect(sortedJsonStringify(true)).toEqual(`true`); + expect(sortedJsonStringify(false)).toEqual(`false`); + expect(sortedJsonStringify("aabbccdd")).toEqual(`"aabbccdd"`); + expect(sortedJsonStringify(75)).toEqual(`75`); + expect(sortedJsonStringify(null)).toEqual(`null`); + expect(sortedJsonStringify([5, 6, 7, 1])).toEqual(`[5,6,7,1]`); + expect(sortedJsonStringify([5, ["a", "b"], true, null, 1])).toEqual(`[5,["a","b"],true,null,1]`); }); it("sorts objects by key", () => { // already sorted - expect(sortJson({})).toEqual({}); - expect(sortJson({ a: 3 })).toEqual({ a: 3 }); - expect(sortJson({ a: 3, b: 2, c: 1 })).toEqual({ a: 3, b: 2, c: 1 }); + expect(sortedJsonStringify({})).toEqual(`{}`); + expect(sortedJsonStringify({ a: 3 })).toEqual(`{"a":3}`); + expect(sortedJsonStringify({ a: 3, b: 2, c: 1 })).toEqual(`{"a":3,"b":2,"c":1}`); // not yet sorted - expect(sortJson({ b: 2, a: 3, c: 1 })).toEqual({ a: 3, b: 2, c: 1 }); - expect(sortJson({ aaa: true, aa: true, a: true })).toEqual({ a: true, aa: true, aaa: true }); + expect(sortedJsonStringify({ b: 2, a: 3, c: 1 })).toEqual(`{"a":3,"b":2,"c":1}`); + expect(sortedJsonStringify({ aaa: true, aa: true, a: true })).toEqual( + `{"a":true,"aa":true,"aaa":true}`, + ); }); it("sorts nested objects", () => { // already sorted - expect(sortJson({ x: { y: { z: null } } })).toEqual({ x: { y: { z: null } } }); + expect(sortedJsonStringify({ x: { y: { z: null } } })).toEqual(`{"x":{"y":{"z":null}}}`); // not yet sorted - expect(sortJson({ b: { z: true, x: true, y: true }, a: true, c: true })).toEqual({ - a: true, - b: { x: true, y: true, z: true }, - c: true, - }); + expect(sortedJsonStringify({ b: { z: true, x: true, y: true }, a: true, c: true })).toEqual( + `{"a":true,"b":{"x":true,"y":true,"z":true},"c":true}`, + ); }); it("sorts objects in arrays", () => { // already sorted - expect(sortJson([1, 2, { x: { y: { z: null } } }, 4])).toEqual([1, 2, { x: { y: { z: null } } }, 4]); + expect(sortedJsonStringify([1, 2, { x: { y: { z: null } } }, 4])).toEqual( + `[1,2,{"x":{"y":{"z":null}}},4]`, + ); // not yet sorted - expect(sortJson([1, 2, { b: { z: true, x: true, y: true }, a: true, c: true }, 4])).toEqual([ - 1, - 2, - { - a: true, - b: { x: true, y: true, z: true }, - c: true, - }, - 4, - ]); + expect(sortedJsonStringify([1, 2, { b: { z: true, x: true, y: true }, a: true, c: true }, 4])).toEqual( + `[1,2,{"a":true,"b":{"x":true,"y":true,"z":true},"c":true},4]`, + ); }); }); }); diff --git a/packages/launchpad/src/encoding.ts b/packages/launchpad/src/encoding.ts index df041d12..6090cc79 100644 --- a/packages/launchpad/src/encoding.ts +++ b/packages/launchpad/src/encoding.ts @@ -5,25 +5,30 @@ import { Uint53 } from "@cosmjs/math"; import { Msg } from "./msgs"; import { StdFee } from "./types"; -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export function sortJson(json: any): any { - if (typeof json !== "object" || json === null) { - return json; +function sortedObject(obj: any): any { + if (typeof obj !== "object" || obj === null) { + return obj; } - if (Array.isArray(json)) { - return json.map(sortJson); + if (Array.isArray(obj)) { + return obj.map(sortedObject); } - const sortedKeys = Object.keys(json).sort(); + const sortedKeys = Object.keys(obj).sort(); const result = sortedKeys.reduce( (accumulator, key) => ({ ...accumulator, - [key]: sortJson(json[key]), + [key]: sortedObject(obj[key]), }), {}, ); return result; } +/** Returns a JSON string with objects sorted by key */ +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export function sortedJsonStringify(obj: any): string { + return JSON.stringify(sortedObject(obj)); +} + /** * The document to be signed * @@ -57,6 +62,5 @@ export function makeSignDoc( } export function serializeSignDoc(signDoc: StdSignDoc): Uint8Array { - const sortedSignDoc = sortJson(signDoc); - return toUtf8(JSON.stringify(sortedSignDoc)); + return toUtf8(sortedJsonStringify(signDoc)); } diff --git a/packages/launchpad/types/encoding.d.ts b/packages/launchpad/types/encoding.d.ts index 1144a81d..0cad6f04 100644 --- a/packages/launchpad/types/encoding.d.ts +++ b/packages/launchpad/types/encoding.d.ts @@ -1,6 +1,7 @@ import { Msg } from "./msgs"; import { StdFee } from "./types"; -export declare function sortJson(json: any): any; +/** Returns a JSON string with objects sorted by key */ +export declare function sortedJsonStringify(obj: any): string; /** * The document to be signed *