diff --git a/packages/bcp/src/address.ts b/packages/bcp/src/address.ts index 1fc4ddb2..ce6aa25b 100644 --- a/packages/bcp/src/address.ts +++ b/packages/bcp/src/address.ts @@ -1,4 +1,4 @@ -import { CosmosBech32Prefix, decodeBech32Pubkey, encodeAddress, isValidAddress } from "@cosmwasm/sdk"; +import { CosmosBech32Prefix, decodeBech32Pubkey, encodeAddress, isValidAddress, types } from "@cosmwasm/sdk"; import { Address, Algorithm, PubkeyBundle, PubkeyBytes } from "@iov/bcp"; import { Secp256k1 } from "@iov/crypto"; import { Encoding } from "@iov/encoding"; @@ -12,9 +12,9 @@ export function decodeCosmosPubkey( ): { readonly algo: Algorithm; readonly data: PubkeyBytes } { const sdkPubKey = decodeBech32Pubkey(encodedPubkey); switch (sdkPubKey.type) { - case "tendermint/PubKeySecp256k1": + case types.pubkeyType.secp256k1: return { algo: Algorithm.Secp256k1, data: fromBase64(sdkPubKey.value) as PubkeyBytes }; - case "tendermint/PubKeyEd25519": + case types.pubkeyType.ed25519: return { algo: Algorithm.Ed25519, data: fromBase64(sdkPubKey.value) as PubkeyBytes }; default: throw new Error("Unsupported Pubkey type: " + sdkPubKey.type); @@ -23,22 +23,20 @@ export function decodeCosmosPubkey( // See https://github.com/tendermint/tendermint/blob/f2ada0a604b4c0763bda2f64fac53d506d3beca7/docs/spec/blockchain/encoding.md#public-key-cryptography export function pubkeyToAddress(pubkey: PubkeyBundle, prefix: CosmosBech32Prefix): Address { - let pubkeyType: "tendermint/PubKeySecp256k1" | "tendermint/PubKeyEd25519"; - let pubkeyData: Uint8Array = pubkey.data; - + let sdkKey: types.PubKey; if (pubkey.algo === Algorithm.Secp256k1) { - pubkeyType = "tendermint/PubKeySecp256k1"; - if (pubkeyData.length > 33) { - pubkeyData = Secp256k1.compressPubkey(pubkey.data); - } + sdkKey = { + type: types.pubkeyType.secp256k1, + value: toBase64(pubkey.data.length > 33 ? Secp256k1.compressPubkey(pubkey.data) : pubkey.data), + }; } else if (pubkey.algo === Algorithm.Ed25519) { - pubkeyType = "tendermint/PubKeyEd25519"; + sdkKey = { + type: types.pubkeyType.ed25519, + value: toBase64(pubkey.data), + }; } else { throw new Error(`Unsupported algorithm: ${pubkey.algo}`); } - const sdkKey = { - type: pubkeyType, - value: toBase64(pubkeyData), - }; + return encodeAddress(sdkKey, prefix) as Address; } diff --git a/packages/bcp/src/decode.ts b/packages/bcp/src/decode.ts index 77b3eb30..c68325ba 100644 --- a/packages/bcp/src/decode.ts +++ b/packages/bcp/src/decode.ts @@ -25,14 +25,12 @@ const { fromBase64 } = Encoding; export function decodePubkey(pubkey: types.PubKey): PubkeyBundle { switch (pubkey.type) { - // https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/secp256k1/secp256k1.go#L23 - case "tendermint/PubKeySecp256k1": + case types.pubkeyType.secp256k1: return { algo: Algorithm.Secp256k1, data: fromBase64(pubkey.value) as PubkeyBytes, }; - // https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/ed25519/ed25519.go#L22 - case "tendermint/PubKeyEd25519": + case types.pubkeyType.ed25519: return { algo: Algorithm.Ed25519, data: fromBase64(pubkey.value) as PubkeyBytes, diff --git a/packages/bcp/src/encode.ts b/packages/bcp/src/encode.ts index 164fb867..479895b2 100644 --- a/packages/bcp/src/encode.ts +++ b/packages/bcp/src/encode.ts @@ -20,12 +20,12 @@ export function encodePubkey(pubkey: PubkeyBundle): types.PubKey { switch (pubkey.algo) { case Algorithm.Secp256k1: return { - type: "tendermint/PubKeySecp256k1", + type: types.pubkeyType.secp256k1, value: toBase64(pubkey.data), }; case Algorithm.Ed25519: return { - type: "tendermint/PubKeyEd25519", + type: types.pubkeyType.ed25519, value: toBase64(pubkey.data), }; default: diff --git a/packages/sdk/src/address.ts b/packages/sdk/src/address.ts index 5819dca3..9f553d5c 100644 --- a/packages/sdk/src/address.ts +++ b/packages/sdk/src/address.ts @@ -2,7 +2,7 @@ import { Ripemd160, Sha256 } from "@iov/crypto"; import { Bech32, Encoding } from "@iov/encoding"; import equal from "fast-deep-equal"; -import { Bech32PubKey, PubKey } from "./types"; +import { Bech32PubKey, PubKey, pubkeyType } from "./types"; const { fromBase64, toBase64 } = Encoding; @@ -40,7 +40,7 @@ export function decodeBech32Pubkey(bech: Bech32PubKey): PubKey { throw new Error("Invalid rest data length. Expected 33 bytes (compressed secp256k1 pubkey)."); } return { - type: "tendermint/PubKeySecp256k1", + type: pubkeyType.secp256k1, value: toBase64(rest), }; } else if (equal(aminoPrefix, pubkeyAminoPrefixEd25519)) { @@ -48,7 +48,7 @@ export function decodeBech32Pubkey(bech: Bech32PubKey): PubKey { throw new Error("Invalid rest data length. Expected 32 bytes (Ed25519 pubkey)."); } return { - type: "tendermint/PubKeyEd25519", + type: pubkeyType.ed25519, value: toBase64(rest), }; } else if (equal(aminoPrefix, pubkeyAminoPrefixSr25519)) { @@ -56,7 +56,7 @@ export function decodeBech32Pubkey(bech: Bech32PubKey): PubKey { throw new Error("Invalid rest data length. Expected 32 bytes (Sr25519 pubkey)."); } return { - type: "tendermint/PubKeySr25519", + type: pubkeyType.sr25519, value: toBase64(rest), }; } else { @@ -81,7 +81,7 @@ export function isValidAddress(address: string): boolean { export function encodeAddress(pubkey: PubKey, prefix: string): string { const pubkeyBytes = fromBase64(pubkey.value); switch (pubkey.type) { - case "tendermint/PubKeySecp256k1": { + case pubkeyType.secp256k1: { if (pubkeyBytes.length !== 33) { throw new Error(`Invalid Secp256k1 pubkey length (compressed): ${pubkeyBytes.length}`); } @@ -89,14 +89,14 @@ export function encodeAddress(pubkey: PubKey, prefix: string): string { const hash2 = new Ripemd160(hash1).digest(); return Bech32.encode(prefix, hash2); } - case "tendermint/PubKeyEd25519": { + case pubkeyType.ed25519: { if (pubkeyBytes.length !== 32) { throw new Error(`Invalid Ed25519 pubkey length: ${pubkeyBytes.length}`); } const hash = new Sha256(pubkeyBytes).digest(); return Bech32.encode(prefix, hash.slice(0, 20)); } - case "tendermint/PubKeySr25519": { + case pubkeyType.sr25519: { if (pubkeyBytes.length !== 32) { throw new Error(`Invalid Sr25519 pubkey length: ${pubkeyBytes.length}`); } diff --git a/packages/sdk/src/encoding.ts b/packages/sdk/src/encoding.ts index 88844d26..ad3a4fa1 100644 --- a/packages/sdk/src/encoding.ts +++ b/packages/sdk/src/encoding.ts @@ -1,7 +1,7 @@ import { Secp256k1 } from "@iov/crypto"; import { Encoding } from "@iov/encoding"; -import { Msg, NonceInfo, StdFee, StdSignature, StdTx } from "./types"; +import { Msg, NonceInfo, pubkeyType, StdFee, StdSignature, StdTx } from "./types"; const { toBase64, toUtf8 } = Encoding; @@ -62,7 +62,7 @@ export function encodeSecp256k1Signature(pubkey: Uint8Array, signature: Uint8Arr return { // eslint-disable-next-line @typescript-eslint/camelcase pub_key: { - type: "tendermint/PubKeySecp256k1", + type: pubkeyType.secp256k1, value: toBase64(Secp256k1.compressPubkey(pubkey)), }, // Recovery seems to be unused diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts index 2e1ecbe8..c09e0130 100644 --- a/packages/sdk/src/types.ts +++ b/packages/sdk/src/types.ts @@ -110,11 +110,16 @@ export interface PubKey { readonly value: string; } -export const pubkeyTypes: readonly string[] = [ - "tendermint/PubKeySecp256k1", - "tendermint/PubKeyEd25519", - "tendermint/PubKeySr25519", -]; +export const pubkeyType = { + /** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/ed25519/ed25519.go#L22 */ + secp256k1: "tendermint/PubKeySecp256k1" as const, + /** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/secp256k1/secp256k1.go#L23 */ + ed25519: "tendermint/PubKeyEd25519" as const, + /** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/sr25519/codec.go#L12 */ + sr25519: "tendermint/PubKeySr25519" as const, +}; + +export const pubkeyTypes: readonly string[] = [pubkeyType.secp256k1, pubkeyType.ed25519, pubkeyType.sr25519]; // bech32-encoded amino-binary encoded PubKey interface. oof. export type Bech32PubKey = string; diff --git a/packages/sdk/types/types.d.ts b/packages/sdk/types/types.d.ts index fc750bf8..c495126c 100644 --- a/packages/sdk/types/types.d.ts +++ b/packages/sdk/types/types.d.ts @@ -74,6 +74,14 @@ export interface PubKey { readonly type: string; readonly value: string; } +export declare const pubkeyType: { + /** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/ed25519/ed25519.go#L22 */ + secp256k1: "tendermint/PubKeySecp256k1"; + /** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/secp256k1/secp256k1.go#L23 */ + ed25519: "tendermint/PubKeyEd25519"; + /** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/sr25519/codec.go#L12 */ + sr25519: "tendermint/PubKeySr25519"; +}; export declare const pubkeyTypes: readonly string[]; export declare type Bech32PubKey = string; export interface BaseAccount {