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
get_quote/2-- POST /api/intent/quoteexecute/2-- POST /api/intent/executeget_status/2-- GET /api/intent/:id/statusget_history/2-- GET /api/intent/history?wallet=claim/2-- POST /api/stealth/claim
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 presentsX-Xochi-Delegationper call. Best fit for an agent acting for a Member. WiresRaxol.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 sendsX-PAYMENT. WiresRaxol.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
Functions
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" => ...}}.
@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.
@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 intent history for a wallet.
@spec get_quote(config(), Raxol.Payments.Xochi.Schemas.QuoteRequest.t()) :: {:ok, Raxol.Payments.Xochi.Schemas.QuoteResponse.t()} | error()
Request an intent quote.
@spec get_status(config(), String.t()) :: {:ok, Raxol.Payments.Xochi.Schemas.IntentStatus.t()} | error()
Get intent status by ID.