GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — feat: uniswap-trading AI-agent skill (D3 skeleton) by TimeToBuildBob · Pull Request #478 · uniswap-python/uniswap-python

feat: uniswap-trading AI-agent skill (D3 skeleton) #478

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Sign up for GitHub

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
TimeToBuildBob wants to merge 7 commits into uniswap-python:master
base: master
Loading
Loading
from TimeToBuildBob:feat/agent-skill-skeleton

Uh oh!

There was an error while loading. Please reload this page.

Draft

feat: uniswap-trading AI-agent skill (D3 skeleton) #478

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
7 commits
Select commit Hold shift + click to select a range
70dc6ac
feat: add uniswap-trading AI-agent skill (skeleton)
TimeToBuildBob Aug 27, 2026
09bf93e
fix(skill): require wallet address for balance
TimeToBuildBob Aug 27, 2026
4efdb86
docs(skill): clarify balance address requirement
TimeToBuildBob Aug 27, 2026
29a5c7a
fix(skill): validate balance wallet address
TimeToBuildBob Aug 27, 2026
2cdf77f
feat(skill): fold in dogfood corrections from cross-agent testing
TimeToBuildBob Aug 27, 2026
668418b
ci: retrigger CI — previous run failed on transient eth.drpc.org RPC …
TimeToBuildBob Oct 15, 2026
25ec81e
ci: upgrade codecov-action v4→v5, set fail_ci_if_error=false
TimeToBuildBob Oct 15, 2026
File filter
Filter by extension


Clear filters
Conversations
Failed to load comments.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Jump to
Jump to file
Failed to load files.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Diff view
Diff view

There are no files selected for viewing

4 changes: 2 additions & 2 deletions 4 .github/workflows/test.yml
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ jobs:
make test

- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
fail_ci_if_error: false

typecheck:
name: typecheck
Expand Down
58 changes: 58 additions & 0 deletions 58 skills/uniswap-trading/README.md
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# uniswap-trading agent skill

An AI-agent integration for uniswap-python: a [SKILL.md](SKILL.md) following
the [Anthropic skill format](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/skills)
plus a subprocess-friendly CLI (`scripts/uniswap_agent.py`) that any agent
framework can call.

## Install into an agent

- **Claude Code**: symlink or copy this directory to `~/.claude/skills/uniswap-trading`
(or `.claude/skills/uniswap-trading` in a project). The skill loads on demand.
- **gptme**: add this directory to a configured lessons/skills path; the
`description` frontmatter drives matching.
- **Anything else** (LangChain, OpenAI tools, MCP): wrap
`scripts/uniswap_agent.py --json <command>` as a subprocess tool. The CLI is
the integration surface — stdout is one JSON object, exit codes are stable
(0 ok, 1 runtime error, 2 safety refusal).

## Demo

`./demo_sepolia.sh` runs read-only mainnet quotes (v3 + v4, verified working
against public RPCs) plus Sepolia status, and — once the library gains Sepolia
support — a real Sepolia swap with `DEMO_BROADCAST=1` and a funded key.

## Tests

```bash
python3 -m pytest skills/uniswap-trading/tests/ -q
```

No network needed — tests cover the safety gates and argument surface.

## Status

Skeleton (grant deliverable D3 groundwork). Verified working: v3 + v4
mainnet quotes over public RPCs, dry-run swap plans, all safety gates.
Cross-agent dogfood (Gordon, 2026-08-27): install clean, mainnet v3/v4 +
Polygon v3 quoting verified; his four corrections are folded in — human
amounts in JSON, deterministic v3-testnet refusal, branch-install setup
docs, double-armed mainnet broadcast (`UNISWAP_AGENT_ALLOW_MAINNET=1` +
`--allow-mainnet`).
TODO before production:

- [ ] **Sepolia enablement in the library** (blocks the D3 testnet tx demo):
v3 hardcodes the mainnet quoter/router in `uniswap.py`; the v4 maps in
`constants.py` have no `"sepolia"` entries. Official Sepolia v4
deployments (PoolManager `0xE03A1074c86CFeDd5C142C4F04F1a1536e203543`,
UniversalRouter `0x3A9D48AB9751398BbFa63ad67599Bb04e4BdF98b`, V4Quoter
`0x61b3f2011a92d183c7dbadbda940a7555ccf9227`, StateView
`0xe1dd9c3fa50edb962e442f60dfbc432e24537e4c`, PositionManager
`0x429ba70129df741B2Ca2a85BC3A2a3328e5c09b4`, Permit2
`0x000000000022D473030F116dDEE9F6B43aC78BA3`) cover 6 of the 8
contracts `Uniswap4.__init__` requires — `position_descriptor` and
`reserves_lens` still need deployments/addresses.
- [ ] v4 route/multi-hop support in `swap` (currently single-hop PoolKey)
- [ ] Wire tests into repo CI
- [ ] MCP server wrapper (optional distribution surface)
- [ ] Publish demo transcript + testnet tx hash in docs
95 changes: 95 additions & 0 deletions 95 skills/uniswap-trading/SKILL.md
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
name: uniswap-trading
description: Quote prices and execute Uniswap v2/v3/v4 swaps via uniswap-python. Use when asked to check on-chain token prices, get swap quotes, or trade tokens on Uniswap. Testnet-first — mainnet requires explicit opt-in. Do NOT use for CEX trading, fiat, or chains without Uniswap deployments.
---

# Uniswap Trading

Trade on Uniswap through [uniswap-python](https://github.com/uniswap-python/uniswap-python)
using a single CLI: `scripts/uniswap_agent.py`. All commands are safe to
explore — state-changing operations are **dry-run unless `--broadcast`** is
passed, and non-testnet chains are refused unless explicitly allowed.

## Setup

Requires uniswap-python **with this skill included** — until the next PyPI
release contains it, install from the PR branch:

```bash
pip install "uniswap-python @ git+https://github.com/TimeToBuildBob/uniswap-python.git@feat/agent-skill-skeleton"
# after the skill ships in a release: pip install "uniswap-python>=0.8.1"
```

Then:

```bash
export PROVIDER=https://ethereum-sepolia-rpc.publicnode.com # any JSON-RPC endpoint
export UNISWAP_AGENT_ADDRESS=0xYourWallet # for balances/swaps
export UNISWAP_AGENT_PRIVATE_KEY=0x... # ONLY for --broadcast
```

Never echo `UNISWAP_AGENT_PRIVATE_KEY` or write it to disk. Read-only
commands (status, quote) work with just `PROVIDER`.

## Commands

```bash
SKILL_DIR=$(dirname "$0") # or the directory containing this SKILL.md

# Connectivity + wallet overview
python3 "$SKILL_DIR/scripts/uniswap_agent.py" --json status

# Quote: how much USDC for 0.01 WETH? (amounts in wei/base units)
python3 "$SKILL_DIR/scripts/uniswap_agent.py" --json quote WETH USDC 10000000000000000

# Dry-run swap (prints plan: quote, min-out after slippage; sends nothing)
python3 "$SKILL_DIR/scripts/uniswap_agent.py" --json swap WETH USDC 10000000000000000

# Real swap on testnet (requires key; approve the router first for ERC-20 input)
python3 "$SKILL_DIR/scripts/uniswap_agent.py" --json approve WETH --broadcast
python3 "$SKILL_DIR/scripts/uniswap_agent.py" --json swap WETH USDC 10000000000000000 --broadcast

# Uniswap v4 (single-hop; pool identified by fee + tick spacing)
python3 "$SKILL_DIR/scripts/uniswap_agent.py" --json --version 4 \
quote WETH USDC 10000000000000000 --fee 3000 --tick-spacing 60
```

On Sepolia the symbols `ETH`, `WETH`, `USDC` resolve automatically; on other
chains pass 0x token addresses.

## Safety rules (enforced by the CLI, exit code 2 on refusal)

1. Read-only commands (status, quote, balance) work on any chain. Broadcasting
outside known testnets (Sepolia, Arbitrum/Base/Optimism Sepolia) is
**double-armed**: it requires BOTH `UNISWAP_AGENT_ALLOW_MAINNET=1` in the
environment AND `--allow-mainnet` on the specific call. Never set the
environment arm yourself — that is the human operator's standing decision;
the flag is your per-call confirmation.
2. Nothing is signed or sent without `--broadcast`.
3. Slippage above 5% is refused (`UNISWAP_AGENT_MAX_SLIPPAGE` to override).
4. v3 on testnets is refused deterministically (exit 2) — the library's v3
contracts are mainnet-hardcoded; don't retry, use a production network or
v4.

## Current network coverage (uniswap-python 0.8.0)

Quotes work today on the ~18 production networks configured in the library
(mainnet, base, arbitrum, optimism, polygon, ...). Sepolia broadcasting is
pending library-side enablement: the v3 client hardcodes mainnet contract
addresses, and the v4 address maps don't include Sepolia yet. Until then, use
mainnet for read-only quoting and expect `status` (but not `quote`/`swap`) to
work on Sepolia.

## Interpreting output

With `--json`, results are a single JSON object on stdout. Errors go to
stderr as `{"error": ..., "kind": "safety"|"runtime"}`; exit code 2 means a
safety guard refused (do not retry with workarounds — report to the human),
1 means a runtime error (bad pool, no liquidity, RPC down — often worth one
retry or a different fee tier).

Amounts are integers in the token's base units (wei for ETH/WETH: 1 ETH =
10^18). Where token decimals are readable on-chain, outputs also carry
advisory `<field>_human` (decimal string) and `decimals_<field>` companions —
prefer those when showing humans, but treat the integer fields as the source
of truth (the human fields are omitted when a decimals lookup fails).
43 changes: 43 additions & 0 deletions 43 skills/uniswap-trading/demo_sepolia.sh
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
# Demo for the uniswap-trading agent skill.
#
# Part 1 (works today): read-only quoting against mainnet — no key needed.
# Part 2 (Sepolia broadcast): blocked on library-side Sepolia enablement
# (v3 hardcodes mainnet contracts; v4 address maps lack Sepolia). Once
# uniswap-python configures Sepolia, run with:
# UNISWAP_AGENT_ADDRESS=0x... UNISWAP_AGENT_PRIVATE_KEY=0x... DEMO_BROADCAST=1
set -euo pipefail

SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
AGENT="python3 $SKILL_DIR/scripts/uniswap_agent.py --json"

MAINNET_RPC="${MAINNET_RPC:-https://ethereum-rpc.publicnode.com}"
SEPOLIA_RPC="${SEPOLIA_RPC:-https://ethereum-sepolia-rpc.publicnode.com}"

# 0.001 WETH in wei
QTY=1000000000000000

echo "== [mainnet, read-only] status =="
PROVIDER=$MAINNET_RPC $AGENT status

echo "== [mainnet, read-only] v3 quote: 0.001 WETH -> USDC =="
PROVIDER=$MAINNET_RPC $AGENT quote WETH USDC "$QTY"

echo "== [mainnet, read-only] v4 quote: 0.001 ETH -> USDC =="
PROVIDER=$MAINNET_RPC $AGENT --version 4 quote ETH USDC "$QTY" --fee 500 --tick-spacing 10

echo "== [mainnet] dry-run swap plan (nothing is sent) =="
PROVIDER=$MAINNET_RPC $AGENT swap WETH USDC "$QTY"

echo "== [sepolia] status =="
PROVIDER=$SEPOLIA_RPC $AGENT status

if [ "${DEMO_BROADCAST:-0}" = "1" ]; then
echo "== [sepolia] approve WETH (broadcast) =="
PROVIDER=$SEPOLIA_RPC $AGENT approve WETH --broadcast
echo "== [sepolia] swap 0.001 WETH -> USDC (broadcast) =="
PROVIDER=$SEPOLIA_RPC $AGENT swap WETH USDC "$QTY" --broadcast
else
echo "(Sepolia swap skipped: needs DEMO_BROADCAST=1, a funded key, and"
echo " library-side Sepolia contract enablement — see README status list)"
fi
Loading
Oops, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Loading
Oops, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.