Skip to main content

HOGSWAP SDK (Python)

The official Python SDK for the HOGSWAP v1 router API — one call to quote the best route across every integrated Algorand DEX (STAMM, Tinyman, Pact, Humble, AlgoFi, Folks, liquid-staking mints), one call to get unsigned transactions your user's wallet signs. The API never touches keys and never broadcasts — your app stays in full control.

  • Zero dependencies. Pure standard library (urllib), Python 3.9+.
  • Sync and async. HogswapClient and AsyncHogswapClient expose the identical surface; the async client runs requests in worker threads via asyncio.to_thread — no extra deps, real concurrency.
  • Honest numbers. expected_out and min_out_at_slippage are what the contract actually delivers — routing fee included. Attach the user's wallet address and their HOG-holdings fee discount is priced in exactly.
  • Everything is atomic. A swap either delivers at least the quoted minimum or the whole transaction group reverts. No partial fills, no stuck funds.
  • Typed. Ships py.typed with full type hints.
Base URL: https://hogswap-v1.liquihog.dev

60-second start

from hogswap import HogswapClient, from_base_units

hogswap = HogswapClient()

# How much USDC for 10 ALGO?  (amounts are integer base units: 1 ALGO = 1_000_000)
quote = hogswap.swap_quote(
    asset_in=0,              # ALGO
    asset_out=31566704,      # USDC
    amount_in=10_000_000,
    slippage_bps=50,         # 0.5% tolerance
)

print("expected:", from_base_units(quote["expected_out"], 6), "USDC")
print("worst case:", from_base_units(quote["min_out_at_slippage"], 6), "USDC")
print("route:", " + ".join(leg["dex_name"] for leg in quote["legs"]))

Async, same surface:

import asyncio
from hogswap import AsyncHogswapClient

async def main():
    hogswap = AsyncHogswapClient()
    quote = await hogswap.swap_quote(asset_in=0, asset_out=31566704,
                                     amount_in=10_000_000)
    print(quote["expected_out"])

asyncio.run(main())

The full trade loop

import base64
from algosdk import encoding                # signing is YOUR side; any wallet works
from hogswap import HogswapClient

hogswap = HogswapClient(sender=user_address)   # fee discount priced in

# 1. Quote
quote = hogswap.swap_quote(asset_in=0, asset_out=31566704, amount_in=10_000_000)

# 2. Build unsigned transactions (call this right before signing)
built = hogswap.execute(quote_id=quote["quote_id"], user_address=user_address)

# 3. Sign with the user's wallet / key (py-algorand-sdk shown)
signed = [encoding.msgpack_decode(b64).sign(private_key) for b64 in built["txns_b64"]]

# 4. Submit the group to any algod node
txid = algod.send_transactions(signed)

Or, for a key you manage yourself, the optional helper (the ONLY key-touching code in the SDK, and it needs an explicit pip install py-algorand-sdk):

from hogswap import account_signer
sign = account_signer(private_key)             # -> sign(txns_b64, purpose)
signed_b64 = sign(built["txns_b64"], "swap")

Install

pip install hogswap-py-sdk

The import name is hogswap. Add local-signing support (optional) with pip install hogswap-py-sdk[signing].

What you can quote

Method What it does
swap_quote best route for amount_in of A → B
exact_out_quote minimum input that guarantees an exact output
multi_input_quote 2-4 assets → one output, single atomic group (dust consolidation)
basket_quote one input → primary + up to 3 exact-amount side outputs
lp_mint_quote add liquidity to a STAMM pool tier — with pool assets or any asset (auto-converted)
lp_redeem_quote burn LP tokens into any asset
execute quote → unsigned transaction group
swap quote + execute in one call

Market data (all edge-cached ~5s): assets, asset, asset_pools, pools, pool, stamm_pools, pair, price, prices, price_anchors, staking_assets, tvl, assets_tvl, health.

Batch lookups: assets(ids=[...]), prices([...]), assets_tvl([...]) — up to 100 asset ids per call.

Bounded-complexity routes (1.1.0): pass max_legs (1-16) to swap_quote to cap the TOTAL leg count, parallel pool splits included — max_hops bounds depth only. Built for callers that replay the session under their own resource budget (contract vaults, composed groups): you get the best route that fits, at a slightly worse price, instead of a rejection.

Watches: server-side arming over SSE (1.1.0)

Stop polling for prices: register a standing condition once and get pushed an event the block it arms. Free with any self-issued API key.

client = HogswapClient(api_key="hsk_...")

# "Tell me when swapping 100 ALGO would deliver >= 8.65 USDC."
client.put_watch(
    client_key="my-bot:algo-usdc", kind="target",
    asset_in=0, asset_out=31566704,
    amount_in=100_000_000, min_out=8_650_000,
)

for ev in client.watch_events():          # blocking generator
    if ev["type"] == "fired":
        ...  # numbers only — re-quote NOW, then execute

# async client: same surface, `async for` over watch_events()

Edge-triggered with per-watch re-arm hysteresis and cooldown; TTL auto-expiry; at-least-once delivery with seq-numbered replay. Events are hints — fills stay gated by your quote's on-chain floor. Details: docs/API.md.

Live block stream — the one endpoint without a wrapper method: it's plain Server-Sent Events at GET /stream/blocks; use any SSE client.

Full request/response reference: docs/API.md.

Amounts, fees, and floors — the three things to know

  1. Everything is integer base units. 1 ALGO = 1,000,000 µALGO; each ASA's decimals comes from assets(). Use to_base_units("1.5", 6) / from_base_units(1500000, 6) to convert safely (exact decimal.Decimal math, no float drift).
  2. Quotes are delivery-exact. The router's fee (5 bps, discounted by the sender's HOG holdings, free at 100+ HOG) is already subtracted from expected_out and min_out_at_slippage. Don't subtract anything client-side.
  3. min_out_at_slippage is enforced on-chain. If market movement makes delivery fall below it, the group reverts atomically and the user only spends network fees.

x402: paid tier + pay any invoice with any asset

The SDK speaks x402 end to end, strictly non-custodially — you provide sign and submit callables; the SDK never sees keys.

from hogswap import HogswapClient, PaymentRequiredError

hogswap = HogswapClient(api_key="hsk_...")

# Self-issue a key (no signup, no human): sign a challenge locally.
ch = hogswap.register(address=address)
res = hogswap.register_verify(
    address=address, challenge=ch["challenge"],
    signature_b64=my_sign_bytes(ch["challenge"]),   # e.g. algosdk.util.sign_bytes
)
hogswap.set_api_key(res["api_key"])

# Out of credits? Any call raises PaymentRequiredError whose `.offer`
# IS the x402 payment instruction. Top up with ANY 1-4 assets you
# hold (here: minimum ALGO, solved by the exact-out router):
try:
    hogswap.swap_quote(...)
except PaymentRequiredError:
    hogswap.topup_with_assets(
        usdc_micro=1_000_000, user_address=address,
        inputs=[{"asset_id": 0}],            # pay 1 USDC worth of ALGO
        sign=lambda txns_b64, purpose: wallet.sign_group(txns_b64),
        submit=lambda signed, purpose: algod.send_transactions(signed),
    )                                        # returns when credits land
    # retry the original call

# Or pay ANY third-party Algorand x402 invoice the same way:
hogswap.pay_invoice(invoice=offer["accepts"][0], user_address=address,
                    inputs=[{"asset_id": 0}], sign=sign, submit=submit)

Groups are submitted in order (swap first — its on-chain floor guarantees the payment is funded). On the async client, sign and submit may be coroutine functions. AI agents get the same tools over MCP: hogswap-mcp; JavaScript apps get hogswap-js-sdk.

Being a good API citizen (limits)

Limit Value On violation
Quote rate 30 requests / 10s / IP HTTP 429 for ~10s
Concurrency 4 in-flight requests / IP immediate HTTP 429
Execute budget 5 builds per quote_id HTTP 429 — get a fresh quote
Quote lifetime ~30 seconds HTTP 404 on execute — get a fresh quote

The SDK raises typed errors (RateLimitError, QuoteExpiredError, ExecuteBudgetError, …) so handling these is an isinstance check. Identical anonymous quotes within 5s are served from cache — repeats are nearly free, so don't build your own quote cache.

Tips: debounce type-to-quote inputs (~300ms); request a quote when the user is ready to see a price, execute right before signing; never hardcode pool/app ids — everything you need is in the API responses. (The router's on-chain app id may change between releases; transactions returned by execute always target the current one.)

FAQ

Do I need an API key? No. Public, rate-limited per IP.

Which wallets work? Any Algorand wallet that signs standard transaction groups (Pera, Defly, Exodus, KMD, …). The API returns plain unsigned transactions; nothing wallet-specific.

Is my seed phrase ever involved? Never. The API builds unsigned transactions; signing happens entirely in your app/wallet, and you submit to algod yourself. The SDK core takes no keys anywhere; the optional account_signer helper is the single, explicit opt-in for local keys.

Sync or async? Same surface, your call. AsyncHogswapClient wraps the sync core with asyncio.to_thread, so there's exactly one implementation to trust.

License

MIT — see LICENSE.

Metadata

Release files for hogswap-py-sdk 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hogswap-py-sdk 1.1.0
File Size Uploaded
hogswap_py_sdk-1.1.0.tar.gz 35.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hogswap-py-sdk 1.1.0
File Interpreter ABI Platform
hogswap_py_sdk-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 63.1 kB

Release files / hogswap_py_sdk-1.1.0.tar.gz

Download URL hogswap_py_sdk-1.1.0.tar.gz
Size 35.6 kB
Tags Source
SHA-256 checksum
How to use checksums
ce54ecaa10ee03e93ea00a692ad789ca3b5f1ff9c4a6293c5786123bdf949411
BLAKE2b-256 checksum
How to use checksums
8f1d6ca41941e36dc26eabf1c07ef08c997aecc4d826d316a11b73b0e8bab89b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / hogswap_py_sdk-1.1.0-py3-none-any.whl

Download URL hogswap_py_sdk-1.1.0-py3-none-any.whl
Size 27.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
26fcbf487a6b63c4fb6c490a205918b73d40c0b17d073df5cee8e8e2099f4cd0
BLAKE2b-256 checksum
How to use checksums
d7a84176626bfa211694e354a71a02f07f4359e748202e128f30115e92d34604
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release history Release notifications | RSS feed

1.3.0

2 release files

1.2.0

2 release files

This release

1.1.0 This release

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page