0x-cli
Overview
I built 0x-cli as a demo project for 0x Labs, packaged as a terminal trading bot that drives the 0x Gasless API end to end. Instead of the usual web-app surface, the whole flow lives inside the shell: a single start command from commander launches an interactive session, and @clack/prompts walks the user through entering a token address, private key, stop-loss, take-profit, ETH amount, and timeout, with each input bouncing through a custom validator before the engine spins up.
The trading engine is built on viem against Base mainnet using a privateKeyToAccount wallet client. On startup the engine reads the ERC-20's decimals on chain, checks Mongo for any existing incomplete order against that token (so a crashed run can be resumed mid-trade), and either continues the prior order or kicks off a fresh WETH-for-token buy by routing through the 0x service.
The 0x integration is the meat of the project. The service hits the v2 gasless price endpoint to scope the trade, then the gasless quote endpoint to fetch a signed-order envelope. From there I implemented the full Permit2 dance: when the quote reports an outstanding allowance and gasless approval is available I sign the EIP-712 approval typed data, otherwise I fall back to an on-chain approve with maxUint256. I also handle the permit2-quote path used when the user has insufficient WETH and opts to wrap ETH first, splicing the EIP-712 signature length and signature bytes onto the end of the returned transaction calldata before broadcasting via sendRawTransaction.
For the gasless submit itself I sign the trade's EIP-712 typed data with viem, split the resulting hex into r, s, v using @noble/curves/secp256k1 (with a small pad helper to fix the missing-leading-byte edge cases that bite a lot of EIP-712 implementations), wrap it with the typed-data signature type, post the bundled trade and approval to the gasless submit endpoint, and then poll gasless-status on a 3-second tick with a 5-minute timeout until the relay reports succeeded and surfaces the final transaction hash.
Once the buy lands, a TokenMonitor (an EventEmitter) polls the spot price every five seconds and emits take-profit, stop-loss, or timeout events against the user's configured thresholds. Whichever fires, the engine flips into sell mode, runs the same gasless quote-sign-submit cycle in reverse, computes realized PnL, and persists the round trip. State lives in a MongoDB schema of users, orders, and trades through mongoose, with a Docker recipe for a local Mongo container.
The terminal UX leans hard on chalk for color, @clack/prompts spinners and steps for transaction-pending feedback, and emoji status markers for buy, sell, take-profit, stop-loss, and timeout transitions. The codebase ships under Apache-2.0 as a reference implementation other developers can fork against the gasless API.