Skip to content

feat(hive): serialize limit_order_create / limit_order_cancel#373

Merged
BitHighlander merged 1 commit into
developfrom
feat/hive-limit-order-serializer
Jul 20, 2026
Merged

feat(hive): serialize limit_order_create / limit_order_cancel#373
BitHighlander merged 1 commit into
developfrom
feat/hive-limit-order-serializer

Conversation

@BitHighlander

Copy link
Copy Markdown
Collaborator

Last link in the Hive internal-market swap chain. Firmware clear-signs both ops (keepkey-firmware #315), but the vault had no serializer for them, so a dApp swap died at hive_broadcast with:

Error: Operation not in the KeepKey clear-sign table (got limit_order_create)

Wire format

Mirrors the firmware parser byte-for-byte:

limit_order_create (5, active): varint(5) str(owner) u32le(orderid)
  asset(amount_to_sell) asset(min_to_receive) u8(fill_or_kill) u32le(expiration)
limit_order_cancel (6, active): varint(6) str(owner) u32le(orderid)

Host-side rejections

The firmware rejects these; mirrored here so the user sees a real message instead of a device reject: same symbol on both sides, either amount zero, a symbol other than HIVE/HBD (VESTS never trades on the internal market), fill_or_kill that isn't a boolean. Active tier, so the existing mixed-tier guard already blocks sharing a tx with posting ops.

expiration is deliberately unbounded — the device has no RTC, and a stale or far-future value costs an on-chain rejection, not a bad signature.

Tests

11 new cases in hive-ops.test.ts, vectors taken from the firmware unit tests (Hive.LimitOrderCreateRetainsEveryDisplayedField, Hive.LimitOrderRejectsDegenerateOrders, Hive.LimitOrderCancelParses). Expected bytes are hand-built in the test from the condenser layout, so a serializer bug can't cancel out against itself. 41/41 pass.

Requires firmware >= the release cut from #315.

🤖 Generated with Claude Code

Unblocks Hive internal-market swaps. Firmware clear-signs both ops
(keepkey-firmware #315); the vault had no serializer, so hive_broadcast
failed before the request reached the device.

Byte layout mirrors the firmware parser and its unit-test vectors
(Hive.LimitOrderCreateRetainsEveryDisplayedField / LimitOrderCancelParses).
The firmware's degenerate-order rejections — same symbol on both sides,
zero amount, non-HIVE/HBD symbol, non-0/1 fill_or_kill — are mirrored
host-side so the user gets a clear error instead of a device reject.

Requires firmware >= the release cut from #315.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@BitHighlander
BitHighlander merged commit a99194c into develop Jul 20, 2026
1 check passed
@BitHighlander
BitHighlander deleted the feat/hive-limit-order-serializer branch July 20, 2026 14:47
BitHighlander added a commit that referenced this pull request Jul 20, 2026
…sion tests

keepkey-sdk had zero Hive coverage — no address getter, no sign methods —
despite the vault exposing /addresses/hive and /hive/sign-operations since
7.15.0. Adds address.hiveGetAddress and hive.hiveSignOperations, mirroring
the existing osmosis/tron/ton client blocks exactly. Scoped to what the new
tests need; sign-transfer/sign-message coverage is a separate follow-on
(see handoff-keepkey-sdk-clearsign-coverage.md).

Adds two test suites, following the tests/thorchain/ruji.js pattern (live
Vault + attached device/emulator, no mocks):

- tests/hive/phase3-ops.js — limit_order_create/cancel (fw #315, vault
  #373) sign successfully, plus the host-side degenerate-order rejections
  (same-symbol, zero-amount, VESTS-on-market, mixed-tier) fire without a
  device round-trip. Requires firmware >= rc15, the vault's hive_enabled
  setting, and live Pioneer for TaPoS header data — the endpoint is
  explicitly STAGED in rest-api.ts pending this smoke pass.
- tests/osmosis/format-amount-regression.js — send/delegate/undelegate
  still sign with amounts beyond a float's ~7 significant digits, proving
  the atof()+"%.6f" removal (fw #315) didn't break signing. Does not (and
  cannot, from the SDK) verify the OLED renders the exact digits — that's
  Gate-3 OLED proof, still owed.

lib/*.js and openapi/swagger.json are the rebuilt output (npm run build);
src/ is the source of truth.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant