diff --git a/CHANGELOG.md b/CHANGELOG.md index bd7aca98..00d536e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,13 @@ and this project adheres to - @cosmjs/socket: Upgrade dependency "ws" to version 7 to avoid potential security problems. +## [0.25.6] - 2021-07-26 + +### Fixed + +- @cosmjs/stargate: Fix types `AminoMsgTransfer` and `AminoHeight` as well as + the encoding of `MsgTransfer` for Amino signing. + ## [0.25.5] - 2021-06-23 ### Added @@ -554,6 +561,7 @@ CHANGELOG entries missing. Please see [the diff][0.24.1]. - @cosmjs/sdk38: Rename package to @cosmjs/launchpad. [unreleased]: https://github.com/cosmos/cosmjs/compare/v0.25.3...HEAD +[0.25.6]: https://github.com/cosmos/cosmjs/compare/v0.25.5...v0.25.6 [0.25.5]: https://github.com/cosmos/cosmjs/compare/v0.25.4...v0.25.5 [0.25.4]: https://github.com/cosmos/cosmjs/compare/v0.25.3...v0.25.4 [0.25.3]: https://github.com/cosmos/cosmjs/compare/v0.25.2...v0.25.3 diff --git a/packages/amino/nonces/1627297145 b/packages/amino/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/amino/package.json b/packages/amino/package.json index dd50b134..66e38e9e 100644 --- a/packages/amino/package.json +++ b/packages/amino/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/amino", - "version": "0.25.5", + "version": "0.25.6", "description": "Helpers for Amino based signing which are shared between @cosmjs/launchpad and @cosmjs/stargate.", "contributors": [ "Simon Warta " diff --git a/packages/cli/nonces/1627297145 b/packages/cli/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/cli/package.json b/packages/cli/package.json index 70cbf436..df421021 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/cli", - "version": "0.25.5", + "version": "0.25.6", "description": "Command line interface", "contributors": [ "IOV SAS ", diff --git a/packages/cosmwasm-stargate/nonces/1627297145 b/packages/cosmwasm-stargate/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/cosmwasm-stargate/package.json b/packages/cosmwasm-stargate/package.json index 3333a1b4..8722002e 100644 --- a/packages/cosmwasm-stargate/package.json +++ b/packages/cosmwasm-stargate/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/cosmwasm-stargate", - "version": "0.25.5", + "version": "0.25.6", "description": "CosmWasm SDK", "contributors": [ "Will Clark " diff --git a/packages/crypto/nonces/1627297145 b/packages/crypto/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/crypto/package.json b/packages/crypto/package.json index 5bd94648..c0604080 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/crypto", - "version": "0.25.5", + "version": "0.25.6", "description": "Cryptography resources for blockchain projects", "contributors": [ "IOV SAS ", diff --git a/packages/encoding/nonces/1627297145 b/packages/encoding/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/encoding/package.json b/packages/encoding/package.json index d7b20628..d64fc94d 100644 --- a/packages/encoding/package.json +++ b/packages/encoding/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/encoding", - "version": "0.25.5", + "version": "0.25.6", "description": "Encoding helpers for blockchain projects", "contributors": [ "IOV SAS " diff --git a/packages/faucet-client/nonces/1627297145 b/packages/faucet-client/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/faucet-client/package.json b/packages/faucet-client/package.json index 3de96520..cb4f08f8 100644 --- a/packages/faucet-client/package.json +++ b/packages/faucet-client/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/faucet-client", - "version": "0.25.5", + "version": "0.25.6", "description": "The faucet client", "contributors": [ "Will Clark " diff --git a/packages/faucet/nonces/1627297145 b/packages/faucet/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/faucet/package.json b/packages/faucet/package.json index ae8952c2..fc419272 100644 --- a/packages/faucet/package.json +++ b/packages/faucet/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/faucet", - "version": "0.25.5", + "version": "0.25.6", "description": "The faucet", "contributors": [ "Ethan Frey ", diff --git a/packages/json-rpc/nonces/1627297145 b/packages/json-rpc/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/package.json b/packages/json-rpc/package.json index 817f4831..32441613 100644 --- a/packages/json-rpc/package.json +++ b/packages/json-rpc/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/json-rpc", - "version": "0.25.5", + "version": "0.25.6", "description": "Framework for implementing a JSON-RPC 2.0 API", "contributors": [ "IOV SAS ", diff --git a/packages/launchpad/nonces/1627297145 b/packages/launchpad/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/launchpad/package.json b/packages/launchpad/package.json index edb5c287..bea8c856 100644 --- a/packages/launchpad/package.json +++ b/packages/launchpad/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/launchpad", - "version": "0.25.5", + "version": "0.25.6", "description": "A client library for the Cosmos SDK 0.37 (cosmoshub-3), 0.38 and 0.39 (Launchpad)", "contributors": [ "Ethan Frey ", diff --git a/packages/ledger-amino/nonces/1627297145 b/packages/ledger-amino/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/ledger-amino/package.json b/packages/ledger-amino/package.json index c6c8df69..f59f3626 100644 --- a/packages/ledger-amino/package.json +++ b/packages/ledger-amino/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/ledger-amino", - "version": "0.25.5", + "version": "0.25.6", "description": "A library for signing Amino-encoded transactions using Ledger devices", "contributors": [ "Will Clark " diff --git a/packages/math/nonces/1627297145 b/packages/math/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/math/package.json b/packages/math/package.json index 6fb30761..3af0b53a 100644 --- a/packages/math/package.json +++ b/packages/math/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/math", - "version": "0.25.5", + "version": "0.25.6", "description": "Math helpers for blockchain projects", "contributors": [ "IOV SAS " diff --git a/packages/proto-signing/nonces/1627297145 b/packages/proto-signing/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/proto-signing/package.json b/packages/proto-signing/package.json index 85d6eaf3..f08f5ac4 100644 --- a/packages/proto-signing/package.json +++ b/packages/proto-signing/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/proto-signing", - "version": "0.25.5", + "version": "0.25.6", "description": "Utilities for protobuf based signing (Cosmos SDK 0.40+)", "contributors": [ "Will Clark ", diff --git a/packages/socket/nonces/1627297145 b/packages/socket/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/socket/package.json b/packages/socket/package.json index cb8f6cff..606232ff 100644 --- a/packages/socket/package.json +++ b/packages/socket/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/socket", - "version": "0.25.5", + "version": "0.25.6", "description": "Utility functions for working with WebSockets", "contributors": [ "IOV SAS ", diff --git a/packages/stargate/nonces/1627297145 b/packages/stargate/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/stargate/package.json b/packages/stargate/package.json index 0a6dbb33..8498493f 100644 --- a/packages/stargate/package.json +++ b/packages/stargate/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/stargate", - "version": "0.25.5", + "version": "0.25.6", "description": "Utilities for Cosmos SDK 0.40", "contributors": [ "Simon Warta " diff --git a/packages/stargate/src/aminomsgs.ts b/packages/stargate/src/aminomsgs.ts index 5040c11f..aaabe64d 100644 --- a/packages/stargate/src/aminomsgs.ts +++ b/packages/stargate/src/aminomsgs.ts @@ -338,8 +338,10 @@ export function isAminoMsgUndelegate(msg: AminoMsg): msg is AminoMsgUndelegate { // https://github.com/cosmos/ibc-go/blob/07b6a97b67d17fd214a83764cbdb2c2c3daef445/modules/core/02-client/types/client.pb.go#L297-L312 interface AminoHeight { - readonly revision_number: string; - readonly revision_height: string; + /** 0 values must be omitted (https://github.com/cosmos/cosmos-sdk/blob/v0.42.7/x/ibc/core/02-client/types/client.pb.go#L252). */ + readonly revision_number?: string; + /** 0 values must be omitted (https://github.com/cosmos/cosmos-sdk/blob/v0.42.7/x/ibc/core/02-client/types/client.pb.go#L254). */ + readonly revision_height?: string; } // https://github.com/cosmos/ibc-go/blob/07b6a97b67d17fd214a83764cbdb2c2c3daef445/modules/apps/transfer/types/tx.pb.go#L33-L53 @@ -354,10 +356,19 @@ export interface AminoMsgTransfer extends AminoMsg { readonly sender: string; /** Bech32 account address */ readonly receiver: string; - readonly timeout_height?: AminoHeight; - // Timeout timestamp (in nanoseconds) relative to the current block timestamp. - // The timeout is disabled when set to 0. - readonly timeout_timestamp: string; + /** + * The timeout as a (revision_number, revision_height) pair. + * + * This fied is is non-optional (https://github.com/cosmos/cosmos-sdk/blob/v0.42.7/x/ibc/applications/transfer/types/tx.pb.go#L49). + * In order to not set the timeout height, set it to {}. + */ + readonly timeout_height: AminoHeight; + /** + * Timeout timestamp (in nanoseconds). The timeout is disabled when set to 0. + * + * 0 values must be omitted (https://github.com/cosmos/cosmos-sdk/blob/v0.42.7/x/ibc/applications/transfer/types/tx.pb.go#L52). + */ + readonly timeout_timestamp?: string; }; } diff --git a/packages/stargate/src/aminotypes.spec.ts b/packages/stargate/src/aminotypes.spec.ts index 6a4509aa..338cbe28 100644 --- a/packages/stargate/src/aminotypes.spec.ts +++ b/packages/stargate/src/aminotypes.spec.ts @@ -353,6 +353,70 @@ describe("AminoTypes", () => { expect(aminoMsg).toEqual(expected); }); + it("works for MsgTransfer with empty values", () => { + const msg: MsgTransfer = { + sourcePort: "testport", + sourceChannel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeoutHeight: { + revisionHeight: Long.UZERO, + revisionNumber: Long.UZERO, + }, + timeoutTimestamp: Long.UZERO, + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: msg, + }); + const expected: AminoMsgTransfer = { + type: "cosmos-sdk/MsgTransfer", + value: { + source_port: "testport", + source_channel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeout_height: { + revision_height: undefined, + revision_number: undefined, + }, + timeout_timestamp: undefined, + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgTransfer with no height timeout", () => { + const msg: MsgTransfer = { + sourcePort: "testport", + sourceChannel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeoutHeight: undefined, + timeoutTimestamp: Long.UZERO, + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: msg, + }); + const expected: AminoMsgTransfer = { + type: "cosmos-sdk/MsgTransfer", + value: { + source_port: "testport", + source_channel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeout_height: {}, + timeout_timestamp: undefined, + }, + }; + expect(aminoMsg).toEqual(expected); + }); + it("works with custom type url", () => { const msg = { foo: "bar", @@ -661,6 +725,41 @@ describe("AminoTypes", () => { }); }); + it("works for MsgTransfer with default values", () => { + const aminoMsg: AminoMsgTransfer = { + type: "cosmos-sdk/MsgTransfer", + value: { + source_port: "testport", + source_channel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeout_height: { + // revision_height omitted + // revision_number omitted + }, + // timeout_timestamp omitted + }, + }; + const msg = new AminoTypes().fromAmino(aminoMsg); + const expectedValue: MsgTransfer = { + sourcePort: "testport", + sourceChannel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeoutHeight: { + revisionHeight: Long.UZERO, + revisionNumber: Long.UZERO, + }, + timeoutTimestamp: Long.UZERO, + }; + expect(msg).toEqual({ + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: expectedValue, + }); + }); + it("works for custom type url", () => { const aminoMsg = { type: "my-sdk/CustomType", diff --git a/packages/stargate/src/aminotypes.ts b/packages/stargate/src/aminotypes.ts index 8c2d89a5..7df819fd 100644 --- a/packages/stargate/src/aminotypes.ts +++ b/packages/stargate/src/aminotypes.ts @@ -41,6 +41,22 @@ export interface AminoConverter { readonly fromAmino: (value: any) => any; } +function omitDefault(input: T): T | undefined { + if (typeof input === "string") { + return input === "" ? undefined : input; + } + + if (typeof input === "number") { + return input === 0 ? undefined : input; + } + + if (Long.isLong(input)) { + return input.isZero() ? undefined : input; + } + + throw new Error(`Got unsupported type '${typeof input}'`); +} + function createDefaultTypes(prefix: string): Record { return { "/cosmos.bank.v1beta1.MsgSend": { @@ -345,11 +361,11 @@ function createDefaultTypes(prefix: string): Record { receiver: receiver, timeout_height: timeoutHeight ? { - revision_height: timeoutHeight.revisionHeight.toString(), - revision_number: timeoutHeight.revisionNumber.toString(), + revision_height: omitDefault(timeoutHeight.revisionHeight)?.toString(), + revision_number: omitDefault(timeoutHeight.revisionNumber)?.toString(), } - : undefined, - timeout_timestamp: timeoutTimestamp.toString(), + : {}, + timeout_timestamp: omitDefault(timeoutTimestamp)?.toString(), }), fromAmino: ({ source_port, @@ -367,11 +383,11 @@ function createDefaultTypes(prefix: string): Record { receiver: receiver, timeoutHeight: timeout_height ? { - revisionHeight: Long.fromString(timeout_height.revision_height, true), - revisionNumber: Long.fromString(timeout_height.revision_number, true), + revisionHeight: Long.fromString(timeout_height.revision_height || "0", true), + revisionNumber: Long.fromString(timeout_height.revision_number || "0", true), } : undefined, - timeoutTimestamp: Long.fromString(timeout_timestamp, true), + timeoutTimestamp: Long.fromString(timeout_timestamp || "0", true), }), }, }; diff --git a/packages/stargate/src/signingstargateclient.spec.ts b/packages/stargate/src/signingstargateclient.spec.ts index 961a59d5..44d3b01a 100644 --- a/packages/stargate/src/signingstargateclient.spec.ts +++ b/packages/stargate/src/signingstargateclient.spec.ts @@ -6,6 +6,7 @@ import { MsgSend } from "cosmjs-types/cosmos/bank/v1beta1/tx"; import { Coin } from "cosmjs-types/cosmos/base/v1beta1/coin"; import { DeepPartial, MsgDelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx"; import { AuthInfo, TxBody, TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; +import Long from "long"; import protobuf from "protobufjs/minimal"; import { decodeTxRaw } from "../../proto-signing/build"; @@ -13,7 +14,7 @@ import { AminoMsgDelegate } from "./aminomsgs"; import { AminoTypes } from "./aminotypes"; import { MsgDelegateEncodeObject, MsgSendEncodeObject } from "./encodeobjects"; import { PrivateSigningStargateClient, SigningStargateClient } from "./signingstargateclient"; -import { assertIsBroadcastTxSuccess } from "./stargateclient"; +import { assertIsBroadcastTxSuccess, isBroadcastTxFailure } from "./stargateclient"; import { defaultSendFee, faucet, @@ -105,6 +106,98 @@ describe("SigningStargateClient", () => { }); }); + describe("sendIbcTokens", () => { + it("works with direct signing", async () => { + pendingWithoutSimapp(); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner(simapp.tendermintUrl, wallet); + const memo = "Cross-chain fun"; + const fee = { + amount: coins(2000, "ucosm"), + gas: "180000", // 180k + }; + + // both timeouts set + { + const result = await client.sendIbcTokens( + faucet.address0, + faucet.address1, + coin(1234, "ucosm"), + "fooPort", + "fooChannel", + { revisionHeight: Long.fromNumber(123), revisionNumber: Long.fromNumber(456) }, + Math.floor(Date.now() / 1000) + 60, + fee, + memo, + ); + // CheckTx must pass but the execution must fail in DeliverTx due to invalid channel/port + expect(isBroadcastTxFailure(result)).toEqual(true); + } + + // no height timeout + { + const result = await client.sendIbcTokens( + faucet.address0, + faucet.address1, + coin(1234, "ucosm"), + "fooPort", + "fooChannel", + undefined, + Math.floor(Date.now() / 1000) + 60, + fee, + memo, + ); + // CheckTx must pass but the execution must fail in DeliverTx due to invalid channel/port + expect(isBroadcastTxFailure(result)).toEqual(true); + } + }); + + it("works with Amino signing", async () => { + pendingWithoutSimapp(); + const wallet = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner(simapp.tendermintUrl, wallet); + const memo = "Cross-chain fun"; + const fee = { + amount: coins(2000, "ucosm"), + gas: "180000", // 180k + }; + + // both timeouts set + { + const result = await client.sendIbcTokens( + faucet.address0, + faucet.address1, + coin(1234, "ucosm"), + "fooPort", + "fooChannel", + { revisionHeight: Long.fromNumber(123), revisionNumber: Long.fromNumber(456) }, + Math.floor(Date.now() / 1000) + 60, + fee, + memo, + ); + // CheckTx must pass but the execution must fail in DeliverTx due to invalid channel/port + expect(isBroadcastTxFailure(result)).toEqual(true); + } + + // no height timeout + { + const result = await client.sendIbcTokens( + faucet.address0, + faucet.address1, + coin(1234, "ucosm"), + "fooPort", + "fooChannel", + undefined, + Math.floor(Date.now() / 1000) + 60, + fee, + memo, + ); + // CheckTx must pass but the execution must fail in DeliverTx due to invalid channel/port + expect(isBroadcastTxFailure(result)).toEqual(true); + } + }); + }); + describe("signAndBroadcast", () => { describe("direct mode", () => { it("works", async () => { diff --git a/packages/stream/nonces/1627297145 b/packages/stream/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/stream/package.json b/packages/stream/package.json index 4d04f30a..c8402387 100644 --- a/packages/stream/package.json +++ b/packages/stream/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/stream", - "version": "0.25.5", + "version": "0.25.6", "description": "Utility functions for producing and consuming streams", "contributors": [ "IOV SAS ", diff --git a/packages/tendermint-rpc/nonces/1627297145 b/packages/tendermint-rpc/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/tendermint-rpc/package.json b/packages/tendermint-rpc/package.json index 6cc583e0..94d48223 100644 --- a/packages/tendermint-rpc/package.json +++ b/packages/tendermint-rpc/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/tendermint-rpc", - "version": "0.25.5", + "version": "0.25.6", "description": "Tendermint RPC clients", "contributors": [ "IOV SAS ", diff --git a/packages/utils/nonces/1627297145 b/packages/utils/nonces/1627297145 new file mode 100644 index 00000000..e69de29b diff --git a/packages/utils/package.json b/packages/utils/package.json index 001d58ed..6e785dfc 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@cosmjs/utils", - "version": "0.25.5", + "version": "0.25.6", "description": "Utility tools, primarily for testing code", "contributors": [ "IOV SAS "