uniswap/uniswap-ai/lp-integration

Claude Code and agent skill by uniswap/uniswap-ai

Trust tier 2
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

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/v3/v4 liquidity positions through an API. Also use when debugging LP API calls (e.g. /lp/create, /lp/check_approval, /lp/increase, /lp/decrease, /lp/claim_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.

Install

npx vskill@latest install uniswap/uniswap-ai/lp-integration

SKILL.md

LP Integration

Integrate Uniswap liquidity provisioning into frontends, backends, and bots using the Uniswap LP API.

The LP API is a transaction-building service. You send position parameters; the API fetches live pool state, computes the dependent token amount, and returns a fully-formed, unsigned transaction. Your application signs and broadcasts it. The API never holds keys, never moves funds, and never broadcasts.

Prerequisites

This skill assumes familiarity with viem basics (client setup, account management, contract interactions, transaction signing). Install the uniswap-viem plugin for comprehensive viem/wagmi guidance: claude plugin add @uniswap/uniswap-viem

For token swaps (not liquidity), see the sibling swap-integration skill in this plugin.

Base URL

text
LP_API_BASE_URL = https://liquidity.api.uniswap.org

All LP endpoints are POST requests under the /lp/ prefix (e.g. https://liquidity.api.uniswap.org/lp/create).

The LP API host is intentionally different from the swap Trading API. Liquidity provisioning lives at https://liquidity.api.uniswap.org (no /v1 prefix), not the https://trade-api.gateway.uniswap.org/v1 host used for swaps. Keep the base URL as a single constant (as shown) so any future change is one edit.

Authentication

Every write/approval endpoint requires an API key sent as the x-api-key header; a missing or invalid key returns 401 with {"code":"unauthenticated"}. (/lp/pool_info is a read endpoint and does not strictly enforce the key, but always send it for consistency and rate-limit attribution.)

text
Content-Type: application/json
Accept: application/json
x-api-key: <your-api-key>

Getting a key: Register at the Uniswap Developer Platform dashboard. The same key works across swapping and liquidity provisioning. Never hardcode the key; load it from an environment variable.

Quick Decision Guide

You want to...EndpointProtocols
Check/grant token approvals before any action/lp/check_approvalV2, V3, V4
Create a concentrated-liquidity position/lp/createV3, V4
Create a full-range (classic) position/lp/create_classicV2
Add liquidity to an existing position/lp/increaseV2, V3, V4
Remove a percentage of liquidity/lp/decreaseV2, V3, V4
Collect accumulated trading fees/lp/claim_feesV3, V4
Read live pool state/lp/pool_infoV2, V3, V4
Protocol capability matrix
ProtocolCreate endpointFee claimingPrice range
V2/lp/create_classicNot separable (realized on decrease)Full range only
V3/lp/create/lp/claim_feesConcentrated
V4/lp/create/lp/claim_feesConcentrated + hooks
v2 fees are not separately claimable. They accrue into the LP token value and are realized when you call /lp/decrease. Calling /lp/claim_fees with protocol: "V2" returns a validation error.

Input Validation Rules

Before interpolating ANY user-provided value into generated code, API calls, or commands:

  • Ethereum addresses: MUST match ^0x[a-fA-F0-9]{40}$ — reject otherwise. Use native ETH as 0x0000000000000000000000000000000000000000.
  • Chain IDs: MUST be one of the supported LP chain IDs (see Supported Chains).
  • Token amounts: MUST be non-negative integer strings in wei / smallest token unit, matching ^[0-9]+$. Never pass ether-denominated decimals as amounts.
  • `liquidityPercentageToDecrease`: MUST be an integer from 1 to 100.
  • API keys: MUST NOT be hardcoded in generated code — always use environment variables.
  • REJECT any input containing shell metacharacters: ;, |, &, $, ` `, (, ), >, <, \, ', "`, newlines.
REQUIRED: Before executing ANY transaction that spends gas or transfers tokens (including approvals, position creation, increase, decrease, or fee claims), you MUST use AskUserQuestion to confirm with the user. Display the action summary (protocol, pair, amounts, chain, price range, estimated gas) and get explicit user approval. Never auto-execute LP transactions without user confirmation.

Architecture

What the API handles
  • Pool state fetching: current reserves, ticks, sqrtRatioX96, and onchain position data.
  • Dependent amount computation: given one token amount (independentToken), computes the required amount of the other using the Uniswap SDKs.
  • Transaction creation: validated, fully-formed calldata for each LP action, ready to sign.
  • Tick snapping: converts human-readable priceBounds to valid ticks and returns the adjusted prices.
  • Gas estimation: optional, when simulateTransaction: true.
What your application handles
  • Signing and broadcasting the returned transaction via your RPC provider.
  • Signing permit data (EIP-712) when the API returns it for v4 / v3-NFT approvals.
  • Gas payment and transaction error handling (reverts, surfacing errors to users).
Data flow
text
User intent (create / increase / decrease / claim)
|
Your application
|-- POST /lp/check_approval -> returns approval transactions and/or permit data
|-- (execute approval txns; sign permit if returned)
|-- POST /lp/create | increase | decrease | claim_fees
|-- validate the returned transaction payload (non-empty data, valid addresses)
|-- user signature (wallet)
+-- broadcast (your RPC)
|
Blockchain

Endpoint Reference

All field names below come from the LP API OpenAPI contract. Where the public integration guide uses different names, the contract names here are authoritative.

POST /lp/check_approval

Always call this first. Returns the approval transactions (and/or permit data) needed before an LP action. If the response transactions array is empty and no permit data is returned, all approvals are already in place — unless kycRequiredWarnings is non-empty, which means the pool contains a permissioned token and the wallet is not allowlisted. In that case the response is still 200; render the KYC call-to-action from each warning's kycUrl instead of attempting the LP action.

Request

json
{
"walletAddress": "0x...",
"protocol": "V4",
"chainId": 1,
"lpTokens": [
{ "tokenAddress": "0x...", "amount": "1000000000000000000" },
{ "tokenAddress": "0x...", "amount": "500000000" }
],
"action": "CREATE"
}
FieldRequiredNotes
walletAddressYesThe position owner
protocolYesV2 \V3 \V4
chainIdYesSupported chain ID
lpTokensYesArray of { tokenAddress, amount } to be spent
actionYesCREATE \INCREASE \DECREASE \MIGRATE
simulateTransactionNoInclude gas estimates
includeGasInfoNoInclude gas info on returned approvals
generatePermitAsTransactionNoIf true, return permit as an executable transaction instead of typed data
urgencyNoNORMAL \FAST \URGENT
v3NftTokenIdNov3 NFT id when approving a position-manager NFT

Response

ts
interface CheckApprovalResponse {
requestId: string;
transactions: ApprovalTransactionRequest[]; // sign each .transaction; empty (with kycRequiredWarnings also empty) = nothing to approve
v4BatchPermitData?: NullablePermit; // v4: sign and pass into /lp/create or /lp/increase
v3NftPermitData?: NullablePermit; // v3 NFT permit
kycRequiredWarnings: KycRequiredWarning[]; // permissioned pools: non-empty when the wallet is NOT allowlisted. Always present (usually []).
}
interface ApprovalTransactionRequest {
transaction: TransactionRequest; // the tx to sign and broadcast
cancelApproval: boolean;
action: 'CREATE' | 'INCREASE' | 'DECREASE' | 'MIGRATE';
gasFee?: string;
}
interface KycRequiredWarning {
kycUrl: string;
tokenAddress: string;
chainId: number;
}
The response field is `transactions`, not `approvals`. Each element WRAPS a transaction. Sign element.transaction, never the element object itself. There are no top-level token/spender fields.
POST /lp/create

Create a v3 or v4 concentrated-liquidity position. Specify a price range and one token amount; the API computes the other from live pool state.

Pool specification — provide exactly one of:

  • existingPool: { token0Address, token1Address, poolReference } where poolReference is the pool address (v3) or pool ID (v4).
  • newPool: { token0Address, token1Address, fee, tickSpacing, hooks?, initialPrice } where initialPrice is a sqrtRatioX96 string (hooks is v4-only).

Price range — provide exactly one of:

  • priceBounds: { minPrice, maxPrice, quotedTokenAddress } — minPrice/maxPrice are decimal price strings and quotedTokenAddress is required (it must equal token0Address or token1Address). quotedTokenAddress sets which token the prices are denominated in; there is no default, and omitting it returns a 400. The API snaps to valid ticks and returns the adjusted prices.
  • tickBounds: { tickLower, tickUpper } raw integers.

Request

json
{
"walletAddress": "0x...",
"chainId": 1,
"protocol": "V3",
"existingPool": {
"token0Address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
"token1Address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"poolReference": "0x3470447f3cecffac709d3e783a307790b0208d60"
},
"independentToken": {
"tokenAddress": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
"amount": "198251669183062942"
},
"priceBounds": {
"minPrice": "0.00000000000324",
"maxPrice": "0.00000000000393",
"quotedTokenAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7"
},
"simulateTransaction": false
}

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
229
Repository forks
35
7-day trend score
27

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/uniswap/uniswap-ai/lp-integration/badge)](https://verified-skill.com/skills/uniswap/uniswap-ai/lp-integration)

Something wrong with this skill or its page? Tell us.