[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-uniswap-copy-trade":3,"mdc--yl2z64-key":36,"related-org-uniswap-copy-trade":1596,"related-repo-uniswap-copy-trade":1742},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":25,"repoUrl":26,"updatedAt":27,"license":28,"forks":29,"topics":30,"repo":31,"sourceUrl":34,"mdContent":35},"copy-trade","copy trades from crypto wallets","This skill should be used when the user asks to \"copy trades from\" a wallet, \"mirror a wallet\", \"follow this address\", set up \"copy trading\", \"track and replicate a trader\", or mirror another account's swaps bounded by guardrails. Watches a target wallet and mirrors its trades, filtered by chain, asset match, position size, and the follower's own portfolio state.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},"uniswap","Uniswap","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Funiswap.png",[12,16,19,22],{"name":13,"slug":14,"type":15},"Automation","automation","tag",{"name":17,"slug":18,"type":15},"Web3","web3",{"name":20,"slug":21,"type":15},"Trading","trading",{"name":23,"slug":24,"type":15},"Ethereum","ethereum",215,"https:\u002F\u002Fgithub.com\u002FUniswap\u002Funiswap-ai","2026-07-17T06:04:21.974052","MIT",35,[],{"repoUrl":26,"stars":25,"forks":29,"topics":32,"description":33},[],"AI tools for building on Uniswap — skills, plugins, and agents for any coding agent.","https:\u002F\u002Fgithub.com\u002FUniswap\u002Funiswap-ai\u002Ftree\u002FHEAD\u002Fpackages\u002Fplugins\u002Funiswap-trading-tools\u002Fskills\u002Fcopy-trade","---\nname: copy-trade\ndescription: This skill should be used when the user asks to \"copy trades from\" a wallet, \"mirror a wallet\", \"follow this address\", set up \"copy trading\", \"track and replicate a trader\", or mirror another account's swaps bounded by guardrails. Watches a target wallet and mirrors its trades, filtered by chain, asset match, position size, and the follower's own portfolio state.\nallowed-tools: Read, Write, Edit, Glob, Grep, Bash(npm:*), Bash(npx:*), Bash(curl:*), WebFetch, AskUserQuestion\nmodel: sonnet\nlicense: MIT\nmetadata:\n  author: uniswap\n  version: '0.2.0'\nprerequisites:\n  - swap-integration\n  - viem-integration\n---\n\n# Copy Trade\n\nWatch a target (\"leader\") wallet on the target chain and mirror its swaps into the follower's wallet, bounded by guardrails. This is a thin strategy layer: it decides what to mirror and whether to mirror it, then delegates the actual swap to `swap-integration` and `viem-integration`. The skill never builds quote, approval, swap, or signing logic itself.\n\n> **Runtime Compatibility:** This skill uses `AskUserQuestion` for execution-mode and confirmation prompts. If `AskUserQuestion` is not available in your runtime, collect the same parameters and confirmations through natural language conversation instead.\n\n## Overview\n\nThe host scheduler invokes this skill on a cadence (about every 5 minutes). Each invocation is a single, self-contained, deterministic run:\n\n1. Read the stored cursor (last processed block).\n2. Read the leader wallet's new on-chain actions since the cursor.\n3. For each new action, apply guardrails.\n4. For actions that pass, delegate the mirror swap to `swap-integration`.\n5. Advance the cursor and record which leader actions were mirrored.\n\nTreat this as a state machine, not free-form reasoning. Read state, diff against the chain, decide per action, act, advance the cursor. Do not infer intent beyond what the on-chain events say, and never re-derive a decision a prior run already recorded.\n\n## Prerequisites\n\nThis skill delegates all infrastructure. It never reimplements quoting, approval, signing, or swap construction.\n\n- **swap-integration** (uniswap-trading): the only execution path. Every mirror swap goes through its Trading API flow (`check_approval` then `quote` then `swap`, then sign and broadcast). Do not reimplement any of it.\n- **viem-integration** (uniswap-viem): accounts, clients, signing, transaction broadcast, and reading the leader wallet's activity. Read the leader's transactions and receipts since the cursor block to detect swaps (see Step 2).\n\nRead these plugin references before acting and treat them as ground truth:\n\n- selected target-chain template: chainId, chain name, contract addresses, tradable token source, RPC \u002F read path, indexing availability, funding constraints, and template-specific caveats. For the reference Robinhood Chain template, see `..\u002F..\u002Freferences\u002Frobinhood-chain.md`.\n- `..\u002F..\u002Freferences\u002Fexecution-model.md`: the Trading API requirement, execution modes, restrictions, and disclaimer rules.\n- `..\u002F..\u002Freferences\u002Fstrategy-state.md`: the shared state file and scheduler pattern.\n\n## Template inputs\n\nThe selected target-chain template must provide:\n\n- chain id, chain name, native gas token, and RPC \u002F read path.\n- deployed Uniswap router, Permit2, PoolManager, and v2\u002Fv3\u002Fv4 pool factory \u002F reader addresses needed to decode leader activity.\n- whether a public indexer exists; if not, the skill polls RPC and scans bounded block ranges.\n- tradable token resolution rules, including any token list or allowlist source.\n- funding constraints, transfer-restriction caveats, and market-hours guidance.\n\n## Workflow (deterministic state machine)\n\n### Step 1: Read state cursor\n\nLoad the JSON state file (shape in `strategy-state.md`). For copy-trade the relevant fields are the last processed cursor (block or log position) and the set of leader intents already mirrored (keyed at the transaction level by `leaderTxHash`, plus a sub-index when one tx yields more than one independent intent; see Step 2). If no state file exists, this is the first run: initialize the cursor to the current head block and mirror nothing on this pass (avoid replaying the leader's full history unless the operator explicitly opts in).\n\nThis first-run-at-head behavior is skill-specific, not template-specific. It prevents accidental history replay on any target chain.\n\n### Step 2: Read leader actions since the cursor\n\nDetect the leader's swaps by scanning the leader's own transactions, not by topic-filtering pool events on the leader address. The pool `Swap` events do not carry the leader EOA: v2 indexes `sender`\u002F`to` and v3 indexes `recipient` (all of which are the router when the trade routes through UniversalRouter \u002F SwapRouter02, not the leader), and v4 `Swap` indexes only `PoolId` and `sender` (the PoolManager's caller, again the router). A `getLogs` filter keyed on the leader address therefore returns nothing for router-routed trades. Instead:\n\n1. Iterate blocks in the range `(cursor, head]` and select transactions where `tx.from` equals the leader. (Use viem's block\u002Ftransaction reads via `viem-integration`; scan in bounded ranges to respect RPC limits.)\n2. For each such transaction, fetch its receipt and decode the `Swap` logs it contains. A single leader transaction may emit one or more `Swap` logs (a multi-hop route emits one log per leg; a batch\u002Fmulticall emits one log per independent swap). The protocol version is identified by the emitting contract: a v4 `Swap` is emitted by the `PoolManager`; v2\u002Fv3 `Swap` logs are emitted by individual pool contracts.\n3. Resolve each pool to its token pair before deciding direction. v2\u002Fv3 `Swap` logs do not name the tokens -- read `token0()` \u002F `token1()` on the emitting pool (or decode the v4 `PoolKey` from the `PoolId`) to learn the pair. The token addresses come from these reads plus the selected target-chain template; never invent them. Pool `Swap` logs always reference `WETH` (the ERC-20), never native `ETH`: a native-ETH leg is a router wrap\u002Funwrap and emits no ERC-20 `Swap` event. Canonicalize any leg token that resolves to `WETH` as `WETH` here, and apply the ETH\u002FWETH normalization rule in `execution-model.md` when matching against the allowlist (Step 3).\n4. Determine in vs out from the amount signs, and mind that v3 and v4 use opposite sign conventions. v2 reports unsigned `amount0In\u002Famount1In\u002Famount0Out\u002Famount1Out`; the non-zero `*In` token is `tokenIn`. v3 (`int256`) reports the pool's balance delta, so a positive amount is the token flowing into the pool (`tokenIn`) and a negative amount is the token flowing out (`tokenOut`). v4 (`int128`) reports the swapper's delta instead, which is inverted: a negative amount is the token the swapper paid in (`tokenIn`) and a positive amount is the token the swapper received (`tokenOut`). (v4's `Swap` NatSpec reuses v3's pool-balance wording, but the contract emits the swapper's signed `BalanceDelta`, verified against live v4 swaps; follow the swapper-delta convention.) After assigning direction, take `amountIn`\u002F`amountOut` as the absolute values.\n\nNow decode each leg into `{ tokenIn, tokenOut, amountIn, amountOut, leaderTxHash, logIndex, blockNumber }`. Within a single leader transaction, collapse legs that form one route before producing the actions to mirror:\n\n- **Chain legs by matching `tokenOut` -> `tokenIn`.** A leg whose `tokenOut` equals the next leg's `tokenIn` (within the same tx, in `logIndex` order) is part of the same route. A maximal such chain collapses to a single net intent: `tokenIn` = first leg's `tokenIn`, `tokenOut` = last leg's `tokenOut`, `amountIn` = first leg's `amountIn`, `amountOut` = last leg's `amountOut`. Drop the intermediate legs. (Example: `USDG -> WETH -> AAAx` is two `Swap` logs that collapse to one intent `USDG -> AAAx`; mirroring both legs would wrongly buy the intermediate `WETH` and then spend it again.) If a collapsed chain returns to its starting token so the net `tokenIn` equals `tokenOut` (for example an arbitrage round-trip `USDG -> WETH -> USDG`), it is a net no-op: drop it and mirror nothing for that chain.\n- **Independent swaps stay separate.** A transaction may instead be a batch \u002F multicall whose legs do not chain (no leg's `tokenOut` feeds another leg's `tokenIn`). Those are independent swaps, not a route: each is its own net intent and is mirrored separately.\n\nThe result is one mirror intent per maximal chain (and one per independent leg). Key each resulting intent at the transaction level by `leaderTxHash`. When a single tx yields more than one independent intent, append a sub-index equal to the `logIndex` of that intent's first leg; `logIndex` is immutable per transaction, so the key is reproducible across re-scans and crash recovery, and a multi-hop route mirrors at most once. A tx that yields a single intent uses `leaderTxHash` alone. Sort the resulting intents by `(blockNumber, first-leg logIndex)` so processing is deterministic.\n\n> **IMPORTANT: read activity according to the selected template.** If the template does not provide a public indexer, poll the RPC and scan logs directly against the deployed contracts. Scan in bounded block ranges to respect RPC `getLogs` limits, and persist the cursor every run so successive ranges normally do not overlap; the Step 3 idempotency guardrail (skip any `leaderTxHash` intent already mirrored) is what keeps an overlapping range safe when the cursor did not advance (e.g. after a crash).\n\n### Step 3: Apply guardrails per action\n\nProcess each new action in order. Skip (do not mirror) any action that fails a guardrail, and record the skip reason. Guardrails:\n\nBefore processing actions, read configured guardrails. If the per-mirror, per-run, or per-period spend cap is missing, ask the operator for those caps using `AskUserQuestion` (or natural language if unavailable); include the funding token or denomination used for comparison. If any cap remains unset, do not enter `autonomous` mode. In `confirm` mode, proceed only with per-mirror confirmation and report that autonomous mode remains unavailable.\n\n| Guardrail         | Rule                                                                                                                                                                                                                                                                                                                                                                                                                                                              |\n| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Chain filter      | Action must be on the selected target chain. Ignore anything else.                                                                                                                                                                                                                                                                                                                                                                                                |\n| Asset match       | Both `tokenIn` and `tokenOut` must be in the operator's allowed token set (default: tradable tokens from the selected template). `ETH` and `WETH` are equivalent for this match: a leg decoded as `WETH` (pool logs always reference the ERC-20, per Step 2) satisfies an `ETH` or a `WETH` allowlist entry, so a WETH-decoded leg is never falsely skipped against an ETH entry. Apply the ETH\u002FWETH normalization rule in `execution-model.md` before comparing. |\n| Position-size cap | Mirror amount must not exceed the per-trade cap and the per-period spend cap. Scale or skip if over.                                                                                                                                                                                                                                                                                                                                                              |\n| Follower balance  | The follower wallet must hold enough `tokenIn` (and gas) to execute. If not, skip and report.                                                                                                                                                                                                                                                                                                                                                                     |\n| Idempotency       | If this intent's `leaderTxHash` (with its sub-index, if any) is already in the mirrored set, skip; never double-mirror. Keying at the transaction level means a multi-hop route mirrors at most once.                                                                                                                                                                                                                                                             |\n\nPosition sizing is operator-chosen: either a fixed notional per mirrored trade, or a proportion of the leader's amount, always clamped to the caps above. Never mirror more than the caps allow.\n\n### Step 4: Delegate the mirror swap\n\nFor each intent that passes all guardrails, hand off to `swap-integration`. Pass the target chain id and token addresses from the selected template. The Trading API flow (`check_approval` then `quote` then `swap`) handles routing, approvals, Permit2, signing, and broadcast. This skill supplies only: `tokenIn`, `tokenOut`, the sized `amount`, the target chain id, and the follower's wallet. Do not reimplement quote, approval, swap, or signing logic. The execution form for an ETH\u002FWETH leg (native `ETH` vs wrapped `WETH`, and any wrap\u002Funwrap) is owned by the `swap-integration` Trading API path: do not assume the follower mirror must use the same form the leader used, and do not hand-roll a wrap\u002Funwrap. Pass the canonicalized token and let the Trading API choose the form.\n\n### Step 5: Advance cursor and record\n\nWrite state to disk immediately after each leader intent resolves -- do not batch the writes to the end of the run. As each intent resolves (broadcast confirmed, or recorded skip), append its `leaderTxHash` key (with sub-index, if any) to the mirrored (or skipped) set with the result and the follower tx hash, then persist. Advance the durable `cursor` only past intents whose records are already committed, so a partially processed range is never marked done. This per-intent write is the idempotency guarantee: if the run crashes mid-batch after a broadcast confirms, the record for that intent is already on disk, and the idempotency check in Step 3 skips it on the next wake. Batching the writes to run-exit would leave already-broadcast mirrors unrecorded on a mid-run crash and re-mirror them with real funds.\n\n## Execution mode\n\nExpose the execution mode from `execution-model.md`, chosen by the operator:\n\n| Mode                | Behavior                                                                                                                                                                                     |\n| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `confirm` (default) | Use `AskUserQuestion` to confirm each mirror swap before broadcast, showing tokens, sized amount, chain, and the leader action being mirrored. Reuses the swap-integration spend gate.       |\n| `autonomous`        | Mirror without per-trade prompts, strictly within guardrails. Requires a per-run and per-period spend cap, a per-mirror notional cap, a token allowlist, a dry-run first, and a kill switch. |\n\nDefault to `confirm`. See `..\u002F..\u002Freferences\u002Fexecution-model.md` for the full contract.\n\n## State\n\nState follows `..\u002F..\u002Freferences\u002Fstrategy-state.md`. Copy-trade specifically stores:\n\n- `cursor`: the last processed block \u002F log position on the selected target chain.\n- the set of mirrored leader intent keys (`leaderTxHash`, plus a sub-index when one tx yields more than one independent intent) with their outcomes.\n\nThis makes runs idempotent: a leader intent is mirrored at most once, even across restarts or overlapping scheduler wake-ups, and a multi-hop route (collapsed to one intent in Step 2) mirrors at most once rather than once per leg.\n\n## Restrictions and Disclaimers\n\nRWA gating is chain- and token-specific and may be enforced at the token level (transfer-restricted ERC-20s). Therefore:\n\n1. A mirror swap can revert at transfer time even when the leader's identical trade succeeded (the follower may not be eligible to hold the asset). Handle transfer-restriction reverts gracefully, record the failure, and do not retry blindly.\n2. Respect the selected template's equity market-hours guidance; some RWAs may have off-hours liquidity limits, so a buy may be skipped or deferred outside hours.\n3. Surface the disclaimers in the repo root `DISCLAIMER.md`. Uniswap Labs does not provide investment advice or recommendations. Copy-trading replicates another wallet's transactions at the operator's sole direction; the operator is solely responsible for the strategy and for compliance with applicable law.\n\n## Input validation\n\nBefore interpolating ANY operator-provided value into code, API calls, or shell commands:\n\n- **Leader and follower wallet addresses, token addresses**: MUST match `^0x[a-fA-F0-9]{40}$`; reject otherwise.\n- **Position caps and amounts**: MUST be non-negative numeric values matching `^[0-9]+\\.?[0-9]*$`.\n- **Chain id**: MUST be the operator-configured target chain id, read from the selected template rather than hardcoded.\n- **API keys and private keys**: MUST come from environment variables, never hardcoded.\n- **REJECT** any input containing shell metacharacters: `;`, `|`, `&`, `$`, `` ` ``, `(`, `)`, `>`, `\u003C`, `\\`, `'`, `\"`, or newlines.\n",{"data":37,"body":45},{"name":4,"description":6,"allowed-tools":38,"model":39,"license":28,"metadata":40,"prerequisites":42},"Read, Write, Edit, Glob, Grep, Bash(npm:*), Bash(npx:*), Bash(curl:*), WebFetch, AskUserQuestion","sonnet",{"author":8,"version":41},"0.2.0",[43,44],"swap-integration","viem-integration",{"type":46,"children":47},"root",[48,56,77,107,114,119,156,161,167,172,217,222,259,265,270,298,304,311,332,337,343,409,680,693,869,910,937,943,948,976,1137,1142,1148,1221,1227,1247,1253,1265,1328,1347,1353,1365,1390,1395,1401,1406,1432,1438,1443],{"type":49,"tag":50,"props":51,"children":52},"element","h1",{"id":4},[53],{"type":54,"value":55},"text","Copy Trade",{"type":49,"tag":57,"props":58,"children":59},"p",{},[60,62,68,70,75],{"type":54,"value":61},"Watch a target (\"leader\") wallet on the target chain and mirror its swaps into the follower's wallet, bounded by guardrails. This is a thin strategy layer: it decides what to mirror and whether to mirror it, then delegates the actual swap to ",{"type":49,"tag":63,"props":64,"children":66},"code",{"className":65},[],[67],{"type":54,"value":43},{"type":54,"value":69}," and ",{"type":49,"tag":63,"props":71,"children":73},{"className":72},[],[74],{"type":54,"value":44},{"type":54,"value":76},". The skill never builds quote, approval, swap, or signing logic itself.",{"type":49,"tag":78,"props":79,"children":80},"blockquote",{},[81],{"type":49,"tag":57,"props":82,"children":83},{},[84,90,92,98,100,105],{"type":49,"tag":85,"props":86,"children":87},"strong",{},[88],{"type":54,"value":89},"Runtime Compatibility:",{"type":54,"value":91}," This skill uses ",{"type":49,"tag":63,"props":93,"children":95},{"className":94},[],[96],{"type":54,"value":97},"AskUserQuestion",{"type":54,"value":99}," for execution-mode and confirmation prompts. If ",{"type":49,"tag":63,"props":101,"children":103},{"className":102},[],[104],{"type":54,"value":97},{"type":54,"value":106}," is not available in your runtime, collect the same parameters and confirmations through natural language conversation instead.",{"type":49,"tag":108,"props":109,"children":111},"h2",{"id":110},"overview",[112],{"type":54,"value":113},"Overview",{"type":49,"tag":57,"props":115,"children":116},{},[117],{"type":54,"value":118},"The host scheduler invokes this skill on a cadence (about every 5 minutes). Each invocation is a single, self-contained, deterministic run:",{"type":49,"tag":120,"props":121,"children":122},"ol",{},[123,129,134,139,151],{"type":49,"tag":124,"props":125,"children":126},"li",{},[127],{"type":54,"value":128},"Read the stored cursor (last processed block).",{"type":49,"tag":124,"props":130,"children":131},{},[132],{"type":54,"value":133},"Read the leader wallet's new on-chain actions since the cursor.",{"type":49,"tag":124,"props":135,"children":136},{},[137],{"type":54,"value":138},"For each new action, apply guardrails.",{"type":49,"tag":124,"props":140,"children":141},{},[142,144,149],{"type":54,"value":143},"For actions that pass, delegate the mirror swap to ",{"type":49,"tag":63,"props":145,"children":147},{"className":146},[],[148],{"type":54,"value":43},{"type":54,"value":150},".",{"type":49,"tag":124,"props":152,"children":153},{},[154],{"type":54,"value":155},"Advance the cursor and record which leader actions were mirrored.",{"type":49,"tag":57,"props":157,"children":158},{},[159],{"type":54,"value":160},"Treat this as a state machine, not free-form reasoning. Read state, diff against the chain, decide per action, act, advance the cursor. Do not infer intent beyond what the on-chain events say, and never re-derive a decision a prior run already recorded.",{"type":49,"tag":108,"props":162,"children":164},{"id":163},"prerequisites",[165],{"type":54,"value":166},"Prerequisites",{"type":49,"tag":57,"props":168,"children":169},{},[170],{"type":54,"value":171},"This skill delegates all infrastructure. It never reimplements quoting, approval, signing, or swap construction.",{"type":49,"tag":173,"props":174,"children":175},"ul",{},[176,208],{"type":49,"tag":124,"props":177,"children":178},{},[179,183,185,191,193,199,200,206],{"type":49,"tag":85,"props":180,"children":181},{},[182],{"type":54,"value":43},{"type":54,"value":184}," (uniswap-trading): the only execution path. Every mirror swap goes through its Trading API flow (",{"type":49,"tag":63,"props":186,"children":188},{"className":187},[],[189],{"type":54,"value":190},"check_approval",{"type":54,"value":192}," then ",{"type":49,"tag":63,"props":194,"children":196},{"className":195},[],[197],{"type":54,"value":198},"quote",{"type":54,"value":192},{"type":49,"tag":63,"props":201,"children":203},{"className":202},[],[204],{"type":54,"value":205},"swap",{"type":54,"value":207},", then sign and broadcast). Do not reimplement any of it.",{"type":49,"tag":124,"props":209,"children":210},{},[211,215],{"type":49,"tag":85,"props":212,"children":213},{},[214],{"type":54,"value":44},{"type":54,"value":216}," (uniswap-viem): accounts, clients, signing, transaction broadcast, and reading the leader wallet's activity. Read the leader's transactions and receipts since the cursor block to detect swaps (see Step 2).",{"type":49,"tag":57,"props":218,"children":219},{},[220],{"type":54,"value":221},"Read these plugin references before acting and treat them as ground truth:",{"type":49,"tag":173,"props":223,"children":224},{},[225,237,248],{"type":49,"tag":124,"props":226,"children":227},{},[228,230,236],{"type":54,"value":229},"selected target-chain template: chainId, chain name, contract addresses, tradable token source, RPC \u002F read path, indexing availability, funding constraints, and template-specific caveats. For the reference Robinhood Chain template, see ",{"type":49,"tag":63,"props":231,"children":233},{"className":232},[],[234],{"type":54,"value":235},"..\u002F..\u002Freferences\u002Frobinhood-chain.md",{"type":54,"value":150},{"type":49,"tag":124,"props":238,"children":239},{},[240,246],{"type":49,"tag":63,"props":241,"children":243},{"className":242},[],[244],{"type":54,"value":245},"..\u002F..\u002Freferences\u002Fexecution-model.md",{"type":54,"value":247},": the Trading API requirement, execution modes, restrictions, and disclaimer rules.",{"type":49,"tag":124,"props":249,"children":250},{},[251,257],{"type":49,"tag":63,"props":252,"children":254},{"className":253},[],[255],{"type":54,"value":256},"..\u002F..\u002Freferences\u002Fstrategy-state.md",{"type":54,"value":258},": the shared state file and scheduler pattern.",{"type":49,"tag":108,"props":260,"children":262},{"id":261},"template-inputs",[263],{"type":54,"value":264},"Template inputs",{"type":49,"tag":57,"props":266,"children":267},{},[268],{"type":54,"value":269},"The selected target-chain template must provide:",{"type":49,"tag":173,"props":271,"children":272},{},[273,278,283,288,293],{"type":49,"tag":124,"props":274,"children":275},{},[276],{"type":54,"value":277},"chain id, chain name, native gas token, and RPC \u002F read path.",{"type":49,"tag":124,"props":279,"children":280},{},[281],{"type":54,"value":282},"deployed Uniswap router, Permit2, PoolManager, and v2\u002Fv3\u002Fv4 pool factory \u002F reader addresses needed to decode leader activity.",{"type":49,"tag":124,"props":284,"children":285},{},[286],{"type":54,"value":287},"whether a public indexer exists; if not, the skill polls RPC and scans bounded block ranges.",{"type":49,"tag":124,"props":289,"children":290},{},[291],{"type":54,"value":292},"tradable token resolution rules, including any token list or allowlist source.",{"type":49,"tag":124,"props":294,"children":295},{},[296],{"type":54,"value":297},"funding constraints, transfer-restriction caveats, and market-hours guidance.",{"type":49,"tag":108,"props":299,"children":301},{"id":300},"workflow-deterministic-state-machine",[302],{"type":54,"value":303},"Workflow (deterministic state machine)",{"type":49,"tag":305,"props":306,"children":308},"h3",{"id":307},"step-1-read-state-cursor",[309],{"type":54,"value":310},"Step 1: Read state cursor",{"type":49,"tag":57,"props":312,"children":313},{},[314,316,322,324,330],{"type":54,"value":315},"Load the JSON state file (shape in ",{"type":49,"tag":63,"props":317,"children":319},{"className":318},[],[320],{"type":54,"value":321},"strategy-state.md",{"type":54,"value":323},"). For copy-trade the relevant fields are the last processed cursor (block or log position) and the set of leader intents already mirrored (keyed at the transaction level by ",{"type":49,"tag":63,"props":325,"children":327},{"className":326},[],[328],{"type":54,"value":329},"leaderTxHash",{"type":54,"value":331},", plus a sub-index when one tx yields more than one independent intent; see Step 2). If no state file exists, this is the first run: initialize the cursor to the current head block and mirror nothing on this pass (avoid replaying the leader's full history unless the operator explicitly opts in).",{"type":49,"tag":57,"props":333,"children":334},{},[335],{"type":54,"value":336},"This first-run-at-head behavior is skill-specific, not template-specific. It prevents accidental history replay on any target chain.",{"type":49,"tag":305,"props":338,"children":340},{"id":339},"step-2-read-leader-actions-since-the-cursor",[341],{"type":54,"value":342},"Step 2: Read leader actions since the cursor",{"type":49,"tag":57,"props":344,"children":345},{},[346,348,354,356,362,364,370,372,378,380,385,387,393,394,399,401,407],{"type":54,"value":347},"Detect the leader's swaps by scanning the leader's own transactions, not by topic-filtering pool events on the leader address. The pool ",{"type":49,"tag":63,"props":349,"children":351},{"className":350},[],[352],{"type":54,"value":353},"Swap",{"type":54,"value":355}," events do not carry the leader EOA: v2 indexes ",{"type":49,"tag":63,"props":357,"children":359},{"className":358},[],[360],{"type":54,"value":361},"sender",{"type":54,"value":363},"\u002F",{"type":49,"tag":63,"props":365,"children":367},{"className":366},[],[368],{"type":54,"value":369},"to",{"type":54,"value":371}," and v3 indexes ",{"type":49,"tag":63,"props":373,"children":375},{"className":374},[],[376],{"type":54,"value":377},"recipient",{"type":54,"value":379}," (all of which are the router when the trade routes through UniversalRouter \u002F SwapRouter02, not the leader), and v4 ",{"type":49,"tag":63,"props":381,"children":383},{"className":382},[],[384],{"type":54,"value":353},{"type":54,"value":386}," indexes only ",{"type":49,"tag":63,"props":388,"children":390},{"className":389},[],[391],{"type":54,"value":392},"PoolId",{"type":54,"value":69},{"type":49,"tag":63,"props":395,"children":397},{"className":396},[],[398],{"type":54,"value":361},{"type":54,"value":400}," (the PoolManager's caller, again the router). A ",{"type":49,"tag":63,"props":402,"children":404},{"className":403},[],[405],{"type":54,"value":406},"getLogs",{"type":54,"value":408}," filter keyed on the leader address therefore returns nothing for router-routed trades. Instead:",{"type":49,"tag":120,"props":410,"children":411},{},[412,440,481,576],{"type":49,"tag":124,"props":413,"children":414},{},[415,417,423,425,431,433,438],{"type":54,"value":416},"Iterate blocks in the range ",{"type":49,"tag":63,"props":418,"children":420},{"className":419},[],[421],{"type":54,"value":422},"(cursor, head]",{"type":54,"value":424}," and select transactions where ",{"type":49,"tag":63,"props":426,"children":428},{"className":427},[],[429],{"type":54,"value":430},"tx.from",{"type":54,"value":432}," equals the leader. (Use viem's block\u002Ftransaction reads via ",{"type":49,"tag":63,"props":434,"children":436},{"className":435},[],[437],{"type":54,"value":44},{"type":54,"value":439},"; scan in bounded ranges to respect RPC limits.)",{"type":49,"tag":124,"props":441,"children":442},{},[443,445,450,452,457,459,464,466,472,474,479],{"type":54,"value":444},"For each such transaction, fetch its receipt and decode the ",{"type":49,"tag":63,"props":446,"children":448},{"className":447},[],[449],{"type":54,"value":353},{"type":54,"value":451}," logs it contains. A single leader transaction may emit one or more ",{"type":49,"tag":63,"props":453,"children":455},{"className":454},[],[456],{"type":54,"value":353},{"type":54,"value":458}," logs (a multi-hop route emits one log per leg; a batch\u002Fmulticall emits one log per independent swap). The protocol version is identified by the emitting contract: a v4 ",{"type":49,"tag":63,"props":460,"children":462},{"className":461},[],[463],{"type":54,"value":353},{"type":54,"value":465}," is emitted by the ",{"type":49,"tag":63,"props":467,"children":469},{"className":468},[],[470],{"type":54,"value":471},"PoolManager",{"type":54,"value":473},"; v2\u002Fv3 ",{"type":49,"tag":63,"props":475,"children":477},{"className":476},[],[478],{"type":54,"value":353},{"type":54,"value":480}," logs are emitted by individual pool contracts.",{"type":49,"tag":124,"props":482,"children":483},{},[484,486,491,493,499,501,507,509,515,517,522,524,529,531,537,539,545,547,552,554,559,561,566,568,574],{"type":54,"value":485},"Resolve each pool to its token pair before deciding direction. v2\u002Fv3 ",{"type":49,"tag":63,"props":487,"children":489},{"className":488},[],[490],{"type":54,"value":353},{"type":54,"value":492}," logs do not name the tokens -- read ",{"type":49,"tag":63,"props":494,"children":496},{"className":495},[],[497],{"type":54,"value":498},"token0()",{"type":54,"value":500}," \u002F ",{"type":49,"tag":63,"props":502,"children":504},{"className":503},[],[505],{"type":54,"value":506},"token1()",{"type":54,"value":508}," on the emitting pool (or decode the v4 ",{"type":49,"tag":63,"props":510,"children":512},{"className":511},[],[513],{"type":54,"value":514},"PoolKey",{"type":54,"value":516}," from the ",{"type":49,"tag":63,"props":518,"children":520},{"className":519},[],[521],{"type":54,"value":392},{"type":54,"value":523},") to learn the pair. The token addresses come from these reads plus the selected target-chain template; never invent them. Pool ",{"type":49,"tag":63,"props":525,"children":527},{"className":526},[],[528],{"type":54,"value":353},{"type":54,"value":530}," logs always reference ",{"type":49,"tag":63,"props":532,"children":534},{"className":533},[],[535],{"type":54,"value":536},"WETH",{"type":54,"value":538}," (the ERC-20), never native ",{"type":49,"tag":63,"props":540,"children":542},{"className":541},[],[543],{"type":54,"value":544},"ETH",{"type":54,"value":546},": a native-ETH leg is a router wrap\u002Funwrap and emits no ERC-20 ",{"type":49,"tag":63,"props":548,"children":550},{"className":549},[],[551],{"type":54,"value":353},{"type":54,"value":553}," event. Canonicalize any leg token that resolves to ",{"type":49,"tag":63,"props":555,"children":557},{"className":556},[],[558],{"type":54,"value":536},{"type":54,"value":560}," as ",{"type":49,"tag":63,"props":562,"children":564},{"className":563},[],[565],{"type":54,"value":536},{"type":54,"value":567}," here, and apply the ETH\u002FWETH normalization rule in ",{"type":49,"tag":63,"props":569,"children":571},{"className":570},[],[572],{"type":54,"value":573},"execution-model.md",{"type":54,"value":575}," when matching against the allowlist (Step 3).",{"type":49,"tag":124,"props":577,"children":578},{},[579,581,587,589,595,597,603,605,611,613,618,620,626,628,634,636,641,643,648,650,655,657,663,665,671,672,678],{"type":54,"value":580},"Determine in vs out from the amount signs, and mind that v3 and v4 use opposite sign conventions. v2 reports unsigned ",{"type":49,"tag":63,"props":582,"children":584},{"className":583},[],[585],{"type":54,"value":586},"amount0In\u002Famount1In\u002Famount0Out\u002Famount1Out",{"type":54,"value":588},"; the non-zero ",{"type":49,"tag":63,"props":590,"children":592},{"className":591},[],[593],{"type":54,"value":594},"*In",{"type":54,"value":596}," token is ",{"type":49,"tag":63,"props":598,"children":600},{"className":599},[],[601],{"type":54,"value":602},"tokenIn",{"type":54,"value":604},". v3 (",{"type":49,"tag":63,"props":606,"children":608},{"className":607},[],[609],{"type":54,"value":610},"int256",{"type":54,"value":612},") reports the pool's balance delta, so a positive amount is the token flowing into the pool (",{"type":49,"tag":63,"props":614,"children":616},{"className":615},[],[617],{"type":54,"value":602},{"type":54,"value":619},") and a negative amount is the token flowing out (",{"type":49,"tag":63,"props":621,"children":623},{"className":622},[],[624],{"type":54,"value":625},"tokenOut",{"type":54,"value":627},"). v4 (",{"type":49,"tag":63,"props":629,"children":631},{"className":630},[],[632],{"type":54,"value":633},"int128",{"type":54,"value":635},") reports the swapper's delta instead, which is inverted: a negative amount is the token the swapper paid in (",{"type":49,"tag":63,"props":637,"children":639},{"className":638},[],[640],{"type":54,"value":602},{"type":54,"value":642},") and a positive amount is the token the swapper received (",{"type":49,"tag":63,"props":644,"children":646},{"className":645},[],[647],{"type":54,"value":625},{"type":54,"value":649},"). (v4's ",{"type":49,"tag":63,"props":651,"children":653},{"className":652},[],[654],{"type":54,"value":353},{"type":54,"value":656}," NatSpec reuses v3's pool-balance wording, but the contract emits the swapper's signed ",{"type":49,"tag":63,"props":658,"children":660},{"className":659},[],[661],{"type":54,"value":662},"BalanceDelta",{"type":54,"value":664},", verified against live v4 swaps; follow the swapper-delta convention.) After assigning direction, take ",{"type":49,"tag":63,"props":666,"children":668},{"className":667},[],[669],{"type":54,"value":670},"amountIn",{"type":54,"value":363},{"type":49,"tag":63,"props":673,"children":675},{"className":674},[],[676],{"type":54,"value":677},"amountOut",{"type":54,"value":679}," as the absolute values.",{"type":49,"tag":57,"props":681,"children":682},{},[683,685,691],{"type":54,"value":684},"Now decode each leg into ",{"type":49,"tag":63,"props":686,"children":688},{"className":687},[],[689],{"type":54,"value":690},"{ tokenIn, tokenOut, amountIn, amountOut, leaderTxHash, logIndex, blockNumber }",{"type":54,"value":692},". Within a single leader transaction, collapse legs that form one route before producing the actions to mirror:",{"type":49,"tag":173,"props":694,"children":695},{},[696,845],{"type":49,"tag":124,"props":697,"children":698},{},[699,717,719,724,726,731,733,739,741,746,748,753,755,760,762,767,768,773,774,779,780,785,786,791,793,799,801,806,808,814,816,821,823,828,830,835,837,843],{"type":49,"tag":85,"props":700,"children":701},{},[702,704,709,711,716],{"type":54,"value":703},"Chain legs by matching ",{"type":49,"tag":63,"props":705,"children":707},{"className":706},[],[708],{"type":54,"value":625},{"type":54,"value":710}," -> ",{"type":49,"tag":63,"props":712,"children":714},{"className":713},[],[715],{"type":54,"value":602},{"type":54,"value":150},{"type":54,"value":718}," A leg whose ",{"type":49,"tag":63,"props":720,"children":722},{"className":721},[],[723],{"type":54,"value":625},{"type":54,"value":725}," equals the next leg's ",{"type":49,"tag":63,"props":727,"children":729},{"className":728},[],[730],{"type":54,"value":602},{"type":54,"value":732}," (within the same tx, in ",{"type":49,"tag":63,"props":734,"children":736},{"className":735},[],[737],{"type":54,"value":738},"logIndex",{"type":54,"value":740}," order) is part of the same route. A maximal such chain collapses to a single net intent: ",{"type":49,"tag":63,"props":742,"children":744},{"className":743},[],[745],{"type":54,"value":602},{"type":54,"value":747}," = first leg's ",{"type":49,"tag":63,"props":749,"children":751},{"className":750},[],[752],{"type":54,"value":602},{"type":54,"value":754},", ",{"type":49,"tag":63,"props":756,"children":758},{"className":757},[],[759],{"type":54,"value":625},{"type":54,"value":761}," = last leg's ",{"type":49,"tag":63,"props":763,"children":765},{"className":764},[],[766],{"type":54,"value":625},{"type":54,"value":754},{"type":49,"tag":63,"props":769,"children":771},{"className":770},[],[772],{"type":54,"value":670},{"type":54,"value":747},{"type":49,"tag":63,"props":775,"children":777},{"className":776},[],[778],{"type":54,"value":670},{"type":54,"value":754},{"type":49,"tag":63,"props":781,"children":783},{"className":782},[],[784],{"type":54,"value":677},{"type":54,"value":761},{"type":49,"tag":63,"props":787,"children":789},{"className":788},[],[790],{"type":54,"value":677},{"type":54,"value":792},". Drop the intermediate legs. (Example: ",{"type":49,"tag":63,"props":794,"children":796},{"className":795},[],[797],{"type":54,"value":798},"USDG -> WETH -> AAAx",{"type":54,"value":800}," is two ",{"type":49,"tag":63,"props":802,"children":804},{"className":803},[],[805],{"type":54,"value":353},{"type":54,"value":807}," logs that collapse to one intent ",{"type":49,"tag":63,"props":809,"children":811},{"className":810},[],[812],{"type":54,"value":813},"USDG -> AAAx",{"type":54,"value":815},"; mirroring both legs would wrongly buy the intermediate ",{"type":49,"tag":63,"props":817,"children":819},{"className":818},[],[820],{"type":54,"value":536},{"type":54,"value":822}," and then spend it again.) If a collapsed chain returns to its starting token so the net ",{"type":49,"tag":63,"props":824,"children":826},{"className":825},[],[827],{"type":54,"value":602},{"type":54,"value":829}," equals ",{"type":49,"tag":63,"props":831,"children":833},{"className":832},[],[834],{"type":54,"value":625},{"type":54,"value":836}," (for example an arbitrage round-trip ",{"type":49,"tag":63,"props":838,"children":840},{"className":839},[],[841],{"type":54,"value":842},"USDG -> WETH -> USDG",{"type":54,"value":844},"), it is a net no-op: drop it and mirror nothing for that chain.",{"type":49,"tag":124,"props":846,"children":847},{},[848,853,855,860,862,867],{"type":49,"tag":85,"props":849,"children":850},{},[851],{"type":54,"value":852},"Independent swaps stay separate.",{"type":54,"value":854}," A transaction may instead be a batch \u002F multicall whose legs do not chain (no leg's ",{"type":49,"tag":63,"props":856,"children":858},{"className":857},[],[859],{"type":54,"value":625},{"type":54,"value":861}," feeds another leg's ",{"type":49,"tag":63,"props":863,"children":865},{"className":864},[],[866],{"type":54,"value":602},{"type":54,"value":868},"). Those are independent swaps, not a route: each is its own net intent and is mirrored separately.",{"type":49,"tag":57,"props":870,"children":871},{},[872,874,879,881,886,888,893,895,900,902,908],{"type":54,"value":873},"The result is one mirror intent per maximal chain (and one per independent leg). Key each resulting intent at the transaction level by ",{"type":49,"tag":63,"props":875,"children":877},{"className":876},[],[878],{"type":54,"value":329},{"type":54,"value":880},". When a single tx yields more than one independent intent, append a sub-index equal to the ",{"type":49,"tag":63,"props":882,"children":884},{"className":883},[],[885],{"type":54,"value":738},{"type":54,"value":887}," of that intent's first leg; ",{"type":49,"tag":63,"props":889,"children":891},{"className":890},[],[892],{"type":54,"value":738},{"type":54,"value":894}," is immutable per transaction, so the key is reproducible across re-scans and crash recovery, and a multi-hop route mirrors at most once. A tx that yields a single intent uses ",{"type":49,"tag":63,"props":896,"children":898},{"className":897},[],[899],{"type":54,"value":329},{"type":54,"value":901}," alone. Sort the resulting intents by ",{"type":49,"tag":63,"props":903,"children":905},{"className":904},[],[906],{"type":54,"value":907},"(blockNumber, first-leg logIndex)",{"type":54,"value":909}," so processing is deterministic.",{"type":49,"tag":78,"props":911,"children":912},{},[913],{"type":49,"tag":57,"props":914,"children":915},{},[916,921,923,928,930,935],{"type":49,"tag":85,"props":917,"children":918},{},[919],{"type":54,"value":920},"IMPORTANT: read activity according to the selected template.",{"type":54,"value":922}," If the template does not provide a public indexer, poll the RPC and scan logs directly against the deployed contracts. Scan in bounded block ranges to respect RPC ",{"type":49,"tag":63,"props":924,"children":926},{"className":925},[],[927],{"type":54,"value":406},{"type":54,"value":929}," limits, and persist the cursor every run so successive ranges normally do not overlap; the Step 3 idempotency guardrail (skip any ",{"type":49,"tag":63,"props":931,"children":933},{"className":932},[],[934],{"type":54,"value":329},{"type":54,"value":936}," intent already mirrored) is what keeps an overlapping range safe when the cursor did not advance (e.g. after a crash).",{"type":49,"tag":305,"props":938,"children":940},{"id":939},"step-3-apply-guardrails-per-action",[941],{"type":54,"value":942},"Step 3: Apply guardrails per action",{"type":49,"tag":57,"props":944,"children":945},{},[946],{"type":54,"value":947},"Process each new action in order. Skip (do not mirror) any action that fails a guardrail, and record the skip reason. Guardrails:",{"type":49,"tag":57,"props":949,"children":950},{},[951,953,958,960,966,968,974],{"type":54,"value":952},"Before processing actions, read configured guardrails. If the per-mirror, per-run, or per-period spend cap is missing, ask the operator for those caps using ",{"type":49,"tag":63,"props":954,"children":956},{"className":955},[],[957],{"type":54,"value":97},{"type":54,"value":959}," (or natural language if unavailable); include the funding token or denomination used for comparison. If any cap remains unset, do not enter ",{"type":49,"tag":63,"props":961,"children":963},{"className":962},[],[964],{"type":54,"value":965},"autonomous",{"type":54,"value":967}," mode. In ",{"type":49,"tag":63,"props":969,"children":971},{"className":970},[],[972],{"type":54,"value":973},"confirm",{"type":54,"value":975}," mode, proceed only with per-mirror confirmation and report that autonomous mode remains unavailable.",{"type":49,"tag":977,"props":978,"children":979},"table",{},[980,999],{"type":49,"tag":981,"props":982,"children":983},"thead",{},[984],{"type":49,"tag":985,"props":986,"children":987},"tr",{},[988,994],{"type":49,"tag":989,"props":990,"children":991},"th",{},[992],{"type":54,"value":993},"Guardrail",{"type":49,"tag":989,"props":995,"children":996},{},[997],{"type":54,"value":998},"Rule",{"type":49,"tag":1000,"props":1001,"children":1002},"tbody",{},[1003,1017,1084,1097,1117],{"type":49,"tag":985,"props":1004,"children":1005},{},[1006,1012],{"type":49,"tag":1007,"props":1008,"children":1009},"td",{},[1010],{"type":54,"value":1011},"Chain filter",{"type":49,"tag":1007,"props":1013,"children":1014},{},[1015],{"type":54,"value":1016},"Action must be on the selected target chain. Ignore anything else.",{"type":49,"tag":985,"props":1018,"children":1019},{},[1020,1025],{"type":49,"tag":1007,"props":1021,"children":1022},{},[1023],{"type":54,"value":1024},"Asset match",{"type":49,"tag":1007,"props":1026,"children":1027},{},[1028,1030,1035,1036,1041,1043,1048,1049,1054,1056,1061,1063,1068,1070,1075,1077,1082],{"type":54,"value":1029},"Both ",{"type":49,"tag":63,"props":1031,"children":1033},{"className":1032},[],[1034],{"type":54,"value":602},{"type":54,"value":69},{"type":49,"tag":63,"props":1037,"children":1039},{"className":1038},[],[1040],{"type":54,"value":625},{"type":54,"value":1042}," must be in the operator's allowed token set (default: tradable tokens from the selected template). ",{"type":49,"tag":63,"props":1044,"children":1046},{"className":1045},[],[1047],{"type":54,"value":544},{"type":54,"value":69},{"type":49,"tag":63,"props":1050,"children":1052},{"className":1051},[],[1053],{"type":54,"value":536},{"type":54,"value":1055}," are equivalent for this match: a leg decoded as ",{"type":49,"tag":63,"props":1057,"children":1059},{"className":1058},[],[1060],{"type":54,"value":536},{"type":54,"value":1062}," (pool logs always reference the ERC-20, per Step 2) satisfies an ",{"type":49,"tag":63,"props":1064,"children":1066},{"className":1065},[],[1067],{"type":54,"value":544},{"type":54,"value":1069}," or a ",{"type":49,"tag":63,"props":1071,"children":1073},{"className":1072},[],[1074],{"type":54,"value":536},{"type":54,"value":1076}," allowlist entry, so a WETH-decoded leg is never falsely skipped against an ETH entry. Apply the ETH\u002FWETH normalization rule in ",{"type":49,"tag":63,"props":1078,"children":1080},{"className":1079},[],[1081],{"type":54,"value":573},{"type":54,"value":1083}," before comparing.",{"type":49,"tag":985,"props":1085,"children":1086},{},[1087,1092],{"type":49,"tag":1007,"props":1088,"children":1089},{},[1090],{"type":54,"value":1091},"Position-size cap",{"type":49,"tag":1007,"props":1093,"children":1094},{},[1095],{"type":54,"value":1096},"Mirror amount must not exceed the per-trade cap and the per-period spend cap. Scale or skip if over.",{"type":49,"tag":985,"props":1098,"children":1099},{},[1100,1105],{"type":49,"tag":1007,"props":1101,"children":1102},{},[1103],{"type":54,"value":1104},"Follower balance",{"type":49,"tag":1007,"props":1106,"children":1107},{},[1108,1110,1115],{"type":54,"value":1109},"The follower wallet must hold enough ",{"type":49,"tag":63,"props":1111,"children":1113},{"className":1112},[],[1114],{"type":54,"value":602},{"type":54,"value":1116}," (and gas) to execute. If not, skip and report.",{"type":49,"tag":985,"props":1118,"children":1119},{},[1120,1125],{"type":49,"tag":1007,"props":1121,"children":1122},{},[1123],{"type":54,"value":1124},"Idempotency",{"type":49,"tag":1007,"props":1126,"children":1127},{},[1128,1130,1135],{"type":54,"value":1129},"If this intent's ",{"type":49,"tag":63,"props":1131,"children":1133},{"className":1132},[],[1134],{"type":54,"value":329},{"type":54,"value":1136}," (with its sub-index, if any) is already in the mirrored set, skip; never double-mirror. Keying at the transaction level means a multi-hop route mirrors at most once.",{"type":49,"tag":57,"props":1138,"children":1139},{},[1140],{"type":54,"value":1141},"Position sizing is operator-chosen: either a fixed notional per mirrored trade, or a proportion of the leader's amount, always clamped to the caps above. Never mirror more than the caps allow.",{"type":49,"tag":305,"props":1143,"children":1145},{"id":1144},"step-4-delegate-the-mirror-swap",[1146],{"type":54,"value":1147},"Step 4: Delegate the mirror swap",{"type":49,"tag":57,"props":1149,"children":1150},{},[1151,1153,1158,1160,1165,1166,1171,1172,1177,1179,1184,1185,1190,1192,1198,1200,1205,1207,1212,1214,1219],{"type":54,"value":1152},"For each intent that passes all guardrails, hand off to ",{"type":49,"tag":63,"props":1154,"children":1156},{"className":1155},[],[1157],{"type":54,"value":43},{"type":54,"value":1159},". Pass the target chain id and token addresses from the selected template. The Trading API flow (",{"type":49,"tag":63,"props":1161,"children":1163},{"className":1162},[],[1164],{"type":54,"value":190},{"type":54,"value":192},{"type":49,"tag":63,"props":1167,"children":1169},{"className":1168},[],[1170],{"type":54,"value":198},{"type":54,"value":192},{"type":49,"tag":63,"props":1173,"children":1175},{"className":1174},[],[1176],{"type":54,"value":205},{"type":54,"value":1178},") handles routing, approvals, Permit2, signing, and broadcast. This skill supplies only: ",{"type":49,"tag":63,"props":1180,"children":1182},{"className":1181},[],[1183],{"type":54,"value":602},{"type":54,"value":754},{"type":49,"tag":63,"props":1186,"children":1188},{"className":1187},[],[1189],{"type":54,"value":625},{"type":54,"value":1191},", the sized ",{"type":49,"tag":63,"props":1193,"children":1195},{"className":1194},[],[1196],{"type":54,"value":1197},"amount",{"type":54,"value":1199},", the target chain id, and the follower's wallet. Do not reimplement quote, approval, swap, or signing logic. The execution form for an ETH\u002FWETH leg (native ",{"type":49,"tag":63,"props":1201,"children":1203},{"className":1202},[],[1204],{"type":54,"value":544},{"type":54,"value":1206}," vs wrapped ",{"type":49,"tag":63,"props":1208,"children":1210},{"className":1209},[],[1211],{"type":54,"value":536},{"type":54,"value":1213},", and any wrap\u002Funwrap) is owned by the ",{"type":49,"tag":63,"props":1215,"children":1217},{"className":1216},[],[1218],{"type":54,"value":43},{"type":54,"value":1220}," Trading API path: do not assume the follower mirror must use the same form the leader used, and do not hand-roll a wrap\u002Funwrap. Pass the canonicalized token and let the Trading API choose the form.",{"type":49,"tag":305,"props":1222,"children":1224},{"id":1223},"step-5-advance-cursor-and-record",[1225],{"type":54,"value":1226},"Step 5: Advance cursor and record",{"type":49,"tag":57,"props":1228,"children":1229},{},[1230,1232,1237,1239,1245],{"type":54,"value":1231},"Write state to disk immediately after each leader intent resolves -- do not batch the writes to the end of the run. As each intent resolves (broadcast confirmed, or recorded skip), append its ",{"type":49,"tag":63,"props":1233,"children":1235},{"className":1234},[],[1236],{"type":54,"value":329},{"type":54,"value":1238}," key (with sub-index, if any) to the mirrored (or skipped) set with the result and the follower tx hash, then persist. Advance the durable ",{"type":49,"tag":63,"props":1240,"children":1242},{"className":1241},[],[1243],{"type":54,"value":1244},"cursor",{"type":54,"value":1246}," only past intents whose records are already committed, so a partially processed range is never marked done. This per-intent write is the idempotency guarantee: if the run crashes mid-batch after a broadcast confirms, the record for that intent is already on disk, and the idempotency check in Step 3 skips it on the next wake. Batching the writes to run-exit would leave already-broadcast mirrors unrecorded on a mid-run crash and re-mirror them with real funds.",{"type":49,"tag":108,"props":1248,"children":1250},{"id":1249},"execution-mode",[1251],{"type":54,"value":1252},"Execution mode",{"type":49,"tag":57,"props":1254,"children":1255},{},[1256,1258,1263],{"type":54,"value":1257},"Expose the execution mode from ",{"type":49,"tag":63,"props":1259,"children":1261},{"className":1260},[],[1262],{"type":54,"value":573},{"type":54,"value":1264},", chosen by the operator:",{"type":49,"tag":977,"props":1266,"children":1267},{},[1268,1284],{"type":49,"tag":981,"props":1269,"children":1270},{},[1271],{"type":49,"tag":985,"props":1272,"children":1273},{},[1274,1279],{"type":49,"tag":989,"props":1275,"children":1276},{},[1277],{"type":54,"value":1278},"Mode",{"type":49,"tag":989,"props":1280,"children":1281},{},[1282],{"type":54,"value":1283},"Behavior",{"type":49,"tag":1000,"props":1285,"children":1286},{},[1287,1312],{"type":49,"tag":985,"props":1288,"children":1289},{},[1290,1300],{"type":49,"tag":1007,"props":1291,"children":1292},{},[1293,1298],{"type":49,"tag":63,"props":1294,"children":1296},{"className":1295},[],[1297],{"type":54,"value":973},{"type":54,"value":1299}," (default)",{"type":49,"tag":1007,"props":1301,"children":1302},{},[1303,1305,1310],{"type":54,"value":1304},"Use ",{"type":49,"tag":63,"props":1306,"children":1308},{"className":1307},[],[1309],{"type":54,"value":97},{"type":54,"value":1311}," to confirm each mirror swap before broadcast, showing tokens, sized amount, chain, and the leader action being mirrored. Reuses the swap-integration spend gate.",{"type":49,"tag":985,"props":1313,"children":1314},{},[1315,1323],{"type":49,"tag":1007,"props":1316,"children":1317},{},[1318],{"type":49,"tag":63,"props":1319,"children":1321},{"className":1320},[],[1322],{"type":54,"value":965},{"type":49,"tag":1007,"props":1324,"children":1325},{},[1326],{"type":54,"value":1327},"Mirror without per-trade prompts, strictly within guardrails. Requires a per-run and per-period spend cap, a per-mirror notional cap, a token allowlist, a dry-run first, and a kill switch.",{"type":49,"tag":57,"props":1329,"children":1330},{},[1331,1333,1338,1340,1345],{"type":54,"value":1332},"Default to ",{"type":49,"tag":63,"props":1334,"children":1336},{"className":1335},[],[1337],{"type":54,"value":973},{"type":54,"value":1339},". See ",{"type":49,"tag":63,"props":1341,"children":1343},{"className":1342},[],[1344],{"type":54,"value":245},{"type":54,"value":1346}," for the full contract.",{"type":49,"tag":108,"props":1348,"children":1350},{"id":1349},"state",[1351],{"type":54,"value":1352},"State",{"type":49,"tag":57,"props":1354,"children":1355},{},[1356,1358,1363],{"type":54,"value":1357},"State follows ",{"type":49,"tag":63,"props":1359,"children":1361},{"className":1360},[],[1362],{"type":54,"value":256},{"type":54,"value":1364},". Copy-trade specifically stores:",{"type":49,"tag":173,"props":1366,"children":1367},{},[1368,1378],{"type":49,"tag":124,"props":1369,"children":1370},{},[1371,1376],{"type":49,"tag":63,"props":1372,"children":1374},{"className":1373},[],[1375],{"type":54,"value":1244},{"type":54,"value":1377},": the last processed block \u002F log position on the selected target chain.",{"type":49,"tag":124,"props":1379,"children":1380},{},[1381,1383,1388],{"type":54,"value":1382},"the set of mirrored leader intent keys (",{"type":49,"tag":63,"props":1384,"children":1386},{"className":1385},[],[1387],{"type":54,"value":329},{"type":54,"value":1389},", plus a sub-index when one tx yields more than one independent intent) with their outcomes.",{"type":49,"tag":57,"props":1391,"children":1392},{},[1393],{"type":54,"value":1394},"This makes runs idempotent: a leader intent is mirrored at most once, even across restarts or overlapping scheduler wake-ups, and a multi-hop route (collapsed to one intent in Step 2) mirrors at most once rather than once per leg.",{"type":49,"tag":108,"props":1396,"children":1398},{"id":1397},"restrictions-and-disclaimers",[1399],{"type":54,"value":1400},"Restrictions and Disclaimers",{"type":49,"tag":57,"props":1402,"children":1403},{},[1404],{"type":54,"value":1405},"RWA gating is chain- and token-specific and may be enforced at the token level (transfer-restricted ERC-20s). Therefore:",{"type":49,"tag":120,"props":1407,"children":1408},{},[1409,1414,1419],{"type":49,"tag":124,"props":1410,"children":1411},{},[1412],{"type":54,"value":1413},"A mirror swap can revert at transfer time even when the leader's identical trade succeeded (the follower may not be eligible to hold the asset). Handle transfer-restriction reverts gracefully, record the failure, and do not retry blindly.",{"type":49,"tag":124,"props":1415,"children":1416},{},[1417],{"type":54,"value":1418},"Respect the selected template's equity market-hours guidance; some RWAs may have off-hours liquidity limits, so a buy may be skipped or deferred outside hours.",{"type":49,"tag":124,"props":1420,"children":1421},{},[1422,1424,1430],{"type":54,"value":1423},"Surface the disclaimers in the repo root ",{"type":49,"tag":63,"props":1425,"children":1427},{"className":1426},[],[1428],{"type":54,"value":1429},"DISCLAIMER.md",{"type":54,"value":1431},". Uniswap Labs does not provide investment advice or recommendations. Copy-trading replicates another wallet's transactions at the operator's sole direction; the operator is solely responsible for the strategy and for compliance with applicable law.",{"type":49,"tag":108,"props":1433,"children":1435},{"id":1434},"input-validation",[1436],{"type":54,"value":1437},"Input validation",{"type":49,"tag":57,"props":1439,"children":1440},{},[1441],{"type":54,"value":1442},"Before interpolating ANY operator-provided value into code, API calls, or shell commands:",{"type":49,"tag":173,"props":1444,"children":1445},{},[1446,1464,1481,1491,1501],{"type":49,"tag":124,"props":1447,"children":1448},{},[1449,1454,1456,1462],{"type":49,"tag":85,"props":1450,"children":1451},{},[1452],{"type":54,"value":1453},"Leader and follower wallet addresses, token addresses",{"type":54,"value":1455},": MUST match ",{"type":49,"tag":63,"props":1457,"children":1459},{"className":1458},[],[1460],{"type":54,"value":1461},"^0x[a-fA-F0-9]{40}$",{"type":54,"value":1463},"; reject otherwise.",{"type":49,"tag":124,"props":1465,"children":1466},{},[1467,1472,1474,1480],{"type":49,"tag":85,"props":1468,"children":1469},{},[1470],{"type":54,"value":1471},"Position caps and amounts",{"type":54,"value":1473},": MUST be non-negative numeric values matching ",{"type":49,"tag":63,"props":1475,"children":1477},{"className":1476},[],[1478],{"type":54,"value":1479},"^[0-9]+\\.?[0-9]*$",{"type":54,"value":150},{"type":49,"tag":124,"props":1482,"children":1483},{},[1484,1489],{"type":49,"tag":85,"props":1485,"children":1486},{},[1487],{"type":54,"value":1488},"Chain id",{"type":54,"value":1490},": MUST be the operator-configured target chain id, read from the selected template rather than hardcoded.",{"type":49,"tag":124,"props":1492,"children":1493},{},[1494,1499],{"type":49,"tag":85,"props":1495,"children":1496},{},[1497],{"type":54,"value":1498},"API keys and private keys",{"type":54,"value":1500},": MUST come from environment variables, never hardcoded.",{"type":49,"tag":124,"props":1502,"children":1503},{},[1504,1509,1511,1517,1518,1524,1525,1531,1532,1538,1539,1545,1546,1552,1553,1559,1560,1566,1567,1573,1574,1580,1581,1587,1588,1594],{"type":49,"tag":85,"props":1505,"children":1506},{},[1507],{"type":54,"value":1508},"REJECT",{"type":54,"value":1510}," any input containing shell metacharacters: ",{"type":49,"tag":63,"props":1512,"children":1514},{"className":1513},[],[1515],{"type":54,"value":1516},";",{"type":54,"value":754},{"type":49,"tag":63,"props":1519,"children":1521},{"className":1520},[],[1522],{"type":54,"value":1523},"|",{"type":54,"value":754},{"type":49,"tag":63,"props":1526,"children":1528},{"className":1527},[],[1529],{"type":54,"value":1530},"&",{"type":54,"value":754},{"type":49,"tag":63,"props":1533,"children":1535},{"className":1534},[],[1536],{"type":54,"value":1537},"$",{"type":54,"value":754},{"type":49,"tag":63,"props":1540,"children":1542},{"className":1541},[],[1543],{"type":54,"value":1544},"`",{"type":54,"value":754},{"type":49,"tag":63,"props":1547,"children":1549},{"className":1548},[],[1550],{"type":54,"value":1551},"(",{"type":54,"value":754},{"type":49,"tag":63,"props":1554,"children":1556},{"className":1555},[],[1557],{"type":54,"value":1558},")",{"type":54,"value":754},{"type":49,"tag":63,"props":1561,"children":1563},{"className":1562},[],[1564],{"type":54,"value":1565},">",{"type":54,"value":754},{"type":49,"tag":63,"props":1568,"children":1570},{"className":1569},[],[1571],{"type":54,"value":1572},"\u003C",{"type":54,"value":754},{"type":49,"tag":63,"props":1575,"children":1577},{"className":1576},[],[1578],{"type":54,"value":1579},"\\",{"type":54,"value":754},{"type":49,"tag":63,"props":1582,"children":1584},{"className":1583},[],[1585],{"type":54,"value":1586},"'",{"type":54,"value":754},{"type":49,"tag":63,"props":1589,"children":1591},{"className":1590},[],[1592],{"type":54,"value":1593},"\"",{"type":54,"value":1595},", or newlines.",{"items":1597,"total":1741},[1598,1613,1620,1633,1646,1659,1672,1685,1699,1710,1720,1731],{"slug":1599,"name":1599,"fn":1600,"description":1601,"org":1602,"tags":1603,"stars":25,"repoUrl":26,"updatedAt":1612},"configurator","configure auction smart contract parameters","Configure CCA (Continuous Clearing Auction) smart contract parameters through an interactive bulk form flow. Use when user says \"configure auction\", \"cca auction\", \"setup token auction\", \"auction configuration\", \"continuous auction\", or mentions CCA contracts.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1604,1607,1608,1611],{"name":1605,"slug":1606,"type":15},"Configuration","configuration",{"name":23,"slug":24,"type":15},{"name":1609,"slug":1610,"type":15},"Smart Contracts","smart-contracts",{"name":17,"slug":18,"type":15},"2026-07-17T06:08:08.974641",{"slug":4,"name":4,"fn":5,"description":6,"org":1614,"tags":1615,"stars":25,"repoUrl":26,"updatedAt":27},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1616,1617,1618,1619],{"name":13,"slug":14,"type":15},{"name":23,"slug":24,"type":15},{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},{"slug":1621,"name":1621,"fn":1622,"description":1623,"org":1624,"tags":1625,"stars":25,"repoUrl":26,"updatedAt":1632},"dca-bot","automate dollar cost average token purchases","This skill should be used when the user wants to \"dca into\" a token, \"buy X every day\", set up a \"recurring buy\", \"dollar cost average\" into an asset, \"schedule a buy\", or \"auto-buy on a dip\". Buys a fixed amount into a token on a schedule, optionally only when a condition holds (for example only when ETH is below a price threshold). The host agent's scheduler wakes the skill on a cadence; each wake is one self-contained run.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1626,1627,1630,1631],{"name":13,"slug":14,"type":15},{"name":1628,"slug":1629,"type":15},"DeFi","defi",{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},"2026-07-17T06:05:37.160647",{"slug":1634,"name":1634,"fn":1635,"description":1636,"org":1637,"tags":1638,"stars":25,"repoUrl":26,"updatedAt":1645},"deployer","deploy Uniswap CCA smart contracts","Deploy CCA (Continuous Clearing Auction) smart contracts using the Factory pattern. Use when user says \"deploy auction\", \"deploy cca\", \"factory deployment\", or wants to deploy a configured auction.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1639,1642,1643,1644],{"name":1640,"slug":1641,"type":15},"Deployment","deployment",{"name":23,"slug":24,"type":15},{"name":1609,"slug":1610,"type":15},{"name":17,"slug":18,"type":15},"2026-07-17T06:08:09.661977",{"slug":1647,"name":1647,"fn":1648,"description":1649,"org":1650,"tags":1651,"stars":25,"repoUrl":26,"updatedAt":1658},"index-bot","create and rebalance asset portfolios","This skill should be used when the user asks to \"create an index\", \"build a basket of top assets\", \"buy a weighted basket\", \"make a portfolio of assets\", \"equal-weight basket\", \"rebalance my portfolio\", \"track the top N tokens\", or wants an automated, weighted multi-asset basket that buys in one pass and rebalances on a cadence. Builds the basket spec, delegates each buy and rebalance swap to the swap-integration Trading API flow, and records target weights in state.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1652,1653,1656,1657],{"name":23,"slug":24,"type":15},{"name":1654,"slug":1655,"type":15},"Portfolio Management","portfolio-management",{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},"2026-07-17T06:04:22.328253",{"slug":1660,"name":1660,"fn":1661,"description":1662,"org":1663,"tags":1664,"stars":25,"repoUrl":26,"updatedAt":1671},"liquidity-planner","plan and create liquidity positions","This skill should be used when the user asks to \"provide liquidity\", \"create LP position\", \"add liquidity to pool\", \"become a liquidity provider\", \"create v3 position\", \"create v4 position\", \"concentrated liquidity\", \"set price range\", or mentions providing liquidity, LP positions, or liquidity pools on Uniswap. Generates deep links to create positions in the Uniswap interface.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1665,1666,1667,1670],{"name":1628,"slug":1629,"type":15},{"name":23,"slug":24,"type":15},{"name":1668,"slug":1669,"type":15},"Liquidity","liquidity",{"name":17,"slug":18,"type":15},"2026-07-17T06:08:09.315325",{"slug":1673,"name":1673,"fn":1674,"description":1675,"org":1676,"tags":1677,"stars":25,"repoUrl":26,"updatedAt":1684},"lp-integration","integrate Uniswap liquidity provisioning","Integrate Uniswap liquidity provisioning (LP) into applications via the LP REST API. Use when the user says \"LP API\", \"liquidity provisioning API\", \"provide liquidity programmatically\", \"create LP position via API\", \"add liquidity via API\", \"increase liquidity\", \"decrease liquidity\", \"remove liquidity\", \"claim LP fees\", \"collect LP fees\", \"manage LP positions in code\", or mentions building a backend, bot, or frontend that creates or manages Uniswap v2\u002Fv3\u002Fv4 liquidity positions through an API. Also use when debugging LP API calls (e.g. \u002Flp\u002Fcreate, \u002Flp\u002Fcheck_approval, \u002Flp\u002Fincrease, \u002Flp\u002Fdecrease, \u002Flp\u002Fclaim_fees), unexpected response fields, the approval or EIP-712 permit flow, or transaction-building errors for liquidity positions. For generating deep links to the Uniswap web app instead of calling the API, use the liquidity-planner skill; for using the Uniswap v4 SDK directly rather than the REST API, use the v4-sdk-integration skill.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1678,1681,1682,1683],{"name":1679,"slug":1680,"type":15},"API Development","api-development",{"name":1628,"slug":1629,"type":15},{"name":1668,"slug":1669,"type":15},{"name":17,"slug":18,"type":15},"2026-07-17T06:08:13.704465",{"slug":1686,"name":1686,"fn":1687,"description":1688,"org":1689,"tags":1690,"stars":25,"repoUrl":26,"updatedAt":1698},"pay-with-any-token","pay HTTP 402 challenges with Uniswap","Pay HTTP 402 payment challenges using tokens via the Tempo CLI and Uniswap Trading API. Use when the user encounters a 402 Payment Required response, needs to fulfill a machine payment, mentions \"MPP\", \"Tempo payment\", \"pay for API access\", \"HTTP 402\", \"x402\", \"machine payment protocol\", \"pay-with-any-token\", \"use tempo\", \"tempo request\", or \"tempo wallet\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1691,1692,1695,1696],{"name":1628,"slug":1629,"type":15},{"name":1693,"slug":1694,"type":15},"Payments","payments",{"name":20,"slug":21,"type":15},{"name":1697,"slug":1697,"type":15},"x402","2026-07-17T06:04:29.756086",{"slug":1700,"name":1700,"fn":1701,"description":1702,"org":1703,"tags":1704,"stars":25,"repoUrl":26,"updatedAt":1709},"pay-with-app","pay 402 payment challenges","Pay HTTP 402 payment challenges issued by OKX's Agent Payments Protocol (APP) on X Layer using tokens from any chain via the Uniswap Trading API. Use this skill whenever the user encounters a 402 challenge whose network resolves to X Layer (chain 196), mentions \"APP\", \"Agent Payments Protocol\", \"OKX agent payment\", \"OKX Onchain OS\", \"OKX agentic wallet\", \"x402 on X Layer\", \"USDT0\", \"x42\", \"Instant Payment\", \"Batch Payment\", \"pay for X Layer API\", or wants to pay an OKX-backed merchant. Even when the user does not explicitly say APP, prefer this skill for any 402 challenge whose network resolves to X Layer (chain 196). For 402 challenges on other chains (Ethereum, Base, Arbitrum, Tempo) use pay-with-any-token instead.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1705,1706,1707,1708],{"name":1679,"slug":1680,"type":15},{"name":1693,"slug":1694,"type":15},{"name":17,"slug":18,"type":15},{"name":1697,"slug":1697,"type":15},"2026-07-17T06:07:38.795043",{"slug":43,"name":43,"fn":1711,"description":1712,"org":1713,"tags":1714,"stars":25,"repoUrl":26,"updatedAt":1719},"integrate Uniswap swap functionality","Integrate Uniswap swaps into applications. Use when user says \"integrate swaps\", \"uniswap\", \"trading api\", \"add swap functionality\", \"build a swap frontend\", \"create a swap script\", \"smart contract swap integration\", \"use Universal Router\", \"Trading API\", or mentions swapping tokens via Uniswap.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1715,1716,1717,1718],{"name":1679,"slug":1680,"type":15},{"name":1628,"slug":1629,"type":15},{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},"2026-07-17T06:08:10.354222",{"slug":1721,"name":1721,"fn":1722,"description":1723,"org":1724,"tags":1725,"stars":25,"repoUrl":26,"updatedAt":1730},"swap-planner","plan and execute token swaps","This skill should be used when the user asks to \"swap tokens\", \"trade ETH for USDC\", \"exchange tokens on Uniswap\", \"buy tokens\", \"sell tokens\", \"convert ETH to stablecoins\", \"find memecoins\", \"discover tokens\", \"research tokens\", \"tokens to buy\", \"find tokens to swap\", \"what should I buy\", or mentions swapping, trading, researching, discovering, buying, or exchanging tokens on any Uniswap-supported chain. Supports both known token swaps and token discovery workflows (discovery uses keyword search and web search — there is no live \"trending\" feed). Generates deep links to execute swaps in the Uniswap interface.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1726,1727,1728,1729],{"name":1628,"slug":1629,"type":15},{"name":1668,"slug":1669,"type":15},{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},"2026-07-17T06:08:10.008152",{"slug":1732,"name":1732,"fn":1733,"description":1734,"org":1735,"tags":1736,"stars":25,"repoUrl":26,"updatedAt":1740},"v4-hook-generator","generate Uniswap v4 hook contracts","Generate Uniswap v4 hook contracts via OpenZeppelin MCP. Use when building custom swap logic, async swaps, hook-owned liquidity, custom curves, dynamic fees, MEV protection, limit orders, or oracle hooks.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1737,1738,1739],{"name":23,"slug":24,"type":15},{"name":1609,"slug":1610,"type":15},{"name":17,"slug":18,"type":15},"2026-07-17T06:04:19.17669",19,{"items":1743,"total":1793},[1744,1751,1758,1765,1772,1779,1786],{"slug":1599,"name":1599,"fn":1600,"description":1601,"org":1745,"tags":1746,"stars":25,"repoUrl":26,"updatedAt":1612},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1747,1748,1749,1750],{"name":1605,"slug":1606,"type":15},{"name":23,"slug":24,"type":15},{"name":1609,"slug":1610,"type":15},{"name":17,"slug":18,"type":15},{"slug":4,"name":4,"fn":5,"description":6,"org":1752,"tags":1753,"stars":25,"repoUrl":26,"updatedAt":27},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1754,1755,1756,1757],{"name":13,"slug":14,"type":15},{"name":23,"slug":24,"type":15},{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},{"slug":1621,"name":1621,"fn":1622,"description":1623,"org":1759,"tags":1760,"stars":25,"repoUrl":26,"updatedAt":1632},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1761,1762,1763,1764],{"name":13,"slug":14,"type":15},{"name":1628,"slug":1629,"type":15},{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},{"slug":1634,"name":1634,"fn":1635,"description":1636,"org":1766,"tags":1767,"stars":25,"repoUrl":26,"updatedAt":1645},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1768,1769,1770,1771],{"name":1640,"slug":1641,"type":15},{"name":23,"slug":24,"type":15},{"name":1609,"slug":1610,"type":15},{"name":17,"slug":18,"type":15},{"slug":1647,"name":1647,"fn":1648,"description":1649,"org":1773,"tags":1774,"stars":25,"repoUrl":26,"updatedAt":1658},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1775,1776,1777,1778],{"name":23,"slug":24,"type":15},{"name":1654,"slug":1655,"type":15},{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},{"slug":1660,"name":1660,"fn":1661,"description":1662,"org":1780,"tags":1781,"stars":25,"repoUrl":26,"updatedAt":1671},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1782,1783,1784,1785],{"name":1628,"slug":1629,"type":15},{"name":23,"slug":24,"type":15},{"name":1668,"slug":1669,"type":15},{"name":17,"slug":18,"type":15},{"slug":1673,"name":1673,"fn":1674,"description":1675,"org":1787,"tags":1788,"stars":25,"repoUrl":26,"updatedAt":1684},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1789,1790,1791,1792],{"name":1679,"slug":1680,"type":15},{"name":1628,"slug":1629,"type":15},{"name":1668,"slug":1669,"type":15},{"name":17,"slug":18,"type":15},15]