Skip to main content

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?)
keyBytes
Uint8Array
required
Raw public key bytes (33 bytes, compressed format)
prefix
string
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)
publicKeyString
string
required
Public key string with prefix (e.g., “STM8m5UgaFAAYQRuaNejYdS8FVLVp9Ss3K1qAVk5de6F8s3HnVbvA”)
returns
PublicKey
New PublicKey instance

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
returns
PublicKey
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)
message
Uint8Array
required
32-byte message hash to verify (typically SHA256 digest)
signature
Signature | string
required
Signature to verify (Signature instance or 130-character hex string)
returns
boolean
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()
returns
string
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()
returns
string
Public key string

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()
returns
string
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)

Format and Encoding

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

Example Format Breakdown

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

key
Uint8Array
Raw 33-byte compressed public key
prefix
string
Address prefix (e.g., ‘STM’, ‘TST’)

See Also

Build docs developers (and LLMs) love