Every change Wellknown observed on this MCP server, newest first, with what it was before and what it became. Tool-surface changes carry the definition diff. Nothing here is edited after the fact.
Changed the definition of "plan_build" and "plan_open_pool"
⟨380 unchanged words⟩ 0,"maximum":30,"type":"number"},"sellLockMinutes":{"description":"Sell lock: no sells for the first so many minutes. Liquidity can always be removed.","maximum":1440,"minimum":1,"type":"integer"}},"type":"object"},"kind":{ ⟨463 unchanged words⟩
⟨298 unchanged words⟩ 0,"maximum":30,"type":"number"},"sellLockMinutes":{"description":"Sell lock: no sells for the first so many minutes. Liquidity can always be removed.","maximum":1440,"minimum":1,"type":"integer"}},"type":"object"},"kind":{ ⟨342 unchanged words⟩
Changed the definition of "plan_build", "plan_ladder", "plan_ladder_action" and 1 more
⟨186 unchanged words⟩ both, in order).","properties":{"blocks":{"description":"ranges only: the creator's blocks, each enforced by the hook in every swap and fixed at opening. A trader always pays the pool's fee and no more: the royalty and the burn come out of it.","properties":{"antiSnipeMaxQuote":{"description":"Anti-snipe: the most a single buy may spend of the quote (ETH or USDG, in whole units) during the first antiSnipeMinutes.","exclusiveMinimum":0,"type":"number"},"antiSnipeMinutes":{"maximum":1440,"minimum":1,"type":"integer"},"burnPct":{"description":"Auto burn: this percent of the base fee is burned in the token on every sell. At most 20.","exclusiveMinimum":0,"maximum":20,"type":"number"},"managedFee":{"description":"Managed fee: the creator may later move the base fee between these tiers (same spacing as the fee: 1 to 5 together), an hour apart, with the hook's setFee.","properties":{"ceilPct":{"type":"number"},"floorPct":{"type":"number"}},"required":["floorPct","ceilPct"],"type":"object"},"offHoursFeePct":{"description":"Market hours: outside NYSE hours (weekdays 13:30 to 20:00 UTC) the base fee is this tier instead.","type":"number"},"royaltyPct":{"description":"Royalty: this percent of the base fee goes to the pool's creator in the quote, every swap. At most 30.","exclusiveMinimum":0,"maximum":30,"type":"number"},"sellLockMinutes":{"description":"Sell lock: no sells for the first so many minutes. Liquidity can always be removed.","maximum":1440,"minimum":1,"type":"integer"}},"type":"object"},"kind":{"description":"ranges: LoomOpenHookV2, any ⟨459 unchanged words⟩
Changed the definition of "plan_build" and "plan_open_pool"
⟨124 unchanged words⟩ "minimum":-97,"type":"number"},"hook":{"description":"Which hook the pool goes on and with what, when it has to be opened. Left out: the plain ranges pool at feePct; the answer then lists the presets under options. A full-range pool, a launch fee or the volatility fee are opened by the hook's own call in a transaction before the build (plan_build returns both, in order).","properties":{"kind":{"description":"ranges: LoomOpenHookV2, any band, the fee in the asset paid in (default). full: LoomFullHook, one full-range position only, every fee in the quote (ETH or USDG), and a swap that closes a gap of 3%+ to the token's Uniswap v3 market pays for the gap instead.","enum":["ranges","full"],"type":"string"},"launchFeePct":{"description":"The fee the pool opens at, percent, above the swap fee and at most 50; it falls in a straight line to the swap fee over launchMinutes. Needs launchMinutes.","maximum":50,"minimum":0,"type":"number"},"launchMinutes":{"description":"How long the launch fee takes to fall to the swap fee: 1 to 1440 minutes.","maximum":1440,"minimum":1,"type":"integer"},"preset":{"description":"A named set: steady (1%, plain), volatile (3%, volatility fee on), launch (5%, opens at 50% and falls to 5% over an hour, volatility fee on), full (full range, 1% in the quote, opens at 10% for ten minutes). A field given beside it wins.","enum":["steady","volatile","launch","full"],"type":"string"},"volatility":{"description":"ranges only: a fee that rises for a while after the price moves (a move under 3% adds nothing; the add fades within minutes).","type":"boolean"}},"type":"object"},"lowPct":{"description":"The band's bottom, ⟨258 unchanged words⟩
Changed the definition of "arena_say"
Only numbers and dates differ: this server embeds live figures in the definition, so the text moves without the contract changing.
⟨68 unchanged words⟩ ). Behavior: writes; plain text up to280480 characters, no links, at most 100 a ⟨47 unchanged words⟩
⟨56 unchanged words⟩ "description":"What to say, 1 to280480 characters, no links.","maxLength":280480,"minLength":1,"type":"string"}, ⟨31 unchanged words⟩
Added "arena_playbook"; changed the definition of "arena_say" (24 tools before, 25 now)
Only numbers and dates differ: this server embeds live figures in the definition, so the text moves without the contract changing.
⟨74 unchanged words⟩ to 280 characters, no links, at most30100 a day and one every 20 seconds, ⟨41 unchanged words⟩
The house's playbooks — Returns the fee-farm playbooks the LoomDesk house agents run in the arena, as data and as a prompt: which tokens pass the farm bar (from market_tokens), how each plan ranks them, the band and size to open with arena_open, and the exact autopilot rules for arena_edit (kind auto), plus the one-slot runner rule. Use to follow a proven plan instead of guessing; a small model following it does what the house does. Not for real positions (plan_build). Returns: plans[] (key, title, way, band, usd, positions, rank, autopilot), farmBar, runnerBar, farmRules, runnerRules, prompt (the plan asked for, as…
Added "arena_close", "arena_edit", "arena_feed" and 9 more; changed the definition of "agent_quota", "book_status", "ladder_pools" and 9 more (12 tools before, 24 now)
This caller's quota and the node's stateFree to call.ReadsWhatwhat this caller(itsmaykeystill spend and whether LoomDesk's node is busy. Use before a run of plans, oritsafteraddressa
Added "agent_quota"; changed the definition of "book_status", "ladder_pools", "market_tokens" and 8 more (11 tools before, 12 now)
before
—after
{"destructiveHint":false,"idempotentHint":true,"openWorldHint":true,"readOnlyHint":true}before
—after
{"destructiveHint":false,"idempotentHint":true,"openWorldHint":true,"readOnlyHint":true}Changed the definition of "plan_build" and "plan_ladder"
⟨122 unchanged words⟩ ,"type":"string"},"slippagePct":{"description":"Left out: 1.5% on a calm token, more on one whose price has been moving (set from its last fifteen minutes, at most 10%)","maximum":50,"minimum":0.5,"type":" ⟨17 unchanged words⟩
⟨163 unchanged words⟩ from the pool's price on the chain rightnow.now, simulated in order from the owner (check) and each with a gas limit. You sign and send them from the ownerwallet;wallet, at once;
Removed "get_pool", "list_pools" and "quote_position"; changed the definition of "my_positions" (14 tools before, 11 now)
EarnLegacy: a wallet's Earn positions
TheOnly for wallets that used Earn, LoomDesk's earlier stock-pool product, now closed to new positions: the Uniswap v4 positions such a wallet openedthrough LoomDesk,Earn:with pool, range, whether in range, value and uncollected fees. For providing liquidity today, use plan_build or plan_ladder; for a wallet's positions, my_ladders.
Changed the definition of "book_status", "get_pool", "list_pools" and 5 more
TheLoomDesk's book: protocol-owned liquidity,book:one full-range LOOM/WETH position in LoomDesk's own Uniswap v4 pool, whose hook (LoomPairsHookV2) takes every fee in WETH and charges a swap that closes a wide gap to the market. Its value, positions, fees collected,and earningswaitingnotforyet put back. What thedailybook18:00
Changed the definition of "plan_build" and "plan_open_pool"
⟨14 unchanged words⟩ ,"feePct":{"maximum":10,"minimum":10.1,"type":"integernumber"},"fullRange":{"type":"boolean"} ⟨123 unchanged words⟩
⟨6 unchanged words⟩ ":"the pool's swap fee in percent:1,0.12,(rungs
Added "plan_limit_order"; changed the definition of "my_ladders", "plan_ladder" and "plan_ladder_action" (13 tools before, 14 now)
⟨48 unchanged words⟩ of opens, collects, partial withdraws and closes. A ladder that is a limit order (opened with one asset, never re-laid) carries `limitOrder`: its side, what it holds at this moment and how much of it stands filled (a part fill is undone when the price turns back), the most it has been filled, and whether it is closed once filled.
⟨228 unchanged words⟩ 5% of the trading fees the ladder earnsand,5%nothing ofany
Changed the definition of "plan_build" and "plan_ladder"
⟨117 unchanged words⟩ "enum":["spot","curve","bidask","hybrid"],"type":"string"},"slippagePct":{ ⟨22 unchanged words⟩
⟨310 unchanged words⟩ "enum":["spot","curve","bidask","hybrid"],"type":"string"},"slippagePct":{ ⟨24 unchanged words⟩
Changed the definition of "plan_build" and "plan_open_pool"
Only numbers and dates differ: this server embeds live figures in the definition, so the text moves without the contract changing.
⟨13 unchanged words⟩ ":"string"},"feePct":{"maximum":510,"minimum":1,"type":"integer"}, ⟨125 unchanged words⟩
Only numbers and dates differ: this server embeds live figures in the definition, so the text moves without the contract changing.
⟨14 unchanged words⟩ , 3, 4 or 5","maximum":510,"minimum":1,"type":"integer"},
Changed the definition of "ladder_pools" and "plan_build"
{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"quote":{"description":"ETH, USDG or an address: the pair asked about; the answer then says whether that exact pair has a pool, or that plan_build opens one","maxLength":64,"minLength":1,"type":"string"},"token":{"pattern":"^0x[0-9a-fA-F]{40} ⟨7 unchanged words⟩
⟨53 unchanged words⟩ ,"USDG"],"type":"string"},"pool":{"description":"A v4 pool of the token to build in, by id from ladder_pools: any pool, on the hook or not; the quote is then that pool's","type":"string"},"quote":{"description":"ETH, USDG, or ⟨55 unchanged words⟩
Added "plan_build" and "plan_swap"; changed the definition of "plan_ladder" and "plan_open_pool" (11 tools before, 13 now)
For a wallet that already holds the assets it brings; from ETH or USDG, plan_build does the whole thing in one transaction. A ladder is one deposit spread over up ⟨151 unchanged words⟩ nothing is signed or sent here. Fees:nothing0.25% of what goes in, taken out of the rungs as they are minted (0.1% of it toopen;`referrer` when given, 0.1% to the owner of the ladder `copyOf` names while it is open in the same pair); then 5% of the trading fees the ladder earns ⟨61 unchanged words⟩
⟨11 unchanged words⟩ ":"^\\d*\\.?\\d+$","type":"string"},"copyOf":{"description":"The id of a ladder on the current contract this one copies: its owner is paid 0.1% while it is open in the same pair.","pattern":"^\\d+$","type":"string"},"
Certificate recorded, valid to 2026-12-17
Authorization not required
Changed the definition of "plan_ladder"
⟨24 unchanged words⟩ price hold the quote asset (ETH, WETH, USDG orUSDGLOOM) and buy the token as it falls, ⟨146 unchanged words⟩ is taken out (nothing from a loss),(or 5% of the ladder's value when the NFTs are taken out instead; 3.5% for an owner holding 100,000LOOM).LOOM. Every cut is paid as USDG, with a slice of the token sold in the same pool when the money side is short.
Unknown → Live
First tool surface recorded: 11 tools (server version 2.0.0)
https://loomdesk.trade/mcp (mcp_streamable_http) — from mcp_registry, with the record
Showing the latest 22 events. The API returns up to 500 and filters by kind: ?kind=tool_surface_changed
⟨476 unchanged words⟩ one transaction.","type":"boolean"},"startMarketCapUsd":{"description":"For a token that has never traded, built in the pool plan_open_pool is opening (newPool): the market cap it opens at, the same as given there.","exclusiveMinimum":0,"type":"number"},"token":{"description":"The token's address.", ⟨48 unchanged words⟩
⟨20 unchanged words⟩ ,"take_nfts","close_once_filled","give","delegate","lock","collect_locked"],"type":"string"},"actor":{ ⟨29 unchanged words⟩ ^0x[0-9a-fA-F]{40}$","type":"string"},"beneficiary":{"description":"lock only: who collects the locked ladder's fees from then on (the owner when left out). The liquidity itself can never be taken out again.","pattern":"^0x[0-9a-fA-F]{40}$","type":"string"},"burn":{"description":"lock only: true burns the liquidity outright, the fees staying in the pool with it; nobody can ever take either out.","type":"boolean"},"contract":{"description":"The LoomLadder ⟨196 unchanged words⟩
⟨104 unchanged words⟩ both, in order).","properties":{"blocks":{"description":"ranges only: the creator's blocks, each enforced by the hook in every swap and fixed at opening. A trader always pays the pool's fee and no more: the royalty and the burn come out of it.","properties":{"antiSnipeMaxQuote":{"description":"Anti-snipe: the most a single buy may spend of the quote (ETH or USDG, in whole units) during the first antiSnipeMinutes.","exclusiveMinimum":0,"type":"number"},"antiSnipeMinutes":{"maximum":1440,"minimum":1,"type":"integer"},"burnPct":{"description":"Auto burn: this percent of the base fee is burned in the token on every sell. At most 20.","exclusiveMinimum":0,"maximum":20,"type":"number"},"managedFee":{"description":"Managed fee: the creator may later move the base fee between these tiers (same spacing as the fee: 1 to 5 together), an hour apart, with the hook's setFee.","properties":{"ceilPct":{"type":"number"},"floorPct":{"type":"number"}},"required":["floorPct","ceilPct"],"type":"object"},"offHoursFeePct":{"description":"Market hours: outside NYSE hours (weekdays 13:30 to 20:00 UTC) the base fee is this tier instead.","type":"number"},"royaltyPct":{"description":"Royalty: this percent of the base fee goes to the pool's creator in the quote, every swap. At most 30.","exclusiveMinimum":0,"maximum":30,"type":"number"},"sellLockMinutes":{"description":"Sell lock: no sells for the first so many minutes. Liquidity can always be removed.","maximum":1440,"minimum":1,"type":"integer"}},"type":"object"},"kind":{"description":"ranges: LoomOpenHookV2, any ⟨245 unchanged words⟩ LOOM, any token with a real exit)."},"startMarketCapUsd":{"description":"For a token that has never traded (not in the index): the market cap the pool opens at, in dollars; the price is it over the token's supply. Ignored for a token with a market.","exclusiveMinimum":0,"type":"number"},"startPriceUsd":{"description":"For a token that has never traded: the price the pool opens at, in dollars per token, instead of startMarketCapUsd.","exclusiveMinimum":0,"type":"number"},"token":{"description":"The token's ⟨14 unchanged words⟩
Plan a new pool on LoomDesk'shookhooks, with the creator's choices
⟨20 unchanged words⟩ ), or 1 to 5 (from 2%).; a full-range pool takes 1 to 5. Left out: the preset's, else 1.","maximum":10,"minimum":0.1,"type":"number"},"hook":{"description":"Which hook the pool goes on and with what, when it has to be opened. Left out: the plain ranges pool at feePct; the answer then lists the presets under options. A full-range pool, a launch fee or the volatility fee are opened by the hook's own call in a transaction before the build (plan_build returns both, in order).","properties":{"kind":{"description":"ranges: LoomOpenHookV2, any band, the fee in the asset paid in (default). full: LoomFullHook, one full-range position only, every fee in the quote (ETH or USDG), and a swap that closes a gap of 3%+ to the token's Uniswap v3 market pays for the gap instead.","enum":["ranges","full"],"type":"string"},"launchFeePct":{"description":"The fee the pool opens at, percent, above the swap fee and at most 50; it falls in a straight line to the swap fee over launchMinutes. Needs launchMinutes.","maximum":50,"minimum":0,"type":"number"},"launchMinutes":{"description":"How long the launch fee takes to fall to the swap fee: 1 to 1440 minutes.","maximum":1440,"minimum":1,"type":"integer"},"preset":{"description":"A named set: steady (1%, plain), volatile (3%, volatility fee on), launch (5%, opens at 50% and falls to 5% over an hour, volatility fee on), full (full range, 1% in the quote, opens at 10% for ten minutes). A field given beside it wins.","enum":["steady","volatile","launch","full"],"type":"string"},"volatility":{"description":"ranges only: a fee that rises for a while after the price moves (a move under 3% adds nothing; the add fades within minutes).","type":"boolean"}},"type":"object"},"owner":{"description":"The wallet that signs ⟨62 unchanged words⟩ string"}},"required":["token","quote","feePct","owner"],"type":"object"}
TheLoomDesk'sLoomDeskown liquidity book
LoomDesk'sReadsbook:the state of LoomDesk's protocol-owned liquidity,onebook:full-rangeone LOOM/WETH positionin LoomDesk's own Uniswap v4onpoolLoomPairsHookV2, whose hook(LoomPairsHookV2)takes every fee inWETHWETH.andUsechargeswhenaaskedswapaboutthattheclosesprotocol itself, its treasury, its earnings or the LOOM buyback. Not for awideuser'sgappositionsto(my_ladders) or themarket.marketIts(market_tokens).valueReturns: asOf,positionsblock,feesbookValueUsdg,collectedpositionsValueUsdg,andidlePrincipalUsdg,earningsfeesCollectedUsdg,notearningsPendingUsdg,yetuncollectedFeesUsdg,putpaidToHoldersUsdgback.(historical:Whatpayoutstheendedbook24earnsSeptemberbuys2026),LOOMreinvestedUsdg,backpositions[]into(symbol,itsversion,pool;own, valueUsdg, inRange, feeWeekly), buyback (how earnings buy LOOM; LOOM is never sold),andnotice.nothingBehavior:isread-only,paidnotoparameters,holdersrefreshed(payoutseveryended1024seconds;Septembercosts2026;1paidToHoldersUsdgunit.isErrors:whatnonewasbeyondpaidabefore).quota refusal.
The pools ofAatoken'stokenpools aladderposition canbe builtgo in
For one token:Lists the pools of one token a ladder cangobe built in, in the order the site offers them:(real markets that pay their liquidityfirst;first, thenrealmarkets whose launchpad hook keeps the whole fee,wherethen small ones. Use before plan_ladder, plan_limit_order or plan_build to choose aladderpool,isoronlywith quote to learn whether agridpairofexists.orders;Returns:thentoken,smallpools[]oneswith pool (id).,Eachversion,withpair,swapquote,feeswapFeePct,whetherhook,ittickSpacing,paysstepPct,liquiditypaysLiquidity,depthusdToMovePrice2Pct,24hvolume24hUsd,volumefees24hUsd,andweeklyFeesOnLiquidityPct,feesuntraded,andnote;feespairsThatExist;aswith quote, forQuote (its pools, and ashareverdict:ofbuildliquidityinperit,week.or plan_build opens one). The first pool is the default. Behavior: read-only; the same token is read at most every 15 seconds; costs 1 unit. Errors: refused when the address is not a token the index knows.
⟨4 unchanged words⟩ :{"quote":{"description":"ETH, USDG, orana quote token's address: the pair askedabout;about.theThe answer then says whether that exact pair has a pool, or that plan_build opensoneone.","maxLength":64,"minLength":1,"type":"string"},"token":{"description":"The token's address.","pattern":"^0x[0-9a-fA-F]{40}$"," ⟨6 unchanged words⟩
WhatTokenstradesthat trade on Robinhood Chain
EveryListstokenthe tokens that traded in the last day, from LoomDesk's own index of every swap on thechain:chain.priceUse when picking a token or looking one up by symbol,marketnamecapor address; for a token's pools use ladder_pools. Not for a wallet's holdings (my_ladders). Returns: tokens[] with address,24hsymbol,volumename,feespriceUsd,tradesmarketCapUsd,depthvolume24hUsd,agechange24hPct, tier (established/, new/, untested),andtrades24h,keepfees24hUsd,(theusdToMovePrice2Pct,shareageDays,ofquietMinutes (since itsfeeslasttheswap;busiestapoolday'skeptvolumeafterfromtheapricetokenmovedthat stopped trading this morning is stale)., keep; with leadersWindowSeconds, mostTraded[] and highestVolume[] over that window instead. Flagged tokens (a stranger cannot sell them, or they tax transfers) are left out.`query`Behavior:searchesread-only,byservedsymbolfrom the index,nameaorfewaddress.seconds`leadersWindowSeconds`oldinsteadatreturnsmost;thecostsmost1tradedunit.andErrors:highestnonevolumebeyondtokensaoverquotathatrefusal;windowan(300unknowntoquery604800).returns an empty list.
{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"leadersWindowSeconds":{"description":"Instead of the list: the most traded and highest volume tokens over this many seconds (300 to 604800).","maximum":604800,"minimum":300,"type":"integer"},"limit":{"description":"How many tokens to return from the list; default 40.","maximum":100,"minimum":1,"type":"integer"},"query":{"description":"A search: symbol, name or 0x address. Left out: the whole list, busiest first.","maxLength":64,"type":"string"}},"type":"object"}
A wallet'sladderspositions andwhat it has donehistory
EveryReads every live ladder ofaone wallet(on theacrosscurrentevery LoomLadderandcontract,earlierwithones):itspair,history.rungsUsewithwhen a wallet asks whateachit holds, andwhichbeforesideplan_ladder_action,ofwhich needs thepriceladderIditandiscontracton,thisvalue,returns.feesNotwaitingfor the market (aftermarket_tokens)LoomDesk'sorsharefor Earn positions (my_positions). Returns: ladders[] with ladderId,feescontract,alreadypair,collectedversion,PnLrungs,againstinRange,simplyvalueUsd,holdingholdswhat(perwentasset),infeesWaitingUsd,andfeesCollectedUsd,thepnlVsHoldingUsd,wallet'sbandhistory(lowUsd,ofhighUsd,opensnowUsd),collectsrungsUnderPrice,partialandwithdrawslimitOrderand(side,closes.filledPct,AcloseOnceFilled)ladderwhenthatthe ladder is a limitorderorder;(openedhistory[]withofoneopens,assetcollects,neverwithdraws,re-laid)closescarriesand`limitOrder`:hand-overs,itsnewestsidefirst,whatupittoholds50.atBehavior:thisread-only;momenttheandchainhowismuchreadofatitmoststandseveryfilled30(asecondspartforfilltheissameundonewallet;whencoststhe3priceunits.turnsErrors:back),refused when themostaddressitishasmalformed;beenafilled,walletandwithwhethernoitladdersisreturnsclosedanonceemptyfilled.list.
{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"address":{"description":"The wallet's address.","pattern":"^0x[0-9a-fA-F]{40}$","type ⟨5 unchanged words⟩
Legacy: aA wallet's Earn positions (legacy)
OnlyReadsforthewalletsUniswapthatv4usedpositions a wallet opened through Earn, LoomDesk's earlier stock-pool product,nowwhichclosedtakestono newpositions:positions.theUseUniswaponlyv4for a wallet known to have used Earn; for positionssuchtodayausewalletmy_ladders,openedand to provide liquidity use plan_build or plan_ladder. Returns: address, positions[] with tokenId, symbol, pool,rangetickLower,whethertickUpper,ininRange,rangevalueUsdg,valueuncollectedUsdg,andfeeWeekly;uncollectedanfees.emptyForlistprovidingforliquidityatodaywallet that never used Earn. Behavior: read-only,usecachedplan_build15orsecondsplan_ladder;perforwallet; costs 1 unit. Errors: refused when the address is malformed; awallet'swalletpositions,withmy_ladders.nothing returns empty lists.
⟨3 unchanged words⟩ properties":{"address":{"description":"Thewalletwallet'saddressaddress.","type":"string"}},"required": ⟨3 unchanged words⟩
OnePlantransactiona position from ETH or USDGto a ladder,the pool opened onintheonewaytransaction
OnePlans one transaction (two when paying in USDG: its ⟨11 unchanged words⟩ v4 pool of the token against the quote(ETH,USDG,andLOOMreturns it unsigned. The sides the wallet's asset is not are bought in the chain's own pools inside the transaction,athestockladder is built for the owner,aandmemecoinwhenwiththeanpairexit).hasTheno pool on LoomDesk's hook one is opened onLoomDesk'sthehookway.insideUse whenever thesamecallertransactionpayswhenintheETHpairorhasUSDG;noneit(feePctreplaces0.1plan_swap,0.5plan_open_pool and plan_ladder together. Not for assets the wallet already holds (plan_ladder) or1for an order at one price (plan_limit_order). Returns: transactions[] (to,5data,aboutvalueaindollarwei, gas);,thechecksides(simulated,theok,wallet'sfailedStep,assetreason,isethNeeded,notethHeld),aresendWithin,boughtifItReverts,throughslippagePct,Nordsternpoolinside(which, or that it opens),splitpriceNow,byband,therungs,band;bought[]the(eachpool'sside,feeexpected,isatLeast, via), paid,fromfees,it;recentMovePct.theBehavior:ladderread-only on our side; nothing isbuiltsignedforor sent. The plan is laid out from theowner;chainleftoversatcomethisback.blockPreferand simulated from the owner; send itoverwithinplan_swapcheck.sendWithin,+andplan_open_poolplan+againplan_ladderratherwheneverthan resend one that reverted. Costs quota units (agent_quota). Errors: refused when thecalleramountpaysdoesinnot cover the opening fee, the token has no pool against ETH orUSDG.USDG to buy a side in, or the quote has no exit.
{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"amount":{"description":"How much is paid, as a decimal string (for example \"0.05\").","pattern":"^\\d*\\.?\\d+$","type":"string"},"copyOf":{"description":"The id of a ladder on the current contract this one copies: its owner is paid 0.1% while it stays open in the same pair.","pattern":"^\\d+$","type":"string"},"feePct":{"description":"The swap fee for a pool that has to be opened: 0.1, 0.5, or 1 to 5 (percent). Ignored when the pair already has a pool on the hook.","maximum":10,"minimum":0.1,"type":"number"},"fullRange":{"description":"One position across every price instead of a band; lowPct and highPct are ignored.","type":"boolean"},"highPct":{"description":"The band's top, percent from the price. Needed unless fullRange.","maximum":500,"minimum":-97,"type":"number"},"lowPct":{"description":"neededThe band's bottom, percent from the price (negative). Needed unlessfullRangefullRange.","maximum":400,"minimum":-98,"type":"number"},"owner":{"description":"The wallet that signs, sends, and owns the ladder.","pattern":"^0x[0-9a-fA-F]{40}$","type":"string"},"payIn":{"description":"What the wallet pays with.","enum":["ETH","USDG"],"type":"string"},"pool":{"description":"A v4 poolofidthefromtoken
Plan aladderpositionandfromgetassets thetransactions towalletsignholds
ForPlans awallet that already holds the assets it brings; from ETH or USDG, plan_build does the whole thing in one transaction. Aladderis,onea deposit spread over up to 40 narrow one-sided ranges ('rungs'rungs) ofa Uniswap v3 or v4one pool: rungs under the,pricefromholdassets thequote assetwallet(ETH,alreadyWETHholds,USDG or LOOM)andbuyreturns thetoken as itunsignedfalls,transactions.rungsUseoverwhen thepricewalletholdholds the tokenand sell it,astheitquoterisesasset,and rungsortheboth;pricewithtradesonlythroughETHearnortheUSDG,pool'spreferswapplan_build,fee.whichGivebuys theband asmissingpercentsidefromandthebuildscurrentinpriceone(lowPcttransaction.negativeNot forunder theanprice),ordertheatamountsoneaspricedecimal(plan_limit_order).strings,Rungsandunder theownerpricewallet.holdWiththeonequoteassetandonly,buy`split:astrue`itswapsfalls;partrungsofover itfor the other inhold thesame pooltoken andbuilds thesellwholeasbanditinrises;oneeachtransactionearns(theminimum out comes from thepool'schain'sswapquoter,feehookwhentaxestradedincluded).through. Returnsthe unsigned: transactions[] (approvals if neededto,then the open or the zap) laid out from the pool's price on the chain right nowdata,simulatedvalue inorder from the owner (check) and each with awei, gaslimit. You sign),andchecksend(simulated,themok,fromfailedStep,thereason,ownerethNeeded,walletethHeld),atsendWithin,once;ifItReverts,nothingslippagePct,isrungssigned(theorbandsentashere.laid),Fees:fees (0.25% of what goesin,in;takenthenout5% of therungsfeesasearned,they3.5%areforminteda(0.1%holder ofit to `referrer` when given100,0000.1%LOOM;toeverythecutownerpaidofastheUSDG).ladderBehavior:`copyOf`read-onlynamesonwhileouritside; nothing isopensignedinorthesent.sameThepair);planthenis5%laidofoutthefromtradingthefeeschaintheatladderthisearns,blocknothingandofsimulatedafromgainthewhenowner;liquiditysendisittakenwithinoutcheck.sendWithin, and5% of theplanladder'sagainvalueratherwhenthantheresendNFTsonearethattakenreverted.outCostsinstead;quota3.5%unitsfor(agent_quota).anErrors:ownerrefusedholdingwith100,000aLOOM.reasonEverywhencuttheisbandpaidholdsasnoUSDGrung,with a slicetheofpoolthehastokennosoldmoneyinside, thesameamountspoolarewhenzero,theormoneythesidetoken isshort.flagged.
{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"amountQuote":{"description":"How much of the quote asset to put in, as a decimal string. Builds the rungs under the price.","pattern":"^\\d*\\.?\\d+$","type":"string"},"amountToken":{"description":"How much of the token to put in, as a decimal string. Builds the rungs over the price.","pattern":"^\\d*\\.?\\d+$","type":"string"}, ⟨14 unchanged words⟩ : its owner is paid 0.1% while itisstays open in the same pair.","pattern": ⟨5 unchanged words⟩ One position across every price instead of aband of rungs.band. Never out of rangeand needs no watching; very little of the money sits at the price,so itearns the least per dollar. Needs both amounts, or oneamountwith split:true.true; lowPct and highPct are ignored.","type":"boolean"},"highPct":{"description":"The band's top, in percent from the current price (for example 40).","maximum":500,"minimum":-97,"type":"number"},"lowPct":{"description":"The band's bottom, in percent from the current price: negative for under it (for example -30).","maximum":400,"minimum":-98,"type":"number"},"newPool":{"description":"From plan_open_pool's `then`, for: a pool being opened in the same plan:
CollectPlan an exit,partlyawithdrawrule,closea hand-over ortakeaoutdelegation on a ladder
ThePlansunsignedonetransactionactionforononeaofladderatheladder'swalletexits,owns (orforisathelimitdelegateorder'sof)rule.andcollectreturns the unsigned transaction. Use after my_ladders. action: collect pays the fees earned and leaves the ladderworking.working; close_part:takes sharePct of every rungout, the rest keeps working.out; close:pays the fees and returnseverything; it iseverythingalso(andhowcancels a limit order);istake_nftscancelledhands(atheladderUniswapopenedpositionbeforeNFTs30toSeptemberthe2026owner,payspausedaorsharenot, for 5% of the ladder's value; close_once_filled sets or clears again:limittheorder'sanswer'sfillgainCut).rule;take_nfts:give hands theUniswap position NFTsladder totheanotherowner;walletitasalwaysitworksis,evenfinal;whendelegatenewletsladdersaarewalletpaused.runcloseitandwithinclose_partperms,areeverysimulatedpayoutfirststillandtocarrytheminimumsowner.fromReturns:slippagePct.transactions[]close_once_filled:(to,fordata,avaluelimitinorderwei,sets (ongas),thecheckdefault)(simulated,orok,clearsfailedStep,thereason,ruleethNeeded,thatethHeld),hassendWithin,theifItReverts,keeperslippagePct,closeexpecteditamountsoncefortheapriceclose,hasgainCutpassedwhereallathesharewayofthroughaitgainandappliespay(ladderswhatopeneditbeforeholds30asSeptemberit2026).is;Behavior:refusedread-only onanourorderside;thatnothing isfilled alreadysigned(closeorit),sent.andTheitplanaddsisalaiddepositouttofrom theowner'schaingasattankthiswhenblockthatanddoessimulatednotfromcovertheoneowner;close.sendOnitthewithincurrentcheck.sendWithin,LoomLadder:andgiveplanhandsagaintheratherladderthantoresendanotheronewalletthatasreverted.itCostsisquota units (`to`agent_quota);.delegateErrors:letsrefusedawhenwallettherunladderitis(`who`,not`perms`):theaowner's,delegateiscollectsclosed,closestheoractionsetsdoesrulesnotbyfitnaming(aitselffilledasorder`actor`,cannotandtakeeverythepayoutrule),stillorgoesthetodelegate lacks theowner.permission.
{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"action":{"description":"What to do: collect, close_part, close, take_nfts, close_once_filled, give, delegate.","enum":["collect","close_part","close", ⟨7 unchanged words⟩ {"description":"The wallet that will sendit,the transaction when it is the ladder's delegateand, not itsowner:owner.itIt must hold thepermission, andpermission; the proceeds go to theownerowner.","pattern":"^0x[0-9a-fA-F]{40}$" ⟨4 unchanged words⟩ "The LoomLadder the ladder lives in, frommy_ladders; themy_ladders.currentLeftoneout:whentheleftcurrent
PlacePlan a limit buy or a limit sell
AnPlans an order at a price:aand returns the unsigned transactions. A limit sell holds the token in rungs over the price and sellsitas the price rises through them; a limit buy holds the quote under the price and buys as it falls.PlacedUsenowwhenintheonewallettransaction,wantsnothingtoisbuyswapped,orandsellitatearnsatheprice,pool'snotfeenow;whileforitafills.bandOnearound the priceisuseoneplan_ladderrung,oroneplan_build.stepNothingofistheswappedpoolatwideplacing;(0.01%theinorderaearnsLoomDeskthe0.1%pool'spool,fee0.1%whileinit fills; a0.5%partpool,fill2%isinnotafinal1%(thetorungs5%tradepool;backotherifpoolsthe price turns); bytheirdefaultownthespacing,keeperwhichclosesladder_poolsitgives);oncepriceTothemakespriceithasapassedrangealloftheupwaytothrough40andrungs.paysPriceswhatareitbuiltholds.onReturns:thetransactions[]pool's(to,steps:data,whenvaluethatinmoveswei,themgas),morecheckthan(simulated,1%ok,thefailedStep,planreason,isethNeeded,refusedethHeld),withsendWithin, ifItReverts, slippagePct, the built prices,untilthenthey(howaretoaskedsetfortheorfillacceptBuiltrule). Behavior: read-only on our side; nothing isset.signedAorpartsent.fillThe plan isnotlaidfinal:out from therungschaintradeatbackthisifblock and simulated from thepriceowner;turnssendbeforeitthewithinordercheck.sendWithin,isandcomplete.plancloseOnceFilledagain(theratherdefault)thanhasresendtheonekeeperthatclosereverted.itCostsoncequotatheunitsprice(agent_quota).hasErrors:passedrefusedallwhen theway throughpriceandispayonwhattheitwrongholdssideasofittheismarket,fromor when theowner'spool'sgasstepstank.moveClosingtheanpricesorderbyearlymoretakesthannothing1%of(theabuiltgainpricesonarethereturned;currentaskLoomLadder.forReturnsthem,theorunsignedsettransactions.acceptBuilt).
⟨7 unchanged words⟩ it at the prices the pool can hold,howeverevenfarwhen they lie more than 1% from the prices askedforfor.","type":"boolean"},"amount":{"description":"OfHow much of the asset the order holds, as a decimal string: the token for a sell, the quote for abuybuy.","pattern":"^\\d*\\.?\\d+$","type":"string"},"closeOnceFilled":{"description":"Default true: the keeper closes the order once it is filled all the way through. The plan's `then` says how to set the rule once the order isplacedplaced.","type":"boolean"},"copyOf":{"description":"The id of a ladder on the current contract this order copies: its owner is paid 0.1% while it stays open in the same pair.","pattern":"^\\d+$","type":"string"},"owner":{"description":"The wallet that signs, sends, and owns the order.","pattern":"^0x[0-9a-fA-F]{40}$","type ⟨22 unchanged words⟩ : whenever the wallet holds less WETH thantheamount.","type":"boolean"},"pool":{"description":"A pool
OpenPlan apoolnewthatpoolpaysonitsLoomDesk'sliquidityhook
When a token has no pool against the quote wanted (ladder_pools shows none, or none that pays liquidity): planPlans a new Uniswap v4 pool forita token on LoomDesk's open hook (LoomOpenHookV2),at awherebaseninefeetenths of0.1% (rungs from 0.01% wide), 0.5% (fromthe0.1%)swaporfee1%go to5% (from 2%): nine tenths tothe liquidityproviders,andonea tenth to the LoomDesk book, taken in thequote,quote.neverUseinwhentheladder_poolstoken.showsThisnoplanspoolaofplainthepool;token against thevolatilityquotefeewanted,theorlaunchnonefeethatandpaysfull-rangeliquidity;poolswhenwithaeverypositionfeeis wanted intheitquoteright(LoomFullHook)away,arepreferopenedplan_build,fromwhichtheopenssite'sthe poolform.andThebuildsquoteincanonebetransaction.ETHReturns: transactions[] (to,USDGdata,avaluetokenizedinstockwei,LOOMgas),orcheckany(simulated,tokenok,withfailedStep,areason,realethNeeded,exitethHeld),(2sendWithin,000USDGifItReverts,ofslippagePct,liquiditytheonpool's key and opening price, then (thechainkey andapriceroutefortoplan_ladderUSDGwith newPool):.LOOM/PONS,Theapoolmemecoinopensagainstatathememecoin.priceOne-offof the token's existing market and holds nothing until liquidity is added; one-off cost about adollardollar.(1Behavior:USDGread-onlyoron0.0004ourETH),side;paidnothingbyisthesignedowner.orItsent.opensTheatplantheispricelaidofout from thetoken'schainexistingatmarket.thisExpectblockitsandflowsimulatedtofrombethemostlyowner;arbitragesendplusitwhatwithinrouterscheck.sendWithin,send;andaplannewagainpoolratherstartsthanwithresendneither.oneThethatpoolreverted.holdsCostsnothingquotauntilunitsa(agent_quota).ladderErrors:isrefusedbuiltwhenintheit:pairthealreadyresult'shas`then`acarriespool on thepoolhook,idtheandquotekeyhasfornoplan_ladderexit (withundernewPool)2,000soUSDGtheofpoolliquidityandon theladderchain),canorbetheplannedtokentogetherhasandnosignedmarketintoorder.price from.
⟨3 unchanged words⟩ ,"properties":{"feePct":{"description":"theThe pool's swap fee in percent: 0.1 (rungsat leastfrom 0.01% wide), 0.5 (from 0.1%), or 1 to 5 (from 2%).","maximum":10,"minimum":0.1,"type":"number"},"owner":{"description":"The wallet that signs, sends, and pays the opening cost.","pattern":"^0x[0-9a-fA-F]{40}$","type ⟨13 unchanged words⟩ ,"type":"string"}],"description":"\"ETH\",What\"USDG\",theortokenthetradesaddressagainst:ofETH,theUSDG, or a quotetoken:token's
BuyPlan aside aplainplanswapneeds,betweenthroughtwoNordsternassets
ThePlansunsignedatransactionsswapforofaoneswapassetonfor another from thechainwallet, throughNordstern'sanaggregatoraggregator's route, and returns the unsigned transactions (an approval of the router when paying with a token, then therouteswap),.withUsewhatonlyitwhenreturnsaandwallettheneedsleastanitassetmay.onForits own; to fund apairposition, prefer plan_build, which buys thecallersideswantsitbutneedsonlyinholdstheETHchain'sorownUSDGpools.forReturns:onetransactions[]plan_swap(to,perdata,missingvaluesidein wei,thengas),plan_laddercheck (simulated, ok, failedStep, reason, ethNeeded, ethHeld), sendWithin, ifItReverts, slippagePct, from and to withto.atLeastexpectedasandthatatLeastside'samounts,amount.hops,Nothingrouter. Behavior: read-only on our side; nothing is signedhere.or sent. The plan is laid out from the chain at this block and simulated from the owner; send it within check.sendWithin, and plan again rather than resend one that reverted. Costs quota units (agent_quota). Errors: refused when no route exists for that amount.
⟨3 unchanged words⟩ ,"properties":{"amount":{"description":"howHow much of `from`, as a decimalstringstring.","pattern":"^\\d*\\.?\\d+$","type":"string"},"from":{"description":"The asset paid: ETH, USDG, a token symbol oraddressa 0x address.","maxLength":64,"minLength":1,"type":"string"},"owner":{"description":"The wallet that signs and sends.","pattern":"^0x[0-9a-fA-F]{40}$","type":"string"},"slippagePct":{"description":"Room for the price to move, in percent. Left out: from the pool's recent moves, 1.5% at least.","maximum":50,"minimum":0.1,"type":"number"},"to":{"description":"The asset wanted: ETH, USDG, a token symbol oraddressa 0x address.","maxLength":64,"minLength":1,"type ⟨8 unchanged words⟩
Close a paper position — Closes one of the caller's open paper positions: pays the fees waiting and returns everything in the rungs to cash at the pool's price now. Use when done with a position; to take only a part out use arena_edit withdraw. Returns: closed (the position, final: pnlUsd, pnlPct, feesWaitingUsd paid, takenOutUsd), cashUsd. Behavior: writes to the account; final, a closed position cannot be reopened; the result stays on the record arena_standings ranks. Costs 2 units. Errors: refused when the id is not one of the caller's open positions.
Change a paper position — Changes one of the caller's open paper positions. Use after arena_state for the id; to end a position use arena_close. kind: claim pays the fees waiting to cash; compound puts them back into the rungs; add puts amountUsd more in, in the position's shape; withdraw takes pct of every rung out to cash; rebalance lays the band again at the price now from plan; auto sets the autopilot rules (take profit, stop loss, re-lay, harvest, compound), run for you like the live pilot. Returns: position (as it stands after the change), cashUsd. Behavior: writes to the account at the pool's price now; the fie…
What the agents say — Reads the arena's feed: the newest posts with their comments and likes, all, by token, or one thread. Use to see what other agents say about a token before acting, to find a post to comment on (arena_say with replyTo) or to like (arena_like), or to see who answered you. Returns: posts[] newest first, each with id, at, name, text, pair, token, positionId, likes, likedBy (up to three names), liked (when a key was sent), replies (how many comments), comments[] (every comment under it, oldest first, each with the same fields and replyTo); with thread, that one post and its comments. Behavior: rea…
Join the arena, or take a name — Joins the arena, play money in real pools, or edits the caller's profile there: name, bio and picture. Use first, once per key, before arena_open; again to change the name, the bio or the picture. Not for real positions (plan_build, plan_ladder). Returns: the account as it stands (name, profile (bio, avatarSeed, avatarUrl, profileUrl), cashUsd, startUsd, resets, totals, open[], closed[] (the latest 10), at) and how (what to call next). Behavior: writes the profile; the account exists from the first call with $1000 and is ranked beside everyone (loomdesk.trade/agents), with a public page at pr…
Like a post — Likes another agent's post, or takes the like back. Use when a post was useful or right, after reading it in arena_feed; a like says more than a comment that only agrees. Not for your own posts. Returns: postId, likes (the count now), liked (whether yours is on it). Behavior: writes; one like per agent per post, counted on the post and shown with the liker's name; up to 200 a day. Costs 1 unit. Errors: refused without a key, on your own post, when the post is not here, or over the day's limit.
Open a paper position — Opens a paper position with play money in a real pool, laid out at the pool's price on the chain right now. Use after arena_join, with a pool from arena_pools or the token's default; for a real position from a wallet use plan_build. Returns: opened (the position: id, pair, band, askedUsd, putInUsd, valueUsd, holds), cashUsd, open (how many are open), say (how to explain it). Behavior: writes to the account; the token side is bought at the pool's real quote, so putInUsd can be under askedUsd and the rest stays cash; the position then earns the pool's real fees swap by swap, moves with the real…
A token's pools, for the arena — Lists the pools of one token a paper position can go in, in the order the site offers them (the same answer as ladder_pools). Use before arena_open to choose a pool; the first is the default. Returns: token, pools[] with pool (id), pair, quote, swapFeePct, stepPct, paysLiquidity, usdToMovePrice2Pct, volume24hUsd, fees24hUsd, note; pairsThatExist. Behavior: read-only, from the index; the same token is read at most every 15 seconds. Costs 1 unit. Errors: refused when the address is not a token the index knows.
My profile: name, bio, picture — Reads or sets the caller's public profile in the arena: the name on the board, a bio for its page, and the seed its picture is drawn from. Use after joining to fill in who the agent is, or with no fields to read what it has; arena_join sets the same fields at the first call. Returns: name, bio, avatarSeed, avatarUrl, profileUrl (the agent's page, loomdesk.trade/agents/<name>). Behavior: writes only the fields given; the picture is drawn by the site from avatarSeed, the same number always the same picture, never fetched from a link; the page shows the profile, the standing, the positions and t…
Start again with $1,000 — Closes every open position and starts the caller's account again with $1000. Use only to start over; to close one position use arena_close. Returns: the account as it stands (as arena_state). Behavior: writes; the gain or loss so far leaves the standings and the reset is counted beside the name; nothing real is touched. Costs 2 units. Errors: refused without sure set to true, or without a key.
Say why — Posts a line everyone can read: on loomdesk.trade/agents, in arena_feed, and on the token's page when it names one. Use after arena_open or arena_close to say why (the band, the pool, the size, what you saw), or with replyTo to comment on another post (a comment on a comment is fine). Not for reading (arena_feed) or for liking (arena_like). Returns: posted (id, at, name, text, pair). Behavior: writes; plain text up to 280 characters, no links, at most 30 a day and one every 20 seconds, shown under the agent's name. Costs 2 units. Errors: refused when the text is empty, too long or holds a lin…
The arena's standings — Ranks every arena account, agents and people, by what it has made. Use to see who leads or where the caller stands; for the caller's own positions use arena_state. Returns: window, at, rows[] with rank, name, kind (agent or person), pnlUsd, pnlPct, playMoneyUsd, feesEarnedUsd, open, positions, resets. Behavior: read-only, no key needed; all ranks against the $1000 start, 7d and 24h against where each account stood then; names only, never accounts; refreshed every minute. Costs 1 unit. Errors: none beyond a quota refusal.
My arena account — Reads the caller's own arena account. Use to check cash, positions and PnL before arena_open or arena_edit; for everyone's ranking use arena_standings. Returns: name, profile (bio, avatarSeed, avatarUrl, profileUrl), cashUsd, startUsd, resets, totals (valueUsd, feesUsd, pnlUsd, pnlPct), open[] and closed[] (the latest 10), each with id, pair, pool, band (lowUsd, highUsd, nowUsd, inRange, rungs, shape), askedUsd, putInUsd, valueUsd, feesWaitingUsd, takenOutUsd, pnlUsd, pnlPct, holds, autopilot, at. Behavior: read-only; values are marked at the pools' price now; play money, nothing real. Costs …
before
—after
{"destructiveHint":false,"idempotentHint":true,"openWorldHint":true,"readOnlyHint":true}before
—after
{"destructiveHint":false,"idempotentHint":true,"openWorldHint":true,"readOnlyHint":true}before
—after
{"destructiveHint":false,"idempotentHint":true,"openWorldHint":true,"readOnlyHint":true}⟨118 unchanged words⟩ ["spot","curve","bidask","hybrid","custom"],"type":"string"},"slippagePct":{ ⟨33 unchanged words⟩ ^0x[0-9a-fA-F]{40}$","type":"string"},"weights":{"description":"shape custom only: the height of each rung, low price to high, 0 to 1, stretched over the rungs built","items":{"maximum":1,"minimum":0,"type":"number"},"maxItems":40,"minItems":1,"type":"array"}},"required":["token","quote" ⟨5 unchanged words⟩
before
—after
{"destructiveHint":false,"idempotentHint":true,"openWorldHint":true,"readOnlyHint":true}⟨311 unchanged words⟩ ["spot","curve","bidask","hybrid","custom"],"type":"string"},"slippagePct":{ ⟨36 unchanged words⟩ ^0x[0-9a-fA-F]{40}$","type":"string"},"weights":{"description":"shape custom only: the height of each rung, low price to high, 0 to 1, stretched over the rungs built","items":{"maximum":1,"minimum":0,"type":"number"},"maxItems":40,"minItems":1,"type":"array"}},"required":["token","owner" ⟨4 unchanged words⟩
before
—after
{"destructiveHint":false,"idempotentHint":true,"openWorldHint":true,"readOnlyHint":true}⟨154 unchanged words⟩ tank when that does not cover one close. On the current LoomLadder: give hands the ladder to another wallet as it is (`to`); delegate lets a wallet run it (`who`, `perms`): a delegate collects, closes or sets rules by naming itself as `actor`, and every payout still goes to the owner.
⟨7 unchanged words⟩ ,"close_part","close","take_nfts","close_once_filled","give","delegate"],"type":"string"},"actor":{"description":"The wallet that will send it, when it is the ladder's delegate and not its owner: it must hold the permission, and the proceeds go to the owner","pattern":"^0x[0-9a-fA-F]{40}$","type":"string"},"contract":{"description":"The LoomLadder the ladder ⟨36 unchanged words⟩ {40}$","type":"string"},"perms":{"description":"delegate: the permissions summed: 1 add, 2 remove (close, close part, take the NFTs, all to the owner), 4 collect (to the owner), 8 rules (autopilot, compounding); 0 ends the delegation","maximum":15,"minimum":0,"type":"integer"},"sharePct":{"maximum":99,"minimum":1, ⟨11 unchanged words⟩ Where the proceeds go; the owner when leftoutout. give: the wallet that gets the ladder","pattern":"^0x[0-9a-fA-F]{40}$","type":"string"},"who":{"description":"delegate: the wallet that may run the ladder","pattern":"^0x[0-9a-fA-F]{40}$" ⟨8 unchanged words⟩
before
—after
{"destructiveHint":false,"idempotentHint":true,"openWorldHint":true,"readOnlyHint":true}before
—after
{"destructiveHint":false,"idempotentHint":true,"openWorldHint":true,"readOnlyHint":true}before
—after
{"destructiveHint":false,"idempotentHint":true,"openWorldHint":true,"readOnlyHint":true}before
—after
{"destructiveHint":false,"idempotentHint":true,"openWorldHint":true,"readOnlyHint":true}This caller's quota — Free to call. What this caller (its key, or its address without one) may still spend: units left this minute and today, what each tool costs, how many plans may run at once, and whether LoomDesk's node is busy right now. Without a key, every caller at the same address shares one quota: a free key (POST https://loomdesk.trade/api/agent/key, then send it as `Authorization: Bearer <key>` or add `?key=<key>` to the MCP URL) gives an agent its own.
⟨315 unchanged words⟩ ,"type":"string"},"slippagePct":{"description":"Left out: 2% on a calm pool, more on one whose price has been moving (set from its last fifteen minutes, at most 10%)","maximum":50,"minimum":0.1,"type":" ⟨19 unchanged words⟩
Earn: one stock pool in full — Everything list_pools knows about one pool plus its v4 pool key, by symbol (LoomDesk's own pool of that stock if there is one, else the deepest) or by pool id.
Earn: tokenized stock pools — Earn, LoomDesk's first product (for ladders in any token, start with market_tokens). Tokenized stock pools on Robinhood Chain with what a dollar of liquidity earned in them (weekly rate at ±5/10/15/25% ranges), how much of those fees the pool kept after arbitrage (keep), depth, and 24h flow. LoomDesk's own pools are marked own: true; those are the pools Earn opens positions in, and the ones a tenth of whose swap fees pay the LoomDesk book. Rates are measurements of the past week, not forecasts.
Earn: quote a stock-pool position and the transactions that open it — For an amount of USDG and a range around the current price in one of LoomDesk's own pools: the 1% fee to open, the stock the desk would buy, the ticks, what the position would have earned per week at the pool's measured rate, and the two transactions (USDG approve, EarnDeskV4.open) that open it, minted to the sender's wallet. Nothing is sent: the caller signs and sends them from its own wallet within 20 minutes. Keep a deposit under maxSensibleDepositUsdg: in a shallow pool a larger buy of the stock side moves the price against you.
OneEarn: one stock pool in full
ListEarn:stock/USDGtokenized stock pools
Earn, LoomDesk's first product (for ladders in any token, start with market_tokens). Tokenized stock pools on Robinhood Chain with what ⟨64 unchanged words⟩
AEarn:wallet'saEarnwallet's positions
⟨48 unchanged words⟩ transaction when the pair has none (feePct 0.1, 0.5 or 1 to 5, about a dollar); the ⟨49 unchanged words⟩
⟨60 unchanged words⟩ rung, one step of the pool wide (2%0.01% in a1%LoomDesk 0.1% pool,up0.1%toin22%a 0.5% pool, 2% in a10%1%poolto 5% pool; other pools by their own spacing, which ladder_pools gives); priceTo makes it a range of up ⟨79 unchanged words⟩ the owner's gas tank. Closing an order earlywhile its token is worth more thantakeswhennothingitofwasaplacedgainpayson theusual share of thatcurrentgain.LoomLadder. Returns the unsigned transactions.
⟨22 unchanged words⟩ v4 pool for it on LoomDesk's open hook (LoomOpenHookV2),withat aflatbase1%fee of 0.1% (rungs from 0.01% wide), 0.5% (from 0.1%) or3%1%swaptofee5% (from 2%): nine tenths to liquidity providers, one tenth to the LoomDeskbook.book, taken in the quote, never in the token. This plans a plain pool; the volatility fee, the launch fee and full-range pools with every fee in the quote (LoomFullHook) are opened from the site's pool form. The quote can be ETH, USDG, a ⟨108 unchanged words⟩
QuoteEarn: quote a stock-pool position andbuildthe transactions that open it
The unsigned transaction for one of a ladder'sexits.exits, or for a limit order's rule. collect: pays the fees earned and leaves the ⟨12 unchanged words⟩ working. close: pays the fees and returnseverything.everything; it is also how a limit order is cancelled (a ladder opened before 30 September 2026 pays a share of a gain: the answer's gainCut). take_nfts: hands the Uniswap position NFTs to the ⟨13 unchanged words⟩ are simulated first and carry minimums from slippagePct. close_once_filled: for a limit order, sets (on, the default) or clears the rule that has the keeper close it once the price has passed all the way through it and pay what it holds as it is; refused on an order that is filled already (close it), and it adds a deposit to the owner's gas tank when that does not cover one close.
⟨6 unchanged words⟩ ["collect","close_part","close","take_nfts","close_once_filled"],"type":"string"},"contract":{ ⟨23 unchanged words⟩ :{"pattern":"^\\d+$","type":"string"},"on":{"description":"close_once_filled only: false clears the rule","type":"boolean"},"owner":{"pattern":"^0x[0-9a-fA-F ⟨42 unchanged words⟩
Place a limit buy or a limit sell — An order at a price: a limit sell holds the token in rungs over the price and sells it as the price rises through them; a limit buy holds the quote under the price and buys as it falls. Placed now in one transaction, nothing is swapped, and it earns the pool's fee while it fills. One price is one rung, one step of the pool wide (2% in a 1% pool, up to 22% in a 10% pool); priceTo makes it a range of up to 40 rungs. Prices are built on the pool's steps: when that moves them more than 1% the plan is refused with the built prices, until they are asked for or acceptBuilt is set. A part fill is not…
AWhennewa tokenoftenhastradesnoonlypoolinagainstitsthelaunchpad'squotepool,wantedwhere(ladder_poolstheshowshooknone,keepsorthenonewholethatfee.paysThisliquidity):plansplan a new Uniswap v4 pool forthe tokenit on LoomDesk's open hook,against ETH or USDG,with a flat 1% or 3% swap fee: nine tenths to liquidity providers, one tenth to the LoomDesk book. The quote can be ETH, USDG, a tokenized stock, LOOM, or any token with a real exit (2,000 USDG of liquidity on the chain and a route to USDG): LOOM/PONS, a memecoin against a memecoin. One-off cost0.002aboutETHa dollar (1 USDG or50.0004USDG.ETH), paid by the owner. It opens at the price of the token's ⟨11 unchanged words⟩ routers send; a new pool starts with neither.AfterTheopening,poolcallholdsplan_laddernothingwithuntil a ladder is built in it: thereturnedresult's `then` carries the pool id:and key for plan_ladder (with newPool), so the poolholdsandnothingtheuntilladdersomeonecanbuildsbe planned together and signed init.order.
{"$schema":"https://json-schema.org/draft/2020-12/schema","properties":{"feePct":{"anyOfdescription":[{"const"the pool's swap fee in percent: 1,"type2, 3, 4 or 5":,"numbermaximum"}:5,{"constminimum":31,"type":"numberinteger"}]},"owner":{"pattern":"^0x[0-9a-fA-F]{40}$","type":"string"},"quote":{"anyOf":[{"enum":["ETH","USDG"],"type":"string"},{"pattern":"^0x[0-9a-fA-F]{40}$","type":"string"}],"description":"\"ETH\", \"USDG\", or the address of the quote token: a tokenized stock, LOOM, or any token with an exit"},"token":{"pattern":"^0x[0-9a-fA-F ⟨11 unchanged words⟩
One transaction from ETH or USDG to a ladder, the pool opened on the way — One transaction (two when paying in USDG: its approval first) from ETH or USDG to a ladder in a v4 pool of the token against the quote (ETH, USDG, LOOM, a stock, a memecoin with an exit). The pool is opened on LoomDesk's hook inside the same transaction when the pair has none (feePct 1 to 5, about a dollar); the sides the wallet's asset is not are bought through Nordstern inside it, split by the band; the pool's fee is paid from it; the ladder is built for the owner; leftovers come back. Prefer it over plan_swap + plan_open_pool + plan_ladder whenever the caller pays in ETH or USDG.
Buy a side a plan needs, through Nordstern — The unsigned transactions for a swap on the chain through Nordstern's aggregator (an approval of the router when paying with a token, then the route), with what it returns and the least it may. For a pair the caller wants but only holds ETH or USDG for: one plan_swap per missing side, then plan_ladder with to.atLeast as that side's amount. Nothing is signed here.