Skip to main content

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.

  • 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
  • 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'

Metadata

Release files for netmind-sugar 0.3.9

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

Source distribution (sdist)

Source distribution for netmind-sugar 0.3.9
File Size Uploaded Provenance
netmind_sugar-0.3.9.tar.gz 55.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for netmind-sugar 0.3.9
File Interpreter ABI Platform
netmind_sugar-0.3.9-py3-none-any.whl Python 3 none any Details

Total release size: 114.4 kB

Release files / netmind_sugar-0.3.9.tar.gz

Download URL netmind_sugar-0.3.9.tar.gz
Size 55.5 kB
Tags Source
SHA-256 checksum
How to use checksums
fe03e43eddb3f05999dacb2a2b3c2d6eb631580443d204172fcbb67353dbaf72
BLAKE2b-256 checksum
How to use checksums
31482d0ab13d20d3cc851c966b0069ac3dccf45c28d29e0f43c60ae8328381af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.16

Release files / netmind_sugar-0.3.9-py3-none-any.whl

Download URL netmind_sugar-0.3.9-py3-none-any.whl
Size 58.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b556141e903d1bf89f11506c254a701575c997947118eb5d8c4e1b8aabd6d36c
BLAKE2b-256 checksum
How to use checksums
2ed2f4cfff6ef42c4ae2247f48597db7ec3049bab49002f67b5f8a77b17658e7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.16

Security for netmind-sugar 0.3.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

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