publicliveAn ordinary wallet swap
- Kept from view
- Nothing
- Still on chain
- Wallet, token, size and pool
Describe a stock-token trade once and get back the exact unsigned steps, a dry run of them from your wallet, and an allow, warn or block verdict. Nothing moves until your wallet agrees.
$UMBIX contract address coming soonPOST /api/trades/plan
{
"side": "buy",
"symbol": "NVDA",
"quote": "USDG",
"amountIn": "500",
"wallet": "0x…"
}
→ steps + verdict + reasonsOne answer for apps, wallets,
scripts and agents.
Every plan Umbix returns ties together the official token, the pool route, the order of the steps, the simulation result, the privacy mode and an expiry, so the code that receives it can decide in one place and the person signing can see why.
const answer = await fetch("https://umbix.xyz/api/trades/plan", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
side: "buy",
symbol: "NVDA",
quote: "USDG",
amountIn: "500",
wallet: account,
privacy: { mode: "public" },
}),
}).then((r) => r.json());
// answer.verdict · answer.reasons · answer.transactionsPlenty of contracts on Robinhood Chain call themselves NVDA. The planner ignores the name and checks the token's code for Robinhood's stock-token beacon, then reads whether trading is paused and what the dividend multiplier is, before a single pool is looked at.
Two numbers stay apart: the Chainlink reference value of one token, and what a Uniswap v3 pool would really hand over across every fee tier, directly or through USDG or WETH. The gap between them comes back in basis points, so a thin pool cannot hide its cost.
When your allowance falls short, step one approves exactly the amount you spend, never an open-ended sum. Step two is the swap, carrying your minimum output and an on-chain deadline. Each step arrives as plain to, data and value fields that any wallet library can send.
The whole sequence is replayed from your wallet address against the latest block with eth_simulateV1, approval first and swap second. A revert anywhere turns the verdict to block, and the contract's error comes back as a sentence a person can read.
The planner holds no key and has no way to move funds. A block verdict carries no steps at all, so there is nothing to sign by mistake. On allow or warn your app hands the unsigned steps to the wallet, and the person approves them or does not.
One field sets the mode. This build produces public plans only; asking for stealth or shielded returns a block verdict that says so, instead of a plan that pretends.
publiclivestealthplannedshieldedroadmapThe field that switches itprivacy: { mode: "public" }
A ticker resolves only when the token's code embeds Robinhood's beacon, so look-alike contracts never reach a pool.
How assets are checked 01Approvals cover the amount you spend and nothing more, so nothing is left standing for a later mistake to drain.
Read the step format 02The steps run from your own address in one simulated block, so balance and allowance problems surface before any signature.
See the simulation 03UmbixPlanLatch recomputes the plan hash on chain and settles a plan once, for the named wallet, before its deadline. Written and tested; not deployed yet.
About the latch 04When the pause state, the reference price or the balance cannot be read, the verdict is block rather than a guess.
Every reason code 05The later modes aim to keep a trading strategy from being read by every market watcher, while the holder can still show what they did to someone entitled to see it. A public observer will always see that a proof was submitted and checked, who paid the gas, and how large the pool is.
Where the line is drawnStart and finish with POST /api/trades/plan. The asset and chain routes are there for when you want to show prices or check the network yourself.
/api/trades/planResolve, quote, build, simulate and judge one trade.
↗GET/api/assetsEvery official stock token with its value, multiplier and trading state.
↗GET/api/assets/{symbol}One ticker resolved to its official token, or a 404.
↗GET/api/chainChain head, gas price, ETH/USD and whether the plan latch is deployed.
↗GET/api/plans/{planId}Fetch a stored plan before it expires.planned
↗POST/api/simulateDry-run an ordered list of unsigned calls you built yourself.planned
↗API v0. Amounts are exact decimal strings in and out. About 12 plans a minute per network, no key to manage.
Every surface receives the same checked plan. A person reads the reasons, a script branches on the verdict, an agent proposes and never signs, while only the wallet can move funds.
A phone screen with live Chainlink values that asks the planner about a buy and shows the verdict and the minimum you would get.
See it live ↗02 · Browser extensionA second opinion on any trade pageA popup that reads the order on a broker page and asks whether that exact trade would pass before it reaches the wallet.
See it live ↗03 · Your productThe planner inside your own flowCall the live endpoint from the playground, connect a wallet, and sign the steps one at a time if you choose to.
Go to the playground →04 · AI agentsPlans an agent can proposeAn agent sends plain HTTPS, reads the reason codes and passes the steps to a person or a wallet policy. No key ever enters the agent.
Agent notes →Plain HTTPS and JSON, no account and no key, and the same planner that answers every request on this site. Copy the call, read the verdict, then sign in your wallet.
The endpoint is open and limited per network. Your first plan can go out in the next minute, and nothing secret is ever requested.
no API key12 plans / minCORS openfetch, curl, requests or any HTTP library. The answer is plain JSON with typed reason codes, so there is no package to install.
HTTPS + JSONreason codesdecimal stringsPublic, stealth and shielded share the endpoint and the answer shape. Only public produces steps in this build.
privacy: { mode: "public" }// One small helper is the whole integration.
const API = "https://umbix.xyz/api";
type Intent = { side: "buy" | "sell"; symbol: string; quote: string; amountIn: string; wallet: string };
export async function requestPlan(trade: Intent) {
const r = await fetch(`${API}/trades/plan`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(trade),
});
const answer = await r.json();
if (r.status !== 200) throw new Error(answer.error?.message ?? `HTTP ${r.status}`);
return answer;
}
const answer = await requestPlan({ side: "buy", symbol: "NVDA", quote: "USDG", amountIn: "500", wallet: account });
switch (answer.verdict) {
case "block":
return explain(answer.reasons);
case "warn":
await confirmWithUser(answer.reasons); // then carry on
default:
for (const step of answer.transactions) await signAndWait(step);
}
Live on Robinhood ChainNo account and no key. Connect a wallet to simulate from your own address; nothing is sent unless you sign it.