Skip to main content

Transaction flows

Every state change follows the same pattern: prepare, sign, relay.

  1. Prepare. Your app calls POST …/prepare. It returns { transactions: [ { payload: { xdr } } ] }, an unsigned Stellar transaction.
  2. Sign. The customer signs the authorisation entries with their passkey, on their own device. The private key never leaves it.
  3. Relay. Your app calls POST /api/v2/transactions/relay with { chain, xdr }. The relayer checks that the call is on the allowlist and authorised by the customer's wallet.
  4. Submit. BlockFinaX submits it to Stellar through OpenZeppelin Channels, with a BlockFinaX fee account as fallback, and returns { state, hash } to your app.

Buying protection​

  1. POST /api/v2/quotes returns a ProtectionQuote: economic terms plus an executable payload signed with the pricing key.
  2. POST /api/v2/hedges/prepare with the quote returns the buy_protection transaction.
  3. The client signs and relays it.
  4. On chain, buy_protection:
    1. requires the hedger's authorisation;
    2. rejects if now > deadline, the pool is not accepting, notional < 10, or the tenor is not active;
    3. checks the terms against the pool's structures and limits;
    4. checks the quote is fresh (now − quote_timestamp ≤ 120), its nonce unused, and its ed25519 signature;
    5. computes the reserve and selects backers; rejects if their free money is short;
    6. computes premium and fee; rejects if total > max_cost;
    7. splits the reserve and net premium between backers, records funders, books fees, transfers premium + fee from the hedger;
    8. emits ProtectionPurchased.

Settlement​

  1. After expiry, operators call submit_rate on the oracle with the position id and expiry.
  2. When enough fresh rates agree, the oracle records the consensus.
  3. Anyone calls settle_position(position_id). It reads get_consensus, checks the expiry and band, computes the payout, charges funders, releases reserves, emits PositionSettled.
  4. The hedger calls claim_payout (via POST /api/v2/hedges/:ref/claim/prepare).

Underwriting​

ActionPrepare endpointContract call
DepositPOST /api/v2/pools/:ref/deposits/preparedeposit
PreferencesPOST /api/v2/pools/:ref/preferences/prepareset_lp_preferences
Request withdrawalPOST /api/v2/pools/:ref/withdrawals/preparerequest_withdrawal
Complete withdrawalPOST /api/v2/withdrawals/:chain/:id/execute/prepareexecute_withdrawal

Funding from an EVM network​

Each user has a personal deposit address on each EVM funding network: an EIP-1167 clone of StellarDeposit, created by StellarDepositFactory with CREATE2 and salt keccak256(stellarWallet). The address is known before it exists and is bound to that wallet.

  1. The user (or their exchange) sends USDC to the deposit address.
  2. BlockFinaX reads the canonical USDC balance of every deposit address. It never acts on transfer events, so fake tokens and spoofed logs are ignored.
  3. For a balance at or above the minimum, BlockFinaX calls factory.flush(stellarWallet, maxFee, 1000) from a sponsored platform account. The contract burns exactly its USDC through TokenMessengerV2.depositForBurnWithHook, with Circle's Stellar CctpForwarder as recipient and the user's wallet in the hook. The fee is capped on chain at 0.1%.
  4. BlockFinaX reads Circle's attestation and calls CctpForwarder.mint_and_forward on Stellar. The user is credited only by this mint.

Anyone may call flush; it can only send the address's own USDC to its own wallet.

Withdrawing to an EVM network​

  1. POST /api/v2/routing/execute with kind: "withdraw" returns a USDC approve for Circle's TokenMessengerMinter (marked continues).
  2. After it confirms, POST /api/v2/routing/:id/continue returns deposit_for_burn_with_hook, with Circle's Forwarding Service hook.
  3. Circle attests the burn and submits the mint on the EVM network. BlockFinaX confirms delivery from MessageTransmitterV2.usedNonces.