@dextopus/api-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,391 @@
1
+ type PartnerFee = {
2
+ recipient: string;
3
+ feeBPS: number;
4
+ };
5
+ type QuoteRequest = {
6
+ chainIdFrom: number;
7
+ chainIdTo?: number;
8
+ tokenIn: string;
9
+ tokenOut: string;
10
+ amountIn: string;
11
+ includeBridges?: string[];
12
+ partnerFees?: PartnerFee[];
13
+ };
14
+ type FeeBreakdown = {
15
+ type: 'protocol' | 'integrator' | 'gas' | 'bridge' | 'swap' | string;
16
+ amount: string;
17
+ token: string;
18
+ recipient?: string;
19
+ };
20
+ type FeeDetails = {
21
+ total: string;
22
+ breakdown: FeeBreakdown[];
23
+ };
24
+ type QuoteEdge = {
25
+ from: {
26
+ chainId: number;
27
+ tokenAddress: string;
28
+ };
29
+ to: {
30
+ chainId: number;
31
+ tokenAddress: string;
32
+ };
33
+ adaptor: string;
34
+ type: 'swap' | 'bridge';
35
+ amountIn: string;
36
+ estimatedAmountOut: string;
37
+ priceImpact: string;
38
+ fees: {
39
+ total: string;
40
+ breakdown: Array<{
41
+ type: string;
42
+ amount: string;
43
+ token?: string;
44
+ }>;
45
+ };
46
+ gasEstimate: string;
47
+ metadata: Record<string, unknown>;
48
+ timestamp: number;
49
+ };
50
+ type QuoteRoute = {
51
+ quoteId: string;
52
+ path: QuoteEdge[];
53
+ sourceToken: {
54
+ chainId: number;
55
+ address: string;
56
+ symbol: string;
57
+ decimals: number;
58
+ };
59
+ destToken: {
60
+ chainId: number;
61
+ address: string;
62
+ symbol: string;
63
+ decimals: number;
64
+ };
65
+ amountIn: string;
66
+ amountOut: string;
67
+ fees: FeeDetails;
68
+ priceImpact: string;
69
+ estimatedGas: string;
70
+ expiresAt: number;
71
+ };
72
+ type QuoteAlternativeRoute = {
73
+ path: QuoteEdge[];
74
+ amountOut: string;
75
+ fees: FeeDetails;
76
+ };
77
+ type QuoteResponse = {
78
+ quoteId: string;
79
+ bestRoute: QuoteRoute;
80
+ alternativeRoutes: QuoteAlternativeRoute[];
81
+ };
82
+ type BuildTransactionRequest = {
83
+ quoteId: string;
84
+ userAddress: string;
85
+ recipient?: string;
86
+ partnerFees?: PartnerFee[];
87
+ simulate?: boolean;
88
+ };
89
+ type EvmTransactionPayload = {
90
+ from: string;
91
+ to: string;
92
+ data: string;
93
+ value: string;
94
+ chainId: number;
95
+ gasLimit?: string;
96
+ gasPrice?: string;
97
+ maxFeePerGas?: string;
98
+ maxPriorityFeePerGas?: string;
99
+ nonce?: number;
100
+ };
101
+ type TronTransactionPayload = {
102
+ from: string;
103
+ to: string;
104
+ input: string;
105
+ callValue: string;
106
+ chainId: number;
107
+ };
108
+ type TransactionPayload = EvmTransactionPayload | TronTransactionPayload;
109
+ type TransactionStep = {
110
+ step: number;
111
+ adaptor: string;
112
+ type: 'approval' | 'diamond';
113
+ chainId: number;
114
+ transaction: TransactionPayload;
115
+ description: string;
116
+ };
117
+ type TransactionSimulationStep = {
118
+ step: number;
119
+ type: string;
120
+ adaptor: string;
121
+ chainId: number;
122
+ estimated: boolean;
123
+ gas?: string;
124
+ error?: string;
125
+ };
126
+ type TransactionSimulation = {
127
+ allEstimated: boolean;
128
+ steps: TransactionSimulationStep[];
129
+ };
130
+ type BuildTransactionResponse = {
131
+ quoteId: string;
132
+ transactions: TransactionStep[];
133
+ totalSteps: number;
134
+ expiresAt: number;
135
+ simulation?: TransactionSimulation;
136
+ };
137
+ type DepositFee = {
138
+ recipient: string;
139
+ fee: number;
140
+ };
141
+ type DepositQuoteRequest = {
142
+ originChainId: number;
143
+ destinationChainId: number;
144
+ originAsset: string;
145
+ destinationAsset: string;
146
+ amount: string;
147
+ recipient: string;
148
+ refundTo?: string;
149
+ user?: string;
150
+ slippageBps?: number;
151
+ dry?: boolean;
152
+ partnerFees?: DepositFee[];
153
+ /**
154
+ * If provided, amount is treated as human-readable (e.g., "10" for 10 USDC)
155
+ * and will be converted to smallest unit using this decimals value.
156
+ * If not provided, amount is treated as smallest unit (backward compatible).
157
+ */
158
+ decimals?: number;
159
+ /**
160
+ * Request a static/reusable deposit address.
161
+ * When true, requests a deposit address that:
162
+ * - Can be reused for multiple deposits
163
+ * - Remains valid after quote rate expires (rate recalculated at deposit time)
164
+ * - Accepts different tokens (e.g., send USDC when quote was for SOL)
165
+ * Note: Only available for supported routes. Check supportsStaticAddress field.
166
+ */
167
+ static?: boolean;
168
+ };
169
+ type DepositStatusParams = {
170
+ depositRequestId?: string;
171
+ depositAddress?: string;
172
+ requestId?: string;
173
+ };
174
+ type DepositSubmitRequest = {
175
+ depositRequestId?: string;
176
+ depositAddress?: string;
177
+ txHash: string;
178
+ };
179
+ type DepositQuoteResponse = {
180
+ success: boolean;
181
+ depositRequestId: string;
182
+ depositAddress: string;
183
+ isStaticAddress?: boolean;
184
+ upstreamRequestId?: string;
185
+ upstreamQuoteId?: string;
186
+ amountOut?: string;
187
+ minAmountOut?: string;
188
+ status?: string;
189
+ sentAppFees?: DepositFee[];
190
+ effectiveUpstreamAppFees?: DepositFee[];
191
+ expiresInSeconds?: number;
192
+ };
193
+ type DepositStatusResponse = {
194
+ success: boolean;
195
+ depositRequestId: string;
196
+ depositAddress?: string;
197
+ isStaticAddress?: boolean;
198
+ upstreamRequestId?: string;
199
+ status?: string;
200
+ executionStatus?: string;
201
+ sentAppFees?: DepositFee[];
202
+ effectiveUpstreamAppFees?: DepositFee[];
203
+ originTransactionHashes?: string[];
204
+ destinationTransactionHashes?: string[];
205
+ raw?: Record<string, unknown>;
206
+ };
207
+ type DepositSubmitResponse = {
208
+ success: boolean;
209
+ depositRequestId: string;
210
+ depositAddress: string;
211
+ result: Record<string, unknown>;
212
+ };
213
+ type Currency = {
214
+ address?: string;
215
+ id?: string;
216
+ symbol?: string;
217
+ name?: string;
218
+ decimals?: number;
219
+ };
220
+ type Chain = {
221
+ chainId?: number;
222
+ name?: string;
223
+ solverCurrencies: Currency[];
224
+ supportsStaticAddress?: boolean;
225
+ };
226
+ type DepositToken = {
227
+ address: string;
228
+ symbol: string;
229
+ blockchain: string;
230
+ chainId?: number;
231
+ decimals?: number;
232
+ supportsStaticAddress: boolean;
233
+ };
234
+ type DepositTokensResponse = {
235
+ success: boolean;
236
+ chains: Chain[];
237
+ tokens: DepositToken[];
238
+ countChains: number;
239
+ countTokens: number;
240
+ };
241
+ /** @deprecated Use Currency instead */
242
+ type RelayCurrency = Currency;
243
+ /** @deprecated Use Chain instead */
244
+ type RelayChain = Chain;
245
+ /** @deprecated Use DepositToken instead */
246
+ type NearToken = {
247
+ assetId: string;
248
+ decimals: number;
249
+ blockchain: string;
250
+ symbol: string;
251
+ price?: number;
252
+ priceUpdatedAt?: string;
253
+ contractAddress?: string | null;
254
+ };
255
+ /** @deprecated Use DepositToken instead */
256
+ type UnifiedToken = DepositToken;
257
+ type AddressKind = 'evm' | 'near' | 'solana' | 'tron' | 'bitcoin' | 'litecoin' | 'stellar' | 'sui' | 'ton' | 'xrp';
258
+ type DepositDestination = {
259
+ currency: string;
260
+ symbol?: string;
261
+ blockchain?: string;
262
+ destinationChainId?: number;
263
+ decimals?: number;
264
+ addressKind: AddressKind | null;
265
+ supportsStaticAddress: boolean;
266
+ };
267
+ type DepositDestinationChain = {
268
+ blockchain: string;
269
+ chainId?: number;
270
+ addressKind: AddressKind | null;
271
+ count: number;
272
+ supportsStaticAddress: boolean;
273
+ };
274
+ type DepositDestinationsResponse = {
275
+ success: boolean;
276
+ originAssetId?: string;
277
+ originAddress?: string;
278
+ originAddressKind: AddressKind | null;
279
+ destinations: DepositDestination[];
280
+ destinationChains: DepositDestinationChain[];
281
+ count: number;
282
+ };
283
+ type DepositSource = {
284
+ currency: string;
285
+ symbol?: string;
286
+ blockchain?: string;
287
+ sourceChainId?: number;
288
+ decimals?: number;
289
+ addressKind: AddressKind | null;
290
+ supportsStaticAddress: boolean;
291
+ };
292
+ type DepositSourceChain = {
293
+ blockchain: string;
294
+ chainId?: number;
295
+ addressKind: AddressKind | null;
296
+ count: number;
297
+ supportsStaticAddress: boolean;
298
+ };
299
+ type DepositSourcesResponse = {
300
+ success: boolean;
301
+ destinationAssetId?: string;
302
+ destinationAddress?: string;
303
+ destinationAddressKind: AddressKind | null;
304
+ sources: DepositSource[];
305
+ sourceChains: DepositSourceChain[];
306
+ count: number;
307
+ };
308
+ type DepositDestinationsParams = {
309
+ originAssetId?: string;
310
+ originAddress?: string;
311
+ originChainId?: number;
312
+ };
313
+ type DepositSourcesParams = {
314
+ destinationAssetId?: string;
315
+ destinationAddress?: string;
316
+ destinationChainId?: number;
317
+ };
318
+ type ValidateAddressRequest = {
319
+ chainType: AddressKind;
320
+ address: string;
321
+ };
322
+ type ValidateAddressResponse = {
323
+ success: boolean;
324
+ valid: boolean;
325
+ reason?: string;
326
+ };
327
+ type HealthResponse = {
328
+ status: 'healthy' | 'degraded';
329
+ service: string;
330
+ version: string;
331
+ timestamp: number;
332
+ dependencies: Record<string, 'up' | 'down'>;
333
+ };
334
+ type ApiErrorDetail = {
335
+ field: string;
336
+ message: string;
337
+ };
338
+ type ApiErrorShape = {
339
+ error?: string;
340
+ message?: string;
341
+ errorCode?: string;
342
+ quoteId?: string;
343
+ expiresAt?: number;
344
+ expiredAt?: string;
345
+ details?: ApiErrorDetail[];
346
+ };
347
+
348
+ type ApiClientOptions = {
349
+ baseUrl?: string;
350
+ apiKey?: string;
351
+ fetch?: typeof fetch;
352
+ timeoutMs?: number;
353
+ };
354
+ declare class ApiError extends Error {
355
+ status: number;
356
+ body?: ApiErrorShape | string;
357
+ constructor(status: number, message: string, body?: ApiErrorShape | string);
358
+ }
359
+ /**
360
+ * Convert human-readable amount to smallest unit
361
+ * @param amount Human-readable amount (e.g., "10" for 10 USDC)
362
+ * @param decimals Token decimals (e.g., 6 for USDC, 9 for SOL)
363
+ * @returns Amount in smallest unit as string
364
+ * @example toSmallestUnit("10", 6) // Returns "10000000" for 10 USDC
365
+ * @example toSmallestUnit("1.5", 9) // Returns "1500000000" for 1.5 SOL
366
+ */
367
+ declare function toSmallestUnit(amount: string, decimals: number): string;
368
+ /**
369
+ * Convert smallest unit amount to human-readable format
370
+ * @param amount Amount in smallest unit (e.g., "10000000" for USDC)
371
+ * @param decimals Token decimals (e.g., 6 for USDC, 9 for SOL)
372
+ * @returns Human-readable amount as string
373
+ * @example fromSmallestUnit("10000000", 6) // Returns "10" for 10 USDC
374
+ * @example fromSmallestUnit("1500000000", 9) // Returns "1.5" for 1.5 SOL
375
+ */
376
+ declare function fromSmallestUnit(amount: string, decimals: number): string;
377
+ declare function createApiClient(options?: ApiClientOptions): {
378
+ quote: (payload: QuoteRequest) => Promise<QuoteResponse>;
379
+ buildTransaction: (payload: BuildTransactionRequest) => Promise<BuildTransactionResponse>;
380
+ getQuoteById: (quoteId: string) => Promise<QuoteResponse>;
381
+ health: () => Promise<HealthResponse>;
382
+ depositQuote: (payload: DepositQuoteRequest) => Promise<DepositQuoteResponse>;
383
+ depositStatus: (params: DepositStatusParams) => Promise<DepositStatusResponse>;
384
+ depositSubmit: (payload: DepositSubmitRequest) => Promise<DepositSubmitResponse>;
385
+ depositTokens: () => Promise<DepositTokensResponse>;
386
+ depositDestinations: (params: DepositDestinationsParams) => Promise<DepositDestinationsResponse>;
387
+ depositSources: (params: DepositSourcesParams) => Promise<DepositSourcesResponse>;
388
+ depositValidateAddress: (payload: ValidateAddressRequest) => Promise<ValidateAddressResponse>;
389
+ };
390
+
391
+ export { type AddressKind, ApiError, type ApiErrorDetail, type ApiErrorShape, type BuildTransactionRequest, type BuildTransactionResponse, type Chain, type Currency, type DepositDestination, type DepositDestinationChain, type DepositDestinationsParams, type DepositDestinationsResponse, type DepositFee, type DepositQuoteRequest, type DepositQuoteResponse, type DepositSource, type DepositSourceChain, type DepositSourcesParams, type DepositSourcesResponse, type DepositStatusParams, type DepositStatusResponse, type DepositSubmitRequest, type DepositSubmitResponse, type DepositToken, type DepositTokensResponse, type EvmTransactionPayload, type FeeBreakdown, type FeeDetails, type HealthResponse, type NearToken, type PartnerFee, type QuoteAlternativeRoute, type QuoteEdge, type QuoteRequest, type QuoteResponse, type QuoteRoute, type RelayChain, type RelayCurrency, type TransactionPayload, type TransactionSimulation, type TransactionSimulationStep, type TransactionStep, type TronTransactionPayload, type UnifiedToken, type ValidateAddressRequest, type ValidateAddressResponse, createApiClient, fromSmallestUnit, toSmallestUnit };
@@ -0,0 +1,391 @@
1
+ type PartnerFee = {
2
+ recipient: string;
3
+ feeBPS: number;
4
+ };
5
+ type QuoteRequest = {
6
+ chainIdFrom: number;
7
+ chainIdTo?: number;
8
+ tokenIn: string;
9
+ tokenOut: string;
10
+ amountIn: string;
11
+ includeBridges?: string[];
12
+ partnerFees?: PartnerFee[];
13
+ };
14
+ type FeeBreakdown = {
15
+ type: 'protocol' | 'integrator' | 'gas' | 'bridge' | 'swap' | string;
16
+ amount: string;
17
+ token: string;
18
+ recipient?: string;
19
+ };
20
+ type FeeDetails = {
21
+ total: string;
22
+ breakdown: FeeBreakdown[];
23
+ };
24
+ type QuoteEdge = {
25
+ from: {
26
+ chainId: number;
27
+ tokenAddress: string;
28
+ };
29
+ to: {
30
+ chainId: number;
31
+ tokenAddress: string;
32
+ };
33
+ adaptor: string;
34
+ type: 'swap' | 'bridge';
35
+ amountIn: string;
36
+ estimatedAmountOut: string;
37
+ priceImpact: string;
38
+ fees: {
39
+ total: string;
40
+ breakdown: Array<{
41
+ type: string;
42
+ amount: string;
43
+ token?: string;
44
+ }>;
45
+ };
46
+ gasEstimate: string;
47
+ metadata: Record<string, unknown>;
48
+ timestamp: number;
49
+ };
50
+ type QuoteRoute = {
51
+ quoteId: string;
52
+ path: QuoteEdge[];
53
+ sourceToken: {
54
+ chainId: number;
55
+ address: string;
56
+ symbol: string;
57
+ decimals: number;
58
+ };
59
+ destToken: {
60
+ chainId: number;
61
+ address: string;
62
+ symbol: string;
63
+ decimals: number;
64
+ };
65
+ amountIn: string;
66
+ amountOut: string;
67
+ fees: FeeDetails;
68
+ priceImpact: string;
69
+ estimatedGas: string;
70
+ expiresAt: number;
71
+ };
72
+ type QuoteAlternativeRoute = {
73
+ path: QuoteEdge[];
74
+ amountOut: string;
75
+ fees: FeeDetails;
76
+ };
77
+ type QuoteResponse = {
78
+ quoteId: string;
79
+ bestRoute: QuoteRoute;
80
+ alternativeRoutes: QuoteAlternativeRoute[];
81
+ };
82
+ type BuildTransactionRequest = {
83
+ quoteId: string;
84
+ userAddress: string;
85
+ recipient?: string;
86
+ partnerFees?: PartnerFee[];
87
+ simulate?: boolean;
88
+ };
89
+ type EvmTransactionPayload = {
90
+ from: string;
91
+ to: string;
92
+ data: string;
93
+ value: string;
94
+ chainId: number;
95
+ gasLimit?: string;
96
+ gasPrice?: string;
97
+ maxFeePerGas?: string;
98
+ maxPriorityFeePerGas?: string;
99
+ nonce?: number;
100
+ };
101
+ type TronTransactionPayload = {
102
+ from: string;
103
+ to: string;
104
+ input: string;
105
+ callValue: string;
106
+ chainId: number;
107
+ };
108
+ type TransactionPayload = EvmTransactionPayload | TronTransactionPayload;
109
+ type TransactionStep = {
110
+ step: number;
111
+ adaptor: string;
112
+ type: 'approval' | 'diamond';
113
+ chainId: number;
114
+ transaction: TransactionPayload;
115
+ description: string;
116
+ };
117
+ type TransactionSimulationStep = {
118
+ step: number;
119
+ type: string;
120
+ adaptor: string;
121
+ chainId: number;
122
+ estimated: boolean;
123
+ gas?: string;
124
+ error?: string;
125
+ };
126
+ type TransactionSimulation = {
127
+ allEstimated: boolean;
128
+ steps: TransactionSimulationStep[];
129
+ };
130
+ type BuildTransactionResponse = {
131
+ quoteId: string;
132
+ transactions: TransactionStep[];
133
+ totalSteps: number;
134
+ expiresAt: number;
135
+ simulation?: TransactionSimulation;
136
+ };
137
+ type DepositFee = {
138
+ recipient: string;
139
+ fee: number;
140
+ };
141
+ type DepositQuoteRequest = {
142
+ originChainId: number;
143
+ destinationChainId: number;
144
+ originAsset: string;
145
+ destinationAsset: string;
146
+ amount: string;
147
+ recipient: string;
148
+ refundTo?: string;
149
+ user?: string;
150
+ slippageBps?: number;
151
+ dry?: boolean;
152
+ partnerFees?: DepositFee[];
153
+ /**
154
+ * If provided, amount is treated as human-readable (e.g., "10" for 10 USDC)
155
+ * and will be converted to smallest unit using this decimals value.
156
+ * If not provided, amount is treated as smallest unit (backward compatible).
157
+ */
158
+ decimals?: number;
159
+ /**
160
+ * Request a static/reusable deposit address.
161
+ * When true, requests a deposit address that:
162
+ * - Can be reused for multiple deposits
163
+ * - Remains valid after quote rate expires (rate recalculated at deposit time)
164
+ * - Accepts different tokens (e.g., send USDC when quote was for SOL)
165
+ * Note: Only available for supported routes. Check supportsStaticAddress field.
166
+ */
167
+ static?: boolean;
168
+ };
169
+ type DepositStatusParams = {
170
+ depositRequestId?: string;
171
+ depositAddress?: string;
172
+ requestId?: string;
173
+ };
174
+ type DepositSubmitRequest = {
175
+ depositRequestId?: string;
176
+ depositAddress?: string;
177
+ txHash: string;
178
+ };
179
+ type DepositQuoteResponse = {
180
+ success: boolean;
181
+ depositRequestId: string;
182
+ depositAddress: string;
183
+ isStaticAddress?: boolean;
184
+ upstreamRequestId?: string;
185
+ upstreamQuoteId?: string;
186
+ amountOut?: string;
187
+ minAmountOut?: string;
188
+ status?: string;
189
+ sentAppFees?: DepositFee[];
190
+ effectiveUpstreamAppFees?: DepositFee[];
191
+ expiresInSeconds?: number;
192
+ };
193
+ type DepositStatusResponse = {
194
+ success: boolean;
195
+ depositRequestId: string;
196
+ depositAddress?: string;
197
+ isStaticAddress?: boolean;
198
+ upstreamRequestId?: string;
199
+ status?: string;
200
+ executionStatus?: string;
201
+ sentAppFees?: DepositFee[];
202
+ effectiveUpstreamAppFees?: DepositFee[];
203
+ originTransactionHashes?: string[];
204
+ destinationTransactionHashes?: string[];
205
+ raw?: Record<string, unknown>;
206
+ };
207
+ type DepositSubmitResponse = {
208
+ success: boolean;
209
+ depositRequestId: string;
210
+ depositAddress: string;
211
+ result: Record<string, unknown>;
212
+ };
213
+ type Currency = {
214
+ address?: string;
215
+ id?: string;
216
+ symbol?: string;
217
+ name?: string;
218
+ decimals?: number;
219
+ };
220
+ type Chain = {
221
+ chainId?: number;
222
+ name?: string;
223
+ solverCurrencies: Currency[];
224
+ supportsStaticAddress?: boolean;
225
+ };
226
+ type DepositToken = {
227
+ address: string;
228
+ symbol: string;
229
+ blockchain: string;
230
+ chainId?: number;
231
+ decimals?: number;
232
+ supportsStaticAddress: boolean;
233
+ };
234
+ type DepositTokensResponse = {
235
+ success: boolean;
236
+ chains: Chain[];
237
+ tokens: DepositToken[];
238
+ countChains: number;
239
+ countTokens: number;
240
+ };
241
+ /** @deprecated Use Currency instead */
242
+ type RelayCurrency = Currency;
243
+ /** @deprecated Use Chain instead */
244
+ type RelayChain = Chain;
245
+ /** @deprecated Use DepositToken instead */
246
+ type NearToken = {
247
+ assetId: string;
248
+ decimals: number;
249
+ blockchain: string;
250
+ symbol: string;
251
+ price?: number;
252
+ priceUpdatedAt?: string;
253
+ contractAddress?: string | null;
254
+ };
255
+ /** @deprecated Use DepositToken instead */
256
+ type UnifiedToken = DepositToken;
257
+ type AddressKind = 'evm' | 'near' | 'solana' | 'tron' | 'bitcoin' | 'litecoin' | 'stellar' | 'sui' | 'ton' | 'xrp';
258
+ type DepositDestination = {
259
+ currency: string;
260
+ symbol?: string;
261
+ blockchain?: string;
262
+ destinationChainId?: number;
263
+ decimals?: number;
264
+ addressKind: AddressKind | null;
265
+ supportsStaticAddress: boolean;
266
+ };
267
+ type DepositDestinationChain = {
268
+ blockchain: string;
269
+ chainId?: number;
270
+ addressKind: AddressKind | null;
271
+ count: number;
272
+ supportsStaticAddress: boolean;
273
+ };
274
+ type DepositDestinationsResponse = {
275
+ success: boolean;
276
+ originAssetId?: string;
277
+ originAddress?: string;
278
+ originAddressKind: AddressKind | null;
279
+ destinations: DepositDestination[];
280
+ destinationChains: DepositDestinationChain[];
281
+ count: number;
282
+ };
283
+ type DepositSource = {
284
+ currency: string;
285
+ symbol?: string;
286
+ blockchain?: string;
287
+ sourceChainId?: number;
288
+ decimals?: number;
289
+ addressKind: AddressKind | null;
290
+ supportsStaticAddress: boolean;
291
+ };
292
+ type DepositSourceChain = {
293
+ blockchain: string;
294
+ chainId?: number;
295
+ addressKind: AddressKind | null;
296
+ count: number;
297
+ supportsStaticAddress: boolean;
298
+ };
299
+ type DepositSourcesResponse = {
300
+ success: boolean;
301
+ destinationAssetId?: string;
302
+ destinationAddress?: string;
303
+ destinationAddressKind: AddressKind | null;
304
+ sources: DepositSource[];
305
+ sourceChains: DepositSourceChain[];
306
+ count: number;
307
+ };
308
+ type DepositDestinationsParams = {
309
+ originAssetId?: string;
310
+ originAddress?: string;
311
+ originChainId?: number;
312
+ };
313
+ type DepositSourcesParams = {
314
+ destinationAssetId?: string;
315
+ destinationAddress?: string;
316
+ destinationChainId?: number;
317
+ };
318
+ type ValidateAddressRequest = {
319
+ chainType: AddressKind;
320
+ address: string;
321
+ };
322
+ type ValidateAddressResponse = {
323
+ success: boolean;
324
+ valid: boolean;
325
+ reason?: string;
326
+ };
327
+ type HealthResponse = {
328
+ status: 'healthy' | 'degraded';
329
+ service: string;
330
+ version: string;
331
+ timestamp: number;
332
+ dependencies: Record<string, 'up' | 'down'>;
333
+ };
334
+ type ApiErrorDetail = {
335
+ field: string;
336
+ message: string;
337
+ };
338
+ type ApiErrorShape = {
339
+ error?: string;
340
+ message?: string;
341
+ errorCode?: string;
342
+ quoteId?: string;
343
+ expiresAt?: number;
344
+ expiredAt?: string;
345
+ details?: ApiErrorDetail[];
346
+ };
347
+
348
+ type ApiClientOptions = {
349
+ baseUrl?: string;
350
+ apiKey?: string;
351
+ fetch?: typeof fetch;
352
+ timeoutMs?: number;
353
+ };
354
+ declare class ApiError extends Error {
355
+ status: number;
356
+ body?: ApiErrorShape | string;
357
+ constructor(status: number, message: string, body?: ApiErrorShape | string);
358
+ }
359
+ /**
360
+ * Convert human-readable amount to smallest unit
361
+ * @param amount Human-readable amount (e.g., "10" for 10 USDC)
362
+ * @param decimals Token decimals (e.g., 6 for USDC, 9 for SOL)
363
+ * @returns Amount in smallest unit as string
364
+ * @example toSmallestUnit("10", 6) // Returns "10000000" for 10 USDC
365
+ * @example toSmallestUnit("1.5", 9) // Returns "1500000000" for 1.5 SOL
366
+ */
367
+ declare function toSmallestUnit(amount: string, decimals: number): string;
368
+ /**
369
+ * Convert smallest unit amount to human-readable format
370
+ * @param amount Amount in smallest unit (e.g., "10000000" for USDC)
371
+ * @param decimals Token decimals (e.g., 6 for USDC, 9 for SOL)
372
+ * @returns Human-readable amount as string
373
+ * @example fromSmallestUnit("10000000", 6) // Returns "10" for 10 USDC
374
+ * @example fromSmallestUnit("1500000000", 9) // Returns "1.5" for 1.5 SOL
375
+ */
376
+ declare function fromSmallestUnit(amount: string, decimals: number): string;
377
+ declare function createApiClient(options?: ApiClientOptions): {
378
+ quote: (payload: QuoteRequest) => Promise<QuoteResponse>;
379
+ buildTransaction: (payload: BuildTransactionRequest) => Promise<BuildTransactionResponse>;
380
+ getQuoteById: (quoteId: string) => Promise<QuoteResponse>;
381
+ health: () => Promise<HealthResponse>;
382
+ depositQuote: (payload: DepositQuoteRequest) => Promise<DepositQuoteResponse>;
383
+ depositStatus: (params: DepositStatusParams) => Promise<DepositStatusResponse>;
384
+ depositSubmit: (payload: DepositSubmitRequest) => Promise<DepositSubmitResponse>;
385
+ depositTokens: () => Promise<DepositTokensResponse>;
386
+ depositDestinations: (params: DepositDestinationsParams) => Promise<DepositDestinationsResponse>;
387
+ depositSources: (params: DepositSourcesParams) => Promise<DepositSourcesResponse>;
388
+ depositValidateAddress: (payload: ValidateAddressRequest) => Promise<ValidateAddressResponse>;
389
+ };
390
+
391
+ export { type AddressKind, ApiError, type ApiErrorDetail, type ApiErrorShape, type BuildTransactionRequest, type BuildTransactionResponse, type Chain, type Currency, type DepositDestination, type DepositDestinationChain, type DepositDestinationsParams, type DepositDestinationsResponse, type DepositFee, type DepositQuoteRequest, type DepositQuoteResponse, type DepositSource, type DepositSourceChain, type DepositSourcesParams, type DepositSourcesResponse, type DepositStatusParams, type DepositStatusResponse, type DepositSubmitRequest, type DepositSubmitResponse, type DepositToken, type DepositTokensResponse, type EvmTransactionPayload, type FeeBreakdown, type FeeDetails, type HealthResponse, type NearToken, type PartnerFee, type QuoteAlternativeRoute, type QuoteEdge, type QuoteRequest, type QuoteResponse, type QuoteRoute, type RelayChain, type RelayCurrency, type TransactionPayload, type TransactionSimulation, type TransactionSimulationStep, type TransactionStep, type TronTransactionPayload, type UnifiedToken, type ValidateAddressRequest, type ValidateAddressResponse, createApiClient, fromSmallestUnit, toSmallestUnit };
package/dist/index.js ADDED
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ApiError: () => ApiError,
24
+ createApiClient: () => createApiClient,
25
+ fromSmallestUnit: () => fromSmallestUnit,
26
+ toSmallestUnit: () => toSmallestUnit
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+
30
+ // src/client.ts
31
+ var ApiError = class extends Error {
32
+ status;
33
+ body;
34
+ constructor(status, message, body) {
35
+ super(message);
36
+ this.name = "ApiError";
37
+ this.status = status;
38
+ this.body = body;
39
+ }
40
+ };
41
+ function buildHeaders(apiKey) {
42
+ const headers = { "content-type": "application/json" };
43
+ if (apiKey) headers["x-api-key"] = apiKey;
44
+ return headers;
45
+ }
46
+ function toSmallestUnit(amount, decimals) {
47
+ const num = parseFloat(amount);
48
+ if (isNaN(num)) {
49
+ throw new Error(`Invalid amount: ${amount}`);
50
+ }
51
+ const multiplier = Math.pow(10, decimals);
52
+ const smallestUnit = Math.floor(num * multiplier);
53
+ return smallestUnit.toString();
54
+ }
55
+ function fromSmallestUnit(amount, decimals) {
56
+ const num = parseFloat(amount);
57
+ if (isNaN(num)) {
58
+ throw new Error(`Invalid amount: ${amount}`);
59
+ }
60
+ const divisor = Math.pow(10, decimals);
61
+ return (num / divisor).toString();
62
+ }
63
+ async function requestJson(fetcher, url, options, timeoutMs) {
64
+ const controller = new AbortController();
65
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
66
+ try {
67
+ const res = await fetcher(url, { ...options, signal: controller.signal });
68
+ const text = await res.text();
69
+ const body = text ? JSON.parse(text) : void 0;
70
+ if (!res.ok) {
71
+ throw new ApiError(res.status, body?.message || res.statusText, body || text);
72
+ }
73
+ return body;
74
+ } finally {
75
+ clearTimeout(timeout);
76
+ }
77
+ }
78
+ function createApiClient(options = {}) {
79
+ const rawBaseUrl = options.baseUrl || "https://swap-api.dextopus.com";
80
+ const trimmedBaseUrl = rawBaseUrl.replace(/\/+$/, "");
81
+ const baseUrl = trimmedBaseUrl.endsWith("/api") ? trimmedBaseUrl.slice(0, -4) : trimmedBaseUrl;
82
+ const apiKey = options.apiKey;
83
+ const fetcher = options.fetch || fetch;
84
+ const timeoutMs = options.timeoutMs ?? 1e4;
85
+ const headers = buildHeaders(apiKey);
86
+ return {
87
+ quote: (payload) => requestJson(
88
+ fetcher,
89
+ `${baseUrl}/api/quote`,
90
+ { method: "POST", headers, body: JSON.stringify(payload) },
91
+ timeoutMs
92
+ ),
93
+ buildTransaction: (payload) => requestJson(
94
+ fetcher,
95
+ `${baseUrl}/api/build-transaction`,
96
+ { method: "POST", headers, body: JSON.stringify(payload) },
97
+ timeoutMs
98
+ ),
99
+ getQuoteById: (quoteId) => requestJson(
100
+ fetcher,
101
+ `${baseUrl}/api/quote/${quoteId}`,
102
+ { method: "GET", headers },
103
+ timeoutMs
104
+ ),
105
+ health: () => requestJson(
106
+ fetcher,
107
+ `${baseUrl}/health`,
108
+ { method: "GET", headers },
109
+ timeoutMs
110
+ ),
111
+ depositQuote: (payload) => {
112
+ const apiPayload = { ...payload };
113
+ if (payload.decimals !== void 0) {
114
+ apiPayload.amount = toSmallestUnit(payload.amount, payload.decimals);
115
+ delete apiPayload.decimals;
116
+ }
117
+ return requestJson(
118
+ fetcher,
119
+ `${baseUrl}/api/deposit/quote`,
120
+ { method: "POST", headers, body: JSON.stringify(apiPayload) },
121
+ timeoutMs
122
+ );
123
+ },
124
+ depositStatus: (params) => {
125
+ const query = new URLSearchParams(
126
+ Object.entries(params).filter(([, value]) => value !== void 0).map(([key, value]) => [key, String(value)])
127
+ ).toString();
128
+ return requestJson(
129
+ fetcher,
130
+ `${baseUrl}/api/deposit/status?${query}`,
131
+ { method: "GET", headers },
132
+ timeoutMs
133
+ );
134
+ },
135
+ depositSubmit: (payload) => requestJson(
136
+ fetcher,
137
+ `${baseUrl}/api/deposit/submit`,
138
+ { method: "POST", headers, body: JSON.stringify(payload) },
139
+ timeoutMs
140
+ ),
141
+ depositTokens: () => requestJson(
142
+ fetcher,
143
+ `${baseUrl}/api/deposit/tokens`,
144
+ { method: "GET", headers },
145
+ timeoutMs
146
+ ),
147
+ depositDestinations: (params) => {
148
+ const query = new URLSearchParams(
149
+ Object.entries(params).filter(([, value]) => value !== void 0).map(([key, value]) => [key, String(value)])
150
+ ).toString();
151
+ return requestJson(
152
+ fetcher,
153
+ `${baseUrl}/api/deposit/destinations?${query}`,
154
+ { method: "GET", headers },
155
+ timeoutMs
156
+ );
157
+ },
158
+ depositSources: (params) => {
159
+ const query = new URLSearchParams(
160
+ Object.entries(params).filter(([, value]) => value !== void 0).map(([key, value]) => [key, String(value)])
161
+ ).toString();
162
+ return requestJson(
163
+ fetcher,
164
+ `${baseUrl}/api/deposit/sources?${query}`,
165
+ { method: "GET", headers },
166
+ timeoutMs
167
+ );
168
+ },
169
+ depositValidateAddress: (payload) => requestJson(
170
+ fetcher,
171
+ `${baseUrl}/api/deposit/validate-address`,
172
+ { method: "POST", headers, body: JSON.stringify(payload) },
173
+ timeoutMs
174
+ )
175
+ };
176
+ }
177
+ // Annotate the CommonJS export names for ESM import in node:
178
+ 0 && (module.exports = {
179
+ ApiError,
180
+ createApiClient,
181
+ fromSmallestUnit,
182
+ toSmallestUnit
183
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,153 @@
1
+ // src/client.ts
2
+ var ApiError = class extends Error {
3
+ status;
4
+ body;
5
+ constructor(status, message, body) {
6
+ super(message);
7
+ this.name = "ApiError";
8
+ this.status = status;
9
+ this.body = body;
10
+ }
11
+ };
12
+ function buildHeaders(apiKey) {
13
+ const headers = { "content-type": "application/json" };
14
+ if (apiKey) headers["x-api-key"] = apiKey;
15
+ return headers;
16
+ }
17
+ function toSmallestUnit(amount, decimals) {
18
+ const num = parseFloat(amount);
19
+ if (isNaN(num)) {
20
+ throw new Error(`Invalid amount: ${amount}`);
21
+ }
22
+ const multiplier = Math.pow(10, decimals);
23
+ const smallestUnit = Math.floor(num * multiplier);
24
+ return smallestUnit.toString();
25
+ }
26
+ function fromSmallestUnit(amount, decimals) {
27
+ const num = parseFloat(amount);
28
+ if (isNaN(num)) {
29
+ throw new Error(`Invalid amount: ${amount}`);
30
+ }
31
+ const divisor = Math.pow(10, decimals);
32
+ return (num / divisor).toString();
33
+ }
34
+ async function requestJson(fetcher, url, options, timeoutMs) {
35
+ const controller = new AbortController();
36
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
37
+ try {
38
+ const res = await fetcher(url, { ...options, signal: controller.signal });
39
+ const text = await res.text();
40
+ const body = text ? JSON.parse(text) : void 0;
41
+ if (!res.ok) {
42
+ throw new ApiError(res.status, body?.message || res.statusText, body || text);
43
+ }
44
+ return body;
45
+ } finally {
46
+ clearTimeout(timeout);
47
+ }
48
+ }
49
+ function createApiClient(options = {}) {
50
+ const rawBaseUrl = options.baseUrl || "https://swap-api.dextopus.com";
51
+ const trimmedBaseUrl = rawBaseUrl.replace(/\/+$/, "");
52
+ const baseUrl = trimmedBaseUrl.endsWith("/api") ? trimmedBaseUrl.slice(0, -4) : trimmedBaseUrl;
53
+ const apiKey = options.apiKey;
54
+ const fetcher = options.fetch || fetch;
55
+ const timeoutMs = options.timeoutMs ?? 1e4;
56
+ const headers = buildHeaders(apiKey);
57
+ return {
58
+ quote: (payload) => requestJson(
59
+ fetcher,
60
+ `${baseUrl}/api/quote`,
61
+ { method: "POST", headers, body: JSON.stringify(payload) },
62
+ timeoutMs
63
+ ),
64
+ buildTransaction: (payload) => requestJson(
65
+ fetcher,
66
+ `${baseUrl}/api/build-transaction`,
67
+ { method: "POST", headers, body: JSON.stringify(payload) },
68
+ timeoutMs
69
+ ),
70
+ getQuoteById: (quoteId) => requestJson(
71
+ fetcher,
72
+ `${baseUrl}/api/quote/${quoteId}`,
73
+ { method: "GET", headers },
74
+ timeoutMs
75
+ ),
76
+ health: () => requestJson(
77
+ fetcher,
78
+ `${baseUrl}/health`,
79
+ { method: "GET", headers },
80
+ timeoutMs
81
+ ),
82
+ depositQuote: (payload) => {
83
+ const apiPayload = { ...payload };
84
+ if (payload.decimals !== void 0) {
85
+ apiPayload.amount = toSmallestUnit(payload.amount, payload.decimals);
86
+ delete apiPayload.decimals;
87
+ }
88
+ return requestJson(
89
+ fetcher,
90
+ `${baseUrl}/api/deposit/quote`,
91
+ { method: "POST", headers, body: JSON.stringify(apiPayload) },
92
+ timeoutMs
93
+ );
94
+ },
95
+ depositStatus: (params) => {
96
+ const query = new URLSearchParams(
97
+ Object.entries(params).filter(([, value]) => value !== void 0).map(([key, value]) => [key, String(value)])
98
+ ).toString();
99
+ return requestJson(
100
+ fetcher,
101
+ `${baseUrl}/api/deposit/status?${query}`,
102
+ { method: "GET", headers },
103
+ timeoutMs
104
+ );
105
+ },
106
+ depositSubmit: (payload) => requestJson(
107
+ fetcher,
108
+ `${baseUrl}/api/deposit/submit`,
109
+ { method: "POST", headers, body: JSON.stringify(payload) },
110
+ timeoutMs
111
+ ),
112
+ depositTokens: () => requestJson(
113
+ fetcher,
114
+ `${baseUrl}/api/deposit/tokens`,
115
+ { method: "GET", headers },
116
+ timeoutMs
117
+ ),
118
+ depositDestinations: (params) => {
119
+ const query = new URLSearchParams(
120
+ Object.entries(params).filter(([, value]) => value !== void 0).map(([key, value]) => [key, String(value)])
121
+ ).toString();
122
+ return requestJson(
123
+ fetcher,
124
+ `${baseUrl}/api/deposit/destinations?${query}`,
125
+ { method: "GET", headers },
126
+ timeoutMs
127
+ );
128
+ },
129
+ depositSources: (params) => {
130
+ const query = new URLSearchParams(
131
+ Object.entries(params).filter(([, value]) => value !== void 0).map(([key, value]) => [key, String(value)])
132
+ ).toString();
133
+ return requestJson(
134
+ fetcher,
135
+ `${baseUrl}/api/deposit/sources?${query}`,
136
+ { method: "GET", headers },
137
+ timeoutMs
138
+ );
139
+ },
140
+ depositValidateAddress: (payload) => requestJson(
141
+ fetcher,
142
+ `${baseUrl}/api/deposit/validate-address`,
143
+ { method: "POST", headers, body: JSON.stringify(payload) },
144
+ timeoutMs
145
+ )
146
+ };
147
+ }
148
+ export {
149
+ ApiError,
150
+ createApiClient,
151
+ fromSmallestUnit,
152
+ toSmallestUnit
153
+ };
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@dextopus/api-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Dextopus API SDK",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js",
13
+ "development": "./src/index.ts"
14
+ }
15
+ },
16
+ "files": ["dist"],
17
+ "scripts": {
18
+ "build": "tsup src/index.ts --format esm,cjs --dts",
19
+ "test": "vitest run",
20
+ "lint": "echo 'lint skipped'"
21
+ }
22
+ }