Skip to main content

PerpClient

Struct PerpClient 

Source
pub struct PerpClient { /* private fields */ }
Expand description

High-level client for the PerpCity protocol.

Combines transport, signing, transaction pipeline, state caching, and contract bindings into one ergonomic API. All write operations go through the TxPipeline for zero-RPC-on-hot-path nonce/gas resolution. Read operations use the StateCache to avoid redundant RPC calls.

Implementations§

Source§

impl PerpClient

Source

pub fn new( transport: HftTransport, signer: PrivateKeySigner, deployments: Deployments, chain_id: u64, ) -> Result<Self>

Create a new PerpClient.

  • transport: Multi-endpoint RPC transport (from crate::TransportConfig)
  • signer: Private key for signing transactions
  • deployments: Contract addresses for this PerpCity instance
  • chain_id: Chain ID (8453 for Base mainnet, 84532 for Base Sepolia)

This does NOT make any network calls. Call Self::refresh_gas and Self::sync_nonce before submitting transactions.

Source

pub fn new_base_mainnet( transport: HftTransport, signer: PrivateKeySigner, deployments: Deployments, ) -> Result<Self>

Create a client pre-configured for Base mainnet.

Source

pub async fn sync_nonce(&self) -> Result<()>

Sync the nonce manager with the on-chain transaction count.

Must be called before the first transaction. After this, the pipeline manages nonces locally (zero RPC per transaction).

Source

pub async fn refresh_gas(&self) -> Result<()>

Refresh the gas cache from the latest block header.

Should be called periodically (every 1-2 seconds on Base L2) or from a newHeads subscription callback.

Source

pub async fn open_taker( &self, perp_id: B256, params: &OpenTakerParams, urgency: Urgency, ) -> Result<U256>

Open a taker (long/short) position.

Returns the minted position NFT token ID on success.

§Errors

Returns PerpCityError::TxReverted if the transaction reverts, or PerpCityError::EventNotFound if the PositionOpened event is missing from the receipt.

Source

pub async fn open_maker( &self, perp_id: B256, params: &OpenMakerParams, urgency: Urgency, ) -> Result<U256>

Open a maker (LP) position within a price range.

Converts price_lower/price_upper to aligned ticks internally. Returns the minted position NFT token ID.

Source

pub async fn close_position( &self, pos_id: U256, params: &CloseParams, urgency: Urgency, ) -> Result<CloseResult>

Close a position (taker or maker).

Returns a CloseResult with the transaction hash and optional remaining position ID (for partial closes).

Source

pub async fn adjust_notional( &self, pos_id: U256, usd_delta: f64, perp_limit: u128, urgency: Urgency, ) -> Result<B256>

Adjust the notional exposure of a taker position.

  • usd_delta > 0: increase notional (add exposure)
  • usd_delta < 0: decrease notional (reduce exposure)
Source

pub async fn adjust_margin( &self, pos_id: U256, margin_delta: f64, urgency: Urgency, ) -> Result<B256>

Add or remove margin from a position.

  • margin_delta > 0: deposit more margin
  • margin_delta < 0: withdraw margin
Source

pub async fn ensure_approval(&self, min_amount: U256) -> Result<Option<B256>>

Ensure USDC is approved for the PerpManager to spend.

Checks current allowance and only sends an approve transaction if the allowance is below min_amount. Approves for U256::MAX (infinite approval) to avoid repeated approve calls.

Source

pub async fn get_perp_config(&self, perp_id: B256) -> Result<PerpData>

Get the full perp configuration, fees, and bounds for a market.

Uses the StateCache for fees and bounds (60s TTL). The perp config itself is always fetched fresh (it’s cheap and rarely changes).

Source

pub async fn get_perp_data(&self, perp_id: B256) -> Result<(Address, i32, f64)>

Get perp data: beacon, tick spacing, and current mark price.

Lighter-weight than Self::get_perp_config — skips fees/bounds lookups.

Source

pub async fn get_position(&self, pos_id: U256) -> Result<Position>

Get an on-chain position by its NFT token ID.

Returns the raw contract position struct. Use crate::math::position functions to compute derived values (entry price, PnL, etc.).

Source

pub async fn get_mark_price(&self, perp_id: B256) -> Result<f64>

Get the current mark price for a perp (TWAP with 1-second lookback).

Uses the fast cache layer (2s TTL).

Source

pub async fn get_live_details(&self, pos_id: U256) -> Result<LiveDetails>

Simulate closing a position to get live PnL, funding, and liquidation status.

This is a read-only call (no transaction sent).

Source

pub async fn get_open_interest(&self, perp_id: B256) -> Result<OpenInterest>

Get taker open interest for a perp market.

Source

pub async fn get_funding_rate(&self, perp_id: B256) -> Result<f64>

Get the funding rate per second for a perp, converted to a daily rate.

Uses the fast cache layer (2s TTL).

Source

pub async fn get_usdc_balance(&self) -> Result<f64>

Get the USDC balance of the signer’s address.

Uses the fast cache layer (2s TTL).

Source

pub fn address(&self) -> Address

The signer’s Ethereum address.

Source

pub fn deployments(&self) -> &Deployments

The deployed contract addresses.

Source

pub fn provider(&self) -> &RootProvider<Ethereum>

The underlying Alloy provider (for advanced queries).

Source

pub fn transport(&self) -> &HftTransport

The underlying HFT transport (for health diagnostics).

Source

pub fn invalidate_fast_cache(&self)

Invalidate the fast cache layer (prices, funding, balance).

Call on new-block events to ensure fresh data.

Source

pub fn invalidate_all_cache(&self)

Invalidate all cached state.

Source

pub fn confirm_tx(&self, tx_hash: &[u8; 32])

Confirm a transaction as mined. Removes from in-flight tracking.

Source

pub fn fail_tx(&self, tx_hash: &[u8; 32])

Mark a transaction as failed. Releases the nonce if possible.

Source

pub fn in_flight_count(&self) -> usize

Number of currently in-flight (unconfirmed) transactions.

Trait Implementations§

Source§

impl Debug for PerpClient

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more