Skip to main content

Overview

Version 7 of hive-tx is a complete TypeScript rewrite that brings significant improvements to the API design, type safety, and developer experience. While this means breaking changes, the migration path is straightforward and the benefits are substantial.

What’s New in v7

Major Improvements:
  • Complete TypeScript rewrite with comprehensive type definitions
  • Enhanced JSDoc documentation for all methods
  • Full typing for all Hive blockchain operations
  • New callWithQuorum() for cross-checking results across multiple nodes
  • New callREST() with complete typing for REST APIs
  • Comprehensive test suite including operation validation
  • Three build outputs: ESM, CJS, and browser-ready UMD
  • Detailed guides: QUICKSTART.md and EXAMPLES.md

Library Size

The library remains lightweight at approximately 29KB minified+gzipped (including all dependencies).

Breaking Changes

Version 7 introduces several breaking changes that require code updates. Review each section below carefully.

1. Transaction Creation API

The transaction creation API has been completely redesigned for better ergonomics and type safety. Before (v6):
const tx = new Transaction()
await tx.create([
  ['vote', { 
    voter: 'alice', 
    author: 'bob', 
    permlink: 'post', 
    weight: 10000 
  }]
])
After (v7):
const tx = new Transaction()
await tx.addOperation('vote', { 
  voter: 'alice', 
  author: 'bob', 
  permlink: 'post', 
  weight: 10000 
})
The new API provides better autocomplete and type checking. You can chain multiple addOperation() calls or call it multiple times.

2. API Call Method Renamed

The generic call() function has been renamed to callRPC() with improved error handling. Before (v6):
const result = await call('condenser_api.get_accounts', [['alice']])
const accounts = result.result
After (v7):
const accounts = await callRPC('condenser_api.get_accounts', [['alice']])
// Returns result directly, throws RPCError on errors
The new callRPC() unwraps the result automatically and throws typed errors instead of returning error objects.

3. Transaction Broadcast Signature

The Transaction.broadcast() method signature has changed. Before (v6):
await tx.broadcast(timeout?, retry?)
After (v7):
await tx.broadcast(checkStatus?)
The checkStatus parameter is a boolean that determines whether to verify the transaction was included in a block.

4. Timeout Values Now in Milliseconds

All timeout and expiration values have been standardized to use milliseconds instead of seconds. Before (v6):
import { config } from 'hive-tx'

config.timeout = 10 // 10 seconds
After (v7):
import { config } from 'hive-tx'

config.timeout = 10_000 // 10 seconds (10,000 milliseconds)
This is a critical change. If you don’t update timeout values, your requests will timeout almost immediately!

5. Transaction Constructor Signature

The Transaction constructor signature has changed to accept an options object. Before (v6):
const tx = new Transaction(existingTransaction)
After (v7):
const tx = new Transaction({
  transaction: existingTransaction,
  expiration: 60000 // milliseconds
})

6. Removed Property: signedTransaction

The Transaction.signedTransaction property has been removed. Before (v6):
const signedTx = tx.signedTransaction
After (v7):
const signedTx = tx.transaction

7. Configuration: Node URLs

The configuration has changed from a single node to multiple nodes for better failover support. Before (v6):
import { config } from 'hive-tx'

config.node = 'https://api.hive.blog'
After (v7):
import { config } from 'hive-tx'

config.nodes = [
  'https://api.hive.blog',
  'https://api.deathwing.me',
  'https://api.openhive.network'
]
v7 comes with a pre-configured list of reliable nodes. You only need to modify config.nodes if you want to use custom nodes.

8. Removed Configuration: healthcheckInterval

The config.healthcheckInterval option has been removed in v7. Before (v6):
config.healthcheckInterval = 30
After (v7):
// This configuration option is no longer available
// Node health is managed automatically

New Features in v7

callWithQuorum()

Cross-check RPC results across multiple nodes to ensure data integrity.
import { callWithQuorum } from 'hive-tx'

// Verify result with 2 nodes before returning
const accounts = await callWithQuorum(
  'condenser_api.get_accounts', 
  [['username']], 
  2 // quorum size
)
console.log('Account:', accounts[0])

callREST()

Access Hive’s REST APIs with full TypeScript typing.
import { callREST } from 'hive-tx'

const balance = await callREST('balance', '/accounts/{account-name}/balances', {
  'account-name': 'alice'
})
console.log(balance)

Improved Type Definitions

All operations now have complete type definitions:
import { Transaction, PrivateKey } from 'hive-tx'

const tx = new Transaction()

// Full autocomplete and type checking for operation parameters
await tx.addOperation('transfer', {
  from: 'sender',
  to: 'receiver',
  amount: '1.000 HIVE',
  memo: 'Thanks!'
})

Better Error Messages

Errors now include detailed information and stack traces:
import { RPCError, callRPC } from 'hive-tx'

try {
  await callRPC('condenser_api.get_accounts', [['invalid']])
} catch (error) {
  if (error instanceof RPCError) {
    console.error('RPC Error:', error.message)
    console.error('Code:', error.code)
  }
}

Step-by-Step Migration Guide

Follow these steps to migrate your codebase from v6 to v7:

Step 1: Update Package Version

npm install hive-tx@latest

Step 2: Update Imports

The main imports remain the same, but verify you’re importing the correct functions:
// v7 imports
import { 
  Transaction, 
  PrivateKey, 
  callRPC,        // renamed from 'call'
  callREST,       // new
  callWithQuorum, // new
  config 
} from 'hive-tx'

Step 3: Update Configuration

Convert your node configuration to use an array:
// Before
config.node = 'https://api.hive.blog'
config.timeout = 10

// After
config.nodes = ['https://api.hive.blog']
config.timeout = 10_000 // Convert seconds to milliseconds

Step 4: Update Transaction Creation

Replace all tx.create() calls with tx.addOperation():
// Before
await tx.create([
  ['vote', voteData],
  ['comment', commentData]
])

// After
await tx.addOperation('vote', voteData)
await tx.addOperation('comment', commentData)

Step 5: Update API Calls

Rename call() to callRPC() and update result handling:
// Before
const result = await call('condenser_api.get_accounts', [['alice']])
const accounts = result.result

// After
const accounts = await callRPC('condenser_api.get_accounts', [['alice']])

Step 6: Update Broadcast Calls

Review and update broadcast() calls:
// Before
await tx.broadcast(10, 3)

// After
await tx.broadcast(true) // checkStatus boolean

Step 7: Update Transaction Constructor

If you’re creating transactions from existing transaction objects:
// Before
const tx = new Transaction(existingTx)

// After
const tx = new Transaction({
  transaction: existingTx,
  expiration: 60000
})

Step 8: Remove healthcheckInterval

Remove any references to config.healthcheckInterval:
// Before
config.healthcheckInterval = 30

// After
// Remove this line - health checks are automatic

Step 9: Update signedTransaction References

Replace tx.signedTransaction with tx.transaction:
// Before
const signed = tx.signedTransaction

// After
const signed = tx.transaction

Step 10: Test Thoroughly

Run your test suite to ensure all changes work correctly:
npm test

Common Migration Pitfalls

Watch out for these common issues during migration:

Pitfall 1: Forgetting to Convert Timeouts

// WRONG - will timeout immediately!
config.timeout = 10

// CORRECT
config.timeout = 10_000

Pitfall 2: Not Unwrapping callRPC Results

// WRONG - result is already unwrapped
const data = (await callRPC('...')).result

// CORRECT
const data = await callRPC('...')

Pitfall 3: Using Old create() Syntax

// WRONG - create() no longer exists
await tx.create([['vote', data]])

// CORRECT
await tx.addOperation('vote', data)

Pitfall 4: Single Node String

// WRONG - nodes must be an array
config.nodes = 'https://api.hive.blog'

// CORRECT
config.nodes = ['https://api.hive.blog']

Pitfall 5: Accessing signedTransaction

// WRONG - property removed
const tx = transaction.signedTransaction

// CORRECT
const tx = transaction.transaction

Migration Checklist

Use this checklist to ensure you’ve covered all migration steps:
  • Updated package to v7
  • Changed call() to callRPC()
  • Updated all tx.create() to tx.addOperation()
  • Converted all timeout values from seconds to milliseconds
  • Changed config.node to config.nodes (array)
  • Updated Transaction.broadcast() signature
  • Updated new Transaction() constructor calls
  • Replaced tx.signedTransaction with tx.transaction
  • Removed config.healthcheckInterval references
  • Updated error handling for new RPCError type
  • Ran test suite successfully
  • Verified production functionality in staging environment

Need Help?

If you encounter issues during migration:

Example: Complete Migration

Here’s a complete before/after example showing a typical v6 codebase migrated to v7:

Before (v6)

import { Transaction, PrivateKey, call, config } from 'hive-tx'

// Configuration
config.node = 'https://api.hive.blog'
config.timeout = 10
config.healthcheckInterval = 30

// Get account
const result = await call('condenser_api.get_accounts', [['alice']])
const account = result.result[0]

// Create transaction
const tx = new Transaction()
await tx.create([
  ['vote', {
    voter: 'alice',
    author: 'bob',
    permlink: 'post',
    weight: 10000
  }]
])

// Sign and broadcast
const key = PrivateKey.from('5J...')
tx.sign(key)
await tx.broadcast(10, 3)

// Access signed transaction
const signed = tx.signedTransaction

After (v7)

import { Transaction, PrivateKey, callRPC, config } from 'hive-tx'

// Configuration
config.nodes = ['https://api.hive.blog', 'https://api.deathwing.me']
config.timeout = 10_000

// Get account
const accounts = await callRPC('condenser_api.get_accounts', [['alice']])
const account = accounts[0]

// Create transaction
const tx = new Transaction()
await tx.addOperation('vote', {
  voter: 'alice',
  author: 'bob',
  permlink: 'post',
  weight: 10000
})

// Sign and broadcast
const key = PrivateKey.from('5J...')
tx.sign(key)
await tx.broadcast(true)

// Access transaction
const signed = tx.transaction
The v7 code is cleaner, more type-safe, and provides better error handling!

Build docs developers (and LLMs) love