{ "openapi": "3.0.0", "paths": { "/intents": { "post": { "description": "Creates a new payment intent with cross-chain transfer parameters", "operationId": "IntentController_createIntent", "parameters": [], "requestBody": { "required": true, "description": "Intent creation parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateIntentDto" }, "examples": { "Ethereum to Starknet": { "value": { "sender": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "amount": "1000000", "amountSymbol": "USDC", "tokenIn": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "source_chain": "ETHEREUM_MAINNET", "destination_chain": "STARKNET_MAINNET", "recipient": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "refund_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "metadata": { "orderId": "12345" } } } } } } }, "responses": { "201": { "description": "Intent successfully created", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "number", "example": 2 }, "client_id": { "type": "string", "example": "e1ee3675-cb26-4a76-8206-a84f86e85862" }, "sender": { "type": "string", "example": "0xdA3ECb2E5362295E2b802669dD47127A61d9Ce54" }, "initialAmount": { "type": "string", "example": "1000000" }, "fees_in_usd": { "type": "string", "example": "500" }, "app_fee_in_usd": { "type": "string", "example": "1000" }, "total_amount_in_usd": { "type": "string", "example": "1010500" }, "total_amount_in_asset_token": { "type": "string", "example": "1000500" }, "fees_in_asset_token": { "type": "string", "example": "500" }, "app_fee_in_asset_token": { "type": "string", "example": "0" }, "asset_token_symbol": { "type": "string", "example": "USDC" }, "asset_token_decimals": { "type": "number", "example": 6 }, "slippage": { "type": "string", "example": "0.5" }, "tokenIn": { "type": "string", "example": "0x036CbD53842c5426634e7929541eC2318f3dCF7e" }, "tokenOut": { "type": "string", "example": "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d" }, "intent_address": { "type": "string", "description": "Solana: intent PDA — show to users for QR/Send; transfer tokenIn here (wallet derives deposit ATA). EVM/Starknet: contract address.", "example": "0x4E60e01263E750eD9D087157e19D2480Fd86A900" }, "source_chain": { "type": "string", "example": "BASE_TESTNET" }, "destination_chain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "recipient": { "type": "string", "example": "0xb79541Be080a59fdcE6C0b43219ba56c725eC65e" }, "refund_address": { "type": "string", "example": "0xb79541Be080a59fdcE6C0b43219ba56c725eC65e" }, "relayer": { "type": "string", "example": "" }, "coordinator": { "type": "string", "example": "0x989f47053F188778575113DcF39dB8960Fc450e2" }, "bridger": { "type": "string", "example": "0xa1c943058a631D5506eb7d96036eAbF6968e2338" }, "bridgeExtraData": { "type": "string", "example": "0x00000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000003e8000000000000000000000000000000000000000000000000000000000000000300000000000000000000000075faf114eafb1bdbe2f0316df893fd58ce46aa4d" }, "intent_nonce": { "type": "number", "example": 4267684716645197 }, "intent_status": { "type": "string", "example": "PENDING", "enum": [ "PENDING", "PROCESSING", "COMPLETED", "FAILED" ] }, "tx_hash": { "type": "string", "nullable": true, "example": null }, "needs_relay": { "type": "boolean", "example": false }, "expires_at": { "type": "string", "format": "date-time", "example": "2025-11-11T02:31:23.000Z" }, "metadata": { "type": "object", "example": { "priority": "normal", "description": "Cross-chain USDC transfer" } }, "created_at": { "type": "string", "format": "date-time", "example": "2025-11-11T01:31:23.390Z" }, "updated_at": { "type": "string", "format": "date-time", "example": "2025-11-11T01:31:23.390Z" } } } } } }, "400": { "description": "Bad Request - Invalid parameters" }, "401": { "description": "Unauthorized - Invalid or missing API key" } }, "security": [ { "api-key": [] } ], "summary": "Create new intent", "tags": [ "Intents" ] }, "get": { "description": "Retrieves all intents for the authenticated client with pagination and optional status filtering", "operationId": "IntentController_getAllIntents", "parameters": [ { "name": "limit", "required": false, "in": "query", "description": "Number of intents to return (default: 50, max: 100)", "schema": { "type": "number" } }, { "name": "offset", "required": false, "in": "query", "description": "Number of intents to skip (default: 0)", "schema": { "type": "number" } }, { "name": "status", "required": false, "in": "query", "description": "Filter by intent status", "schema": { "enum": [ "pending", "processing", "completed", "failed" ], "type": "string" } } ], "responses": { "200": { "description": "List of intents retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "intents": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "number", "example": 1 }, "client_id": { "type": "string", "example": "e1ee3675-cb26-4a76-8206-a84f86e85862" }, "sender": { "type": "string", "example": "0xdA3ECb2E5362295E2b802669dD47127A61d9Ce54" }, "initialAmount": { "type": "string", "example": "1000000" }, "fees_in_usd": { "type": "string", "example": "10500" }, "app_fee_in_usd": { "type": "string", "example": "1000" }, "total_amount_in_usd": { "type": "string", "example": "1010500" }, "total_amount_in_asset_token": { "type": "string", "example": "1000500" }, "fees_in_asset_token": { "type": "string", "example": "500" }, "app_fee_in_asset_token": { "type": "string", "example": "0" }, "asset_token_symbol": { "type": "string", "example": "USDC" }, "asset_token_decimals": { "type": "number", "example": 6 }, "slippage": { "type": "string", "example": "0.5" }, "tokenIn": { "type": "string", "example": "0x036CbD53842c5426634e7929541eC2318f3dCF7e" }, "tokenOut": { "type": "string", "example": "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d" }, "intent_address": { "type": "string", "example": "0x4E60e01263E750eD9D087157e19D2480Fd86A900" }, "destination_intent_address": { "type": "string", "example": "0x5F70e12374E750fE0E087158f29E3591Ge97B011" }, "source_chain": { "type": "string", "example": "BASE_TESTNET" }, "destination_chain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "recipient": { "type": "string", "example": "0xb79541Be080a59fdcE6C0b43219ba56c725eC65e" }, "refund_address": { "type": "string", "example": "0xb79541Be080a59fdcE6C0b43219ba56c725eC65e" }, "relayer": { "type": "string", "example": "" }, "coordinator": { "type": "string", "example": "0x989f47053F188778575113DcF39dB8960Fc450e2" }, "bridger": { "type": "string", "example": "0xa1c943058a631D5506eb7d96036eAbF6968e2338" }, "bridgeExtraData": { "type": "string", "example": "0x00000000000000000000000000000000000000000000000000000000000001f4" }, "intent_nonce": { "type": "number", "example": 4267684716645197 }, "intent_status": { "type": "string", "enum": [ "PENDING", "FUNDED", "INITIATED", "COMPLETED", "EXPIRED" ], "example": "PENDING" }, "tx_hash": { "type": "string", "nullable": true, "example": null }, "needs_relay": { "type": "boolean", "example": false }, "relayer_claimed": { "type": "boolean", "example": false }, "paymaster_used": { "type": "boolean", "example": false }, "mode": { "type": "string", "enum": [ "test", "live" ], "example": "test" }, "expires_at": { "type": "string", "format": "date-time", "example": "2025-12-13T03:31:23.000Z" }, "metadata": { "type": "object", "example": { "orderId": "12345" } }, "created_at": { "type": "string", "format": "date-time", "example": "2025-12-13T02:31:23.390Z" }, "updated_at": { "type": "string", "format": "date-time", "example": "2025-12-13T02:31:23.390Z" } } } }, "total": { "type": "number", "example": 100 }, "limit": { "type": "number", "example": 50 }, "offset": { "type": "number", "example": 0 } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get all client intents", "tags": [ "Intents" ] } }, "/intents/{id}": { "get": { "description": "Retrieves information about a specific intent using its unique id", "operationId": "IntentController_getIntent", "parameters": [ { "name": "id", "required": true, "in": "path", "description": "Unique id of the intent", "schema": { "example": 6, "type": "string" } } ], "responses": { "200": { "description": "Intent details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "number", "example": 6 }, "client_id": { "type": "string", "example": "e1ee3675-cb26-4a76-8206-a84f86e85862" }, "sender": { "type": "string", "example": "0xdA3ECb2E5362295E2b802669dD47127A61d9Ce54" }, "initialAmount": { "type": "string", "example": "1000000" }, "fees": { "type": "string", "example": "10500" }, "app_fee_in_usd": { "type": "string", "example": "1000" }, "total_amount_in_usd": { "type": "string", "example": "1010500" }, "total_amount_in_asset_token": { "type": "string", "example": "1000500" }, "fees_in_asset_token": { "type": "string", "example": "500" }, "app_fee_in_asset_token": { "type": "string", "example": "0" }, "asset_token_symbol": { "type": "string", "example": "USDC" }, "asset_token_decimals": { "type": "number", "example": 6 }, "slippage": { "type": "string", "example": "0.5" }, "tokenIn": { "type": "string", "example": "0x036CbD53842c5426634e7929541eC2318f3dCF7e" }, "tokenOut": { "type": "string", "example": "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d" }, "intent_address": { "type": "string", "description": "Solana: intent PDA — show to users for QR/Send; transfer tokenIn here (wallet derives deposit ATA). EVM/Starknet: contract address.", "example": "0x4E60e01263E750eD9D087157e19D2480Fd86A900" }, "deposit_token_account": { "type": "string", "description": "Solana only: ATA(mint, intent PDA). Indexer and recovery only — do not use for QR/Send; fund via intent_address instead.", "example": "DX8aM33XqJqZqZqZqJqZqZqZqJqZqZqZqJqZqZqZqJqZ" }, "destination_intent_address": { "type": "string", "example": "0x5F70e12374E750fE0E087158f29E3591Ge97B011" }, "source_chain": { "type": "string", "example": "BASE_TESTNET" }, "destination_chain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "recipient": { "type": "string", "example": "0xb79541Be080a59fdcE6C0b43219ba56c725eC65e" }, "refund_address": { "type": "string", "example": "0xb79541Be080a59fdcE6C0b43219ba56c725eC65e" }, "relayer": { "type": "string", "example": "" }, "coordinator": { "type": "string", "example": "0x989f47053F188778575113DcF39dB8960Fc450e2" }, "bridger": { "type": "string", "example": "0xa1c943058a631D5506eb7d96036eAbF6968e2338" }, "bridgeExtraData": { "type": "string", "example": "0x00000000000000000000000000000000000000000000000000000000000001f4" }, "intent_nonce": { "type": "number", "example": 4267684716645197 }, "intent_status": { "type": "string", "enum": [ "PENDING", "FUNDED", "INITIATED", "COMPLETED", "EXPIRED" ], "example": "PENDING" }, "tx_hash": { "type": "string", "nullable": true, "example": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" }, "needs_relay": { "type": "boolean", "example": false }, "relayer_claimed": { "type": "boolean", "example": false }, "paymaster_used": { "type": "boolean", "example": false }, "mode": { "type": "string", "enum": [ "test", "live" ], "example": "test" }, "expires_at": { "type": "string", "format": "date-time", "example": "2025-12-13T03:31:23.000Z" }, "metadata": { "type": "object", "example": { "orderId": "12345" } }, "created_at": { "type": "string", "format": "date-time", "example": "2025-12-13T02:31:23.390Z" }, "updated_at": { "type": "string", "format": "date-time", "example": "2025-12-13T02:31:23.390Z" } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } }, "404": { "description": "Intent not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 404 }, "message": { "type": "string", "example": "Intent not found" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get intent by ID", "tags": [ "Intents" ] } }, "/intents/{id}/status": { "patch": { "description": "Updates the status of an existing intent", "operationId": "IntentController_updateIntentStatus", "parameters": [ { "name": "id", "required": true, "in": "path", "description": "Intent unique identifier", "schema": { "example": 6, "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "PENDING", "FUNDED", "INITIATED", "COMPLETED", "EXPIRED" ], "description": "New status to set for the intent", "example": "COMPLETED" } }, "required": [ "status" ] } } } }, "responses": { "200": { "description": "Intent status updated successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "number", "example": 6 }, "client_id": { "type": "string", "example": "e1ee3675-cb26-4a76-8206-a84f86e85862" }, "sender": { "type": "string", "example": "0xdA3ECb2E5362295E2b802669dD47127A61d9Ce54" }, "initialAmount": { "type": "string", "example": "1000000" }, "fees_in_usd": { "type": "string", "example": "10500" }, "app_fee_in_usd": { "type": "string", "example": "1000" }, "total_amount_in_usd": { "type": "string", "example": "1010500" }, "total_amount_in_asset_token": { "type": "string", "example": "1000500" }, "fees_in_asset_token": { "type": "string", "example": "500" }, "app_fee_in_asset_token": { "type": "string", "example": "0" }, "asset_token_symbol": { "type": "string", "example": "USDC" }, "asset_token_decimals": { "type": "number", "example": 6 }, "slippage": { "type": "string", "example": "0.5" }, "tokenIn": { "type": "string", "example": "0x036CbD53842c5426634e7929541eC2318f3dCF7e" }, "tokenOut": { "type": "string", "example": "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d" }, "intent_address": { "type": "string", "description": "Solana: intent PDA — show to users for QR/Send; transfer tokenIn here (wallet derives deposit ATA). EVM/Starknet: contract address.", "example": "0x4E60e01263E750eD9D087157e19D2480Fd86A900" }, "deposit_token_account": { "type": "string", "description": "Solana only: ATA(mint, intent PDA). Indexer and recovery only — do not use for QR/Send; fund via intent_address instead.", "example": "DX8aM33XqJqZqZqZqJqZqZqZqJqZqZqZqJqZqZqZqJqZ" }, "destination_intent_address": { "type": "string", "example": "0x5F70e12374E750fE0E087158f29E3591Ge97B011" }, "source_chain": { "type": "string", "example": "BASE_TESTNET" }, "destination_chain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "recipient": { "type": "string", "example": "0xb79541Be080a59fdcE6C0b43219ba56c725eC65e" }, "refund_address": { "type": "string", "example": "0xb79541Be080a59fdcE6C0b43219ba56c725eC65e" }, "relayer": { "type": "string", "example": "" }, "coordinator": { "type": "string", "example": "0x989f47053F188778575113DcF39dB8960Fc450e2" }, "bridger": { "type": "string", "example": "0xa1c943058a631D5506eb7d96036eAbF6968e2338" }, "bridgeExtraData": { "type": "string", "example": "0x00000000000000000000000000000000000000000000000000000000000001f4" }, "intent_nonce": { "type": "number", "example": 4267684716645197 }, "intent_status": { "type": "string", "enum": [ "PENDING", "FUNDED", "INITIATED", "COMPLETED", "EXPIRED" ], "example": "COMPLETED" }, "tx_hash": { "type": "string", "example": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" }, "needs_relay": { "type": "boolean", "example": false }, "relayer_claimed": { "type": "boolean", "example": true }, "paymaster_used": { "type": "boolean", "example": false }, "mode": { "type": "string", "enum": [ "test", "live" ], "example": "test" }, "expires_at": { "type": "string", "format": "date-time", "example": "2025-12-13T03:31:23.000Z" }, "metadata": { "type": "object", "example": { "orderId": "12345" } }, "created_at": { "type": "string", "format": "date-time", "example": "2025-12-13T02:31:23.390Z" }, "updated_at": { "type": "string", "format": "date-time", "example": "2025-12-13T02:40:05.550Z" } } } } } }, "400": { "description": "Bad Request - Invalid status value", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 400 }, "message": { "type": "string", "example": "Invalid status value" } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } }, "404": { "description": "Intent not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 404 }, "message": { "type": "string", "example": "Intent not found" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Update intent status", "tags": [ "Intents" ] } }, "/intents/{intentAddress}/refund": { "post": { "description": "Manually refunds an expired intent for the authenticated client. This is an escape hatch for recovering stuck funds when automation fails.", "operationId": "IntentController_refundExpiredIntent", "parameters": [ { "name": "intentAddress", "required": true, "in": "path", "description": "The blockchain address of the intent", "schema": { "example": "0x1234567890abcdef1234567890abcdef12345678", "type": "string" } } ], "responses": { "200": { "description": "Refund attempted", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Refund successful" }, "txHash": { "type": "string", "nullable": true, "example": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Refund an expired intent", "tags": [ "Intents" ] } }, "/intents/{intentAddress}/trigger-processing": { "post": { "description": "Triggers manual processing of an intent. Checks funding status, starts the intent if needed, and initiates completion flow. Use this as a fallback when the indexer misses the funding event.", "operationId": "IntentController_triggerIntentProcessing", "parameters": [ { "name": "intentAddress", "required": true, "in": "path", "description": "The blockchain address of the intent", "schema": { "example": "0x1234567890abcdef1234567890abcdef12345678", "type": "string" } } ], "responses": { "200": { "description": "Intent processing triggered successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Intent started successfully" } } } } } }, "400": { "description": "Invalid intent status or not funded", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "Intent has invalid status: COMPLETED" } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } }, "404": { "description": "Intent not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "Intent not found" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Manually trigger intent processing", "tags": [ "Intents" ] } }, "/intents/address/{address}": { "get": { "description": "Retrieves an intent using its contract address", "operationId": "IntentController_getIntentByAddress", "parameters": [ { "name": "address", "required": true, "in": "path", "description": "Intent contract address", "schema": { "example": "0x4E60e01263E750eD9D087157e19D2480Fd86A900", "type": "string" } } ], "responses": { "200": { "description": "Intent retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "number", "example": 3 }, "client_id": { "type": "string", "example": "e1ee3675-cb26-4a76-8206-a84f86e85862" }, "sender": { "type": "string", "example": "0xdA3ECb2E5362295E2b802669dD47127A61d9Ce54" }, "initialAmount": { "type": "string", "example": "1000000" }, "fees_in_usd": { "type": "string", "example": "10500" }, "app_fee_in_usd": { "type": "string", "example": "1000" }, "total_amount_in_usd": { "type": "string", "example": "1010500" }, "total_amount_in_asset_token": { "type": "string", "example": "1000500" }, "fees_in_asset_token": { "type": "string", "example": "500" }, "app_fee_in_asset_token": { "type": "string", "example": "0" }, "asset_token_symbol": { "type": "string", "example": "USDC" }, "asset_token_decimals": { "type": "number", "example": 6 }, "slippage": { "type": "string", "example": "0.5" }, "tokenIn": { "type": "string", "example": "0x036CbD53842c5426634e7929541eC2318f3dCF7e" }, "tokenOut": { "type": "string", "example": "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d" }, "intent_address": { "type": "string", "description": "Solana: intent PDA — show to users for QR/Send; transfer tokenIn here (wallet derives deposit ATA). EVM/Starknet: contract address.", "example": "0x4E60e01263E750eD9D087157e19D2480Fd86A900" }, "deposit_token_account": { "type": "string", "description": "Solana only: ATA(mint, intent PDA). Indexer and recovery only — do not use for QR/Send; fund via intent_address instead.", "example": "DX8aM33XqJqZqZqZqJqZqZqZqJqZqZqZqJqZqZqZqJqZ" }, "destination_intent_address": { "type": "string", "example": "0x5F70e12374E750fE0E087158f29E3591Ge97B011" }, "source_chain": { "type": "string", "example": "BASE_TESTNET" }, "destination_chain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "recipient": { "type": "string", "example": "0xb79541Be080a59fdcE6C0b43219ba56c725eC65e" }, "refund_address": { "type": "string", "example": "0xb79541Be080a59fdcE6C0b43219ba56c725eC65e" }, "relayer": { "type": "string", "example": "" }, "coordinator": { "type": "string", "example": "0x989f47053F188778575113DcF39dB8960Fc450e2" }, "bridger": { "type": "string", "example": "0xa1c943058a631D5506eb7d96036eAbF6968e2338" }, "bridgeExtraData": { "type": "string", "example": "0x00000000000000000000000000000000000000000000000000000000000001f4" }, "intent_nonce": { "type": "number", "example": 4267684716645197 }, "intent_status": { "type": "string", "enum": [ "PENDING", "FUNDED", "INITIATED", "COMPLETED", "EXPIRED" ], "example": "FUNDED" }, "tx_hash": { "type": "string", "nullable": true, "example": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" }, "needs_relay": { "type": "boolean", "example": false }, "relayer_claimed": { "type": "boolean", "example": false }, "paymaster_used": { "type": "boolean", "example": false }, "mode": { "type": "string", "enum": [ "test", "live" ], "example": "test" }, "expires_at": { "type": "string", "format": "date-time", "example": "2025-12-13T03:31:23.000Z" }, "metadata": { "type": "object", "example": { "orderId": "12345" } }, "created_at": { "type": "string", "format": "date-time", "example": "2025-12-13T02:31:23.390Z" }, "updated_at": { "type": "string", "format": "date-time", "example": "2025-12-13T02:33:15.120Z" } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } }, "404": { "description": "Intent not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 404 }, "message": { "type": "string", "example": "Intent not found" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get intent by address", "tags": [ "Intents" ] } }, "/intents/destination-address/{address}": { "get": { "description": "Calculates what the intent address would be on the destination chain for a given source intent", "operationId": "IntentController_getDestinationIntentAddress", "parameters": [ { "name": "address", "required": true, "in": "path", "description": "Source intent contract address", "schema": { "example": "0x4E60e01263E750eD9D087157e19D2480Fd86A900", "type": "string" } } ], "responses": { "200": { "description": "Destination address calculated successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "destinationAddress": { "type": "string", "example": "0x5F70e12374E750fE0E087158f29E3591Ge97B011" } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } }, "404": { "description": "Intent not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "Intent not found" } } } } } }, "500": { "description": "Failed to calculate destination address", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "Failed to calculate destination address: " } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Calculate destination intent address", "tags": [ "Intents" ] } }, "/intents/internal/{id}": { "get": { "operationId": "IntentController_getInternalIntent", "parameters": [ { "name": "id", "required": true, "in": "path", "schema": { "type": "number" } } ], "responses": { "200": { "description": "" } }, "security": [ { "api-key": [] } ], "tags": [ "Intents" ] } }, "/intents/user/{sender}": { "get": { "description": "Retrieves all intents created by a specific user", "operationId": "IntentController_getUserIntents", "parameters": [ { "name": "sender", "required": true, "in": "path", "description": "User wallet address", "schema": { "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "type": "string" } } ], "responses": { "200": { "description": "List of intents for the specified sender", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "number", "example": 1 }, "client_id": { "type": "string", "example": "e1ee3675-cb26-4a76-8206-a84f86e85862" }, "sender": { "type": "string", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" }, "initialAmount": { "type": "string", "example": "1000000" }, "fees_in_usd": { "type": "string", "example": "10500" }, "app_fee_in_usd": { "type": "string", "example": "1000" }, "total_amount_in_usd": { "type": "string", "example": "1010500" }, "total_amount_in_asset_token": { "type": "string", "example": "1000500" }, "fees_in_asset_token": { "type": "string", "example": "500" }, "app_fee_in_asset_token": { "type": "string", "example": "0" }, "asset_token_symbol": { "type": "string", "example": "USDC" }, "asset_token_decimals": { "type": "number", "example": 6 }, "slippage": { "type": "string", "example": "0.5" }, "tokenIn": { "type": "string", "example": "0x036CbD53842c5426634e7929541eC2318f3dCF7e" }, "tokenOut": { "type": "string", "example": "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d" }, "intent_address": { "type": "string", "example": "0x4E60e01263E750eD9D087157e19D2480Fd86A900" }, "destination_intent_address": { "type": "string", "example": "0x5F70e12374E750fE0E087158f29E3591Ge97B011" }, "source_chain": { "type": "string", "example": "BASE_TESTNET" }, "destination_chain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "recipient": { "type": "string", "example": "0xb79541Be080a59fdcE6C0b43219ba56c725eC65e" }, "refund_address": { "type": "string", "example": "0xb79541Be080a59fdcE6C0b43219ba56c725eC65e" }, "relayer": { "type": "string", "example": "" }, "coordinator": { "type": "string", "example": "0x989f47053F188778575113DcF39dB8960Fc450e2" }, "bridger": { "type": "string", "example": "0xa1c943058a631D5506eb7d96036eAbF6968e2338" }, "bridgeExtraData": { "type": "string", "example": "0x00000000000000000000000000000000000000000000000000000000000001f4" }, "intent_nonce": { "type": "number", "example": 4267684716645197 }, "intent_status": { "type": "string", "enum": [ "PENDING", "FUNDED", "INITIATED", "COMPLETED", "EXPIRED" ], "example": "COMPLETED" }, "tx_hash": { "type": "string", "example": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" }, "needs_relay": { "type": "boolean", "example": false }, "relayer_claimed": { "type": "boolean", "example": true }, "paymaster_used": { "type": "boolean", "example": false }, "mode": { "type": "string", "enum": [ "test", "live" ], "example": "test" }, "expires_at": { "type": "string", "format": "date-time", "example": "2025-12-13T03:31:23.000Z" }, "metadata": { "type": "object", "example": { "orderId": "12345" } }, "created_at": { "type": "string", "format": "date-time", "example": "2025-12-13T02:31:23.390Z" }, "updated_at": { "type": "string", "format": "date-time", "example": "2025-12-13T02:35:10.220Z" } } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get user intents", "tags": [ "Intents" ] } }, "/chains": { "get": { "description": "Retrieves all supported blockchain networks, optionally filtered by network type (mainnet/testnet)", "operationId": "ChainsController_getSupportedChains", "parameters": [ { "name": "network", "required": false, "in": "query", "description": "Network type filter (mainnet or testnet)", "schema": { "enum": [ "mainnet", "testnet" ], "type": "string" } } ], "responses": { "200": { "description": "Supported chains retrieved successfully", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "string", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "POLYGON_MAINNET", "POLYGON_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET" ] }, "example": [ "ETHEREUM_MAINNET", "ARBITRUM_MAINNET", "BASE_MAINNET", "OPTIMISM_MAINNET", "POLYGON_MAINNET", "AVALANCHE_MAINNET", "STARKNET_MAINNET" ] } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get supported chains", "tags": [ "Chains" ] } }, "/chains/{chain}/tokens": { "get": { "description": "Retrieves all supported tokens available on the specified blockchain network", "operationId": "ChainsController_getSupportedTokensForChain", "parameters": [ { "name": "chain", "required": true, "in": "path", "description": "Blockchain network to get tokens for", "schema": { "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "type": "string" } } ], "responses": { "200": { "description": "Supported tokens retrieved successfully", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "address": { "type": "string", "description": "Token contract address on the chain", "example": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }, "symbol": { "type": "string", "description": "Token symbol", "example": "USDC" }, "decimals": { "type": "number", "description": "Number of decimal places for the token", "example": 6 }, "name": { "type": "string", "description": "Full token name", "example": "USD Coin" } } }, "example": [ { "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "symbol": "USDC", "decimals": 6, "name": "USD Coin" } ] } } } }, "400": { "description": "Bad Request - Invalid chain parameter", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 400 }, "message": { "type": "string", "example": "Invalid chain parameter" } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get supported tokens for chain", "tags": [ "Chains" ] } }, "/chains/balances/{address}": { "get": { "description": "Retrieves all token balances for the specified wallet address across all supported blockchain networks. Returns only non-zero balances by default.", "operationId": "ChainsController_getWalletBalances", "parameters": [ { "name": "address", "required": true, "in": "path", "description": "Wallet address to check balances for", "schema": { "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "type": "string" } }, { "name": "includeZeroBalances", "required": false, "in": "query", "description": "Include tokens with zero balance in response", "schema": { "example": false, "type": "boolean" } }, { "name": "network", "required": false, "in": "query", "description": "Filter by network type (mainnet or testnet)", "schema": { "enum": [ "mainnet", "testnet" ], "type": "string" } }, { "name": "chainType", "required": false, "in": "query", "description": "Filter by chain type (EVM or STARKNET)", "schema": { "enum": [ "EVM", "STARKNET" ], "type": "string" } } ], "responses": { "200": { "description": "Wallet balances retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "object", "properties": { "symbol": { "type": "string", "example": "USDC" }, "balance": { "type": "string", "description": "Raw balance in wei/smallest unit", "example": "1000000000" }, "decimals": { "type": "number", "example": 6 }, "formatted": { "type": "string", "description": "Human-readable formatted balance", "example": "1000.0" }, "address": { "type": "string", "description": "Token contract address", "example": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" } } } }, "example": { "BASE_MAINNET": [ { "symbol": "USDC", "balance": "1000000000", "decimals": 6, "formatted": "1000.0", "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" } ], "ETHEREUM_MAINNET": [ { "symbol": "ETH", "balance": "5000000000000000000", "decimals": 18, "formatted": "5.0", "address": "0x0000000000000000000000000000000000000000" } ] } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get wallet balances across all chains", "tags": [ "Chains" ] } }, "/chains/tokens/all": { "get": { "description": "Retrieves all unique token symbols supported on Chainrails across all blockchain networks", "operationId": "ChainsController_getAllSupportedTokens", "parameters": [], "responses": { "200": { "description": "Supported tokens retrieved successfully", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "symbol": { "type": "string", "example": "USDC" }, "decimals": { "type": "number", "example": 6 }, "name": { "type": "string", "example": "USD Coin" }, "category": { "type": "string", "enum": [ "stablecoin", "major", "volatile" ], "example": "stablecoin" } } }, "example": [ { "symbol": "USDC", "decimals": 6, "name": "USD Coin", "category": "stablecoin" }, { "symbol": "ETH", "decimals": 18, "name": "Ethereum", "category": "major" } ] } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get all supported tokens", "tags": [ "Chains" ] } }, "/modal/sessions": { "post": { "description": "Creates a modal session with constraints (recipient, token, chain, amount). Returns a session token valid for 60 minutes.", "operationId": "SessionController_createSession", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSessionDto" }, "examples": { "Fixed amount": { "value": { "recipient": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "tokenOut": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "destinationChain": "STARKNET_MAINNET", "amount": "1" } }, "User input amount": { "value": { "recipient": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "tokenOut": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "destinationChain": "STARKNET_MAINNET", "amount": "0" } } } } } }, "responses": { "201": { "description": "Session created successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSessionResponseDto" } } } }, "401": { "description": "Unauthorized - Invalid API key" } }, "security": [ { "api-key": [] } ], "summary": "Create a modal session", "tags": [ "Modal Sessions" ] } }, "/quotes/best": { "get": { "description": "Retrieves the best quote (lowest total fee) from all supported bridge protocols", "operationId": "QuoteController_getBestQuote", "parameters": [ { "name": "tokenIn", "required": true, "in": "query", "description": "Input token address", "schema": { "example": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "type": "string" } }, { "name": "tokenOut", "required": true, "in": "query", "description": "Output token address", "schema": { "example": "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4", "type": "string" } }, { "name": "sourceChain", "required": true, "in": "query", "description": "Source blockchain", "schema": { "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "type": "string" } }, { "name": "destinationChain", "required": true, "in": "query", "description": "Destination blockchain", "schema": { "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "type": "string" } }, { "name": "amount", "required": true, "in": "query", "description": "Amount in token units", "schema": { "example": "10000000", "type": "string" } }, { "name": "excludeBridges", "required": false, "in": "query", "description": "Comma-separated bridges to exclude", "schema": { "example": "GATEWAY,CCTP", "type": "string" } }, { "name": "recipient", "required": false, "in": "query", "description": "Optional recipient address", "schema": { "example": "0x742d35Cc6635C0532925a3b8D62A7fe7B58123D1", "type": "string" } }, { "name": "amountSymbol", "required": false, "in": "query", "description": "Token symbol for amount denomination (defaults to USDC). Use this to specify amounts in other tokens like WETH, ETH, etc.", "schema": { "enum": [ "USDC", "USDT", "DAI", "BUSD", "EURC", "ETH", "WETH", "STRK", "BNB", "LORDS", "USDS", "USDG", "USDT0", "WBTC", "LINK", "SOL", "EKUBO", "AAVE", "UNI", "CURVE", "cbBTC", "VIRTUAL", "stETH", "wstETH", "SKY", "AUSD", "WMON", "LVMON", "OP", "WLD", "ARB", "sAVAX", "WAVAX", "anyBTC", "WBNB", "TRON", "AVAX", "POL", "MON" ], "type": "string" } } ], "responses": { "200": { "description": "Best quote retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "bridgeFeeDetails": { "type": "object", "description": "Bridge-specific fee details from the cheapest option", "example": { "maxFee": "8000" } }, "totalFee": { "type": "string", "description": "Lowest total fee among all bridges", "example": "18000" }, "totalFeeFormatted": { "type": "string", "description": "Human-readable formatted total fee", "example": "0.018" }, "route": { "type": "object", "properties": { "tokenIn": { "type": "string", "example": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }, "tokenOut": { "type": "string", "example": "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4" }, "sourceChain": { "type": "string", "example": "BASE_TESTNET" }, "destinationChain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "amount": { "type": "string", "example": "10000000" }, "bridge": { "type": "string", "enum": [ "ACROSS", "CCTP", "GATEWAY", "RHINOFI" ], "example": "CCTP" }, "recipient": { "type": "string", "nullable": true } } } } } } } }, "400": { "description": "Bad Request - Invalid parameters", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 400 }, "message": { "type": "string", "example": "Amount must be greater than 0" } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } }, "404": { "description": "No quotes available for the route", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 404 }, "message": { "type": "string", "example": "No quotes available for this route. Please check if the route is supported." } } } } } }, "500": { "description": "Internal Server Error", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 500 }, "message": { "type": "string", "example": "Failed to retrieve best quote. Please try again later." } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get best quote across all bridges", "tags": [ "Quotes" ] } }, "/quotes/multi-source": { "get": { "description": "Shows Alice all her options to send money to a specific destination chain, including same-chain transfers", "operationId": "QuoteController_getMultiSourceQuotes", "parameters": [ { "name": "destinationChain", "required": true, "in": "query", "description": "Destination blockchain where Alice wants to send money", "schema": { "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "type": "string" } }, { "name": "amount", "required": true, "in": "query", "description": "Amount in human readable format (supports decimals, e.g., \"1.5\", \"100\", \"0.001\")", "schema": { "example": "1.5", "type": "string" } }, { "name": "tokenOut", "required": true, "in": "query", "description": "Output token address", "schema": { "example": "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4", "type": "string" } }, { "name": "recipient", "required": false, "in": "query", "description": "Optional recipient address", "schema": { "example": "0x742d35Cc6635C0532925a3b8D62A7fe7B58123D1", "type": "string" } }, { "name": "excludeChains", "required": false, "in": "query", "description": "Comma-separated chains to exclude from results", "schema": { "example": "BASE_TESTNET,OPTIMISM", "type": "string" } } ], "responses": { "200": { "description": "Multi-source quotes retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "destinationChain": { "type": "string", "example": "ARBITRUM_TESTNET", "description": "Target destination chain" }, "quotes": { "type": "array", "description": "Quotes from all possible source chains (same-chain listed first, then sorted by cost)", "items": { "type": "object", "properties": { "sourceChain": { "type": "string", "example": "BASE_TESTNET" }, "destinationChain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "totalFee": { "type": "string", "example": "18000", "description": "Total protocol fees in USDC wei" }, "totalFeeFormatted": { "type": "string", "example": "0.018", "description": "Human-readable total fee" }, "bridge": { "type": "string", "enum": [ "ACROSS", "CCTP", "GATEWAY", "RHINOFI" ], "example": "CCTP", "nullable": true, "description": "Bridge used (null for same-chain transfers)" }, "paymentOptions": { "type": "array", "description": "Available payment tokens on source chain with deposit amounts", "items": { "type": "object", "properties": { "token": { "type": "string", "enum": [ "USDC", "USDT", "DAI", "BUSD", "EURC", "ETH", "WETH", "STRK", "BNB", "AVAX" ], "example": "USDC" }, "tokenAddress": { "type": "string", "example": "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d", "description": "Contract address of the token on the source chain" }, "depositAmount": { "type": "string", "example": "1518000", "description": "Amount to deposit in token wei" }, "depositAmountFormatted": { "type": "string", "example": "1.518", "description": "Human-readable deposit amount" }, "slippage": { "type": "number", "example": 0, "description": "Slippage percentage for swap (0 for USDC)" } } } } } } }, "cheapestOption": { "type": "object", "nullable": true, "description": "The cheapest option among all source chains (based on totalFee)", "properties": { "sourceChain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "destinationChain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "totalFee": { "type": "string", "example": "10000", "description": "Total protocol fees in USDC wei" }, "totalFeeFormatted": { "type": "string", "example": "0.01", "description": "Human-readable total fee" }, "bridge": { "type": "string", "enum": [ "ACROSS", "CCTP", "GATEWAY", "RHINOFI" ], "example": null, "nullable": true, "description": "Bridge used (null for same-chain transfers)" }, "paymentOptions": { "type": "array", "description": "Available payment tokens", "items": { "type": "object", "properties": { "token": { "type": "string", "example": "USDC" }, "tokenAddress": { "type": "string", "example": "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d" }, "depositAmount": { "type": "string", "example": "1010000" }, "depositAmountFormatted": { "type": "string", "example": "1.01" }, "slippage": { "type": "number", "example": 0 } } } } } } } } } } }, "400": { "description": "Bad Request - Invalid parameters", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 400 }, "message": { "type": "string", "example": "Amount must be a valid positive number" } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } }, "500": { "description": "Internal Server Error", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 500 }, "message": { "type": "string", "example": "Failed to retrieve multi-source quotes. Please try again later." } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get quotes from all source chains to destination", "tags": [ "Quotes" ] } }, "/quotes/multiple": { "get": { "description": "Retrieves quotes from all supported bridge protocols for comparison", "operationId": "QuoteController_getMultipleQuotes", "parameters": [ { "name": "tokenIn", "required": true, "in": "query", "description": "Input token address", "schema": { "example": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "type": "string" } }, { "name": "tokenOut", "required": true, "in": "query", "description": "Output token address", "schema": { "example": "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4", "type": "string" } }, { "name": "sourceChain", "required": true, "in": "query", "description": "Source blockchain", "schema": { "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "type": "string" } }, { "name": "destinationChain", "required": true, "in": "query", "description": "Destination blockchain", "schema": { "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "type": "string" } }, { "name": "amount", "required": true, "in": "query", "description": "Amount in token units", "schema": { "example": "10000000", "type": "string" } }, { "name": "excludeBridges", "required": false, "in": "query", "description": "Comma-separated bridges to exclude", "schema": { "example": "GATEWAY,CCTP", "type": "string" } }, { "name": "recipient", "required": false, "in": "query", "description": "Optional recipient address", "schema": { "example": "0x742d35Cc6635C0532925a3b8D62A7fe7B58123D1", "type": "string" } }, { "name": "amountSymbol", "required": false, "in": "query", "description": "Token symbol for amount denomination (defaults to USDC). Use this to specify amounts in other tokens like WETH, ETH, etc.", "schema": { "enum": [ "USDC", "USDT", "DAI", "BUSD", "EURC", "ETH", "WETH", "STRK", "BNB", "LORDS", "USDS", "USDG", "USDT0", "WBTC", "LINK", "SOL", "EKUBO", "AAVE", "UNI", "CURVE", "cbBTC", "VIRTUAL", "stETH", "wstETH", "SKY", "AUSD", "WMON", "LVMON", "OP", "WLD", "ARB", "sAVAX", "WAVAX", "anyBTC", "WBNB", "TRON", "AVAX", "POL", "MON" ], "type": "string" } } ], "responses": { "200": { "description": "Multiple quotes retrieved successfully", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "bridgeFeeDetails": { "type": "object", "description": "Bridge-specific fee details", "example": { "maxFee": "8000" } }, "totalFee": { "type": "string", "description": "Total fee in token units", "example": "18000" }, "totalFeeFormatted": { "type": "string", "description": "Human-readable formatted total fee", "example": "0.018" }, "route": { "type": "object", "properties": { "tokenIn": { "type": "string", "example": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }, "tokenOut": { "type": "string", "example": "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4" }, "sourceChain": { "type": "string", "example": "BASE_TESTNET" }, "destinationChain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "amount": { "type": "string", "example": "10000000" }, "bridge": { "type": "string", "enum": [ "ACROSS", "CCTP", "GATEWAY", "RHINOFI" ], "example": "CCTP" }, "recipient": { "type": "string", "nullable": true } } } } } } } } }, "400": { "description": "Bad Request - Invalid parameters", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 400 }, "message": { "type": "string", "example": "Source and destination chains must be different" } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } }, "500": { "description": "Internal Server Error", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 500 }, "message": { "type": "string", "example": "Failed to retrieve quotes. Please try again later." } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get quotes from all bridges", "tags": [ "Quotes" ] } }, "/quotes/single": { "get": { "description": "Retrieves a cross-chain transfer quote from a specific bridge protocol", "operationId": "QuoteController_getQuote", "parameters": [ { "name": "tokenIn", "required": true, "in": "query", "description": "Input token address", "schema": { "example": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "type": "string" } }, { "name": "tokenOut", "required": true, "in": "query", "description": "Output token address", "schema": { "example": "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4", "type": "string" } }, { "name": "sourceChain", "required": true, "in": "query", "description": "Source blockchain", "schema": { "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "type": "string" } }, { "name": "destinationChain", "required": true, "in": "query", "description": "Destination blockchain", "schema": { "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "type": "string" } }, { "name": "amount", "required": true, "in": "query", "description": "Amount in token units (denominated in amountSymbol if specified, otherwise USDC)", "schema": { "example": "10000000", "type": "string" } }, { "name": "bridge", "required": true, "in": "query", "description": "Bridge to use for the quote", "schema": { "enum": [ "ACROSS", "CCTP", "GATEWAY", "RHINOFI" ], "type": "string" } }, { "name": "recipient", "required": false, "in": "query", "description": "Optional recipient address", "schema": { "example": "0x742d35Cc6635C0532925a3b8D62A7fe7B58123D1", "type": "string" } }, { "name": "amountSymbol", "required": false, "in": "query", "description": "Token symbol for amount denomination (defaults to USDC). Use this to specify amounts in other tokens like WETH, DAI, etc.", "schema": { "enum": [ "USDC", "USDT", "DAI", "BUSD", "EURC", "ETH", "WETH", "STRK", "BNB", "LORDS", "USDS", "USDG", "USDT0", "WBTC", "LINK", "SOL", "EKUBO", "AAVE", "UNI", "CURVE", "cbBTC", "VIRTUAL", "stETH", "wstETH", "SKY", "AUSD", "WMON", "LVMON", "OP", "WLD", "ARB", "sAVAX", "WAVAX", "anyBTC", "WBNB", "TRON", "AVAX", "POL", "MON" ], "type": "string" } } ], "responses": { "200": { "description": "Quote retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "bridgeFeeDetails": { "type": "object", "description": "Bridge-specific fee details (structure varies by bridge)", "example": { "timestamp": 1702425683, "fillDeadline": 1702429283, "pctFee": 100000000000000, "flatFee": "5000" } }, "totalFee": { "type": "string", "description": "Total fee in token units (bridge fee + ChainRails fee)", "example": "15500" }, "totalFeeFormatted": { "type": "string", "description": "Human-readable formatted total fee", "example": "0.0155" }, "route": { "type": "object", "properties": { "tokenIn": { "type": "string", "example": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }, "tokenOut": { "type": "string", "example": "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4" }, "sourceChain": { "type": "string", "example": "BASE_TESTNET" }, "destinationChain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "amount": { "type": "string", "example": "10000000" }, "bridge": { "type": "string", "enum": [ "ACROSS", "CCTP", "GATEWAY", "RHINOFI" ], "example": "ACROSS" }, "recipient": { "type": "string", "nullable": true, "example": "0x742d35Cc6635C0532925a3b8D62A7fe7B58123D1" } } } } } } } }, "400": { "description": "Bad Request - Invalid parameters or unsupported route", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 400 }, "message": { "type": "string", "example": "Token addresses are required" } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } }, "500": { "description": "Internal Server Error", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 500 }, "message": { "type": "string", "example": "Failed to retrieve quote. Please try again later." } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get quote from specific bridge", "tags": [ "Quotes" ] } }, "/ramp/countries": { "get": { "description": "Returns all enabled countries with currency details. Optionally filter by fiat currency code, minimum crypto (USDC) amount, and ramp type. When type=off-ramp, only countries with direct S2S off-ramp support (Fonbnk) are returned.", "operationId": "RampController_getCountries", "parameters": [ { "name": "currency", "required": false, "in": "query", "schema": { "example": "EUR", "type": "string" } }, { "name": "amount", "required": false, "in": "query", "schema": { "example": 10, "type": "number" } }, { "name": "type", "required": false, "in": "query", "schema": { "enum": [ "on-ramp", "off-ramp" ], "type": "string" } } ], "responses": { "200": { "description": "List of supported countries with currency info" } }, "security": [ { "api-key": [] } ], "summary": "List supported countries", "tags": [ "Ramp" ] } }, "/ramp/currencies": { "get": { "description": "Returns all enabled fiat currencies. Optionally filter by a specific ramp provider and/or ramp type. When type=off-ramp, only currencies with direct S2S off-ramp support are returned.", "operationId": "RampController_getCurrencies", "parameters": [ { "name": "provider", "required": false, "in": "query", "description": "Filter currencies by a specific provider", "schema": { "example": "FONBNK", "type": "string" } }, { "name": "type", "required": false, "in": "query", "description": "Filter by ramp direction. off-ramp returns only currencies with direct S2S off-ramp support (Fonbnk).", "schema": { "enum": [ "on-ramp", "off-ramp" ], "type": "string" } } ], "responses": { "200": { "description": "List of supported fiat currencies" } }, "security": [ { "api-key": [] } ], "summary": "List supported fiat currencies", "tags": [ "Ramp" ] } }, "/ramp/kyc": { "get": { "description": "Returns the current KYC state for a user from Fonbnk. When `cryptoAmount` is provided, the response includes `requiredKycType` and `canProceed` so the client knows whether to prompt for KYC before creating an order.", "operationId": "RampController_getKycState", "parameters": [ { "name": "provider", "required": true, "in": "query", "description": "The ramp provider to query KYC state from", "schema": { "enum": [ "FONBNK", "ONRAMP_MONEY", "GUARDARIAN" ], "type": "string" } }, { "name": "userEmail", "required": true, "in": "query", "description": "The end-user's email address (Fonbnk keys KYC state by this)", "schema": { "example": "user@example.com", "type": "string" } }, { "name": "countryCode", "required": true, "in": "query", "description": "ISO 3166-1 alpha-2 country code", "schema": { "example": "NG", "type": "string" } }, { "name": "cryptoAmount", "required": false, "in": "query", "description": "Amount of crypto (USDC) the user intends to receive. When provided, the response includes `requiredKycType` and `canProceed`.", "schema": { "example": 25, "type": "number" } } ], "responses": { "200": { "description": "KYC state" }, "400": { "description": "Invalid parameters" } }, "security": [ { "api-key": [] } ], "summary": "Get user KYC state", "tags": [ "Ramp" ] }, "post": { "description": "Submits a KYC document for a user. Returns the updated KYC state. For basic KYC, supply `userFields.id_number`. For advanced KYC, supply `userFields.images` with selfie (0), front (1), and back (5) photos.", "operationId": "RampController_submitKyc", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubmitRampKycDto" } } } }, "responses": { "200": { "description": "Updated KYC state after submission" }, "400": { "description": "Invalid parameters or submission rejected" } }, "security": [ { "api-key": [] } ], "summary": "Submit KYC document", "tags": [ "Ramp" ] } }, "/ramp/orders": { "post": { "description": "Creates an on-ramp or off-ramp order with the selected provider.", "operationId": "RampController_createOrder", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateRampOrderDto" } } } }, "responses": { "201": { "description": "Ramp order created successfully" }, "400": { "description": "Invalid request parameters" }, "401": { "description": "Missing or invalid API key" } }, "security": [ { "api-key": [] } ], "summary": "Create a ramp order", "tags": [ "Ramp" ] }, "get": { "description": "Returns ramp orders for the authenticated client, optionally filtered by type. Newest first.", "operationId": "RampController_listOrders", "parameters": [ { "name": "type", "required": false, "in": "query", "schema": { "enum": [ "on-ramp", "off-ramp" ], "type": "string" } } ], "responses": { "200": { "description": "List of ramp orders" } }, "security": [ { "api-key": [] } ], "summary": "List ramp orders", "tags": [ "Ramp" ] } }, "/ramp/orders/{id}": { "get": { "description": "Returns the full details of a ramp order, scoped to the authenticated client.", "operationId": "RampController_getOrder", "parameters": [ { "name": "id", "required": true, "in": "path", "description": "Ramp order ID", "schema": { "type": "number" } } ], "responses": { "200": { "description": "Ramp order details" }, "404": { "description": "Order not found" } }, "security": [ { "api-key": [] } ], "summary": "Get a ramp order by ID", "tags": [ "Ramp" ] } }, "/ramp/orders/{id}/cancel": { "post": { "description": "Cancels a ramp order if it is still in a cancellable state.", "operationId": "RampController_cancelOrder", "parameters": [ { "name": "id", "required": true, "in": "path", "description": "Ramp order ID", "schema": { "type": "number" } } ], "responses": { "200": { "description": "Order cancelled" }, "400": { "description": "Order cannot be cancelled" }, "404": { "description": "Order not found" } }, "security": [ { "api-key": [] } ], "summary": "Cancel a ramp order", "tags": [ "Ramp" ] } }, "/ramp/orders/{id}/confirm": { "post": { "description": "Confirms a ramp order after the user has completed their deposit action.", "operationId": "RampController_confirmOrder", "parameters": [ { "name": "id", "required": true, "in": "path", "description": "Ramp order ID", "schema": { "type": "number" } } ], "responses": { "200": { "description": "Order confirmed" }, "404": { "description": "Order not found" } }, "security": [ { "api-key": [] } ], "summary": "Confirm a ramp order", "tags": [ "Ramp" ] } }, "/ramp/orders/by-intent/{intentAddress}": { "get": { "description": "Returns the full details of a ramp order looked up by its on-chain intent address.", "operationId": "RampController_getOrderByIntentAddress", "parameters": [ { "name": "intentAddress", "required": true, "in": "path", "description": "On-chain intent address", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Ramp order details" }, "404": { "description": "Order not found" } }, "security": [ { "api-key": [] } ], "summary": "Get a ramp order by intent address", "tags": [ "Ramp" ] } }, "/ramp/quotes": { "get": { "description": "Returns on-ramp or off-ramp quotes from all eligible providers, sorted by cheapest total cost.", "operationId": "RampController_getQuotes", "parameters": [ { "name": "type", "required": true, "in": "query", "description": "Type of quote to get", "schema": { "enum": [ "on-ramp", "off-ramp" ], "type": "string" } }, { "name": "fiatCurrency", "required": true, "in": "query", "description": "ISO 4217 fiat currency code", "schema": { "example": "NGN", "type": "string" } }, { "name": "cryptoAmount", "required": true, "in": "query", "description": "Amount of crypto the user wants to receive (on-ramp) or sell (off-ramp). For off-ramp this is the amount of the selected source token.", "schema": { "example": 10, "type": "number" } }, { "name": "destinationChain", "required": false, "in": "query", "description": "Destination blockchain where user wants funds (required for on-ramp)", "schema": { "example": "BASE_MAINNET", "type": "string", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ] } }, { "name": "sourceChain", "required": false, "in": "query", "description": "Source blockchain where user will send crypto from (required for off-ramp)", "schema": { "example": "BASE_MAINNET", "type": "string", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ] } }, { "name": "amountSymbol", "required": false, "in": "query", "description": "Token symbol for cryptoAmount (defaults to USDC)", "schema": { "enum": [ "USDC", "USDT", "DAI", "BUSD", "EURC", "ETH", "WETH", "STRK", "BNB", "LORDS", "USDS", "USDG", "USDT0", "WBTC", "LINK", "SOL", "EKUBO", "AAVE", "UNI", "CURVE", "cbBTC", "VIRTUAL", "stETH", "wstETH", "SKY", "AUSD", "WMON", "LVMON", "OP", "WLD", "ARB", "sAVAX", "WAVAX", "anyBTC", "WBNB", "TRON", "AVAX", "POL", "MON" ], "type": "string" } }, { "name": "countryCode", "required": false, "in": "query", "description": "ISO 3166-1 alpha-2 country code of the user. Required for multi-country currencies (e.g., XOF — pass \"BJ\" for Benin, \"SN\" for Senegal). Falls back to the currency's default country if omitted.", "schema": { "example": "NG", "type": "string" } }, { "name": "directOnly", "required": false, "in": "query", "description": "If true, only return quotes with direct transfer channels (no widget/redirect)", "schema": { "example": false, "type": "boolean" } }, { "name": "userEmail", "required": false, "in": "query", "description": "User's email. When supplied, recommendation can prefer providers where the user is already KYC-cleared.", "schema": { "example": "user@example.com", "type": "string" } } ], "responses": { "200": { "description": "Aggregated ramp quotes" }, "400": { "description": "Invalid request parameters" }, "401": { "description": "Missing or invalid API key" } }, "security": [ { "api-key": [] } ], "summary": "Get aggregated ramp quotes", "tags": [ "Ramp" ] } }, "/registry/chains": { "get": { "operationId": "RegistryController_getChainRegistry", "parameters": [], "responses": { "200": { "description": "" } }, "tags": [ "Registry" ] } }, "/registry/chains/{chain}": { "get": { "operationId": "RegistryController_getChain", "parameters": [ { "name": "chain", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "200": { "description": "" } }, "tags": [ "Registry" ] } }, "/registry/chains/aliases": { "get": { "operationId": "RegistryController_getAliases", "parameters": [], "responses": { "200": { "description": "" } }, "tags": [ "Registry" ] } }, "/registry/chains/mainnet": { "get": { "operationId": "RegistryController_getMainnetChains", "parameters": [], "responses": { "200": { "description": "" } }, "tags": [ "Registry" ] } }, "/registry/chains/search": { "get": { "operationId": "RegistryController_searchChains", "parameters": [ { "name": "type", "required": true, "in": "query", "schema": { "type": "string" } } ], "responses": { "200": { "description": "" } }, "tags": [ "Registry" ] } }, "/registry/chains/testnet": { "get": { "operationId": "RegistryController_getTestnetChains", "parameters": [], "responses": { "200": { "description": "" } }, "tags": [ "Registry" ] } }, "/registry/tokens": { "get": { "operationId": "RegistryController_getTokenRegistry", "parameters": [], "responses": { "200": { "description": "" } }, "tags": [ "Registry" ] } }, "/registry/tokens/{chain}": { "get": { "operationId": "RegistryController_getTokensByChain", "parameters": [ { "name": "chain", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "200": { "description": "" } }, "tags": [ "Registry" ] } }, "/registry/tokens/{chain}/{symbol}": { "get": { "operationId": "RegistryController_getToken", "parameters": [ { "name": "chain", "required": true, "in": "path", "schema": { "type": "string" } }, { "name": "symbol", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "200": { "description": "" } }, "tags": [ "Registry" ] } }, "/registry/tokens/{chain}/native": { "get": { "operationId": "RegistryController_getNativeTokens", "parameters": [ { "name": "chain", "required": true, "in": "path", "schema": { "type": "string" } } ], "responses": { "200": { "description": "" } }, "tags": [ "Registry" ] } }, "/registry/tokens/search": { "get": { "operationId": "RegistryController_searchTokens", "parameters": [], "responses": { "200": { "description": "" } }, "tags": [ "Registry" ] } }, "/registry/tokens/symbol": { "get": { "operationId": "RegistryController_getSupportedTokenSymbol", "parameters": [], "responses": { "200": { "description": "" } }, "tags": [ "Registry" ] } }, "/router/optimal-route": { "get": { "description": "Analyzes available bridges and returns the optimal route with best pricing", "operationId": "RouterController_findOptimalRoute", "parameters": [ { "name": "tokenIn", "required": true, "in": "query", "description": "Input token contract address", "schema": { "example": "0xA0b86a33E6411192B1F4ec3eB801B21EB56", "type": "string" } }, { "name": "tokenOut", "required": true, "in": "query", "description": "Output token contract address", "schema": { "example": "0xA0b86a33E6411192B1F4ec3eB801B21EB56", "type": "string" } }, { "name": "sourceChain", "required": true, "in": "query", "description": "Source blockchain", "schema": { "example": "BASE_MAINNET", "type": "string", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ] } }, { "name": "destinationChain", "required": true, "in": "query", "description": "Destination blockchain", "schema": { "example": "ARBITRUM_MAINNET", "type": "string", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ] } }, { "name": "amount", "required": true, "in": "query", "description": "Transfer amount in token units (wei for ETH)", "schema": { "example": "1000000000000000000", "type": "string" } }, { "name": "recipient", "required": false, "in": "query", "description": "Recipient address for the cross-chain transfer (required for some bridges like RhinoFi)", "schema": { "example": "0x742d35cc6634c0532925a3b8d7389d8c5b7cf15b", "type": "string" } }, { "name": "amountSymbol", "required": true, "in": "query", "description": "Token symbol for amount denomination (e.g., USDC, USDT, ETH)", "schema": { "example": "USDC", "type": "string" } } ], "responses": { "200": { "description": "Optimal route found successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "sourceChain": { "type": "string", "example": "BASE_TESTNET" }, "destinationChain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "tokenIn": { "type": "string", "example": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }, "tokenOut": { "type": "string", "example": "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4" }, "originalAmount": { "type": "string", "example": "10000000", "description": "Original transfer amount" }, "totalFees": { "type": "string", "example": "18000", "description": "Total fees (bridge fee + ChainRails fee)" }, "bridgeToUse": { "type": "string", "enum": [ "ACROSS", "CCTP", "GATEWAY", "RHINOFI" ], "example": "CCTP", "nullable": true }, "bridgeAddress": { "type": "string", "example": "0xa1c943058a631D5506eb7d96036eAbF6968e2338" }, "bridgeExtraData": { "type": "string", "example": "0x00000000000000000000000000000000000000000000000000000000000001f4" }, "supportedBridges": { "type": "array", "items": { "type": "string", "enum": [ "ACROSS", "CCTP", "GATEWAY", "RHINOFI" ] }, "example": [ "ACROSS", "CCTP" ] }, "bridgeFeeDetails": { "type": "object", "description": "Bridge-specific fee details (structure varies by bridge)", "example": { "maxFee": "8000" } } } } } } }, "400": { "description": "Bad Request - No bridges support the route", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 400 }, "message": { "type": "string", "example": "No bridges support route BASE_TESTNET -> STARKNET_MAINNET" } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } }, "500": { "description": "Internal Server Error", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 500 }, "message": { "type": "string", "example": "Failed to calculate optimal route" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Find optimal cross-chain transfer route", "tags": [ "Router" ] } }, "/router/supported-bridges/all": { "get": { "description": "Returns all bridges and their supported routes", "operationId": "RouterController_getAllSupportedBridges", "parameters": [], "responses": { "200": { "description": "All supported bridges retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "bridges": { "type": "object", "description": "Map of bridge names to their supported routes", "example": { "ACROSS": [ { "sourceChain": "BASE_TESTNET", "destinationChain": "ARBITRUM_TESTNET", "supported": true, "bidirectional": true }, { "sourceChain": "ETHEREUM_MAINNET", "destinationChain": "ARBITRUM_MAINNET", "supported": true, "bidirectional": true } ], "CCTP": [ { "sourceChain": "BASE_TESTNET", "destinationChain": "ARBITRUM_TESTNET", "supported": true, "bidirectional": true } ] } }, "metadata": { "type": "object", "properties": { "totalBridges": { "type": "number", "example": 4, "description": "Total number of supported bridges" }, "totalRoutes": { "type": "number", "example": 25, "description": "Total number of supported routes" }, "lastUpdated": { "type": "string", "format": "date-time", "example": "2025-12-13T02:45:30.123Z" } } } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } }, "500": { "description": "Internal Server Error", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 500 }, "message": { "type": "string", "example": "Failed to retrieve bridge information" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get all supported bridges", "tags": [ "Router" ] } }, "/router/supported-bridges/route": { "get": { "description": "Returns all bridges that support transfers between specific source and destination chains", "operationId": "RouterController_getSupportedBridgesForRoute", "parameters": [ { "name": "sourceChain", "required": true, "in": "query", "description": "Source blockchain", "schema": { "example": "BASE_TESTNET", "type": "string", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ] } }, { "name": "destinationChain", "required": true, "in": "query", "description": "Destination blockchain", "schema": { "example": "ARBITRUM_TESTNET", "type": "string", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ] } } ], "responses": { "200": { "description": "Supported bridges for route retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "supportedBridges": { "type": "array", "items": { "type": "string", "enum": [ "ACROSS", "CCTP", "GATEWAY", "RHINOFI" ] }, "example": [ "ACROSS", "CCTP", "RHINOFI" ] }, "routeInfo": { "type": "object", "properties": { "sourceChain": { "type": "string", "example": "BASE_TESTNET" }, "destinationChain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "bridgeCount": { "type": "number", "example": 3, "description": "Number of bridges supporting this route" }, "isSupported": { "type": "boolean", "example": true, "description": "Whether any bridge supports this route" } } } } } } } }, "400": { "description": "Bad Request - Invalid route parameters", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 400 }, "message": { "type": "string", "example": "Invalid route parameters" } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get supported bridges for specific route", "tags": [ "Router" ] } }, "/router/supported-routes/bridge/{bridge}": { "get": { "description": "Returns all source/destination chain pairs supported by a specific bridge", "operationId": "RouterController_getSupportedRoutesForBridge", "parameters": [ { "name": "bridge", "required": true, "in": "path", "description": "Bridge protocol", "schema": { "enum": [ "ACROSS", "CCTP", "GATEWAY", "RHINOFI" ], "type": "string" } } ], "responses": { "200": { "description": "Supported routes for bridge retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "supportedRoutes": { "type": "array", "items": { "type": "object", "properties": { "sourceChain": { "type": "string", "example": "BASE_TESTNET" }, "destinationChain": { "type": "string", "example": "ARBITRUM_TESTNET" }, "supported": { "type": "boolean", "example": true }, "bidirectional": { "type": "boolean", "example": true } } } }, "bridgeInfo": { "type": "object", "properties": { "bridge": { "type": "string", "enum": [ "ACROSS", "CCTP", "GATEWAY", "RHINOFI" ], "example": "ACROSS" }, "routeCount": { "type": "number", "example": 12, "description": "Number of routes supported by this bridge" } } } } } } } }, "400": { "description": "Bad Request - Invalid bridge parameter", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 400 }, "message": { "type": "string", "example": "Invalid bridge parameter" } } } } } }, "401": { "description": "Unauthorized - Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "statusCode": { "type": "number", "example": 401 }, "message": { "type": "string", "example": "Unauthorized" } } } } } } }, "security": [ { "api-key": [] } ], "summary": "Get supported routes for specific bridge", "tags": [ "Router" ] } } }, "info": { "title": "Chainrails API", "description": "Public API documentation for Chainrails", "version": "1.0", "contact": {} }, "tags": [], "servers": [ { "url": "https://api.chainrails.io/api/v1" } ], "components": { "securitySchemes": { "api-key": { "type": "http", "scheme": "bearer", "bearerFormat": "API Key", "description": "Enter your Chainrails API key as a Bearer token" } }, "schemas": { "CreateClientDto": { "type": "object", "properties": {} }, "LoginClientDto": { "type": "object", "properties": {} }, "ForgotPasswordDto": { "type": "object", "properties": { "email": { "type": "string", "description": "Email address of the account", "example": "user@example.com" } }, "required": [ "email" ] }, "ResetPasswordDto": { "type": "object", "properties": { "token": { "type": "string", "description": "Password reset token from email", "example": "a1b2c3d4e5f6..." }, "newPassword": { "type": "string", "description": "New password (minimum 8 characters)", "example": "NewSecurePassword123!", "minLength": 8 } }, "required": [ "token", "newPassword" ] }, "CreateClientApiKeyDto": { "type": "object", "properties": {} }, "AppFeeResponseDto": { "type": "object", "properties": { "appFeePercentage": { "type": "number", "description": "App fee percentage (e.g., 0.5 for 0.5%)", "example": 0.5 }, "appFeeCap": { "type": "number", "description": "App fee cap in USD", "example": 2 }, "appFeeEnabled": { "type": "boolean", "description": "Whether app fees are enabled", "example": true }, "appFeeRecipientEvm": { "type": "string", "description": "EVM address to receive app fees (for Ethereum, Arbitrum, BSC, etc.)", "example": "0x1234567890abcdef1234567890abcdef12345678" }, "appFeeRecipientStarknet": { "type": "string", "description": "Starknet address to receive app fees", "example": "0x1234567890abcdef1234567890abcdef12345678" }, "appFeeRecipientSolana": { "type": "string", "description": "Solana address (base58 public key) to receive app fees", "example": "3vgp7KVbXUkzjj1uKPoi8FxWop1XDpzN6eCYJ2N19uEr" } }, "required": [ "appFeePercentage", "appFeeCap", "appFeeEnabled" ] }, "UpdateAppFeeDto": { "type": "object", "properties": { "appFeePercentage": { "type": "number", "description": "App fee percentage (e.g., 0.5 for 0.5%). Maximum 5%", "example": 0.5, "minimum": 0, "maximum": 5 }, "appFeeCap": { "type": "number", "description": "App fee cap in USD. Must be a positive number.", "example": 2, "minimum": 0 }, "appFeeRecipientEvm": { "type": "string", "description": "EVM address to receive app fees (42 chars, e.g. 0x...). Required format for Ethereum, Arbitrum, Base, etc.", "example": "0xdA3ECb2E5362295E2b802669dD47127A61d9Ce54" }, "appFeeRecipientStarknet": { "type": "string", "description": "Starknet address to receive app fees (66 chars, e.g. 0x...). Required format for Starknet chains.", "example": "0x02d904Aedff382C0D68F22444B525146ec5eA2926e271fC411845e8D9E751DE1" }, "appFeeRecipientSolana": { "type": "string", "description": "Solana address (base58 public key) to receive app fees on Solana chains.", "example": "3vgp7KVbXUkzjj1uKPoi8FxWop1XDpzN6eCYJ2N19uEr" } }, "required": [ "appFeePercentage", "appFeeCap" ] }, "ToggleAppFeeDto": { "type": "object", "properties": { "enabled": { "type": "boolean", "description": "Whether to enable or disable app fees", "example": true } }, "required": [ "enabled" ] }, "Chains": { "type": "string", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "description": "Source blockchain network for the deposit" }, "CreateDepositDto": { "type": "object", "properties": { "amount": { "type": "string", "description": "Amount in smallest unit (e.g., wei).", "example": "1000000" }, "sourceChain": { "description": "Source blockchain network for the deposit", "example": "ETHEREUM_MAINNET", "allOf": [ { "$ref": "#/components/schemas/Chains" } ] }, "destinationChain": { "description": "Destination blockchain network for the deposit", "example": "ETHEREUM_MAINNET", "allOf": [ { "$ref": "#/components/schemas/Chains" } ] }, "token": { "type": "string", "description": "Token to deposit", "enum": [ "USDC", "USDT", "DAI", "BUSD", "EURC", "ETH", "WETH", "STRK", "BNB", "LORDS", "USDS", "USDG", "USDT0", "WBTC", "LINK", "SOL", "EKUBO", "AAVE", "UNI", "CURVE", "cbBTC", "VIRTUAL", "stETH", "wstETH", "SKY", "AUSD", "WMON", "LVMON", "OP", "WLD", "ARB", "sAVAX", "WAVAX", "anyBTC", "WBNB", "TRON", "AVAX", "POL", "MON" ], "example": "USDC", "default": "USDC" } }, "required": [ "amount", "sourceChain", "destinationChain" ] }, "InitiateGatewayDto": { "type": "object", "properties": {} }, "CreateIntentDto": { "type": "object", "properties": { "sender": { "type": "string", "description": "Sender wallet address on the source chain", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "default": "Default address from config" }, "paymentLinkId": { "type": "string", "description": "Payment link ID associated with the intent", "example": "pl_xw1nw5rpaj" }, "amount": { "type": "string", "description": "Amount to transfer in smallest unit (e.g., wei for ETH).", "example": "1000000000000000000" }, "amountSymbol": { "type": "string", "description": "Token symbol for amount denomination (e.g., USDC, USDT, ETH)", "example": "USDC" }, "tokenIn": { "type": "string", "description": "Token address on the source chain", "example": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" }, "source_chain": { "description": "Source blockchain network", "example": "ETHEREUM_MAINNET", "allOf": [ { "$ref": "#/components/schemas/Chains" } ] }, "destination_chain": { "description": "Destination blockchain network", "example": "STARKNET_MAINNET", "allOf": [ { "$ref": "#/components/schemas/Chains" } ] }, "recipient": { "type": "string", "description": "Recipient wallet address on the destination chain", "example": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" }, "refund_address": { "type": "string", "description": "Refund address on the source chain if intent fails", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "default": "Defaults to sender address" }, "metadata": { "type": "object", "description": "Additional metadata for the intent", "example": { "orderId": "12345", "userId": "user-abc" } } }, "required": [ "amount", "amountSymbol", "tokenIn", "source_chain", "destination_chain", "recipient" ] }, "GetAttestationDto": { "type": "object", "properties": {} }, "ReclaimEventAccountDto": { "type": "object", "properties": { "intentId": { "type": "number", "description": "Intent row id", "example": 123 } }, "required": [ "intentId" ] }, "BulkReclaimEventAccountsDto": { "type": "object", "properties": { "dryRun": { "type": "boolean", "description": "When true (default), only list candidates — do not reclaim on-chain", "default": true }, "limit": { "type": "number", "description": "Max Solana-source CCTP intents to consider (1–500)", "default": 100, "minimum": 1, "maximum": 500 }, "onlyPending": { "type": "boolean", "description": "Skip intents already marked reclaimed in internal_metadata (default true)", "default": true }, "force": { "type": "boolean", "description": "Reclaim even if reclaimEventAccount already succeeded", "default": false }, "staggerMs": { "type": "number", "description": "Pause between successive on-chain reclaim attempts in ms (rate-limit Circle/RPC)", "default": 500, "minimum": 0, "maximum": 60000 } } }, "AddRelayersDto": { "type": "object", "properties": { "relayerAddresses": { "description": "Array of relayer addresses to add", "example": [ "0x1234567890123456789012345678901234567890", "0x0987654321098765432109876543210987654321" ], "minItems": 1, "type": "array", "items": { "type": "string" } }, "chain": { "type": "string", "description": "The blockchain network to add relayers on", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "example": "ARBITRUM_TESTNET" } }, "required": [ "relayerAddresses", "chain" ] }, "RemoveRelayersDto": { "type": "object", "properties": { "relayerAddresses": { "description": "Array of relayer addresses to remove", "example": [ "0x1234567890123456789012345678901234567890", "0x0987654321098765432109876543210987654321" ], "minItems": 1, "type": "array", "items": { "type": "string" } }, "chain": { "type": "string", "description": "The blockchain network to remove relayers from", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "example": "ARBITRUM_TESTNET" } }, "required": [ "relayerAddresses", "chain" ] }, "CreateSessionDto": { "type": "object", "properties": { "recipient": { "type": "string", "description": "Recipient wallet address on the destination chain", "example": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" }, "tokenOut": { "type": "string", "description": "Token address on the destination chain", "example": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" }, "destinationChain": { "description": "Destination blockchain network", "example": "STARKNET_MAINNET", "allOf": [ { "$ref": "#/components/schemas/Chains" } ] }, "amount": { "type": "string", "description": "Amount in human-readable format (e.g., \"1\" for 1 token, \"100\" for 100 tokens, \"1.5\" for 1.5 tokens). Set to \"0\" to allow user to input any amount > 0", "example": "1" } }, "required": [ "recipient", "tokenOut", "destinationChain", "amount" ] }, "ClientInfoResponseDto": { "type": "object", "properties": { "id": { "type": "string", "description": "Client unique identifier", "example": "550e8400-e29b-41d4-a716-446655440000" }, "name": { "type": "string", "description": "Client name", "example": "Acme Corp" }, "email": { "type": "string", "description": "Client email address", "example": "contact@acme.com" }, "logoUrl": { "type": "string", "description": "Client logo URL", "example": "https://acme.com/logo.png" }, "paymasterEnabled": { "type": "boolean", "description": "Whether paymaster is enabled for this client", "example": false }, "merchantKybVerified": { "type": "boolean", "description": "Whether merchant KYB has been verified for live fiat ramp usage", "example": true } }, "required": [ "id", "name", "email", "paymasterEnabled", "merchantKybVerified" ] }, "CreateSessionResponseDto": { "type": "object", "properties": { "sessionId": { "type": "string", "description": "Unique session identifier", "example": "550e8400-e29b-41d4-a716-446655440000" }, "sessionToken": { "type": "string", "description": "JWT session token for authentication", "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }, "expiresAt": { "format": "date-time", "type": "string", "description": "Token expiration timestamp", "example": "2025-12-24T13:45:30.000Z" }, "client": { "description": "Client details associated with this session", "allOf": [ { "$ref": "#/components/schemas/ClientInfoResponseDto" } ] } }, "required": [ "sessionId", "sessionToken", "expiresAt" ] }, "HandoffTokenResponseDto": { "type": "object", "properties": { "sessionId": { "type": "string", "description": "Unique session identifier", "example": "550e8400-e29b-41d4-a716-446655440000" }, "handoffToken": { "type": "string", "description": "Short-lived handoff token that can be passed to a wallet app and exchanged for a fresh session token", "example": "kTQ_9f2Q5h8T6ecT4-0w7Q" }, "expiresAt": { "format": "date-time", "type": "string", "description": "Handoff token expiration timestamp", "example": "2025-12-24T12:10:00.000Z" } }, "required": [ "sessionId", "handoffToken", "expiresAt" ] }, "ResumeSessionDto": { "type": "object", "properties": { "handoffToken": { "type": "string", "description": "Short-lived handoff token issued for the session", "example": "kTQ_9f2Q5h8T6ecT4-0w7Q" } }, "required": [ "handoffToken" ] }, "CreateIntentWithSessionDto": { "type": "object", "properties": { "sender": { "type": "string", "description": "Sender wallet address on the source chain", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" }, "amount": { "type": "string", "description": "Amount to transfer in human-readable format (e.g., \"1\" for 1 token, \"100\" for 100 tokens, \"1.5\" for 1.5 tokens). Must match session amount if not 0, otherwise must be > 0", "example": "1" }, "tokenIn": { "type": "string", "description": "Token address on the source chain", "example": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" }, "paymentLinkId": { "type": "string", "description": "Payment link ID associated with the intent", "example": "pl_xw1nw5rpaj" }, "sourceChain": { "description": "Source blockchain network", "example": "ETHEREUM_MAINNET", "allOf": [ { "$ref": "#/components/schemas/Chains" } ] }, "refundAddress": { "type": "string", "description": "Refund address on the source chain if intent fails", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" }, "metadata": { "type": "object", "description": "Additional metadata for the intent", "example": { "orderId": "12345", "userId": "user-abc" } } }, "required": [ "sender", "amount", "tokenIn", "sourceChain" ] }, "IntentStatusResponseDto": { "type": "object", "properties": { "id": { "type": "number", "description": "Intent database ID", "example": 42 }, "intentAddress": { "type": "string", "description": "Intent address (unique identifier)", "example": "0x1234567890abcdef..." }, "status": { "type": "string", "description": "Current intent status", "enum": [ "PENDING", "FUNDED", "COMPLETED", "REFUNDED", "EXPIRED" ], "example": "PENDING" }, "txHash": { "type": "string", "description": "Transaction hash if available", "example": "0xabcdef1234567890..." }, "createdAt": { "format": "date-time", "type": "string", "description": "Intent creation timestamp", "example": "2025-12-24T12:00:00.000Z" }, "expiresAt": { "format": "date-time", "type": "string", "description": "Intent expiration timestamp", "example": "2025-12-24T13:00:00.000Z" } }, "required": [ "id", "intentAddress", "status" ] }, "IntentHistoryDto": { "type": "object", "properties": {} }, "SendRampEmailOtpDto": { "type": "object", "properties": { "email": { "type": "string", "description": "Email address to verify", "example": "user@example.com" } }, "required": [ "email" ] }, "VerifyRampEmailOtpDto": { "type": "object", "properties": { "email": { "type": "string", "description": "Email address being verified", "example": "user@example.com" }, "otp": { "type": "string", "description": "Six-digit verification code sent to the email address", "example": "123456" } }, "required": [ "email", "otp" ] }, "CreateSessionRampOrderDto": { "type": "object", "properties": { "type": { "type": "string", "description": "Type of ramp order to create", "enum": [ "on-ramp", "off-ramp" ], "example": "on-ramp" }, "provider": { "type": "string", "description": "Ramp provider to use for this order", "enum": [ "FONBNK", "ONRAMP_MONEY", "GUARDARIAN" ], "example": "FONBNK" }, "fiatCurrency": { "type": "string", "description": "ISO 4217 fiat currency code", "example": "NGN" }, "cryptoAmount": { "type": "number", "description": "Amount of the source token the user wants to sell (off-ramp) or USDC to receive (on-ramp)", "example": 10 }, "amountSymbol": { "type": "string", "description": "Token symbol for cryptoAmount (defaults to USDC)", "enum": [ "USDC", "USDT", "DAI", "BUSD", "EURC", "ETH", "WETH", "STRK", "BNB", "LORDS", "USDS", "USDG", "USDT0", "WBTC", "LINK", "SOL", "EKUBO", "AAVE", "UNI", "CURVE", "cbBTC", "VIRTUAL", "stETH", "wstETH", "SKY", "AUSD", "WMON", "LVMON", "OP", "WLD", "ARB", "sAVAX", "WAVAX", "anyBTC", "WBNB", "TRON", "AVAX", "POL", "MON" ], "example": "USDC" }, "countryCode": { "type": "string", "description": "ISO 3166-1 alpha-2 country code of the user", "example": "NG" }, "userEmail": { "type": "string", "description": "User's email — required for Fonbnk direct orders (Fonbnk keys KYC state and order history by email)", "example": "user@example.com" }, "emailVerificationToken": { "type": "string", "description": "Short-lived token returned by POST /v1/modal/sessions/ramp/email-otp/verify. Required when userEmail is supplied." }, "fields": { "type": "object", "description": "Provider-specific fields required by the payment channel (e.g., phone number, bank code)", "example": { "phoneNumber": "+2348012345678" } } }, "required": [ "type", "provider", "fiatCurrency", "cryptoAmount" ] }, "SubmitSessionRampKycDto": { "type": "object", "properties": { "provider": { "type": "string", "description": "The ramp provider to submit KYC to", "enum": [ "FONBNK", "ONRAMP_MONEY", "GUARDARIAN" ], "example": "FONBNK" }, "userEmail": { "type": "string", "description": "The end-user's email address", "example": "user@example.com" }, "emailVerificationToken": { "type": "string", "description": "Short-lived token returned by POST /v1/modal/sessions/ramp/email-otp/verify." }, "countryCode": { "type": "string", "description": "ISO 3166-1 alpha-2 country code", "example": "NG" }, "documentId": { "type": "string", "description": "`_id` of the chosen document from the `kycDocuments` array returned by GET /v1/modal/sessions/ramp/kyc", "example": "67da909b739fc481aa525c45" }, "userFields": { "type": "object", "description": "User-provided fields for the selected document.", "example": { "first_name": "John", "last_name": "Doe", "dob": "1990-01-01", "id_number": "12345678901" } }, "cryptoAmount": { "type": "number", "description": "Amount of USDC the user intends to receive. Used to compute canProceed.", "example": 25 } }, "required": [ "provider", "userEmail", "emailVerificationToken", "countryCode", "documentId", "userFields" ] }, "CreateRampOrderDto": { "type": "object", "properties": { "type": { "type": "string", "description": "Type of ramp order to create", "enum": [ "on-ramp", "off-ramp" ], "example": "on-ramp" }, "provider": { "type": "string", "description": "Ramp provider to use for this order", "enum": [ "FONBNK", "ONRAMP_MONEY", "GUARDARIAN" ], "example": "FONBNK" }, "fiatCurrency": { "type": "string", "description": "ISO 4217 fiat currency code", "example": "NGN" }, "cryptoAmount": { "type": "number", "description": "Amount of crypto the user wants to receive (on-ramp) or sell (off-ramp). For off-ramp this is the amount of the selected source token.", "example": 10 }, "destinationChain": { "type": "string", "description": "Destination blockchain where user wants their funds (required for on-ramp)", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "example": "BASE_MAINNET" }, "sourceChain": { "type": "string", "description": "Source blockchain where user will send crypto from (required for off-ramp)", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "example": "BASE_MAINNET" }, "amountSymbol": { "type": "string", "description": "Token symbol for cryptoAmount (defaults to USDC)", "enum": [ "USDC", "USDT", "DAI", "BUSD", "EURC", "ETH", "WETH", "STRK", "BNB", "LORDS", "USDS", "USDG", "USDT0", "WBTC", "LINK", "SOL", "EKUBO", "AAVE", "UNI", "CURVE", "cbBTC", "VIRTUAL", "stETH", "wstETH", "SKY", "AUSD", "WMON", "LVMON", "OP", "WLD", "ARB", "sAVAX", "WAVAX", "anyBTC", "WBNB", "TRON", "AVAX", "POL", "MON" ], "example": "USDC" }, "recipientAddress": { "type": "string", "description": "Recipient wallet address on the destination chain (required for on-ramp)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" }, "senderAddress": { "type": "string", "description": "User's crypto wallet address / sender (required for off-ramp)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" }, "countryCode": { "type": "string", "description": "ISO 3166-1 alpha-2 country code of the user. Required for multi-country currencies (e.g., XOF — pass \"BJ\" for Benin, \"SN\" for Senegal). Falls back to the currency's default country if omitted.", "example": "NG" }, "userEmail": { "type": "string", "description": "End-user's email address. Required for Fonbnk direct orders (Fonbnk keys KYC state and order history by email).", "example": "user@example.com" }, "fields": { "type": "object", "description": "Provider-specific fields required by the payment channel (e.g., phone number, bank code)", "example": { "phoneNumber": "+2348012345678" } } }, "required": [ "type", "provider", "fiatCurrency", "cryptoAmount" ] }, "SubmitRampKycDto": { "type": "object", "properties": { "provider": { "type": "string", "description": "The ramp provider to submit KYC to", "enum": [ "FONBNK", "ONRAMP_MONEY", "GUARDARIAN" ], "example": "FONBNK" }, "userEmail": { "type": "string", "description": "The end-user's email address", "example": "user@example.com" }, "countryCode": { "type": "string", "description": "ISO 3166-1 alpha-2 country code", "example": "NG" }, "documentId": { "type": "string", "description": "`_id` of the chosen document from the `kycDocuments` array returned by GET /v1/ramp/kyc", "example": "67da909b739fc481aa525c45" }, "userFields": { "type": "object", "description": "User-provided fields for the selected document. For basic KYC: { first_name, last_name, dob, id_number }. For advanced KYC: { first_name, last_name, dob, images: [{ image_type_id, image }] }", "example": { "first_name": "John", "last_name": "Doe", "dob": "1990-01-01", "id_number": "12345678901" } }, "cryptoAmount": { "type": "number", "description": "Amount of crypto (USDC) the user intends to receive — used to compute `canProceed` in the response.", "example": 25 } }, "required": [ "provider", "userEmail", "countryCode", "documentId", "userFields" ] }, "LoginAdminDto": { "type": "object", "properties": {} }, "CreateAdminDto": { "type": "object", "properties": {} }, "ChangePasswordDto": { "type": "object", "properties": {} }, "UpdateClientDto": { "type": "object", "properties": {} }, "CreateApiKeyDto": { "type": "object", "properties": {} }, "CreateServiceApiKeyDto": { "type": "object", "properties": {} }, "WebhookDeliveryResponseDto": { "type": "object", "properties": { "delivery_id": { "type": "string" }, "webhook_id": { "type": "string" }, "event_id": { "type": "string" }, "event_type": { "type": "string" }, "status": { "type": "string" }, "response_status_code": { "type": "number" }, "attempts": { "type": "number" }, "next_retry_at": { "format": "date-time", "type": "string" }, "delivered_at": { "format": "date-time", "type": "string" }, "failed_at": { "format": "date-time", "type": "string" }, "error_message": { "type": "string" }, "created_at": { "format": "date-time", "type": "string" } }, "required": [ "delivery_id", "webhook_id", "event_id", "event_type", "status", "created_at" ] }, "CreateWebhookDto": { "type": "object", "properties": { "url": { "type": "string", "description": "Webhook endpoint URL (HTTPS only, or localhost for test)", "example": "https://api.example.com/webhooks/chainrails" }, "events": { "type": "array", "description": "Array of event types to subscribe to", "example": [ "intent.completed", "intent.funded" ], "items": { "type": "string", "enum": [ "intent.created", "intent.funded", "intent.initiated", "intent.completed", "intent.expired", "intent.refunded", "ramp.order.initiated", "ramp.order.funded", "ramp.order.completed", "ramp.order.failed", "ramp.order.expired", "ramp.order.cancelled" ] } }, "is_active": { "type": "boolean", "description": "Whether the webhook is active", "default": true }, "environment": { "type": "string", "description": "Webhook environment (live or test)", "enum": [ "live", "test" ], "example": "live" } }, "required": [ "url", "events", "environment" ] }, "WebhookResponseDto": { "type": "object", "properties": { "webhook_id": { "type": "string" }, "client_id": { "type": "string" }, "url": { "type": "string" }, "events": { "type": "array", "items": { "type": "string" } }, "is_active": { "type": "boolean" }, "environment": { "type": "string" }, "secret": { "type": "string" }, "created_at": { "format": "date-time", "type": "string" }, "updated_at": { "format": "date-time", "type": "string" } }, "required": [ "webhook_id", "client_id", "url", "events", "is_active", "environment", "created_at", "updated_at" ] }, "UpdateWebhookDto": { "type": "object", "properties": { "url": { "type": "string", "description": "Webhook endpoint URL (HTTPS only)" }, "events": { "type": "array", "description": "Array of event types to subscribe to", "items": { "type": "string", "enum": [ "intent.created", "intent.funded", "intent.initiated", "intent.completed", "intent.expired", "intent.refunded", "ramp.order.initiated", "ramp.order.funded", "ramp.order.completed", "ramp.order.failed", "ramp.order.expired", "ramp.order.cancelled" ] } }, "is_active": { "type": "boolean", "description": "Whether the webhook is active" }, "environment": { "type": "string", "description": "Webhook environment (live or test)", "enum": [ "live", "test" ] } } }, "GoldskyWebhookDto": { "type": "object", "properties": {} }, "WhitelistBroadcasterDto": { "type": "object", "properties": { "contractAddress": { "type": "string", "description": "Contract address to whitelist", "example": "0x1234567890abcdef..." }, "chain": { "type": "string", "description": "Chain where the contract is deployed", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "example": "BASE_MAINNET" } }, "required": [ "contractAddress", "chain" ] }, "WhitelistBroadcasterResponse": { "type": "object", "properties": { "success": { "type": "boolean", "description": "Whether the operation was successful" }, "message": { "type": "string", "description": "Success/error message" }, "contract": { "type": "object", "description": "Whitelisted contract details" } }, "required": [ "success", "message" ] }, "UpdateWhitelistBroadcasterDto": { "type": "object", "properties": { "contractAddress": { "type": "string", "description": "Contract address to whitelist", "example": "0x1234567890abcdef..." }, "chain": { "type": "string", "description": "Chain where the contract is deployed", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "example": "BASE_MAINNET" } }, "required": [ "contractAddress", "chain" ] }, "RemoveBroadcasterDto": { "type": "object", "properties": { "contractAddress": { "type": "string", "description": "Contract address to remove", "example": "0x1234567890abcdef..." }, "chain": { "type": "string", "description": "Chain where the contract is deployed", "enum": [ "ARBITRUM_MAINNET", "ARBITRUM_TESTNET", "AVALANCHE_MAINNET", "AVALANCHE_TESTNET", "BASE_MAINNET", "BASE_TESTNET", "STARKNET_MAINNET", "STARKNET_TESTNET", "BSC_MAINNET", "ETHEREUM_MAINNET", "ETHEREUM_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "MONAD_MAINNET", "MONAD_TESTNET", "POLYGON_MAINNET", "HYPEREVM_MAINNET", "LISK_MAINNET", "SOLANA_MAINNET", "SOLANA_TESTNET", "TRON_MAINNET" ], "example": "BASE_MAINNET" } }, "required": [ "contractAddress", "chain" ] }, "RemoveBroadcasterResponse": { "type": "object", "properties": { "success": { "type": "boolean", "description": "Whether the operation was successful" }, "message": { "type": "string", "description": "Success/error message" } }, "required": [ "success", "message" ] }, "GetWhitelistedContractsResponse": { "type": "object", "properties": { "success": { "type": "boolean", "description": "Whether the operation was successful" }, "contracts": { "description": "Array of whitelisted contracts", "type": "array", "items": { "type": "string" } } }, "required": [ "success", "contracts" ] }, "CreateThemeDto": { "type": "object", "properties": { "name": { "type": "string", "description": "Theme name", "example": "Neon Dreams", "minLength": 3, "maxLength": 100 }, "description": { "type": "string", "description": "Theme description", "example": "A vibrant neon theme with dark backgrounds", "maxLength": 500 }, "category": { "type": "string", "description": "Theme category", "enum": [ "gaming", "health", "travel", "finance", "education", "others" ], "example": "gaming" }, "visibility": { "type": "string", "description": "Theme visibility", "enum": [ "public", "private" ], "example": "public" } }, "required": [ "name", "category", "visibility" ] }, "ThemeResponseDto": { "type": "object", "properties": { "id": { "type": "string", "description": "Theme unique identifier", "example": "550e8400-e29b-41d4-a716-446655440000" }, "name": { "type": "string", "description": "Theme name", "example": "Neon Dreams" }, "slug": { "type": "string", "description": "Theme slug (auto-generated)", "example": "neon-dreams-a4f2e8bc" }, "description": { "type": "string", "description": "Theme description", "example": "A vibrant neon theme with dark backgrounds", "nullable": true }, "category": { "type": "string", "description": "Theme category", "enum": [ "gaming", "health", "travel", "finance", "education", "others" ] }, "visibility": { "type": "string", "description": "Theme visibility", "enum": [ "public", "private" ], "example": "public" }, "status": { "type": "string", "description": "Theme status", "enum": [ "draft", "pending", "approved", "rejected" ], "example": "draft" }, "authorId": { "type": "string", "description": "Author ID (creator of the theme)", "example": "123e4567-e89b-12d3-a456-426614174000" }, "cssContent": { "type": "string", "description": "CSS content", "example": ".cr-modal { background: #000; }" }, "cssHash": { "type": "string", "description": "CSS hash for cache busting", "example": "a3f2b9c8d1e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0", "nullable": true }, "cssSizeBytes": { "type": "number", "description": "CSS size in bytes", "example": 45632, "nullable": true }, "s3Url": { "type": "string", "description": "S3 URL where CSS is stored", "example": "https://api.chainrails.io/themes/neon-dreams-a4f2e8bc.css?v=a3f2b9c8", "nullable": true }, "submittedAt": { "format": "date-time", "type": "string", "description": "Timestamp when theme was submitted for review", "example": "2026-02-05T10:30:00Z", "nullable": true }, "reviewedAt": { "format": "date-time", "type": "string", "description": "Timestamp when theme was reviewed", "example": "2026-02-05T12:00:00Z", "nullable": true }, "rejectionReason": { "type": "string", "description": "Rejection reason (if rejected)", "example": "CSS contains unsafe patterns", "nullable": true }, "createdAt": { "format": "date-time", "type": "string", "description": "Creation timestamp", "example": "2026-02-05T10:00:00Z" }, "updatedAt": { "format": "date-time", "type": "string", "description": "Last update timestamp", "example": "2026-02-05T10:30:00Z" } }, "required": [ "id", "name", "slug", "category", "visibility", "status", "authorId", "createdAt", "updatedAt" ] }, "ThemeListItemDto": { "type": "object", "properties": { "id": { "type": "string", "description": "Theme unique identifier", "example": "550e8400-e29b-41d4-a716-446655440000" }, "name": { "type": "string", "description": "Theme name", "example": "Neon Dreams" }, "slug": { "type": "string", "description": "Theme slug", "example": "neon-dreams-a4f2e8bc" }, "description": { "type": "string", "description": "Theme description", "example": "A vibrant neon theme", "nullable": true }, "visibility": { "type": "string", "description": "Theme visibility", "enum": [ "public", "private" ], "example": "public" }, "status": { "type": "string", "description": "Theme status", "enum": [ "draft", "pending", "approved", "rejected" ], "example": "approved" }, "author_id": { "type": "string", "description": "Author ID", "example": "123e4567-e89b-12d3-a456-426614174000" }, "createdAt": { "format": "date-time", "type": "string", "description": "Creation timestamp", "example": "2026-02-05T10:00:00Z" }, "updatedAt": { "format": "date-time", "type": "string", "description": "Last update timestamp", "example": "2026-02-05T10:30:00Z" } }, "required": [ "id", "name", "slug", "description", "visibility", "status", "author_id", "createdAt", "updatedAt" ] }, "PaginationDto": { "type": "object", "properties": { "page": { "type": "number", "description": "Current page number", "example": 1 }, "limit": { "type": "number", "description": "Items per page", "example": 20 }, "total": { "type": "number", "description": "Total number of items", "example": 150 }, "totalPages": { "type": "number", "description": "Total number of pages", "example": 8 } }, "required": [ "page", "limit", "total", "totalPages" ] }, "ThemeListResponseDto": { "type": "object", "properties": { "themes": { "description": "List of themes", "type": "array", "items": { "$ref": "#/components/schemas/ThemeListItemDto" } }, "pagination": { "description": "Pagination metadata", "allOf": [ { "$ref": "#/components/schemas/PaginationDto" } ] } }, "required": [ "themes", "pagination" ] }, "UpdateThemeDto": { "type": "object", "properties": { "name": { "type": "string", "description": "Theme name", "example": "Neon Dreams Updated", "minLength": 3, "maxLength": 100 }, "description": { "type": "string", "description": "Theme description", "example": "An updated vibrant neon theme with dark backgrounds", "maxLength": 500 }, "category": { "type": "string", "description": "Theme category", "enum": [ "gaming", "health", "travel", "finance", "education", "others" ], "example": "gaming" }, "visibility": { "type": "string", "description": "Theme visibility", "enum": [ "public", "private" ], "example": "public" }, "cssContent": { "type": "string", "description": "CSS content (raw CSS)", "example": ".cr-modal { background: #000; color: #0ff; }" } } }, "RejectThemeDto": { "type": "object", "properties": { "reason": { "type": "string", "description": "Reason for rejecting the theme", "example": "CSS contains unsafe patterns or does not meet quality standards", "minLength": 10, "maxLength": 1000 } }, "required": [ "reason" ] }, "PaymentLinkMetadataDto": { "type": "object", "properties": { "name": { "type": "string", "description": "Human-readable name for the payment link", "example": "Invoice #123", "maxLength": 200 }, "description": { "type": "string", "description": "Detailed description of the payment", "example": "Design Master Class for Intermediate Designers by AJ", "maxLength": 1000 }, "downloadable_media": { "type": "string", "description": "URL to downloadable media/file (optional)", "example": "https://example.com/files/invoice-123.pdf" }, "tax": { "type": "number", "description": "Tax percentage to be applied (0-100, optional)", "example": 10, "minimum": 0, "maximum": 100 } }, "required": [ "name", "description" ] }, "CreatePaymentLinkDto": { "type": "object", "properties": { "recipient": { "type": "string", "description": "Recipient wallet address on the destination chain", "example": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" }, "tokenOut": { "type": "string", "description": "Token address on the destination chain", "example": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" }, "destinationChain": { "description": "Destination blockchain network", "example": "BASE", "allOf": [ { "$ref": "#/components/schemas/Chains" } ] }, "amount": { "type": "string", "description": "Amount in human-readable format (e.g., \"1\" for 1 token, \"100\" for 100 tokens, \"1.5\" for 1.5 tokens). Set to \"0\" to allow user to input any amount", "example": "100" }, "metadata": { "description": "Payment link metadata (name, description, optional downloadable media and tax)", "example": { "name": "Invoice #123", "description": "Design Master Class for Intermediate Designers by AJ", "downloadable_media": "https://example.com/files/course.pdf", "tax": 10 }, "allOf": [ { "$ref": "#/components/schemas/PaymentLinkMetadataDto" } ] } }, "required": [ "recipient", "tokenOut", "destinationChain", "amount", "metadata" ] }, "UpdatePaymentLinkDto": { "type": "object", "properties": {} }, "PaymentLinkDisplayDto": { "type": "object", "properties": { "payment_id": { "type": "string", "example": "pl_qj2p5ep7nx" }, "name": { "type": "string", "example": "Invoice #123" }, "description": { "type": "string", "example": "Design Master Class for Intermediate Designers" }, "amount": { "type": "string", "example": "100" }, "destination_chain": { "example": "BASE", "allOf": [ { "$ref": "#/components/schemas/Chains" } ] }, "token_out": { "type": "string", "example": "usdc" }, "downloadable_media": { "type": "string", "example": "https://example.com/files/invoice-123.pdf" }, "tax": { "type": "number", "example": 10 } }, "required": [ "payment_id", "name", "description", "amount", "destination_chain", "token_out" ] }, "CreatePaymentLinkSessionResponseDto": { "type": "object", "properties": { "sessionId": { "type": "string", "description": "Unique session identifier", "example": "550e8400-e29b-41d4-a716-446655440000" }, "sessionToken": { "type": "string", "description": "JWT session token for authentication", "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }, "expiresAt": { "format": "date-time", "type": "string", "description": "Token expiration timestamp", "example": "2025-12-24T13:45:30.000Z" }, "client": { "description": "Client details associated with this session", "allOf": [ { "$ref": "#/components/schemas/ClientInfoResponseDto" } ] }, "paymentLink": { "$ref": "#/components/schemas/PaymentLinkDisplayDto" } }, "required": [ "sessionId", "sessionToken", "expiresAt", "paymentLink" ] }, "IngestSolanaDepositDto": { "type": "object", "properties": {} }, "IngestSolanaNestedDepositDto": { "type": "object", "properties": {} }, "IngestSolanaDestinationFundingDto": { "type": "object", "properties": {} }, "IngestStarknetDepositDto": { "type": "object", "properties": {} }, "IngestStarknetDestinationFundingDto": { "type": "object", "properties": {} }, "TokenAmountDto": { "type": "object", "properties": { "token": { "type": "string", "description": "Token address (bytes32 format)", "example": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }, "amount": { "type": "string", "description": "Token amount as string", "example": "1000000" } }, "required": [ "token", "amount" ] }, "IngestStarknetBroadcastIntentDto": { "type": "object", "properties": { "broadcastId": { "type": "string", "description": "Unique broadcast ID", "example": "0x1234567890abcdef..." }, "broadcaster": { "type": "string", "description": "ChainRails broadcaster contract address", "example": "0xBroadcasterAddress..." }, "broadcastingContract": { "type": "string", "description": "Client contract that called broadcast_intent (whitelisted)", "example": "0xClientContract..." }, "sender": { "type": "string", "description": "User wallet address", "example": "0xUserAddress..." }, "sourceChain": { "type": "number", "description": "Source chain enum value", "example": 2 }, "destinationChain": { "type": "number", "description": "Destination chain enum value", "example": 0 }, "recipient": { "type": "string", "description": "Destination recipient address", "example": "0xRecipientAddress..." }, "refundAddress": { "type": "string", "description": "Refund address", "example": "0xRefundAddress..." }, "deposits": { "description": "Array of deposited tokens", "type": "array", "items": { "$ref": "#/components/schemas/TokenAmountDto" } }, "bridgeTokenOutOptions": { "description": "Array of bridge token output options", "type": "array", "items": { "$ref": "#/components/schemas/TokenAmountDto" } }, "mode": { "type": "string", "description": "Environment mode", "enum": [ "live", "test" ], "example": "live" }, "chain": { "type": "string", "example": "STARKNET_MAINNET" }, "txHash": { "type": "string", "description": "Transaction hash (0x…)" }, "logIndex": { "type": "number", "description": "Event index in the transaction receipt" }, "blockNumber": { "type": "number", "description": "Block number" }, "observedAtMs": { "type": "number", "description": "Wall-clock millis when indexer observed this event" } }, "required": [ "broadcastId", "broadcaster", "broadcastingContract", "sender", "sourceChain", "destinationChain", "recipient", "refundAddress", "deposits", "bridgeTokenOutOptions", "mode", "chain", "txHash", "logIndex", "blockNumber", "observedAtMs" ] } } }, "security": [ { "api-key": [] } ] }