Reputation: 21
I need to do a conversion using the cosmrs library, but I couldn't do it. Can anyone who has experience with this help with a sample code? Also I have a note to complete it:
Take the address from the pubkey and bech32 encode it using the correct HRP prefix
Cosmrs lib: https://docs.rs/cosmrs/latest/cosmrs/crypto/struct.PublicKey.html
Basically, a prefix should be determined and the relevant conversion process should be performed in this way. this seems a bit over my head. but for the example below, the prefix to use is cosmosvalcons
Example pubkey:
"consensus_pubkey".
{
"consensus_pubkey": {
"@type": "/cosmos.crypto.ed25519.PubKey",
"key": "bDO9bUrbyg0f1pTpmjjZU5cgsweCWdwL6HUVnsKJi7k="
}
}
I need to get an address with cosmosvalcons...
prefixed from pubkey, but all I get is nothing.
Upvotes: 2
Views: 972
Reputation: 938
Following test code was done in MacOS
.
cargo
installed locally.# I call the sample project as the key-test
cargo new key-test
./key-test/Cargo.toml
file:[package]
name = "key-test"
version = "0.1.0"
edition = "2021"
[dependencies]
cosmrs = "0.15"
bech32 = "0.9"
sha2 = "0.10"
base64 = "0.21"
./key-test/src/main.rs
:use bech32::{self, ToBase32, Variant};
use sha2::{Digest, Sha256};
use base64::{Engine as _, engine::general_purpose};
use cosmrs::crypto::PublicKey;
use cosmrs::tendermint;
fn main() {
let base64_pubkey = "bDO9bUrbyg0f1pTpmjjZU5cgsweCWdwL6HUVnsKJi7k=";
// Decode base64 public key
let decoded_bytes = general_purpose::STANDARD.decode(base64_pubkey)
.expect("Failed to decode base64");
// Convert raw bytes into Tendermint PublicKey (Ed25519)
let tendermint_pubkey = tendermint::PublicKey::from_raw_ed25519(&decoded_bytes)
.expect("Invalid public key");
// Convert Tendermint PublicKey to CosmRS PublicKey
let pubkey = PublicKey::from(tendermint_pubkey);
// Compute the address (SHA-256 hash of the pubkey)
let pubkey_bytes = pubkey.to_bytes();
let hash = Sha256::digest(pubkey_bytes);
let truncated_address = &hash[..20]; // Take first 20 bytes
// Encode in Bech32 with the prefix "cosmosvalcons"
let bech32_address = bech32::encode("cosmosvalcons", truncated_address.to_base32(), Variant::Bech32)
.expect("Bech32 encoding failed");
println!("Cosmos Validator Address: {}", bech32_address);
}
cargo run
Compiling key-test v0.1.0 (/Users/farkhodabdukodirov/Development/temp/key-test)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.38s
Running `target/debug/key-test`
Cosmos Validator Address: cosmosvalcons1lth4cv5tkn2fc5yuy4xx6rj7wvzrpxkkqg3my5
base64
keytendermint
pub keysha-256
hash and derive the val consensus addressbech32
with cosmosvalcons
prefixUpvotes: 0
Reputation: 13
I was struggling to convert pub key to consensus address on Axelar ecosystem but I found a solution. Here is the solution:
import { sha256 } from "@cosmjs/crypto";
import { toBech32, fromBase64 } from "@cosmjs/encoding";
const pubKey = {
consensus_pubkey: {
"@type": "/cosmos.crypto.ed25519.PubKey",
key: "ijzDoMl+TKz06uaK5H+V3IgpuvPjqeAyc/HMW4wgsy8=",
},
};
const ed25519PubkeyRaw = fromBase64(pubKey.consensus_pubkey.key);
const addressData = sha256(ed25519PubkeyRaw).slice(0, 20);
const bech32Address = toBech32("axelarvalcons", addressData);
logger.info(bech32Address);
Upvotes: 0