mirror of
https://github.com/cosmos/cosmjs.git
synced 2025-03-11 14:09:15 +00:00
Merge pull request #757 from cosmos/753-tm-address-helpers
Add address helpers to tendermint-rpc
This commit is contained in:
commit
10ddc6282d
@ -61,6 +61,10 @@ and this project adheres to
|
||||
- @cosmjs/proto-signing: Export `DirectSecp256k1HdWalletOptions` interface.
|
||||
- @cosmjs/proto-signing: Add `bip39Password` option to `DirectSecp256k1HdWallet`
|
||||
options.
|
||||
- @cosmjs/amino: Add `rawEd25519PubkeyToRawAddress` helper function.
|
||||
- @cosmjs/tendermint-rpc: Add `pubkeyToAddress`, `pubkeyToRawAddress`,
|
||||
`rawEd25519PubkeyToRawAddress`, and `rawSecp256k1PubkeyToRawAddress` helper
|
||||
functions.
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -6,6 +6,13 @@ import { Bech32, fromBase64 } from "@cosmjs/encoding";
|
||||
import { encodeAminoPubkey } from "./encoding";
|
||||
import { isEd25519Pubkey, isMultisigThresholdPubkey, isSecp256k1Pubkey, Pubkey } from "./pubkeys";
|
||||
|
||||
export function rawEd25519PubkeyToRawAddress(pubkeyData: Uint8Array): Uint8Array {
|
||||
if (pubkeyData.length !== 32) {
|
||||
throw new Error(`Invalid Ed25519 pubkey length: ${pubkeyData.length}`);
|
||||
}
|
||||
return sha256(pubkeyData).slice(0, 20);
|
||||
}
|
||||
|
||||
export function rawSecp256k1PubkeyToRawAddress(pubkeyData: Uint8Array): Uint8Array {
|
||||
if (pubkeyData.length !== 33) {
|
||||
throw new Error(`Invalid Secp256k1 pubkey length (compressed): ${pubkeyData.length}`);
|
||||
@ -20,10 +27,7 @@ export function pubkeyToRawAddress(pubkey: Pubkey): Uint8Array {
|
||||
return rawSecp256k1PubkeyToRawAddress(pubkeyData);
|
||||
} else if (isEd25519Pubkey(pubkey)) {
|
||||
const pubkeyData = fromBase64(pubkey.value);
|
||||
if (pubkeyData.length !== 32) {
|
||||
throw new Error(`Invalid Ed25519 pubkey length: ${pubkeyData.length}`);
|
||||
}
|
||||
return sha256(pubkeyData).slice(0, 20);
|
||||
return rawEd25519PubkeyToRawAddress(pubkeyData);
|
||||
} else if (isMultisigThresholdPubkey(pubkey)) {
|
||||
// https://github.com/tendermint/tendermint/blob/38b401657e4ad7a7eeb3c30a3cbf512037df3740/crypto/multisig/threshold_pubkey.go#L71-L74
|
||||
const pubkeyData = encodeAminoPubkey(pubkey);
|
||||
|
@ -1,4 +1,9 @@
|
||||
export { pubkeyToAddress, pubkeyToRawAddress, rawSecp256k1PubkeyToRawAddress } from "./addresses";
|
||||
export {
|
||||
pubkeyToAddress,
|
||||
pubkeyToRawAddress,
|
||||
rawEd25519PubkeyToRawAddress,
|
||||
rawSecp256k1PubkeyToRawAddress,
|
||||
} from "./addresses";
|
||||
export { Coin, coin, coins, parseCoins } from "./coins";
|
||||
export {
|
||||
decodeAminoPubkey,
|
||||
|
35
packages/tendermint-rpc/src/addresses.spec.ts
Normal file
35
packages/tendermint-rpc/src/addresses.spec.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { fromHex } from "@cosmjs/encoding";
|
||||
|
||||
import { pubkeyToAddress, pubkeyToRawAddress } from "./addresses";
|
||||
|
||||
// Test values from https://github.com/informalsystems/tendermint-rs/blob/v0.18.1/tendermint/src/account.rs#L153-L192
|
||||
|
||||
describe("addresses", () => {
|
||||
describe("pubkeyToRawAddress", () => {
|
||||
it("works for Secp256k1", () => {
|
||||
const pubkey = fromHex("02950E1CDFCB133D6024109FD489F734EEB4502418E538C28481F22BCE276F248C");
|
||||
expect(pubkeyToRawAddress("secp256k1", pubkey)).toEqual(
|
||||
fromHex("7C2BB42A8BE69791EC763E51F5A49BCD41E82237"),
|
||||
);
|
||||
});
|
||||
|
||||
it("works for Ed25519", () => {
|
||||
const pubkey = fromHex("14253D61EF42D166D02E68D540D07FDF8D65A9AF0ACAA46302688E788A8521E2");
|
||||
expect(pubkeyToRawAddress("ed25519", pubkey)).toEqual(
|
||||
fromHex("0CDA3F47EF3C4906693B170EF650EB968C5F4B2C"),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("pubkeyToAddress", () => {
|
||||
it("works for Secp256k1", () => {
|
||||
const pubkey = fromHex("02950E1CDFCB133D6024109FD489F734EEB4502418E538C28481F22BCE276F248C");
|
||||
expect(pubkeyToAddress("secp256k1", pubkey)).toEqual("7C2BB42A8BE69791EC763E51F5A49BCD41E82237");
|
||||
});
|
||||
|
||||
it("works for Ed25519", () => {
|
||||
const pubkey = fromHex("14253D61EF42D166D02E68D540D07FDF8D65A9AF0ACAA46302688E788A8521E2");
|
||||
expect(pubkeyToAddress("ed25519", pubkey)).toEqual("0CDA3F47EF3C4906693B170EF650EB968C5F4B2C");
|
||||
});
|
||||
});
|
||||
});
|
33
packages/tendermint-rpc/src/addresses.ts
Normal file
33
packages/tendermint-rpc/src/addresses.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { ripemd160, sha256 } from "@cosmjs/crypto";
|
||||
import { toHex } from "@cosmjs/encoding";
|
||||
|
||||
export function rawEd25519PubkeyToRawAddress(pubkeyData: Uint8Array): Uint8Array {
|
||||
if (pubkeyData.length !== 32) {
|
||||
throw new Error(`Invalid Ed25519 pubkey length: ${pubkeyData.length}`);
|
||||
}
|
||||
return sha256(pubkeyData).slice(0, 20);
|
||||
}
|
||||
|
||||
export function rawSecp256k1PubkeyToRawAddress(pubkeyData: Uint8Array): Uint8Array {
|
||||
if (pubkeyData.length !== 33) {
|
||||
throw new Error(`Invalid Secp256k1 pubkey length (compressed): ${pubkeyData.length}`);
|
||||
}
|
||||
return ripemd160(sha256(pubkeyData));
|
||||
}
|
||||
|
||||
// For secp256k1 this assumes we already have a compressed pubkey.
|
||||
export function pubkeyToRawAddress(type: "ed25519" | "secp256k1", data: Uint8Array): Uint8Array {
|
||||
switch (type) {
|
||||
case "ed25519":
|
||||
return rawEd25519PubkeyToRawAddress(data);
|
||||
case "secp256k1":
|
||||
return rawSecp256k1PubkeyToRawAddress(data);
|
||||
default:
|
||||
// Keep this case here to guard against new types being added but not handled
|
||||
throw new Error(`Pubkey type ${type} not supported`);
|
||||
}
|
||||
}
|
||||
|
||||
export function pubkeyToAddress(type: "ed25519" | "secp256k1", data: Uint8Array): string {
|
||||
return toHex(pubkeyToRawAddress(type, data)).toUpperCase();
|
||||
}
|
@ -1,3 +1,9 @@
|
||||
export {
|
||||
pubkeyToAddress,
|
||||
pubkeyToRawAddress,
|
||||
rawEd25519PubkeyToRawAddress,
|
||||
rawSecp256k1PubkeyToRawAddress,
|
||||
} from "./addresses";
|
||||
export {
|
||||
adaptor33,
|
||||
adaptor34,
|
||||
|
Loading…
x
Reference in New Issue
Block a user