Exact-amount top-two routing for six pilots; caller signs; AssetFare never signs or submits
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Read the Ed25519-signed release manifest and safety-bundle binding before preparing an action. Example: call this once to verify the current release and contract pins; it never creates state, signs, or submits.
This tool takes no arguments.
Read the Ed25519-signed release manifest and safety-bundle binding before preparing an action. Example: call this once to verify the current release and contract pins; it never creates state, signs, or submits.
No arguments.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {},
"additionalProperties": false
}Read all 100 technically available routes, live provider readiness, route-specific guidance, direct_route_summary, and continuation_v3 contracts before quoting. Forty-four routes are price-recommended only at or above their published threshold; 56 have no current price recommendation. Example: call once before requesting an exact route quote. Confirm every fresh quote. Economic guidance is advisory and never adds an execution gate. continuation_v3 separately binds execution selection, wallets, bounds, and mode. Read-only; creates no wallet login, session, or action.
No arguments.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {},
"additionalProperties": false
}Return one deeply verified first unsigned bundle and caller-wallet handoff. Example: pass caller_approved=true, a one_shot approval_v3, and the quote-bound verification_context; multi-step routes reject one_shot. Economic guidance is advisory and adds no request field. Context is validated before the upstream request and never forwarded. AssetFare never signs or submits.
| Argument | Type | Description |
|---|---|---|
| wallets* | object | Map each chain needed by this route to the caller's public wallet address. Include public addresses only; never private keys or seed phrases. |
| to_chain* | string | Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations. |
| to_token* | string | Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities. |
| amount_usd* | number | Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount. |
| from_chain* | string | Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain. |
Get one fresh AssetFare quote with amount-specific economic_guidance, direct_route_summary, continuation_v3, and unsigned_prepare_requirements. Example: quote Solana USDC to Base USDC. price_recommended_for_amount is advisory; compare alternatives when price matters, but no economic acknowledgement field is required. The quote remains an unranked_candidate until separate explicit approval selects one mode. The adapter validates hashes, path, bounds, and TTL and never creates approval, prepares, signs, or submits.
| Argument | Type | Description |
|---|---|---|
| to_chain* | string | Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations. |
| to_token* | string | Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities. |
| amount_usd* | number | Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount. |
| from_chain* | string | Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain. |
Reuse the chosen exact request-time quote while valid; after expiry refresh only that candidate at the same amount and never reselect. Example: pass candidate_id and the selection receipt hash. An AssetFare result requires a caller-local proof check and fresh wallet simulation before verified_for_signing; remote verification is not signing authority. An external result is only its provider handoff and has no AssetFare transaction-verification claim. Never prepares, signs, submits, or grants transaction authority.
| Argument | Type | Description |
|---|---|---|
| profile | string | Time policy: fast (30s), balanced (60s default), or explicit economy (60s). Every recommendation profile has an absolute 60-second ceiling. |
| to_chain* | string | Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations. |
| to_token* | string | Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities. |
| amount_usd* | number | Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount. |
| from_chain |
Quote the recent top two plus the best AssetFare graph at the exact amount; return up to two all-in choices labeled assetfare_verified_unsigned or external_provider_handoff. AssetFare cost, ETA and rank are always present; a recent winning range needs two supporting higher buckets and disappears on conflict. Example: compare Solana USDC to Base USDC at USD 347.25 with balanced (60s). Fast is 30s; balanced and explicit economy are 60s. The 60-second ceiling is absolute for recommendations; slower routes are reference-only. Never approves, prepares, signs, or submits.
| Argument | Type | Description |
|---|---|---|
| profile | string | Time policy: fast (30s), balanced (60s default), or explicit economy (60s). Every recommendation profile has an absolute 60-second ceiling. |
| to_chain* | string | Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations. |
| to_token* | string | Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities. |
| amount_usd* | number | Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount. |
Create one receipt-driven workflow. Example: pass caller_approved=true, a session approval_v3, its idempotency_key, a caller-local session token, and the quote-bound verification_context. Economic guidance is advisory and adds no request field. The adapter validates approval and context before the upstream request. Every returned action is deeply verified and receives a caller-wallet handoff. AssetFare never signs or submits.
| Argument | Type | Description |
|---|---|---|
| wallets* | object | Map each chain needed by this route to the caller's public wallet address. Include public addresses only; never private keys or seed phrases. |
| to_chain* | string | Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations. |
| to_token* | string | Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities. |
| amount_usd* | number | Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount. |
| from_chain* | string | Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain. |
Read an existing v2 workflow without advancing it. Example: pass session_id, session_token, and the original verification_context after restart. The adapter deeply verifies any current_action and emits a self-verifying wallet handoff, or fails closed. Read-only; never signs or submits.
| Argument | Type | Description |
|---|---|---|
| session_id* | string | V2 workflow session UUID returned by assetfare_v2_session_create. Use only with assetfare_v2_session_* tools; do not pass a legacy session ID. |
| session_token* | string | Sensitive caller-generated v2 session capability: at least 32 CSPRNG bytes encoded as 43-128 URL-safe base64 characters. Generate it locally; never log it or substitute a private key or legacy access token. |
| verification_context* | object | Strict caller-held context copied from the selected quote and approval. It contains public intent/wallet data only, never the raw session token or a private key, and is required whenever a remote MCP session call can return current_action. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"session_token",
"session_id",
"verification_context"
],
"properties": {
"session_id": {
"type": "string",
"format": "uuid",
"description": "V2 workflow session UUID returned by assetfare_v2_session_create. Use only with assetfare_v2_session_* tools; do not pass a legacy session ID."
},
"session_token": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43,128}$",
"description": "Sensitive caller-generated v2 session capability: at least 32 CSPRNG bytes encoded as 43-128 URL-safe base64 characters. Generate it locally; never log it or substitute a private key or legacy access token."
},
"verification_context": {
"type": "object",
"required": [
"version",
"intent",
"wallets",
"event_signer_public",
"approval_v3",
"direct_route_summary",
"verification_context_sha256"
],
"properties": {
"intent": {
"type": "object",
"required": [
"from_chain",
"from_token",
"to_chain",
"to_token",
"amount_usd"
],
"properties": {
"to_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood"
],
"type": "string",
"description": "Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations."
},
"to_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities."
},
"amount_usd": {
"type": "number",
"minimum": 1,
"description": "Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount."
},
"from_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
],
"type": "string",
"description": "Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain."
},
"from_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities."
}
},
"additionalProperties": false
},
"version": {
"type": "string",
"const": "assetfare-session-verification-context-v1"
},
"wallets": {
"type": "object",
"description": "Map each chain needed by this route to the caller's public wallet address. Include public addresses only; never private keys or seed phrases.",
"propertyNames": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
]
},
"additionalProperties": {
"type": "string",
"description": "Caller-owned public wallet address: 0x plus 40 hex characters for EVM, 0x plus 64 hex characters for Aptos, or 32-44 base58 characters for Solana. Never provide secret key material."
}
},
"approval_v3": {
"type": "object",
"required": [
"version",
"quote_id",
"quote_fingerprint",
"selection_status",
"selected_mode",
"maximum_input_base",
"minimum_output_base",
"direct_route_summary_sha256",
"idempotency_key"
],
"properties": {
"version": {
"type": "string",
"const": "assetfare-quote-bound-approval-v3"
},
"quote_id": {
"type": "string",
"format": "uuid"
},
"selected_mode": {
"type": "string",
"const": "session"
},
"idempotency_key": {
"type": "string",
"pattern": "^[A-Za-z0-9._:-]{8,128}$"
},
"selection_status": {
"type": "string",
"const": "selected"
},
"quote_fingerprint": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"maximum_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"minimum_output_base": {
"$ref": "#/properties/verification_context/properties/approval_v3/properties/maximum_input_base"
},
"direct_route_summary_sha256": {
"$ref": "#/properties/verification_context/properties/approval_v3/properties/quote_fingerprint"
}
},
"additionalProperties": false
},
"event_signer_public": {
"anyOf": [
{
"$ref": "#/properties/verification_context/properties/wallets/additionalProperties",
"description": "Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key."
},
{
"type": "null"
}
],
"description": "Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key."
},
"direct_route_summary": {
"type": "object",
"required": [
"version",
"route",
"from",
"to",
"classification",
"mode",
"route_aggregator_used",
"external_intent_protocol_used",
"provider_internal_dex_aggregation_possible",
"assetfare_fee_bps",
"fee_collection_step_index",
"server_signing",
"server_submission",
"step_count",
"steps"
],
"properties": {
"to": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG"
],
"type": "string"
},
"from": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG",
"polygon:USDC",
"optimism:USDC",
"ethereum:USDC",
"hyperevm:USDC",
"xlayer:USDC",
"sei:USDC",
"sonic:USDC",
"monad:USDC",
"avalanche:USDC",
"cronos:USDC",
"injective:USDC",
"linea:USDC",
"aptos:USDC",
"unichain:USDC",
"ink:USDC"
],
"type": "string"
},
"mode": {
"enum": [
"aptos_move_cctp_direct",
"cctp_direct_composition",
"optimism_source_cctp",
"polygon_source_cctp",
"robinhood_across_ingress_composition",
"robinhood_paxos_egress_composition",
"robinhood_paxos_ingress_composition",
"same_chain_direct",
"same_chain_direct_composition"
],
"type": "string"
},
"route": {
"enum": [
"solana:SOL->solana:USDC",
"solana:SOL->solana:USDG",
"solana:SOL->base:ETH",
"solana:SOL->base:USDC",
"solana:SOL->arbitrum:ETH",
"solana:SOL->arbitrum:USDC",
"solana:SOL->robinhood:ETH",
"solana:SOL->robinhood:USDG",
"solana:USDC->solana:SOL",
"solana:USDC->solana:USDG",
"solana:USDC->base:ETH",
"solana:USDC->base:USDC",
"solana:USDC->arbitrum:ETH",
"solana:USDC->arbitrum:USDC",
"solana:USDC->robinhood:ETH",
"solana:USDC->robinhood:USDG",
"solana:USDG->solana:SOL",
"solana:USDG->solana:USDC",
"solana:USDG->base:ETH",
"solana:USDG->base:USDC",
"solana:USDG->arbitrum:ETH",
"solana:USDG->arbitrum:USDC",
"solana:USDG->robinhood:ETH",
"solana:USDG->robinhood:USDG",
"base:ETH->solana:SOL",
"base:ETH->solana:USDC",
"base:ETH->solana:USDG",
"base:ETH->base:USDC",
"base:ETH->arbitrum:ETH",
"base:ETH->arbitrum:USDC",
"base:ETH->robinhood:ETH",
"base:ETH->robinhood:USDG",
"base:USDC->solana:SOL",
"base:USDC->solana:USDC",
"base:USDC->solana:USDG",
"base:USDC->base:ETH",
"base:USDC->arbitrum:ETH",
"base:USDC->arbitrum:USDC",
"base:USDC->robinhood:ETH",
"base:USDC->robinhood:USDG",
"arbitrum:ETH->solana:SOL",
"arbitrum:ETH->solana:USDC",
"arbitrum:ETH->solana:USDG",
"arbitrum:ETH->base:ETH",
"arbitrum:ETH->base:USDC",
"arbitrum:ETH->arbitrum:USDC",
"arbitrum:ETH->robinhood:ETH",
"arbitrum:ETH->robinhood:USDG",
"arbitrum:USDC->solana:SOL",
"arbitrum:USDC->solana:USDC",
"arbitrum:USDC->solana:USDG",
"arbitrum:USDC->base:ETH",
"arbitrum:USDC->base:USDC",
"arbitrum:USDC->arbitrum:ETH",
"arbitrum:USDC->robinhood:ETH",
"arbitrum:USDC->robinhood:USDG",
"robinhood:ETH->solana:SOL",
"robinhood:ETH->solana:USDC",
"robinhood:ETH->solana:USDG",
"robinhood:ETH->base:ETH",
"robinhood:ETH->base:USDC",
"robinhood:ETH->arbitrum:ETH",
"robinhood:ETH->arbitrum:USDC",
"robinhood:ETH->robinhood:USDG",
"robinhood:USDG->solana:SOL",
"robinhood:USDG->solana:USDC",
"robinhood:USDG->solana:USDG",
"robinhood:USDG->base:ETH",
"robinhood:USDG->base:USDC",
"robinhood:USDG->arbitrum:ETH",
"robinhood:USDG->arbitrum:USDC",
"robinhood:USDG->robinhood:ETH",
"polygon:USDC->base:USDC",
"polygon:USDC->arbitrum:USDC",
"optimism:USDC->base:USDC",
"optimism:USDC->arbitrum:USDC",
"ethereum:USDC->solana:USDC",
"ethereum:USDC->base:USDC",
"hyperevm:USDC->solana:USDC",
"hyperevm:USDC->base:USDC",
"xlayer:USDC->solana:USDC",
"xlayer:USDC->base:USDC",
"sei:USDC->solana:USDC",
"sei:USDC->base:USDC",
"sonic:USDC->solana:USDC",
"sonic:USDC->base:USDC",
"monad:USDC->solana:USDC",
"monad:USDC->base:USDC",
"avalanche:USDC->solana:USDC",
"avalanche:USDC->base:USDC",
"cronos:USDC->solana:USDC",
"cronos:USDC->base:USDC",
"injective:USDC->solana:USDC",
"injective:USDC->base:USDC",
"linea:USDC->solana:USDC",
"linea:USDC->base:USDC",
"aptos:USDC->solana:USDC",
"aptos:USDC->base:USDC",
"unichain:USDC->solana:USDC",
"ink:USDC->solana:USDC"
],
"type": "string"
},
"steps": {
"type": "array",
"items": {
"type": "object",
"required": [
"index",
"action",
"provider",
"from",
"to",
"expected_input_base",
"minimum_input_base",
"expected_output_base",
"minimum_output_base",
"assetfare_fee_bps",
"direct_protocol",
"external_intent_protocol",
"aggregator_api_used"
],
"properties": {
"to": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG"
],
"type": "string"
},
"from": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG",
"polygon:USDC",
"optimism:USDC",
"ethereum:USDC",
"hyperevm:USDC",
"xlayer:USDC",
"sei:USDC",
"sonic:USDC",
"monad:USDC",
"avalanche:USDC",
"cronos:USDC",
"injective:USDC",
"linea:USDC",
"aptos:USDC",
"unichain:USDC",
"ink:USDC"
],
"type": "string"
},
"index": {
"type": "integer",
"maximum": 7,
"minimum": 0
},
"action": {
"enum": [
"swap",
"bridge",
"receive"
],
"type": "string"
},
"provider": {
"enum": [
"raydium_clmm",
"orca_whirlpool",
"uniswap_v3",
"circle_cctp",
"circle_cctp_receive",
"paxos_usdg_layerzero_oft",
"across_intent_bridge"
],
"type": "string"
},
"direct_protocol": {
"type": "boolean"
},
"assetfare_fee_bps": {
"enum": [
0,
1
],
"type": "number"
},
"minimum_guard_bps": {
"type": "integer",
"maximum": 500,
"minimum": 1
},
"minimum_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"aggregator_api_used": {
"type": "boolean",
"const": false
},
"expected_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"minimum_output_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"expected_output_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"external_intent_protocol": {
"type": "boolean"
}
},
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1
},
"version": {
"type": "string",
"const": "assetfare-direct-route-summary-v1"
},
"step_count": {
"type": "integer",
"maximum": 8,
"minimum": 1
},
"classification": {
"enum": [
"direct_protocol_only",
"external_intent"
],
"type": "string"
},
"server_signing": {
"type": "boolean",
"const": false
},
"assetfare_fee_bps": {
"type": "number",
"const": 1
},
"server_submission": {
"type": "boolean",
"const": false
},
"economic_eligibility": {
"enum": [
"not_asserted_by_capability",
"coverage_only_not_primary"
],
"type": "string"
},
"route_aggregator_used": {
"type": "boolean",
"const": false
},
"product_classification": {
"enum": [
"primary_direct",
"external_coverage_only"
],
"type": "string"
},
"route_minimum_guard_bps": {
"anyOf": [
{
"type": "integer",
"maximum": 500,
"minimum": 1
},
{
"type": "null"
}
]
},
"fee_collection_step_index": {
"type": "integer",
"maximum": 7,
"minimum": 0
},
"public_execution_eligible": {
"type": "boolean"
},
"primary_selection_eligible": {
"type": "boolean"
},
"external_intent_protocol_used": {
"type": "boolean"
},
"provider_internal_dex_aggregation_possible": {
"type": "boolean"
}
},
"additionalProperties": false
},
"verification_context_sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
},
"description": "Strict caller-held context copied from the selected quote and approval. It contains public intent/wallet data only, never the raw session token or a private key, and is required whenever a remote MCP session call can return current_action.",
"additionalProperties": false
}
},
"additionalProperties": false
}Record an already-produced bridge or destination output, then advance the workflow. Example: pass the output hash, a new idempotency key, and the original verification_context. Any next current_action is deeply verified and receives a wallet handoff. AssetFare never signs or submits.
| Argument | Type | Description |
|---|---|---|
| session_id* | string | V2 workflow session UUID returned by assetfare_v2_session_create. Use only with assetfare_v2_session_* tools; do not pass a legacy session ID. |
| session_token* | string | Sensitive caller-generated v2 session capability: at least 32 CSPRNG bytes encoded as 43-128 URL-safe base64 characters. Generate it locally; never log it or substitute a private key or legacy access token. |
| idempotency_key* | string | Caller-generated retry key, 8-128 characters. Reuse it only when retrying the same logical mutation; choose a new key for a new operation. Strict approval_v3 requests additionally enforce its ASCII key pattern. |
| transaction_hash | string | Optional bridge or destination transaction hash already produced outside AssetFare. Omit only when the provider output can be observed without a hash. |
| verification_context* | object | Strict caller-held context copied from the selected quote and approval. It contains public intent/wallet data only, never the raw session token or a private key, and is required whenever a remote MCP session call can return current_action. |
Record source hashes the caller already signed and submitted, then advance the workflow. Example: pass one finalized source hash, a new idempotency key, and the original verification_context. Any next current_action is deeply verified and receives a wallet handoff. AssetFare never signs or submits.
| Argument | Type | Description |
|---|---|---|
| session_id* | string | V2 workflow session UUID returned by assetfare_v2_session_create. Use only with assetfare_v2_session_* tools; do not pass a legacy session ID. |
| session_token* | string | Sensitive caller-generated v2 session capability: at least 32 CSPRNG bytes encoded as 43-128 URL-safe base64 characters. Generate it locally; never log it or substitute a private key or legacy access token. |
| idempotency_key* | string | Caller-generated retry key, 8-128 characters. Reuse it only when retrying the same logical mutation; choose a new key for a new operation. Strict approval_v3 requests additionally enforce its ASCII key pattern. |
| transaction_hashes* | array | One to eight hashes for source transactions the caller already signed and submitted. Do not provide unsigned payloads or destination hashes. |
| verification_context* | object | Strict caller-held context copied from the selected quote and approval. It contains public intent/wallet data only, never the raw session token or a private key, and is required whenever a remote MCP session call can return current_action. |
Refresh an expired action only while it remains unsubmitted. Example: pass the existing session, a new idempotency key, and the original verification_context. The refreshed action is deeply verified and receives a wallet handoff. Never refresh a submitted step; AssetFare never signs or submits.
| Argument | Type | Description |
|---|---|---|
| session_id* | string | V2 workflow session UUID returned by assetfare_v2_session_create. Use only with assetfare_v2_session_* tools; do not pass a legacy session ID. |
| session_token* | string | Sensitive caller-generated v2 session capability: at least 32 CSPRNG bytes encoded as 43-128 URL-safe base64 characters. Generate it locally; never log it or substitute a private key or legacy access token. |
| idempotency_key* | string | Caller-generated retry key, 8-128 characters. Reuse it only when retrying the same logical mutation; choose a new key for a new operation. Strict approval_v3 requests additionally enforce its ASCII key pattern. |
| verification_context* | object | Strict caller-held context copied from the selected quote and approval. It contains public intent/wallet data only, never the raw session token or a private key, and is required whenever a remote MCP session call can return current_action. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"session_token",
"session_id",
"idempotency_key",
"verification_context"
],
"properties": {
"session_id": {
"type": "string",
"format": "uuid",
"description": "V2 workflow session UUID returned by assetfare_v2_session_create. Use only with assetfare_v2_session_* tools; do not pass a legacy session ID."
},
"session_token": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43,128}$",
"description": "Sensitive caller-generated v2 session capability: at least 32 CSPRNG bytes encoded as 43-128 URL-safe base64 characters. Generate it locally; never log it or substitute a private key or legacy access token."
},
"idempotency_key": {
"type": "string",
"maxLength": 128,
"minLength": 8,
"description": "Caller-generated retry key, 8-128 characters. Reuse it only when retrying the same logical mutation; choose a new key for a new operation. Strict approval_v3 requests additionally enforce its ASCII key pattern."
},
"verification_context": {
"type": "object",
"required": [
"version",
"intent",
"wallets",
"event_signer_public",
"approval_v3",
"direct_route_summary",
"verification_context_sha256"
],
"properties": {
"intent": {
"type": "object",
"required": [
"from_chain",
"from_token",
"to_chain",
"to_token",
"amount_usd"
],
"properties": {
"to_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood"
],
"type": "string",
"description": "Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations."
},
"to_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities."
},
"amount_usd": {
"type": "number",
"minimum": 1,
"description": "Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount."
},
"from_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
],
"type": "string",
"description": "Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain."
},
"from_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities."
}
},
"additionalProperties": false
},
"version": {
"type": "string",
"const": "assetfare-session-verification-context-v1"
},
"wallets": {
"type": "object",
"description": "Map each chain needed by this route to the caller's public wallet address. Include public addresses only; never private keys or seed phrases.",
"propertyNames": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
]
},
"additionalProperties": {
"type": "string",
"description": "Caller-owned public wallet address: 0x plus 40 hex characters for EVM, 0x plus 64 hex characters for Aptos, or 32-44 base58 characters for Solana. Never provide secret key material."
}
},
"approval_v3": {
"type": "object",
"required": [
"version",
"quote_id",
"quote_fingerprint",
"selection_status",
"selected_mode",
"maximum_input_base",
"minimum_output_base",
"direct_route_summary_sha256",
"idempotency_key"
],
"properties": {
"version": {
"type": "string",
"const": "assetfare-quote-bound-approval-v3"
},
"quote_id": {
"type": "string",
"format": "uuid"
},
"selected_mode": {
"type": "string",
"const": "session"
},
"idempotency_key": {
"type": "string",
"pattern": "^[A-Za-z0-9._:-]{8,128}$"
},
"selection_status": {
"type": "string",
"const": "selected"
},
"quote_fingerprint": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"maximum_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"minimum_output_base": {
"$ref": "#/properties/verification_context/properties/approval_v3/properties/maximum_input_base"
},
"direct_route_summary_sha256": {
"$ref": "#/properties/verification_context/properties/approval_v3/properties/quote_fingerprint"
}
},
"additionalProperties": false
},
"event_signer_public": {
"anyOf": [
{
"$ref": "#/properties/verification_context/properties/wallets/additionalProperties",
"description": "Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key."
},
{
"type": "null"
}
],
"description": "Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key."
},
"direct_route_summary": {
"type": "object",
"required": [
"version",
"route",
"from",
"to",
"classification",
"mode",
"route_aggregator_used",
"external_intent_protocol_used",
"provider_internal_dex_aggregation_possible",
"assetfare_fee_bps",
"fee_collection_step_index",
"server_signing",
"server_submission",
"step_count",
"steps"
],
"properties": {
"to": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG"
],
"type": "string"
},
"from": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG",
"polygon:USDC",
"optimism:USDC",
"ethereum:USDC",
"hyperevm:USDC",
"xlayer:USDC",
"sei:USDC",
"sonic:USDC",
"monad:USDC",
"avalanche:USDC",
"cronos:USDC",
"injective:USDC",
"linea:USDC",
"aptos:USDC",
"unichain:USDC",
"ink:USDC"
],
"type": "string"
},
"mode": {
"enum": [
"aptos_move_cctp_direct",
"cctp_direct_composition",
"optimism_source_cctp",
"polygon_source_cctp",
"robinhood_across_ingress_composition",
"robinhood_paxos_egress_composition",
"robinhood_paxos_ingress_composition",
"same_chain_direct",
"same_chain_direct_composition"
],
"type": "string"
},
"route": {
"enum": [
"solana:SOL->solana:USDC",
"solana:SOL->solana:USDG",
"solana:SOL->base:ETH",
"solana:SOL->base:USDC",
"solana:SOL->arbitrum:ETH",
"solana:SOL->arbitrum:USDC",
"solana:SOL->robinhood:ETH",
"solana:SOL->robinhood:USDG",
"solana:USDC->solana:SOL",
"solana:USDC->solana:USDG",
"solana:USDC->base:ETH",
"solana:USDC->base:USDC",
"solana:USDC->arbitrum:ETH",
"solana:USDC->arbitrum:USDC",
"solana:USDC->robinhood:ETH",
"solana:USDC->robinhood:USDG",
"solana:USDG->solana:SOL",
"solana:USDG->solana:USDC",
"solana:USDG->base:ETH",
"solana:USDG->base:USDC",
"solana:USDG->arbitrum:ETH",
"solana:USDG->arbitrum:USDC",
"solana:USDG->robinhood:ETH",
"solana:USDG->robinhood:USDG",
"base:ETH->solana:SOL",
"base:ETH->solana:USDC",
"base:ETH->solana:USDG",
"base:ETH->base:USDC",
"base:ETH->arbitrum:ETH",
"base:ETH->arbitrum:USDC",
"base:ETH->robinhood:ETH",
"base:ETH->robinhood:USDG",
"base:USDC->solana:SOL",
"base:USDC->solana:USDC",
"base:USDC->solana:USDG",
"base:USDC->base:ETH",
"base:USDC->arbitrum:ETH",
"base:USDC->arbitrum:USDC",
"base:USDC->robinhood:ETH",
"base:USDC->robinhood:USDG",
"arbitrum:ETH->solana:SOL",
"arbitrum:ETH->solana:USDC",
"arbitrum:ETH->solana:USDG",
"arbitrum:ETH->base:ETH",
"arbitrum:ETH->base:USDC",
"arbitrum:ETH->arbitrum:USDC",
"arbitrum:ETH->robinhood:ETH",
"arbitrum:ETH->robinhood:USDG",
"arbitrum:USDC->solana:SOL",
"arbitrum:USDC->solana:USDC",
"arbitrum:USDC->solana:USDG",
"arbitrum:USDC->base:ETH",
"arbitrum:USDC->base:USDC",
"arbitrum:USDC->arbitrum:ETH",
"arbitrum:USDC->robinhood:ETH",
"arbitrum:USDC->robinhood:USDG",
"robinhood:ETH->solana:SOL",
"robinhood:ETH->solana:USDC",
"robinhood:ETH->solana:USDG",
"robinhood:ETH->base:ETH",
"robinhood:ETH->base:USDC",
"robinhood:ETH->arbitrum:ETH",
"robinhood:ETH->arbitrum:USDC",
"robinhood:ETH->robinhood:USDG",
"robinhood:USDG->solana:SOL",
"robinhood:USDG->solana:USDC",
"robinhood:USDG->solana:USDG",
"robinhood:USDG->base:ETH",
"robinhood:USDG->base:USDC",
"robinhood:USDG->arbitrum:ETH",
"robinhood:USDG->arbitrum:USDC",
"robinhood:USDG->robinhood:ETH",
"polygon:USDC->base:USDC",
"polygon:USDC->arbitrum:USDC",
"optimism:USDC->base:USDC",
"optimism:USDC->arbitrum:USDC",
"ethereum:USDC->solana:USDC",
"ethereum:USDC->base:USDC",
"hyperevm:USDC->solana:USDC",
"hyperevm:USDC->base:USDC",
"xlayer:USDC->solana:USDC",
"xlayer:USDC->base:USDC",
"sei:USDC->solana:USDC",
"sei:USDC->base:USDC",
"sonic:USDC->solana:USDC",
"sonic:USDC->base:USDC",
"monad:USDC->solana:USDC",
"monad:USDC->base:USDC",
"avalanche:USDC->solana:USDC",
"avalanche:USDC->base:USDC",
"cronos:USDC->solana:USDC",
"cronos:USDC->base:USDC",
"injective:USDC->solana:USDC",
"injective:USDC->base:USDC",
"linea:USDC->solana:USDC",
"linea:USDC->base:USDC",
"aptos:USDC->solana:USDC",
"aptos:USDC->base:USDC",
"unichain:USDC->solana:USDC",
"ink:USDC->solana:USDC"
],
"type": "string"
},
"steps": {
"type": "array",
"items": {
"type": "object",
"required": [
"index",
"action",
"provider",
"from",
"to",
"expected_input_base",
"minimum_input_base",
"expected_output_base",
"minimum_output_base",
"assetfare_fee_bps",
"direct_protocol",
"external_intent_protocol",
"aggregator_api_used"
],
"properties": {
"to": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG"
],
"type": "string"
},
"from": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG",
"polygon:USDC",
"optimism:USDC",
"ethereum:USDC",
"hyperevm:USDC",
"xlayer:USDC",
"sei:USDC",
"sonic:USDC",
"monad:USDC",
"avalanche:USDC",
"cronos:USDC",
"injective:USDC",
"linea:USDC",
"aptos:USDC",
"unichain:USDC",
"ink:USDC"
],
"type": "string"
},
"index": {
"type": "integer",
"maximum": 7,
"minimum": 0
},
"action": {
"enum": [
"swap",
"bridge",
"receive"
],
"type": "string"
},
"provider": {
"enum": [
"raydium_clmm",
"orca_whirlpool",
"uniswap_v3",
"circle_cctp",
"circle_cctp_receive",
"paxos_usdg_layerzero_oft",
"across_intent_bridge"
],
"type": "string"
},
"direct_protocol": {
"type": "boolean"
},
"assetfare_fee_bps": {
"enum": [
0,
1
],
"type": "number"
},
"minimum_guard_bps": {
"type": "integer",
"maximum": 500,
"minimum": 1
},
"minimum_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"aggregator_api_used": {
"type": "boolean",
"const": false
},
"expected_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"minimum_output_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"expected_output_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"external_intent_protocol": {
"type": "boolean"
}
},
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1
},
"version": {
"type": "string",
"const": "assetfare-direct-route-summary-v1"
},
"step_count": {
"type": "integer",
"maximum": 8,
"minimum": 1
},
"classification": {
"enum": [
"direct_protocol_only",
"external_intent"
],
"type": "string"
},
"server_signing": {
"type": "boolean",
"const": false
},
"assetfare_fee_bps": {
"type": "number",
"const": 1
},
"server_submission": {
"type": "boolean",
"const": false
},
"economic_eligibility": {
"enum": [
"not_asserted_by_capability",
"coverage_only_not_primary"
],
"type": "string"
},
"route_aggregator_used": {
"type": "boolean",
"const": false
},
"product_classification": {
"enum": [
"primary_direct",
"external_coverage_only"
],
"type": "string"
},
"route_minimum_guard_bps": {
"anyOf": [
{
"type": "integer",
"maximum": 500,
"minimum": 1
},
{
"type": "null"
}
]
},
"fee_collection_step_index": {
"type": "integer",
"maximum": 7,
"minimum": 0
},
"public_execution_eligible": {
"type": "boolean"
},
"primary_selection_eligible": {
"type": "boolean"
},
"external_intent_protocol_used": {
"type": "boolean"
},
"provider_internal_dex_aggregation_possible": {
"type": "boolean"
}
},
"additionalProperties": false
},
"verification_context_sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
},
"description": "Strict caller-held context copied from the selected quote and approval. It contains public intent/wallet data only, never the raw session token or a private key, and is required whenever a remote MCP session call can return current_action.",
"additionalProperties": false
}
},
"additionalProperties": false
}| from_token* | string | Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities. |
| approval_v3* | object | Strict one-shot approval copied from the exact unexpired selected quote; its bounds may only be strengthened. |
| caller_approved* | boolean | Legacy caller assertion that MUST be supplied explicitly. It is not human-proof and is never auto-inserted; approval_v3 adds server-enforced quote binding. |
| event_signer_public | any | Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key. |
| verification_context* | object | Strict caller-held one-shot context copied from the selected quote, approval and public wallets. It is verified before prepare and never forwarded upstream. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"caller_approved",
"from_chain",
"from_token",
"to_chain",
"to_token",
"amount_usd",
"wallets",
"approval_v3",
"verification_context"
],
"properties": {
"wallets": {
"type": "object",
"description": "Map each chain needed by this route to the caller's public wallet address. Include public addresses only; never private keys or seed phrases.",
"propertyNames": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
]
},
"additionalProperties": {
"type": "string",
"description": "Caller-owned public wallet address: 0x plus 40 hex characters for EVM, 0x plus 64 hex characters for Aptos, or 32-44 base58 characters for Solana. Never provide secret key material."
}
},
"to_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood"
],
"type": "string",
"description": "Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations."
},
"to_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities."
},
"amount_usd": {
"type": "number",
"minimum": 1,
"description": "Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount."
},
"from_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
],
"type": "string",
"description": "Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain."
},
"from_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities."
},
"approval_v3": {
"type": "object",
"required": [
"version",
"quote_id",
"quote_fingerprint",
"selection_status",
"selected_mode",
"maximum_input_base",
"minimum_output_base",
"direct_route_summary_sha256",
"idempotency_key"
],
"properties": {
"version": {
"type": "string",
"const": "assetfare-quote-bound-approval-v3"
},
"quote_id": {
"type": "string",
"format": "uuid"
},
"selected_mode": {
"type": "string",
"const": "one_shot"
},
"idempotency_key": {
"type": "string",
"pattern": "^[A-Za-z0-9._:-]{8,128}$"
},
"selection_status": {
"type": "string",
"const": "selected"
},
"quote_fingerprint": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"maximum_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"minimum_output_base": {
"$ref": "#/properties/approval_v3/properties/maximum_input_base"
},
"direct_route_summary_sha256": {
"$ref": "#/properties/approval_v3/properties/quote_fingerprint"
}
},
"description": "Strict one-shot approval copied from the exact unexpired selected quote; its bounds may only be strengthened.",
"additionalProperties": false
},
"caller_approved": {
"type": "boolean",
"const": true,
"description": "Legacy caller assertion that MUST be supplied explicitly. It is not human-proof and is never auto-inserted; approval_v3 adds server-enforced quote binding."
},
"event_signer_public": {
"$ref": "#/properties/wallets/additionalProperties",
"description": "Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key."
},
"verification_context": {
"type": "object",
"required": [
"version",
"intent",
"wallets",
"event_signer_public",
"approval_v3",
"direct_route_summary",
"verification_context_sha256"
],
"properties": {
"intent": {
"type": "object",
"required": [
"from_chain",
"from_token",
"to_chain",
"to_token",
"amount_usd"
],
"properties": {
"to_chain": {
"$ref": "#/properties/to_chain"
},
"to_token": {
"$ref": "#/properties/to_token"
},
"amount_usd": {
"$ref": "#/properties/amount_usd"
},
"from_chain": {
"$ref": "#/properties/from_chain"
},
"from_token": {
"$ref": "#/properties/from_token"
}
},
"additionalProperties": false
},
"version": {
"type": "string",
"const": "assetfare-one-shot-verification-context-v1"
},
"wallets": {
"$ref": "#/properties/wallets"
},
"approval_v3": {
"type": "object",
"required": [
"version",
"quote_id",
"quote_fingerprint",
"selection_status",
"selected_mode",
"maximum_input_base",
"minimum_output_base",
"direct_route_summary_sha256",
"idempotency_key"
],
"properties": {
"version": {
"$ref": "#/properties/approval_v3/properties/version"
},
"quote_id": {
"$ref": "#/properties/approval_v3/properties/quote_id"
},
"selected_mode": {
"$ref": "#/properties/approval_v3/properties/selected_mode"
},
"idempotency_key": {
"$ref": "#/properties/approval_v3/properties/idempotency_key"
},
"selection_status": {
"$ref": "#/properties/approval_v3/properties/selection_status"
},
"quote_fingerprint": {
"$ref": "#/properties/approval_v3/properties/quote_fingerprint"
},
"maximum_input_base": {
"$ref": "#/properties/approval_v3/properties/maximum_input_base"
},
"minimum_output_base": {
"$ref": "#/properties/approval_v3/properties/maximum_input_base"
},
"direct_route_summary_sha256": {
"$ref": "#/properties/approval_v3/properties/quote_fingerprint"
}
},
"additionalProperties": false
},
"event_signer_public": {
"anyOf": [
{
"$ref": "#/properties/event_signer_public"
},
{
"type": "null"
}
],
"description": "Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key."
},
"direct_route_summary": {
"type": "object",
"required": [
"version",
"route",
"from",
"to",
"classification",
"mode",
"route_aggregator_used",
"external_intent_protocol_used",
"provider_internal_dex_aggregation_possible",
"assetfare_fee_bps",
"fee_collection_step_index",
"server_signing",
"server_submission",
"step_count",
"steps"
],
"properties": {
"to": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG"
],
"type": "string"
},
"from": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG",
"polygon:USDC",
"optimism:USDC",
"ethereum:USDC",
"hyperevm:USDC",
"xlayer:USDC",
"sei:USDC",
"sonic:USDC",
"monad:USDC",
"avalanche:USDC",
"cronos:USDC",
"injective:USDC",
"linea:USDC",
"aptos:USDC",
"unichain:USDC",
"ink:USDC"
],
"type": "string"
},
"mode": {
"enum": [
"aptos_move_cctp_direct",
"cctp_direct_composition",
"optimism_source_cctp",
"polygon_source_cctp",
"robinhood_across_ingress_composition",
"robinhood_paxos_egress_composition",
"robinhood_paxos_ingress_composition",
"same_chain_direct",
"same_chain_direct_composition"
],
"type": "string"
},
"route": {
"enum": [
"solana:SOL->solana:USDC",
"solana:SOL->solana:USDG",
"solana:SOL->base:ETH",
"solana:SOL->base:USDC",
"solana:SOL->arbitrum:ETH",
"solana:SOL->arbitrum:USDC",
"solana:SOL->robinhood:ETH",
"solana:SOL->robinhood:USDG",
"solana:USDC->solana:SOL",
"solana:USDC->solana:USDG",
"solana:USDC->base:ETH",
"solana:USDC->base:USDC",
"solana:USDC->arbitrum:ETH",
"solana:USDC->arbitrum:USDC",
"solana:USDC->robinhood:ETH",
"solana:USDC->robinhood:USDG",
"solana:USDG->solana:SOL",
"solana:USDG->solana:USDC",
"solana:USDG->base:ETH",
"solana:USDG->base:USDC",
"solana:USDG->arbitrum:ETH",
"solana:USDG->arbitrum:USDC",
"solana:USDG->robinhood:ETH",
"solana:USDG->robinhood:USDG",
"base:ETH->solana:SOL",
"base:ETH->solana:USDC",
"base:ETH->solana:USDG",
"base:ETH->base:USDC",
"base:ETH->arbitrum:ETH",
"base:ETH->arbitrum:USDC",
"base:ETH->robinhood:ETH",
"base:ETH->robinhood:USDG",
"base:USDC->solana:SOL",
"base:USDC->solana:USDC",
"base:USDC->solana:USDG",
"base:USDC->base:ETH",
"base:USDC->arbitrum:ETH",
"base:USDC->arbitrum:USDC",
"base:USDC->robinhood:ETH",
"base:USDC->robinhood:USDG",
"arbitrum:ETH->solana:SOL",
"arbitrum:ETH->solana:USDC",
"arbitrum:ETH->solana:USDG",
"arbitrum:ETH->base:ETH",
"arbitrum:ETH->base:USDC",
"arbitrum:ETH->arbitrum:USDC",
"arbitrum:ETH->robinhood:ETH",
"arbitrum:ETH->robinhood:USDG",
"arbitrum:USDC->solana:SOL",
"arbitrum:USDC->solana:USDC",
"arbitrum:USDC->solana:USDG",
"arbitrum:USDC->base:ETH",
"arbitrum:USDC->base:USDC",
"arbitrum:USDC->arbitrum:ETH",
"arbitrum:USDC->robinhood:ETH",
"arbitrum:USDC->robinhood:USDG",
"robinhood:ETH->solana:SOL",
"robinhood:ETH->solana:USDC",
"robinhood:ETH->solana:USDG",
"robinhood:ETH->base:ETH",
"robinhood:ETH->base:USDC",
"robinhood:ETH->arbitrum:ETH",
"robinhood:ETH->arbitrum:USDC",
"robinhood:ETH->robinhood:USDG",
"robinhood:USDG->solana:SOL",
"robinhood:USDG->solana:USDC",
"robinhood:USDG->solana:USDG",
"robinhood:USDG->base:ETH",
"robinhood:USDG->base:USDC",
"robinhood:USDG->arbitrum:ETH",
"robinhood:USDG->arbitrum:USDC",
"robinhood:USDG->robinhood:ETH",
"polygon:USDC->base:USDC",
"polygon:USDC->arbitrum:USDC",
"optimism:USDC->base:USDC",
"optimism:USDC->arbitrum:USDC",
"ethereum:USDC->solana:USDC",
"ethereum:USDC->base:USDC",
"hyperevm:USDC->solana:USDC",
"hyperevm:USDC->base:USDC",
"xlayer:USDC->solana:USDC",
"xlayer:USDC->base:USDC",
"sei:USDC->solana:USDC",
"sei:USDC->base:USDC",
"sonic:USDC->solana:USDC",
"sonic:USDC->base:USDC",
"monad:USDC->solana:USDC",
"monad:USDC->base:USDC",
"avalanche:USDC->solana:USDC",
"avalanche:USDC->base:USDC",
"cronos:USDC->solana:USDC",
"cronos:USDC->base:USDC",
"injective:USDC->solana:USDC",
"injective:USDC->base:USDC",
"linea:USDC->solana:USDC",
"linea:USDC->base:USDC",
"aptos:USDC->solana:USDC",
"aptos:USDC->base:USDC",
"unichain:USDC->solana:USDC",
"ink:USDC->solana:USDC"
],
"type": "string"
},
"steps": {
"type": "array",
"items": {
"type": "object",
"required": [
"index",
"action",
"provider",
"from",
"to",
"expected_input_base",
"minimum_input_base",
"expected_output_base",
"minimum_output_base",
"assetfare_fee_bps",
"direct_protocol",
"external_intent_protocol",
"aggregator_api_used"
],
"properties": {
"to": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG"
],
"type": "string"
},
"from": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG",
"polygon:USDC",
"optimism:USDC",
"ethereum:USDC",
"hyperevm:USDC",
"xlayer:USDC",
"sei:USDC",
"sonic:USDC",
"monad:USDC",
"avalanche:USDC",
"cronos:USDC",
"injective:USDC",
"linea:USDC",
"aptos:USDC",
"unichain:USDC",
"ink:USDC"
],
"type": "string"
},
"index": {
"type": "integer",
"maximum": 7,
"minimum": 0
},
"action": {
"enum": [
"swap",
"bridge",
"receive"
],
"type": "string"
},
"provider": {
"enum": [
"raydium_clmm",
"orca_whirlpool",
"uniswap_v3",
"circle_cctp",
"circle_cctp_receive",
"paxos_usdg_layerzero_oft",
"across_intent_bridge"
],
"type": "string"
},
"direct_protocol": {
"type": "boolean"
},
"assetfare_fee_bps": {
"enum": [
0,
1
],
"type": "number"
},
"minimum_guard_bps": {
"type": "integer",
"maximum": 500,
"minimum": 1
},
"minimum_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"aggregator_api_used": {
"type": "boolean",
"const": false
},
"expected_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"minimum_output_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"expected_output_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"external_intent_protocol": {
"type": "boolean"
}
},
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1
},
"version": {
"type": "string",
"const": "assetfare-direct-route-summary-v1"
},
"step_count": {
"type": "integer",
"maximum": 8,
"minimum": 1
},
"classification": {
"enum": [
"direct_protocol_only",
"external_intent"
],
"type": "string"
},
"server_signing": {
"type": "boolean",
"const": false
},
"assetfare_fee_bps": {
"type": "number",
"const": 1
},
"server_submission": {
"type": "boolean",
"const": false
},
"economic_eligibility": {
"enum": [
"not_asserted_by_capability",
"coverage_only_not_primary"
],
"type": "string"
},
"route_aggregator_used": {
"type": "boolean",
"const": false
},
"product_classification": {
"enum": [
"primary_direct",
"external_coverage_only"
],
"type": "string"
},
"route_minimum_guard_bps": {
"anyOf": [
{
"type": "integer",
"maximum": 500,
"minimum": 1
},
{
"type": "null"
}
]
},
"fee_collection_step_index": {
"type": "integer",
"maximum": 7,
"minimum": 0
},
"public_execution_eligible": {
"type": "boolean"
},
"primary_selection_eligible": {
"type": "boolean"
},
"external_intent_protocol_used": {
"type": "boolean"
},
"provider_internal_dex_aggregation_possible": {
"type": "boolean"
}
},
"additionalProperties": false
},
"verification_context_sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
},
"description": "Strict caller-held one-shot context copied from the selected quote, approval and public wallets. It is verified before prepare and never forwarded upstream.",
"additionalProperties": false
}
},
"additionalProperties": false
}| from_token* |
| string |
| Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"from_chain",
"from_token",
"to_chain",
"to_token",
"amount_usd"
],
"properties": {
"to_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood"
],
"type": "string",
"description": "Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations."
},
"to_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities."
},
"amount_usd": {
"type": "number",
"minimum": 1,
"description": "Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount."
},
"from_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
],
"type": "string",
"description": "Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain."
},
"from_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities."
}
},
"additionalProperties": false
}| string |
| Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain. |
| from_token* | string | Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities. |
| candidate_id* | string | Exact candidate_id returned by assetfare_v2_route_selection; it is never chosen automatically. |
| max_eta_seconds | integer | Optional stricter maximum ETA in seconds; it cannot exceed 60 or the selected profile limit. |
| selection_receipt_sha256* | string | Exact selection_receipt.sha256 returned with the fresh shortlist. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"from_chain",
"from_token",
"to_chain",
"to_token",
"amount_usd",
"candidate_id",
"selection_receipt_sha256"
],
"properties": {
"profile": {
"enum": [
"fast",
"balanced",
"economy"
],
"type": "string",
"description": "Time policy: fast (30s), balanced (60s default), or explicit economy (60s). Every recommendation profile has an absolute 60-second ceiling."
},
"to_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood"
],
"type": "string",
"description": "Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations."
},
"to_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities."
},
"amount_usd": {
"type": "number",
"minimum": 1,
"description": "Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount."
},
"from_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
],
"type": "string",
"description": "Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain."
},
"from_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities."
},
"candidate_id": {
"type": "string",
"maxLength": 160,
"minLength": 1,
"description": "Exact candidate_id returned by assetfare_v2_route_selection; it is never chosen automatically."
},
"max_eta_seconds": {
"type": "integer",
"maximum": 60,
"minimum": 1,
"description": "Optional stricter maximum ETA in seconds; it cannot exceed 60 or the selected profile limit."
},
"selection_receipt_sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$",
"description": "Exact selection_receipt.sha256 returned with the fresh shortlist."
}
},
"additionalProperties": false
}| from_chain* |
| string |
| Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain. |
| from_token* | string | Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities. |
| max_eta_seconds | integer | Optional stricter maximum ETA in seconds; it cannot exceed 60 or the selected profile limit. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"from_chain",
"from_token",
"to_chain",
"to_token",
"amount_usd"
],
"properties": {
"profile": {
"enum": [
"fast",
"balanced",
"economy"
],
"type": "string",
"description": "Time policy: fast (30s), balanced (60s default), or explicit economy (60s). Every recommendation profile has an absolute 60-second ceiling."
},
"to_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood"
],
"type": "string",
"description": "Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations."
},
"to_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities."
},
"amount_usd": {
"type": "number",
"minimum": 1,
"description": "Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount."
},
"from_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
],
"type": "string",
"description": "Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain."
},
"from_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities."
},
"max_eta_seconds": {
"type": "integer",
"maximum": 60,
"minimum": 1,
"description": "Optional stricter maximum ETA in seconds; it cannot exceed 60 or the selected profile limit."
}
},
"additionalProperties": false
}| from_token* | string | Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities. |
| approval_v3* | object | Strict Core 2.4.1 session quote-bound selection from the exact unexpired quote. Required for every remote session flow. |
| session_token* | string | Sensitive caller-generated v2 session capability: at least 32 CSPRNG bytes encoded as 43-128 URL-safe base64 characters. Generate it locally; never log it or substitute a private key or legacy access token. |
| caller_approved* | boolean | Legacy caller assertion that MUST be supplied explicitly. It is not human-proof and is never auto-inserted; approval_v3 adds server-enforced quote binding. |
| idempotency_key* | string | Caller-generated retry key, 8-128 characters. Reuse it only when retrying the same logical mutation; choose a new key for a new operation. Strict approval_v3 requests additionally enforce its ASCII key pattern. |
| event_signer_public | any | Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key. |
| verification_context* | object | Strict caller-held context copied from the selected quote and approval. It contains public intent/wallet data only, never the raw session token or a private key, and is required whenever a remote MCP session call can return current_action. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"caller_approved",
"from_chain",
"from_token",
"to_chain",
"to_token",
"amount_usd",
"wallets",
"approval_v3",
"session_token",
"idempotency_key",
"verification_context"
],
"properties": {
"wallets": {
"type": "object",
"description": "Map each chain needed by this route to the caller's public wallet address. Include public addresses only; never private keys or seed phrases.",
"propertyNames": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
]
},
"additionalProperties": {
"type": "string",
"description": "Caller-owned public wallet address: 0x plus 40 hex characters for EVM, 0x plus 64 hex characters for Aptos, or 32-44 base58 characters for Solana. Never provide secret key material."
}
},
"to_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood"
],
"type": "string",
"description": "Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations."
},
"to_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities."
},
"amount_usd": {
"type": "number",
"minimum": 1,
"description": "Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount."
},
"from_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
],
"type": "string",
"description": "Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain."
},
"from_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities."
},
"approval_v3": {
"type": "object",
"required": [
"version",
"quote_id",
"quote_fingerprint",
"selection_status",
"selected_mode",
"maximum_input_base",
"minimum_output_base",
"direct_route_summary_sha256",
"idempotency_key"
],
"properties": {
"version": {
"type": "string",
"const": "assetfare-quote-bound-approval-v3"
},
"quote_id": {
"type": "string",
"format": "uuid"
},
"selected_mode": {
"type": "string",
"const": "session"
},
"idempotency_key": {
"type": "string",
"pattern": "^[A-Za-z0-9._:-]{8,128}$"
},
"selection_status": {
"type": "string",
"const": "selected"
},
"quote_fingerprint": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"maximum_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"minimum_output_base": {
"$ref": "#/properties/approval_v3/properties/maximum_input_base"
},
"direct_route_summary_sha256": {
"$ref": "#/properties/approval_v3/properties/quote_fingerprint"
}
},
"description": "Strict Core 2.4.1 session quote-bound selection from the exact unexpired quote. Required for every remote session flow.",
"additionalProperties": false
},
"session_token": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43,128}$",
"description": "Sensitive caller-generated v2 session capability: at least 32 CSPRNG bytes encoded as 43-128 URL-safe base64 characters. Generate it locally; never log it or substitute a private key or legacy access token."
},
"caller_approved": {
"type": "boolean",
"const": true,
"description": "Legacy caller assertion that MUST be supplied explicitly. It is not human-proof and is never auto-inserted; approval_v3 adds server-enforced quote binding."
},
"idempotency_key": {
"type": "string",
"maxLength": 128,
"minLength": 8,
"description": "Caller-generated retry key, 8-128 characters. Reuse it only when retrying the same logical mutation; choose a new key for a new operation. Strict approval_v3 requests additionally enforce its ASCII key pattern."
},
"event_signer_public": {
"$ref": "#/properties/wallets/additionalProperties",
"description": "Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key."
},
"verification_context": {
"type": "object",
"required": [
"version",
"intent",
"wallets",
"event_signer_public",
"approval_v3",
"direct_route_summary",
"verification_context_sha256"
],
"properties": {
"intent": {
"type": "object",
"required": [
"from_chain",
"from_token",
"to_chain",
"to_token",
"amount_usd"
],
"properties": {
"to_chain": {
"$ref": "#/properties/to_chain"
},
"to_token": {
"$ref": "#/properties/to_token"
},
"amount_usd": {
"$ref": "#/properties/amount_usd"
},
"from_chain": {
"$ref": "#/properties/from_chain"
},
"from_token": {
"$ref": "#/properties/from_token"
}
},
"additionalProperties": false
},
"version": {
"type": "string",
"const": "assetfare-session-verification-context-v1"
},
"wallets": {
"$ref": "#/properties/wallets"
},
"approval_v3": {
"type": "object",
"required": [
"version",
"quote_id",
"quote_fingerprint",
"selection_status",
"selected_mode",
"maximum_input_base",
"minimum_output_base",
"direct_route_summary_sha256",
"idempotency_key"
],
"properties": {
"version": {
"$ref": "#/properties/approval_v3/properties/version"
},
"quote_id": {
"$ref": "#/properties/approval_v3/properties/quote_id"
},
"selected_mode": {
"$ref": "#/properties/approval_v3/properties/selected_mode"
},
"idempotency_key": {
"$ref": "#/properties/approval_v3/properties/idempotency_key"
},
"selection_status": {
"$ref": "#/properties/approval_v3/properties/selection_status"
},
"quote_fingerprint": {
"$ref": "#/properties/approval_v3/properties/quote_fingerprint"
},
"maximum_input_base": {
"$ref": "#/properties/approval_v3/properties/maximum_input_base"
},
"minimum_output_base": {
"$ref": "#/properties/approval_v3/properties/maximum_input_base"
},
"direct_route_summary_sha256": {
"$ref": "#/properties/approval_v3/properties/quote_fingerprint"
}
},
"additionalProperties": false
},
"event_signer_public": {
"anyOf": [
{
"$ref": "#/properties/event_signer_public"
},
{
"type": "null"
}
],
"description": "Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key."
},
"direct_route_summary": {
"type": "object",
"required": [
"version",
"route",
"from",
"to",
"classification",
"mode",
"route_aggregator_used",
"external_intent_protocol_used",
"provider_internal_dex_aggregation_possible",
"assetfare_fee_bps",
"fee_collection_step_index",
"server_signing",
"server_submission",
"step_count",
"steps"
],
"properties": {
"to": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG"
],
"type": "string"
},
"from": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG",
"polygon:USDC",
"optimism:USDC",
"ethereum:USDC",
"hyperevm:USDC",
"xlayer:USDC",
"sei:USDC",
"sonic:USDC",
"monad:USDC",
"avalanche:USDC",
"cronos:USDC",
"injective:USDC",
"linea:USDC",
"aptos:USDC",
"unichain:USDC",
"ink:USDC"
],
"type": "string"
},
"mode": {
"enum": [
"aptos_move_cctp_direct",
"cctp_direct_composition",
"optimism_source_cctp",
"polygon_source_cctp",
"robinhood_across_ingress_composition",
"robinhood_paxos_egress_composition",
"robinhood_paxos_ingress_composition",
"same_chain_direct",
"same_chain_direct_composition"
],
"type": "string"
},
"route": {
"enum": [
"solana:SOL->solana:USDC",
"solana:SOL->solana:USDG",
"solana:SOL->base:ETH",
"solana:SOL->base:USDC",
"solana:SOL->arbitrum:ETH",
"solana:SOL->arbitrum:USDC",
"solana:SOL->robinhood:ETH",
"solana:SOL->robinhood:USDG",
"solana:USDC->solana:SOL",
"solana:USDC->solana:USDG",
"solana:USDC->base:ETH",
"solana:USDC->base:USDC",
"solana:USDC->arbitrum:ETH",
"solana:USDC->arbitrum:USDC",
"solana:USDC->robinhood:ETH",
"solana:USDC->robinhood:USDG",
"solana:USDG->solana:SOL",
"solana:USDG->solana:USDC",
"solana:USDG->base:ETH",
"solana:USDG->base:USDC",
"solana:USDG->arbitrum:ETH",
"solana:USDG->arbitrum:USDC",
"solana:USDG->robinhood:ETH",
"solana:USDG->robinhood:USDG",
"base:ETH->solana:SOL",
"base:ETH->solana:USDC",
"base:ETH->solana:USDG",
"base:ETH->base:USDC",
"base:ETH->arbitrum:ETH",
"base:ETH->arbitrum:USDC",
"base:ETH->robinhood:ETH",
"base:ETH->robinhood:USDG",
"base:USDC->solana:SOL",
"base:USDC->solana:USDC",
"base:USDC->solana:USDG",
"base:USDC->base:ETH",
"base:USDC->arbitrum:ETH",
"base:USDC->arbitrum:USDC",
"base:USDC->robinhood:ETH",
"base:USDC->robinhood:USDG",
"arbitrum:ETH->solana:SOL",
"arbitrum:ETH->solana:USDC",
"arbitrum:ETH->solana:USDG",
"arbitrum:ETH->base:ETH",
"arbitrum:ETH->base:USDC",
"arbitrum:ETH->arbitrum:USDC",
"arbitrum:ETH->robinhood:ETH",
"arbitrum:ETH->robinhood:USDG",
"arbitrum:USDC->solana:SOL",
"arbitrum:USDC->solana:USDC",
"arbitrum:USDC->solana:USDG",
"arbitrum:USDC->base:ETH",
"arbitrum:USDC->base:USDC",
"arbitrum:USDC->arbitrum:ETH",
"arbitrum:USDC->robinhood:ETH",
"arbitrum:USDC->robinhood:USDG",
"robinhood:ETH->solana:SOL",
"robinhood:ETH->solana:USDC",
"robinhood:ETH->solana:USDG",
"robinhood:ETH->base:ETH",
"robinhood:ETH->base:USDC",
"robinhood:ETH->arbitrum:ETH",
"robinhood:ETH->arbitrum:USDC",
"robinhood:ETH->robinhood:USDG",
"robinhood:USDG->solana:SOL",
"robinhood:USDG->solana:USDC",
"robinhood:USDG->solana:USDG",
"robinhood:USDG->base:ETH",
"robinhood:USDG->base:USDC",
"robinhood:USDG->arbitrum:ETH",
"robinhood:USDG->arbitrum:USDC",
"robinhood:USDG->robinhood:ETH",
"polygon:USDC->base:USDC",
"polygon:USDC->arbitrum:USDC",
"optimism:USDC->base:USDC",
"optimism:USDC->arbitrum:USDC",
"ethereum:USDC->solana:USDC",
"ethereum:USDC->base:USDC",
"hyperevm:USDC->solana:USDC",
"hyperevm:USDC->base:USDC",
"xlayer:USDC->solana:USDC",
"xlayer:USDC->base:USDC",
"sei:USDC->solana:USDC",
"sei:USDC->base:USDC",
"sonic:USDC->solana:USDC",
"sonic:USDC->base:USDC",
"monad:USDC->solana:USDC",
"monad:USDC->base:USDC",
"avalanche:USDC->solana:USDC",
"avalanche:USDC->base:USDC",
"cronos:USDC->solana:USDC",
"cronos:USDC->base:USDC",
"injective:USDC->solana:USDC",
"injective:USDC->base:USDC",
"linea:USDC->solana:USDC",
"linea:USDC->base:USDC",
"aptos:USDC->solana:USDC",
"aptos:USDC->base:USDC",
"unichain:USDC->solana:USDC",
"ink:USDC->solana:USDC"
],
"type": "string"
},
"steps": {
"type": "array",
"items": {
"type": "object",
"required": [
"index",
"action",
"provider",
"from",
"to",
"expected_input_base",
"minimum_input_base",
"expected_output_base",
"minimum_output_base",
"assetfare_fee_bps",
"direct_protocol",
"external_intent_protocol",
"aggregator_api_used"
],
"properties": {
"to": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG"
],
"type": "string"
},
"from": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG",
"polygon:USDC",
"optimism:USDC",
"ethereum:USDC",
"hyperevm:USDC",
"xlayer:USDC",
"sei:USDC",
"sonic:USDC",
"monad:USDC",
"avalanche:USDC",
"cronos:USDC",
"injective:USDC",
"linea:USDC",
"aptos:USDC",
"unichain:USDC",
"ink:USDC"
],
"type": "string"
},
"index": {
"type": "integer",
"maximum": 7,
"minimum": 0
},
"action": {
"enum": [
"swap",
"bridge",
"receive"
],
"type": "string"
},
"provider": {
"enum": [
"raydium_clmm",
"orca_whirlpool",
"uniswap_v3",
"circle_cctp",
"circle_cctp_receive",
"paxos_usdg_layerzero_oft",
"across_intent_bridge"
],
"type": "string"
},
"direct_protocol": {
"type": "boolean"
},
"assetfare_fee_bps": {
"enum": [
0,
1
],
"type": "number"
},
"minimum_guard_bps": {
"type": "integer",
"maximum": 500,
"minimum": 1
},
"minimum_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"aggregator_api_used": {
"type": "boolean",
"const": false
},
"expected_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"minimum_output_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"expected_output_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"external_intent_protocol": {
"type": "boolean"
}
},
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1
},
"version": {
"type": "string",
"const": "assetfare-direct-route-summary-v1"
},
"step_count": {
"type": "integer",
"maximum": 8,
"minimum": 1
},
"classification": {
"enum": [
"direct_protocol_only",
"external_intent"
],
"type": "string"
},
"server_signing": {
"type": "boolean",
"const": false
},
"assetfare_fee_bps": {
"type": "number",
"const": 1
},
"server_submission": {
"type": "boolean",
"const": false
},
"economic_eligibility": {
"enum": [
"not_asserted_by_capability",
"coverage_only_not_primary"
],
"type": "string"
},
"route_aggregator_used": {
"type": "boolean",
"const": false
},
"product_classification": {
"enum": [
"primary_direct",
"external_coverage_only"
],
"type": "string"
},
"route_minimum_guard_bps": {
"anyOf": [
{
"type": "integer",
"maximum": 500,
"minimum": 1
},
{
"type": "null"
}
]
},
"fee_collection_step_index": {
"type": "integer",
"maximum": 7,
"minimum": 0
},
"public_execution_eligible": {
"type": "boolean"
},
"primary_selection_eligible": {
"type": "boolean"
},
"external_intent_protocol_used": {
"type": "boolean"
},
"provider_internal_dex_aggregation_possible": {
"type": "boolean"
}
},
"additionalProperties": false
},
"verification_context_sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
},
"description": "Strict caller-held context copied from the selected quote and approval. It contains public intent/wallet data only, never the raw session token or a private key, and is required whenever a remote MCP session call can return current_action.",
"additionalProperties": false
}
},
"additionalProperties": false
}{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"session_token",
"session_id",
"idempotency_key",
"verification_context"
],
"properties": {
"session_id": {
"type": "string",
"format": "uuid",
"description": "V2 workflow session UUID returned by assetfare_v2_session_create. Use only with assetfare_v2_session_* tools; do not pass a legacy session ID."
},
"session_token": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43,128}$",
"description": "Sensitive caller-generated v2 session capability: at least 32 CSPRNG bytes encoded as 43-128 URL-safe base64 characters. Generate it locally; never log it or substitute a private key or legacy access token."
},
"idempotency_key": {
"type": "string",
"maxLength": 128,
"minLength": 8,
"description": "Caller-generated retry key, 8-128 characters. Reuse it only when retrying the same logical mutation; choose a new key for a new operation. Strict approval_v3 requests additionally enforce its ASCII key pattern."
},
"transaction_hash": {
"type": "string",
"maxLength": 128,
"minLength": 16,
"description": "Optional bridge or destination transaction hash already produced outside AssetFare. Omit only when the provider output can be observed without a hash."
},
"verification_context": {
"type": "object",
"required": [
"version",
"intent",
"wallets",
"event_signer_public",
"approval_v3",
"direct_route_summary",
"verification_context_sha256"
],
"properties": {
"intent": {
"type": "object",
"required": [
"from_chain",
"from_token",
"to_chain",
"to_token",
"amount_usd"
],
"properties": {
"to_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood"
],
"type": "string",
"description": "Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations."
},
"to_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities."
},
"amount_usd": {
"type": "number",
"minimum": 1,
"description": "Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount."
},
"from_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
],
"type": "string",
"description": "Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain."
},
"from_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities."
}
},
"additionalProperties": false
},
"version": {
"type": "string",
"const": "assetfare-session-verification-context-v1"
},
"wallets": {
"type": "object",
"description": "Map each chain needed by this route to the caller's public wallet address. Include public addresses only; never private keys or seed phrases.",
"propertyNames": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
]
},
"additionalProperties": {
"type": "string",
"description": "Caller-owned public wallet address: 0x plus 40 hex characters for EVM, 0x plus 64 hex characters for Aptos, or 32-44 base58 characters for Solana. Never provide secret key material."
}
},
"approval_v3": {
"type": "object",
"required": [
"version",
"quote_id",
"quote_fingerprint",
"selection_status",
"selected_mode",
"maximum_input_base",
"minimum_output_base",
"direct_route_summary_sha256",
"idempotency_key"
],
"properties": {
"version": {
"type": "string",
"const": "assetfare-quote-bound-approval-v3"
},
"quote_id": {
"type": "string",
"format": "uuid"
},
"selected_mode": {
"type": "string",
"const": "session"
},
"idempotency_key": {
"type": "string",
"pattern": "^[A-Za-z0-9._:-]{8,128}$"
},
"selection_status": {
"type": "string",
"const": "selected"
},
"quote_fingerprint": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"maximum_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"minimum_output_base": {
"$ref": "#/properties/verification_context/properties/approval_v3/properties/maximum_input_base"
},
"direct_route_summary_sha256": {
"$ref": "#/properties/verification_context/properties/approval_v3/properties/quote_fingerprint"
}
},
"additionalProperties": false
},
"event_signer_public": {
"anyOf": [
{
"$ref": "#/properties/verification_context/properties/wallets/additionalProperties",
"description": "Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key."
},
{
"type": "null"
}
],
"description": "Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key."
},
"direct_route_summary": {
"type": "object",
"required": [
"version",
"route",
"from",
"to",
"classification",
"mode",
"route_aggregator_used",
"external_intent_protocol_used",
"provider_internal_dex_aggregation_possible",
"assetfare_fee_bps",
"fee_collection_step_index",
"server_signing",
"server_submission",
"step_count",
"steps"
],
"properties": {
"to": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG"
],
"type": "string"
},
"from": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG",
"polygon:USDC",
"optimism:USDC",
"ethereum:USDC",
"hyperevm:USDC",
"xlayer:USDC",
"sei:USDC",
"sonic:USDC",
"monad:USDC",
"avalanche:USDC",
"cronos:USDC",
"injective:USDC",
"linea:USDC",
"aptos:USDC",
"unichain:USDC",
"ink:USDC"
],
"type": "string"
},
"mode": {
"enum": [
"aptos_move_cctp_direct",
"cctp_direct_composition",
"optimism_source_cctp",
"polygon_source_cctp",
"robinhood_across_ingress_composition",
"robinhood_paxos_egress_composition",
"robinhood_paxos_ingress_composition",
"same_chain_direct",
"same_chain_direct_composition"
],
"type": "string"
},
"route": {
"enum": [
"solana:SOL->solana:USDC",
"solana:SOL->solana:USDG",
"solana:SOL->base:ETH",
"solana:SOL->base:USDC",
"solana:SOL->arbitrum:ETH",
"solana:SOL->arbitrum:USDC",
"solana:SOL->robinhood:ETH",
"solana:SOL->robinhood:USDG",
"solana:USDC->solana:SOL",
"solana:USDC->solana:USDG",
"solana:USDC->base:ETH",
"solana:USDC->base:USDC",
"solana:USDC->arbitrum:ETH",
"solana:USDC->arbitrum:USDC",
"solana:USDC->robinhood:ETH",
"solana:USDC->robinhood:USDG",
"solana:USDG->solana:SOL",
"solana:USDG->solana:USDC",
"solana:USDG->base:ETH",
"solana:USDG->base:USDC",
"solana:USDG->arbitrum:ETH",
"solana:USDG->arbitrum:USDC",
"solana:USDG->robinhood:ETH",
"solana:USDG->robinhood:USDG",
"base:ETH->solana:SOL",
"base:ETH->solana:USDC",
"base:ETH->solana:USDG",
"base:ETH->base:USDC",
"base:ETH->arbitrum:ETH",
"base:ETH->arbitrum:USDC",
"base:ETH->robinhood:ETH",
"base:ETH->robinhood:USDG",
"base:USDC->solana:SOL",
"base:USDC->solana:USDC",
"base:USDC->solana:USDG",
"base:USDC->base:ETH",
"base:USDC->arbitrum:ETH",
"base:USDC->arbitrum:USDC",
"base:USDC->robinhood:ETH",
"base:USDC->robinhood:USDG",
"arbitrum:ETH->solana:SOL",
"arbitrum:ETH->solana:USDC",
"arbitrum:ETH->solana:USDG",
"arbitrum:ETH->base:ETH",
"arbitrum:ETH->base:USDC",
"arbitrum:ETH->arbitrum:USDC",
"arbitrum:ETH->robinhood:ETH",
"arbitrum:ETH->robinhood:USDG",
"arbitrum:USDC->solana:SOL",
"arbitrum:USDC->solana:USDC",
"arbitrum:USDC->solana:USDG",
"arbitrum:USDC->base:ETH",
"arbitrum:USDC->base:USDC",
"arbitrum:USDC->arbitrum:ETH",
"arbitrum:USDC->robinhood:ETH",
"arbitrum:USDC->robinhood:USDG",
"robinhood:ETH->solana:SOL",
"robinhood:ETH->solana:USDC",
"robinhood:ETH->solana:USDG",
"robinhood:ETH->base:ETH",
"robinhood:ETH->base:USDC",
"robinhood:ETH->arbitrum:ETH",
"robinhood:ETH->arbitrum:USDC",
"robinhood:ETH->robinhood:USDG",
"robinhood:USDG->solana:SOL",
"robinhood:USDG->solana:USDC",
"robinhood:USDG->solana:USDG",
"robinhood:USDG->base:ETH",
"robinhood:USDG->base:USDC",
"robinhood:USDG->arbitrum:ETH",
"robinhood:USDG->arbitrum:USDC",
"robinhood:USDG->robinhood:ETH",
"polygon:USDC->base:USDC",
"polygon:USDC->arbitrum:USDC",
"optimism:USDC->base:USDC",
"optimism:USDC->arbitrum:USDC",
"ethereum:USDC->solana:USDC",
"ethereum:USDC->base:USDC",
"hyperevm:USDC->solana:USDC",
"hyperevm:USDC->base:USDC",
"xlayer:USDC->solana:USDC",
"xlayer:USDC->base:USDC",
"sei:USDC->solana:USDC",
"sei:USDC->base:USDC",
"sonic:USDC->solana:USDC",
"sonic:USDC->base:USDC",
"monad:USDC->solana:USDC",
"monad:USDC->base:USDC",
"avalanche:USDC->solana:USDC",
"avalanche:USDC->base:USDC",
"cronos:USDC->solana:USDC",
"cronos:USDC->base:USDC",
"injective:USDC->solana:USDC",
"injective:USDC->base:USDC",
"linea:USDC->solana:USDC",
"linea:USDC->base:USDC",
"aptos:USDC->solana:USDC",
"aptos:USDC->base:USDC",
"unichain:USDC->solana:USDC",
"ink:USDC->solana:USDC"
],
"type": "string"
},
"steps": {
"type": "array",
"items": {
"type": "object",
"required": [
"index",
"action",
"provider",
"from",
"to",
"expected_input_base",
"minimum_input_base",
"expected_output_base",
"minimum_output_base",
"assetfare_fee_bps",
"direct_protocol",
"external_intent_protocol",
"aggregator_api_used"
],
"properties": {
"to": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG"
],
"type": "string"
},
"from": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG",
"polygon:USDC",
"optimism:USDC",
"ethereum:USDC",
"hyperevm:USDC",
"xlayer:USDC",
"sei:USDC",
"sonic:USDC",
"monad:USDC",
"avalanche:USDC",
"cronos:USDC",
"injective:USDC",
"linea:USDC",
"aptos:USDC",
"unichain:USDC",
"ink:USDC"
],
"type": "string"
},
"index": {
"type": "integer",
"maximum": 7,
"minimum": 0
},
"action": {
"enum": [
"swap",
"bridge",
"receive"
],
"type": "string"
},
"provider": {
"enum": [
"raydium_clmm",
"orca_whirlpool",
"uniswap_v3",
"circle_cctp",
"circle_cctp_receive",
"paxos_usdg_layerzero_oft",
"across_intent_bridge"
],
"type": "string"
},
"direct_protocol": {
"type": "boolean"
},
"assetfare_fee_bps": {
"enum": [
0,
1
],
"type": "number"
},
"minimum_guard_bps": {
"type": "integer",
"maximum": 500,
"minimum": 1
},
"minimum_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"aggregator_api_used": {
"type": "boolean",
"const": false
},
"expected_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"minimum_output_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"expected_output_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"external_intent_protocol": {
"type": "boolean"
}
},
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1
},
"version": {
"type": "string",
"const": "assetfare-direct-route-summary-v1"
},
"step_count": {
"type": "integer",
"maximum": 8,
"minimum": 1
},
"classification": {
"enum": [
"direct_protocol_only",
"external_intent"
],
"type": "string"
},
"server_signing": {
"type": "boolean",
"const": false
},
"assetfare_fee_bps": {
"type": "number",
"const": 1
},
"server_submission": {
"type": "boolean",
"const": false
},
"economic_eligibility": {
"enum": [
"not_asserted_by_capability",
"coverage_only_not_primary"
],
"type": "string"
},
"route_aggregator_used": {
"type": "boolean",
"const": false
},
"product_classification": {
"enum": [
"primary_direct",
"external_coverage_only"
],
"type": "string"
},
"route_minimum_guard_bps": {
"anyOf": [
{
"type": "integer",
"maximum": 500,
"minimum": 1
},
{
"type": "null"
}
]
},
"fee_collection_step_index": {
"type": "integer",
"maximum": 7,
"minimum": 0
},
"public_execution_eligible": {
"type": "boolean"
},
"primary_selection_eligible": {
"type": "boolean"
},
"external_intent_protocol_used": {
"type": "boolean"
},
"provider_internal_dex_aggregation_possible": {
"type": "boolean"
}
},
"additionalProperties": false
},
"verification_context_sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
},
"description": "Strict caller-held context copied from the selected quote and approval. It contains public intent/wallet data only, never the raw session token or a private key, and is required whenever a remote MCP session call can return current_action.",
"additionalProperties": false
}
},
"additionalProperties": false
}{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"session_token",
"session_id",
"idempotency_key",
"transaction_hashes",
"verification_context"
],
"properties": {
"session_id": {
"type": "string",
"format": "uuid",
"description": "V2 workflow session UUID returned by assetfare_v2_session_create. Use only with assetfare_v2_session_* tools; do not pass a legacy session ID."
},
"session_token": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43,128}$",
"description": "Sensitive caller-generated v2 session capability: at least 32 CSPRNG bytes encoded as 43-128 URL-safe base64 characters. Generate it locally; never log it or substitute a private key or legacy access token."
},
"idempotency_key": {
"type": "string",
"maxLength": 128,
"minLength": 8,
"description": "Caller-generated retry key, 8-128 characters. Reuse it only when retrying the same logical mutation; choose a new key for a new operation. Strict approval_v3 requests additionally enforce its ASCII key pattern."
},
"transaction_hashes": {
"type": "array",
"items": {
"type": "string",
"maxLength": 128,
"minLength": 16
},
"maxItems": 8,
"minItems": 1,
"description": "One to eight hashes for source transactions the caller already signed and submitted. Do not provide unsigned payloads or destination hashes."
},
"verification_context": {
"type": "object",
"required": [
"version",
"intent",
"wallets",
"event_signer_public",
"approval_v3",
"direct_route_summary",
"verification_context_sha256"
],
"properties": {
"intent": {
"type": "object",
"required": [
"from_chain",
"from_token",
"to_chain",
"to_token",
"amount_usd"
],
"properties": {
"to_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood"
],
"type": "string",
"description": "Destination chain for the v2 route: Solana, Base, Arbitrum, or Robinhood Chain. Source-only chains are not destinations."
},
"to_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Output token symbol on to_chain. The chain-token pair must appear in current v2 capabilities."
},
"amount_usd": {
"type": "number",
"minimum": 1,
"description": "Requested input value in USD, minimum 1. USD 1 is reachability/schema smoke only. A USD 50 competitive bucket was observed only for dated 2026-09-23 Solana USDC to Base USDC evidence and must not be generalized to another corridor. USD 1,000 is the primary representative amount. SOL input includes a swap. Always quote the actual intended amount."
},
"from_chain": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
],
"type": "string",
"description": "Source chain for the v2 route. Polygon, Optimism, Ethereum, HyperEVM, X Layer, Sei, Sonic, Monad, Avalanche, Cronos, Injective, Linea, Aptos, Unichain, and Ink are source-only and cannot be used as to_chain."
},
"from_token": {
"enum": [
"SOL",
"ETH",
"USDC",
"USDG"
],
"type": "string",
"description": "Input token symbol on from_chain. The chain-token pair must appear in current v2 capabilities."
}
},
"additionalProperties": false
},
"version": {
"type": "string",
"const": "assetfare-session-verification-context-v1"
},
"wallets": {
"type": "object",
"description": "Map each chain needed by this route to the caller's public wallet address. Include public addresses only; never private keys or seed phrases.",
"propertyNames": {
"enum": [
"solana",
"base",
"arbitrum",
"robinhood",
"polygon",
"optimism",
"ethereum",
"hyperevm",
"xlayer",
"sei",
"sonic",
"monad",
"avalanche",
"cronos",
"injective",
"linea",
"aptos",
"unichain",
"ink"
]
},
"additionalProperties": {
"type": "string",
"description": "Caller-owned public wallet address: 0x plus 40 hex characters for EVM, 0x plus 64 hex characters for Aptos, or 32-44 base58 characters for Solana. Never provide secret key material."
}
},
"approval_v3": {
"type": "object",
"required": [
"version",
"quote_id",
"quote_fingerprint",
"selection_status",
"selected_mode",
"maximum_input_base",
"minimum_output_base",
"direct_route_summary_sha256",
"idempotency_key"
],
"properties": {
"version": {
"type": "string",
"const": "assetfare-quote-bound-approval-v3"
},
"quote_id": {
"type": "string",
"format": "uuid"
},
"selected_mode": {
"type": "string",
"const": "session"
},
"idempotency_key": {
"type": "string",
"pattern": "^[A-Za-z0-9._:-]{8,128}$"
},
"selection_status": {
"type": "string",
"const": "selected"
},
"quote_fingerprint": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"maximum_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"minimum_output_base": {
"$ref": "#/properties/verification_context/properties/approval_v3/properties/maximum_input_base"
},
"direct_route_summary_sha256": {
"$ref": "#/properties/verification_context/properties/approval_v3/properties/quote_fingerprint"
}
},
"additionalProperties": false
},
"event_signer_public": {
"anyOf": [
{
"$ref": "#/properties/verification_context/properties/wallets/additionalProperties",
"description": "Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key."
},
{
"type": "null"
}
],
"description": "Solana CCTP only: caller-generated ephemeral public key. Keep the matching private key client-side and use it to co-sign the returned unsigned event-account transaction; never send the private key."
},
"direct_route_summary": {
"type": "object",
"required": [
"version",
"route",
"from",
"to",
"classification",
"mode",
"route_aggregator_used",
"external_intent_protocol_used",
"provider_internal_dex_aggregation_possible",
"assetfare_fee_bps",
"fee_collection_step_index",
"server_signing",
"server_submission",
"step_count",
"steps"
],
"properties": {
"to": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG"
],
"type": "string"
},
"from": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG",
"polygon:USDC",
"optimism:USDC",
"ethereum:USDC",
"hyperevm:USDC",
"xlayer:USDC",
"sei:USDC",
"sonic:USDC",
"monad:USDC",
"avalanche:USDC",
"cronos:USDC",
"injective:USDC",
"linea:USDC",
"aptos:USDC",
"unichain:USDC",
"ink:USDC"
],
"type": "string"
},
"mode": {
"enum": [
"aptos_move_cctp_direct",
"cctp_direct_composition",
"optimism_source_cctp",
"polygon_source_cctp",
"robinhood_across_ingress_composition",
"robinhood_paxos_egress_composition",
"robinhood_paxos_ingress_composition",
"same_chain_direct",
"same_chain_direct_composition"
],
"type": "string"
},
"route": {
"enum": [
"solana:SOL->solana:USDC",
"solana:SOL->solana:USDG",
"solana:SOL->base:ETH",
"solana:SOL->base:USDC",
"solana:SOL->arbitrum:ETH",
"solana:SOL->arbitrum:USDC",
"solana:SOL->robinhood:ETH",
"solana:SOL->robinhood:USDG",
"solana:USDC->solana:SOL",
"solana:USDC->solana:USDG",
"solana:USDC->base:ETH",
"solana:USDC->base:USDC",
"solana:USDC->arbitrum:ETH",
"solana:USDC->arbitrum:USDC",
"solana:USDC->robinhood:ETH",
"solana:USDC->robinhood:USDG",
"solana:USDG->solana:SOL",
"solana:USDG->solana:USDC",
"solana:USDG->base:ETH",
"solana:USDG->base:USDC",
"solana:USDG->arbitrum:ETH",
"solana:USDG->arbitrum:USDC",
"solana:USDG->robinhood:ETH",
"solana:USDG->robinhood:USDG",
"base:ETH->solana:SOL",
"base:ETH->solana:USDC",
"base:ETH->solana:USDG",
"base:ETH->base:USDC",
"base:ETH->arbitrum:ETH",
"base:ETH->arbitrum:USDC",
"base:ETH->robinhood:ETH",
"base:ETH->robinhood:USDG",
"base:USDC->solana:SOL",
"base:USDC->solana:USDC",
"base:USDC->solana:USDG",
"base:USDC->base:ETH",
"base:USDC->arbitrum:ETH",
"base:USDC->arbitrum:USDC",
"base:USDC->robinhood:ETH",
"base:USDC->robinhood:USDG",
"arbitrum:ETH->solana:SOL",
"arbitrum:ETH->solana:USDC",
"arbitrum:ETH->solana:USDG",
"arbitrum:ETH->base:ETH",
"arbitrum:ETH->base:USDC",
"arbitrum:ETH->arbitrum:USDC",
"arbitrum:ETH->robinhood:ETH",
"arbitrum:ETH->robinhood:USDG",
"arbitrum:USDC->solana:SOL",
"arbitrum:USDC->solana:USDC",
"arbitrum:USDC->solana:USDG",
"arbitrum:USDC->base:ETH",
"arbitrum:USDC->base:USDC",
"arbitrum:USDC->arbitrum:ETH",
"arbitrum:USDC->robinhood:ETH",
"arbitrum:USDC->robinhood:USDG",
"robinhood:ETH->solana:SOL",
"robinhood:ETH->solana:USDC",
"robinhood:ETH->solana:USDG",
"robinhood:ETH->base:ETH",
"robinhood:ETH->base:USDC",
"robinhood:ETH->arbitrum:ETH",
"robinhood:ETH->arbitrum:USDC",
"robinhood:ETH->robinhood:USDG",
"robinhood:USDG->solana:SOL",
"robinhood:USDG->solana:USDC",
"robinhood:USDG->solana:USDG",
"robinhood:USDG->base:ETH",
"robinhood:USDG->base:USDC",
"robinhood:USDG->arbitrum:ETH",
"robinhood:USDG->arbitrum:USDC",
"robinhood:USDG->robinhood:ETH",
"polygon:USDC->base:USDC",
"polygon:USDC->arbitrum:USDC",
"optimism:USDC->base:USDC",
"optimism:USDC->arbitrum:USDC",
"ethereum:USDC->solana:USDC",
"ethereum:USDC->base:USDC",
"hyperevm:USDC->solana:USDC",
"hyperevm:USDC->base:USDC",
"xlayer:USDC->solana:USDC",
"xlayer:USDC->base:USDC",
"sei:USDC->solana:USDC",
"sei:USDC->base:USDC",
"sonic:USDC->solana:USDC",
"sonic:USDC->base:USDC",
"monad:USDC->solana:USDC",
"monad:USDC->base:USDC",
"avalanche:USDC->solana:USDC",
"avalanche:USDC->base:USDC",
"cronos:USDC->solana:USDC",
"cronos:USDC->base:USDC",
"injective:USDC->solana:USDC",
"injective:USDC->base:USDC",
"linea:USDC->solana:USDC",
"linea:USDC->base:USDC",
"aptos:USDC->solana:USDC",
"aptos:USDC->base:USDC",
"unichain:USDC->solana:USDC",
"ink:USDC->solana:USDC"
],
"type": "string"
},
"steps": {
"type": "array",
"items": {
"type": "object",
"required": [
"index",
"action",
"provider",
"from",
"to",
"expected_input_base",
"minimum_input_base",
"expected_output_base",
"minimum_output_base",
"assetfare_fee_bps",
"direct_protocol",
"external_intent_protocol",
"aggregator_api_used"
],
"properties": {
"to": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG"
],
"type": "string"
},
"from": {
"enum": [
"solana:SOL",
"solana:USDC",
"solana:USDG",
"base:ETH",
"base:USDC",
"arbitrum:ETH",
"arbitrum:USDC",
"robinhood:ETH",
"robinhood:USDG",
"polygon:USDC",
"optimism:USDC",
"ethereum:USDC",
"hyperevm:USDC",
"xlayer:USDC",
"sei:USDC",
"sonic:USDC",
"monad:USDC",
"avalanche:USDC",
"cronos:USDC",
"injective:USDC",
"linea:USDC",
"aptos:USDC",
"unichain:USDC",
"ink:USDC"
],
"type": "string"
},
"index": {
"type": "integer",
"maximum": 7,
"minimum": 0
},
"action": {
"enum": [
"swap",
"bridge",
"receive"
],
"type": "string"
},
"provider": {
"enum": [
"raydium_clmm",
"orca_whirlpool",
"uniswap_v3",
"circle_cctp",
"circle_cctp_receive",
"paxos_usdg_layerzero_oft",
"across_intent_bridge"
],
"type": "string"
},
"direct_protocol": {
"type": "boolean"
},
"assetfare_fee_bps": {
"enum": [
0,
1
],
"type": "number"
},
"minimum_guard_bps": {
"type": "integer",
"maximum": 500,
"minimum": 1
},
"minimum_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"aggregator_api_used": {
"type": "boolean",
"const": false
},
"expected_input_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"minimum_output_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"expected_output_base": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"external_intent_protocol": {
"type": "boolean"
}
},
"additionalProperties": false
},
"maxItems": 8,
"minItems": 1
},
"version": {
"type": "string",
"const": "assetfare-direct-route-summary-v1"
},
"step_count": {
"type": "integer",
"maximum": 8,
"minimum": 1
},
"classification": {
"enum": [
"direct_protocol_only",
"external_intent"
],
"type": "string"
},
"server_signing": {
"type": "boolean",
"const": false
},
"assetfare_fee_bps": {
"type": "number",
"const": 1
},
"server_submission": {
"type": "boolean",
"const": false
},
"economic_eligibility": {
"enum": [
"not_asserted_by_capability",
"coverage_only_not_primary"
],
"type": "string"
},
"route_aggregator_used": {
"type": "boolean",
"const": false
},
"product_classification": {
"enum": [
"primary_direct",
"external_coverage_only"
],
"type": "string"
},
"route_minimum_guard_bps": {
"anyOf": [
{
"type": "integer",
"maximum": 500,
"minimum": 1
},
{
"type": "null"
}
]
},
"fee_collection_step_index": {
"type": "integer",
"maximum": 7,
"minimum": 0
},
"public_execution_eligible": {
"type": "boolean"
},
"primary_selection_eligible": {
"type": "boolean"
},
"external_intent_protocol_used": {
"type": "boolean"
},
"provider_internal_dex_aggregation_possible": {
"type": "boolean"
}
},
"additionalProperties": false
},
"verification_context_sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
},
"description": "Strict caller-held context copied from the selected quote and approval. It contains public intent/wallet data only, never the raw session token or a private key, and is required whenever a remote MCP session call can return current_action.",
"additionalProperties": false
}
},
"additionalProperties": false
}