Getting Started
Four steps stand between you and your first quote: depositing USDC.e onto Polygon, deploying a wallet, granting token approvals to the exchange contracts, and generating API credentials.
Step 1: Deposit USDC.e
Section titled “Step 1: Deposit USDC.e”Openfish markets settle in USDC.e (bridged USDC) on Polygon. Load your trading wallet using whichever method fits your workflow.
| Method | Best For |
|---|---|
| Bridge API | Automated deposits from Ethereum or other chains |
| Direct Polygon transfer | You already hold USDC.e on Polygon |
| Cross-chain bridge | Large deposits from Ethereum mainnet |
Step 2: Deploy a Wallet
Section titled “Step 2: Deploy a Wallet”A standard Ethereum externally owned account. You pay gas for all on-chain operations (approvals, splits, merges, settlement).
Safe Wallet
Section titled “Safe Wallet”A Gnosis Safe deployed via the Openfish relayer. Benefits include gasless transactions for on-chain operations and support for batched calls.
Deploy a Safe wallet with the Rust SDK:
use openfish_client_sdk::wallet::deploy_safe;
let safe_address = deploy_safe(&relayer_client, &signer).await?;println!("Safe deployed at: {safe_address:#x}");Step 3: Approve Tokens
Section titled “Step 3: Approve Tokens”The exchange contracts need permission to move your tokens before you can trade.
Required Approvals
Section titled “Required Approvals”| Token | Spender | Purpose |
|---|---|---|
| USDC.e | CTF Contract | Split USDC.e into outcome tokens |
| CTF (outcome tokens) | CTF Exchange | Trade on standard markets |
| CTF (outcome tokens) | Neg Risk CTF Exchange | Trade on negative risk markets |
Contract Addresses
Section titled “Contract Addresses”// All contracts live on Polygon mainnet (chain ID 137).const USDC_E: &str = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";const CTF: &str = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045";const CTF_EXCHANGE: &str = "0xA642f9165D192Ff13b1D43a0Ef56B3BD074614bB";const NEG_RISK_EXCHANGE: &str = "0x700eaF3f3FEb1D3f2aE67000e1A4FA41a6E35DF1";const NEG_RISK_ADAPTER: &str = "0x0d8FA66CFe5D5EF96D6be9C4e808BD4279527d6e";Approve via the SDK
Section titled “Approve via the SDK”use openfish_client_sdk::{POLYGON, contract_config};use openfish_client_sdk::ctf::Client as CtfClient;
let config = contract_config(POLYGON, false).expect("polygon config");
// Approve USDC.e for the CTF contract (splitting)ctf_client.approve_erc20(config.collateral, config.conditional_tokens, u256::MAX).await?;
// Approve outcome tokens for the CTF Exchange (trading)ctf_client.approve_for_all(config.conditional_tokens, config.exchange).await?;
// For negative risk markets, also approve the Neg Risk Exchangelet neg = contract_config(POLYGON, true).expect("neg risk config");ctf_client.approve_for_all(neg.conditional_tokens, neg.exchange).await?;Step 4: Generate API Credentials
Section titled “Step 4: Generate API Credentials”Authenticated CLOB endpoints rely on L2 API credentials derived from a wallet signature.
use openfish_client_sdk::clob::{Client, Config};use openfish_client_sdk::auth::{LocalSigner, Signer};use std::str::FromStr;
let private_key = std::env::var("OPENFISH_PRIVATE_KEY")?;let signer = LocalSigner::from_str(&private_key)? .with_chain_id(Some(openfish_client_sdk::POLYGON));
let client = Client::new("https://api.openfish.fun", Config::default())? .authentication_builder(&signer) .authenticate() .await?;// The client now holds your API key, secret, and passphrase internally.Persist credentials in environment variables — never check them into version control.
export OPENFISH_PRIVATE_KEY="0x..."export OPENFISH_API_KEY="..."export OPENFISH_SECRET="..."export OPENFISH_PASSPHRASE="..."Next Steps
Section titled “Next Steps”- Trading — Post limit orders and manage quotes.
- Market Data — Connect to real-time orderbook feeds.
- Inventory — Split USDC.e into outcome tokens for quoting.