From b14339ca5ec5a31f87c3d896d787d72cf6c9e928 Mon Sep 17 00:00:00 2001 From: Codebane Date: Thu, 22 Oct 2026 11:29:06 +0100 Subject: [PATCH] Fix #524: [Docs] - Add API Reference Examples for Trades Endpoints --- apps/docs-site/pages/api-reference/trades.mdx | 217 ++++++++++++++++++ server/openapi.json | 158 ++++++++++++- 2 files changed, 364 insertions(+), 11 deletions(-) diff --git a/apps/docs-site/pages/api-reference/trades.mdx b/apps/docs-site/pages/api-reference/trades.mdx index d05339a..ae04c4a 100644 --- a/apps/docs-site/pages/api-reference/trades.mdx +++ b/apps/docs-site/pages/api-reference/trades.mdx @@ -303,3 +303,220 @@ Seller confirms delivery of the traded asset. Returns 202 immediately; `release_ --- + +# Trades API Reference + +Manage P2P airtime and data exchange trade offers. + +## Create Trade + +Create a new trade offer. + +### Request + +`POST /api/v1/trades` + +```bash +curl -X POST http://localhost:3001/api/v1/trades \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "asset_type": "MTN_AIRTIME", + "amount": 500, + "counterparty_address": "GBXRX2W5V3Z4Q42C3F6Q7QW8E9R0T1Y2U3I4O5P6A7S8D9F0G1H2J3K4" + }' +``` + +### Responses + +#### 201 Created +```json +{ + "id": "c3029f63-1234-4ef5-9f5e-9a28c3104e11", + "seller_id": "b1028e52-4111-4bc4-8e4d-8a17b2093d00", + "buyer_id": null, + "asset_type": "MTN_AIRTIME", + "amount": 500, + "status": "Active", + "contract_listing_id": "listing_stellar_9981", + "escrow_tx_hash": null, + "expires_at": "2026-12-31T23:59:59Z", + "created_at": "2026-10-01T10:00:00Z", + "updated_at": "2026-10-01T10:00:00Z" +} +``` + +#### 400 Bad Request +```json +{ + "error": "Invalid request body format" +} +``` + +#### 422 Unprocessable Entity +```json +{ + "error": "Validation failed", + "details": { + "amount": ["Amount must be greater than zero"] + } +} +``` + +--- + +## List Trades + +Retrieve paginated trade offers. + +### Request + +`GET /api/v1/trades?page=1&limit=20&status=Active` + +### Responses + +#### 200 OK +```json +{ + "trades": [ + { + "id": "c3029f63-1234-4ef5-9f5e-9a28c3104e11", + "seller_id": "b1028e52-4111-4bc4-8e4d-8a17b2093d00", + "buyer_id": null, + "asset_type": "MTN_AIRTIME", + "amount": 500, + "status": "Active", + "contract_listing_id": "listing_stellar_9981", + "escrow_tx_hash": null, + "expires_at": "2026-12-31T23:59:59Z", + "created_at": "2026-10-01T10:00:00Z", + "updated_at": "2026-10-01T10:00:00Z" + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 1, + "totalPages": 1 + } +} +``` + +#### 400 Bad Request +```json +{ + "error": "Invalid query parameters provided" +} +``` + +#### 422 Unprocessable Entity +```json +{ + "error": "Validation failed", + "details": { + "page": ["Expected number, received NaN"] + } +} +``` + +--- + +## Get Trade by ID + +Retrieve specific trade details. + +### Request + +`GET /api/v1/trades/c3029f63-1234-4ef5-9f5e-9a28c3104e11` + +### Responses + +#### 200 OK +```json +{ + "id": "c3029f63-1234-4ef5-9f5e-9a28c3104e11", + "seller_id": "b1028e52-4111-4bc4-8e4d-8a17b2093d00", + "buyer_id": "a2917d41-3333-4ab3-7d3c-7a06a1982c99", + "asset_type": "MTN_AIRTIME", + "amount": 500, + "status": "Locked", + "contract_listing_id": "listing_stellar_9981", + "escrow_tx_hash": "3a82f6f1c29e0789123456789abcdef0123456789abcdef0123456789abcdef0", + "expires_at": "2026-12-31T23:59:59Z", + "created_at": "2026-10-01T10:00:00Z", + "updated_at": "2026-10-01T10:05:00Z" +} +``` + +#### 400 Bad Request +```json +{ + "error": "Invalid trade ID format" +} +``` + +#### 404 Not Found +```json +{ + "error": "Trade offer not found" +} +``` + +--- + +## Update Trade Status + +Update status of an existing trade offer. + +### Request + +`PATCH /api/v1/trades/c3029f63-1234-4ef5-9f5e-9a28c3104e11/status` + +```json +{ + "status": "Locked" +} +``` + +### Responses + +#### 200 OK +```json +{ + "id": "c3029f63-1234-4ef5-9f5e-9a28c3104e11", + "seller_id": "b1028e52-4111-4bc4-8e4d-8a17b2093d00", + "buyer_id": "a2917d41-3333-4ab3-7d3c-7a06a1982c99", + "asset_type": "MTN_AIRTIME", + "amount": 500, + "status": "Locked", + "contract_listing_id": "listing_stellar_9981", + "escrow_tx_hash": "3a82f6f1c29e0789123456789abcdef0123456789abcdef0123456789abcdef0", + "expires_at": "2026-12-31T23:59:59Z", + "created_at": "2026-10-01T10:00:00Z", + "updated_at": "2026-10-01T10:05:00Z" +} +``` + +#### 400 Bad Request +```json +{ + "error": "Invalid status transition" +} +``` + +#### 404 Not Found +```json +{ + "error": "Trade offer not found" +} +``` + +#### 422 Unprocessable Entity +```json +{ + "error": "Validation failed", + "details": { + "status": ["Invalid status value"] + } +} +``` diff --git a/server/openapi.json b/server/openapi.json index adc8966..d957136 100644 --- a/server/openapi.json +++ b/server/openapi.json @@ -276,7 +276,8 @@ "properties": { "id": { "type": "string", - "format": "uuid" + "format": "uuid", + "example": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11" }, "seller_id": { "type": "string", @@ -296,7 +297,8 @@ "null" ], "format": "uuid", - "nullable": true + "nullable": true, + "example": "b1ffcd88-8d1a-3de7-aa5c-5aa8ac270b22" }, "asset_type": { "type": "string", @@ -327,15 +329,18 @@ }, "expires_at": { "type": "string", - "format": "date-time" + "format": "date-time", + "example": "2026-08-02T12:00:00Z" }, "created_at": { "type": "string", - "format": "date-time" + "format": "date-time", + "example": "2026-08-01T12:00:00Z" }, "updated_at": { "type": "string", - "format": "date-time" + "format": "date-time", + "example": "2026-08-01T12:00:00Z" } } }, @@ -391,7 +396,8 @@ "properties": { "xdr": { "type": "string", - "description": "Unsigned, already-simulated transaction envelope (base64 XDR)." + "description": "Unsigned, already-simulated transaction envelope (base64 XDR).", + "example": "AAAAAgAAAAD..." }, "networkPassphrase": { "type": "string", @@ -400,7 +406,8 @@ }, "publicKey": { "type": "string", - "description": "Buyer's Stellar account — the envelope's source account." + "description": "Buyer's Stellar account — the envelope's source account.", + "example": "GBXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ" } } }, @@ -1423,7 +1430,30 @@ "application/json": { "schema": { "$ref": "#/components/schemas/TradeListResponse" + }, + "example": { + "data": [ + { + "id": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", + "seller_handle": "@airflex_2f9a", + "buyer_id": null, + "asset_type": "MTN_AIRTIME", + "amount": 500, + "status": "Active", + "contract_listing_id": "42", + "escrow_tx_hash": null, + "expires_at": "2026-08-02T12:00:00Z", + "created_at": "2026-08-01T12:00:00Z", + "updated_at": "2026-08-01T12:00:00Z" } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 1, + "totalPages": 1 + } + } } } }, @@ -1433,6 +1463,9 @@ "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" + }, + "example": { + "error": "Invalid query parameters: page must be >= 1" } } } @@ -1486,9 +1519,25 @@ "$ref": "#/components/schemas/TradeOffer" } } + }, + "example": { + "data": { + "id": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", + "seller_id": "c2ddba77-2c9a-4ef8-bb6d-6bb9bd380a22", + "seller_handle": "@airflex_2f9a", + "buyer_id": null, + "asset_type": "MTN_AIRTIME", + "amount": 500, + "status": "Active", + "contract_listing_id": "42", + "escrow_tx_hash": null, + "expires_at": "2026-08-02T12:00:00Z", + "created_at": "2026-08-01T12:00:00Z", + "updated_at": "2026-08-01T12:00:00Z" } } } + } }, "400": { "description": "Seller wallet not found or contract call failed.", @@ -1496,6 +1545,9 @@ "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" + }, + "example": { + "error": "Seller stellar wallet not configured" } } } @@ -1504,7 +1556,22 @@ "$ref": "#/components/responses/Unauthorized" }, "422": { - "$ref": "#/components/responses/UnprocessableEntity" + "description": "Request body failed schema validation.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + }, + "example": { + "errors": [ + { + "field": "amount", + "message": "amount is required" + } + ] + } + } + } }, "500": { "$ref": "#/components/responses/InternalError" @@ -1542,9 +1609,25 @@ "$ref": "#/components/schemas/TradeOffer" } } + }, + "example": { + "data": { + "id": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", + "seller_id": "c2ddba77-2c9a-4ef8-bb6d-6bb9bd380a22", + "seller_handle": "@airflex_2f9a", + "buyer_id": null, + "asset_type": "MTN_AIRTIME", + "amount": 500, + "status": "Active", + "contract_listing_id": "42", + "escrow_tx_hash": null, + "expires_at": "2026-08-02T12:00:00Z", + "created_at": "2026-08-01T12:00:00Z", + "updated_at": "2026-08-01T12:00:00Z" } } } + } }, "404": { "$ref": "#/components/responses/NotFound" @@ -1590,9 +1673,16 @@ "$ref": "#/components/schemas/PrepareBuyResponse" } } + }, + "example": { + "data": { + "xdr": "AAAAAgAAAAD...", + "networkPassphrase": "Test SDF Network ; September 2015", + "publicKey": "GBXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ" } } } + } }, "400": { "description": "Trade not available, already locked, or buyer is the seller.", @@ -1600,6 +1690,9 @@ "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" + }, + "example": { + "error": "Cannot buy your own trade offer" } } } @@ -1661,9 +1754,25 @@ "$ref": "#/components/schemas/TradeOffer" } } + }, + "example": { + "data": { + "id": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", + "seller_id": "c2ddba77-2c9a-4ef8-bb6d-6bb9bd380a22", + "seller_handle": "@airflex_2f9a", + "buyer_id": "b1ffcd88-8d1a-3de7-aa5c-5aa8ac270b22", + "asset_type": "MTN_AIRTIME", + "amount": 500, + "status": "Locked", + "contract_listing_id": "42", + "escrow_tx_hash": "abc123txhash", + "expires_at": "2026-08-02T12:00:00Z", + "created_at": "2026-08-01T12:00:00Z", + "updated_at": "2026-08-01T12:30:00Z" } } } + } }, "400": { "description": "Trade not available, already locked, or buyer is the seller.", @@ -1671,6 +1780,9 @@ "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" + }, + "example": { + "error": "Trade is no longer available" } } } @@ -1682,7 +1794,22 @@ "$ref": "#/components/responses/NotFound" }, "422": { - "$ref": "#/components/responses/UnprocessableEntity" + "description": "Request body failed schema validation.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + }, + "example": { + "errors": [ + { + "field": "signedXdr", + "message": "signedXdr is required" + } + ] + } + } + } }, "500": { "$ref": "#/components/responses/InternalError" @@ -1722,13 +1849,19 @@ "type": "object", "properties": { "message": { - "type": "string" + "type": "string", + "example": "Delivery confirmation accepted" }, "tradeId": { "type": "string", - "format": "uuid" + "format": "uuid", + "example": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11" } } + }, + "example": { + "message": "Delivery confirmation accepted", + "tradeId": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11" } } } @@ -1739,6 +1872,9 @@ "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" + }, + "example": { + "error": "Trade must be in Locked state to confirm delivery" } } }