Skip to content

Commit 8184348

Browse files
webmaster128allthatjazzleochiulamBigtoCautofix-ci[bot]
authored
Add support for Cosmos EVM (#1932)
* feat: add support for EthSecp256k1 public keys and signatures - Implemented encoding for EthSecp256k1 public keys in amino format. - Added functions to encode and decode EthSecp256k1 signatures. - Updated pubkey type definitions to include EthSecp256k1. - Enhanced signing clients to handle EthSecp256k1 accounts. - Created DirectEthSecp256k1HdWallet for managing EthSecp256k1 keypairs. - Added tests for DirectEthSecp256k1HdWallet and DirectEthSecp256k1Wallet functionalities. * feat: add DirectEthSecp256k1 wallet exports to index * feat: add EthSecp256k1Pubkey to pubkeyToRawAddress function * feat: support both eth_secp256k1 and ethsecp256k1 algorithms in pubkey encoding * feat: support ethsecp256k1 algorithm in SigningStargateClient for pubkey encoding * refactor: consolidate crypto imports in addresses.ts * feat: add utility functions for Ethereum secp256k1 account handling and update pubkey encoding in clients * feat: add ethsecp256k1 to supported pubkey types in isSinglePubkey function * feat: add support for ethsecp256k1 pubkey type in encoding * chore: Specific getAminoPubkey return type instead of any * test: add encoding and decoding functions for EthSecp256k1 signatures in tests * refactor: remove eslint disable for naming convention in signingcosmwasmclient.ts * fix: add missing 'ethsecp256k1' algorithm type in Algo definition * fix: update ethsecp256k1 references and class name in wallet documentation * doc: Add comments for the code block * rollback .pnp.cjs * chore: lint fix * fix: update getAminoPubkey return type and import missing pubkey types * [autofix.ci] apply automated fixes * Adapt to changes from main * Remove serialization/deserialization of DirectEthSecp256k1HdWallet See #1796 * Imrpve some comments and organize decodeSignature tests * Add CHANGELOG entry --------- Co-authored-by: allthatjazzleo <leo.pang@mantra.finance> Co-authored-by: Chiu Lam <happylam23@gmail.com> Co-authored-by: BigtoC <taitocdt@gmail.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent e3629c8 commit 8184348

18 files changed

+651
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ and this project adheres to
2323
price from the chain. ([#1926])
2424
- @cosmjs/cosmwasm-stargate: Add the ability to specify a custom account parser
2525
for `CosmWasmClient`. ([#1928])
26+
- Add support for Cosmos EVM key handling and signing. ([#1932])
2627

2728
[#1883]: https://github.com/cosmos/cosmjs/issues/1883
2829
[#1916]: https://github.com/cosmos/cosmjs/pull/1916
2930
[#1926]: https://github.com/cosmos/cosmjs/pull/1926
3031
[#1928]: https://github.com/cosmos/cosmjs/pull/1928
32+
[#1932]: https://github.com/cosmos/cosmjs/pull/1932
3133

3234
### Changed
3335

packages/amino/src/addresses.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
// See https://github.com/tendermint/tendermint/blob/f2ada0a604b4c0763bda2f64fac53d506d3beca7/docs/spec/blockchain/encoding.md#public-key-cryptography
22

3-
import { ripemd160, sha256 } from "@cosmjs/crypto";
3+
import { keccak256, ripemd160, Secp256k1, sha256 } from "@cosmjs/crypto";
44
import { fromBase64, toBech32 } from "@cosmjs/encoding";
55

66
import { encodeAminoPubkey } from "./encoding";
7-
import { isEd25519Pubkey, isMultisigThresholdPubkey, isSecp256k1Pubkey, Pubkey } from "./pubkeys";
7+
import {
8+
isEd25519Pubkey,
9+
isEthSecp256k1Pubkey,
10+
isMultisigThresholdPubkey,
11+
isSecp256k1Pubkey,
12+
Pubkey,
13+
} from "./pubkeys";
814

915
export function rawEd25519PubkeyToRawAddress(pubkeyData: Uint8Array): Uint8Array<ArrayBuffer> {
1016
if (pubkeyData.length !== 32) {
@@ -20,11 +26,24 @@ export function rawSecp256k1PubkeyToRawAddress(pubkeyData: Uint8Array): Uint8Arr
2026
return ripemd160(sha256(pubkeyData));
2127
}
2228

29+
export function rawEthSecp256k1PubkeyToRawAddress(pubkeyData: Uint8Array): Uint8Array<ArrayBuffer> {
30+
if (pubkeyData.length !== 33) {
31+
throw new Error(`Invalid Secp256k1 pubkey length (compressed): ${pubkeyData.length}`);
32+
}
33+
const uncompressed = Secp256k1.uncompressPubkey(pubkeyData);
34+
const pubkeyWithoutPrefix = uncompressed.slice(1);
35+
const hash = keccak256(pubkeyWithoutPrefix);
36+
return hash.slice(-20);
37+
}
38+
2339
// For secp256k1 this assumes we already have a compressed pubkey.
2440
export function pubkeyToRawAddress(pubkey: Pubkey): Uint8Array<ArrayBuffer> {
2541
if (isSecp256k1Pubkey(pubkey)) {
2642
const pubkeyData = fromBase64(pubkey.value);
2743
return rawSecp256k1PubkeyToRawAddress(pubkeyData);
44+
} else if (isEthSecp256k1Pubkey(pubkey)) {
45+
const pubkeyData = fromBase64(pubkey.value);
46+
return rawEthSecp256k1PubkeyToRawAddress(pubkeyData);
2847
} else if (isEd25519Pubkey(pubkey)) {
2948
const pubkeyData = fromBase64(pubkey.value);
3049
return rawEd25519PubkeyToRawAddress(pubkeyData);

packages/amino/src/encoding.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import { arrayContentStartsWith } from "@cosmjs/utils";
44

55
import {
66
Ed25519Pubkey,
7+
EthSecp256k1Pubkey,
78
isEd25519Pubkey,
9+
isEthSecp256k1Pubkey,
810
isMultisigThresholdPubkey,
911
isSecp256k1Pubkey,
1012
MultisigThresholdPubkey,
@@ -41,10 +43,27 @@ export function encodeEd25519Pubkey(pubkey: Uint8Array): Ed25519Pubkey {
4143
};
4244
}
4345

46+
/**
47+
* Takes a EthSecp256k1 public key as raw bytes and returns the Amino JSON
48+
* representation of it (the type/value wrapper object).
49+
*/
50+
export function encodeEthSecp256k1Pubkey(pubkey: Uint8Array): EthSecp256k1Pubkey {
51+
if (pubkey.length !== 33 || (pubkey[0] !== 0x02 && pubkey[0] !== 0x03)) {
52+
throw new Error("Public key must be compressed secp256k1, i.e. 33 bytes starting with 0x02 or 0x03");
53+
}
54+
return {
55+
type: pubkeyType.ethsecp256k1,
56+
value: toBase64(pubkey),
57+
};
58+
}
59+
4460
// As discussed in https://github.com/binance-chain/javascript-sdk/issues/163
4561
// Prefixes listed here: https://github.com/tendermint/tendermint/blob/d419fffe18531317c28c29a292ad7d253f6cafdf/docs/spec/blockchain/encoding.md#public-key-cryptography
4662
// Last bytes is varint-encoded length prefix
4763
const pubkeyAminoPrefixSecp256k1 = fromHex("eb5ae987" + "21" /* fixed length */);
64+
// See https://github.com/tendermint/go-amino/blob/8e779b71f40d175cd1302d3cd41a75b005225a7a/README.md#computing-the-prefix-and-disambiguation-bytes
65+
// for how this is computed
66+
const pubkeyAminoPrefixEthSecp256k1 = fromHex("5D7423DF" + "21" /* fixed length */);
4867
const pubkeyAminoPrefixEd25519 = fromHex("1624de64" + "20" /* fixed length */);
4968
const pubkeyAminoPrefixSr25519 = fromHex("0dfb1005" + "20" /* fixed length */);
5069
/** See https://github.com/tendermint/tendermint/commit/38b401657e4ad7a7eeb3c30a3cbf512037df3740 */
@@ -207,6 +226,8 @@ export function encodeAminoPubkey(pubkey: Pubkey): Uint8Array<ArrayBuffer> {
207226
return new Uint8Array([...pubkeyAminoPrefixEd25519, ...fromBase64(pubkey.value)]);
208227
} else if (isSecp256k1Pubkey(pubkey)) {
209228
return new Uint8Array([...pubkeyAminoPrefixSecp256k1, ...fromBase64(pubkey.value)]);
229+
} else if (isEthSecp256k1Pubkey(pubkey)) {
230+
return new Uint8Array([...pubkeyAminoPrefixEthSecp256k1, ...fromBase64(pubkey.value)]);
210231
} else {
211232
throw new Error("Unsupported pubkey type");
212233
}

packages/amino/src/index.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export {
22
pubkeyToAddress,
33
pubkeyToRawAddress,
44
rawEd25519PubkeyToRawAddress,
5+
rawEthSecp256k1PubkeyToRawAddress,
56
rawSecp256k1PubkeyToRawAddress,
67
} from "./addresses";
78
export type { Coin } from "./coins";
@@ -12,20 +13,23 @@ export {
1213
encodeAminoPubkey,
1314
encodeBech32Pubkey,
1415
encodeEd25519Pubkey,
16+
encodeEthSecp256k1Pubkey,
1517
encodeSecp256k1Pubkey,
1618
} from "./encoding";
1719
export { createMultisigThresholdPubkey } from "./multisig";
1820
export { omitDefault } from "./omitdefault";
1921
export { makeCosmoshubPath } from "./paths";
2022
export type {
2123
Ed25519Pubkey,
24+
EthSecp256k1Pubkey,
2225
MultisigThresholdPubkey,
2326
Pubkey,
2427
Secp256k1Pubkey,
2528
SinglePubkey,
2629
} from "./pubkeys";
2730
export {
2831
isEd25519Pubkey,
32+
isEthSecp256k1Pubkey,
2933
isMultisigThresholdPubkey,
3034
isSecp256k1Pubkey,
3135
isSinglePubkey,
@@ -37,9 +41,15 @@ export {
3741
Secp256k1HdWallet,
3842
} from "./secp256k1hdwallet";
3943
export { Secp256k1Wallet } from "./secp256k1wallet";
40-
export { type StdSignature, decodeSignature, encodeSecp256k1Signature } from "./signature";
44+
export {
45+
type StdSignature,
46+
decodeSignature,
47+
encodeEthSecp256k1Signature,
48+
encodeSecp256k1Signature,
49+
} from "./signature";
4150
export type { AminoMsg, StdFee, StdSignDoc } from "./signdoc";
4251
export { makeSignDoc, serializeSignDoc } from "./signdoc";
4352
export type { AccountData, Algo, AminoSignResponse, OfflineAminoSigner } from "./signer";
53+
export { getAminoPubkey, isEthereumSecp256k1Account } from "./signerutils";
4454
export { type StdTx, isStdTx, makeStdTx } from "./stdtx";
4555
export { type KdfConfiguration, executeKdf } from "./wallet";

packages/amino/src/pubkeys.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,22 @@ export function isSecp256k1Pubkey(pubkey: Pubkey): pubkey is Secp256k1Pubkey {
2424
return (pubkey as Secp256k1Pubkey).type === "tendermint/PubKeySecp256k1";
2525
}
2626

27+
export interface EthSecp256k1Pubkey extends SinglePubkey {
28+
readonly type: "os/PubKeyEthSecp256k1";
29+
/** Compressed (33 bytes) secp256k1 public key in base64 encoding */
30+
readonly value: string;
31+
}
32+
33+
export function isEthSecp256k1Pubkey(pubkey: Pubkey): pubkey is EthSecp256k1Pubkey {
34+
return (pubkey as EthSecp256k1Pubkey).type === "os/PubKeyEthSecp256k1";
35+
}
36+
2737
export const pubkeyType = {
28-
/** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/ed25519/ed25519.go#L22 */
29-
secp256k1: "tendermint/PubKeySecp256k1" as const,
3038
/** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/secp256k1/secp256k1.go#L23 */
39+
secp256k1: "tendermint/PubKeySecp256k1" as const,
40+
/** @see https://github.com/cosmos/evm/blob/v1.0.0-rc2/crypto/ethsecp256k1/ethsecp256k1.go#L35-L36 */
41+
ethsecp256k1: "os/PubKeyEthSecp256k1" as const,
42+
/** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/ed25519/ed25519.go#L22 */
3143
ed25519: "tendermint/PubKeyEd25519" as const,
3244
/** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/sr25519/codec.go#L12 */
3345
sr25519: "tendermint/PubKeySr25519" as const,
@@ -53,7 +65,12 @@ export interface SinglePubkey extends Pubkey {
5365
}
5466

5567
export function isSinglePubkey(pubkey: Pubkey): pubkey is SinglePubkey {
56-
const singPubkeyTypes: string[] = [pubkeyType.ed25519, pubkeyType.secp256k1, pubkeyType.sr25519];
68+
const singPubkeyTypes: string[] = [
69+
pubkeyType.ed25519,
70+
pubkeyType.secp256k1,
71+
pubkeyType.ethsecp256k1,
72+
pubkeyType.sr25519,
73+
];
5774
return singPubkeyTypes.includes(pubkey.type);
5875
}
5976

packages/amino/src/signature.spec.ts

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { fromBase64 } from "@cosmjs/encoding";
22

3-
import { decodeSignature, encodeSecp256k1Signature, StdSignature } from "./signature";
3+
import {
4+
decodeSignature,
5+
encodeEthSecp256k1Signature,
6+
encodeSecp256k1Signature,
7+
StdSignature,
8+
} from "./signature";
49

510
describe("signature", () => {
611
describe("encodeSecp256k1Signature", () => {
@@ -44,6 +49,47 @@ describe("signature", () => {
4449
});
4550
});
4651

52+
describe("encodeEthSecp256k1Signature", () => {
53+
it("encodes a full signature", () => {
54+
const pubkey = fromBase64("AywEwHmedyGF0jQ11+SY/dLGn/QwoN+cf09VWFAfUxUs");
55+
const signature = fromBase64(
56+
"sGcYUlDfO1PDA/Z9NqUBtgSTdRTJ+AJ8tvgw+5qtXalPgh5XqZj4R2eY1b7RXMU1m5and6aOl7YGpk9cZnESmQ==",
57+
);
58+
expect(encodeEthSecp256k1Signature(pubkey, signature)).toEqual({
59+
pub_key: {
60+
type: "os/PubKeyEthSecp256k1",
61+
value: "AywEwHmedyGF0jQ11+SY/dLGn/QwoN+cf09VWFAfUxUs",
62+
},
63+
signature: "sGcYUlDfO1PDA/Z9NqUBtgSTdRTJ+AJ8tvgw+5qtXalPgh5XqZj4R2eY1b7RXMU1m5and6aOl7YGpk9cZnESmQ==",
64+
});
65+
});
66+
67+
it("throws when getting uncompressed public keys", () => {
68+
const pubkey = fromBase64(
69+
"BE8EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQE7WHpoHoNswYeoFkuYpYSKK4mzFzMV/dB0DVAy4lnNU=",
70+
);
71+
const signature = fromBase64(
72+
"sGcYUlDfO1PDA/Z9NqUBtgSTdRTJ+AJ8tvgw+5qtXalPgh5XqZj4R2eY1b7RXMU1m5and6aOl7YGpk9cZnESmQ==",
73+
);
74+
expect(() => encodeEthSecp256k1Signature(pubkey, signature)).toThrowError(
75+
/public key must be compressed secp256k1/i,
76+
);
77+
});
78+
79+
it("throws if signature contains recovery byte", () => {
80+
const pubkey = fromBase64("AywEwHmedyGF0jQ11+SY/dLGn/QwoN+cf09VWFAfUxUs");
81+
const signature = Uint8Array.from([
82+
...fromBase64(
83+
"sGcYUlDfO1PDA/Z9NqUBtgSTdRTJ+AJ8tvgw+5qtXalPgh5XqZj4R2eY1b7RXMU1m5and6aOl7YGpk9cZnESmQ==",
84+
),
85+
99,
86+
]);
87+
expect(() => encodeEthSecp256k1Signature(pubkey, signature)).toThrowError(
88+
/signature must be 64 bytes long/i,
89+
);
90+
});
91+
});
92+
4793
describe("decodeSignature", () => {
4894
it("works for secp256k1", () => {
4995
const signature: StdSignature = {
@@ -60,5 +106,21 @@ describe("signature", () => {
60106
),
61107
});
62108
});
109+
110+
it("works for ethsecp256k1", () => {
111+
const signature: StdSignature = {
112+
pub_key: {
113+
type: "os/PubKeyEthSecp256k1",
114+
value: "AywEwHmedyGF0jQ11+SY/dLGn/QwoN+cf09VWFAfUxUs",
115+
},
116+
signature: "sGcYUlDfO1PDA/Z9NqUBtgSTdRTJ+AJ8tvgw+5qtXalPgh5XqZj4R2eY1b7RXMU1m5and6aOl7YGpk9cZnESmQ==",
117+
};
118+
expect(decodeSignature(signature)).toEqual({
119+
pubkey: fromBase64("AywEwHmedyGF0jQ11+SY/dLGn/QwoN+cf09VWFAfUxUs"),
120+
signature: fromBase64(
121+
"sGcYUlDfO1PDA/Z9NqUBtgSTdRTJ+AJ8tvgw+5qtXalPgh5XqZj4R2eY1b7RXMU1m5and6aOl7YGpk9cZnESmQ==",
122+
),
123+
});
124+
});
63125
});
64126
});

packages/amino/src/signature.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable @typescript-eslint/naming-convention */
22
import { fromBase64, toBase64 } from "@cosmjs/encoding";
33

4-
import { encodeSecp256k1Pubkey } from "./encoding";
4+
import { encodeEthSecp256k1Pubkey, encodeSecp256k1Pubkey } from "./encoding";
55
import { Pubkey, pubkeyType } from "./pubkeys";
66

77
export interface StdSignature {
@@ -28,6 +28,25 @@ export function encodeSecp256k1Signature(pubkey: Uint8Array, signature: Uint8Arr
2828
};
2929
}
3030

31+
/**
32+
* Takes a binary pubkey and signature to create a signature object
33+
*
34+
* @param pubkey a compressed secp256k1 public key
35+
* @param signature a 64 byte fixed length representation of secp256k1 signature components r and s
36+
*/
37+
export function encodeEthSecp256k1Signature(pubkey: Uint8Array, signature: Uint8Array): StdSignature {
38+
if (signature.length !== 64) {
39+
throw new Error(
40+
"Signature must be 64 bytes long. Cosmos SDK uses a 2x32 byte fixed length encoding for the secp256k1 signature integers r and s.",
41+
);
42+
}
43+
44+
return {
45+
pub_key: encodeEthSecp256k1Pubkey(pubkey),
46+
signature: toBase64(signature),
47+
};
48+
}
49+
3150
export function decodeSignature(signature: StdSignature): {
3251
readonly pubkey: Uint8Array;
3352
readonly signature: Uint8Array;
@@ -39,6 +58,11 @@ export function decodeSignature(signature: StdSignature): {
3958
pubkey: fromBase64(signature.pub_key.value),
4059
signature: fromBase64(signature.signature),
4160
};
61+
case pubkeyType.ethsecp256k1:
62+
return {
63+
pubkey: fromBase64(signature.pub_key.value),
64+
signature: fromBase64(signature.signature),
65+
};
4266
default:
4367
throw new Error("Unsupported pubkey type");
4468
}

packages/amino/src/signer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { StdSignature } from "./signature";
22
import { StdSignDoc } from "./signdoc";
33

4-
export type Algo = "secp256k1" | "ed25519" | "sr25519";
4+
export type Algo = "secp256k1" | "ed25519" | "sr25519" | "eth_secp256k1" | "ethsecp256k1";
55

66
export interface AccountData {
77
/** A printable address (typically bech32 encoded) */

packages/amino/src/signerutils.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Utility functions for working with signer accounts and algorithm detection.
3+
*/
4+
5+
import { encodeEthSecp256k1Pubkey, encodeSecp256k1Pubkey } from "./encoding";
6+
import { EthSecp256k1Pubkey, Secp256k1Pubkey } from "./pubkeys";
7+
import type { AccountData } from "./signer";
8+
9+
/**
10+
* Checks if an account uses Ethereum secp256k1 keys by examining the algorithm name.
11+
*
12+
* Handle Ethereum secp256k1 keys with dual naming convention support:
13+
* Different wallets and chains report Ethereum key algorithms inconsistently:
14+
* - "eth_secp256k1" (with underscore) - de facto standard used by Keplr wallet, CosmJS, some Cosmos SDK chains
15+
* - "ethsecp256k1" (without underscore) - used by Evmos, Cronos, and other EVM-compatible chains
16+
* Both represent the same Ethereum-compatible secp256k1 keys that require keccak256 address derivation
17+
*
18+
* @param account The account data from a signer
19+
* @returns true if the account uses Ethereum secp256k1 keys, false otherwise
20+
*/
21+
export function isEthereumSecp256k1Account(account: AccountData): boolean {
22+
return account.algo === "eth_secp256k1" || account.algo === "ethsecp256k1";
23+
}
24+
25+
/**
26+
* Gets the correctly encoded amino pubkey for an account based on its algorithm.
27+
*
28+
* This utility automatically selects the appropriate encoding function based on whether
29+
* the account uses Ethereum secp256k1 keys or standard secp256k1 keys.
30+
*
31+
* @param account The account data from a signer
32+
* @returns The amino-encoded pubkey (EthSecp256k1Pubkey or Secp256k1Pubkey)
33+
*/
34+
export function getAminoPubkey(account: AccountData): EthSecp256k1Pubkey | Secp256k1Pubkey {
35+
if (isEthereumSecp256k1Account(account)) {
36+
return encodeEthSecp256k1Pubkey(account.pubkey);
37+
} else {
38+
return encodeSecp256k1Pubkey(account.pubkey);
39+
}
40+
}

packages/cosmwasm/src/signingcosmwasmclient.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { encodeSecp256k1Pubkey, makeSignDoc as makeSignDocAmino } from "@cosmjs/amino";
1+
import { encodeSecp256k1Pubkey, getAminoPubkey, makeSignDoc as makeSignDocAmino } from "@cosmjs/amino";
22
import { sha256 } from "@cosmjs/crypto";
33
import { fromBase64, toHex, toUtf8 } from "@cosmjs/encoding";
44
import { Int53, Uint53 } from "@cosmjs/math";
@@ -772,7 +772,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
772772
if (!accountFromSigner) {
773773
throw new Error("Failed to retrieve account from signer");
774774
}
775-
const pubkey = encodePubkey(encodeSecp256k1Pubkey(accountFromSigner.pubkey));
775+
const pubkey = encodePubkey(getAminoPubkey(accountFromSigner));
776776
const signMode = SignMode.SIGN_MODE_LEGACY_AMINO_JSON;
777777
const msgs = messages.map((msg) => this.aminoTypes.toAmino(msg));
778778
const signDoc = makeSignDocAmino(msgs, fee, chainId, memo, accountNumber, sequence, timeoutHeight);
@@ -818,7 +818,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
818818
if (!accountFromSigner) {
819819
throw new Error("Failed to retrieve account from signer");
820820
}
821-
const pubkey = encodePubkey(encodeSecp256k1Pubkey(accountFromSigner.pubkey));
821+
const pubkey = encodePubkey(getAminoPubkey(accountFromSigner));
822822
const txBody: TxBodyEncodeObject = {
823823
typeUrl: "/cosmos.tx.v1beta1.TxBody",
824824
value: {

0 commit comments

Comments
 (0)