Smeltor is a single deterministic API that connects apps and agents to DeFi protocols — swap, earn, perp, bridge, borrow, restake, limit orders — without deploying smart contracts or touching user funds.
Deterministic resolver with structured JSON input. Any LLM or
application can call the API directly. You describe the user's
intent — a structured action (swap, earn,
perp_open, bridge, borrow,
restake, limit_order) or a multi-step plan —
and Smeltor returns ready-to-sign EVM calldata. The user's wallet
executes. We never touch funds.
One endpoint, two transports. Call the REST API directly from any language, or run the MCP server from any LLM client (Claude Desktop, Cursor, Inspector, custom agent loop). Both wrap the same engine — fee params, slippage clamping, aggregator failover, gas estimation, simulation, EIP-7702 atomic batching live in one place.
Pass one of these as action on
/api/public/workflow/resolve, or chain several together
via steps[] for a multi-step plan. Amounts pipe between
steps automatically.
Live coverage as of this deploy. The authoritative source is
GET /api/public/system/coverage — poll it any time.
| Category | Protocols | Chains |
|---|---|---|
| Swap | 1inch · ParaSwap · KyberSwap · OpenOcean · 0x · Odos · Curve · Uniswap V3 Direct · Jupiter (Solana) | base, arbitrum, ethereum, polygon, bsc, avalanche, solana |
| Earn | Aave V3 · Moonwell · Morpho · Compound V3 · Spark (sUSDS) · Pendle (fixed) · Lido · Rocket Pool · ether.fi · Ethena · Maple · Ondo USDY (surface) · Marinade (mSOL, Solana) | base, ethereum, arbitrum, polygon, bsc, avalanche, zksync, solana |
| Borrow | Aave V3 · Morpho Blue | base, ethereum, arbitrum, polygon, bsc, avalanche |
| Restake | EigenLayer | ethereum |
| LP | Aerodrome vAMM · Aerodrome Slipstream | base |
| Bridge | Across · Stargate V2 · Ondo Bridge (LayerZero V2 OFT) | base, arbitrum, ethereum, polygon, bsc, optimism, avalanche (Stargate), zksync (Across), hyperevm (Ondo only) |
| Perps | Hyperliquid · GMX V2 · dYdX v4 | arbitrum (HL bridge2 + GMX), dYdX app-chain |
| TWAP / DCA | CoW Protocol (ComposableCoW) | base, arbitrum, ethereum |
| Limit orders | 1inch LOP v4 | base, arbitrum, ethereum |
| RWA | Ondo Global Markets (SPYon · QQQon · NVDAon · TSLAon · GOOGLon · NFLXon · COINon · AAPLon) · Ondo USDY (Treasury) | ethereum, bsc, hyperevm |
Strategy templates. The resolver recognises higher-level
strategy phrases and expands them into multi-step plans:
basis_trade (long Ondo tokenized stock + short matching
Hyperliquid perp = delta-neutral funding-rate yield),
stock_yield (tokenized stock collateral on Felix Protocol
→ borrow → earn — ROADMAP-gated),
leveraged_staking, yield_stack,
hedge_earn. Trigger phrases: "basis trade on SPY",
"delta neutral TSLA", "hedge SPY", "earn yield on my SPYon".
Streamable HTTP transport, no auth, hosted on Supabase Edge Functions.
Drop this block into your MCP client config (Claude Desktop, Cursor,
Inspector, custom LLM agent) and the Smeltor tools become available
immediately. mcp-remote handles the streaming transport
for clients that don't speak it natively.
{
"mcpServers": {
"smeltor": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://juaroposgdkfbvqvzvxf.supabase.co/functions/v1/smeltor-mcp"
]
}
}
}
Smoke-test the MCP endpoint directly:
curl -sX POST https://juaroposgdkfbvqvzvxf.supabase.co/functions/v1/smeltor-mcp \ -H "Content-Type: application/json" \ -H "Accept: text/event-stream, application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
One endpoint, any action. Pass a single action + params
for structured callers (agents, wallets) or a steps[] array for
multi-step plans. The same endpoint accepts a natural-language
intent string for callers who want the resolver to parse
first — most production integrations pass structured input directly.
curl -sX POST https://api.smeltor.com/api/public/workflow/resolve \ -H "Content-Type: application/json" \ -d '{ "walletAddress": "0xYourWallet…", "action": "swap", "params": { "fromToken": "USDC", "toToken": "ETH", "amount": "10", "chain": "base" } }'
Multi-step plans pipe amounts automatically. The example below swaps USDC→ETH, bridges to Ethereum, then stakes via Lido — three protocols, one request, one composed response.
curl -sX POST https://api.smeltor.com/api/public/workflow/resolve \ -H "Content-Type: application/json" \ -d '{ "walletAddress": "0xYourWallet…", "steps": [ { "action": "swap", "params": { "fromToken": "USDC", "toToken": "ETH", "amount": "100", "chain": "base" } }, { "action": "bridge", "params": { "token": "ETH", "fromChain": "base", "toChain": "ethereum" } }, { "action": "earn", "params": { "token": "ETH", "chain": "ethereum", "protocol": "lido" } } ] }'
The response carries the composed plan + ready-to-sign calldata,
plus an execution object describing EIP-7702 batch
grouping so single-chain plans with multiple txs collapse to one
signature on supporting wallets (Coinbase Smart Wallet, MetaMask
with EIP-7702, Privy embedded wallets).
{
"steps": [ /* one entry per action with transactions[], simulationPassed, quoteFreshness, mevRisk, estimatedGas */ ],
"execution": {
"atomic": true,
"totalSignatures": 1,
"method": "eip7702_batch",
"batches": [{ "chainId": 8453, "calls": [ /* approve + swap as one batch */ ] }]
},
"summary": "3-step plan · 1 signature · ~$0.012 gas · highest net APY 4.74%",
"nextActions": [ /* per-action suggestions agents can render as buttons */ ],
"warnings": [],
"reasoning": [ /* NL inference trail when the caller passed a natural-language intent */ ]
}
Pass testnet: true on any /resolve call.
The endpoint returns the same shape as mainnet, with
network: "testnet", real calldata, and zero risk to
user funds. The intended use is integration testing — partners can
exercise the full request/response surface before any mainnet
address is touched.
curl -sX POST https://api.smeltor.com/api/public/workflow/resolve \ -H "Content-Type: application/json" \ -d '{ "walletAddress": "0xYourWallet…", "testnet": true, "action": "swap", "params": { "fromToken": "USDC", "toToken": "ETH", "amount": "10", "chain": "base" } }'
What's real on testnet: swap, bridge, earn, and the
simulated EIP-7702 batch — every action returns calldata against
testnet routers / contracts when an equivalent testnet deployment
exists. What's mocked: perps (Hyperliquid /
dYdX testnet is not configured), restake (EigenLayer testnet
surface is intentionally read-only), and any protocol that only
runs on mainnet. Mocked actions return a simulated: true
step with representative response shape so integration tests can
assert against it.
Pass partnerFee (decimal, max 5%) plus
partnerAddress on /resolve. The resolver
deducts the fee from the input amount BEFORE running gates, then
prepends a USDC.transfer(partner, fee) call to the
EIP-7702 batch — the partner is paid in the SAME on-chain tx as
the user's workflow. Atomic. Verified live on Base
(tx 0xaf934d17…): a 0.20 USDC swap with 3% fee paid
the partner 6000 raw units of USDC in the same transaction as the
swap.
curl -sX POST https://api.smeltor.com/api/public/workflow/resolve \ -H "Content-Type: application/json" \ -d '{ "walletAddress": "0xYourWallet…", "partnerFee": 0.03, "partnerAddress": "0xYourPartnerWallet…", "action": "swap", "params": { "fromToken": "USDC", "toToken": "ETH", "amount": "10", "chain": "base" } }'
Returns the wallet's on-chain holdings plus DeFi positions detected
via the receipt-token registry, plus a typed list of factual
opportunities (idle_asset, yield_upgrade,
consolidation). Opportunities are informational —
never "recommendations" — so the calling agent picks. Data is
pulled from Zerion (primary) with a viem multicall fallback when
Zerion lags.
curl -sX POST https://api.smeltor.com/api/public/portfolio \ -H "Content-Type: application/json" \ -d '{ "walletAddress": "0xYourWallet…" }'
{
"tokens": [ /* { symbol, address, chain, balance, usdValue } */ ],
"positions": [ /* { protocol, kind, asset, chain, balance, apy } */ ],
"opportunities": [
{ "type": "idle_asset", "asset": "USDC", "chain": "base", "info": "100 USDC idle on Base" },
{ "type": "yield_upgrade", "from": "aave", "to": "moonwell", "delta_apy": 0.81 },
{ "type": "consolidation", "asset": "USDC", "chains": ["base", "arbitrum"] }
]
}
All of these flow through /api/public/workflow/resolve
with the matching action value.
Returns EIP-712 typed-data + orderHash. Gasless for
the user — resolvers pay gas when the order fills. NL: "buy ETH
at $2000", "sell ETH at $3000". Gates:
PARAM_REQUIRED, INVALID_PRICE,
expiry range [60s, 30d].
curl -sX POST https://api.smeltor.com/api/public/workflow/resolve \ -H "Content-Type: application/json" \ -d '{ "walletAddress": "0xYourWallet…", "action": "limit_order", "params": { "fromToken": "USDC", "toToken": "ETH", "amount": "100", "limitPrice": "2000", "side": "buy", "expiry": 86400, "chain": "base" } }'
On-chain reads (getUserAccountData,
getReserveConfigurationData, getReserveCaps),
post-borrow Health Factor projection, classification taxonomy
(ok / warn / danger /
liquidatable / no_collateral /
asset_disabled / frozen /
cap_exceeded). Variable rate (interestRateMode=2).
curl -sX POST https://api.smeltor.com/api/public/workflow/resolve \ -H "Content-Type: application/json" \ -d '{ "walletAddress": "0xYourWallet…", "action": "borrow", "params": { "token": "USDC", "amount": "100", "chain": "base", "protocol": "aave" } }'
Deposits stETH, cbETH, or rETH into the corresponding EigenLayer
Strategy contract on Ethereum mainnet. Returns approval + deposit
calldata. Operator delegation is a separate flow surfaced via
nextActions[].
curl -sX POST https://api.smeltor.com/api/public/workflow/resolve \ -H "Content-Type: application/json" \ -d '{ "walletAddress": "0xYourWallet…", "action": "restake", "params": { "token": "stETH", "amount": "1", "chain": "ethereum", "protocol": "eigenlayer" } }'
Smeltor builds the bridge2 deposit calldata when needed (HL only
— dYdX is native on its app-chain), formats the limit price to
the protocol's tick size, and returns the unsigned EIP-712 order
body. The caller signs with the user's local agent key and POSTs
to the venue. Default venue: "hyperliquid"; pass
venue: "dydx" to route to dYdX v4.
curl -sX POST https://api.smeltor.com/api/public/workflow/resolve \ -H "Content-Type: application/json" \ -d '{ "walletAddress": "0xYourWallet…", "action": "perp_open", "params": { "asset": "ETH", "side": "short", "leverage": 5, "amount": "50", "venue": "hyperliquid" } }'
Every earn option in the response carries a facts
block. We present facts; the agent decides risk. Fields:
tvl_usd, audited,
audit_firms[], months_live,
previous_exploits[], governance,
type. The earn / yield-comparison response includes
a yieldComparison object with
options[], highestApy,
longestLive, and largestTvl so callers
can rank by whichever axis matters to them.
Smeltor is a routing engine, not a financial advisor. Options are
surfaced with technical descriptors (highest_yield,
same_chain, fixed_rate,
lowest_cost, no_bridge,
primary) — never "best" or "recommended". The
calling agent or end user picks.
The fastest way to internalize the surface is the live demo — same routes, browser-side, no setup. Click around and watch real on-chain data. Toggle testnet mode at the top of the demo to preview the calldata against testnet routers.