forked from ezedike-evan/stellar-intel
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathopenapi.ts
More file actions
140 lines (125 loc) · 4.52 KB
/
Copy pathopenapi.ts
File metadata and controls
140 lines (125 loc) · 4.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import {
OpenAPIRegistry,
OpenApiGeneratorV31,
extendZodWithOpenApi,
} from '@asteasolutions/zod-to-openapi';
import { z } from 'zod';
import { STELLAR_PUBKEY_PATTERN, AMOUNT_PATTERN, AMOUNT_7DP_PATTERN } from '@/lib/patterns';
extendZodWithOpenApi(z);
export const registry = new OpenAPIRegistry();
// ─── Schemas (mirrors types/intent.ts — OpenAPI layer only) ───────────────────
const OfframpIntentSchema = registry.register(
'OfframpIntent',
z.object({
anchorId: z.string().min(1),
corridorId: z.string().min(1),
amount: z.string().regex(AMOUNT_7DP_PATTERN),
publicKey: z.string().regex(STELLAR_PUBKEY_PATTERN),
})
);
const SignedIntentEnvelopeSchema = registry.register(
'SignedIntentEnvelope',
z.object({
intent: OfframpIntentSchema,
hash: z.string().regex(/^[0-9a-f]{64}$/),
signature: z.string().min(1),
publicKey: z.string().regex(STELLAR_PUBKEY_PATTERN),
})
);
registry.register(
'IntentV1',
z.object({
id: z.string().min(1),
from: z.string().min(1).describe('Source asset identifier (e.g. "stellar:USDC:GA5...")'),
to: z.string().min(1).describe('Destination fiat identifier (e.g. "iso4217:NGN")'),
amount: z.string().regex(AMOUNT_PATTERN),
floor: z.string().regex(AMOUNT_PATTERN),
deadline: z.string().describe('RFC 3339 datetime after which the intent must not execute'),
recipient: z.string().min(1),
nonce: z
.string()
.regex(/^[0-9a-f]{32}$/i)
.describe('128-bit random hex for replay protection'),
metadata: z.record(z.string(), z.unknown()).optional(),
})
);
const OfframpRouteSchema = registry.register(
'OfframpRoute',
z.object({
anchorId: z.string(),
anchorDomain: z.string(),
corridorId: z.string(),
estimatedFee: z.string(),
estimatedReceived: z.string(),
})
);
const OfframpIntentResponseSchema = registry.register(
'OfframpIntentResponse',
z.object({
route: OfframpRouteSchema,
unsignedTx: z.string().describe('XDR-encoded unsigned Stellar transaction'),
quoteId: z.string().describe('Hex-encoded SHA-256 quote identifier'),
})
);
const ApiErrorSchema = registry.register(
'ApiError',
z.object({
code: z.string().describe('Machine-readable error code'),
message: z.string().describe('Human-readable error description'),
})
);
const IntentRequestSchema = registry.register(
'IntentRequest',
z.object({
type: z.literal('offramp'),
sourceAsset: z.string().min(1),
destinationAsset: z.string().min(1),
amount: z.string().regex(AMOUNT_PATTERN),
sender: z.string().min(1).describe('Stellar public key of the sender'),
recipient: z.string().min(1).describe('Destination address for the payout'),
})
);
// Suppress unused-variable warnings — schemas are referenced only via the registry
void SignedIntentEnvelopeSchema;
// ─── Route registrations ───────────────────────────────────────────────────────
registry.registerPath({
method: 'post',
path: '/api/intent/offramp',
summary: 'Submit an off-ramp intent',
description:
'Resolves an anchor route for the given asset corridor, builds an unsigned Stellar payment transaction, and returns a quote ID.',
tags: ['Intent'],
request: {
body: {
required: true,
content: { 'application/json': { schema: IntentRequestSchema } },
},
},
responses: {
200: {
description: 'Route resolved and unsigned transaction built',
content: { 'application/json': { schema: OfframpIntentResponseSchema } },
},
400: {
description: 'Validation error or no route found',
content: { 'application/json': { schema: ApiErrorSchema } },
},
500: {
description: 'Transaction build failure',
content: { 'application/json': { schema: ApiErrorSchema } },
},
},
});
// ─── Spec builder ──────────────────────────────────────────────────────────────
export function buildOpenApiSpec() {
const generator = new OpenApiGeneratorV31(registry.definitions);
return generator.generateDocument({
openapi: '3.1.0',
info: {
title: 'Stellar Intel API',
version: '1.2.0',
description: 'Intent router and anchor rate aggregation API for the Stellar Intel platform.',
},
servers: [{ url: 'https://stellar-intel.vercel.app', description: 'Production' }],
});
}