Skip to main content

Python SDK for Renegade darkpool

Project description

Renegade Python SDK

The Renegade Python SDK is a client library for interacting with the Renegade darkpool.

Installation

uv add renegade-sdk

or

pip install renegade-sdk

Usage

See examples/ for usage examples.

Basic Use

Todo...

External Matches

In addition to the standard darkpool flow -- deposit, place order, receive a match, then withdraw -- Renegade also supports external matches. An external match is a match between an internal party -- with state committed into the darkpool -- and an external party, with no state in the darkpool. Importantly, external matches are settled atomically; that is, the deposit, place order, match, withdraw flow is emulated in a single transaction for the external party.

An external match is generated and submitted on-chain by a client (see ExternalMatchClient). The client submits an ExternalOrder to the relayer to fetch a quote, and the relayer will attempt to match it against all consenting internal orders. If a match is found, the relayer will respond to the client with a quote containing:

  • The match itself, specifying the amount and mint (ERC20 address) of the tokens bought and sold, fees, etc.
  • A signature of the quote; which allows the client to authoritatively assemble the quote into a match bundle

If the client is satisfied with the quote, it can assemble the quote into a match bundle, which contains:

  • The match itself, specifying the amount and mint (ERC20 address) of the tokens bought and sold
  • An EVM transaction that the external party may submit in order to settle the match with the darkpool

The client should then submit this match to the darkpool.

Upon receiving an external match, the darkpool contract will update the encrypted state of the internal party, and fulfill obligations to the external party directly through ERC20 transfers. As such, the external party must approve the token they sell before the external match can be settled.

Example

The following snippet demonstrates how to request an external match, assemble the quote into a match bundle, and submit the bundle to the darkpool. See examples/external_match.py for a complete example.

from renegade import ExternalMatchClient
from renegade.types import AtomicMatchApiBundle, OrderSide, ExternalOrder

# Constants
BASE_MINT = "0xc3414a7ef14aaaa9c4522dfc00a4e66e74e9c25a"  # Testnet wETH
QUOTE_MINT = "0xdf8d259c04020562717557f2b5a3cf28e92707d1"  # Testnet USDC

# Create the client
api_key = os.getenv("EXTERNAL_MATCH_KEY")
api_secret = os.getenv("EXTERNAL_MATCH_SECRET")
client = ExternalMatchClient.new_sepolia_client(api_key, api_secret)

# Create the order
order = ExternalOrder(
    base_mint=BASE_MINT,
    quote_mint=QUOTE_MINT,
    side=OrderSide.SELL,
    quote_amount=30_000_000,  # $30 USDC
    min_fill_size=3_000_000,  # $3 USDC minimum
)

# Fetch a quote from the relayer
print("Fetching quote...")
quote = await client.request_quote(order)
if not quote:
    raise ValueError("No quote found")

# Assemble the quote into a bundle
print("Assembling quote...")
bundle = await client.assemble_quote(quote)
if not bundle:
    raise ValueError("No bundle found")

print(f"Received bundle: {bundle}")

Gas Sponsorship

The Renegade relayer will cover the gas cost of external match transactions, up to a daily limit. When requested, the relayer will re-route the settlement transaction through a gas rebate contract. This contract refunds the cost of the transaction, either in native Ether, or in terms of the buy-side token in the external match. The rebate can optionally be sent to a configured address.

For in-kind sponsorship, if no refund address is given, the rebate is sent to the receiver of the match. This is equivalent to the receiver getting a better price in the match, and as such the quoted price returned by the SDK is updated to reflect that.

In-kind gas sponsorship is enabled by default!

If, however, you would like to disable gas sponsorship, simply add with_gas_sponsorship_disabled to the RequestQuoteOptions type:

# Refund address defaults to tx.origin
options = RequestQuoteOptions.new().with_gas_sponsorship_disabled(True)
quote = client.request_quote_with_options(quote, options)
# ... Assemble + submit bundle ... #

For examples on how to configure gas sponsorship, see examples/native_eth_gas_sponsorship.rs, and examples/in_kind_gas_sponsorship.py

Gas Sponsorship Notes

  • The refund amount may not exactly equal the gas costs, as this must be estimated before constructing the transaction so it can be returned in the quote.
  • The gas estimate returned by eth_estimateGas will not reflect the rebate, as the rebate does not reduce the gas used; it merely refunds the ether paid for the gas. If you wish to understand the true gas cost ahead of time, the transaction can be simulated (e.g. with alchemy_simulateExecution or similar).
  • The rate limits currently sponsor up to ~500 matches/day ($100 in gas).

Bundle Details

The quote returned by the relayer for an external match has the following structure:

  • order: The original external order
  • match_result: The result of the match, including:
  • fees: The fees for the match
    • relayer_fee: The fee paid to the relayer
    • protocol_fee: The fee paid to the protocol
  • receive: The asset transfer the external party will receive, after fees are deducted.
    • mint: The token address
    • amount: The amount to receive
  • send: The asset transfer the external party needs to send. No fees are charged on the send transfer. (same fields as receive)
  • price: The price used for the match. If in-kind sponsorship was enabled, and directed to the receiver of the match, this price accounts for the additional tokens received.
  • timestamp: The timestamp of the quote

When assembled into a bundle (returned from assemble_quote or request_external_match), the structure is as follows:

  • match_result: The final match result
  • fees: The fees to be paid
  • receive: The asset transfer the external party will receive
  • send: The asset transfer the external party needs to send
  • settlement_tx: The transaction to submit on-chain
    • tx_type: The transaction type
    • to: The contract address
    • data: The calldata
    • value: The ETH value to send

See example examples/quote_validation.py for an example of using these fields to validate a quote before submitting it.

This can be run with

uv run examples/quote_validation.py

Rate Limits

The rate limits for external match endpoints are as follows:

  • Quote: 100 requests per minute
  • Assemble (Exclusive Bundle): 5 unsettled bundles per minute. That is, if an assembled bundle is submitted on-chain, the rate limiter will reset.
  • Assemble (Shared Bundle): 50 unsettled shared bundles per minute. A shared bundle is an assembled bundle that the relayer may send to multiple external parties, rather than enforcing that only one external party can settle the bundle. See examples/shared_bundle.py for an example of how to assemble a shared bundle. If an assembled match is not settled on-chain, the rate limiter will remove one token from the per-minute allowance.

Supported Tokens

The tokens supported by the darkpool can be found at the following links:

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

renegade_sdk-0.1.9.tar.gz (18.1 kB view details)

Uploaded Source

Built Distribution

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

renegade_sdk-0.1.9-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

Details for the file renegade_sdk-0.1.9.tar.gz.

File metadata

  • Download URL: renegade_sdk-0.1.9.tar.gz
  • Upload date:
  • Size: 18.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.7

File hashes

Hashes for renegade_sdk-0.1.9.tar.gz
Algorithm Hash digest
SHA256 0f9ea14b4096017bebdb6660f51bd7f9cee76120983f640e493cb0bbc6c6a81d
MD5 0e544120ee84fef43c856f6acf3818d8
BLAKE2b-256 1e81e8c03e54ecc87b1acf6ae44d65599019f5b30c113a43e9607fda245977d9

See more details on using hashes here.

File details

Details for the file renegade_sdk-0.1.9-py3-none-any.whl.

File metadata

File hashes

Hashes for renegade_sdk-0.1.9-py3-none-any.whl
Algorithm Hash digest
SHA256 fa4fb38948f197bf57f25a910f49946bcf6ed759f36915f89e194e6b18c69798
MD5 fc0033ccdcd9fcae153a8011a4d428a6
BLAKE2b-256 160c04be4fb6bd1db221801841697be3347e7adf4e74f216ca3abe82ddf07761

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