Python SDK for Pact smart contracts.
What is covered by the library:
- Fetching pools
- Opt-in for assets
- Managing liquidity
- Inspecting pools state
- Making swaps
Signing and sending transactions is not covered by the library. The provided examples use algosdk directly to send the transactions.
pip install pactsdk
CAUTION - The library uses integers for asset amounts e.g. microalgos instead of algos so if you want to send 1 algo, you need to specify it as 1_000_000.
Create a Pact client.
from algosdk.v2client.algod import AlgodClient
import pactsdk
algod = AlgodClient(token, url)
pact = pactsdk.PactClient(algod)
Optionally you can specify custom Pact API url. By default it directs to production API.
pact = pactsdk.PactClient(algod, pact_api_url="https://api.testnet.pact.fi")
Fetching pools by assets pair. It uses Pact API to retrieve the pool. Can return multiple pools with differing fee_bps.
algo = pact.fetch_asset(0)
other_coin = pact.fetch_asset(8949213)
pools = pact.fetch_pools_by_assets(algo, other_coin) # The pool will be fetched regardless of assets order.
You can fetch a pool by providing assets ids instead of Asset objects.
pools = pact.fetch_pools_by_assets(0, 8949213)
You can also fetch a pool by providing app id. This way the pool is retrieved directly from the chain.
pool = pact.fetch_pool_by_id(456321)
You can list all pools from the Pact API.
pools = pact.list_pools()
print(pools)
# {
# "count": 19,
# "next": "http://api.pact.fi/api/pools?page=2",
# "previous": None,
# "results": [...],
# }
# The listing uses pagination and filtering.
pools = pact.list_pools(
page=2,
primary_asset__algoid=9843123,
)
Before making the transactions you need to opt-in for the assets. There's no need to opt-in for algo.
import algosdk
private_key = algosdk.mnemonic.to_private_key('<mnemonic>')
address = algosdk.account.address_from_private_key(private_key)
def opt_in(asset):
is_opted_in = asset.is_opted_in(address)
if not is_opted_in
opt_in_tx = asset.prepare_opt_in_tx(address)
signed_tx = opt_in_tx.sign(private_key)
algod.send_transaction(signed_tx)
}
}
opt_in(pool.primary_asset)
opt_in(pool.secondary_asset)
opt_in(pool.liquidity_asset) # Needed if you want to manage the liquidity.
Check the current pool state.
print(pool.state)
# PoolState(
# total_liquidity=900000,
# total_primary=956659,
# total_secondary=849972,
# primary_asset_price=Decimal(0.8884795940873393),
# secondary_asset_price=Decimal(1.1255182523659604),
# )
Explicit pool state update is necessary periodically and after each pool operation.
pool.update_state()
pool.state # Now holds fresh values.
Managing the liquidity.
# Add liquidity.
add_liq_tx_group = pool.prepare_add_liquidity_tx(
address=address,
primary_asset_amount=100_000,
secondary_asset_amount=50_000,
);
signed_add_liq_tx_group = add_liq_tx_group.sign(private_key)
algod.send_transactions(signed_add_liq_tx_group)
# Remove liquidity.
remove_liq_tx_group = pool.prepare_remove_liquidity_tx(
address=address,
amount=100_000,
)
signed_remove_liq_tx_group = remove_liq_tx_group.sign(private_key)
algod.send_transactions(signed_remove_liq_tx_group)
Making a swap.
swap = pool.prepare_swap(
asset=algo,
amount=200_000,
slippage_pct=2,
)
# You can inspect swap effect before submitting the transaction.
print(swap.effect)
# SwapEffect(
# amount_out=200000,
# amount_in=146529,
# minimum_amount_in=143598,
# fee=441,
# price=Decimal(0.73485),
# primary_asset_price_after_swap=Decimal("0.6081680080300244"),
# secondary_asset_price_after_swap=Decimal("1.6442824791774173"),
# primary_asset_price_change_pct=Decimal("-31.549580645715963"),
# secondary_asset_price_change_pct=Decimal("46.091142966447585"),
# )
# Let's submit the swap.
swap_tx_group = swap.prepare_tx(address)
signed_tx_group = swap_tx_group.sign_txn(private_key)
algod.send_transactions(signed_tx_group)
Look for more examples.
poetry install
Development requires Pact contracts V1 to be checked out.
git clone [email protected]:pactfi/algorand-testbed.git
cd algorand-testbed
poetry install
docker compose up -d
cd ..
poetry build
You can install the package locally with
pip install dist/pactsdk-<version>.whl
Validate the installation python -c "import pactsdk; print(pactsdk.__version__)"
poetry run pytest