Quickstart
Sign in with a wallet, get a quote, run a trade as a dry run, then for real. The same flow in TypeScript, in Python, and for an AI assistant through MCP.
Before you start#
- A wallet for the agent on Robinhood Chain (4663), with a little ETH for gas (a trade costs about a cent). Use a wallet that holds only what the agent trades, never your main savings.
- Node.js 20 or later for TypeScript, or Python 3.10 or later.
- The API URL:
https://api.orblivion.com. The SDKs and the MCP server use it unless you name another server, as an argument to the client or once in the environment:
export ORBLIVION_API_URL="https://api.orblivion.com" # the default; set another server hereTypeScript#
Install#
npm install @orblivion/sdk viemConnect with a wallet#
The client takes a viem account. Signing in is a Sign-In with Ethereum message the SDK checks and signs for you on first use; it returns an API key bound to this wallet.
import { createOrblivionClient } from '@orblivion/sdk'
import { privateKeyToAccount } from 'viem/accounts'
const client = createOrblivionClient({
baseUrl: 'https://api.orblivion.com', // the default: leave it out, or set ORBLIVION_API_URL
account: privateKeyToAccount(process.env.AGENT_KEY as `0x${string}`),
maxNotionalUsd: 25, // the client refuses any trade larger than this
})
await client.signIn() // optional: the first call signs in for youQuote#
A quote is read-only: nothing is built for signing and nothing is refused for risk.
const q = await client.quote({ sell: 'ETH', buy: 'USDG', amountUsd: 5 })
console.log(q.best?.label, q.best?.amountOut, q.feeBps, q.feeClass, q.risks)Trade: a dry run first#
trade() plans the trade, checks the disclosures, decodes and verifies the transaction, and signs it. With dryRun: true it stops before sending, so you can see exactly what would happen.
const dry = await client.trade({ sell: 'ETH', buy: 'USDG', amountUsd: 5, dryRun: true })
console.log(dry.simulatedOut, dry.minOut, dry.feeBps, dry.feeClass, dry.feeTier, dry.checks.length)
const r = await client.trade({ sell: 'ETH', buy: 'USDG', amountUsd: 5 })
console.log(r.txHash, r.amountOut, r.diffBps, r.fee, r.gasUsed)Selling a token (USDG here) needs an approval to Permit2 the first time and a Permit2 signature for each trade. The SDK handles both and checks them before signing; approval: 'budget' approves a few trades' worth at once instead of the unlimited approval many apps ask for.
const back = await client.trade({ sell: 'USDG', buy: 'ETH', amountUsd: 5, approval: 'budget', budgetUsd: 25 })Python#
Install#
pip install orblivionConnect with a wallet#
import os
from eth_account import Account
from orblivion import OrblivionClient
client = OrblivionClient(
base_url="https://api.orblivion.com", # the default: leave it out, or set ORBLIVION_API_URL
account=Account.from_key(os.environ["AGENT_KEY"]),
max_notional_usd=25, # the client refuses any trade larger than this
)
client.sign_in() # optional: the first call signs in for youQuote#
q = client.quote(sell="ETH", buy="USDG", amount_usd=5)
print(q.best, q.fee_bps, q.fee_class, q.risks)Trade: a dry run first#
dry = client.trade(sell="ETH", buy="USDG", amount_usd=5, dry_run=True)
print(dry.simulated_out, dry.min_out, dry.fee_bps, dry.fee_class, dry.fee_tier, len(dry.checks))
r = client.trade(sell="ETH", buy="USDG", amount_usd=5)
print(r.tx_hash, r.amount_out, r.diff_bps, r.fee, r.gas_used)
back = client.trade(sell="USDG", buy="ETH", amount_usd=5, approval="budget", budget_usd=25)Amounts can also be given exactly, in the input token's smallest unit: amountIn: 5_000_000n in TypeScript, amount_in=5_000_000 in Python (5 USDG).
The fee#
Every quote and plan says what Orblivion's fee is: fee_bps, its fee_class (major or other), its fee_tier (the rate before Shield) and shield. ETH to USDG is a major trade, since both tokens are majors: it pays 0.25%, less once the wallet's 30-day volume passes $50,000. A trade with any other token pays 0.50%. Dossier Shield adds 0.10% to either. See Fees and gas.
The SDK reads the class itself and refuses a plan that disagrees (FEE_CLASS), or whose fee the schedule doesn't allow (FEE_BPS). To cap the fee, set maxFeeBps (TypeScript) or max_fee_bps (Python) on the client: a plan above it is refused before anything is signed.
Any other token#
Every token outside the core list is named by its contract address. The SDK reads the token on chain itself, fetches Orblivion's record of it, and shows you the disclosures. A severe one stops the trade until you accept it by name:
const t = await client.trade({ sell: 'ETH', buy: '0x...', amountUsd: 5, dryRun: true })
// refused with RISK_NOT_ACCEPTED if the token carries, say, TRANSFER_TAX; to trade it anyway:
const t2 = await client.trade({ sell: 'ETH', buy: '0x...', amountUsd: 5, acceptRisks: ['TRANSFER_TAX'] })t = client.trade(sell="ETH", buy="0x...", amount_usd=5, dry_run=True)
# refused with RISK_NOT_ACCEPTED if the token carries, say, TRANSFER_TAX; to trade it anyway:
t2 = client.trade(sell="ETH", buy="0x...", amount_usd=5, accept_risks=["TRANSFER_TAX"])Read Tokens and risks before you accept anything.
Without an SDK#
The API is plain JSON over HTTPS, so any language works. You then do yourself what the SDK does: check the challenge message before you sign it, decode every transaction before you sign it, and check what was mined.
# 1. a sign-in challenge for the wallet
curl -s https://api.orblivion.com/api/v1/auth/challenge \
-H 'Content-Type: application/json' -d '{"address": "0xYourAgentWallet"}'
# 2. sign its "message" with the wallet (personal_sign), then exchange the signature for an API key
curl -s https://api.orblivion.com/api/v1/auth/verify \
-H 'Content-Type: application/json' -d '{"address": "0xYourAgentWallet", "signature": "0x..."}'
# 3. plan a trade: quote, checks, unsigned transaction and its simulation, in one call
# (max_fee_bps is optional: the most the trade may pay, here 0.25%)
curl -s https://api.orblivion.com/api/v1/live/prepare \
-H "Authorization: Bearer $ORBLIVION_API_KEY" -H 'Content-Type: application/json' \
-d '{"wallet": "0xYourAgentWallet", "token_in": "ETH", "token_out": "USDG", "notional_usd": 5, "max_fee_bps": 25}'
# 4. sign the returned "tx" yourself after checking it, then relay it
curl -s https://api.orblivion.com/api/v1/live/submit \
-H "Authorization: Bearer $ORBLIVION_API_KEY" -H 'Content-Type: application/json' \
-d '{"raw_tx": "0x02f9..."}'Trading explains each step, and the API reference lists every field.
MCP#
The Orblivion MCP server, @orblivion/mcp, gives an AI assistant tools to look up tokens, quote, plan and trade through the TypeScript SDK. The assistant decides; the server enforces the owner's policy, which it reads from its environment once, at start, where nothing in a conversation can change it. Every trade passes the same SDK checks as above, and nothing is sent until the owner turns live sends on.
Add it to an assistant#
Most MCP clients (Claude Desktop, Claude Code and others) take an entry like this. The wallet's key is read from a file only you can read (chmod 600), never from a prompt:
{
"mcpServers": {
"orblivion": {
"command": "npx",
"args": ["-y", "@orblivion/mcp"],
"env": {
"ORBLIVION_KEY_FILE": "<path to a file holding the agent wallet's key>",
"ORBLIVION_MAX_TRADE_USD": "10",
"ORBLIVION_MAX_DAY_USD": "50"
}
}
}
}Set the owner's limits#
A tool call may ask for less than the policy allows, never more. A value that doesn't parse stops the server rather than falling back to a default.
| Variable | Default | What it sets |
|---|---|---|
ORBLIVION_API_URL | https://api.orblivion.com | the Orblivion API |
ORBLIVION_KEY_FILE or ORBLIVION_PRIVATE_KEY | none | the agent wallet's key (a file is preferred; never both). Without one, the server can only read and quote. |
ORBLIVION_MCP_LIVE | 0 | 1 lets execute_trade and session_trade sign and send. Off, they plan and verify only. |
ORBLIVION_MAX_TRADE_USD, ORBLIVION_MAX_DAY_USD | required when live | the most one trade, and any 24 hours, may spend. The day is counted in a ledger kept on disk (ORBLIVION_STATE_DIR). |
ORBLIVION_ALLOWED_TOKENS | any | when set, both sides of every trade must be in it: core symbols or addresses, comma-separated |
ORBLIVION_ACCEPT_RISKS | none | the severe risks a call may accept, comma-separated; a call can't accept any other |
ORBLIVION_SHIELD | 0 | 1 puts every quote and trade under Dossier Shield, which adds 0.10% to the fee |
ORBLIVION_MAX_SLIPPAGE_BPS | 100 | the most slippage a call may ask for (at most 300) |
ORBLIVION_OWNER_ATTESTS_NON_US | 0 | 1 is the owner's statement that they aren't a US person, which stock tokens need |
ORBLIVION_SESSION_ID, ORBLIVION_SESSION_WALLET | none | trade as the executor of an owner-signed session instead of from the key's own wallet |
ORBLIVION_MAX_CALLS_PER_MINUTE, ORBLIVION_MAX_SENDS_PER_MINUTE | 30, 2 | rate limits on the assistant |
ORBLIVION_RPC_URL | the SDK's | Robinhood Chain RPCs for the SDK's own reads |
The tools#
| Tool | What it does |
|---|---|
get_config | the server's checked configuration, the wallet, and the owner's policy with what is left today. The assistant should read it first. |
search_tokens, get_token | find tokens and read one, with its disclosures (and Dossier's verdict with Shield) |
get_quote | an indicative quote: the server's word, not verified |
get_balances | balances read from the chain |
plan_trade | plan a trade and verify every transaction, signing nothing |
execute_trade | with live sends off, the same as plan_trade; with them on, verify, sign, send and check what was mined |
session_status, session_trade | the session's state, and a trade as its executor, under the session's signed terms |
hosted_agents_list | the wallet's hosted agents |
Answers that carry text from the server, a token contract or a token's launcher (names, symbols, risk details) say that it is data, never instructions, and long strings are cut short. That helps an assistant ignore a token named like an instruction, but it is the owner's caps, allowed tokens and accepted risks that bind.
Dry run first#
Leave ORBLIVION_MCP_LIVE off while you try it. Ask the assistant for a quote, then for a planned trade, and read what it reports back: the route, the simulated output, the minimum, the fee, the disclosures and every check. Turn live sends on only when that matches what you expect, and keep the caps small. For an assistant that should trade without the wallet's main key, give it a session: its limits are then enforced on chain and by the co-signer as well.