Skip to main content
Hummingbot is the canonical open-source market-making framework for Python. The Python protocol SDK is the intended integration path — you import it inside a StrategyV2Base subclass and drive trades through it on every tick. Kash never sees a private key; the strategy holds the signer.

Architectural shape

Kash is on neither side of the wire. Your strategy holds the EOA signer; your RPC sees the read traffic and the signed transaction.

Reference strategy

The package ships examples/hummingbot/amm_arb_kash_uniswap.py — a working StrategyV2Base that demonstrates the canonical SDK integration pattern. Skeleton runs against Base Sepolia in EOA mode; the Uniswap leg + sizing model are stubbed for you to wire to your real venue.
The full file is at examples/hummingbot/amm_arb_kash_uniswap.py on the public mirror.

Running the strategy in Hummingbot

Resource requirements

Per active strategy: A typical 1-second tick interval generates ~2 RPS to the chain RPC and ~0.05 RPS of trade submits (assuming 5% of ticks find a profitable spread). Both well under any commercial RPC’s free tier.

Latency profile

Numbers are anecdotal — they depend on your RPC, your signer (local vs remote), and the chain’s mempool state. Use them as order-of-magnitude estimates, not SLA targets.

Observability

Every public method accepts an optional signal: asyncio.Event for cancellation. Long-running strategies should propagate Hummingbot’s shutdown signal into every SDK call so a ctrl-c cleanly aborts in-flight ops. Lifecycle hooks (KashProtocolHooks) are six fire-and-forget callbacks for telemetry / structured logging — all optional, passed on the client config:
  • on_bundler_request(BundlerRequestEvent) — before every bundler JSON-RPC call (method, url)
  • on_bundler_response(BundlerResponseEvent) — on a successful bundler response (method, url, duration_ms, status)
  • on_bundler_error(BundlerErrorEvent) — on a bundler JSON-RPC error (method, url, duration_ms, error)
  • on_signer_request(SignerRequestEvent) — before a signer adapter call (owner_address, kind: userop-hash / typed-data / transaction)
  • on_signer_error(SignerErrorEvent) — on a signer adapter failure
  • on_wait_orphaned(WaitOrphanedEvent) — a send.* call gave up waiting for inclusion (consumer aborted, or the bundler poll timed out)
Hooks are invoked via safe_fire — exceptions never propagate into the request path, and async callbacks are scheduled but never awaited. Wire these into your existing logging stack (Hummingbot’s structured log, OpenTelemetry, or whatever) without polluting the trade-path code with logging side effects. Never use hooks for control flow.

Cancellation + clean shutdown

Always close the client. Hummingbot’s on_stop is the hook:
This drains the httpx pool, closes the WebSocket subscription if any, and is idempotent — calling it twice is a no-op. The async with form does this for you in standalone scripts.

Troubleshooting

  • KashSimulationRevertedError (code SIMULATION_REVERTED) — the prepared trade will revert on-chain. The decoded revert reason lives in context["revert_reason"] (and context["decoded_error"]) — a common cause is a max_slippage_bps tighter than the market could meet. The pre-flight eth_call caught the revert before you paid for any signing-infra round-trips.
  • KashSignerError (code STALE_SIGNED_TX) — you signed a tx and then mutated its gas/fees/nonce before submit. The submit-side staleness guard recovered the signing address from the bytes, saw a mismatch, and refused to broadcast.
  • KashChainError (e.g. codes QUOTE_FAILED, MARKET_READ_FAILED, TX_SEND_FAILED) — a chain RPC call failed; often your RPC is down or rate-limiting. Back off and retry; the stable code string tells you which read/write path failed.

See also

EOA quickstart

The EOA-mode Python integration the strategy above uses.

Smart-account mode

For AA-stack Python integrations.

Cross-language parity

Same encoding bytes as the TypeScript SDK.