Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Transaction Fields

Every transaction submitted to the Bullet exchange is wrapped in an UnsignedTransaction containing three components: the call message, a uniqueness value, and transaction details. This guide covers the uniqueness and details fields.

Uniqueness

The UniquenessData field prevents transaction replay. Bullet supports two modes:

#![allow(unused)]
fn main() {
enum UniquenessData {
    Nonce(u64) = 0,
    Generation(u64) = 1,
}
}

The uniqueness value can be whatever you want — it just needs to be unique per user within a block window (~5-6 seconds). We recommend using microsecond timestamps.

  • No need to track or increment a counter
  • Multiple transactions can be in-flight concurrently

Best practice: use SystemTime::now() in microseconds. Avoid reusing values — if you submit multiple transactions in a tight loop, ensure each is distinct.

Nonce mode

Use Nonce(u64) for strict sequential ordering. The nonce must be exactly current_nonce + 1 for the credential. This mode is simpler but only allows one in-flight transaction at a time.

TxDetails

#![allow(unused)]
fn main() {
struct TxDetails {
    max_priority_fee_bips: u64,
    max_fee: Amount,
    gas_limit: Option<[u64; 2]>,
    chain_id: u64,
}
}

These fields are required in every transaction. We recommend using the values below.

FieldTypeDescription
chain_idu64Chain identifier — fetch from GET /fapi/v1/exchangeInfochainInfo.chainId
max_feeAmount(u128)Maximum fee the sender is willing to pay
gas_limitOption<[u64; 2]>2D gas limit: [compute, storage]. None defaults to block limit
max_priority_fee_bipsu64Priority fee tip in basis points

Gas model

Bullet uses a 2D gas model with separate compute and storage dimensions. The gas_limit field caps how much of each resource a transaction may consume.

Paymaster

Gas fees are covered by a paymaster — users do not pay gas out of pocket. The fields are still required for transaction validity.

FieldRecommended valueNotes
uniquenessGeneration(timestamp_us())Microsecond timestamp
max_priority_fee_bips0
max_fee1 << 48
gas_limitNoneDefaults to block limit. Use [5_000_000, 5_000_000] for order placement or [500_000, 500_000] for simpler ops if you want explicit caps
chain_idfrom exchangeInfoMust match the chain you are submitting to

See the default_tx_details helper for a ready-to-use implementation.