# Uniswap plugin (https://docs.helico.site/docs/uniswap-plugin)

Uniswap v4 on chain through the official SDKs and viem, on any chain, without signing or sending.

[`@helico/plugin-uniswap`](https://github.com/0xHelico/helico/tree/main/packages/plugins/uniswap) resolves addresses, reads
pools, quotes, and builds calldata. It never signs or sends. No API key, no wallet.

| Module                  | Does                                                                                                                                                                                                         |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `addresses`, `networks` | addresses and the Universal Router version per chain, from the SDKs; built-ins for Ethereum, Arbitrum, Polygon, BNB, Base, Base Sepolia, Robinhood Chain and its testnet; runtime registration for any other |
| `pool`                  | pool keys, `poolId` matching v4's own, state through `StateView`, tick and price helpers                                                                                                                     |
| `quote`                 | exact-in and exact-out, single and multi-hop, through the v4 `Quoter` over `eth_call`                                                                                                                        |
| `swap`                  | Universal Router calldata for every swap shape, with the router-level `SWEEP` for native exact-output                                                                                                        |
| `approval`              | Permit2 allowances, the two approvals, EIP-712 `PermitSingle` data                                                                                                                                           |
| `liquidity`             | `V4PositionManager` calldata: initialise, mint, increase, decrease, collect                                                                                                                                  |

```ts
import * as uni from '@helico/plugin-uniswap'
import { createPublicClient, http } from 'viem'

const net = uni.network('arbitrum')
const client = createPublicClient({ chain: net.chain, transport: http() })
const poolKey = uni.createPoolKey({ currencyA: '0x0000000000000000000000000000000000000000', currencyB: net.usd.address, fee: 500, tickSpacing: 10 })
const { amountOut } = await uni.quoteExactInputSingle(client, { poolKey, zeroForOne: true, amountIn: 10n ** 18n })
const tx = uni.encodeSwapExactInSingle({ chainId: net.chain.id, poolKey, zeroForOne: true, amountIn: 10n ** 18n, amountOutMinimum: uni.minimumAfterSlippage(amountOut, 50), deadline: uni.deadlineFromNow(600) })
// tx = { to, data, value }: simulate it, or sign and send it yourself
```

## Scripts
```bash
bun run --filter @helico/plugin-uniswap test                     # offline
CHAIN=base bun run --filter @helico/plugin-uniswap smoke         # live, read-only
CHAIN=base-sepolia bun run --filter @helico/plugin-uniswap e2e   # sends real transactions; needs PRIVATE_KEY
```

## Executed on chain
The full lifecycle, wrap, initialise, approve, mint, increase, swap both ways, collect, burn,
has run on Base Sepolia and on Robinhood Chain Testnet with every step `status: success`.
Read-only checks have run on Arbitrum One and Robinhood Chain. The hashes are in
[the README](https://github.com/0xHelico/helico/blob/main/packages/plugins/uniswap/README.md#executed-on-chain); what was
hard about v4 is in [`FEEDBACK.md`](https://github.com/0xHelico/helico/blob/main/FEEDBACK.md).

## Do not forget
`amountOutMinimum` and `amountInMaximum` are the only slippage guards, so derive them from a
fresh quote. The V4\_SWAP input is `V4Planner.finalize()`. Native-input exact-output swaps leave
ETH in the router, which is why the encoders add a `SWEEP`.
