diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b39c428..5e3a9cc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ and this project adheres to ([#932]). - @cosmjs/stargate: Merge `DeliverTxFailure` and `DeliverTxSuccess` into a single `DeliverTxResponse` ([#878], [#949]). Add `assertIsDeliverTxFailure`. +- @cosmjs/stargate: Created `types.Dec` decoder function + `decodeCosmosSdkDecFromProto`. - @cosmjs/amino: Added `StdTx`, `isStdTx` and `makeStdTx` and removed them from @cosmjs/launchpad. They are re-exported in @cosmjs/launchpad for backwards compatibility. diff --git a/packages/stargate/src/index.ts b/packages/stargate/src/index.ts index 7b7eedc8..3e41e69b 100644 --- a/packages/stargate/src/index.ts +++ b/packages/stargate/src/index.ts @@ -62,6 +62,7 @@ export { BankExtension, createPagination, createProtobufRpcClient, + decodeCosmosSdkDecFromProto, DistributionExtension, GovExtension, GovParamsType, diff --git a/packages/stargate/src/queries/index.ts b/packages/stargate/src/queries/index.ts index 56160501..913b2f8c 100644 --- a/packages/stargate/src/queries/index.ts +++ b/packages/stargate/src/queries/index.ts @@ -11,4 +11,9 @@ export { GovExtension, GovParamsType, GovProposalId, setupGovExtension } from ". export { IbcExtension, setupIbcExtension } from "./ibc"; export { setupStakingExtension, StakingExtension } from "./staking"; export { setupTxExtension, TxExtension } from "./tx"; -export { createPagination, createProtobufRpcClient, ProtobufRpcClient } from "./utils"; +export { + createPagination, + createProtobufRpcClient, + decodeCosmosSdkDecFromProto, + ProtobufRpcClient, +} from "./utils"; diff --git a/packages/stargate/src/queries/utils.spec.ts b/packages/stargate/src/queries/utils.spec.ts new file mode 100644 index 00000000..703efca4 --- /dev/null +++ b/packages/stargate/src/queries/utils.spec.ts @@ -0,0 +1,21 @@ +import { fromHex } from "@cosmjs/encoding"; + +import { decodeCosmosSdkDecFromProto } from "./utils"; + +describe("utils", () => { + describe("decodeCosmosSdkDecFromProto", () => { + it("works for string inputs", () => { + expect(decodeCosmosSdkDecFromProto("0").toString()).toEqual("0"); + expect(decodeCosmosSdkDecFromProto("1").toString()).toEqual("0.000000000000000001"); + expect(decodeCosmosSdkDecFromProto("3000000").toString()).toEqual("0.000000000003"); + expect(decodeCosmosSdkDecFromProto("123456789123456789").toString()).toEqual("0.123456789123456789"); + expect(decodeCosmosSdkDecFromProto("1234567891234567890").toString()).toEqual("1.23456789123456789"); + }); + + it("works for byte inputs", () => { + expect(decodeCosmosSdkDecFromProto(fromHex("313330303033343138373830313631333938")).toString()).toEqual( + "0.130003418780161398", + ); + }); + }); +}); diff --git a/packages/stargate/src/queries/utils.ts b/packages/stargate/src/queries/utils.ts index 9b565d03..c931727d 100644 --- a/packages/stargate/src/queries/utils.ts +++ b/packages/stargate/src/queries/utils.ts @@ -1,5 +1,5 @@ -import { Bech32 } from "@cosmjs/encoding"; -import { Uint64 } from "@cosmjs/math"; +import { Bech32, fromAscii } from "@cosmjs/encoding"; +import { Decimal, Uint64 } from "@cosmjs/math"; import { PageRequest } from "cosmjs-types/cosmos/base/query/v1beta1/pagination"; import Long from "long"; @@ -53,3 +53,14 @@ export function longify(value: string | number | Long | Uint64): Long { const checkedValue = Uint64.fromString(value.toString()); return Long.fromBytesBE([...checkedValue.toBytesBigEndian()], true); } + +/** + * Takes a string or binary encoded `github.com/cosmos/cosmos-sdk/types.Dec` from the + * protobuf API and converts it into a `Decimal` with 18 fractional digits. + * + * See https://github.com/cosmos/cosmos-sdk/issues/10863 for more context why this is needed. + */ +export function decodeCosmosSdkDecFromProto(input: string | Uint8Array): Decimal { + const asString = typeof input === "string" ? input : fromAscii(input); + return Decimal.fromAtomics(asString, 18); +}