One key. Every chain.
Typed key generation, address derivation, and message signing for eight blockchains. One interface in TypeScript, the same thirteen operations over MCP, and nothing ever leaves the process.
- 8
- chains
- 2
- curves
- 0
- network calls
- 13
- MCP tools
Derivation
Keys in, addresses out
A private key is an integer. Multiply it by the generator, hash the result, encode the hash, and you have an address. Every chain is the same three steps with different rules. The panel walks the keyspace live.
- secp256k1 through @noble, ed25519 through SLIP-10
- Legacy, SegWit, Taproot, EIP-55, base58check, bech32
- Same 32 bytes, eight chains, derived in this tab
private key 1
Bitcoin · secp256k1
- 132-byte secretinteger in 1 … n − 10000000000000000000000000000000000000000000000000000000000000001
- 2public keyk · G, compressed, 33 bytes0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
- 3addresshash, then encode
- legacyP2PKH · base58check1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
- segwitP2WPKH · bech32bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
- taprootP2TR · bech32mbc1pmfr3p9j00pfxjh0zmgp99y8zftmd3s5pmedqhyptwy6lm87hf5sspknck9
One interface
Same calls, every chain
Every blockchain is a class with the same shape. Swap the import and the rest of the code stays. Options that a chain does not support are rejected, not ignored.
- generateWallet, getAddress, signMessage on every driver
- Drivers load lazily, only the chains you use ship
- Custom chains extend the same abstract class
import { useBlockchain, blockchains } from "@agntn/keys";
const chain = useBlockchain(await blockchains.bitcoin()());
const wallet = chain.generateWallet();
const signature = chain.signMessage("hello", wallet.private);
// address of private key 1 on this chain
// bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4HD wallets
Mnemonic to wallet in one call
Walk a BIP39 mnemonic down a BIP44 path and get the wallet at the end of it. Paths are parsed and validated, so a hardened segment in the wrong place fails before derivation.
- BIP39 mnemonics in ten languages, checksum enforced
- BIP32 for secp256k1, SLIP-10 for ed25519
- Bitcoin infers the address type from the purpose
derivation path
BIP44 · Ethereum · test vector
const wallet = chain.deriveHDWallet(mnemonic, "m/44'/60'/0'/0/0");
// wallet.address
// 0x9858EfFD232B4033E47d90003D41EC34EcaEda94Blockchains
Eight drivers, one shape
Each chain is an adapter over the shared primitives. Adding one means implementing the hashing and encoding rules, not the cryptography.
- Mainnet and testnet address formats
- Address validation for every chain
- Sui on both curves, Cardano enterprise and stake
Agents
Thirteen tools over MCP
Everything the library does is exposed as an MCP tool with the same parameters. Point an agent at it and it derives, validates, and signs without touching the network.
- Keys, mnemonics, BIP44 paths, addresses, signing
- stdio server started with one command
- Ambiguous or unsupported inputs are rejected with a reason
toolkeys_get_address
stdio · keys mcp
request
{
"blockchain": "bitcoin",
"publicKey": "0279be667ef9dcbbac…f81798",
"addressType": "segwit"
}result
{
"chain": "bitcoin",
"network": "mainnet",
"address": "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"
}Start with one command
Experimental until 1.0. Pin exact versions and keep real funds on a hardware wallet.