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
Open the explorer

private key 1

Bitcoin · secp256k1

  1. 132-byte secretinteger in 1 … n − 1
    0000000000000000000000000000000000000000000000000000000000000001
  2. 2public keyk · G, compressed, 33 bytes
    0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
  3. 3addresshash, then encode
    • legacyP2PKH · base58check1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
    • segwitP2WPKH · bech32bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
    • taprootP2TR · bech32mbc1pmfr3p9j00pfxjh0zmgp99y8zftmd3s5pmedqhyptwy6lm87hf5sspknck9
all chains in the explorer

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
Working with keys
TSbitcoin.ts
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
// bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4

HD 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
Generating wallets

derivation path

BIP44 · Ethereum · test vector

mmaster/44'purpose/60'coin/0'account/0change/0index
const wallet = chain.deriveHDWallet(mnemonic, "m/44'/60'/0'/0/0");
// wallet.address
// 0x9858EfFD232B4033E47d90003D41EC34EcaEda94

Blockchains

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
All blockchains

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
MCP server setup

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.

@agntn/keys·MIT license· Keys never leave the browser.