Skip to content

Building a Trading Bot

This guide walks through building an automated trading bot from scratch. By the end, you will have a runnable script that registers an agent, creates a managed wallet, monitors token prices, and executes swaps when conditions are met.

What the Bot Does

1. Registers with the Suwappu API and saves the API key

2. Creates a managed wallet for server-side swap execution

3. Polls token prices in a loop

4. Executes a swap when a price target is hit

5. Tracks the swap status until completion

6. Handles errors and rate limits gracefully

Python Version

class=class="hl-str">"hl-comment">#!/usr/bin/env python3
class="hl-str">""class="hl-str">"
Suwappu Trading Bot — Python

Monitors ETH/USDC price on Base and buys when price drops below target.

"class="hl-str">""

import os import sys import time import requests

BASE_URL = class="hl-str">"https:class="hl-commentclass="hl-str">">//api.suwappu.bot/v1/agent"

class=class="hl-str">"hl-comment"># Configuration

CHAIN = class="hl-str">"base"

FROM_TOKEN = class="hl-str">"USDC"

TO_TOKEN = class="hl-str">"ETH"

BUY_AMOUNT = class="hl-str">"100" class=class="hl-str">"hl-comment"># Buy 100 USDC worth of ETH

PRICE_TARGET = 2000.0 class=class="hl-str">"hl-comment"># Buy when ETH drops below $2000

POLL_INTERVAL = 30 class=class="hl-str">"hl-comment"># Check price every 30 seconds

MAX_RETRIES = 3 class=class="hl-str">"hl-comment"># Retry failed requests up to 3 times

def register_agent():

class="hl-str">""class="hl-str">"Register a new agent and return the API key."class="hl-str">""

response = requests.post(

fclass="hl-str">"{BASE_URL}/register",

json={class="hl-str">"name": fclass="hl-str">"trading-bot-{int(time.time())}"},

)

response.raise_for_status()

data = response.json()

api_key = data[class="hl-str">"agent"][class="hl-str">"api_key"]

print(fclass="hl-str">"Registered agent: {data[class="hl-str">'agent'][class="hl-str">'name']}")

print(fclass="hl-str">"API key: {api_key[:20]}...")

return api_key

def create_wallet(headers):

class="hl-str">""class="hl-str">"Create a managed wallet for swap execution."class="hl-str">""

response = requests.post(fclass="hl-str">"{BASE_URL}/wallets", headers=headers)

response.raise_for_status()

wallet = response.json()[class="hl-str">"wallet"]

print(fclass="hl-str">"Wallet created: {wallet[class="hl-str">'address']}")

print(fclass="hl-str">"Chain type: {wallet[class="hl-str">'chain_type']}")

print(fclass="hl-str">"Fund this wallet with {FROM_TOKEN} on {CHAIN} to start trading.")

return wallet[class="hl-str">"address"]

def get_price(headers, token, chain):

class="hl-str">""class="hl-str">"Fetch the current USD price for a token."class="hl-str">""

response = requests.get(

fclass="hl-str">"{BASE_URL}/prices",

headers=headers,

params={class="hl-str">"token": token, class="hl-str">"chain": chain},

)

response.raise_for_status()

return float(response.json()[class="hl-str">"price_usd"])

def execute_swap(headers, from_token, to_token, amount, chain):

class="hl-str">""class="hl-str">"Get a quote and execute a swap. Returns the swap ID."class="hl-str">""

class=class="hl-str">"hl-comment"># Step 1: Get a quote

quote_response = requests.post(

fclass="hl-str">"{BASE_URL}/quote",

headers=headers,

json={

class="hl-str">"from_token": from_token,

class="hl-str">"to_token": to_token,

class="hl-str">"amount": amount,

class="hl-str">"chain": chain,

},

)

quote_response.raise_for_status()

quote = quote_response.json()

print(fclass="hl-str">"Quote: {amount} {from_token} -> {quote[class="hl-str">'expected_output']} {to_token}")

class=class="hl-str">"hl-comment"># Step 2: Execute

swap_response = requests.post(

fclass="hl-str">"{BASE_URL}/swap/execute",

headers=headers,

json={class="hl-str">"quote_id": quote[class="hl-str">"quote_id"]},

)

swap_response.raise_for_status()

swap = swap_response.json()

print(fclass="hl-str">"Swap submitted: ID {swap[class="hl-str">'swap_id']}, tx: {swap.get(class="hl-str">'tx_hash', class="hl-str">'pending')}")

return swap[class="hl-str">"swap_id"]

def wait_for_completion(headers, swap_id):

class="hl-str">""class="hl-str">"Poll swap status until it completes or fails."class="hl-str">""

while True:

response = requests.get(

fclass="hl-str">"{BASE_URL}/swap/status/{swap_id}",

headers=headers,

)

response.raise_for_status()

status = response.json()

print(fclass="hl-str">" Swap {swap_id}: {status[class="hl-str">'status']}")

if status[class="hl-str">"status"] == class="hl-str">"completed":

print(fclass="hl-str">" Completed! TX: {status[class="hl-str">'tx_hash']}")

return True

elif status[class="hl-str">"status"] == class="hl-str">"failed":

print(fclass="hl-str">" Failed.")

return False

time.sleep(5)

def main():

class=class="hl-str">"hl-comment"># Use existing API key or register a new agent

api_key = os.environ.get(class="hl-str">"SUWAPPU_API_KEY")

if not api_key:

print(class="hl-str">"No SUWAPPU_API_KEY found. Registering new agent...")

api_key = register_agent()

print(fclass="hl-str">"\nSet this for future runs:")

print(fclass="hl-str">" export SUWAPPU_API_KEY={api_key}\n")

headers = {class="hl-str">"Authorization": fclass="hl-str">"Bearer {api_key}"}

class=class="hl-str">"hl-comment"># Check for existing wallets or create one

wallets = requests.get(fclass="hl-str">"{BASE_URL}/wallets", headers=headers).json()

if not wallets.get(class="hl-str">"wallets"):

print(class="hl-str">"No wallets found. Creating one...")

address = create_wallet(headers)

print(fclass="hl-str">"\nFund {address} with {FROM_TOKEN} on {CHAIN}, then restart.\n")

sys.exit(0)

else:

address = wallets[class="hl-str">"wallets"][0][class="hl-str">"address"]

print(fclass="hl-str">"Using wallet: {address}")

class=class="hl-str">"hl-comment"># Price monitoring loop

print(fclass="hl-str">"\nMonitoring {TO_TOKEN} price on {CHAIN}...")

print(fclass="hl-str">"Will buy {BUY_AMOUNT} {FROM_TOKEN} worth of {TO_TOKEN} when price < ${PRICE_TARGET}")

print(fclass="hl-str">"Checking every {POLL_INTERVAL}s. Press Ctrl+C to stop.\n")

retries = 0

while True:

try:

price = get_price(headers, TO_TOKEN, CHAIN)

print(fclass="hl-str">"{TO_TOKEN}: ${price:.2f}", end=class="hl-str">"")

if price < PRICE_TARGET:

print(fclass="hl-str">" < ${PRICE_TARGET} -- BUYING!")

swap_id = execute_swap(

headers, FROM_TOKEN, TO_TOKEN, BUY_AMOUNT, CHAIN

)

success = wait_for_completion(headers, swap_id)

if success:

print(class="hl-str">"Trade executed successfully.")

else:

print(class="hl-str">"Trade failed. Will retry on next signal.")

else:

print(fclass="hl-str">" (target: < ${PRICE_TARGET})")

retries = 0 class=class="hl-str">"hl-comment"># Reset retries on success

except requests.exceptions.HTTPError as e:

if e.response.status_code == 429:

retries += 1

wait = min(60, POLL_INTERVAL * retries)

print(fclass="hl-str">"Rate limited. Waiting {wait}s... (retry {retries}/{MAX_RETRIES})")

time.sleep(wait)

if retries >= MAX_RETRIES:

print(class="hl-str">"Max retries reached. Exiting.")

sys.exit(1)

continue

else:

print(fclass="hl-str">"HTTP error: {e}")

retries += 1

if retries >= MAX_RETRIES:

print(class="hl-str">"Max retries reached. Exiting.")

sys.exit(1)

except KeyboardInterrupt:

print(class="hl-str">"\nStopped.")

sys.exit(0)

except Exception as e:

print(fclass="hl-str">"Error: {e}")

retries += 1

if retries >= MAX_RETRIES:

print(class="hl-str">"Max retries reached. Exiting.")

sys.exit(1)

time.sleep(POLL_INTERVAL)

if __name__ == class="hl-str">"__main__":

main()

Running the Python Bot

-str">"hl-comment"># Install dependencies
-kw">pip install requests

-str">"hl-comment"># First run: registers agent and creates wallet

python trading_bot.py

-str">"hl-comment"># Set the API key for future runs -kw">export SUWAPPU_API_KEY=suwappu_sk_your_api_key -str">"hl-comment"># Fund the wallet address printed above, then run again

python trading_bot.py

---

TypeScript Version

class=class="hl-str">"hl-comment">#!/usr/bin/env npx tsx

/**

* Suwappu Trading Bot — TypeScript

* Monitors ETH/USDC price on Base and buys when price drops below target.

*/

const BASE_URL = class="hl-str">"https:class="hl-commentclass="hl-str">">//api.suwappu.bot/v1/agent"; class=class="hl-str">"hl-comment">// Configuration const CHAIN = class="hl-str">"base"; const FROM_TOKEN = class="hl-str">"USDC"; const TO_TOKEN = class="hl-str">"ETH"; const BUY_AMOUNT = class="hl-str">"100"; const PRICE_TARGET = 2000.0; const POLL_INTERVAL = 30_000; class=class="hl-str">"hl-comment">// 30 seconds const MAX_RETRIES = 3; const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); async function api(

path: string,

options: RequestInit & { params?: Record<string, string> } = {},

apiKey?: string

) {

const { params, ...fetchOptions } = options;

let url = ${BASE_URL}${path};

if (params) url += ?${new URLSearchParams(params)};

const headers: Record<string, string> = {

class="hl-str">"Content-Type": class="hl-str">"application/json",

...(options.headers as Record<string, string>),

};

if (apiKey) headers.Authorization = Bearer ${apiKey};

const response = await fetch(url, { ...fetchOptions, headers });

if (!response.ok) {

const text = await response.text();

throw new Error(HTTP ${response.status}: ${text});

}

if (response.status === 204) return {};

return response.json();

}

async function registerAgent(): Promise<string> {

const data = await api(class="hl-str">"/register", {

method: class="hl-str">"POST",

body: JSON.stringify({ name: trading-bot-${Date.now()} }),

});

const apiKey = data.agent.api_key;

console.log(Registered agent: ${data.agent.name});

console.log(API key: ${apiKey.slice(0, 20)}...);

return apiKey;

}

async function createWallet(apiKey: string): Promise<string> {

const data = await api(class="hl-str">"/wallets", { method: class="hl-str">"POST" }, apiKey);

const wallet = data.wallet;

console.log(Wallet created: ${wallet.address});

console.log(Chain type: ${wallet.chain_type});

console.log(Fund this wallet with ${FROM_TOKEN} on ${CHAIN} to start trading.);

return wallet.address;

}

async function getPrice(apiKey: string, token: string, chain: string): Promise<number> {

const data = await api(class="hl-str">"/prices", { params: { token, chain } }, apiKey);

return parseFloat(data.price_usd);

}

async function executeSwap(

apiKey: string,

fromToken: string,

toToken: string,

amount: string,

chain: string

): Promise<number> {

class=class="hl-str">"hl-comment">// Get a quote

const quote = await api(

class="hl-str">"/quote",

{

method: class="hl-str">"POST",

body: JSON.stringify({

from_token: fromToken,

to_token: toToken,

amount,

chain,

}),

},

apiKey

);

console.log(Quote: ${amount} ${fromToken} -> ${quote.expected_output} ${toToken});

class=class="hl-str">"hl-comment">// Execute

const swap = await api(

class="hl-str">"/swap/execute",

{

method: class="hl-str">"POST",

body: JSON.stringify({ quote_id: quote.quote_id }),

},

apiKey

);

console.log(Swap submitted: ID ${swap.swap_id}, tx: ${swap.tx_hash ?? class="hl-str">"pending"});

return swap.swap_id;

}

async function waitForCompletion(apiKey: string, swapId: number): Promise<boolean> {

while (true) {

const status = await api(/swap/status/${swapId}, {}, apiKey);

console.log( Swap ${swapId}: ${status.status});

if (status.status === class="hl-str">"completed") {

console.log( Completed! TX: ${status.tx_hash});

return true;

}

if (status.status === class="hl-str">"failed") {

console.log( Failed.);

return false;

}

await sleep(5000);

}

}

async function main() {

class=class="hl-str">"hl-comment">// Use existing API key or register a new agent

let apiKey = process.env.SUWAPPU_API_KEY;

if (!apiKey) {

console.log(class="hl-str">"No SUWAPPU_API_KEY found. Registering new agent...");

apiKey = await registerAgent();

console.log(\nSet this for future runs:);

console.log( export SUWAPPU_API_KEY=${apiKey}\n);

}

class=class="hl-str">"hl-comment">// Check for existing wallets or create one

const walletData = await api(class="hl-str">"/wallets", {}, apiKey);

if (!walletData.wallets?.length) {

console.log(class="hl-str">"No wallets found. Creating one...");

const address = await createWallet(apiKey);

console.log(\nFund ${address} with ${FROM_TOKEN} on ${CHAIN}, then restart.\n);

process.exit(0);

}

const address = walletData.wallets[0].address;

console.log(Using wallet: ${address});

class=class="hl-str">"hl-comment">// Price monitoring loop

console.log(\nMonitoring ${TO_TOKEN} price on ${CHAIN}...);

console.log(

Will buy ${BUY_AMOUNT} ${FROM_TOKEN} worth of ${TO_TOKEN} when price < $${PRICE_TARGET}

);

console.log(Checking every ${POLL_INTERVAL / 1000}s. Press Ctrl+C to stop.\n);

let retries = 0;

while (true) {

try {

const price = await getPrice(apiKey, TO_TOKEN, CHAIN);

process.stdout.write(${TO_TOKEN}: $${price.toFixed(2)});

if (price < PRICE_TARGET) {

console.log( < $${PRICE_TARGET} -- BUYING!);

const swapId = await executeSwap(apiKey, FROM_TOKEN, TO_TOKEN, BUY_AMOUNT, CHAIN);

const success = await waitForCompletion(apiKey, swapId);

console.log(success ? class="hl-str">"Trade executed successfully." : class="hl-str">"Trade failed. Will retry.");

} else {

console.log( (target: < $${PRICE_TARGET}));

}

retries = 0;

} catch (error: unknown) {

const message = error instanceof Error ? error.message : String(error);

if (message.includes(class="hl-str">"429")) {

retries++;

const wait = Math.min(60_000, POLL_INTERVAL * retries);

console.log(Rate limited. Waiting ${wait / 1000}s... (retry ${retries}/${MAX_RETRIES}));

await sleep(wait);

if (retries >= MAX_RETRIES) {

console.log(class="hl-str">"Max retries reached. Exiting.");

process.exit(1);

}

continue;

}

console.error(Error: ${message});

retries++;

if (retries >= MAX_RETRIES) {

console.log(class="hl-str">"Max retries reached. Exiting.");

process.exit(1);

}

}

await sleep(POLL_INTERVAL);

}

}

main().catch(console.error);

Running the TypeScript Bot

-str">"hl-comment"># Install tsx for running TypeScript directly
-kw">npm install -g tsx

-str">"hl-comment"># First run: registers agent and creates wallet

npx tsx trading_bot.ts

-str">"hl-comment"># Set the API key for future runs -kw">export SUWAPPU_API_KEY=suwappu_sk_your_api_key -str">"hl-comment"># Fund the wallet address printed above, then run again

npx tsx trading_bot.ts

---

Customizing the Bot

Different Trading Strategies

The bot above uses a simple "buy below target price" strategy. Here are ideas for modifications:

Dollar-cost averaging (DCA): Remove the price check and buy a fixed amount at regular intervals.
class=class="hl-str">"hl-comment"># Replace the price check with a simple timer

while True:

swap_id = execute_swap(headers, FROM_TOKEN, TO_TOKEN, BUY_AMOUNT, CHAIN)

wait_for_completion(headers, swap_id)

time.sleep(3600) class=class="hl-str">"hl-comment"># Buy every hour

Sell above target: Reverse the token pair and condition.
FROM_TOKEN = class="hl-str">"ETH"

TO_TOKEN = class="hl-str">"USDC"

BUY_AMOUNT = class="hl-str">"0.05"

PRICE_TARGET = 2500.0 class=class="hl-str">"hl-comment"># Sell when ETH is above $2500

class=class="hl-str">"hl-comment"># In the loop: if price > PRICE_TARGET:

execute_swap(...)

Multi-chain monitoring: Check prices across different chains and swap where the best rate is.

Error Handling Tips

  • Rate limits: The bot handles 429 responses with exponential backoff. The standard tier allows 60 requests per minute.
  • Quote expiration: Quotes expire after a few minutes. The bot gets a fresh quote before each swap.
  • Network errors: Transient failures (timeouts, 500s) are retried up to MAX_RETRIES times before exiting.
  • Insufficient balance: If your wallet does not have enough tokens, the swap execution will fail. Check your wallet balance before trading.