Raxol.Payments.Xochi.Client (Raxol Payments v0.2.0)

Copy Markdown View Source

Client for the Xochi private execution protocol.

Talks to the Xochi worker's /api/intent/* endpoints. The worker is the sole agent surface: it applies trust-tier fees and attestations, is the x402 boundary, and calls the Riddler solver internally. Do not target riddler.axol.io/xochi/* directly -- that bypasses Xochi's fee/tier logic and returns the raw solver quote (a thinner shape, no can_solve/xochi_fee).

Endpoints

Pinned contract: xochi/docs/contracts/xochi-intent-api.md. It covers quote, execute, and status; the history and stealth claim paths live in the worker's OpenAPI spec.

Authentication

An autonomous agent cannot mint a passkey-issued Member JWT the way a browser can, so the client supports the worker's three auth modes via :auth:

  • {:mandate, agent_wallet} -- a Member signs an EIP-712 delegation envelope once; the agent presents X-Xochi-Delegation per call. Best fit for an agent acting for a Member. Wires Raxol.Payments.Req.Mandate, which looks up the soonest-expiring active mandate for the wallet. Pass plugin overrides with {:mandate, agent_wallet, opts}.
  • {:x402, wallet: MyWallet} -- Guest mode. The agent signs an EIP-3009 USDC micropayment per call and sends X-PAYMENT. Wires Raxol.Payments.Req.AutoPay (restricted to :x402), which regenerates the payment from each 402 challenge.
  • {:member, jwt} -- only if a passkey-issued JWT is provisioned out of band.

Configuration

# Mandate (recommended for agents)
config = %{base_url: "https://api.xochi.fi", auth: {:mandate, "0xAgent..."}}

# Guest / x402
config = %{base_url: "https://api.xochi.fi", auth: {:x402, wallet: MyWallet}}

# Member JWT (legacy `:auth_token` is equivalent to `{:member, token}`)
config = %{base_url: "https://api.xochi.fi", auth_token: "bearer-token"}

{:ok, quote} = Xochi.Client.get_quote(config, %QuoteRequest{...})

Summary

Functions

Submit a gasless stealth settlement claim.

Execute a quoted intent with a signed payload.

Request a deposit-route quote for a non-EVM (Tron) origin.

Get intent history for a wallet.

Request an intent quote.

Get intent status by ID.

Types

auth()

@type auth() ::
  {:member, String.t()}
  | {:mandate, String.t()}
  | {:mandate, String.t(), keyword()}
  | {:x402, keyword()}
  | :none

config()

@type config() :: %{
  :base_url => String.t(),
  optional(:auth) => auth(),
  optional(:auth_token) => String.t(),
  optional(:req_options) => keyword()
}

error()

@type error() :: {:error, {:http, integer(), term()}} | {:error, term()}

Functions

claim(config, params)

@spec claim(config(), map()) :: {:ok, map()} | error()

Submit a gasless stealth settlement claim.

Posts the signed claim to the worker's single stealth claim endpoint (POST /api/stealth/claim), which sponsors it via Pimlico/ERC-4337 and proxies to the Riddler solver. The agent derives stealth keys from an ERC-5564 announcement and signs the claim message before calling this.

Required params (snake_case, per the pinned contract): :stealth_address, :recipient, :ephemeral_pub_key, :signature. Optional: :view_tag. Returns {:ok, %{"tx_hash" => ..., "status" => ...}}.

execute(config, request)

@spec execute(config(), Raxol.Payments.Xochi.Schemas.ExecuteRequest.t()) ::
  {:ok, Raxol.Payments.Xochi.Schemas.ExecuteResponse.t()} | error()

Execute a quoted intent with a signed payload.

get_deposit_route_quote(config, request)

@spec get_deposit_route_quote(
  config(),
  Raxol.Payments.Xochi.Schemas.DepositRouteRequest.t()
) ::
  {:ok, Raxol.Payments.Xochi.Schemas.QuoteResponse.t()} | error()

Request a deposit-route quote for a non-EVM (Tron) origin.

Same /api/intent/quote endpoint as get_quote/2, but the request allows a base58 origin and the response carries a deposit_address + deposit_attestation (verify it before sending funds) instead of EIP-712 typed data to sign.

get_history(config, wallet, opts \\ [])

@spec get_history(config(), String.t(), keyword()) :: {:ok, [map()]} | error()

Get intent history for a wallet.

get_quote(config, request)

@spec get_quote(config(), Raxol.Payments.Xochi.Schemas.QuoteRequest.t()) ::
  {:ok, Raxol.Payments.Xochi.Schemas.QuoteResponse.t()} | error()

Request an intent quote.

get_status(config, intent_id)

@spec get_status(config(), String.t()) ::
  {:ok, Raxol.Payments.Xochi.Schemas.IntentStatus.t()} | error()

Get intent status by ID.