Repository navigation
[simplex]: post bids to the HyperFX orderbook, and to it alone without BRIDGE; the SDK reads bids from both - #1426
Merged
Conversation
…t BRIDGE; the SDK reads bids from both The orderbook now takes bids on swappers' orders (submitBid) and serves them under the order's commitment (bids). Simplex posts every bid there and to Hyperbridge only while the account holds BRIDGE for the deposit, read by a balance gate before each bid. Orderbook acceptance is recorded on the bid row (onOrderbook) so fills on orderbook-only bids settle against the limit order that priced them, while the retraction sweep keeps to rows with a Hyperbridge deposit. The SDK's OrderExecutor reads bids from the coprocessor and the orderbook together, merged by solver and bid id, and no longer requires a coprocessor to execute an order. The schema fixture is refreshed from hyperfx-orderbook main.
`orderbook-only-bid` restarts solver 1 on an unfunded Hyperbridge account before its book is posted, so its bid can only reach the orderbook, and passes when the order is filled by solver 1 from a bid the orderbook served and Hyperbridge never held. The swap worker points the SDK at the orderbook under test and records which solvers each venue serves whenever bids arrive.
pnpm 11.28.7 applies the workspace's `trustPolicy: no-downgrade` to the version pinned in `packageManager` before switching to it. pnpm@11.0.0 was token-published after 10.33.x had been published through trusted publishing, so every CI install on a `version: 11` runner now fails in the install step with a trust downgrade. 11.28.7 is trusted-publisher again and a frozen install under it leaves the lockfile unchanged.
seunlanlege
reviewed
Oct 22, 2026
seunlanlege
left a comment
Member
There was a problem hiding this comment.
Reviewed the full diff. The design holds up, and the orderbook-only-bid e2e shows it working on testnet: solver 1, with no BRIDGE, won from a bid only the orderbook held.
Inline comments cover:
- Should fix: the warning fires on every bid; the balance check holds up the orderbook post when the HTTP endpoint is dead; the
1010match; dashboard stats count orderbook-only bids as Failed. - Nits and one design point on retraction.
- Two requests: optional
substratePrivateKeyin simplex, and an explicitly optional coprocessor in the SDK.
Also:
- The description's "Not covered: no end-to-end test places a real bid on a running orderbook" is out of date: d228489 adds that scenario.
- The failing
livejob isgetRequestBscAmoy.test.tstiming out while the indexer was erroring. This PR doesn't touch that path.
- The BRIDGE balance gate owns the "orderbook alone" warning, so it fires once per change of answer rather than per bid; a failed balance read stands for the TTL; the orderbook post no longer waits on the balance read; Substrate's generic 1010 no longer counts as an empty balance; the pallet's InsufficientBalance pays its fee, as the docs now say. - Bid stats and `failed()` count a bid the orderbook alone holds as placed. - A bid Hyperbridge refused but the orderbook holds logs at warn. - The SDK merges bids by userOpHash, skips an orderbook bid whose op does not decode, and documents the coprocessor as optional; the docs examples create the gateway without one; the retry result carries the last attempt's error. - `simplex.substratePrivateKey` is optional: without it the solver still delegates and bids on the orderbook alone; `simplex init` and the UI wizard allow skipping it. - e2e: solver 1 runs with no key at all in `orderbook-only-bid`, and `orderbook-only-swapper` runs the SDK without a coprocessor. - The changelog states what retraction guarantees now that an orderbook bid cannot be withdrawn.
seunlanlege
approved these changes
Oct 22, 2026
seunlanlege
left a comment
Member
There was a problem hiding this comment.
All 11 points from the earlier review are addressed in 37d2dcf, including the optional substratePrivateKey and the optional coprocessor. Thanks.
Non-blocking nits, fine as a follow-up:
src/tests/core/undelegated-chains.test.ts:77: the comment still sayssetupSolverSelectionbails without a Hyperbridge connection.bid-venues.ts:49-50and the changelog say a failed read "lets the bid through"; that only holds with no prior reading, since otherwise the last reading is kept.filler.ts:300: a config withhyperbridgeWsUrlbut no key never connects, without saying so. Aninfolog ("no substratePrivateKey; bids go to the orderbook alone") would make that visible.- The
livejob'sgetRequestBscAmoy.test.tshas failed on both runs here (self-delivery got "Missing or invalid parameters", then it timed out waiting for a relayer) but passed on main on Oct 21. This PR doesn't touch that path, but it's worth a re-run before merging.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The HyperFX orderbook (main) now takes bids on swappers' orders with
submitBid(userOp)and serves them under the order's commitment withbids(commitment, leg, solver). This PR makes simplex post its bids there and the SDK read them from there.Simplex
The Hyperbridge key is optional. Without
simplex.substratePrivateKeythe solver still delegates its SolverAccount and funds the EntryPoint, and bids on the orderbook alone.simplex initand the UI wizard let it be skipped.Every bid goes to the orderbook: the same SCALE-encoded fill op Hyperbridge takes. New
OrderbookClient.submitBid;REJECTION_CODESgainsNO_LIMIT_ORDERandTOO_MANY_BIDS.Hyperbridge only while the account holds BRIDGE.
BridgeBalanceGate(src/core/bid-venues.ts) reads the free balance before a bid and lets it through while it covers one bid's cost: the pallet's storage deposit (on-chain value, else the runtime constant), the existential deposit and thepaymentInfofee. The reading stands for 30 s, is lowered after each placement, and is zeroed when Hyperbridge answersInsufficientBalance. Without BRIDGE a bid goes to the orderbook alone, logged once until the balance is back. A balance read that fails lets the bid through.FillerStrategy.executeOrder(order, bids?: BidPlacer)replaces the rawIntentsCoprocessorparameter.FillResult.success/txHash/pending/errorstay Hyperbridge's answer;FillResult.orderbookis the orderbook's.Bid store:
StoredBid.onOrderbook(SQLiteon_orderbook, added in place). Retraction and the deposit sweep keep to rows with a Hyperbridge deposit, since an orderbook bid has none and cannot be withdrawn. Fill attribution counts an orderbook-only row as a live candidate inside the same window a retracted bid gets. The dashboard shows Orderbook for a bid Hyperbridge did not take.orderExecuted.successand the activitybidrow now mean "placed on either venue". Order intake no longer refuses a solver-selection order for want of a Hyperbridge connection while an orderbook is configured.SDK
HyperFxOrderbook.bids(commitment, { leg?, solver? })returnsOrderbookBid[]with the SCALE-encodeduserOp.OrderExecutor.fetchBidsreads the coprocessor (when configured) and the gateway's orderbook together, merged by(sender, bidId); the Hyperbridge copy wins a tie. One source failing leaves the other's bids; both failing throws.FillerBid.venueis"orderbook"for a bid read there.IntentGateway.executeOrderno longer requires a coprocessor;withOrderbookalso redirects where bids are read from.Note:
sdk/packages/simplex/docs/ai/changelog/2026-10-21-bids-on-the-orderbook.md.Validation
polytope-labs/hyperfx-orderbookmain;schema.test.tsholds every document against it.https://orderbook.hyperfx.finance/testnet/graphql:bidsanswered, andsubmitBidreached op verification (BidRejected: MALFORMED_USER_OPfor a junk op).tscclean on touched files;vitest src/tests/core src/tests/data src/tests/orderbook src/tests/services→ 817 passed, 4 skipped. New tests:core/bid-venues.test.ts,core/orderbook-bids.test.ts.typecheckclean;bidSelection,orderbookSchema,orderbookMarket,intentsCoprocessorHttpFallback,phantomBidDeclarationsuites pass, including new merge tests.orderbook-only-bid(solver 1 restarted with no Hyperbridge key; passes only when the fill comes from its orderbook bid, which Hyperbridge never held) andorderbook-only-swapper(the SDK given no coprocessor, reading bids from the orderbook alone).🤖 Generated with Claude Code