From bfa2525bfa224d3b09fb261b3c4a27aec32207a8 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Tue, 27 Oct 2020 15:42:50 +0100 Subject: [PATCH] stargate: Extract encoding helpers and add tests --- packages/stargate/src/encoding.spec.ts | 58 +++++++++++++++++++ packages/stargate/src/encoding.ts | 35 +++++++++++ .../stargate/src/signingstargateclient.ts | 37 +----------- packages/stargate/types/encoding.d.ts | 3 + 4 files changed, 97 insertions(+), 36 deletions(-) create mode 100644 packages/stargate/src/encoding.spec.ts create mode 100644 packages/stargate/src/encoding.ts create mode 100644 packages/stargate/types/encoding.d.ts diff --git a/packages/stargate/src/encoding.spec.ts b/packages/stargate/src/encoding.spec.ts new file mode 100644 index 00000000..e5611827 --- /dev/null +++ b/packages/stargate/src/encoding.spec.ts @@ -0,0 +1,58 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { coin, coins, makeSignDoc as makeSignDocAmino } from "@cosmjs/launchpad"; + +import { cosmos } from "./codec"; +import { getMsgType, snakifyForAmino } from "./encoding"; +import { faucet, validator } from "./testutils.spec"; + +describe("encoding", () => { + describe("snakifyForAmino", () => { + it("works", () => { + const msg = cosmos.staking.v1beta1.MsgDelegate.create({ + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(1234, "ustake"), + }); + const msgAny = { + type: "cosmos-sdk/MsgDelegate", + value: msg, + }; + const fee = { + amount: coins(2000, "ucosm"), + gas: "200000", + }; + const chainId = "testing"; + const memo = "testing testing"; + const accountNumber = 1; + const sequence = 16; + const signDoc = makeSignDocAmino([msgAny], fee, chainId, memo, accountNumber, sequence); + expect(snakifyForAmino(signDoc)).toEqual({ + ...signDoc, + msgs: [ + { + type: "cosmos-sdk/MsgDelegate", + value: { + delegator_address: faucet.address0, + validator_address: validator.validatorAddress, + amount: { + amount: "1234", + denom: "ustake", + }, + }, + }, + ], + }); + }); + }); + + describe("getMsgType", () => { + it("works for known type url", () => { + const msgType = getMsgType("/cosmos.staking.v1beta1.MsgDelegate"); + expect(msgType).toEqual("cosmos-sdk/MsgDelegate"); + }); + + it("throws for unknown type url", () => { + expect(() => getMsgType("/xxx.Unknown")).toThrowError(/type url not known/i); + }); + }); +}); diff --git a/packages/stargate/src/encoding.ts b/packages/stargate/src/encoding.ts new file mode 100644 index 00000000..b745fc05 --- /dev/null +++ b/packages/stargate/src/encoding.ts @@ -0,0 +1,35 @@ +import { Msg, StdSignDoc } from "@cosmjs/launchpad"; + +function snakifyMsgValue(obj: Msg): Msg { + return { + ...obj, + value: Object.entries(obj.value).reduce( + (snakified, [key, value]) => ({ + ...snakified, + [key + .split(/(?=[A-Z])/) + .join("_") + .toLowerCase()]: value, + }), + {}, + ), + }; +} + +export function snakifyForAmino(signDoc: StdSignDoc): StdSignDoc { + return { + ...signDoc, + msgs: signDoc.msgs.map(snakifyMsgValue), + }; +} + +export function getMsgType(typeUrl: string): string { + const typeRegister: Record = { + "/cosmos.staking.v1beta1.MsgDelegate": "cosmos-sdk/MsgDelegate", + }; + const type = typeRegister[typeUrl]; + if (!type) { + throw new Error("Type URL not known"); + } + return type; +} diff --git a/packages/stargate/src/signingstargateclient.ts b/packages/stargate/src/signingstargateclient.ts index e7203f49..288b8e28 100644 --- a/packages/stargate/src/signingstargateclient.ts +++ b/packages/stargate/src/signingstargateclient.ts @@ -9,9 +9,7 @@ import { GasLimits, GasPrice, makeSignDoc as makeSignDocAmino, - Msg, StdFee, - StdSignDoc, } from "@cosmjs/launchpad"; import { Int53 } from "@cosmjs/math"; import { @@ -26,44 +24,11 @@ import { import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; import { cosmos } from "./codec"; +import { getMsgType, snakifyForAmino } from "./encoding"; import { BroadcastTxResponse, StargateClient } from "./stargateclient"; const { TxRaw } = cosmos.tx.v1beta1; -function snakifyMsgValue(obj: Msg): Msg { - return { - ...obj, - value: Object.entries(obj.value).reduce( - (snakified, [key, value]) => ({ - ...snakified, - [key - .split(/(?=[A-Z])/) - .join("_") - .toLowerCase()]: value, - }), - {}, - ), - }; -} - -function snakifyForAmino(signDoc: StdSignDoc): StdSignDoc { - return { - ...signDoc, - msgs: signDoc.msgs.map(snakifyMsgValue), - }; -} - -function getMsgType(typeUrl: string): string { - const typeRegister: Record = { - "/cosmos.staking.v1beta1.MsgDelegate": "cosmos-sdk/MsgDelegate", - }; - const type = typeRegister[typeUrl]; - if (!type) { - throw new Error("Type URL not known"); - } - return type; -} - const defaultGasPrice = GasPrice.fromString("0.025ucosm"); const defaultGasLimits: GasLimits = { send: 80000 }; diff --git a/packages/stargate/types/encoding.d.ts b/packages/stargate/types/encoding.d.ts new file mode 100644 index 00000000..605706cb --- /dev/null +++ b/packages/stargate/types/encoding.d.ts @@ -0,0 +1,3 @@ +import { StdSignDoc } from "@cosmjs/launchpad"; +export declare function snakifyForAmino(signDoc: StdSignDoc): StdSignDoc; +export declare function getMsgType(typeUrl: string): string;