From 0136d127e63a027bffba38fb55cb716725774e9e Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 4 Aug 2022 21:12:55 +0200 Subject: [PATCH] Add Amino JSON support for MsgCreateVestingAccount --- CHANGELOG.md | 1 + packages/stargate/src/index.ts | 2 + packages/stargate/src/modules/index.ts | 6 +- .../src/modules/vesting/aminomessages.spec.ts | 64 ++++++++++++++ .../src/modules/vesting/aminomessages.ts | 52 ++++++++++- .../src/modules/vesting/messages.spec.ts | 87 +++++++++++++------ packages/stargate/src/testutils.spec.ts | 6 ++ 7 files changed, 189 insertions(+), 29 deletions(-) create mode 100644 packages/stargate/src/modules/vesting/aminomessages.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index df259927..0942c23a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to - @cosmjs/stargate: Add missing exports `AminoMsgTransfer`/`isAminoMsgTransfer`. - @cosmjs/stargate: Add support for `MsgVoteWeighted` (register by default and create Amino JSON converters) ([#1224]). +- @cosmjs/stargate: Add Amino JSON support for `MsgCreateVestingAccount`. [#1072]: https://github.com/cosmos/cosmjs/issues/1072 [#1154]: https://github.com/cosmos/cosmjs/issues/1154 diff --git a/packages/stargate/src/index.ts b/packages/stargate/src/index.ts index 3f8748c3..47d27f6b 100644 --- a/packages/stargate/src/index.ts +++ b/packages/stargate/src/index.ts @@ -5,6 +5,7 @@ export * as logs from "./logs"; export { AminoMsgBeginRedelegate, AminoMsgCreateValidator, + AminoMsgCreateVestingAccount, AminoMsgDelegate, AminoMsgDeposit, AminoMsgEditValidator, @@ -31,6 +32,7 @@ export { IbcExtension, isAminoMsgBeginRedelegate, isAminoMsgCreateValidator, + isAminoMsgCreateVestingAccount, isAminoMsgDelegate, isAminoMsgDeposit, isAminoMsgEditValidator, diff --git a/packages/stargate/src/modules/index.ts b/packages/stargate/src/modules/index.ts index 70b5531d..e96cf863 100644 --- a/packages/stargate/src/modules/index.ts +++ b/packages/stargate/src/modules/index.ts @@ -90,5 +90,9 @@ export { } from "./staking/messages"; export { setupStakingExtension, StakingExtension } from "./staking/queries"; export { setupTxExtension, TxExtension } from "./tx/queries"; -export { createVestingAminoConverters } from "./vesting/aminomessages"; +export { + AminoMsgCreateVestingAccount, + createVestingAminoConverters, + isAminoMsgCreateVestingAccount, +} from "./vesting/aminomessages"; export { vestingTypes } from "./vesting/messages"; diff --git a/packages/stargate/src/modules/vesting/aminomessages.spec.ts b/packages/stargate/src/modules/vesting/aminomessages.spec.ts new file mode 100644 index 00000000..3060c859 --- /dev/null +++ b/packages/stargate/src/modules/vesting/aminomessages.spec.ts @@ -0,0 +1,64 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { coins } from "@cosmjs/amino"; +import { MsgCreateVestingAccount } from "cosmjs-types/cosmos/vesting/v1beta1/tx"; +import Long from "long"; + +import { AminoTypes } from "../../aminotypes"; +import { AminoMsgCreateVestingAccount, createVestingAminoConverters } from "./aminomessages"; + +describe("vesting Amino messages", () => { + describe("toAmino", () => { + it("works for MsgCreateVestingAccount", () => { + const msg = MsgCreateVestingAccount.fromPartial({ + fromAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + toAddress: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + amount: coins(1234, "ucosm"), + endTime: Long.fromString("1838718434"), + delayed: true, + }); + const aminoTypes = new AminoTypes(createVestingAminoConverters()); + const aminoMsg = aminoTypes.toAmino({ + typeUrl: "/cosmos.vesting.v1beta1.MsgCreateVestingAccount", + value: msg, + }); + const expected: AminoMsgCreateVestingAccount = { + type: "cosmos-sdk/MsgCreateVestingAccount", + value: { + from_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + to_address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + amount: coins(1234, "ucosm"), + end_time: "1838718434", + delayed: true, + }, + }; + expect(aminoMsg).toEqual(expected); + }); + }); + + describe("fromAmino", () => { + it("works for MsgCreateVestingAccount", () => { + const aminoMsg: AminoMsgCreateVestingAccount = { + type: "cosmos-sdk/MsgCreateVestingAccount", + value: { + from_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + to_address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + amount: coins(1234, "ucosm"), + end_time: "1838718434", + delayed: true, + }, + }; + const msg = new AminoTypes(createVestingAminoConverters()).fromAmino(aminoMsg); + const expectedValue: MsgCreateVestingAccount = { + fromAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + toAddress: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + amount: coins(1234, "ucosm"), + endTime: Long.fromString("1838718434"), + delayed: true, + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.vesting.v1beta1.MsgCreateVestingAccount", + value: expectedValue, + }); + }); + }); +}); diff --git a/packages/stargate/src/modules/vesting/aminomessages.ts b/packages/stargate/src/modules/vesting/aminomessages.ts index b50ba8b2..d33d3884 100644 --- a/packages/stargate/src/modules/vesting/aminomessages.ts +++ b/packages/stargate/src/modules/vesting/aminomessages.ts @@ -1,7 +1,57 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { AminoMsg, Coin } from "@cosmjs/amino"; +import { MsgCreateVestingAccount } from "cosmjs-types/cosmos/vesting/v1beta1/tx"; +import Long from "long"; + import { AminoConverters } from "../../aminotypes"; +export interface AminoMsgCreateVestingAccount extends AminoMsg { + readonly type: "cosmos-sdk/MsgCreateVestingAccount"; + readonly value: { + /** Bech32 account address */ + readonly from_address: string; + /** Bech32 account address */ + readonly to_address: string; + readonly amount: readonly Coin[]; + readonly end_time: string; + readonly delayed: boolean; + }; +} + +export function isAminoMsgCreateVestingAccount(msg: AminoMsg): msg is AminoMsgCreateVestingAccount { + return msg.type === "cosmos-sdk/MsgCreateVestingAccount"; +} + export function createVestingAminoConverters(): AminoConverters { return { - "/cosmos.vesting.v1beta1.MsgCreateVestingAccount": "not_supported_by_chain", + "/cosmos.vesting.v1beta1.MsgCreateVestingAccount": { + aminoType: "cosmos-sdk/MsgCreateVestingAccount", + toAmino: ({ + fromAddress, + toAddress, + amount, + endTime, + delayed, + }: MsgCreateVestingAccount): AminoMsgCreateVestingAccount["value"] => ({ + from_address: fromAddress, + to_address: toAddress, + amount: [...amount], + end_time: endTime.toString(), + delayed: delayed, + }), + fromAmino: ({ + from_address, + to_address, + amount, + end_time, + delayed, + }: AminoMsgCreateVestingAccount["value"]): MsgCreateVestingAccount => ({ + fromAddress: from_address, + toAddress: to_address, + amount: [...amount], + endTime: Long.fromString(end_time), + delayed: delayed, + }), + }, }; } diff --git a/packages/stargate/src/modules/vesting/messages.spec.ts b/packages/stargate/src/modules/vesting/messages.spec.ts index 18b66a1d..bc1588d0 100644 --- a/packages/stargate/src/modules/vesting/messages.spec.ts +++ b/packages/stargate/src/modules/vesting/messages.spec.ts @@ -1,4 +1,4 @@ -import { coin, coins } from "@cosmjs/amino"; +import { coin, coins, Secp256k1HdWallet } from "@cosmjs/amino"; import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; import { MsgCreateVestingAccount } from "cosmjs-types/cosmos/vesting/v1beta1/tx"; import Long from "long"; @@ -10,37 +10,70 @@ import { faucet, makeRandomAddress, pendingWithoutSimapp, + pendingWithoutSimapp46, simapp, } from "../../testutils.spec"; -describe("vestingTypes", () => { - it("can sign MsgCreateVestingAccount with sign mode direct", async () => { - pendingWithoutSimapp(); - const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); - const client = await SigningStargateClient.connectWithSigner( - simapp.tendermintUrl, - wallet, - defaultSigningClientOptions, - ); +describe("vesting messages", () => { + describe("MsgCreateVestingAccount", () => { + it("works with sign mode direct", async () => { + pendingWithoutSimapp(); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); - const memo = "Vesting is cool!"; - const recipient = makeRandomAddress(); - const vestingMsg = { - typeUrl: "/cosmos.vesting.v1beta1.MsgCreateVestingAccount", - value: MsgCreateVestingAccount.fromPartial({ - fromAddress: faucet.address0, - toAddress: recipient, - amount: coins(1234, "ucosm"), - endTime: Long.fromString("1838718434"), - delayed: true, - }), - }; + const memo = "Vesting is cool!"; + const recipient = makeRandomAddress(); + const vestingMsg = { + typeUrl: "/cosmos.vesting.v1beta1.MsgCreateVestingAccount", + value: MsgCreateVestingAccount.fromPartial({ + fromAddress: faucet.address0, + toAddress: recipient, + amount: coins(1234, "ucosm"), + endTime: Long.fromString("1838718434"), + delayed: true, + }), + }; - const result = await client.signAndBroadcast(faucet.address0, [vestingMsg], "auto", memo); - assertIsDeliverTxSuccess(result); - const balance = await client.getBalance(recipient, "ucosm"); - expect(balance).toEqual(coin(1234, "ucosm")); + const result = await client.signAndBroadcast(faucet.address0, [vestingMsg], "auto", memo); + assertIsDeliverTxSuccess(result); + const balance = await client.getBalance(recipient, "ucosm"); + expect(balance).toEqual(coin(1234, "ucosm")); - client.disconnect(); + client.disconnect(); + }); + + it("works with Amino JSON sign mode", async () => { + pendingWithoutSimapp46(); // Amino JSON broken on chain before Cosmos SDK 0.46 + const wallet = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const memo = "Vesting is cool!"; + const recipient = makeRandomAddress(); + const vestingMsg = { + typeUrl: "/cosmos.vesting.v1beta1.MsgCreateVestingAccount", + value: MsgCreateVestingAccount.fromPartial({ + fromAddress: faucet.address0, + toAddress: recipient, + amount: coins(1234, "ucosm"), + endTime: Long.fromString("1838718434"), + delayed: true, + }), + }; + + const result = await client.signAndBroadcast(faucet.address0, [vestingMsg], "auto", memo); + assertIsDeliverTxSuccess(result); + const balance = await client.getBalance(recipient, "ucosm"); + expect(balance).toEqual(coin(1234, "ucosm")); + + client.disconnect(); + }); }); }); diff --git a/packages/stargate/src/testutils.spec.ts b/packages/stargate/src/testutils.spec.ts index e6dc00a4..47f33fdc 100644 --- a/packages/stargate/src/testutils.spec.ts +++ b/packages/stargate/src/testutils.spec.ts @@ -33,6 +33,12 @@ export function pendingWithoutSimapp44Or46(): void { } } +export function pendingWithoutSimapp46(): void { + if (!simapp46Enabled()) { + return pending("Set SIMAPP46_ENABLED to enable Simapp based tests"); + } +} + export function pendingWithoutSimapp(): void { if (!simappEnabled()) { return pending("Set SIMAPP{44,46}_ENABLED to enable Simapp based tests");