degenbot.dispatch¶

Companion-layer surface over the Rust dispatch/sim/signer pyclasses.

This package re-exports the Rust-owned dispatch, simulation, and transaction signing symbols under stable, seam-agnostic names. Driver code (bot operators, example bots) imports from here — never from the PyO3 wrapper module degenbot._ffi.

The Py* prefix and _py suffix on the FFI names are the seam naming itself: Py marks a raw pyclass, *_py marks a pyfunction. Those conventions are for the FFI layer’s own bookkeeping and should never leak into driver code. This package hides them.

Note

Most of these are direct alias re-exports (from degenbot._ffi import PyX as X), not Python wrapper classes. The Rust engine constructs and consumes these pyclasses / pyfunctions directly — driver code constructs a SimulateContext / TxSigner in Python and passes it to a Rust pyfunction that expects the exact SimulateContext / TxSigner pyclass. A wrapper class would break type identity at the FFI boundary.

dispatch_and_submit is the one deliberate exception: it is a thin async wrapper whose ONLY transformation is decoding the leaf’s returned record dicts into the typed records of degenbot.dispatch.records (the single home for that wire format). Call-site arguments pass to the FFI pyfunction unchanged — pyclass identity for candidates/dispatcher/signer is preserved.

Symbol map (FFI name → stable companion name):

  • CandidateAssembly → CandidateAssembly

  • DispatchCandidate → DispatchCandidate

  • DispatchOutcome → DispatchOutcome

  • Dispatcher → Dispatcher

  • SimulateContext → SimulateContext

  • TxSigner → TxSigner

  • assemble_dispatch_candidates_py → assemble_dispatch_candidates

  • build_batch_executor_py → build_batch_executor

  • dispatch_profitable_py → dispatch_profitable

  • merge_payload_results_py → merge_payload_results

  • dispatch_and_submit_py → dispatch_and_submit (wrapper: dict → typed records)

  • fetch_fee_history_py → fetch_fee_history

Submodules¶

Package Contents¶

class degenbot.dispatch.SkippedRecord¶

The candidate was skipped — detail set for BROADCAST_FAILED.

path_id: int¶
reason: SubmitSkipReason¶
detail: str | None = None¶
degenbot.dispatch.SubmitRecord¶
class degenbot.dispatch.SubmitSkipReason¶

Bases: enum.StrEnum

The typed SkipReason vocabulary of the Rust submit leaf.

POOLS_CLAIMED = 'pools_claimed'¶
DRY_RUN = 'dry_run'¶
INJECT_CODE = 'inject_code'¶
BROADCAST_FAILED = 'broadcast_failed'¶
class degenbot.dispatch.SubmittedRecord¶

The tx was broadcast — the resulting tx_hash + claimed nonce.

path_id: int¶
tx_hash: str¶
nonce: int¶
degenbot.dispatch.typed_submit_record(raw: collections.abc.Mapping[str, Any], /) → SubmitRecord¶

Decode one FFI submit-record dict into a typed record.

Returns:

The typed record.

Raises:

DegenbotValueError – On an unrecognized or missing “kind”, an unknown skip “reason”, or missing payload keys — wire drift, loud.

class degenbot.dispatch.SubmitContext¶

Per-call parameters the companion submit seam carries to the FFI leaf.

The Rust dispatch_and_submit_py pyfunction takes these as keyword arguments; grouping them here keeps the companion signature stable as the runner’s submit knobs grow. broadcast_providers is the relay fan-out (one Rust provider pyclass per endpoint), or None for the public mempool.

signer: degenbot._ffi.submission.TxSigner¶
operator_nonce: int¶
current_block: int¶
dry_run: bool¶
inject_code: bool¶
broadcast_providers: list[degenbot._ffi.provider.AsyncAlloyProvider] | None = None¶
async degenbot.dispatch.dispatch_and_submit(candidates: list[degenbot._ffi.submission.SubmitCandidate], dispatcher: degenbot._ffi.submission.Dispatcher, provider: degenbot._ffi.provider.AsyncAlloyProvider, *, context: SubmitContext, submit_leaf: collections.abc.Callable[..., Any] = _dispatch_and_submit_py) → list[records.SubmitRecord]¶

Await the Rust submit leaf and decode its records to typed values.

The FFI pyfunction returns raw dicts (a “kind” discriminator plus payloads); this companion wrapper is the single home for decoding them into SubmittedRecord / SkippedRecord — unknown wire values raise instead of dropping a submission event. context carries the per-call submit knobs through to the pyfunction unchanged; pyclass identity for candidates/dispatcher/provider/context.signer is preserved. submit_leaf is the FFI seam (tests inject a fake leaf returning raw dicts); the default is the production pyfunction.

Returns:

The typed per-candidate records, in submit order.