Skip to main content

Fully on-chain Python SDK for the Sally DeFi CrossHybrid protocol (Base + BSC) — swaps, pricing, liquidity. No API, no subgraph, no backend.

Project description

sally-defi-py-sdk · Python SDK

sally-defi-py-sdk · Python SDK

One client for CrossHybrid swaps & liquidity on Base + BSC.

Wraps the live Sally v2.0.2 protocol — best-route hybrid swaps, V2·V3·V4·Slipstream liquidity, 1e18 USD pricing, honeypot screening, locks and referral fees — behind one typed, beginner-friendly and AI-agent-ready API.

100% on-chain — no API, no subgraph, no backend.

Website · Docs · Examples · support@sally.tools


Why sally-defi-py-sdk

Most Python DeFi code is raw web3.py: untyped tuples, hand-rolled approvals, a quote you hope matches execution, and zero protection against honeypots or sandwiches. sally-defi-py-sdk collapses all of that into one safe call.

swap.execute does the work a careful integrator would do by hand — approve → enumerate routes → simulate every route on-chain → screen the output token for honeypot/tax → set minOut from the simulated output → send → assert you actually received it. That whole pipeline is the default, not an opt-in.

  • 🌐 Fully on-chain & decentralized. Every read — prices, routes, positions, balances — is a direct eth_call to the contracts. No proprietary API, no subgraph / Graph Node, no backend. Point it at any RPC (or your own node) and the only thing you trust is the chain itself.
  • 🛡️ Safety in the hot path. Simulate-before-execute + post-trade balance-delta assertion — not just in your test suite. (The balance-delta check is something even mature SDKs don't ship.)
  • 🧱 Typed end-to-end. pos.liquidity, plan.is_safe, quote.estimated_amount_out — dataclasses, autocomplete, JSON-able. No tuple[7].
  • 🤖 AI-agent-ready by construction. Every return serializes cleanly, so wiring Sally into LLM tools is mechanical.
  • Async + MEV-protection + permit are constructor/keyword arguments, not projects.
  • 🪶 Light deps (web3, eth-account, eth-abi, eth-utils, pydantic), Python ≥3.12, py.typed.

Honest about scope: Sally routes within its own protocol on Base + BSC — it is not a 100-source aggregator. Full, cited comparison (vorteile and nachteile) vs raw web3.py / uniswap-python / eth_defi / Ape / aggregator SDKs: docs/comparison.md.

🌐 Fully on-chain, fully decentralized

The SDK talks to the chain and nothing else. Routing, pricing, positions, honeypot screening and balances are all read with plain eth_calls against the on-chain contracts — there is no Sally API, no Graph Node / subgraph, no indexer and no backend service in the data path. Runtime dependencies are just the web3 stack (web3, eth-account, eth-abi, eth-utils, pydantic). Bring your own RPC or node and you trust nothing but the chain. (Aggregator SDKs, by contrast, require their off-chain API; subgraph-backed tools require an indexer.)

What you get

  • One object, every function. SallyClient exposes the whole protocol through feature namespaces (prices, swap, wallet, liquidity, fees, treasury, admin). Reads need only an RPC; writes need a signer.
  • Safe by default. swap.execute enumerates routes, integrity-checks each so funds can never enter a wrong pool, simulates every candidate on-chain, picks the best realized output, runs a honeypot/tax probe on the output token, sets minOut from the simulation, then asserts the received balance actually grew.
  • Single source of truth. All addresses + ABIs come from the bundled deployment.json (addresses + ABIs only). Nothing hard-coded; drop in a new deployment and the SDK follows.
  • Proxy-fallback aware. v2.0.2 serves Lens views through the swap proxy and Sidecar views through the liq proxy — the SDK wires this for you.
  • Typed returns. Every struct is a dataclass (SwapPath, V3Position, Lock, SwapPlan, …) — pos.liquidity, not pos[7].

Install

uv add sally-defi-py-sdk          # or: pip install sally-defi-py-sdk

Install as sally-defi-py-sdk, import as sally_defi (like pip install scikit-learnimport sklearn).

Requires Python ≥ 3.12 and web3 >= 7.6.

Quickstart (read-only)

from sally_defi import SallyClient
from sally_defi.constants import Base

sally = SallyClient("base", "https://mainnet.base.org")

sally.prices.usd(Base.USDC).as_float            # 1.0  (display / spot-mid)
sally.prices.usd_impact(Base.WETH).as_float     # 1703.19  (execution-aware)

quote = sally.swap.quote(Base.WETH, Base.USDC, 10**18)
quote.estimated_amount_out / 1e6                # 1703.45 USDC

Swapping — safe by default

sally = SallyClient("base", RPC, private_key="0x…")   # or SALLY_PRIVATE_KEY env

# Inspect first: compares every route, simulates each, screens the output token.
plan = sally.swap.plan(Base.WETH, Base.USDC, 10**18)
plan.summary()             # 'SwapPlan(… out~1702924727 sim=1702924727 min=1694410103 impact=13bps steps=2 SAFE)'
plan.is_safe               # False if honeypot / excessive tax / >15% impact / bad route
plan.candidates            # every route considered, with simulated output

# Execute: same vetting, then send + balance-delta assertion.
receipt = sally.swap.execute(Base.WETH, Base.USDC, 10**18, slippage_bps=50)

# Native ETH in — pass the NATIVE sentinel; value is attached for you.
from sally_defi.token import NATIVE
sally.swap.execute(NATIVE, Base.USDC, 10**17, slippage_bps=50)

What execute does, in order: approve (exact amount) → enumerate routes → integrity-check → simulate each on-chain → pick best realized output → honeypot/tax preflight → minOut from the simulation → send → assert received ≥ minOut. See docs/safety.md.

Tune the guard rails:

from sally_defi import SafetyConfig
sally = SallyClient("base", RPC, private_key="0x…",
                    safety=SafetyConfig(slippage_bps=30, tax_block_bps=3000,
                                        price_impact_block_bps=1000))

Liquidity

sally.liquidity.add_v2(dex_id=4, token_a=Base.WETH, token_b=Base.USDC,
                       amount_a=10**15, amount_b=2_000_000, lock_days=0)

sally.liquidity.positions_v3(wallet, 0, 10)     # list[V3Position]
sally.liquidity.locks(wallet)                   # list[Lock]
sally.liquidity.claimable_fees(npm, token_id)   # ClaimableFees
# add_v3 / add_v4 / add_slipstream, increase/decrease, remove_v2,
# lock/unlock, claim_fees_v3/v4(+_locked), mass_claim_fees, harvest_op

Referral system 💸

Every swap and liquidity action takes a referral address. Pass yours and the protocol accrues referral fees to it; read and claim them anytime:

sally.swap.execute(Base.WETH, Base.USDC, 10**18, referral="0xYourRef")

sally.fees.total_referral_owed("0xYourRef")     # total owed across tokens
sally.fees.referral_tokens("0xYourRef")         # per-token breakdown (paged)
sally.fees.claim_referral([Base.USDC, Base.WETH])   # claim selected tokens

See docs/referrals.md.

Async · permit · private mempool

# Async (concurrent quoting + simulation)
from sally_defi.aio import AsyncSallyClient
sally = AsyncSallyClient("base", RPC, private_key="0x…")
await sally.swap.execute(Base.WETH, Base.USDC, 10**18, slippage_bps=50)

# EIP-2612 permit instead of approve
sally.swap.execute(Base.USDC, Base.WETH, 10**8, approval="permit")

# Private mempool (MEV protection)
from sally_defi.constants import PrivateRelays
SallyClient("base", RPC, private_key="0x…", private_rpc_url=PrivateRelays.FLASHBOTS_FAST)

Full guide: docs/advanced.md.

Sign with your own wallet 🔑

Give a private_key, a mnemonic, or no key at all — build a vetted, simulated, ABI-decoded unsigned transaction and sign it with your own web3:

# mnemonic seed phrase
sally = SallyClient("base", RPC, mnemonic="word1 … word12", account_index=0)

# external signing — the SDK never holds your key
sally = SallyClient("base", RPC, address="0xYourWallet")   # knows sender, no key
build = sally.swap.execute(Base.WETH, Base.USDC, 10**18, build_only=True)
build.plan.summary()       # what happens to your wallet: out, min, impact, safe?
build.needs_approval       # sign build.approve_tx first if True
build.swap_tx              # unsigned tx → sign with your own account, then broadcast

# preview ANY call: decoded function + args + simulated result + revert reason
sally.preview(some_contract_fn).summary()

See docs/signing.md.

Namespaces

Namespace What it covers
client.prices usd (display), usd_impact (exec), spot, weth, usd_liquidity, token_info
client.swap quote(_v2/v3/v4/deep), candidates, plan, simulate_route, execute (+ build_only), token_info
client.wallet balances, balances_raw, total_usd
client.liquidity add / increase / decrease / remove / lock / claim / harvest, positions, pool state, dex registry
client.fees referral + batch fee reads & claims, swap_fee

Raw contracts are always reachable: client.swap_contract, …liquidity_contract, …lens_contract, …sidecar_contract.

AI agents

Every call returns a JSON-able dataclass with a clear docstring — wrapping Sally as LLM tools is trivial. See docs/ai-agents.md and examples/10_ai_agent_tools.py.

Docs

Why sally-defi-py-sdk comparison vs other DeFi SDKs, advantages & trade-offs
Getting started install, connect, first read & swap
Swap & safety route comparison, simulation, all guard rails
Liquidity add/remove/lock/harvest across V2·V3·V4
Pricing display vs execution price, spot, impact
Referrals earn & claim referral fees
Advanced async client, EIP-2612 permit, Permit2, private mempool, BSC
AI agents typed returns as tool functions
API reference every namespace + method

Live deployment (v2.0.2, Base = BSC)

Contract Address
SwapController (proxy) 0x7777D0e2e2d772b5D750540B3932261574e87777
LiquidityController (proxy) 0x7777d7fFF155B043CE0A0785dd8c8c42bEbe7777
Treasury 0x7777D7dC7ea65F33EC126165e03C6B6030887777

Development & tests

uv sync
uv run pytest -m "not fork"        # offline unit tests
anvil --fork-url $BASE_RPC --port 8547 --chain-id 8453 &
SALLY_RPC_URL=http://127.0.0.1:8547 uv run pytest   # + fork smoke tests

Support

Questions, integrations, partnerships → support@sally.tools · sally.tools

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sally_defi_py_sdk-0.3.1.tar.gz (56.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sally_defi_py_sdk-0.3.1-py3-none-any.whl (68.1 kB view details)

Uploaded Python 3

File details

Details for the file sally_defi_py_sdk-0.3.1.tar.gz.

File metadata

  • Download URL: sally_defi_py_sdk-0.3.1.tar.gz
  • Upload date:
  • Size: 56.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sally_defi_py_sdk-0.3.1.tar.gz
Algorithm Hash digest
SHA256 3d780020d68f33145c24a3e7c1b59b42768754d462c34d42db69bc9bd7f0a02d
MD5 6f8760d4cadcde2d1f3ad09d8df2984b
BLAKE2b-256 9475b7cef39660c76e04c941f786656764a17a5a2d32991b8a4d46861e257fe2

See more details on using hashes here.

File details

Details for the file sally_defi_py_sdk-0.3.1-py3-none-any.whl.

File metadata

File hashes

Hashes for sally_defi_py_sdk-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5be2b381db8172fcd0112b773b9ea43b8fb9fca60e310bf2c4beaf710b814b7e
MD5 555a3aa775f20f986bcfab496d0977db
BLAKE2b-256 27575847b8ce8cf7cbd6cf0937aa6e382ebcf12b0735eacb6a674c7ef2377d39

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page