Skip to content

Releases: Conrad-sudo/langchain-uniswap-v2

v0.5.1 — Badge update

Choose a tag to compare

@Conrad-sudo Conrad-sudo released this 20 Aug 10:06

Release v0.5.1

What's Changed

  • Documentation & PyPI Improvements: Added status badges to the README.md and PyPI project description to display supported Python versions and project licensing.

Badges Added

Python
License


Full Changelog: https://github.com/Conrad-sudo/langchain-uniswap-v2/commits/v0.5.1

v0.5.0 — gas_estimated moves onto the plan

Choose a tag to compare

@Conrad-sudo Conrad-sudo released this 20 Aug 07:15

One shape change, in the EOA path only. calls mode is untouched.

Breaking

  • gas_estimated no longer appears inside each transaction dict. It reaches you as
    plan["gas_estimated"] — a list of one bool per transaction, index for index with
    plan["transactions"], and None in calls mode, where nothing is estimated.

Why

A transaction dict now holds transaction fields and nothing else, so it signs exactly as
returned. Previously eth_account rejected it outright:

plan = tools["swap_exact_tokens_for_tokens"].invoke({...})
acct.sign_transaction(plan["transactions"][0])
# 0.4.0: TypeError: Unknown kwargs: ['gas_estimated']
# 0.5.0: signs

That broke the first thing every EOA consumer does, and the traceback pointed at
eth_account rather than at this package. The README worked around it in prose, telling
callers to pop the key before signing. "Did this limit come from a live estimate" is
provenance about the plan, not a field an Ethereum transaction has, so it now travels
beside the transactions instead of inside them.

Migrating

behaviour 0.4.0 0.5.0
acct.sign_transaction(plan["transactions"][0]) TypeError: Unknown kwargs signs
reading the flag plan["transactions"][i]["gas_estimated"] plan["gas_estimated"][i]
tx.pop("gas_estimated") in a signing loop required KeyError — delete the line
calls mode unaffected unaffected

The tolerant tx.pop("gas_estimated", None) keeps working as written; the strict form now
raises and the line should simply be removed.

Verification

Checked against a mainnet fork with an [approve, swap] plan, which exercises both flag
states: gas_estimated == [True, False], both transactions signed unmodified, and both
executed — approve 55,558 gas against a 69,921 limit, swap 127,760 against the 300,000
DEFAULT_GAS fallback. The fallback that a False flag reports is comfortably sufficient
in practice. 222 tests.

v0.4.0 — native_wrapped on every chain, quote-based route selection

Choose a tag to compare

@Conrad-sudo Conrad-sudo released this 12 Aug 11:48

No API change: nothing renamed, no signature removed, no return shape altered. Existing code keeps working as written.

Added

  • native_wrapped is now populated for all supported chains (previously None on 10 of 13), enabling the native-asset swap and liquidity tools and wrapped-native multi-hop routing on Optimism, Polygon, Base, Arbitrum, Avalanche, Unichain, Monad, X Layer, World Chain and Zora. Every value is verified equal to the chain router's own WETH().
  • scripts/verify_native_wrapped.py re-checks the whole registry against the live chains — router bytecode, WETH(), factory(), plus each wrapped native's symbol and decimals. Runs weekly in CI; unreachable endpoints skip, mismatches fail.

Fixed

  • for_chain() no longer raises TypeError when a caller overrides router_address, factory_address or native_wrapped_address.
  • Route selection no longer prefers a direct pair holding negligible reserves over a wrapped-native route that quotes better. Both candidates are quoted and the better fill wins; ties go to the direct pool. Previously this could select a materially worse price with no error — measured at 34% worse on a live Avalanche USDC/USDT pair holding under $1 a side, and silent, because amount_out_min derives from the same quote.

Behaviour changes for existing callers

0.3.0 0.4.0
eight native-asset tools on 10 of 13 chains raise ToolException build plans
token→token pairs with no direct pool, on those chains raise "no liquidity path" route through the wrapped native
direct pool holding dust, better route available silently takes the dust pool takes the better route
for_chain(cid, native_wrapped_address=...) TypeError override applied

https://pypi.org/project/langchain-uniswap-v2/0.4.0/

v0.3.0 — Write tools now return execution plans, for EOAs and smart-contract wallets

Choose a tag to compare

@Conrad-sudo Conrad-sudo released this 06 Aug 19:00

Breaking change

Every write tool now returns an execution plan instead of a bare unsigned transaction dict:

{
  "calls": [...],          # ordered, account-agnostic (to, value, data) list
  "transactions": [...] | None,  # EOA mode only; same calls, signable, nonces assigned
  "chain_id": 1,
  "summary": {...},        # amounts in whole units, safe to show a user
}

calls works directly with an ERC-4337/ERC-7579 smart-contract wallet's own batch executor. transactions (rendered by default, tx_mode="eoa") is the same calls as unsigned, signable EOA transactions with sequential nonces already assigned. tx_mode="calls" returns calls only, with zero nonce/gas/fee RPC calls.

Fixed

  • The core defect this release exists for: every allowance-dependent write tool used to fail at build time, because eth_estimateGas reverts when the approval it depends on isn't mined yet. Plans now build fine — the call that can't be simulated falls back to a static per-role gas limit (gas_estimated: False) instead of raising.
  • _build_path used to always route token→token swaps through the wrapped-native token, even when a liquid direct pair existed (paying the 0.3% fee twice). Direct pairs are now preferred when they have liquidity.
  • approve_token's "pass a very large number for unlimited" advice could raise a raw, unformatted web3 exception for amounts that overflow uint256. Replaced with unlimited=True, which approves 2**256 - 1 exactly.

Added

  • tx_mode, estimate_gas, gas_buffer, default_gas, reset_residual_approvals, preflight constructor options.
  • Every write tool includes its own approval call(s) automatically — no more manual approve_token-first flow. A trailing zero-approval reset is appended where the router may pull less than approved (governed by reset_residual_approvals).
  • recipient parameter on all ten swap/liquidity tools, defaulting to from_address.
  • preflight balance checks (on by default) run before building, raising ToolException naming the shortfall.
  • DEFAULT_GAS exported from the package.

Migration

See the README's Migration section for the full 0.2.0 → 0.3.0 diff.

https://pypi.org/project/langchain-uniswap-v2/0.3.0/

v0.2.0 — Write tools (unsigned transactions) and balance-sufficiency checks

Choose a tag to compare

@Conrad-sudo Conrad-sudo released this 04 Aug 11:25

This release adds write-side capability to the toolkit for the first time, without introducing a signer, session key, or any wallet state — every write tool builds and returns a plain unsigned transaction dict for the caller to sign and submit with their own wallet infrastructure. Nothing in this package ever touches key material. All 5 original read-only tools are unchanged; this is a fully backward-compatible, additive release.

Added — Write tools (11)

Every write tool takes an explicit from_address, derives amountOutMin/amountInMax/equivalent from a live on-chain quote via slippage_bps (default 50 bps), takes deadline_secs (default 600) for on-chain expiry, and accepts an optional nonce override for sequencing multiple unsigned transactions before submitting any of them.

  • approve_token — unsigned ERC20 approve. Always a separate transaction from the swap/deposit it precedes; there's no session-key-style atomic batching to lean on here.
  • swap_exact_tokens_for_tokens, swap_tokens_for_exact_tokens
  • swap_exact_eth_for_tokens, swap_eth_for_exact_tokens
  • swap_exact_tokens_for_eth, swap_tokens_for_exact_eth
  • add_liquidity, add_liquidity_eth — the paired-token amount is derived from live pool reserves so the deposit matches the current ratio
  • remove_liquidity, remove_liquidity_eth

Added — Balance-sufficiency checks (7)

Read-only tools that answer "does this address hold enough" before a write tool would actually be called, given an explicit owner_address — useful for an agent to check before spending gas building/submitting a transaction that would just revert.

  • is_token_balance_sufficient, is_native_balance_sufficient
  • is_derived_token_input_sufficient, is_derived_native_input_sufficient
  • is_liquidity_sufficient, is_liquidity_sufficient_eth
  • is_liquidity_removal_sufficient

Changed

  • UniswapV2Toolkit.get_tools() now returns 23 tools (up from 5), unconditionally — no gating, no constructor changes required for existing callers.
  • pyproject.toml description updated to reflect write capability.
  • ruff pinned to an exact version (==0.16.1) in the dev extra, after an unpinned ruff>=0.15 caused a CI failure when Ruff 0.16 made Markdown-embedded code-block formatting a stable default — the formatter, unlike the linter, isn't guaranteed stable across versions.

Not included in this release

  • No signer, no signers.py, no wallet abstraction of any kind — deliberately out of scope for this design; see the README's Scope section.
  • No live/testnet verification of build_transaction() output yet — write tools are covered by an extensive mocked test suite (138 tests total) but have not yet been exercised against a real chain the way the read-only tools were before v0.1.0.

Full docs: see the README for the complete tool reference and usage examples.
PyPI: https://pypi.org/project/langchain-uniswap-v2/0.2.0/

v0.1.0 — Initial release

Choose a tag to compare

@Conrad-sudo Conrad-sudo released this 09 Jul 11:06

Initial public release.

Read-only LangChain tools for querying Uniswap V2 (and Uniswap-V2-shaped fork,
e.g. PancakeSwap) pools — no wallet or ticker registry required.

Tools: get_quote_in, get_quote_out, get_pool_quote, get_lp_amounts,
get_liquidity_token_balance

Built-in chain registry: 13 EVM chains (Ethereum, Arbitrum, Base,
Optimism, Polygon, Avalanche, BSC via PancakeSwap, Unichain, Zora,
World Chain, Monad, X Layer, Sepolia).

📦 PyPI: https://pypi.org/project/langchain-uniswap-v2/0.1.0/