Skip to main content

Sugar SDK

Project description

Sugar SDK

Sugar SDK

Sugar makes Velodrome and Aerodrome devs life sweeter 🍭

Contents

Using Sugar

pip install git+https://github.com/velodrome-finance/sugar-sdk.git@v0.3.1

You can take it for a spin on CodeSandbox

Base Quickstart

Getting started with Sugar on Base network:

from sugar.chains import BaseChain, AsyncBaseChain

# async version
async with AsyncBaseChain() as chain:
    prices = await chain.get_prices(await chain.get_all_tokens())
    for p in prices[:5]:
        print(f"{p.token.symbol} price: {p.price}")

# sync version
with BaseChain() as chain:
    for p in chain.get_prices(chain.get_all_tokens())[:5]:
        print(f"{p.token.symbol} price: {p.price}")

OP Quickstart

Getting started with Sugar on OP network:

from sugar.chains import AsyncOPChain, OPChain

async with AsyncOPChain() as chain:
    prices = await chain.get_prices(await chain.get_all_tokens())
    for p in prices[:5]:
        print(f"{p.token.symbol} price: {p.price}")

with OPChain() as chain:
    for p in chain.get_prices(chain.get_all_tokens())[:5]:
        print(f"{p.token.symbol} price: {p.price}")

Pools

Getting information about pools:

from sugar.chains import AsyncOPChain, OPChain

async with AsyncOPChain() as chain:
    pools = await chain.get_pools()
    usdc_velo = next(iter([p for p in pools if p.token0.token_address == OPChain.usdc.token_address and p.token1.token_address == OPChain.velo.token_address]), None)
    print(f"{usdc_velo.symbol}")
    print("-----------------------")
    print(f"Volume: {usdc_velo.token0_volume} {usdc_velo.token0.symbol} | {usdc_velo.token1_volume} {usdc_velo.token1.symbol} | ${usdc_velo.volume}")
    print(f"Fees: {usdc_velo.token0_fees.amount} {usdc_velo.token0.symbol} | {usdc_velo.token1_fees.amount} {usdc_velo.token1.symbol} | ${usdc_velo.total_fees}")
    print(f"TVL: {usdc_velo.reserve0.amount} {usdc_velo.token0.symbol} | {usdc_velo.reserve1.amount} {usdc_velo.token1.symbol} | ${usdc_velo.tvl}")
    print(f"APR: {usdc_velo.apr}%")

with OPChain() as chain:
    pools = chain.get_pools()
    usdc_velo = next(iter([p for p in pools if p.token0.token_address == OPChain.usdc.token_address and p.token1.token_address == OPChain.velo.token_address]), None)
    print(f"{usdc_velo.symbol}")
    print("-----------------------")
    print(f"Volume: {usdc_velo.token0_volume} {usdc_velo.token0.symbol} | {usdc_velo.token1_volume} {usdc_velo.token1.symbol} | ${usdc_velo.volume}")
    print(f"Fees: {usdc_velo.token0_fees.amount} {usdc_velo.token0.symbol} | {usdc_velo.token1_fees.amount} {usdc_velo.token1.symbol} | ${usdc_velo.total_fees}")
    print(f"TVL: {usdc_velo.reserve0.amount} {usdc_velo.token0.symbol} | {usdc_velo.reserve1.amount} {usdc_velo.token1.symbol} | ${usdc_velo.tvl}")
    print(f"APR: {usdc_velo.apr}%")

Fees and Incentives

To get information for the latest epochs across all the pools:

async with AsyncOPChain() as chain:
    epochs = await chain.get_latest_pool_epochs()
    ep = epochs[0]
    print(f"{ep.pool.symbol}")
    print(f"Epoch date: {ep.epoch_date}")
    print(f"Fees: {' '.join([f'{fee.amount} {fee.token.symbol}' for fee in ep.fees])} {ep.total_fees}")
    print(f"Incentives: {' '.join([f'{incentive.amount} {incentive.token.symbol}' for incentive in ep.incentives])} {ep.total_incentives}")

You can also get epochs for a specific pool using its address:

async with AsyncOPChain() as chain:
    epochs = await chain.get_pool_epochs("0x7A7f1187c4710010DB17d0a9ad3fcE85e6ecD90a")
    ep = epochs[0]
    print(f"{ep.pool.symbol}")
    print(f"Epoch date: {ep.epoch_date}")
    print(f"Fees: {' '.join([f'{fee.amount} {fee.token.symbol}' for fee in ep.fees])} {ep.total_fees}")
    print(f"Incentives: {' '.join([f'{incentive.amount} {incentive.token.symbol}' for incentive in ep.incentives])} {ep.total_incentives}")

Swaps

Get a quote and swap:

from sugar.chains import AsyncOPChain

async with AsyncOPChain() as op:
    quote = await op.get_quote(from_token=AsyncOPChain.velo, to_token=AsyncOPChain.eth, amount=AsyncOPChain.velo.parse_units(10))
    if not quote:
        # no quote found 
    # check quote.amount_out
    await op.swap_from_quote(quote)

“I am Feeling lucky” swap:

from sugar.chains import AsyncOPChain

async with AsyncOPChain() as op:
    await op.swap(from_token=velo, to_token=eth, amount=velo.parse_units(10))

Superswaps

from sugar import OPChain, LiskChain, Superswap

superswap = Superswap()
quote = superswap.get_super_quote(from_token=OPChain.velo, to_token=LiskChain.lsk, amount=OPChain.velo.parse_units(100))
superswap.swap_from_quote(quote)

# feeling lucky Superswap
Superswap().swap(from_token=OPChain.velo, to_token=LiskChain.lsk, amount=OPChain.velo.parse_units(100))

As always, async version is also available

from sugar import OPChain, LiskChain, AsyncSuperswap

superswap = AsyncSuperswap()
quote = await superswap.get_super_quote(from_token=OPChain.velo, to_token=LiskChain.lsk, amount=OPChain.velo.parse_units(100))
await superswap.swap_from_quote(quote)

# feeling lucky Superswap
await AsyncSuperswap().swap(from_token=OPChain.velo, to_token=LiskChain.lsk, amount=OPChain.velo.parse_units(100))

Configuration

Full list of configuration parameters for Sugar. Chain IDs can be found here. Sugar uses decimal versions: Base is 8453, OP is 10.

config env default value
native_token_symbol ETH
native_token_decimals 18
wrapped_native_token_addr SUGAR_WRAPPED_NATIVE_TOKEN_ADDR_<CHAIN_ID> chain specific
rpc_uri SUGAR_RPC_URI_<CHAIN_ID> chain specific
sugar_contract_addr SUGAR_CONTRACT_ADDR_<CHAIN_ID> chain specific
slipstream_contract_addr SUGAR_SLIPSTREAM_CONTRACT_ADDR_<CHAIN_ID> chain specific
nfpm_contract_addr SUGAR_NFPM_CONTRACT_ADDR chain specific
price_oracle_contract_addr SUGAR_PRICE_ORACLE_ADDR_<CHAIN_ID> chain specific
router_contract_addr SUGAR_ROUTER_CONTRACT_ADDR_<CHAIN_ID> chain specific
swapper_contract_addr SUGAR_ROUTER_SWAPPER_CONTRACT_ADDR_<CHAIN_ID> chain specific
swap_slippage SUGAR_SWAP_SLIPPAGE_<CHAIN_ID> 0.01
token_addr SUGAR_TOKEN_ADDR_<CHAIN_ID> chain specific
stable_token_addr SUGAR_STABLE_TOKEN_ADDR_<CHAIN_ID> chain specific
connector_tokens_addrs SUGAR_CONNECTOR_TOKENS_ADDRS_<CHAIN_ID> chain specific
excluded_tokens_addrs SUGAR_EXCLUDED_TOKENS_ADDRS_<CHAIN_ID> chain specific
price_batch_size SUGAR_PRICE_BATCH_SIZE 40
price_threshold_filter SUGAR_PRICE_THRESHOLD_FILTER 10
interchain_router_contract_addr SUGAR_INTERCHAIN_ROUTER_CONTRACT_ADDR_<CHAIN_ID> chain specific
bridge_contract_addr SUGAR_BRIDGE_CONTRACT_ADDR_<CHAIN_ID> chain specific
bridge_token_addr SUGAR_BRIDGE_TOKEN_ADDR_<CHAIN_ID> chain specific
message_module_contract_addr SUGAR_MESSAGE_MODULE_CONTRACT_ADDR_<CHAIN_ID> chain specific
pool_page_size SUGAR_POOL_PAGE_SIZE 500
pools_count_upper_bound POOLS_COUNT_UPPER_BOUND_<CHAIN_ID> 2500
pagination_limit SUGAR_PAGINATION_LIMIT 2000
pricing_cache_timeout_seconds SUGAR_PRICING_CACHE_TIMEOUT_SECONDS_<CHAIN_ID> 5
threading_max_workers SUGAR_THREADING_MAX_WORKERS_<CHAIN_ID> 5

In order to write to Sugar contracts, you need to set your wallet private key using env var SUGAR_PK

You can override specific settings in 2 ways:

  • by setting corresponding env var: SUGAR_RPC_URI_10=https://myrpc.com
  • in code:
from sugar.chains import OPChain

async with OPChain(rpc_uri="https://myrpc.com") as chain:
    ...

Contributing to Sugar

Set up and activate python virtual env

python3 -m venv env
source env/bin/activate

Install dependencies

pip install nbdev pre-commit
pip install -e '.[dev]'

Install pre-commit hooks for nbdev prep and cleanup

pre-commit install

Regenerate ABIs if needed

ABIs for contracts are stored inside sugar/abis dir. To regenerate them, use abis.py script (make sure you have ETHERSCAN_API_KEY env var set). We use Optimistic Etherscan.

Useful Links

  • keep an eye on the latest sugar contract deployment for your favorite chain here
  • latest universal router contract (referred to as "swapper" in this sdk) deployment can be found here

Chores and random release related gymnastics

  • getting one file diff for LLM ingestion (skipping notebooks and ABIs): git diff main YOUR_NEW_BRANCH --output=YOUR_NEW_BRANCH.diff ':(exclude)src/*.ipynb' ':(exclude)sugar/_modidx.py' ':(exclude)sugar/abis/*.json'

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

sugar_sdk-0.3.1.tar.gz (54.5 kB view details)

Uploaded Source

Built Distribution

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

sugar_sdk-0.3.1-py3-none-any.whl (57.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: sugar_sdk-0.3.1.tar.gz
  • Upload date:
  • Size: 54.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.12

File hashes

Hashes for sugar_sdk-0.3.1.tar.gz
Algorithm Hash digest
SHA256 7022d7a1d3216102a3fe76594683bc1e27415e137a2842d092e4c394611f6962
MD5 ce7341c102b72c60000556d7567db38b
BLAKE2b-256 efa7fd344d739a311a2fcb5f729d8f5d1eeda7fd3abf9e6781bdb57bdf680076

See more details on using hashes here.

File details

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

File metadata

  • Download URL: sugar_sdk-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 57.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.12

File hashes

Hashes for sugar_sdk-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 39f4ce92b5a32f9da74e6ffb64de22f9f9cfe2cdbd610324e929eeb143217535
MD5 d986cafe21b9654bc9976522acd92a63
BLAKE2b-256 872edd1ef496339709ba8d2b618755bc503dab98605990707f6dbedbf808a9c5

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