Chain Utils
A Rust library for generating blockchain addresses from public keys obtained via ICP threshold signatures, with support for CAIP (Chain Agnostic Improvement Proposals) chain identifiers.
Features
- Multi-chain support: Generate addresses for different blockchain networks
- CAIP integration: Uses CAIP-2 chain identifiers for standardized chain specification
- ICP threshold signature compatibility: Designed to work with public keys from ICP threshold ECDSA/Schnorr signatures
- Comprehensive testing: Full test coverage with validation for multiple scenarios
Supported Chains
| Namespace | Chain | Address Format | Public Key Format |
|---|---|---|---|
eip155 |
Ethereum & EVM chains | 0x-prefixed hex (42 chars) | SEC1-encoded hex string |
solana |
Solana | Base58-encoded (32-44 chars) | 32-byte hex string |
bip122 |
Bitcoin & Bitcoin-compatible | P2PKH base58 (26-35 chars) | SEC1-encoded hex string |
Usage
Basic Address Generation
use generate_address;
use ChainId;
// Generate Ethereum address
let eth_pubkey = "04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235";
let eth_chain = new.unwrap; // Ethereum mainnet
let eth_address = generate_address?;
println!; // 0x1234...
// Generate Solana address
let sol_pubkey = "e258d6e13adfb7b6eb771e0c9e8b1e3d4e3f1a2b3c4d5e6f7a8b9c0d1e2f3a4b";
let sol_chain = new.unwrap; // Solana mainnet
let sol_address = generate_address?;
println!; // Fe3d...
// Generate Bitcoin address, compressed by default
let btc_pubkey = "04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235";
let btc_chain = new.unwrap; // Bitcoin mainnet
let btc_address = generate_address?;
println!; // 1ABC...
Chain-Specific Generation
use address as eth;
use address as sol;
use address as btc;
// Direct Ethereum address generation
let eth_addr = generate_address?;
// Direct Solana address generation
let sol_addr = generate_address?;
// Direct Bitcoin address generation (compressed format recommended)
let btc_addr = generate_p2pkh_address?;
Public Key Formats
Ethereum (EIP155)
Accepts SEC1-encoded public keys in hex format:
- Uncompressed: 65 bytes starting with
04(130 hex chars) - Compressed: 33 bytes starting with
02or03(66 hex chars)
// Uncompressed (recommended for ICP threshold signatures)
let uncompressed = "04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235";
// Compressed
let compressed = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798";
Solana
Requires exactly 32-byte public keys in hex format (64 hex characters):
let solana_pubkey = "e258d6e13adfb7b6eb771e0c9e8b1e3d4e3f1a2b3c4d5e6f7a8b9c0d1e2f3a4b";
Bitcoin (BIP122)
Accepts SEC1-encoded public keys in hex format, similar to Ethereum:
- Uncompressed: 65 bytes starting with
04(130 hex chars) - Compressed: 33 bytes starting with
02or03(66 hex chars)
The address type (mainnet/testnet) is determined by the chain reference:
000000000019d6689c085ae165831e93- Bitcoin mainnet (addresses start with1)000000000933ea01ad0ee984209779ba- Bitcoin testnet (addresses start withmorn)0f9188f13cb7b2c71f2a335e3a4fc328- Bitcoin regtest (addresses start withmorn)
Important: The compression flag affects the generated address:
use_compressed: true- Uses compressed public key format (recommended)use_compressed: false- Uses uncompressed public key format (legacy)
let bitcoin_pubkey = "04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235";
// Compressed format (recommended)
let compressed_addr = generate_p2pkh_address?;
// Uncompressed format (legacy)
let uncompressed_addr = generate_p2pkh_address?;
Error Handling
All functions return Result<String, String> with descriptive error messages:
match generate_address
Common errors:
"Unsupported namespace: <namespace>"- Chain not supported
Testing
Run the test suite: