Skip to content

Commit bc0bbf1

Browse files
authored
feat: remove all direct RPC calls, route through Turbine API (#30)
* feat: remove all direct RPC calls, route through Turbine API Eliminates the SDK's dependency on direct blockchain RPC connections. All on-chain queries now route through the Turbine API. Changes: - _get_contract_nonce() → GET /contracts/nonce/:contract/:owner - get_usdc_balance() → GET /users/:address/balances - get_usdc_allowance() → GET /users/:address/balances - approve_usdc() → gasless permit via POST /relayer/usdc-permit - claim_winnings() → GET /users/:address/claim-data + sign + POST /relayer/ctf-redemption - batch_claim_winnings() → same pattern, batched - discover_positions() → GET /users/:address/claimable (replaces Multicall3) - Removed hardcoded Ankr RPC key from discovery.py - Removed web3 from required dependencies All method signatures remain backward compatible. The SDK no longer requires any RPC URL or web3 connection. Requires: ojo-network/turbine-clob#241 (new API endpoints) * docs: update all docs to reflect API-only SDK (no RPC/web3) - CLAUDE.md: added API-only description, updated approve_usdc to return dict, updated Gasless concept, added API routing details under the hood - create-bot/SKILL.md: updated gasless approval pattern - create-liquidity-bot/SKILL.md: updated gasless approval pattern - setup/SKILL.md: noted API-only in env var description - README.md: added API-only overview, no RPC note in credentials - docs/onboarding.md: reinforced no RPC/web3 needed
1 parent a641f01 commit bc0bbf1

File tree

9 files changed

+203
-655
lines changed

9 files changed

+203
-655
lines changed

.claude/skills/create-bot/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ After the bot is running, suggest next steps based on the user's goals (from `us
364364
365365
1. **Order verification chain:** After `post_order()`, sleep 2 seconds, then check failed trades → pending trades → recent trades → open orders. This sequence ensures the bot knows the true state of its order. Skipping steps causes phantom orders or missed fills.
366366
367-
2. **Gasless USDC approval:** One-time max EIP-2612 permit per settlement contract. Check allowance first, skip if already approved. Never do per-order approvals.
367+
2. **Gasless USDC approval:** One-time gasless permit via API per settlement contract. `approve_usdc()` returns a dict with `tx_hash` key (not a raw tx hash string). Check allowance first via API, skip if already approved. Never do per-order approvals. No web3 or RPC needed.
368368
369369
3. **Market transitions:** Poll every 5 seconds for new markets. On transition: cancel all orders on the old market, reset state (pending orders, processed trade IDs, expiration flag), approve USDC for the new settlement if needed, then resume trading.
370370

.claude/skills/create-liquidity-bot/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ After the bot is running, suggest next steps based on the user's goals:
329329
330330
**DO NOT modify these when generating bots.** They exist in `examples/market_maker.py` for a reason and must be preserved exactly:
331331
332-
1. **Gasless USDC approval:** One-time max EIP-2612 permit per settlement contract. Check allowance first, skip if already approved. Never do per-order approvals.
332+
1. **Gasless USDC approval:** One-time gasless permit via API per settlement contract. `approve_usdc()` returns a dict with `tx_hash` key (not a raw tx hash string). Check allowance first via API, skip if already approved. Never do per-order approvals. No web3 or RPC needed.
333333
334334
2. **Graceful rebalance:** Place new orders FIRST, brief pause, then cancel old ones. This ensures continuous liquidity — no gap where traders can't trade. This is critical and different from cancel-then-place.
335335

.claude/skills/setup/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ TURBINE_HOST=https://api.turbinefi.com
228228
- `TURBINE_PRIVATE_KEY` — Their wallet's signing key. Never leaves this machine.
229229
- `TURBINE_API_KEY_ID` / `TURBINE_API_PRIVATE_KEY` — Left blank intentionally. The bot auto-registers API credentials on first run and saves them back to this file.
230230
- `CHAIN_ID=137` — Polygon mainnet. This is where Turbine's active markets are.
231-
- `TURBINE_HOST` — Turbine's API endpoint.
231+
- `TURBINE_HOST` — Turbine's API endpoint. All SDK operations (approvals, claims, balance checks) route through this — no RPC URL or web3 needed.
232232

233233
---
234234

CLAUDE.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ This matters because it dramatically lowers the barrier to entry. A new user doe
4747

4848
Turbine runs an off-chain orderbook (CLOB) with on-chain settlement. Orders are signed off-chain using EIP-712, matched by Turbine's API, then settled on-chain via modified Gnosis CTF smart contracts. Market resolution is handled by the UMA Optimistic Oracle — after 15 minutes, the oracle checks BTC's price against the strike and declares a winner. The 1% flat fee per trade is the only cost.
4949

50+
**From the SDK's perspective**, everything goes through the Turbine API — there are no direct RPC or on-chain calls. USDC approvals use gasless permits via `/relayer/usdc-permit`, balance/allowance checks go through `/users/:address/balances`, claims go through `/users/:address/claim-data` + the relayer, and contract nonces come from `/contracts/nonce/:contract/:owner`.
51+
5052
### Competitions and Hackathons
5153

5254
Turbine is actively growing its user base through two channels:
@@ -61,6 +63,8 @@ Turbine is actively growing its user base through two channels:
6163

6264
This is the official Python SDK for Turbine's API, bundled with example trading bots and Claude Code skills for bot generation. It exists to get people trading on Turbine as fast as possible.
6365

66+
**The SDK is fully API-routed** — all operations go through `api.turbinefi.com`. There is no RPC URL, no web3 dependency, and no direct blockchain node access required. Users only need a private key, chain ID, and the API host.
67+
6468
**Why it exists:** Turbine is a prediction markets platform, but a platform without traders is empty. This repo is the primary onboarding funnel — it's how new users go from "curious" to "actively trading." The easier it is to clone this repo, build a bot, and start competing, the more traders Turbine gets.
6569

6670
The typical user journey:
@@ -213,7 +217,7 @@ When a user wants to create or modify a bot:
213217

214218
4. **Preserve critical infrastructure patterns.** These exist in every working bot and must not be removed or altered:
215219
- **Order verification chain:** After submitting an order, wait 2 seconds, then check failed trades → pending trades → recent trades → open orders. This sequence ensures the bot knows the true state of its order.
216-
- **Gasless USDC approval:** One-time max EIP-2612 permit per settlement contract. Check allowance first, skip if already approved.
220+
- **Gasless USDC approval:** One-time gasless permit via API per settlement contract. `approve_usdc()` returns a dict with `tx_hash` (not a raw tx hash string). Check allowance first via API, skip if already approved.
217221
- **Market transitions:** Poll for new markets every 5 seconds. When a new market appears, cancel all orders on the old market, reset state, and start trading the new one.
218222
- **Claiming:** Background task that checks for resolved markets and claims winnings via the gasless relayer. Enforce a 15-second delay between claims (API rate limit).
219223
- **Market expiration:** Stop placing new orders when less than 60 seconds remain in a market. The `market_expiring` flag prevents the bot from getting stuck with orders on an expired market.
@@ -255,7 +259,7 @@ client.get_user_positions(address) # Current positions
255259
client.get_orders(trader) # Open orders
256260

257261
# Gasless relayer operations
258-
client.approve_usdc_for_settlement(addr) # One-time max USDC permit (gasless)
262+
client.approve_usdc_for_settlement(addr) # One-time gasless permit via API (returns dict with tx_hash)
259263
client.claim_winnings(contract_addr) # Claim from a resolved market (gasless)
260264
client.batch_claim_winnings(addrs) # Claim from multiple markets at once
261265
```
@@ -275,8 +279,8 @@ For a deeper explanation aimed at newcomers, see `docs/prediction-markets.md`.
275279
- **Strike price:** The BTC price threshold set when the market opens. If BTC ends above it, YES wins. Below, NO wins. This is the anchor that every trading decision revolves around.
276280
- **Settlement address:** The on-chain contract that holds USDC collateral and executes trades. There's one per chain, shared across all markets. Requires a one-time gasless approval before the bot can trade.
277281
- **Contract address:** A per-market contract for outcome tokens (ERC1155). Only needed when claiming winnings after a market resolves — not during trading.
278-
- **Gasless:** Turbine's relayer pays all gas fees. Users sign messages with their private key (free, off-chain), and the relayer handles on-chain submission. This is why users only need USDC — no ETH, MATIC, or AVAX.
279-
- **USDC approval:** A one-time max EIP-2612 permit per settlement contract. Once approved, all future orders on that chain reuse the allowance. No per-trade approval overhead.
282+
- **Gasless:** The SDK is fully API-routed — all operations (approvals, claims, balance checks) go through Turbine's API, which handles on-chain submission via a relayer. Users sign messages with their private key (free, off-chain) and never need RPC access, web3, or native gas tokens (no ETH, MATIC, or AVAX). Only USDC is needed.
283+
- **USDC approval:** A one-time gasless EIP-2612 permit via the API's `/relayer/usdc-permit` endpoint. Returns a dict with `tx_hash`. Once approved, all future orders on that chain reuse the allowance. No per-trade approval overhead.
280284
- **UMA Oracle:** The decentralized oracle that resolves markets. After a market expires, UMA checks BTC's price and declares whether YES or NO wins. This is trustless — no single party controls the outcome.
281285
- **Pyth Network:** Provides real-time BTC price data. This is the same feed Turbine uses for market resolution, which is why the Price Action strategy (which trades based on Pyth data) is recommended — the bot's signal aligns with how winners are determined.
282286

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ This client provides a clean, typed interface for:
3737
- Submitting orders to the Turbine orderbook
3838
- Managing positions and tracking fills
3939
- Subscribing to real-time orderbook updates via WebSocket
40+
- Gasless USDC approvals and claiming winnings via API relayer
41+
42+
**Fully API-routed** — no RPC URL, web3 dependency, or blockchain node access required. Everything goes through `api.turbinefi.com`.
4043

4144
## Table of Contents
4245

@@ -80,6 +83,8 @@ To trade on Turbine, you need:
8083
2. **API Key ID** - Identifier for your API key
8184
3. **API Private Key** - Ed25519 private key for authenticating API requests
8285

86+
No RPC URL or native gas tokens are required. The SDK routes all operations through the Turbine API.
87+
8388
### Self-Service Registration
8489

8590
You can register for API credentials directly using your wallet:
@@ -385,7 +390,7 @@ print(f"Current BTC: ${price.price}")
385390

386391
## Claiming Winnings
387392

388-
After a market resolves, you can claim your winnings using gasless permits (no gas required).
393+
After a market resolves, you can claim your winnings via the API's gasless relayer (no RPC or gas tokens required).
389394

390395
### Single Market
391396

docs/onboarding.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ TURBINE_HOST=https://api.turbinefi.com
6565
- `TURBINE_PRIVATE_KEY` — Your wallet's signing key. Used locally to sign transactions.
6666
- `TURBINE_API_KEY_ID` / `TURBINE_API_PRIVATE_KEY` — Leave blank. The bot auto-registers API credentials on first run and fills these in.
6767
- `CHAIN_ID=137` — Polygon mainnet, where Turbine's active markets are.
68-
- `TURBINE_HOST` — Turbine's API endpoint.
68+
- `TURBINE_HOST` — Turbine's API endpoint. All SDK operations route through this — no RPC URL or web3 needed.
6969

7070
## 4. Fund Your Wallet
7171

@@ -111,7 +111,7 @@ python price_action_bot.py
111111
### What happens on first run
112112

113113
1. **API credentials register** — the bot signs a message with your wallet, gets API keys, and saves them to `.env`
114-
2. **USDC approval** — a one-time gasless permit is signed to allow trading
114+
2. **USDC approval** — a one-time gasless permit is signed via the API (no RPC or gas tokens needed)
115115
3. **Trading starts** — the bot fetches the current BTC market, runs its strategy, and places trades
116116
4. **Market rotation** — every 15 minutes the market expires and a new one opens. The bot switches automatically.
117117
5. **Claiming** — the bot claims winnings from resolved markets in the background

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ dependencies = [
3030
"eth-account>=0.13.0",
3131
"eth-utils>=4.1.1",
3232
"httpx[http2]>=0.27.0",
33-
"web3>=6.0.0",
3433
"websockets>=12.0",
3534
"pynacl>=1.5.0",
3635
"python-dotenv>=1.0.0",

0 commit comments

Comments
 (0)