Overview
The PrivateKey class handles ECDSA (secp256k1) private keys for the Hive blockchain. It provides methods for key generation, derivation from seeds/passwords, signing transactions, and encryption operations.
All private keys are stored internally as Uint8Array and can be converted to/from Wallet Import Format (WIF) strings for storage and transmission.
Constructor
const key = new PrivateKey(keyBytes)
Raw 32-byte private key as Uint8Array
The constructor validates that the key is valid for secp256k1. Invalid keys will throw an error.
Example
import { PrivateKey } from 'hive-tx'
import { randomBytes } from '@noble/hashes/utils'
// Create from raw bytes (must be valid secp256k1 key)
const keyBytes = randomBytes(32)
const key = new PrivateKey(keyBytes)
Static Methods
from
Creates a PrivateKey instance from a WIF string or raw Uint8Array. Automatically detects the input type.
const key = PrivateKey.from(value)
value
string | Uint8Array
required
WIF formatted string or raw 32-byte key as Uint8Array
Example
import { PrivateKey } from 'hive-tx'
// From WIF string
const key = PrivateKey.from('5JdeC9P7Pbd1uGdFVEsJ41EkEnADbbHGq6p1BwFxm6txNBsQnsw')
// From Uint8Array
const keyBytes = new Uint8Array(32)
const key = PrivateKey.from(keyBytes)
fromString
Creates a PrivateKey from a Wallet Import Format (WIF) encoded string.
const key = PrivateKey.fromString(wif)
WIF encoded private key string (starts with ‘5’)
Example
import { PrivateKey } from 'hive-tx'
const wif = '5JdeC9P7Pbd1uGdFVEsJ41EkEnADbbHGq6p1BwFxm6txNBsQnsw'
const key = PrivateKey.fromString(wif)
console.log(key.toString()) // Returns original WIF
fromSeed
Creates a PrivateKey from a seed string or Uint8Array. The seed is hashed with SHA256 to produce the private key.
const key = PrivateKey.fromSeed(seed)
seed
string | Uint8Array
required
Seed string (hex or UTF-8) or raw byte array
New PrivateKey instance derived from seed
Example
import { PrivateKey } from 'hive-tx'
// From UTF-8 string seed
const key1 = PrivateKey.fromSeed('my-secret-seed-phrase')
// From hex string
const key2 = PrivateKey.fromSeed('a0b1c2d3e4f5')
// From Uint8Array
const seedBytes = new Uint8Array([1, 2, 3, 4, 5])
const key3 = PrivateKey.fromSeed(seedBytes)
fromLogin
Derives a PrivateKey from username, password, and role using Hive’s key derivation scheme. This generates the same keys that Hive wallets use for login-based keys.
const key = PrivateKey.fromLogin(username, password, role?)
Hive username (without ’@’)
Master password or seed phrase
role
KeyRole
default:"'active'"
Key role: 'owner', 'active', 'posting', or 'memo'
New PrivateKey instance for the specified role
Example
import { PrivateKey } from 'hive-tx'
// Generate active key from login
const activeKey = PrivateKey.fromLogin('alice', 'my-master-password', 'active')
// Generate posting key
const postingKey = PrivateKey.fromLogin('alice', 'my-master-password', 'posting')
// Generate owner key
const ownerKey = PrivateKey.fromLogin('alice', 'my-master-password', 'owner')
// Generate memo key
const memoKey = PrivateKey.fromLogin('alice', 'my-master-password', 'memo')
Key Roles:
owner: Highest authority, can change all other keys
active: Can transfer funds and perform most operations
posting: Can post, comment, vote, and follow
memo: Used for encrypting private messages
randomKey
Generates a new cryptographically secure random private key using the secp256k1 key generation algorithm.
const key = PrivateKey.randomKey()
New randomly generated PrivateKey instance
This method may take up to 250ms due to secure entropy collection.
Example
import { PrivateKey } from 'hive-tx'
// Generate a new random key
const randomKey = PrivateKey.randomKey()
// Export to WIF for storage
const wif = randomKey.toString()
console.log('New private key:', wif)
// Get corresponding public key
const publicKey = randomKey.createPublic()
console.log('Public key:', publicKey.toString())
Instance Methods
sign
Signs a 32-byte message hash using ECDSA and returns a recoverable signature. The signature includes recovery information to allow public key recovery.
const signature = key.sign(message)
32-byte message hash to sign (typically SHA256 digest)
Signature object containing the signature data with recovery information
Example
import { PrivateKey, Transaction } from 'hive-tx'
import { sha256 } from '@noble/hashes/sha2'
const key = PrivateKey.fromLogin('alice', 'password', 'active')
// Sign a transaction
const tx = new Transaction()
await tx.addOperation('vote', {
voter: 'alice',
author: 'bob',
permlink: 'my-post',
weight: 10000
})
const { digest } = tx.digest()
const signature = key.sign(digest)
console.log('Signature:', signature.customToString())
createPublic
Derives the corresponding public key for this private key.
const publicKey = key.createPublic(prefix?)
Optional address prefix (defaults to config.address_prefix, typically ‘STM’)
PublicKey instance derived from this private key
Example
import { PrivateKey } from 'hive-tx'
const key = PrivateKey.fromLogin('alice', 'password', 'posting')
// Get default public key (STM prefix)
const publicKey = key.createPublic()
console.log(publicKey.toString())
// Output: STM8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA
// Get public key with custom prefix
const customPublic = key.createPublic('TST')
console.log(customPublic.toString())
// Output: TST8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA
getSharedSecret
Computes a shared secret using ECDH key exchange for memo encryption. The shared secret is used as a key for AES encryption/decryption.
const sharedSecret = key.getSharedSecret(publicKey)
64-byte shared secret (SHA512 hash of ECDH shared point)
Example
import { PrivateKey, PublicKey } from 'hive-tx'
// Alice's keys
const aliceMemoKey = PrivateKey.fromLogin('alice', 'password', 'memo')
const alicePublic = aliceMemoKey.createPublic()
// Bob's keys
const bobMemoKey = PrivateKey.fromLogin('bob', 'password', 'memo')
const bobPublic = bobMemoKey.createPublic()
// Both parties derive the same shared secret
const aliceShared = aliceMemoKey.getSharedSecret(bobPublic)
const bobShared = bobMemoKey.getSharedSecret(alicePublic)
// These are identical and can be used for encryption
console.log('Secrets match:', aliceShared.toString() === bobShared.toString())
toString
Returns the private key as a Wallet Import Format (WIF) encoded string. This includes network ID and checksum for safe storage/transmission.
const wif = key.toString()
WIF encoded private key string
Example
import { PrivateKey } from 'hive-tx'
const key = PrivateKey.fromLogin('alice', 'password', 'active')
const wif = key.toString()
console.log('WIF:', wif)
// Output: 5JdeC9P7Pbd1uGdFVEsJ41EkEnADbbHGq6p1BwFxm6txNBsQnsw
// Store securely
process.env.HIVE_ACTIVE_KEY = wif
// Later, restore from storage
const restoredKey = PrivateKey.fromString(process.env.HIVE_ACTIVE_KEY)
inspect
Returns a masked representation of the private key for debugging/logging. Shows only the first and last 6 characters to avoid accidental exposure.
const masked = key.inspect()
Masked key representation for safe logging
Always use inspect() for logging. Never log toString() output as it exposes the full private key.
Example
import { PrivateKey } from 'hive-tx'
const key = PrivateKey.fromLogin('alice', 'password', 'active')
// Safe for logging
console.log(key.inspect())
// Output: PrivateKey: 5JdeC9...BsQnsw
// UNSAFE - exposes full key
console.log(key.toString())
// Output: 5JdeC9P7Pbd1uGdFVEsJ41EkEnADbbHGq6p1BwFxm6txNBsQnsw
Security Best Practices
Critical Security Guidelines:
- Never expose private keys: Never log, transmit, or store private keys in plain text
- Use environment variables: Store keys in environment variables or secure key management systems
- Use role-appropriate keys: Only use the minimum required key role for each operation
- Secure key generation: Always use
randomKey() or fromLogin() for key generation
- Validate sources: Only load keys from trusted sources
- Memory safety: Clear sensitive key material from memory when done
Secure Storage Example
import { PrivateKey } from 'hive-tx'
// ✅ GOOD: Load from secure environment variable
const key = PrivateKey.fromString(process.env.HIVE_ACTIVE_KEY!)
// ✅ GOOD: Use inspect() for logging
console.log('Using key:', key.inspect())
// ❌ BAD: Hardcoded private key
const badKey = PrivateKey.fromString('5JdeC9P7Pbd1uGdFVEsJ41EkEnADbbHGq6p1BwFxm6txNBsQnsw')
// ❌ BAD: Logging full key
console.log('Key:', key.toString())
Key Role Selection
import { PrivateKey, Transaction } from 'hive-tx'
// ✅ GOOD: Use posting key for posting operations
const postingKey = PrivateKey.fromLogin('alice', 'password', 'posting')
const tx = new Transaction()
await tx.addOperation('vote', {
voter: 'alice',
author: 'bob',
permlink: 'my-post',
weight: 10000
})
tx.sign(postingKey)
// ❌ BAD: Using active key when posting key would suffice
const activeKey = PrivateKey.fromLogin('alice', 'password', 'active')
tx.sign(activeKey) // Works but unnecessarily exposes more powerful key
KeyRole Type
The KeyRole type defines the four key authority levels in Hive:
type KeyRole = 'owner' | 'active' | 'posting' | 'memo'
| Role | Authority Level | Common Operations |
|---|
owner | Highest | Change keys, recover account |
active | High | Transfer funds, power up/down, witness voting |
posting | Medium | Post, comment, vote, follow, reblog |
memo | Low | Encrypt/decrypt private messages |
Complete Examples
Generate and Store New Keys
import { PrivateKey } from 'hive-tx'
import * as fs from 'fs'
// Generate new random keys for all roles
const ownerKey = PrivateKey.randomKey()
const activeKey = PrivateKey.randomKey()
const postingKey = PrivateKey.randomKey()
const memoKey = PrivateKey.randomKey()
// Get public keys for account creation
const keys = {
owner: {
private: ownerKey.toString(),
public: ownerKey.createPublic().toString()
},
active: {
private: activeKey.toString(),
public: activeKey.createPublic().toString()
},
posting: {
private: postingKey.toString(),
public: postingKey.createPublic().toString()
},
memo: {
private: memoKey.toString(),
public: memoKey.createPublic().toString()
}
}
// Store securely (in production, use a proper key management system)
fs.writeFileSync('.keys.json', JSON.stringify(keys, null, 2), {
mode: 0o600 // Read/write for owner only
})
console.log('Keys generated and stored securely')
Sign Transaction with Multiple Keys
import { Transaction, PrivateKey } from 'hive-tx'
async function multiSigTransfer() {
const tx = new Transaction()
// Operation requiring multiple signatures
await tx.addOperation('transfer', {
from: 'multisig-account',
to: 'recipient',
amount: '100.000 HIVE',
memo: ''
})
// Sign with multiple authority keys
const key1 = PrivateKey.fromString(process.env.SIGNER1_KEY!)
const key2 = PrivateKey.fromString(process.env.SIGNER2_KEY!)
tx.sign([key1, key2])
const result = await tx.broadcast()
console.log('Multi-sig transaction broadcast:', result.tx_id)
}
See Also
- PublicKey - Public key management and verification
- Signature - Signature creation and verification
- Transaction - Transaction signing and broadcasting
- Memo - Encrypted message utilities