{"openapi":"3.1.0","info":{"title":"Vurto AnA — AI n AAVE","version":"1.1.0","description":"Public API for AI agents to execute AAVE DeFi operations (supply, borrow, withdraw, repay, switches, dual swaps, crosschain supply/repay) via Vurto. No API key required. All token amounts are integer strings in raw units (wei-like, using token decimals). Agents must sign and send built transactions onchain. Crosschain operations allow supplying or repaying on a destination chain using funds from a source chain, bridged via Across or USDT0.","contact":{"name":"Vurto","url":"https://vurto.cc"}},"servers":[{"url":"https://ana.vurto.cc/api/v1","description":"Production"}],"paths":{"/health":{"get":{"operationId":"healthCheck","summary":"Health check","description":"Returns API health status.","responses":{"200":{"description":"API is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}}}},"/donator-status":{"post":{"operationId":"getDonatorStatus","summary":"Check donor status and fee profile","description":"Returns whether a wallet is a verified donor (fee-free) or subject to the base 2.5 bps fee. Always call before quote/build to resolve the effective fee.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["walletAddress"],"properties":{"walletAddress":{"type":"string","description":"EVM wallet address (0x-prefixed, 40 hex chars)"},"chainId":{"type":"integer","description":"Chain ID to check donor status on"},"force":{"type":"boolean","description":"Force fresh lookup bypassing cache"}}}}}},"responses":{"200":{"description":"Donor status resolved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DonatorStatusResponse"}}}}}}},"/position":{"post":{"operationId":"getPosition","summary":"Get wallet AAVE positions","description":"Returns supply, borrow, and market asset positions for a wallet across one or all chains. Call before any operation to know available assets and balances.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["walletAddress"],"properties":{"walletAddress":{"type":"string","description":"EVM wallet address"},"chainId":{"type":"integer","description":"Specific chain ID, or omit for all chains"},"marketAddress":{"type":"string","description":"Specific AAVE market address"}}}}}},"responses":{"200":{"description":"Position data","content":{"application/json":{"schema":{"type":"object","description":"Position data keyed by chain ID with supplies, borrows, marketAssets, and summary"}}}}}}},"/wallet/token-balances":{"post":{"operationId":"getWalletTokenBalances","summary":"Get wallet token balances","description":"Returns raw ERC20 balances for specified tokens in a wallet on a given chain.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["walletAddress","chainId","tokens"],"properties":{"walletAddress":{"type":"string"},"chainId":{"type":"integer"},"tokens":{"type":"array","items":{"type":"string","description":"Token contract address"},"description":"Array of token addresses to query"}}}}}},"responses":{"200":{"description":"Token balances","content":{"application/json":{"schema":{"type":"object","properties":{"balances":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of token address → raw balance string"}}}}}}}}},"/build/supply":{"post":{"operationId":"buildSupply","summary":"Build supply transaction","description":"Builds an unsigned transaction to supply (deposit) a token into an AAVE lending pool. The agent must sign and send the returned transaction onchain.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoolActionRequest"}}}},"responses":{"200":{"description":"Unsigned transaction ready to sign","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildTransactionResponse"}}}}}}},"/build/withdraw":{"post":{"operationId":"buildWithdraw","summary":"Build withdraw transaction","description":"Builds an unsigned transaction to withdraw a supplied token from an AAVE lending pool.","requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/PoolActionRequest"},{"type":"object","properties":{"recipient":{"type":"string","description":"Recipient address (defaults to walletAddress)"},"useMaxAmount":{"type":"boolean","description":"Withdraw full balance"}}}]}}}},"responses":{"200":{"description":"Unsigned transaction ready to sign","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildTransactionResponse"}}}}}}},"/build/borrow":{"post":{"operationId":"buildBorrow","summary":"Build borrow transaction","description":"Builds an unsigned transaction to borrow a token from an AAVE lending pool.","requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/PoolActionRequest"},{"type":"object","properties":{"interestRateMode":{"type":"integer","enum":[1,2],"default":2,"description":"1 = stable, 2 = variable (default)"}}}]}}}},"responses":{"200":{"description":"Unsigned transaction ready to sign","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildTransactionResponse"}}}}}}},"/build/repay":{"post":{"operationId":"buildRepay","summary":"Build repay transaction","description":"Builds an unsigned transaction to repay borrowed debt on an AAVE lending pool.","requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/PoolActionRequest"},{"type":"object","properties":{"interestRateMode":{"type":"integer","enum":[1,2],"default":2,"description":"1 = stable, 2 = variable (default)"}}}]}}}},"responses":{"200":{"description":"Unsigned transaction ready to sign","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildTransactionResponse"}}}}}}},"/quote/collateral":{"post":{"operationId":"quoteCollateral","summary":"Quote collateral swap (zap in / switch supplied)","description":"Gets a swap quote for collateral operations: zap-in (swap before supply) or switch supplied position. Returns priceRoute needed for the subsequent build call.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwapQuoteRequest"}}}},"responses":{"200":{"description":"Swap quote with priceRoute","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwapQuoteResponse"}}}}}}},"/quote/debt":{"post":{"operationId":"quoteDebt","summary":"Quote debt swap (switch borrowed)","description":"Gets a swap quote for debt switch operations. Uses destAmount (target debt amount) instead of srcAmount. Returns priceRoute for the build call.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["chainId","walletAddress","userAddress","fromToken","toToken","destAmount"],"properties":{"chainId":{"type":"integer"},"walletAddress":{"type":"string"},"userAddress":{"type":"string"},"fromToken":{"$ref":"#/components/schemas/TokenDescriptor"},"toToken":{"$ref":"#/components/schemas/TokenDescriptor"},"destAmount":{"type":"string","description":"Target amount in raw units (destination token decimals)"},"slippageBps":{"type":"integer","description":"Slippage tolerance in basis points"},"apyPercent":{"type":"number","description":"Current APY percent for debt calculation"}}}}}},"responses":{"200":{"description":"Swap quote with priceRoute","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwapQuoteResponse"}}}}}}},"/build/collateral/paraswap":{"post":{"operationId":"buildCollateralSwap","summary":"Build collateral swap transaction","description":"Builds an unsigned swap transaction for collateral operations (zap-in, switch supplied). Requires priceRoute from a prior /quote/collateral call.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwapBuildRequest"}}}},"responses":{"200":{"description":"Unsigned swap transaction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildTransactionResponse"}}}}}}},"/build/debt/paraswap":{"post":{"operationId":"buildDebtSwap","summary":"Build debt swap transaction","description":"Builds an unsigned swap transaction for debt switch operations. Requires priceRoute from a prior /quote/debt call.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwapBuildRequest"}}}},"responses":{"200":{"description":"Unsigned swap transaction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildTransactionResponse"}}}}}}},"/quote/dual":{"post":{"operationId":"quoteDual","summary":"Quote dual swap (collateral + debt switch)","description":"Gets quotes for both collateral and debt legs of a dual swap in one call. Returns priceRoutes for both legs needed by the dual build endpoint.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DualQuoteRequest"}}}},"responses":{"200":{"description":"Dual swap quote with both priceRoutes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DualQuoteResponse"}}}}}}},"/build/dual/aave-adapter":{"post":{"operationId":"buildDualAaveAdapter","summary":"Build dual swap via AAVE adapter (preferred)","description":"Builds an unsigned dual swap transaction using the on-chain AAVE adapter contract. This is the preferred path. Uses priceRoutes from /quote/dual.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DualBuildRequest"}}}},"responses":{"200":{"description":"Unsigned dual swap transaction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildTransactionResponse"}}}}}}},"/build/dual/executor":{"post":{"operationId":"buildDualExecutor","summary":"Build dual swap via executor (fallback)","description":"Builds an unsigned dual swap transaction using the executor contract. Fallback for chains without the AAVE adapter.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DualBuildRequest"}}}},"responses":{"200":{"description":"Unsigned dual swap transaction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildTransactionResponse"}}}}}}},"/transactions/{transactionId}/send-hash":{"post":{"operationId":"reportTransactionHash","summary":"Report sent transaction hash","description":"After signing and sending a built transaction, report the tx hash for tracking.","parameters":[{"name":"transactionId","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["txHash"],"properties":{"txHash":{"type":"string","description":"0x-prefixed transaction hash"}}}}}},"responses":{"200":{"description":"Hash recorded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionUpdate"}}}}}}},"/transactions/{transactionId}/confirm":{"post":{"operationId":"confirmTransaction","summary":"Confirm transaction success","description":"Report that a transaction was confirmed onchain.","parameters":[{"name":"transactionId","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"gasUsed":{"type":"string"},"actualPaid":{"type":"string"},"srcActualAmount":{"type":"string"},"collectorAmount":{"type":"string"},"priceImplicitUsd":{"type":"string"},"apyPercent":{"type":"number"},"gasPrice":{"type":"string"},"txFee":{"type":"string"}}}}}},"responses":{"200":{"description":"Confirmation recorded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionUpdate"}}}}}}},"/transactions/{transactionId}/reject":{"post":{"operationId":"rejectTransaction","summary":"Report transaction rejection","description":"Report that the user rejected signing the transaction.","parameters":[{"name":"transactionId","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","default":"user_rejected"}}}}}},"responses":{"200":{"description":"Rejection recorded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionUpdate"}}}}}}},"/transactions/{transactionId}/fail":{"post":{"operationId":"reportTransactionFailure","summary":"Report transaction failure","description":"Report that a sent transaction failed onchain.","parameters":[{"name":"transactionId","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","default":"execution_failed"}}}}}},"responses":{"200":{"description":"Failure recorded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionUpdate"}}}}}}},"/transactions/user/{walletAddress}":{"get":{"operationId":"getTransactionHistory","summary":"Get transaction history for a wallet","description":"Returns recent transactions built and tracked for a wallet address.","parameters":[{"name":"walletAddress","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}}],"responses":{"200":{"description":"Transaction list","content":{"application/json":{"schema":{"type":"object","properties":{"transactions":{"type":"array","items":{"type":"object"}}}}}}}}}},"/apy/history":{"get":{"operationId":"getApyHistory","summary":"Get current APY rates for a chain","description":"Returns current supply and borrow APY rates for all AAVE V3 tokens on a given chain, sourced from DeFi Llama bulk endpoints.","parameters":[{"name":"chainId","in":"query","schema":{"type":"integer","default":42161},"description":"Chain ID (137=Polygon, 42161=Arbitrum, 8453=Base, 1=Ethereum, 56=BNB, 100=Gnosis)"}],"responses":{"200":{"description":"Current APY rates per token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApyHistoryResponse"}}}}}}},"/apy/history/rolling":{"get":{"operationId":"getApyHistoryRolling","summary":"Get rolling APY averages with self-collected data","description":"Returns supply and borrow APY averages (30d, 90d, 180d, 365d) per token. Data is sourced from DeFi Llama charts (when available) combined with Vurto's own daily snapshots collected every 12 hours. The self-collected data grows daily toward full 365-day independence.","parameters":[{"name":"chainId","in":"query","schema":{"type":"integer","default":42161},"description":"Chain ID (137=Polygon, 42161=Arbitrum, 8453=Base, 1=Ethereum, 56=BNB, 100=Gnosis)"},{"name":"days","in":"query","schema":{"type":"integer","default":365,"minimum":1,"maximum":365},"description":"Maximum history window in days"}],"responses":{"200":{"description":"Rolling APY averages with collection status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApyRollingResponse"}}}}}}},"/quote/longshot":{"post":{"operationId":"quoteCrosschain","summary":"Quote crosschain supply or repay","description":"Gets a crosschain route quote for supplying or repaying on a destination chain using funds (borrow or withdraw) from a source chain. The bridge providers (Across, USDT0) are auto-selected based on cost and reliability. Returns a quoteId needed for the build call. Quote expires in ~5 minutes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrosschainQuoteRequest"}}}},"responses":{"200":{"description":"Crosschain route quote with selected bridge provider and expected output","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrosschainQuoteResponse"}}}},"422":{"description":"Guardrail or route validation failure (e.g. health factor too low, no valid route, destination reserve frozen)"}}}},"/build/longshot":{"post":{"operationId":"buildCrosschain","summary":"Build crosschain execution from a quote","description":"Builds a full crosschain execution plan from a prior quote. Returns a multi-step execution with source transaction, bridge deposit, and destination transaction. The agent must execute each step sequentially, reporting events via the event endpoint. Non-atomic: each step is a separate onchain tx.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrosschainBuildRequest"}}}},"responses":{"200":{"description":"Multi-step crosschain execution plan with transactions for each step","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrosschainBuildResponse"}}}},"403":{"description":"Quote wallet does not match build wallet"},"404":{"description":"Quote not found"},"410":{"description":"Quote expired"}}}},"/longshot/executions/{executionId}/event":{"post":{"operationId":"reportCrosschainEvent","summary":"Report crosschain execution lifecycle event","description":"Report state transitions during a crosschain execution (source submitted, source confirmed, bridge confirmed, destination submitted, etc.). Used to advance the execution state machine.","parameters":[{"name":"executionId","in":"path","required":true,"schema":{"type":"string"},"description":"Execution ID from build response"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["walletAddress","event"],"properties":{"walletAddress":{"type":"string","description":"Wallet address that owns this execution"},"event":{"type":"string","enum":["source_submitted","source_confirmed","source_failed","bridge_confirmed","bridge_failed","destination_submitted","destination_confirmed","destination_failed"],"description":"Lifecycle event name"},"txHash":{"type":"string","description":"0x-prefixed transaction hash (for submitted/confirmed events)"},"reason":{"type":"string","description":"Optional reason detail"}}}}}},"responses":{"200":{"description":"Event applied, new state returned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrosschainEventResponse"}}}},"422":{"description":"Event not allowed for current execution state"}}}},"/longshot/executions/{executionId}/status":{"get":{"operationId":"getCrosschainStatus","summary":"Get crosschain execution status","description":"Returns the current state, steps, and recoverable actions for a crosschain execution.","parameters":[{"name":"executionId","in":"path","required":true,"schema":{"type":"string"}},{"name":"walletAddress","in":"query","required":true,"schema":{"type":"string"},"description":"Wallet address that owns this execution"}],"responses":{"200":{"description":"Execution status with steps and recoverable actions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrosschainStatusResponse"}}}},"403":{"description":"Execution does not belong to this wallet"},"404":{"description":"Execution not found"}}}},"/longshot/executions/{executionId}/bridge-check":{"get":{"operationId":"checkCrosschainBridge","summary":"Check bridge arrival status","description":"Checks whether the bridged funds have arrived on the destination chain. If arrival is detected, the execution state is auto-transitioned to bridge_confirmed. Poll this endpoint after the source tx confirms and bridge deposit is executed.","parameters":[{"name":"executionId","in":"path","required":true,"schema":{"type":"string"}},{"name":"walletAddress","in":"query","required":true,"schema":{"type":"string"},"description":"Wallet address that owns this execution"}],"responses":{"200":{"description":"Bridge arrival check result","content":{"application/json":{"schema":{"type":"object","properties":{"executionId":{"type":"string"},"bridged":{"type":"boolean","description":"Whether funds have arrived on destination chain"},"provider":{"type":"string","description":"Bridge provider that delivered (across, usdt0)"},"autoConfirmed":{"type":"boolean","description":"Whether state was auto-transitioned to bridge_confirmed"},"newState":{"type":"string","description":"New execution state if auto-confirmed"},"balanceBefore":{"type":"string"},"balanceAfter":{"type":"string"}}}}}}}}},"/longshot/executions/{executionId}/recover":{"post":{"operationId":"recoverCrosschainExecution","summary":"Recover a failed crosschain execution step","description":"Applies a recovery action to a failed crosschain execution. Allowed actions depend on current state: retry_source (on source_failed), retry_bridge (on bridge_failed), retry_destination (on destination_failed), mark_abandoned (on any failed or awaiting state).","parameters":[{"name":"executionId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["walletAddress","action"],"properties":{"walletAddress":{"type":"string","description":"Wallet address that owns this execution"},"action":{"type":"string","enum":["retry_source","retry_bridge","retry_destination","mark_abandoned"],"description":"Recovery action to apply"},"providerOverride":{"type":"string","enum":["across","usdt0"],"description":"Optional: override bridge provider for retry"}}}}}},"responses":{"200":{"description":"Recovery applied, new state returned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrosschainEventResponse"}}}},"422":{"description":"Recovery action not allowed for current state"}}}}},"components":{"schemas":{"TokenDescriptor":{"type":"object","required":["address","decimals","symbol"],"properties":{"address":{"type":"string","description":"ERC20 token contract address (0x-prefixed)"},"decimals":{"type":"integer","description":"Token decimals (e.g. 6 for USDC, 18 for WETH)"},"symbol":{"type":"string","description":"Token symbol (e.g. USDC, WETH)"}}},"PoolActionRequest":{"type":"object","required":["chainId","walletAddress","token","amount"],"properties":{"chainId":{"type":"integer","description":"Chain ID (e.g. 137 for Polygon, 42161 for Arbitrum)"},"walletAddress":{"type":"string","description":"Wallet address executing the action"},"poolAddress":{"type":"string","description":"AAVE pool contract address"},"token":{"$ref":"#/components/schemas/TokenDescriptor"},"amount":{"type":"string","description":"Amount in raw units (token decimals)"},"onBehalfOf":{"type":"string","description":"Execute on behalf of another address"}}},"SwapQuoteRequest":{"type":"object","required":["chainId","walletAddress","userAddress","fromToken","toToken","srcAmount"],"properties":{"chainId":{"type":"integer"},"walletAddress":{"type":"string"},"userAddress":{"type":"string","description":"Address that will execute the swap (usually same as walletAddress)"},"fromToken":{"$ref":"#/components/schemas/TokenDescriptor"},"toToken":{"$ref":"#/components/schemas/TokenDescriptor"},"srcAmount":{"type":"string","description":"Source amount in raw units"},"slippageBps":{"type":"integer","description":"Slippage tolerance in basis points (e.g. 3 = 0.03%)"}}},"SwapBuildRequest":{"type":"object","required":["chainId","walletAddress","userAddress","fromToken","toToken","priceRoute"],"properties":{"chainId":{"type":"integer"},"walletAddress":{"type":"string"},"userAddress":{"type":"string"},"fromToken":{"$ref":"#/components/schemas/TokenDescriptor"},"toToken":{"$ref":"#/components/schemas/TokenDescriptor"},"srcAmount":{"type":"string"},"destAmount":{"type":"string"},"priceRoute":{"type":"object","description":"Price route object from the quote response"},"slippageBps":{"type":"integer"},"isMaxSwap":{"type":"boolean","description":"Whether this is a max-amount swap"}}},"DualQuoteRequest":{"type":"object","required":["chainId","walletAddress","userAddress","collateral","debt"],"properties":{"chainId":{"type":"integer"},"walletAddress":{"type":"string"},"userAddress":{"type":"string"},"collateral":{"type":"object","required":["fromToken","toToken","srcAmount"],"properties":{"fromToken":{"$ref":"#/components/schemas/TokenDescriptor"},"toToken":{"$ref":"#/components/schemas/TokenDescriptor"},"srcAmount":{"type":"string"},"slippageBps":{"type":"integer"}}},"debt":{"type":"object","required":["fromToken","toToken","destAmount"],"properties":{"fromToken":{"$ref":"#/components/schemas/TokenDescriptor"},"toToken":{"$ref":"#/components/schemas/TokenDescriptor"},"destAmount":{"type":"string"},"slippageBps":{"type":"integer"},"apyPercent":{"type":"number"}}}}},"DualBuildRequest":{"type":"object","required":["chainId","walletAddress"],"properties":{"chainId":{"type":"integer"},"walletAddress":{"type":"string"},"userAddress":{"type":"string"},"recipient":{"type":"string"},"collateral":{"type":"object","properties":{"fromToken":{"$ref":"#/components/schemas/TokenDescriptor"},"toToken":{"$ref":"#/components/schemas/TokenDescriptor"},"srcAmount":{"type":"string"},"priceRoute":{"type":"object"},"slippageBps":{"type":"integer"}}},"debt":{"type":"object","properties":{"fromToken":{"$ref":"#/components/schemas/TokenDescriptor"},"toToken":{"$ref":"#/components/schemas/TokenDescriptor"},"destAmount":{"type":"string"},"priceRoute":{"type":"object"},"slippageBps":{"type":"integer"}}}}},"BuildTransactionResponse":{"type":"object","properties":{"to":{"type":"string","description":"Contract address to send the transaction to"},"data":{"type":"string","description":"Encoded calldata (0x-prefixed hex)"},"value":{"type":"string","description":"Native token value to send (usually '0')"},"transactionId":{"type":"integer","description":"Backend transaction ID for lifecycle tracking"},"feeBps":{"type":"number","description":"Effective fee in basis points (0 for donors)"},"feeAmount":{"type":"string","description":"Fee amount in raw token units"},"_meta":{"type":"object","properties":{"backend":{"type":"string"},"mode":{"type":"string"},"configuredFeeBps":{"type":"number"},"donator":{"type":"object"},"donatorPolicy":{"type":"object"}}}}},"SwapQuoteResponse":{"type":"object","properties":{"priceRoute":{"type":"object","description":"Opaque price route to pass to the build endpoint"},"srcAmount":{"type":"string"},"destAmount":{"type":"string"},"feeBps":{"type":"number"},"feePercent":{"type":"number"},"discountPercent":{"type":"number"}}},"DualQuoteResponse":{"type":"object","properties":{"collateral":{"type":"object","description":"Collateral leg quote with priceRoute"},"debt":{"type":"object","description":"Debt leg quote with priceRoute"},"feeBps":{"type":"number"},"feePercent":{"type":"number"},"discountPercent":{"type":"number"}}},"DonatorStatusResponse":{"type":"object","properties":{"donator":{"type":"object","properties":{"isDonator":{"type":"boolean"},"discountPercent":{"type":"number"},"validUntil":{"type":"string","format":"date-time"},"activeTierMinUsd":{"type":"number"},"activeTierValidityDays":{"type":"integer"}}},"donatorPolicy":{"type":"object","properties":{"minimumDonationUsd":{"type":"number"},"walletAddressByChain":{"type":"object","additionalProperties":{"type":"string"}}}}}},"TransactionUpdate":{"type":"object","properties":{"ok":{"type":"boolean"},"transaction":{"type":"object","description":"Updated transaction record"}}},"ApyHistoryResponse":{"type":"object","properties":{"chainId":{"type":"integer"},"chain":{"type":"string"},"updatedAt":{"type":"string","format":"date-time"},"source":{"type":"string","description":"Data source identifier (e.g. defillama)"},"tokens":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ApyTokenEntry"},"description":"Map of token address → APY data. Includes symbol aliases like 'symbol:USDC' for unique tokens."}}},"ApyRollingResponse":{"type":"object","properties":{"chainId":{"type":"integer"},"chain":{"type":"string"},"updatedAt":{"type":"string","format":"date-time"},"source":{"type":"string","description":"Data source: vurto_collected, defillama+vurto_collected, or defillama+rolling_chart"},"requestedDays":{"type":"integer"},"maxWindowDays":{"type":"integer"},"tokens":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ApyRollingTokenEntry"},"description":"Map of token address → rolling APY data with averages"},"collection":{"$ref":"#/components/schemas/ApyCollectionStatus"}}},"ApyTokenEntry":{"type":"object","properties":{"pool":{"type":"string","description":"DeFi Llama pool ID"},"symbol":{"type":"string"},"chain":{"type":"string"},"underlyingToken":{"type":"string"},"supply":{"type":"object","properties":{"current":{"type":"number","description":"Current supply APY %"},"avg30d":{"type":"number","description":"30-day average supply APY %"}}},"borrow":{"type":"object","properties":{"current":{"type":"number","description":"Current borrow APY %"}}}}},"ApyRollingTokenEntry":{"type":"object","properties":{"pool":{"type":"string","nullable":true},"symbol":{"type":"string"},"chain":{"type":"string"},"underlyingToken":{"type":"string"},"coverageDays":{"type":"integer","description":"Max coverage days across supply and borrow"},"supplyCoverageDays":{"type":"integer","description":"Days of supply APY history available"},"borrowCoverageDays":{"type":"integer","description":"Days of borrow APY history (from Vurto self-collection)"},"supply":{"type":"object","properties":{"current":{"type":"number"},"avg30d":{"type":"number","nullable":true},"avg90d":{"type":"number","nullable":true},"avg180d":{"type":"number","nullable":true},"avg365d":{"type":"number","nullable":true},"avgCoverage":{"type":"number","description":"Average over all available days"}}},"borrow":{"type":"object","properties":{"current":{"type":"number"},"avg30d":{"type":"number","nullable":true},"avg90d":{"type":"number","nullable":true},"avg180d":{"type":"number","nullable":true},"avg365d":{"type":"number","nullable":true},"avgCoverage":{"type":"number","description":"Average over all available days"}}}}},"ApyCollectionStatus":{"type":"object","description":"Status of Vurto's independent APY rate collection. Rates are collected every 12 hours.","properties":{"collectedDays":{"type":"integer","description":"Number of unique daily snapshots collected"},"oldestSnapshot":{"type":"string","nullable":true,"description":"Oldest snapshot date (YYYY-MM-DD)"},"newestSnapshot":{"type":"string","nullable":true,"description":"Most recent snapshot date (YYYY-MM-DD)"},"notice":{"type":"string","description":"Human-readable collection status message"}}},"CrosschainQuoteRequest":{"type":"object","required":["walletAddress","intent","sourceChainId","destinationChainId","sourceFunding","destinationAction"],"properties":{"walletAddress":{"type":"string","description":"EVM wallet address executing the crosschain operation"},"intent":{"type":"string","enum":["supply","repay"],"description":"What to do on the destination chain"},"sourceChainId":{"type":"integer","description":"Chain ID to source funds from (borrow or withdraw)"},"destinationChainId":{"type":"integer","description":"Chain ID where supply/repay will be executed"},"sourceFunding":{"$ref":"#/components/schemas/CrosschainSourceFunding"},"destinationAction":{"$ref":"#/components/schemas/CrosschainDestinationAction"},"slippageBps":{"type":"integer","default":30,"description":"Slippage tolerance in basis points (1-1000)"},"providerOverride":{"type":"string","enum":["across","usdt0"],"description":"Optional: force a specific bridge provider"}}},"CrosschainSourceFunding":{"type":"object","required":["mode","token","amount","poolAddress","projectedSourceHealthFactor"],"properties":{"mode":{"type":"string","enum":["borrow","borrow_stable","withdraw","withdraw_and_zap_out"],"description":"How to obtain funds on source chain"},"token":{"$ref":"#/components/schemas/TokenDescriptor"},"amount":{"type":"string","description":"Amount in raw units (token decimals)"},"poolAddress":{"type":"string","description":"AAVE pool contract address on source chain"},"projectedSourceHealthFactor":{"type":"number","description":"Expected health factor after source action (must be >= ~1.08)"},"interestRateMode":{"type":"integer","enum":[1,2],"default":2,"description":"1 = stable, 2 = variable (for borrow modes)"}}},"CrosschainDestinationAction":{"type":"object","required":["token","amount","poolAddress"],"properties":{"token":{"$ref":"#/components/schemas/TokenDescriptor"},"amount":{"type":"string","description":"Amount in raw units (destination token decimals)"},"poolAddress":{"type":"string","description":"AAVE pool contract address on destination chain"},"interestRateMode":{"type":"integer","enum":[1,2],"default":2,"description":"1 = stable, 2 = variable (for repay intent)"}}},"CrosschainQuoteResponse":{"type":"object","properties":{"quoteId":{"type":"string","description":"Unique quote ID to pass to /build/longshot"},"walletAddress":{"type":"string"},"intent":{"type":"string","enum":["supply","repay"]},"sourceChainId":{"type":"integer"},"destinationChainId":{"type":"integer"},"donator":{"$ref":"#/components/schemas/DonatorStatusResponse"},"selectedRoute":{"type":"object","properties":{"provider":{"type":"string","enum":["across","usdt0"],"description":"Selected bridge provider"},"expectedReceived":{"type":"string","description":"Expected amount received on destination chain (raw units)"},"totalFeesUsd":{"type":"number","description":"Total bridge + provider fees in USD"},"expectedFillTimeSec":{"type":"integer","description":"Expected bridge fill time in seconds"},"stableAsset":{"type":"string","description":"Stable token symbol used for bridging (e.g. USDC)"}}},"routeCandidates":{"type":"array","items":{"type":"object"},"description":"All evaluated route candidates with availability and fees"},"needsZapIn":{"type":"boolean","description":"Whether a swap is needed on destination before final action"},"needsZapOut":{"type":"boolean","description":"Whether a swap is needed on source before bridging"},"expectedReceived":{"type":"string"},"totalFeesUsd":{"type":"number"},"expectedFillTimeSec":{"type":"integer"},"expiresAt":{"type":"string","format":"date-time","description":"Quote expiration timestamp"},"guardrails":{"type":"object","properties":{"source":{"type":"object","description":"Source health factor guardrail result"},"destination":{"type":"object","description":"Destination reserve status guardrail result"}}}}},"CrosschainBuildRequest":{"type":"object","required":["quoteId","walletAddress"],"properties":{"quoteId":{"type":"string","description":"Quote ID from /quote/longshot response"},"walletAddress":{"type":"string","description":"Same wallet address used in the quote"},"providerOverride":{"type":"string","enum":["across","usdt0"],"description":"Optional: override bridge provider"}}},"CrosschainBuildResponse":{"type":"object","properties":{"executionId":{"type":"string","description":"Unique execution ID for status/event/recover tracking"},"quoteId":{"type":"string"},"walletAddress":{"type":"string"},"state":{"type":"string","description":"Current execution state (starts as awaiting_source_signature)"},"currentStep":{"type":"string","enum":["source","bridge","destination"],"description":"Which step is active"},"nonAtomic":{"type":"boolean","description":"Always true — each step is a separate onchain tx"},"steps":{"type":"array","description":"Ordered execution steps: source (borrow/withdraw), bridge (approve+deposit), destination (supply/repay)","items":{"$ref":"#/components/schemas/CrosschainStep"}},"statusUrl":{"type":"string","description":"URL to poll for execution status"},"recoverUrl":{"type":"string","description":"URL to post recovery actions"},"recoverableActions":{"type":"array","items":{"type":"string"},"description":"Currently available recovery actions"},"needsZapIn":{"type":"boolean"},"needsZapOut":{"type":"boolean"},"updatedAt":{"type":"string","format":"date-time"}}},"CrosschainStep":{"type":"object","properties":{"id":{"type":"string","enum":["source","bridge","destination"],"description":"Step identifier"},"chainId":{"type":"integer","description":"Chain where this step executes"},"status":{"type":"string","enum":["awaiting_signature","pending","submitted","confirmed","failed","blocked"],"description":"Step status"},"tx":{"$ref":"#/components/schemas/BuildTransactionResponse"},"provider":{"type":"string","description":"Bridge provider (bridge step only)"},"swapApproveTx":{"type":"object","description":"Zap-out swap approval tx (bridge step, if needed)"},"swapTx":{"type":"object","description":"Zap-out swap tx (bridge step, if needed)"},"approveTx":{"type":"object","description":"Bridge token approval tx (bridge step)"},"depositTx":{"type":"object","description":"Bridge deposit tx (bridge step)"},"bridgeFeeTransfer":{"type":"object","description":"Fee transfer details for non-donors (bridge step). Execute ERC20 transfer before deposit.","properties":{"receiver":{"type":"string","description":"Fee receiver address"},"feeBps":{"type":"number","description":"Fee in basis points (2.5 for non-donors, 0 for donors)"}}},"reason":{"type":"string","description":"Reason for blocked steps (e.g. zap_in_required_before_destination)"}}},"CrosschainEventResponse":{"type":"object","properties":{"ok":{"type":"boolean"},"executionId":{"type":"string"},"state":{"type":"string","description":"New execution state after event"},"currentStep":{"type":"string"},"recoverableActions":{"type":"array","items":{"type":"string"}},"updatedAt":{"type":"string","format":"date-time"}}},"CrosschainStatusResponse":{"type":"object","properties":{"executionId":{"type":"string"},"owner":{"type":"string","description":"Wallet address that owns this execution"},"state":{"type":"string"},"currentStep":{"type":"string"},"steps":{"type":"array","items":{"$ref":"#/components/schemas/CrosschainStep"}},"recoverableActions":{"type":"array","items":{"type":"string"}},"updatedAt":{"type":"string","format":"date-time"}}}}}}