{
  "schemaVersion": "1.0",
  "item": {
    "slug": "uniswap-v4",
    "name": "Uniswap V4",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/openclaw-consensus-bot/uniswap-v4",
    "canonicalUrl": "https://clawhub.ai/openclaw-consensus-bot/uniswap-v4",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/uniswap-v4",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=uniswap-v4",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "CHANGELOG.md",
      "README.md",
      "SKILL.md",
      "package-lock.json",
      "package.json",
      "references/addresses.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-07T17:22:31.273Z",
      "expiresAt": "2026-05-14T17:22:31.273Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
        "contentDisposition": "attachment; filename=\"afrexai-annual-report-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/uniswap-v4"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/uniswap-v4",
    "agentPageUrl": "https://openagent3.xyz/skills/uniswap-v4/agent",
    "manifestUrl": "https://openagent3.xyz/skills/uniswap-v4/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/uniswap-v4/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Uniswap V4 🦄",
        "body": "Swap tokens and read pool state on Uniswap V4 via the Universal Router.\n\nChains: Base (8453), Ethereum (1), Base Sepolia (84532)\n\nContractBaseEthereumPoolManager0x498581fF718922c3f8e6A244956aF099B2652b2b0x000000000004444c5dc75cB358380D2e3dE08A90UniversalRouter0x6ff5693b99212da76ad316178a184ab56d299b430x66a9893cC07D91D95644AEDD05D03f95e1dBA8AfPermit20x000000000022D473030F116dDEE9F6B43aC78BA30x000000000022D473030F116dDEE9F6B43aC78BA3StateView0xa3c0c9b65bad0b08107aa264b0f3db444b867a710x7ffe42c4a5deea5b0fec41c94c136cf115597227V4Quoter0x0d5e0f971ed27fbff6c2837bf31316121532048d0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203\n\nAddresses from docs.uniswap.org/contracts/v4/deployments, verified 2026-02-08."
      },
      {
        "title": "Decision Tree",
        "body": "Read pool state? → src/pool-info.ts (free, no gas, no key)\nGet swap quote? → src/quote.ts (free, uses on-chain V4Quoter)\nApprove tokens? → src/approve.ts (write, ~100K gas, needs PRIVATE_KEY)\nExecute swap? → src/swap.ts (write, ~300-350K gas, needs PRIVATE_KEY)\nFirst time with an ERC20? → Run approve first, or use --auto-approve on swap"
      },
      {
        "title": "Scripts Reference",
        "body": "All scripts in src/. Run with npx tsx. Pass --help for usage."
      },
      {
        "title": "pool-info.ts — Read Pool State (free)",
        "body": "Returns pool ID, sqrtPriceX96, tick, liquidity, fees, token symbols/decimals.\nAuto-detects the best pool by liquidity (or specify --fee/--tick-spacing).\n\nnpx tsx src/pool-info.ts --token0 ETH --token1 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 --chain base --rpc $BASE_RPC_URL\n\nEnv: BASE_RPC_URL or ETH_RPC_URL (or pass --rpc)"
      },
      {
        "title": "quote.ts — Quote Swap Amounts (free)",
        "body": "Quotes exact input amounts via the on-chain V4Quoter contract (simulation, no tx).\nReturns expected output amount and gas estimate.\n\nnpx tsx src/quote.ts \\\n  --token-in ETH \\\n  --token-out 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \\\n  --amount 10000000000000000 \\\n  --chain base \\\n  --rpc $BASE_RPC_URL\n\nEnv: BASE_RPC_URL or ETH_RPC_URL"
      },
      {
        "title": "approve.ts — Set Up Token Approvals (write)",
        "body": "Two-step Permit2 flow: ERC20 → Permit2, then Permit2 → Universal Router.\nSkips if already approved. Only needed for ERC20 tokens (not ETH).\n\nPRIVATE_KEY=0x... npx tsx src/approve.ts \\\n  --token 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \\\n  --chain base \\\n  --rpc $BASE_RPC_URL \\\n  --json\n\nEnv: PRIVATE_KEY (required), BASE_RPC_URL"
      },
      {
        "title": "swap.ts — Execute Swap (write)",
        "body": "Exact-input swap via Universal Router. Quotes expected output first, applies slippage,\nthen sends the transaction.\n\nPRIVATE_KEY=0x... npx tsx src/swap.ts \\\n  --token-in ETH \\\n  --token-out 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \\\n  --amount 10000000000000000 \\\n  --slippage 50 \\\n  --chain base \\\n  --rpc $BASE_RPC_URL \\\n  --json\n\nWith auto-approval (sets up Permit2 if needed):\n\nPRIVATE_KEY=0x... npx tsx src/swap.ts \\\n  --token-in 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \\\n  --token-out ETH \\\n  --amount 25000000 \\\n  --slippage 100 \\\n  --auto-approve \\\n  --chain base \\\n  --rpc $BASE_RPC_URL\n\nOptions: --slippage <bps> (default 50 = 0.5%), --recipient <addr>, --auto-approve, --json\nEnv: PRIVATE_KEY (required), BASE_RPC_URL"
      },
      {
        "title": "Token Input",
        "body": "ETH or eth → native ETH (address(0) in V4)\nContract address → ERC20 token\nCommon Base tokens: USDC 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, WETH 0x4200000000000000000000000000000000000006"
      },
      {
        "title": "Environment Variables",
        "body": "VariableUsed ByRequiredDescriptionPRIVATE_KEYapprove, swapYes*Wallet private key (never CLI!)BASE_RPC_URLall (Base)NoBase mainnet RPC URLETH_RPC_URLall (Ethereum)NoEthereum mainnet RPC URLBASE_SEPOLIA_RPC_URLall (testnet)NoBase Sepolia RPC URL\n\n* Only required for write operations. Read operations (pool-info, quote) don't need a key."
      },
      {
        "title": "V4 Architecture Notes",
        "body": "Singleton PoolManager holds all pools in one contract\nState read via StateView contract (wraps PoolManager storage)\nSwaps: Universal Router → PoolManager via V4_SWAP command\nApprovals: ERC20 → Permit2 → Universal Router (two-step)\nPool ID: keccak256(abi.encode(currency0, currency1, fee, tickSpacing, hooks))\nCurrency ordering: currency0 < currency1 by numeric value. ETH = address(0)\nAction sequence: SWAP_EXACT_IN_SINGLE (0x06) + SETTLE_ALL (0x0c) + TAKE_ALL (0x0f)\nSee references/v4-encoding.md for full encoding reference"
      },
      {
        "title": "Error Handling",
        "body": "ErrorCauseFixNo V4 pool foundPair not listed on V4 for this chainCheck token addressesQuote failedPool exists but can't simulate swapCheck amount, pool may lack liqPRIVATE_KEY requiredMissing env var for write operationexport PRIVATE_KEY=0x...No RPC URLMissing RPC configPass --rpc or set env varTx revertsInsufficient balance, expired, slippageCheck balance, increase slippageuint128 maxAmount too large for V4Use smaller amount"
      },
      {
        "title": "SECURITY",
        "body": "PRIVATE_KEY must be provided via an environment variable or secret manager only.\n\n\nNEVER paste or send PRIVATE_KEY in chat.\n\n\nNEVER commit PRIVATE_KEY (or .env files) to git.\n\n\nTreat stdout/stderr as public logs (CI, terminals, chat). CI tests ensure the PRIVATE_KEY value is never printed.\n\n\nNEVER pass private keys as CLI arguments (rejected by all scripts)\n\n\nPrivate keys accepted via PRIVATE_KEY env var only\n\n\nAll inputs validated: addresses (format), amounts (BigInt bounds), slippage (0-10000)\n\n\nNo eval(), no exec(), no shell commands — pure TypeScript\n\n\nBigInt used everywhere for token amounts (no floating point, no overflow)"
      },
      {
        "title": "Testing",
        "body": "npm run test:unit      # Unit tests (no network)\nnpm run test:fork      # Fork tests (needs: anvil --fork-url https://mainnet.base.org)\nnpm run test:testnet   # Testnet reads (Base Sepolia)\nnpm run test:mainnet   # Mainnet smoke tests (read-only)\nnpm run security       # Security scan"
      },
      {
        "title": "References",
        "body": "V4 encoding reference: references/v4-encoding.md\nContract addresses: references/addresses.md\nV4 architecture: references/v4-architecture.md"
      }
    ],
    "body": "Uniswap V4 🦄\n\nSwap tokens and read pool state on Uniswap V4 via the Universal Router.\n\nChains: Base (8453), Ethereum (1), Base Sepolia (84532)\n\nContract\tBase\tEthereum\nPoolManager\t0x498581fF718922c3f8e6A244956aF099B2652b2b\t0x000000000004444c5dc75cB358380D2e3dE08A90\nUniversalRouter\t0x6ff5693b99212da76ad316178a184ab56d299b43\t0x66a9893cC07D91D95644AEDD05D03f95e1dBA8Af\nPermit2\t0x000000000022D473030F116dDEE9F6B43aC78BA3\t0x000000000022D473030F116dDEE9F6B43aC78BA3\nStateView\t0xa3c0c9b65bad0b08107aa264b0f3db444b867a71\t0x7ffe42c4a5deea5b0fec41c94c136cf115597227\nV4Quoter\t0x0d5e0f971ed27fbff6c2837bf31316121532048d\t0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203\n\nAddresses from docs.uniswap.org/contracts/v4/deployments, verified 2026-02-08.\n\nDecision Tree\nRead pool state? → src/pool-info.ts (free, no gas, no key)\nGet swap quote? → src/quote.ts (free, uses on-chain V4Quoter)\nApprove tokens? → src/approve.ts (write, ~100K gas, needs PRIVATE_KEY)\nExecute swap? → src/swap.ts (write, ~300-350K gas, needs PRIVATE_KEY)\nFirst time with an ERC20? → Run approve first, or use --auto-approve on swap\nScripts Reference\n\nAll scripts in src/. Run with npx tsx. Pass --help for usage.\n\npool-info.ts — Read Pool State (free)\n\nReturns pool ID, sqrtPriceX96, tick, liquidity, fees, token symbols/decimals. Auto-detects the best pool by liquidity (or specify --fee/--tick-spacing).\n\nnpx tsx src/pool-info.ts --token0 ETH --token1 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 --chain base --rpc $BASE_RPC_URL\n\n\nEnv: BASE_RPC_URL or ETH_RPC_URL (or pass --rpc)\n\nquote.ts — Quote Swap Amounts (free)\n\nQuotes exact input amounts via the on-chain V4Quoter contract (simulation, no tx). Returns expected output amount and gas estimate.\n\nnpx tsx src/quote.ts \\\n  --token-in ETH \\\n  --token-out 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \\\n  --amount 10000000000000000 \\\n  --chain base \\\n  --rpc $BASE_RPC_URL\n\n\nEnv: BASE_RPC_URL or ETH_RPC_URL\n\napprove.ts — Set Up Token Approvals (write)\n\nTwo-step Permit2 flow: ERC20 → Permit2, then Permit2 → Universal Router. Skips if already approved. Only needed for ERC20 tokens (not ETH).\n\nPRIVATE_KEY=0x... npx tsx src/approve.ts \\\n  --token 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \\\n  --chain base \\\n  --rpc $BASE_RPC_URL \\\n  --json\n\n\nEnv: PRIVATE_KEY (required), BASE_RPC_URL\n\nswap.ts — Execute Swap (write)\n\nExact-input swap via Universal Router. Quotes expected output first, applies slippage, then sends the transaction.\n\nPRIVATE_KEY=0x... npx tsx src/swap.ts \\\n  --token-in ETH \\\n  --token-out 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \\\n  --amount 10000000000000000 \\\n  --slippage 50 \\\n  --chain base \\\n  --rpc $BASE_RPC_URL \\\n  --json\n\n\nWith auto-approval (sets up Permit2 if needed):\n\nPRIVATE_KEY=0x... npx tsx src/swap.ts \\\n  --token-in 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 \\\n  --token-out ETH \\\n  --amount 25000000 \\\n  --slippage 100 \\\n  --auto-approve \\\n  --chain base \\\n  --rpc $BASE_RPC_URL\n\n\nOptions: --slippage <bps> (default 50 = 0.5%), --recipient <addr>, --auto-approve, --json Env: PRIVATE_KEY (required), BASE_RPC_URL\n\nToken Input\nETH or eth → native ETH (address(0) in V4)\nContract address → ERC20 token\nCommon Base tokens: USDC 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, WETH 0x4200000000000000000000000000000000000006\nEnvironment Variables\nVariable\tUsed By\tRequired\tDescription\nPRIVATE_KEY\tapprove, swap\tYes*\tWallet private key (never CLI!)\nBASE_RPC_URL\tall (Base)\tNo\tBase mainnet RPC URL\nETH_RPC_URL\tall (Ethereum)\tNo\tEthereum mainnet RPC URL\nBASE_SEPOLIA_RPC_URL\tall (testnet)\tNo\tBase Sepolia RPC URL\n\n* Only required for write operations. Read operations (pool-info, quote) don't need a key.\n\nV4 Architecture Notes\nSingleton PoolManager holds all pools in one contract\nState read via StateView contract (wraps PoolManager storage)\nSwaps: Universal Router → PoolManager via V4_SWAP command\nApprovals: ERC20 → Permit2 → Universal Router (two-step)\nPool ID: keccak256(abi.encode(currency0, currency1, fee, tickSpacing, hooks))\nCurrency ordering: currency0 < currency1 by numeric value. ETH = address(0)\nAction sequence: SWAP_EXACT_IN_SINGLE (0x06) + SETTLE_ALL (0x0c) + TAKE_ALL (0x0f)\nSee references/v4-encoding.md for full encoding reference\nError Handling\nError\tCause\tFix\nNo V4 pool found\tPair not listed on V4 for this chain\tCheck token addresses\nQuote failed\tPool exists but can't simulate swap\tCheck amount, pool may lack liq\nPRIVATE_KEY required\tMissing env var for write operation\texport PRIVATE_KEY=0x...\nNo RPC URL\tMissing RPC config\tPass --rpc or set env var\nTx reverts\tInsufficient balance, expired, slippage\tCheck balance, increase slippage\nuint128 max\tAmount too large for V4\tUse smaller amount\nSECURITY\n\nPRIVATE_KEY must be provided via an environment variable or secret manager only.\n\nNEVER paste or send PRIVATE_KEY in chat.\n\nNEVER commit PRIVATE_KEY (or .env files) to git.\n\nTreat stdout/stderr as public logs (CI, terminals, chat). CI tests ensure the PRIVATE_KEY value is never printed.\n\nNEVER pass private keys as CLI arguments (rejected by all scripts)\n\nPrivate keys accepted via PRIVATE_KEY env var only\n\nAll inputs validated: addresses (format), amounts (BigInt bounds), slippage (0-10000)\n\nNo eval(), no exec(), no shell commands — pure TypeScript\n\nBigInt used everywhere for token amounts (no floating point, no overflow)\n\nTesting\nnpm run test:unit      # Unit tests (no network)\nnpm run test:fork      # Fork tests (needs: anvil --fork-url https://mainnet.base.org)\nnpm run test:testnet   # Testnet reads (Base Sepolia)\nnpm run test:mainnet   # Mainnet smoke tests (read-only)\nnpm run security       # Security scan\n\nReferences\nV4 encoding reference: references/v4-encoding.md\nContract addresses: references/addresses.md\nV4 architecture: references/v4-architecture.md"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/openclaw-consensus-bot/uniswap-v4",
    "publisherUrl": "https://clawhub.ai/openclaw-consensus-bot/uniswap-v4",
    "owner": "openclaw-consensus-bot",
    "version": "2.0.4",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/uniswap-v4",
    "downloadUrl": "https://openagent3.xyz/downloads/uniswap-v4",
    "agentUrl": "https://openagent3.xyz/skills/uniswap-v4/agent",
    "manifestUrl": "https://openagent3.xyz/skills/uniswap-v4/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/uniswap-v4/agent.md"
  }
}