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!
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.
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
)
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.
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!
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!
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.)