ID@agntn/keysv0.7.0

One key. Every chain.

Key generation, address derivation and message signing for twenty-three blockchains, typed and built on noble, scure and our own hashes. One interface in TypeScript, the same tools over MCP, Pi and OMP, and nothing ever leaves the process.

Chains
23
two curves
Tools
36
MCP · Pi · OMP
Network
0 calls
in process
Install$ pnpm add @agntn/keys
Callchain.getAddress(k · G)23 chains · 2 curves
Private key

1

0000000000000000000000000000000000000000000000000000000000000001

Public key
0279be667e…16f81798
Range
1 … n − 1
Addresses
23 from one key

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.

  • Both curves from @noble, nothing else underneath
  • Legacy, SegWit, Taproot, EIP-55, base58check, bech32
  • Same 32 bytes, twenty-three chains, derived in this tab
Read Open the keyspace
Callbitcoin.getAddress(k · G)k = 1

0000000000000000000000000000000000000000000000000000000000000001

Public key
0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
Legacy
1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
Segwit
bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
Taproot
bc1pmfr3p9j00pfxjh0zmgp99y8zftmd3s5pmedqhyptwy6lm87hf5sspknck9
Bitcoin · secp256k1 / in this tab
Key

Same calls, every chain

Every blockchain is a class with the same shape. Swap the import and the rest of the code stays. A chain that can't do what you asked throws, Decred on a segwit address, Cardano on an HD walk, instead of handing you something that only looks right.

  • generateWallet, getAddress, signMessage on every driver
  • Drivers load lazily, only the chains you use ship
  • Custom chains extend the same abstract class
Read Working with keys
Filebitcoin.tssame shape · 23 drivers

Driver

import { useBlockchain, blockchains } from "@agntn/keys";const chain = useBlockchain(await blockchains.bitcoin()());const wallet = chain.generateWallet();const signature = chain.signMessage("hello", wallet.private);// key 1 on Bitcoin: bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4

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. Puzzle phrases with a bad checksum go through on request, words untouched.

  • BIP32 for secp256k1, SLIP-10 for ed25519
  • Bitcoin, Bitcoin Gold and Litecoin infer the address type from the purpose
  • Broken checksum? Derive anyway and get a warning with the wallet
Read Generating wallets
Callethereum.deriveHDWallet(mnemonic, "m/44'/60'/0'/0/0")

Path

  1. mmaster
  2. 44'purpose
  3. 60'coin
  4. 0'account
  5. 0change
  6. 0index
Mnemonic
abandon abandon … about
Address
0x9858EfFD232B4033E47d90003D41EC34EcaEda94
BIP39 test vector / never a real walletBIP32 · secp256k1

23 drivers, one class shape

Each chain is an adapter over the shared primitives: its hashing, its encoding and the arguments that matter there. Adding one means writing those rules, not the cryptography. Every driver has a page with its formats and the traps.

Import@agntn/keys/blockchains/<key>

blockchains23 drivers · registry order
About
BitcoinbitcoinFive address formats, testnet, and a taproot that does the real BIP341 tweak.secp256k1
Bitcoin CashbitcoincashBitcoin's key and hash written as CashAddr, bitcoincash:q..., and nothing else.secp256k1
Bitcoin GoldbitcoingoldBitcoin's formats behind G, A and btg1q, and no taproot, because the chain never turned it on.secp256k1
Bitcoin SVbitcoinsvBitcoin's 1 address, byte for byte, and no P2SH since Genesis.secp256k1
LitecoinlitecoinBitcoin's five formats behind L, M and ltc1, plus its own message preamble.secp256k1
DashdashBitcoin's P2PKH behind an X, a preamble still called DarkCoin, and no SegWit.secp256k1
DecreddecredBLAKE-256 in every hash, addresses that start with Ds, and no HD walk, on purpose.secp256k1
DogecoindogecoinBitcoin's P2PKH behind a D, its own preamble, and no SegWit to wrap anything in.secp256k1
ZcashzcashThe transparent half only: t1 behind two version bytes, and nothing shielded.secp256k1
eCashecashBitcoin Cash's CashAddr under ecash:, its own preamble, and none of the CashTokens types.secp256k1
EthereumethereumEIP-55 checksummed hex and the personal_sign preamble.secp256k1
BasebaseSame driver as Ethereum under a different name. Same key, same address.secp256k1
TRONtronEthereum's 20 bytes wrapped in base58check, so it starts with T.secp256k1
SolanasolanaThe address is the public key in base58, no hashing at all.ed25519
StellarstellarThe public key as a G StrKey with a CRC16 checksum, and SEP-53 message signing.ed25519
AptosaptosSHA3-256 over the key and a scheme byte, 0x hex out.ed25519
SuisuiBoth curves on one chain. Blake2b over a flag byte and the key.ed25519 · secp256k1
CardanocardanoBase, enterprise and stake addresses in bech32. No mnemonic derivation, on purpose.ed25519
XRP LedgerxrplFamily seeds, both curves, and Bitcoin's base58 shuffled until every account starts with r.secp256k1 · ed25519
NEARnearThe account is the public key in hex. No hash, no checksum, not even base58.ed25519
CosmoscosmosOne driver for the Hub, Osmosis, Celestia and the rest. Same key, same path, only the letters before the 1 disagree.secp256k1
PolkadotpolkadotSS58 under any network prefix, Kusama included. ed25519 for now, sr25519 is still waiting its turn.ed25519
MoneromoneroTwo public keys in one 95-character address, and a 25th seed word that only checks the other 24.ed25519
one class shape / no networkblockchains.<key>()() loads one

Thirty-six 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. The Pi and OMP extensions run the same executors.

  • Keys, WIF, mnemonics, BIP44 paths, addresses, signing
  • stdio server started with one command
  • A generated mnemonic comes back marked as already in the transcript
Read MCP server setup
Callkeys_address_get("bitcoin")
Address / mainnet

Bitcoin

secp256k1

Public key
0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
Type
segwit
Address
bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
MCP · Pi · OMP / no networkkeys mcp · stdio
Startpnpm add @agntn/keysNode.js 26 or newer

Start with one command

One install gives you the library, the keys CLI and the MCP server. Load a driver, hand it a key and read the address.

  • PinPre-1.0, so pin exact versions.
  • FundsKeep real funds on a hardware wallet, not in a script.
  • LocalDerivation and signing run in the process. Nothing goes out.

First address

$ pnpm add @agntn/keysimport { useBlockchain, blockchains } from "@agntn/keys";const chain = useBlockchain(await blockchains.bitcoin()());const publicKey = chain.getKeyPublic("0000…0001");chain.getAddress(publicKey, "segwit");  // "bc1qw508d6…v8f3t4"