Overview
The PublicKey class handles ECDSA (secp256k1) public keys for the Hive blockchain. It provides methods for parsing public key strings, verifying signatures, and converting between different representations.
Public keys are stored in compressed format (33 bytes) and include an address prefix (e.g., ‘STM’ for Hive mainnet).
Constructor
const publicKey = new PublicKey(keyBytes, prefix?)
Raw public key bytes (33 bytes, compressed format)
Optional address prefix (defaults to config.address_prefix, typically ‘STM’)
Example
import { PublicKey } from 'hive-tx'
// Create from raw bytes
const keyBytes = new Uint8Array(33) // Must be valid compressed public key
const publicKey = new PublicKey(keyBytes)
// With custom prefix
const testnetKey = new PublicKey(keyBytes, 'TST')
Static Methods
fromString
Creates a PublicKey from a string representation.
const publicKey = PublicKey.fromString(publicKeyString)
Public key string with prefix (e.g., “STM8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA”)
Example
import { PublicKey } from 'hive-tx'
const pubKeyStr = 'STM8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA'
const publicKey = PublicKey.fromString(pubKeyStr)
console.log('Prefix:', publicKey.prefix) // 'STM'
console.log('String:', publicKey.toString()) // Original string
from
Creates a PublicKey from a string or returns the instance if already a PublicKey. Useful for accepting flexible input types.
const publicKey = PublicKey.from(value)
value
string | PublicKey
required
Public key string or existing PublicKey instance
New or existing PublicKey instance
Example
import { PublicKey } from 'hive-tx'
// From string
const key1 = PublicKey.from('STM8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA')
// From existing instance (returns same instance)
const key2 = PublicKey.from(key1)
console.log(key1 === key2) // true
// Useful for function parameters
function verifySignature(pubKey: string | PublicKey, signature: string) {
const key = PublicKey.from(pubKey)
// ... verify logic
}
Instance Methods
verify
Verifies a signature against a message hash using this public key.
const isValid = publicKey.verify(message, signature)
32-byte message hash to verify (typically SHA256 digest)
signature
Signature | string
required
Signature to verify (Signature instance or 130-character hex string)
true if signature is valid, false otherwise
Example
import { PrivateKey, PublicKey, Transaction } from 'hive-tx'
// Create and sign a transaction
const privateKey = PrivateKey.fromLogin('alice', 'password', 'active')
const publicKey = privateKey.createPublic()
const tx = new Transaction()
await tx.addOperation('vote', {
voter: 'alice',
author: 'bob',
permlink: 'my-post',
weight: 10000
})
const { digest } = tx.digest()
const signature = privateKey.sign(digest)
// Verify the signature
const isValid = publicKey.verify(digest, signature)
console.log('Signature valid:', isValid) // true
// Verify with signature string
const isValid2 = publicKey.verify(digest, signature.customToString())
console.log('Signature valid:', isValid2) // true
toString
Returns the public key as a string for storage or transmission.
const keyString = publicKey.toString()
Public key string with prefix (e.g., “STM8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA”)
Example
import { PrivateKey } from 'hive-tx'
const privateKey = PrivateKey.fromLogin('alice', 'password', 'posting')
const publicKey = privateKey.createPublic()
// Convert to string for storage or API calls
const keyString = publicKey.toString()
console.log('Public key:', keyString)
// Output: STM8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA
// Store in database or send to API
const accountData = {
username: 'alice',
posting_key: keyString
}
toJSON
Returns JSON representation of the public key (same as toString()).
const json = publicKey.toJSON()
Example
import { PrivateKey } from 'hive-tx'
const privateKey = PrivateKey.fromLogin('alice', 'password', 'active')
const publicKey = privateKey.createPublic()
// Automatically called by JSON.stringify
const json = JSON.stringify({ activeKey: publicKey })
console.log(json)
// Output: {"activeKey":"STM8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA"}
inspect
Returns a string representation for debugging.
const debugString = publicKey.inspect()
Formatted public key string for debugging
Example
import { PublicKey } from 'hive-tx'
const publicKey = PublicKey.fromString('STM8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA')
console.log(publicKey.inspect())
// Output: PublicKey: STM8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA
Deriving from Private Key
The most common way to obtain a PublicKey is by deriving it from a PrivateKey:
import { PrivateKey } from 'hive-tx'
// Derive from private key
const privateKey = PrivateKey.fromLogin('alice', 'password', 'posting')
const publicKey = privateKey.createPublic()
console.log('Private key:', privateKey.inspect())
console.log('Public key:', publicKey.toString())
Recovering from Signature
You can recover the public key that created a signature:
import { PrivateKey, Transaction } from 'hive-tx'
// Sign a transaction
const privateKey = PrivateKey.fromLogin('alice', 'password', 'active')
const tx = new Transaction()
await tx.addOperation('vote', {
voter: 'alice',
author: 'bob',
permlink: 'my-post',
weight: 10000
})
const { digest } = tx.digest()
const signature = privateKey.sign(digest)
// Recover public key from signature
const recoveredPublicKey = signature.getPublicKey(digest)
const expectedPublicKey = privateKey.createPublic()
console.log('Keys match:', recoveredPublicKey.toString() === expectedPublicKey.toString())
// Output: true
Signature Verification Example
import { PrivateKey, PublicKey, Transaction, Signature } from 'hive-tx'
async function verifyTransactionSignature(
transaction: Transaction,
signatureHex: string,
expectedPublicKey: string
): Promise<boolean> {
// Parse public key
const publicKey = PublicKey.fromString(expectedPublicKey)
// Get transaction digest
const { digest } = transaction.digest()
// Parse signature
const signature = Signature.from(signatureHex)
// Verify signature
const isValid = publicKey.verify(digest, signature)
return isValid
}
// Usage
const tx = new Transaction()
await tx.addOperation('transfer', {
from: 'alice',
to: 'bob',
amount: '1.000 HIVE',
memo: ''
})
const privateKey = PrivateKey.fromLogin('alice', 'password', 'active')
const { digest } = tx.digest()
const signature = privateKey.sign(digest)
const isValid = await verifyTransactionSignature(
tx,
signature.customToString(),
privateKey.createPublic().toString()
)
console.log('Signature is valid:', isValid) // true
Account Authority Verification
import { PublicKey } from 'hive-tx'
import { Client } from '@hiveio/dhive'
const client = new Client(['https://api.hive.blog'])
async function verifyAccountAuthority(
username: string,
publicKey: PublicKey,
requiredRole: 'owner' | 'active' | 'posting'
): Promise<boolean> {
// Fetch account data
const [account] = await client.database.getAccounts([username])
if (!account) {
throw new Error(`Account ${username} not found`)
}
// Get the authority object
const authority = account[requiredRole]
// Check if public key is in the authority
const publicKeyStr = publicKey.toString()
const hasAuthority = authority.key_auths.some(
([key, weight]: [string, number]) => key === publicKeyStr && weight > 0
)
return hasAuthority
}
// Usage
const publicKey = PublicKey.fromString('STM8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA')
const hasPostingAuth = await verifyAccountAuthority('alice', publicKey, 'posting')
console.log('Has posting authority:', hasPostingAuth)
Hive public keys use the following format:
[PREFIX][BASE58_ENCODED_KEY_WITH_CHECKSUM]
- Prefix: Network identifier (e.g., ‘STM’ for Hive mainnet, ‘TST’ for testnet)
- Encoding: Base58 encoding with RIPEMD160 checksum (first 4 bytes)
- Key format: 33-byte compressed secp256k1 public key
import { PublicKey } from 'hive-tx'
const pubKeyStr = 'STM8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA'
// ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Prefix Base58 encoded key + checksum
const publicKey = PublicKey.fromString(pubKeyStr)
console.log('Prefix:', publicKey.prefix) // 'STM'
console.log('Key bytes length:', publicKey.key.length) // 33
console.log('Full string:', publicKey.toString()) // Original
Working with Multiple Networks
import { PrivateKey } from 'hive-tx'
const privateKey = PrivateKey.fromLogin('alice', 'password', 'active')
// Mainnet public key (STM prefix)
const mainnetKey = privateKey.createPublic('STM')
console.log('Mainnet:', mainnetKey.toString())
// Output: STM8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA
// Testnet public key (TST prefix)
const testnetKey = privateKey.createPublic('TST')
console.log('Testnet:', testnetKey.toString())
// Output: TST8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA
// Note: The encoded portion is identical, only the prefix differs
Properties
Raw 33-byte compressed public key
Address prefix (e.g., ‘STM’, ‘TST’)
See Also