Trading SDK
The Trading SDK is the highest-level SDK in the Swarm Collection. It combines the Market Maker and Cross-Chain Access platforms into a single, intelligent interface — automatically selecting the best price, with built-in fallback if a platform is unavailable.
Use this when you want: automatic price optimisation, fallback protection, and a single trade() method that works across all platforms.
Advantages over individual SDKs
| Feature | Trading SDK | Market Maker SDK | Cross-Chain Access SDK |
|---|---|---|---|
| Smart routing | ✅ Automatic | ❌ Manual | ❌ Manual |
| Price comparison | ✅ Real-time | ❌ No | ❌ No |
| Auto fallback | ✅ Built-in | ❌ No | ❌ No |
| 24/7 availability | ✅ Via Market Maker | ✅ Yes | ❌ Market hours only |
| Best price guarantee | ✅ Compares both | ❌ Single platform | ❌ Single platform |
| Unified interface | ✅ One method | ❌ Separate | ❌ Separate |
Trade-offs: The Trading SDK does not support creating or cancelling offers (those are Market Maker-specific features). Use the Market Maker SDK directly if you need to provide liquidity.
Prerequisites
- Python 3.8+
- A wallet with a private key and gas tokens
- An RPQ API Key — for Market Maker quotes
- A user email — for Cross-Chain Access
- KYC verification at https://dotc.eth.limo/ — for Cross-Chain Access
The Trading SDK works even if only one platform is available. If you have not completed KYC, it will automatically use Market Maker only.
Initialising the client
from swarm.trading_sdk import TradingClient, RoutingStrategy
from swarm.shared.models import Network
async with TradingClient(
network=Network.POLYGON,
private_key="0x...",
rpq_api_key="your_rpq_key",
user_email="you@example.com",
routing_strategy=RoutingStrategy.BEST_PRICE # default
) as client:
# Ready to trade
pass
Always use the async with pattern — it handles authentication and cleanup automatically.
Constructor parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| network | Network | ✅ | Blockchain network (e.g. Network.POLYGON) |
| private_key | str | ✅ | Wallet private key (with 0x prefix) |
| rpq_api_key | str | ✅ | API key for Market Maker RPQ Service |
| user_email | str | ❌ | Email for Cross-Chain Access (recommended) |
| rpc_url | str | ❌ | Custom RPC endpoint |
| routing_strategy | RoutingStrategy | ❌ | Default routing strategy (default: BEST_PRICE) |
Routing strategies
Choose from five strategies to control how the SDK selects a platform:
| Strategy | Compares prices? | Has fallback? | Best for |
|---|---|---|---|
| BEST_PRICE | ✅ Yes | ✅ Yes | Optimal pricing — recommended |
| CROSS_CHAIN_ACCESS_FIRST | ❌ No | ✅ Yes | Stock market preference with P2P fallback |
| MARKET_MAKER_FIRST | ❌ No | ✅ Yes | P2P preference with stock market fallback |
| CROSS_CHAIN_ACCESS_ONLY | ❌ No | ❌ No | Stock market only, fail if unavailable |
| MARKET_MAKER_ONLY | ❌ No | ❌ No | P2P only, fail if unavailable |
from swarm.trading_sdk import RoutingStrategy
RoutingStrategy.BEST_PRICE # Recommended
RoutingStrategy.CROSS_CHAIN_ACCESS_FIRST
RoutingStrategy.MARKET_MAKER_FIRST
RoutingStrategy.CROSS_CHAIN_ACCESS_ONLY
RoutingStrategy.MARKET_MAKER_ONLY
How BEST_PRICE works:
- Fetches quotes from both platforms in parallel
- For buy orders: selects the platform offering more tokens per USDC (lower rate)
- For sell orders: selects the platform offering more USDC per token (higher rate)
- Falls back to the alternative platform if the primary trade fails
Getting quotes
Compare prices across both platforms before trading:
from decimal import Decimal
async with TradingClient(...) as client:
quotes = await client.get_quotes(
from_token="0xUSDC...",
to_token="0xRWA...",
from_amount=Decimal("100"),
to_token_symbol="AAPL" # required for Cross-Chain Access
)
if quotes["market_maker"]:
print(f"Market Maker: ${quotes['market_maker'].rate}")
if quotes["cross_chain_access"]:
print(f"Cross-Chain Access: ${quotes['cross_chain_access'].rate}")
Returns {"market_maker": Quote | None, "cross_chain_access": Quote | None}. This method never raises — unavailable platforms return None.
Executing a trade
from decimal import Decimal
async with TradingClient(
network=Network.POLYGON,
private_key="0x...",
rpq_api_key="your_key",
user_email="you@example.com"
) as client:
result = await client.trade(
from_token="0xUSDC...",
to_token="0xRWA...",
from_amount=Decimal("100"), # spend 100 USDC
to_token_symbol="AAPL",
user_email="you@example.com"
)
print(f"Platform used: {result.source}")
print(f"TX Hash: {result.tx_hash}")
print(f"Spent: {result.sell_amount} USDC")
print(f"Received: {result.buy_amount} AAPL")
print(f"Rate: ${result.rate}")
Specify sell amount or buy amount — not both:
# Option 1: specify how much to spend
result = await client.trade(from_amount=Decimal("100"), ...)
# Option 2: specify how much to receive
result = await client.trade(to_amount=Decimal("10"), ...)
Override routing strategy per trade:
result = await client.trade(
...,
routing_strategy=RoutingStrategy.MARKET_MAKER_ONLY
)
What happens behind the scenes:
- Quotes fetched from both platforms in parallel
- Router selects optimal platform based on strategy
- Tokens approved and trade submitted on-chain
- If primary platform fails (and strategy allows), fallback is attempted automatically
- Returns
TradeResultor raises an exception
Error handling
from swarm.trading_sdk.exceptions import (
TradingException,
NoLiquidityException,
AllPlatformsFailedException,
)
async with TradingClient(...) as client:
try:
result = await client.trade(...)
except NoLiquidityException as e:
# No platform had an available quote
print(f"No liquidity: {e}")
# Check market hours or Market Maker offer availability
except AllPlatformsFailedException as e:
# Both primary and fallback trade attempts failed
print(f"All platforms failed: {e}")
except ValueError as e:
# Both or neither of from_amount / to_amount was provided
print(f"Invalid parameters: {e}")
except TradingException as e:
print(f"Trading error: {e}")
| Exception | When it occurs |
|---|---|
| NoLiquidityException | No platforms available (market closed, no offers) |
| AllPlatformsFailedException | Both primary and fallback execution failed |
| ValueError | Invalid parameter combination |
| TradingException | Base class for other trading errors |
Supported networks
| Network | Chain ID | Market Maker | Cross-Chain Access |
|---|---|---|---|
| Polygon | 137 | ✅ | ✅ |
| Ethereum | 1 | ✅ | ✅ |
| Base | 8453 | ✅ | ✅ |
| Arbitrum | 42161 | ✅ | ❌ (MM only) |
| Optimism | 10 | ✅ | ❌ (MM only) |
On networks where only one platform is available, the SDK uses that platform regardless of routing strategy.
Complete example
import asyncio
from decimal import Decimal
from swarm.trading_sdk import TradingClient, RoutingStrategy
from swarm.shared.models import Network
from swarm.trading_sdk.exceptions import (
NoLiquidityException,
AllPlatformsFailedException,
TradingException,
)
PRIVATE_KEY = "0x..."
RPQ_API_KEY = "your_key"
USER_EMAIL = "you@example.com"
USDC = "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359" # Polygon USDC
RWA = "0x..." # RWA token address
async def main():
async with TradingClient(
network=Network.POLYGON,
private_key=PRIVATE_KEY,
rpq_api_key=RPQ_API_KEY,
user_email=USER_EMAIL,
routing_strategy=RoutingStrategy.BEST_PRICE
) as client:
# Step 1: Compare prices across platforms
quotes = await client.get_quotes(
from_token=USDC,
to_token=RWA,
from_amount=Decimal("100"),
to_token_symbol="AAPL"
)
for platform, quote in quotes.items():
if quote:
print(f"{platform}: ${quote.rate} — receive {quote.buy_amount} tokens")
# Step 2: Execute trade with smart routing
try:
result = await client.trade(
from_token=USDC,
to_token=RWA,
from_amount=Decimal("100"),
to_token_symbol="AAPL",
user_email=USER_EMAIL
)
print(f"✅ Trade successful via {result.source}")
print(f" TX: {result.tx_hash}")
print(f" Spent: {result.sell_amount} USDC")
print(f" Received: {result.buy_amount} AAPL")
except NoLiquidityException as e:
print(f"No liquidity: {e}")
except AllPlatformsFailedException as e:
print(f"All platforms failed: {e}")
asyncio.run(main())
Quick reference
# Imports
from swarm.trading_sdk import TradingClient, RoutingStrategy
from swarm.shared.models import Network
from swarm.trading_sdk.exceptions import (
NoLiquidityException, AllPlatformsFailedException, TradingException
)
from decimal import Decimal
# Initialise
async with TradingClient(
network=Network.POLYGON,
private_key="0x...",
rpq_api_key="your_key",
user_email="you@example.com",
routing_strategy=RoutingStrategy.BEST_PRICE
) as client:
# Get quotes
quotes = await client.get_quotes(
from_token="0xUSDC...", to_token="0xRWA...",
from_amount=Decimal("100"), to_token_symbol="AAPL"
)
# Execute trade
result = await client.trade(
from_token="0xUSDC...", to_token="0xRWA...",
from_amount=Decimal("100"), to_token_symbol="AAPL",
user_email="you@example.com"
)
.png)