{"id":15598,"library":"ecpair","title":"ECPair: SECP256k1 Keypair Management for Bitcoin","description":"ecpair is a JavaScript/TypeScript library designed for managing SECP256k1 keypairs, primarily used within the BitcoinJS ecosystem for client-side applications. Currently at stable version 3.0.1, it provides core functionalities for generating new keypairs, importing them from various formats like WIF (Wallet Import Format) or raw private/public keys, and deriving public keys. Releases are generally stable, driven by updates within the broader BitcoinJS ecosystem or critical bug fixes. A key differentiator is its modular architecture, which externalizes all elliptic curve cryptography operations to a separate ECC library (e.g., `tiny-secp256k1`), enhancing flexibility and allowing for specific backend optimizations or compliance. The library is written in TypeScript and ships with comprehensive type definitions, promoting robust development practices.","status":"active","version":"3.0.1","language":"javascript","source_language":"en","source_url":"https://github.com/bitcoinjs/ecpair","tags":["javascript","bitcoinjs","bitcoin","browserify","typescript"],"install":[{"cmd":"npm install ecpair","lang":"bash","label":"npm"},{"cmd":"yarn add ecpair","lang":"bash","label":"yarn"},{"cmd":"pnpm add ecpair","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required as the external ECC library for all cryptographic operations (e.g., key generation, signing, validation).","package":"tiny-secp256k1","optional":false}],"imports":[{"note":"ecpair v3 is an ESM-first package. This is the primary export for initializing the ECPair API.","wrong":"const { ECPairFactory } = require('ecpair');","symbol":"ECPairFactory","correct":"import { ECPairFactory } from 'ecpair';"},{"note":"This is a TypeScript type definition. The runtime instance is created via `ECPairFactory`.","wrong":"import ECPair from 'ecpair'; // ECPairAPI is a type, not a runtime value","symbol":"ECPairAPI","correct":"import { ECPairAPI } from 'ecpair';"},{"note":"This is a TypeScript interface defining the required methods for the external ECC library (e.g., `tiny-secp256k1`).","symbol":"TinySecp256k1Interface","correct":"import { TinySecp256k1Interface } from 'ecpair';"}],"quickstart":{"code":"import { ECPairFactory, TinySecp256k1Interface, ECPairInterface } from 'ecpair';\nimport * as crypto from 'crypto';\n\n// You need to provide an ECC library that implements TinySecp256k1Interface\n// This is typically 'tiny-secp256k1'\nconst tinysecp: TinySecp256k1Interface = require('tiny-secp256k1');\nconst ECPair = ECPairFactory(tinysecp);\n\n// Generate a random key pair\nconst keyPair1: ECPairInterface = ECPair.makeRandom();\nconsole.log('Random Private Key (HEX):', keyPair1.privateKey?.toString('hex'));\nconsole.log('Random Public Key (HEX):', keyPair1.publicKey.toString('hex'));\n\n// Import from WIF\nconst wifKey = 'L45P2H58kPq611cRjP5H3rXfRjP5H3rXfRjP5H3rXfRjP5H3rXfRjP5H3rXfRjP5H3rXfRjP5H3rXf'; // Example WIF (DO NOT USE FOR REAL ASSETS)\nconst keyPair2: ECPairInterface = ECPair.fromWIF(wifKey);\nconsole.log('WIF Public Key (HEX):', keyPair2.publicKey.toString('hex'));\n\n// Import from a private key buffer\nconst privateKeyBuffer = crypto.randomBytes(32);\nconst keyPair3: ECPairInterface = ECPair.fromPrivateKey(privateKeyBuffer);\nconsole.log('Imported Private Key (HEX):', keyPair3.privateKey?.toString('hex'));\n\n// Import from a public key buffer\nconst keyPair4: ECPairInterface = ECPair.fromPublicKey(keyPair1.publicKey);\nconsole.log('Imported Public Key (HEX):', keyPair4.publicKey.toString('hex'));\n\n// Demonstrate custom network and RNG\nconst customNetwork = { messagePrefix: '\\x18Bitcoin Signed Message:\\n', bip32: { public: 0x0488b21e, private: 0x0488ade4 }, pubKeyHash: 0x00, scriptHash: 0x05, wif: 0x80 };\nconst customRng = (size: number): Buffer => crypto.randomBytes(size);\nconst keyPair5 = ECPair.makeRandom({ network: customNetwork, rng: customRng });\nconsole.log('Custom Network Public Key (HEX):', keyPair5.publicKey.toString('hex'));","lang":"typescript","description":"This quickstart demonstrates how to initialize `ecpair` with an ECC library, generate random keypairs, and import keys from WIF, private keys, and public keys, including custom network and RNG function usage."},"warnings":[{"fix":"For Node.js < 20, either provide a custom `rng` function (e.g., using `randombytes` package) or run Node.js with `--experimental-global-webcrypto` flag. Ensure your Node.js environment is v20.0.0 or higher.","message":"The `ECPair.makeRandom()` method, when no custom `rng` function is provided, internally uses `crypto.getRandomValues`. This API was experimental in Node.js 18.19.0 and earlier. Running on older Node versions without the `--experimental-global-webcrypto` flag or a polyfill can lead to issues.","severity":"gotcha","affected_versions":"<3.0.0 || <=18.19.0 (Node.js)"},{"fix":"Update your project to use ES Modules (`import`/`export`) for `ecpair`. Ensure your Node.js version is 20.0.0 or higher. If you need CommonJS, consider using a bundler (like Webpack or Rollup) or stick to `ecpair` v2.x if compatible with your other dependencies.","message":"Version 3.x of `ecpair` has moved to an ESM-first (ECMAScript Module) architecture and mandates Node.js >= 20.0.0. Direct `require()` statements for `ecpair` will generally not work in new projects or if your environment is configured for ESM. Similarly, the internal usage of `crypto.getRandomValues` instead of `randombytes` is a significant change.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Only provide a custom `rng` function if you fully understand cryptographic random number generation and have a strong justification for it. In most cases, rely on the default, cryptographically secure RNG provided by the library (which uses `crypto.getRandomValues`).","message":"Passing a custom Random Number Generator (RNG) function to `ECPair.makeRandom({ rng: customRng })` requires extreme caution. A poorly implemented or compromised RNG can lead to predictable private keys, resulting in significant security vulnerabilities and loss of funds.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure you initialize `ECPair` by calling `const ECPair = ECPairFactory(tinysecp);` after importing `ECPairFactory` and `tiny-secp256k1`.","cause":"The `ECPair` object itself is not directly imported but is the result of calling `ECPairFactory` with an ECC library.","error":"TypeError: ECPair.makeRandom is not a function"},{"fix":"Install `tiny-secp256k1` (`npm install tiny-secp256k1`) and pass it to the factory: `const tinysecp = require('tiny-secp256k1'); const ECPair = ECPairFactory(tinysecp);`","cause":"`ECPairFactory` was called without a valid implementation of `TinySecp256k1Interface` (most commonly `tiny-secp256k1`).","error":"Error: Missing TinySecp256k1Interface implementation. Please provide an ECC library (e.g., tiny-secp256k1)."},{"fix":"Use ES Module `import` syntax: `import { ECPairFactory } from 'ecpair';`.","cause":"Attempting to use `require()` to import `ecpair` in an ES Module context.","error":"ReferenceError: require is not defined in ES module scope"}],"ecosystem":"npm"}