Files
cryptowallet/apps/api/swagger.json
2026-05-03 20:01:58 +03:00

421 lines
18 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"openapi": "3.0.0",
"info": {
"title": "CryptoWallet API",
"version": "2.1.0",
"description": "Multi-chain crypto wallet API. Auth via JWT (cookie/Bearer), issued by external auth-service (BITOK). Non-custodial: server NEVER signs transactions, только строит unsigned tx + хранит зашифрованный vault."
},
"servers": [
{ "url": "/api", "description": "API root" }
],
"tags": [
{ "name": "System", "description": "Health & service info" },
{ "name": "Wallets", "description": "User wallet records" },
{ "name": "Wallet Ops", "description": "Per-chain balance / transactions / send" },
{ "name": "Vault", "description": "Encrypted mnemonic blob storage (opaque)" },
{ "name": "BTC", "description": "Bitcoin RPC proxy (Blockstream)" },
{ "name": "TRON", "description": "TRON RPC proxy (TronGrid)" },
{ "name": "Solana", "description": "Solana swap proxy (Jupiter)" },
{ "name": "TRON Swap", "description": "TRON swap proxy (SunSwap + FeeSwapRouter)" },
{ "name": "BSC", "description": "BSC swap proxy (PancakeSwap V2)" },
{ "name": "Relay", "description": "Cross-chain bridges (Relay Protocol)" }
],
"components": {
"securitySchemes": {
"bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" },
"cookieAuth": { "type": "apiKey", "in": "cookie", "name": "access_token" }
},
"schemas": {
"Error": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": false },
"error": { "type": "string" }
}
},
"SuccessEmpty": {
"type": "object",
"properties": { "success": { "type": "boolean", "example": true } }
},
"HealthResponse": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": true },
"data": { "type": "object", "properties": { "status": { "type": "string", "example": "ok" } } }
}
},
"Chain": {
"type": "string",
"enum": ["ETH", "BTC", "SOL", "TRX", "BSC"]
},
"Wallet": {
"type": "object",
"properties": {
"chain": { "$ref": "#/components/schemas/Chain" },
"address": { "type": "string" },
"derivationPath": { "type": "string" }
}
},
"WalletInput": {
"type": "object",
"required": ["chain", "address", "derivationPath"],
"properties": {
"chain": { "$ref": "#/components/schemas/Chain" },
"address": { "type": "string", "maxLength": 256 },
"derivationPath": { "type": "string", "maxLength": 64 }
}
},
"CreateWalletsRequest": {
"type": "object",
"required": ["wallets"],
"properties": {
"wallets": {
"type": "array", "minItems": 1, "maxItems": 20,
"items": { "$ref": "#/components/schemas/WalletInput" }
}
}
},
"WalletsResponse": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": true },
"data": { "type": "array", "items": { "$ref": "#/components/schemas/Wallet" } }
}
},
"BalanceResponse": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": true },
"data": {
"type": "object",
"properties": {
"chain": { "$ref": "#/components/schemas/Chain" },
"address": { "type": "string" },
"native": { "type": "string", "description": "Balance в smallest units (sat/wei/lamports/sun)" },
"tokens": {
"type": "object",
"additionalProperties": { "type": "string" },
"example": { "USDT": "12345678" }
}
}
}
}
},
"Transaction": {
"type": "object",
"properties": {
"txid": { "type": "string" },
"timestamp": { "type": "integer", "nullable": true, "description": "Unix seconds" },
"direction": { "type": "string", "enum": ["in", "out", "self"] },
"amount": { "type": "string", "nullable": true },
"token": { "type": "string", "nullable": true },
"from": { "type": "string", "nullable": true },
"to": { "type": "string", "nullable": true }
}
},
"TransactionsResponse": {
"type": "object",
"properties": {
"success": { "type": "boolean" },
"data": { "type": "array", "items": { "$ref": "#/components/schemas/Transaction" } }
}
},
"SendRequest": {
"type": "object",
"required": ["to", "amount"],
"properties": {
"to": { "type": "string", "description": "Recipient address" },
"amount": { "type": "string", "description": "Amount в smallest units" },
"token": { "type": "string", "nullable": true, "description": "Например USDT для TRC20/ERC20/BEP20. Без token = native (TRX/ETH/BNB/BTC)" }
}
},
"UnsignedTxResponse": {
"type": "object",
"properties": {
"success": { "type": "boolean" },
"data": {
"type": "object",
"description": "Unsigned tx — формат зависит от chain (kind: btc | tron | evm | solana). Клиент подписывает приватом и broadcast'ит через соответствующий /api/{btc,tron}/broadcast endpoint"
}
}
},
"VaultResponse": {
"type": "object",
"properties": {
"success": { "type": "boolean" },
"data": {
"type": "object",
"properties": {
"encryptedVault": { "type": "string", "description": "AES-GCM encrypted mnemonic, base64" },
"vaultSalt": { "type": "string", "description": "PBKDF2 salt, hex" }
}
}
}
},
"VaultPutRequest": {
"type": "object",
"required": ["encryptedVault", "vaultSalt"],
"properties": {
"encryptedVault": { "type": "string", "maxLength": 8192 },
"vaultSalt": { "type": "string", "maxLength": 128 }
}
}
}
},
"security": [
{ "cookieAuth": [] },
{ "bearerAuth": [] }
],
"paths": {
"/health": {
"get": {
"summary": "Liveness check",
"tags": ["System"],
"security": [],
"responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HealthResponse" } } } } }
}
},
"/wallets": {
"get": {
"summary": "Get all wallets of authenticated user",
"tags": ["Wallets"],
"responses": {
"200": { "description": "List of wallets", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WalletsResponse" } } } },
"401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
}
},
"post": {
"summary": "Upsert wallets for authenticated user",
"description": "user_id берётся из JWT (sub). При первом обращении создаёт user-row автоматически. На конфликт (user_id, chain) — обновляет address + derivationPath.",
"tags": ["Wallets"],
"requestBody": {
"required": true,
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWalletsRequest" } } }
},
"responses": {
"201": { "description": "Created/updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WalletsResponse" } } } },
"400": { "description": "Invalid input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
}
}
},
"/wallets/{chain}/balance": {
"get": {
"summary": "Balance for user wallet in chain",
"tags": ["Wallet Ops"],
"parameters": [{ "name": "chain", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/Chain" } }],
"responses": {
"200": { "description": "Balance", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BalanceResponse" } } } },
"404": { "description": "Wallet for this chain not found" },
"502": { "description": "Upstream RPC error" }
}
}
},
"/wallets/{chain}/transactions": {
"get": {
"summary": "Transaction history for user wallet in chain",
"tags": ["Wallet Ops"],
"parameters": [
{ "name": "chain", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/Chain" } },
{ "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "minimum": 1, "maximum": 100 } }
],
"responses": {
"200": { "description": "List of transactions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TransactionsResponse" } } } },
"404": { "description": "Wallet for this chain not found" }
}
}
},
"/wallets/{chain}/send": {
"post": {
"summary": "Build unsigned send transaction (non-custodial)",
"description": "Возвращает unsigned tx. Клиент подписывает приватным ключом и broadcast'ит через /api/{btc,tron}/broadcast или RPC своей цепи.",
"tags": ["Wallet Ops"],
"parameters": [{ "name": "chain", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/Chain" } }],
"requestBody": {
"required": true,
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/SendRequest" } } }
},
"responses": {
"200": { "description": "Unsigned tx", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UnsignedTxResponse" } } } },
"400": { "description": "Invalid input" },
"404": { "description": "Wallet not found" },
"502": { "description": "Upstream RPC error" }
}
}
},
"/vault": {
"get": {
"summary": "Get user's encrypted mnemonic vault",
"tags": ["Vault"],
"responses": {
"200": { "description": "Encrypted vault blob", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VaultResponse" } } } },
"404": { "description": "Vault not yet stored" }
}
},
"put": {
"summary": "Save / replace encrypted mnemonic vault",
"description": "Vault — opaque blob (AES-GCM на стороне клиента). Сервер хранит как есть, не расшифровывает.",
"tags": ["Vault"],
"requestBody": {
"required": true,
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/VaultPutRequest" } } }
},
"responses": {
"200": { "description": "Saved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SuccessEmpty" } } } },
"400": { "description": "Invalid input" }
}
}
},
"/btc/utxos/{address}": {
"get": {
"summary": "Confirmed UTXOs for Bitcoin address",
"tags": ["BTC"],
"parameters": [{ "name": "address", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "UTXOs" }, "401": { "description": "Not authenticated" } }
}
},
"/btc/fee-estimates": {
"get": {
"summary": "Bitcoin fee estimates (sat/vB)",
"tags": ["BTC"],
"responses": { "200": { "description": "fast/normal/slow" }, "401": { "description": "Not authenticated" } }
}
},
"/btc/broadcast": {
"post": {
"summary": "Broadcast raw signed Bitcoin tx",
"tags": ["BTC"],
"requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["hex"], "properties": { "hex": { "type": "string" } } } } } },
"responses": { "200": { "description": "txid" }, "400": { "description": "Invalid hex" } }
}
},
"/tron/account/{address}": {
"get": {
"summary": "TRON account info + USDT (TRC20) balance",
"tags": ["TRON"],
"parameters": [{ "name": "address", "in": "path", "required": true, "schema": { "type": "string" } }],
"responses": { "200": { "description": "Account data" } }
}
},
"/tron/createtransaction": {
"post": {
"summary": "Build unsigned TRX transfer",
"tags": ["TRON"],
"requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["owner_address", "to_address", "amount"], "properties": { "owner_address": { "type": "string" }, "to_address": { "type": "string" }, "amount": { "type": "integer" } } } } } },
"responses": { "200": { "description": "Unsigned tx" } }
}
},
"/tron/triggersmartcontract": {
"post": {
"summary": "Build unsigned TRC20 contract call",
"tags": ["TRON"],
"requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object" } } } },
"responses": { "200": { "description": "Unsigned tx" } }
}
},
"/tron/broadcasttransaction": {
"post": {
"summary": "Broadcast signed TRON tx",
"tags": ["TRON"],
"requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object" } } } },
"responses": { "200": { "description": "Result" } }
}
},
"/sol/swap/quote": {
"get": {
"summary": "Jupiter swap quote (Solana)",
"tags": ["Solana"],
"parameters": [
{ "name": "inputMint", "in": "query", "required": true, "schema": { "type": "string" } },
{ "name": "outputMint", "in": "query", "required": true, "schema": { "type": "string" } },
{ "name": "amount", "in": "query", "required": true, "schema": { "type": "string" } },
{ "name": "slippageBps", "in": "query", "required": true, "schema": { "type": "integer" } }
],
"responses": { "200": { "description": "Quote" } }
}
},
"/sol/swap/build": {
"post": {
"summary": "Jupiter swap build",
"tags": ["Solana"],
"requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["quoteResponse", "userPublicKey"], "properties": { "quoteResponse": { "type": "object" }, "userPublicKey": { "type": "string" } } } } } },
"responses": { "200": { "description": "Swap tx" } }
}
},
"/tron/swap/quote": {
"get": {
"summary": "TRON swap quote (TRX <-> USDT)",
"tags": ["TRON Swap"],
"parameters": [
{ "name": "from", "in": "query", "required": true, "schema": { "type": "string", "enum": ["TRX", "USDT"] } },
{ "name": "to", "in": "query", "required": true, "schema": { "type": "string", "enum": ["TRX", "USDT"] } },
{ "name": "amount", "in": "query", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Quote" } }
}
},
"/tron/swap/build": {
"post": {
"summary": "Build TRON swap transactions",
"tags": ["TRON Swap"],
"requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["from", "to", "amount", "amountOutMin", "userAddress"], "properties": { "from": { "type": "string" }, "to": { "type": "string" }, "amount": { "type": "string" }, "amountOutMin": { "type": "string" }, "userAddress": { "type": "string" } } } } } },
"responses": { "200": { "description": "Unsigned txs" } }
}
},
"/tron/swap/broadcast": {
"post": {
"summary": "Broadcast signed TRON swap",
"tags": ["TRON Swap"],
"requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["signedTransaction"], "properties": { "signedTransaction": { "type": "object" } } } } } },
"responses": { "200": { "description": "Result" } }
}
},
"/bsc/swap/quote": {
"get": {
"summary": "BSC swap quote (PancakeSwap V2)",
"tags": ["BSC"],
"parameters": [
{ "name": "from", "in": "query", "required": true, "schema": { "type": "string", "enum": ["BNB", "USDT", "DOGE"] } },
{ "name": "to", "in": "query", "required": true, "schema": { "type": "string", "enum": ["BNB", "USDT", "DOGE"] } },
{ "name": "amount", "in": "query", "required": true, "schema": { "type": "string" } }
],
"responses": { "200": { "description": "Quote" } }
}
},
"/bsc/swap/build": {
"post": {
"summary": "Build BSC swap transactions",
"tags": ["BSC"],
"requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["from", "to", "amount", "amountOutMin", "userAddress"], "properties": { "from": { "type": "string" }, "to": { "type": "string" }, "amount": { "type": "string" }, "amountOutMin": { "type": "string" }, "userAddress": { "type": "string" } } } } } },
"responses": { "200": { "description": "Unsigned txs" } }
}
},
"/relay/quote/v2": {
"get": { "summary": "Relay bridge quote", "tags": ["Relay"], "responses": { "200": { "description": "Quote" } } }
},
"/relay/intents/status/v3": {
"get": { "summary": "Relay intent status", "tags": ["Relay"], "responses": { "200": { "description": "Status" } } }
},
"/relay/execute/{action}": {
"post": {
"summary": "Relay execute",
"tags": ["Relay"],
"parameters": [{ "name": "action", "in": "path", "required": true, "schema": { "type": "string" } }],
"requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object" } } } },
"responses": { "200": { "description": "Result" } }
}
}
}
}