diff --git a/packages/stargate/src/modules/staking/aminomessages.spec.ts b/packages/stargate/src/modules/staking/aminomessages.spec.ts index 3a2291463e..53927b2451 100644 --- a/packages/stargate/src/modules/staking/aminomessages.spec.ts +++ b/packages/stargate/src/modules/staking/aminomessages.spec.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { encodeBech32Pubkey } from "@cosmjs/amino"; import { fromBase64 } from "@cosmjs/encoding"; import { coin } from "@cosmjs/proto-signing"; +import { PubKey as CosmosCryptoSecp256k1Pubkey } from "cosmjs-types/cosmos/crypto/secp256k1/keys"; import { MsgBeginRedelegate, MsgCreateValidator, @@ -65,7 +65,13 @@ describe("AminoTypes", () => { validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", pubkey: { typeUrl: "/cosmos.crypto.secp256k1.PubKey", - value: fromBase64("A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ"), + value: Uint8Array.from( + CosmosCryptoSecp256k1Pubkey.encode( + CosmosCryptoSecp256k1Pubkey.fromPartial({ + key: fromBase64("A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ"), + }), + ).finish(), + ), }, value: coin(1234, "ucosm"), }; @@ -92,10 +98,10 @@ describe("AminoTypes", () => { min_self_delegation: "123", delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", - pubkey: encodeBech32Pubkey( - { type: "tendermint/PubKeySecp256k1", value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ" }, - "cosmos", - ), + pubkey: { + type: "tendermint/PubKeySecp256k1", + value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ", + }, value: coin(1234, "ucosm"), }, }; @@ -226,10 +232,10 @@ describe("AminoTypes", () => { min_self_delegation: "123", delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", - pubkey: encodeBech32Pubkey( - { type: "tendermint/PubKeySecp256k1", value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ" }, - "cosmos", - ), + pubkey: { + type: "tendermint/PubKeySecp256k1", + value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ", + }, value: coin(1234, "ucosm"), }, }; @@ -252,7 +258,13 @@ describe("AminoTypes", () => { validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", pubkey: { typeUrl: "/cosmos.crypto.secp256k1.PubKey", - value: fromBase64("A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ"), + value: Uint8Array.from( + CosmosCryptoSecp256k1Pubkey.encode( + CosmosCryptoSecp256k1Pubkey.fromPartial({ + key: fromBase64("A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ"), + }), + ).finish(), + ), }, value: coin(1234, "ucosm"), }; diff --git a/packages/stargate/src/modules/staking/aminomessages.ts b/packages/stargate/src/modules/staking/aminomessages.ts index 9a4723e9eb..957cbba0dc 100644 --- a/packages/stargate/src/modules/staking/aminomessages.ts +++ b/packages/stargate/src/modules/staking/aminomessages.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { AminoMsg, Coin, decodeBech32Pubkey, encodeBech32Pubkey } from "@cosmjs/amino"; -import { fromBase64, toBase64 } from "@cosmjs/encoding"; +import { AminoMsg, Coin, Pubkey } from "@cosmjs/amino"; import { Decimal } from "@cosmjs/math"; +import { anyToSinglePubkey, encodePubkey } from "@cosmjs/proto-signing"; import { assertDefinedAndNotNull } from "@cosmjs/utils"; import { MsgBeginRedelegate, @@ -51,8 +51,8 @@ export interface AminoMsgCreateValidator extends AminoMsg { readonly delegator_address: string; /** Bech32 encoded validator address */ readonly validator_address: string; - /** Bech32 encoded public key */ - readonly pubkey: string; + /** Public key */ + readonly pubkey: Pubkey; readonly value: Coin; }; } @@ -132,7 +132,7 @@ export function isAminoMsgUndelegate(msg: AminoMsg): msg is AminoMsgUndelegate { } export function createStakingAminoConverters( - prefix: string, + _prefix: string, ): Record { return { "/cosmos.staking.v1beta1.MsgBeginRedelegate": { @@ -194,13 +194,7 @@ export function createStakingAminoConverters( min_self_delegation: minSelfDelegation, delegator_address: delegatorAddress, validator_address: validatorAddress, - pubkey: encodeBech32Pubkey( - { - type: "tendermint/PubKeySecp256k1", - value: toBase64(pubkey.value), - }, - prefix, - ), + pubkey: anyToSinglePubkey(pubkey), value: value, }; }, @@ -213,10 +207,6 @@ export function createStakingAminoConverters( pubkey, value, }: AminoMsgCreateValidator["value"]): MsgCreateValidator => { - const decodedPubkey = decodeBech32Pubkey(pubkey); - if (decodedPubkey.type !== "tendermint/PubKeySecp256k1") { - throw new Error("Only Secp256k1 public keys are supported"); - } return { description: { moniker: description.moniker, @@ -233,10 +223,7 @@ export function createStakingAminoConverters( minSelfDelegation: min_self_delegation, delegatorAddress: delegator_address, validatorAddress: validator_address, - pubkey: { - typeUrl: "/cosmos.crypto.secp256k1.PubKey", - value: fromBase64(decodedPubkey.value), - }, + pubkey: encodePubkey(pubkey), value: value, }; }, diff --git a/packages/stargate/src/modules/staking/messages.spec.ts b/packages/stargate/src/modules/staking/messages.spec.ts index 6046ac00c7..56c3b53fa3 100644 --- a/packages/stargate/src/modules/staking/messages.spec.ts +++ b/packages/stargate/src/modules/staking/messages.spec.ts @@ -1,4 +1,4 @@ -import { coin } from "@cosmjs/amino"; +import { coin, Secp256k1HdWallet } from "@cosmjs/amino"; import { Random } from "@cosmjs/crypto"; import { fromBech32, toBase64, toBech32 } from "@cosmjs/encoding"; import { DirectSecp256k1HdWallet, encodePubkey } from "@cosmjs/proto-signing"; @@ -31,7 +31,7 @@ async function sendFeeAndStakingTokens(address: string): Promise { client.disconnect(); } -describe("staking messages", () => { +fdescribe("staking messages", () => { describe("MsgCreateValidator", () => { it("works", async () => { pendingWithoutSimapp(); @@ -82,5 +82,55 @@ describe("staking messages", () => { client.disconnect(); }); + + it("works with Amino JSON sign mode", async () => { + pendingWithoutSimapp(); + + const valWallet = await Secp256k1HdWallet.generate(); + const [valAccount] = await valWallet.getAccounts(); + + await sendFeeAndStakingTokens(valAccount.address); + + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + valWallet, + defaultSigningClientOptions, + ); + + const createMsg: MsgCreateValidatorEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgCreateValidator", + value: { + description: { + moniker: "That's me", + identity: "AABB1234", + website: "http://example.com/me", + details: "What should I write?", + securityContact: "DM on Twitter", + }, + commission: { + maxChangeRate: "10000000000000000", // 0.01 + maxRate: "200000000000000000", // 0.2 + rate: "100000000000000000", // 0.1 + }, + minSelfDelegation: "1", + // Those two addresses need to be the same with different prefix 🤷‍♂️ + delegatorAddress: valAccount.address, + validatorAddress: changePrefix(valAccount.address, "cosmosvaloper"), + pubkey: encodePubkey({ + type: "tendermint/PubKeyEd25519", + value: toBase64(Random.getBytes(32)), + }), + value: { + amount: "1", + denom: simapp.denomStaking, + }, + }, + }; + const result = await client.signAndBroadcast(valAccount.address, [createMsg], "auto"); + + assertIsDeliverTxSuccess(result); + + client.disconnect(); + }); }); });