Features
- 40+ operations Vote, transfer, custom_json, power up/down, escrow, proposals, witness management, account recovery, and more.
- Multi-node failover Pass multiple API nodes — requests fall through to the next on error automatically.
- Local signing Transactions are binary-serialized and signed locally. Private keys never leave your process.
- Dry-run mode Build and sign transactions without broadcasting. Inspect the wire format before submitting.
- Block streaming Stream blocks sequentially from any starting point with automatic polling at the chain head.
- 80%+ test coverage Unit tests with beem-verified serialization vectors, plus integration tests against a live node.
Quick start
import "github.com/cadawg/hivego"
// Connect to one or more API nodes (automatic failover)
client := hivego.NewClient(
"https://api.hive.blog",
"https://api.deathwing.me",
)
// Load a key from WIF once at the boundary
key, err := hivego.KeyPairFromWif("5J...")
// Vote on a post
_, txid, err := client.Broadcast.Vote("voter", "author", "permlink", 10000, key)
// Transfer HIVE
amount, _ := hivego.ParseAsset("1.000 HIVE")
_, txid, err = client.Broadcast.Transfer("alice", "bob", amount, "memo", key)
// Read a block
block, err := client.Database.GetBlock(88000000)
fmt.Println(block.Witness, block.Timestamp.Time())
Supported operations
All operations are available as structs implementing HiveOperation, with convenience methods on client.Broadcast:
Social
votecommentcomment_optionsdelete_comment
Transfers
transferrecurrent_transfertransfer_to_savingstransfer_from_savingscancel_transfer_from_savings
Hive Power
transfer_to_vestingwithdraw_vestingdelegate_vesting_sharesset_withdraw_vesting_routeclaim_reward_balance
Market
convertcollateralized_convertlimit_order_createlimit_order_cancel
Accounts
account_createcreate_claimed_accountclaim_accountaccount_updateaccount_update2
Witnesses
witness_updatewitness_set_propertiesaccount_witness_voteaccount_witness_proxyfeed_publish
Proposals (DHF)
create_proposalupdate_proposalupdate_proposal_votesremove_proposal
Recovery & Escrow
request_account_recoveryrecover_accountchange_recovery_accountescrow_transferescrow_approveescrow_disputeescrow_release
Custom
custom_jsoncustomcustom_binarydecline_voting_rights
Need an operation not listed? Implement the HiveOperation interface and pass it to client.BroadcastOps.
More examples
Multi-operation transactions
// comment + comment_options must be in the same transaction
maxPayout, _ := hivego.ParseAsset("1000000.000 HBD")
ops := []hivego.HiveOperation{
hivego.CommentOperation{
Author: "alice", Permlink: "my-post",
ParentPermlink: "hive-blog",
Title: "Hello Hive", Body: "...",
JsonMetadata: `{"tags":["blog"]}`,
},
hivego.CommentOptionsOperation{
Author: "alice", Permlink: "my-post",
MaxAcceptedPayout: maxPayout,
PercentHbd: 10000, AllowVotes: true, AllowCurationRewards: true,
Beneficiaries: []hivego.Beneficiary{{Account: "appdev", Weight: 500}},
},
}
_, txid, err := client.BroadcastOps(ops, postingKey)
Dry-run / inspect transactions
client := hivego.NewClient("https://api.hive.blog").WithNoBroadcast()
tx, txid, err := client.Broadcast.Vote("voter", "author", "permlink", 10000, key)
fmt.Println("txid:", txid)
b, _ := tx.Serialize()
fmt.Printf("wire: %x\n", b)
Stream blocks
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
blocks, errc := client.Database.StreamBlocks(ctx, 88000000, 3*time.Second)
for block := range blocks {
fmt.Println(block.BlockID, block.Timestamp.Time())
}
if err := <-errc; err != nil {
log.Fatal(err)
}
Testnet
client := hivego.NewClient("https://testnet.openhive.network")
client.ChainID = "18dcf0a285365fc58b71f18b3d3fec954aa0c141c44e4e5cb4cf777b9eab274e"
client.PublicKeyPrefix = "TST"
Error handling
// Sentinel errors — use errors.Is
if errors.Is(err, hivego.ErrChecksumMismatch) { ... }
if errors.Is(err, hivego.ErrInvalidAsset) { ... }
// RPC errors from the node — use errors.As
var rpcErr *hivego.RPCError
if errors.As(err, &rpcErr) {
fmt.Println(rpcErr.Code, rpcErr.Message)
}