Python SDK for Rubicon

Today we are releasing a Python SDK for Rubicon! With rubi-py, developers can interact with and trade on the Rubicon protocol using a simple Pythonic interface, abstracting away many of the complexities of trading on-chain.

In this post, we’ll show you how to get started with the SDK, and walk through an example of placing a Limit Order on WETH/USDC while logging relevant data!

Overview

Most DeFi SDKs and tooling are built in JavaScript/TypeScript and aimed at a crypto-native user base. We talked to lots of user groups and recognized the need for a different form of programmatic interface that would allow developers of all levels to get started using the Rubicon protocol. It quickly became clear that Python is widely used in the world of crypto trading for everything from trading systems to data analysis, but is not well supported throughout DeFi.

The result is rubi-py: an SDK that offers developers a wide range of functionality for interacting with the Rubicon smart contracts within their Python applications. With a focus on efficiency and reliability, rubi-py offers seamless integration with the protocol without needing to learn a new language or navigate complex tooling.

Getting Started

To get started, install the rubi package using pip or poetry. We recommend using poetry, as it handles the virtual environment and dependencies while offering easy testing commands.

The main entry point is the client class. It provides a simple and understandable interface for interacting with the Rubicon protocol.

To instantiate a read-write client, create a .env file with the following format:

HTTP_NODE_URL = <an optimism mainnet node url>
WALLET = <wallet address that will sign transactions and pay gas>
KEY = <private key of the signing address>

Optimism provides a public endpoint with rate limits, and you can also get a node URL from a provider like Alchemy or Infura.

To read the environment variables, you can use the python-dotenv package as follows:

import os
from dotenv import load_dotenv

# load from env file
load_dotenv(".env")

# set the env variables
http_node_url = os.getenv("HTTP_NODE_URL")
wallet = os.getenv("WALLET")
key = os.getenv("KEY")

Finally, we instantiate a client to start interacting with Rubicon:

import os
from dotenv import load_dotenv
from rubi import Client

# load from env file
load_dotenv(".env")

# set the env variables
http_node_url = os.getenv("HTTP_NODE_URL")
wallet = os.getenv("WALLET")
key = os.getenv("KEY")

# create a read-write client
client = Client.from_http_node_url(
    http_node_url=http_node_url,
    wallet=wallet,
    key=key
)

Example: Placing a Limit Order

Here’s a full example that instantiates a client, places a new LimitOrder on the WETH/USDC pair on the Rubicon order book contract, and logs the market activity of the pair:

import logging as log
import os
from _decimal import Decimal
from multiprocessing import Queue

from dotenv import load_dotenv

from rubi import Client
from rubi import EmitOfferEvent, Transaction, NewLimitOrder, OrderSide

# load from env file
load_dotenv(".env")

# set logging to get events emitted by the contract
log.basicConfig(level=log.INFO)

# set the env variables
http_node_url = os.getenv("HTTP_NODE_URL")
wallet = os.getenv("DEV_WALLET")
key = os.getenv("DEV_KEY")

# create a queue to receive messages
queue = Queue()

# create client
client = Client.from_http_node_url(
    http_node_url=http_node_url,
    wallet=wallet,
    key=key,
    message_queue=queue
)

# add the WETH/USDC pair to the client and set token allowances (optional)
client.add_pair(pair_name="WETH/USDC", base_asset_allowance=Decimal("1"), quote_asset_allowance=Decimal("2000"))

# start listening to offer events created by your wallet on the WETH/USDC market 
# and the WETH/USDC order book
client.start_event_poller("WETH/USDC", event_type=EmitOfferEvent)
client.start_orderbook_poller("WETH/USDC")

# create a new limit order
limit_order = NewLimitOrder(
    pair_name="WETH/USDC",
    order_side=OrderSide.BUY,
    size=Decimal("1"),
    price=Decimal("1914.13")
)

# place the limit order transaction
transaction_result = client.place_limit_order(
    transaction=Transaction(
        orders=[limit_order]
    )
)
log.info(transaction_result)

# print events and order books
while True:
    message = queue.get()
    log.info(message)

To understand more about event polling and the queue, visit the SDK docs.

Diving Deeper: Batch Order Functions

We hope this intro to rubi-py helps you get started interacting with the Rubicon protocol using Python!

For traders who want to use the SDK in production systems and reduce their gas costs, we recommend checking out the batch order functions that enable you to place, cancel, or update multiple orders in a single transaction, limited only by the networks gas limit!

Contributing

This SDK is open-source under the Apache 2.0 license, and all contributions and feedback are welcome! You can open an issue or request a new feature on Github. We are excited to continue improving rubi-py, and feature requests with widespread community support will be prioritized!

Lastly, many thanks to the core contributors Adam, Denver, and Ishan for their work building and maintaining this SDK!

Resources

Alea iacta est.

(This post is for educational purposes only. Nothing in it should be construed as financial advice. Do your own research before making investments.)

Subscribe to Rubicon
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.