Skip to main content
hivecomb

hivecomb

Hive blockchain keys, serialization and offline transaction signing. A Python extension module written in Rust.

pip install hivecomb

Wheels are abi3, so one per platform covers CPython 3.8 and up. No Python dependencies — where beem pulled in requests, websocket-client, Click, click-shell, pycryptodomex and prettytable, this pulls in nothing.

Replacing beem in an existing program? Install hivecomb-beem instead and keep writing import beem. This package is the layer underneath it.


Signing needs no network

A transaction needs exactly two things from outside itself: the chain id, which is a compile-time constant, and a recent block reference, which stays valid far longer than any submit window. So the signing key never has to live on a machine that talks to a node.

import hivecomb

# The only input from the chain. From any node, or carried across an air gap.
ref = hivecomb.BlockRef.from_block_id(head_block_id)

tx = hivecomb.sign_transaction(
    [("custom_json", {
        "required_auths": [],
        "required_posting_auths": ["alice"],
        "id": "my_app",
        "json": {"hello": "hive"},
    })],
    ref,
    [posting_wif],
)
# tx is the exact envelope condenser_api.broadcast_transaction wants

sign_transaction takes (operations, block_ref, wifs) and returns a dict with ref_block_num, ref_block_prefix, expiration, operations, extensions, signatures and trx_id. Pass expiration_seconds= to change the default 60s window, and chain= to sign for a testnet.

API

Keys

key = hivecomb.PrivateKey(wif)                    # WIF or 64-char hex
key = hivecomb.PrivateKey.generate()              # from the OS CSPRNG
key = hivecomb.PrivateKey.from_login("alice", "posting", master_password)

key.public_key()          # -> PublicKey
str(key.public_key())     # 'STM8...'
repr(key)                 # '<PrivateKey redacted>' — never the secret

A private key is redacted in repr(), str() and f-strings, so it cannot reach a log line or a crash report by accident. beem returned the raw scalar from __repr__.

BIP-39 mnemonics: generate_mnemonic(words=12), validate_mnemonic(phrase).

Messages

sig = hivecomb.sign_message("login challenge", wif)   # hex, same shape as beem's
hivecomb.verify_message("login challenge", sig, str(pubkey))   # -> bool
hivecomb.recover_message("login challenge", sig)               # -> the signing key

verify_message returns a bool that you must check. beem's equivalent computed the answer and discarded it.

Memos

cipher = hivecomb.encode_memo("hello", sender_memo_wif, recipient_memo_pubkey)
plain  = hivecomb.decode_memo(cipher, recipient_memo_wif)
hivecomb.is_encrypted_memo(cipher)     # leading '#'

Interoperable with Keychain, hive-js, dhive and beem: the plaintext carries the varint length prefix the rest of the ecosystem writes.

Authorities

check = hivecomb.check_authority(account["posting"], [str(pubkey)])
check["satisfied"]            # met from these keys alone
check["conclusive"]           # False => depends on accounts not looked up
check["unresolved_accounts"]  # the delegations not followed

The three-way answer matters: most active Hive accounts share posting rights with an app account, and "not from these keys alone" is not the same as "no".

Block references and TaPoS

ref = hivecomb.BlockRef.from_block_id(head_block_id)

cache = hivecomb.TaposCache(max_age_seconds=600)   # refresh out of band
cache.store_block_id(head_block_id)
ref = cache.block_ref()                            # raises once stale

Wallet

w = hivecomb.Wallet(path)
w.create(passphrase); w.unlock(passphrase)
w.add_key(wif); w.get_key(str(pubkey))

scrypt for the key derivation, AES-256-GCM for the contents — authenticated, so a tampered file fails to open rather than decrypting to garbage.

Hive-Engine and other sidechains

A Hive-Engine operation is a custom_json, so signing one needs nothing this library does not already do:

tx = hivecomb.sign_transaction(
    [("custom_json", {
        "required_auths": ["alice"],        # see the note below
        "required_posting_auths": [],
        "id": "ssc-mainnet-hive",
        "json": {
            "contractName": "tokens",
            "contractAction": "transfer",
            "contractPayload": {
                "symbol": "BEE",
                "to": "bob",
                "quantity": "1.234",        # a decimal string, never a float
                "memo": "",
            },
        },
    })],
    ref, [active_wif],
)

Two things are easy to get wrong, and neither is something Hive will tell you about.

The authority depends on the contract action, and Hive does not check it. hived sees a custom_json and validates whatever authority you declared; the sidechain then decides which list it reads. Declare the wrong one and the transaction is accepted by Hive and quietly does nothing on Hive-Engine — no error, no rejection, just a no-op you paid resource credits for. Most actions (tokens, market, marketpools) want required_auths; several NFT actions want required_posting_auths. Take the split from a library that tracks the sidechain — nectarengine is the current one — rather than guessing.

Quantities are decimal strings at the token's precision. Not floats. 1.1 as a double is 1.100000000000000088…, and rounding that down to a token's precision can land one unit low. The token's precision comes from a Hive-Engine API call, which this library does not make.

hivecomb deliberately ships no Hive-Engine client. It is a separate chain with its own nodes and its own contract schema, on its own release schedule — the same reason there is no HAF client. What it does is sign the custom_json correctly, which is the part where a mistake costs you money.

Types, and why you should still check at runtime

The wheel ships py.typed and __init__.pyi, so a type checker resolves the module fully rather than as Any.

Stubs are not a substitute for a runtime capability check, and it is worth being precise about why. They are checked against whatever is on the path at type-check time; a capability check runs against the .so that is actually loaded. The failure they cannot catch is a stale installed build — source updated, package not reinstalled — where the checker is perfectly happy and the loaded module is old. An integrator hit exactly that state while upgrading and reported it.

So bind to __all__, which is declared explicitly and is identical however the package was installed:

REQUIRED = {"sign_transaction", "transaction_digest", "chain_id", "TaposCache"}
missing = REQUIRED - set(hivecomb.__all__)
if missing:
    raise RuntimeError(f"hivecomb is missing {missing}; is the installed build stale?")

Not dir(): Python binds a submodule on its parent at import, so a wheel-installed package also has hivecomb.hivecomb in dir() where a bare .so does not. That difference is an artifact of packaging, not of version, and it is exactly the sort of thing a capability tuple should not trip over.

__version__ is available too, but it tells you what the source claimed, not what is loaded — which is the question worth asking.

Things worth knowing

  • Amounts are exact. "50000000000.123456 VESTS" is parsed as a decimal, never through a float. beem's float() path loses digits past 2⁵³ units.
  • Timestamps are UTC, parsed strictly. hived's "never" sentinel — printed as 1969-12-31T23:59:59 — reads as None rather than a date in 1969.
  • custom_json auth lists are sorted, because hived declares them flat_set and reconstructs them sorted before checking the signature. An unsorted list yields a signature the chain will not accept.
  • Every post-HF25 operation is available, including recurrent_transfer with the HF28 pair_id, collateralized_convert and the DHF proposal operations.

How this is verified

  • Against hived itself — a node is asked to serialize each of the 48 operations and the digests are compared. 57/57 identical.
  • Against beem — 150-case differential digest corpus, 0 unexpected divergences.
  • On the live chain — a transaction signed by this library was accepted into block 109242605.

One accepted transaction is a proof, not a track record. What is and is not established is written down in BROADCAST.md.

Credit

A reimplementation of beem by Holger Nahrstaedt, which descends from python-bitshares and python-graphenelib by Fabian Schuh. The protocol knowledge is theirs. See CREDITS.md.

MIT.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hivecomb-0.1.0.tar.gz (388.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

hivecomb-0.1.0-cp38-abi3-win_amd64.whl (1.9 MB view details)

Uploaded CPython 3.8+Windows x86-64

hivecomb-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.0 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

hivecomb-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.9 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

hivecomb-0.1.0-cp38-abi3-macosx_11_0_arm64.whl (1.9 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

hivecomb-0.1.0-cp38-abi3-macosx_10_12_x86_64.whl (2.0 MB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file hivecomb-0.1.0.tar.gz.

File metadata

  • Download URL: hivecomb-0.1.0.tar.gz
  • Upload date:
  • Size: 388.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hivecomb-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3479d90b126c24dcbbd269d51d9f57c2eb668dd5618340d084088ea524d4bfb6
MD5 153ade516f9b381a1a87915df28d11d9
BLAKE2b-256 3912b335f5c9eaa3a660c12d4086109388cd1194d40a361c5f59143679d1a0b9

See more details on using hashes here.

Provenance

The following attestation bundles were made for hivecomb-0.1.0.tar.gz:

Publisher: release.yml on flosolcher/hivecomb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hivecomb-0.1.0-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: hivecomb-0.1.0-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.9 MB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hivecomb-0.1.0-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 959bdaef9690bc88389ffeda08094b14c010e1f03ddb7ed934dbdeb42eb91373
MD5 2446b388d04207be290204efd44b0fb8
BLAKE2b-256 c06197215eb87d70d266f2399a81c8936dd7ccf27941bc21bd559ace84a7ae1c

See more details on using hashes here.

Provenance

The following attestation bundles were made for hivecomb-0.1.0-cp38-abi3-win_amd64.whl:

Publisher: release.yml on flosolcher/hivecomb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hivecomb-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for hivecomb-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 785d9c1fb702d777e87f1c408c81d76ffaebed4126d65694aad80dc1a652117b
MD5 7e6c5e039024cb4f2866f906b6bc8c45
BLAKE2b-256 ed9c27d067c0b817ab642d77fab280b4131281696b2e559645528c88e38ddb3a

See more details on using hashes here.

Provenance

The following attestation bundles were made for hivecomb-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on flosolcher/hivecomb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hivecomb-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for hivecomb-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 68c0ffe5b29976737cc5797bbb12efc8bbe3ad02e4b2502b5e90d5e4712748c0
MD5 ac40107742a0d1beb99617f663d2c88e
BLAKE2b-256 f6e88356bfedf1066f50d57508e0ed1e3a957e929ae05529716f6bfe7d7caafb

See more details on using hashes here.

Provenance

The following attestation bundles were made for hivecomb-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on flosolcher/hivecomb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hivecomb-0.1.0-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for hivecomb-0.1.0-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b4b4c0259917b0ad58cd56fd999dadb4af07e48b62980e40c51dfaaa2ae284c8
MD5 b74877cc814828c89f54dd17a48fca3a
BLAKE2b-256 239e16788a679f54c97ad54801b192053f0e9de1b7512685308e8a5ca36a7cd3

See more details on using hashes here.

Provenance

The following attestation bundles were made for hivecomb-0.1.0-cp38-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on flosolcher/hivecomb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hivecomb-0.1.0-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for hivecomb-0.1.0-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 387336e20f9fd391341f2adba933e8f867416db4822c483b3425f0793ed2f225
MD5 1590b2c2bd2781032529e38efd36c8b0
BLAKE2b-256 02901a0e22b40108407dd70e94bb4319bcebe497fe07d2fb9eb2a0383945ac8c

See more details on using hashes here.

Provenance

The following attestation bundles were made for hivecomb-0.1.0-cp38-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on flosolcher/hivecomb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

6 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page