Raxol.Payments.Actions.Payments.ExecuteRelayTransfer (Raxol Payments v0.2.0)

Copy Markdown View Source

Agent Action that initiates a Tron cross-chain transfer through the Relay rail.

Relay is deposit-address based: this Action quotes the transfer (which returns a Riddler-managed deposit address), authorizes the spend through SpendGate, and initiates execution. It does not broadcast the on-chain deposit itself -- the wallet that holds the source funds sends them to the returned deposit_address; poll the result with Raxol.Payments.Actions.Payments.PollRelayStatus.

Tron has no stealth settlement. A stealth or shielded request to a Tron destination fails closed with {:error, :stealth_unsupported_on_chain} and must be re-requested with public settlement, rather than silently downgrading the privacy preference to public.

Funding the deposit

Three paths, picked from the quote and context:

  • Gasless (A) -- when the quote returns a gasless typed-data block, the wallet signs it and the signature rides on execute so the solver pulls. No broadcast. Delivered Riddler-side (axol-io/Riddler#120, PR #160) behind RELAY_GASLESS_PULL_ENABLED; Permit2 only (ERC-3009 deferred, Riddler#159).
  • Broadcast (B) -- when a :broadcaster is in context, it sends the on-chain token transfer to the deposit address. The default route while Riddler's /relay/* surface stays production-gated.
  • External (C) -- otherwise the deposit address is returned for an outside wallet to fund.

Context keys

  • :relay_config -- %{base_url:, auth_token:} for Relay.Client.
  • :wallet -- defaults from_address; signs the gasless authorization (A).
  • :broadcaster -- a Raxol.Payments.Relay.Broadcaster module (B).
  • :policy, :ledger, :agent_id, :on_confirm -- see SpendGate.
  • :checkpoint -- optional {module, handle} Raxol.Payments.Checkpoint store for idempotent recovery (nil disables it).
  • :idempotency_key -- optional explicit key; derived from the payment when absent.

Idempotent recovery

The transfer_id is minted client-side, so a naive re-run after a crash would mint a fresh one, re-quote, and re-sign or re-broadcast -- a double-spend. With a :checkpoint store the transfer is checkpointed before the funding step; a re-run of the same logical payment resumes the recorded transfer (returning it to poll) instead of starting a new one. The reused transfer_id also lets an idempotent broadcaster dedupe a retried deposit. Without a store the path is unchanged.

Summary

Functions

Validate input, run the action, validate output.

Generate an LLM tool definition for this action.

Functions

call(params, context \\ %{})

Validate input, run the action, validate output.

Returns {:ok, result}, {:ok, result, commands}, or {:error, reason}.

to_tool_definition()

Generate an LLM tool definition for this action.