@flashnet/sdk 0.3.40 → 0.4.1
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.
- package/dist/cjs/index.d.ts +3 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +10 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/src/api/client.d.ts.map +1 -1
- package/dist/cjs/src/api/client.js +14 -15
- package/dist/cjs/src/api/client.js.map +1 -1
- package/dist/cjs/src/api/typed-endpoints.d.ts +9 -1
- package/dist/cjs/src/api/typed-endpoints.d.ts.map +1 -1
- package/dist/cjs/src/api/typed-endpoints.js +6 -2
- package/dist/cjs/src/api/typed-endpoints.js.map +1 -1
- package/dist/cjs/src/client/FlashnetClient.d.ts +232 -1
- package/dist/cjs/src/client/FlashnetClient.d.ts.map +1 -1
- package/dist/cjs/src/client/FlashnetClient.js +905 -109
- package/dist/cjs/src/client/FlashnetClient.js.map +1 -1
- package/dist/cjs/src/types/errors.d.ts +264 -0
- package/dist/cjs/src/types/errors.d.ts.map +1 -0
- package/dist/cjs/src/types/errors.js +758 -0
- package/dist/cjs/src/types/errors.js.map +1 -0
- package/dist/cjs/src/types/index.d.ts +1 -1
- package/dist/cjs/src/types/index.d.ts.map +1 -1
- package/dist/esm/index.d.ts +3 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/src/api/client.d.ts.map +1 -1
- package/dist/esm/src/api/client.js +14 -15
- package/dist/esm/src/api/client.js.map +1 -1
- package/dist/esm/src/api/typed-endpoints.d.ts +9 -1
- package/dist/esm/src/api/typed-endpoints.d.ts.map +1 -1
- package/dist/esm/src/api/typed-endpoints.js +6 -2
- package/dist/esm/src/api/typed-endpoints.js.map +1 -1
- package/dist/esm/src/client/FlashnetClient.d.ts +232 -1
- package/dist/esm/src/client/FlashnetClient.d.ts.map +1 -1
- package/dist/esm/src/client/FlashnetClient.js +905 -109
- package/dist/esm/src/client/FlashnetClient.js.map +1 -1
- package/dist/esm/src/types/errors.d.ts +264 -0
- package/dist/esm/src/types/errors.d.ts.map +1 -0
- package/dist/esm/src/types/errors.js +749 -0
- package/dist/esm/src/types/errors.js.map +1 -0
- package/dist/esm/src/types/index.d.ts +1 -1
- package/dist/esm/src/types/index.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,758 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Flashnet AMM Gateway Error System
|
|
5
|
+
*
|
|
6
|
+
* Error code format: FSAG-XXXX
|
|
7
|
+
* Categories by range:
|
|
8
|
+
* - 1000–1999: Validation
|
|
9
|
+
* - 2000–2999: Security/Auth
|
|
10
|
+
* - 3000–3999: Infrastructure/External
|
|
11
|
+
* - 4000–4999: Business/AMM Logic
|
|
12
|
+
* - 5000–5999: System/Service
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Comprehensive metadata for all FSAG error codes
|
|
16
|
+
*/
|
|
17
|
+
const ERROR_CODE_METADATA = {
|
|
18
|
+
// ===== Validation Errors (1000-1999) - Clawback Required =====
|
|
19
|
+
"FSAG-1000": {
|
|
20
|
+
httpStatus: 400,
|
|
21
|
+
category: "Validation",
|
|
22
|
+
recovery: "clawback_required",
|
|
23
|
+
summary: "Validation failed",
|
|
24
|
+
userMessage: "The request failed validation checks.",
|
|
25
|
+
actionHint: "Check your input parameters and try again. If you sent funds, initiate a clawback.",
|
|
26
|
+
isRetryable: false,
|
|
27
|
+
},
|
|
28
|
+
"FSAG-1001": {
|
|
29
|
+
httpStatus: 400,
|
|
30
|
+
category: "Validation",
|
|
31
|
+
recovery: "clawback_required",
|
|
32
|
+
summary: "Required field missing",
|
|
33
|
+
userMessage: "A required field is missing from your request.",
|
|
34
|
+
actionHint: "Ensure all required fields are provided. If you sent funds, initiate a clawback.",
|
|
35
|
+
isRetryable: false,
|
|
36
|
+
},
|
|
37
|
+
"FSAG-1002": {
|
|
38
|
+
httpStatus: 400,
|
|
39
|
+
category: "Validation",
|
|
40
|
+
recovery: "clawback_required",
|
|
41
|
+
summary: "Invalid field format",
|
|
42
|
+
userMessage: "One or more fields have an invalid format.",
|
|
43
|
+
actionHint: "Check the format of your inputs (addresses, amounts, etc.). If you sent funds, initiate a clawback.",
|
|
44
|
+
isRetryable: false,
|
|
45
|
+
},
|
|
46
|
+
"FSAG-1003": {
|
|
47
|
+
httpStatus: 400,
|
|
48
|
+
category: "Validation",
|
|
49
|
+
recovery: "clawback_required",
|
|
50
|
+
summary: "Value out of range",
|
|
51
|
+
userMessage: "A value is outside the acceptable range.",
|
|
52
|
+
actionHint: "Adjust the value to be within valid bounds. If you sent funds, initiate a clawback.",
|
|
53
|
+
isRetryable: false,
|
|
54
|
+
},
|
|
55
|
+
"FSAG-1004": {
|
|
56
|
+
httpStatus: 409,
|
|
57
|
+
category: "Validation",
|
|
58
|
+
recovery: "clawback_required",
|
|
59
|
+
summary: "Duplicate value",
|
|
60
|
+
userMessage: "This value already exists and must be unique.",
|
|
61
|
+
actionHint: "Use a different value or check if the operation was already completed.",
|
|
62
|
+
isRetryable: false,
|
|
63
|
+
},
|
|
64
|
+
// ===== Security/Auth Errors (2000-2999) - Clawback Required =====
|
|
65
|
+
"FSAG-2001": {
|
|
66
|
+
httpStatus: 403,
|
|
67
|
+
category: "Security",
|
|
68
|
+
recovery: "clawback_required",
|
|
69
|
+
summary: "Signature verification failed",
|
|
70
|
+
userMessage: "Your request signature could not be verified.",
|
|
71
|
+
actionHint: "Ensure you're signing with the correct key. If you sent funds, initiate a clawback.",
|
|
72
|
+
isRetryable: false,
|
|
73
|
+
},
|
|
74
|
+
"FSAG-2002": {
|
|
75
|
+
httpStatus: 403,
|
|
76
|
+
category: "Security",
|
|
77
|
+
recovery: "clawback_required",
|
|
78
|
+
summary: "Token identity mismatch",
|
|
79
|
+
userMessage: "The token identity doesn't match the expected public key.",
|
|
80
|
+
actionHint: "Ensure you're using the correct wallet/identity. If you sent funds, initiate a clawback.",
|
|
81
|
+
isRetryable: false,
|
|
82
|
+
},
|
|
83
|
+
"FSAG-2003": {
|
|
84
|
+
httpStatus: 401,
|
|
85
|
+
category: "Security",
|
|
86
|
+
recovery: "none",
|
|
87
|
+
summary: "Authorization token missing",
|
|
88
|
+
userMessage: "Authentication is required for this operation.",
|
|
89
|
+
actionHint: "Authenticate first by calling the auth flow.",
|
|
90
|
+
isRetryable: true,
|
|
91
|
+
},
|
|
92
|
+
"FSAG-2004": {
|
|
93
|
+
httpStatus: 401,
|
|
94
|
+
category: "Security",
|
|
95
|
+
recovery: "none",
|
|
96
|
+
summary: "Authorization token invalid or expired",
|
|
97
|
+
userMessage: "Your session has expired or the token is invalid.",
|
|
98
|
+
actionHint: "Re-authenticate to get a new access token.",
|
|
99
|
+
isRetryable: true,
|
|
100
|
+
},
|
|
101
|
+
"FSAG-2005": {
|
|
102
|
+
httpStatus: 403,
|
|
103
|
+
category: "Security",
|
|
104
|
+
recovery: "clawback_required",
|
|
105
|
+
summary: "Nonce verification failed",
|
|
106
|
+
userMessage: "The request nonce is invalid or has already been used.",
|
|
107
|
+
actionHint: "Generate a new nonce and retry. If you sent funds, initiate a clawback.",
|
|
108
|
+
isRetryable: false,
|
|
109
|
+
},
|
|
110
|
+
"FSAG-2101": {
|
|
111
|
+
httpStatus: 400,
|
|
112
|
+
category: "Security",
|
|
113
|
+
recovery: "clawback_required",
|
|
114
|
+
summary: "Public key invalid",
|
|
115
|
+
userMessage: "The provided public key is invalid.",
|
|
116
|
+
actionHint: "Check that the public key is correctly formatted. If you sent funds, initiate a clawback.",
|
|
117
|
+
isRetryable: false,
|
|
118
|
+
},
|
|
119
|
+
// ===== Infrastructure/External Errors (3000-3999) - Clawback Recommended =====
|
|
120
|
+
"FSAG-3001": {
|
|
121
|
+
httpStatus: 503,
|
|
122
|
+
category: "Infrastructure",
|
|
123
|
+
recovery: "clawback_recommended",
|
|
124
|
+
summary: "Internal server error",
|
|
125
|
+
userMessage: "A temporary service issue occurred. Please try again.",
|
|
126
|
+
actionHint: "Wait a moment and retry. If you sent funds, consider initiating a clawback.",
|
|
127
|
+
isRetryable: true,
|
|
128
|
+
},
|
|
129
|
+
"FSAG-3002": {
|
|
130
|
+
httpStatus: 500,
|
|
131
|
+
category: "Infrastructure",
|
|
132
|
+
recovery: "clawback_recommended",
|
|
133
|
+
summary: "Internal server error",
|
|
134
|
+
userMessage: "A temporary service issue occurred. Please try again.",
|
|
135
|
+
actionHint: "Wait a moment and retry. If you sent funds, consider initiating a clawback.",
|
|
136
|
+
isRetryable: true,
|
|
137
|
+
},
|
|
138
|
+
"FSAG-3101": {
|
|
139
|
+
httpStatus: 500,
|
|
140
|
+
category: "Infrastructure",
|
|
141
|
+
recovery: "clawback_recommended",
|
|
142
|
+
summary: "Internal server error",
|
|
143
|
+
userMessage: "A database error occurred. Please try again.",
|
|
144
|
+
actionHint: "Wait a moment and retry. If you sent funds, consider initiating a clawback.",
|
|
145
|
+
isRetryable: true,
|
|
146
|
+
},
|
|
147
|
+
"FSAG-3201": {
|
|
148
|
+
httpStatus: 503,
|
|
149
|
+
category: "Infrastructure",
|
|
150
|
+
recovery: "clawback_recommended",
|
|
151
|
+
summary: "Internal server error",
|
|
152
|
+
userMessage: "The settlement service is temporarily unavailable.",
|
|
153
|
+
actionHint: "Wait and retry. If you sent funds and they haven't been processed, consider initiating a clawback.",
|
|
154
|
+
isRetryable: true,
|
|
155
|
+
},
|
|
156
|
+
"FSAG-3201T1": {
|
|
157
|
+
httpStatus: 503,
|
|
158
|
+
category: "Infrastructure",
|
|
159
|
+
recovery: "clawback_recommended",
|
|
160
|
+
summary: "Internal server error",
|
|
161
|
+
userMessage: "The settlement service is temporarily unavailable.",
|
|
162
|
+
actionHint: "Wait and retry. If you sent funds and they haven't been processed, consider initiating a clawback.",
|
|
163
|
+
isRetryable: true,
|
|
164
|
+
},
|
|
165
|
+
"FSAG-3201T2": {
|
|
166
|
+
httpStatus: 503,
|
|
167
|
+
category: "Infrastructure",
|
|
168
|
+
recovery: "clawback_recommended",
|
|
169
|
+
summary: "Internal server error",
|
|
170
|
+
userMessage: "The settlement request timed out.",
|
|
171
|
+
actionHint: "Check if your transaction was processed. If not, you may retry or initiate a clawback.",
|
|
172
|
+
isRetryable: true,
|
|
173
|
+
},
|
|
174
|
+
"FSAG-3202": {
|
|
175
|
+
httpStatus: 503,
|
|
176
|
+
category: "Infrastructure",
|
|
177
|
+
recovery: "clawback_recommended",
|
|
178
|
+
summary: "Internal server error",
|
|
179
|
+
userMessage: "A dependent service is temporarily unavailable.",
|
|
180
|
+
actionHint: "Wait a moment and retry.",
|
|
181
|
+
isRetryable: true,
|
|
182
|
+
},
|
|
183
|
+
"FSAG-3301": {
|
|
184
|
+
httpStatus: 500,
|
|
185
|
+
category: "Infrastructure",
|
|
186
|
+
recovery: "clawback_recommended",
|
|
187
|
+
summary: "Internal server error",
|
|
188
|
+
userMessage: "The AMM processor couldn't receive your request.",
|
|
189
|
+
actionHint: "Wait and retry. If you sent funds, consider initiating a clawback.",
|
|
190
|
+
isRetryable: true,
|
|
191
|
+
},
|
|
192
|
+
"FSAG-3302": {
|
|
193
|
+
httpStatus: 503,
|
|
194
|
+
category: "Infrastructure",
|
|
195
|
+
recovery: "clawback_recommended",
|
|
196
|
+
summary: "Internal server error",
|
|
197
|
+
userMessage: "The AMM processor timed out while processing your request.",
|
|
198
|
+
actionHint: "Check if your transaction was processed. If not, you may retry or initiate a clawback.",
|
|
199
|
+
isRetryable: true,
|
|
200
|
+
},
|
|
201
|
+
"FSAG-3401": {
|
|
202
|
+
httpStatus: 500,
|
|
203
|
+
category: "Infrastructure",
|
|
204
|
+
recovery: "clawback_recommended",
|
|
205
|
+
summary: "Internal server error",
|
|
206
|
+
userMessage: "An internal processing error occurred.",
|
|
207
|
+
actionHint: "This is likely a temporary issue. Wait and retry. If you sent funds, consider initiating a clawback.",
|
|
208
|
+
isRetryable: true,
|
|
209
|
+
},
|
|
210
|
+
"FSAG-3402": {
|
|
211
|
+
httpStatus: 500,
|
|
212
|
+
category: "Infrastructure",
|
|
213
|
+
recovery: "clawback_recommended",
|
|
214
|
+
summary: "Internal server error",
|
|
215
|
+
userMessage: "An internal processing error occurred.",
|
|
216
|
+
actionHint: "This is likely a temporary issue. Wait and retry. If you sent funds, consider initiating a clawback.",
|
|
217
|
+
isRetryable: true,
|
|
218
|
+
},
|
|
219
|
+
// ===== Business/AMM Logic Errors (4000-4999) - Auto Refund =====
|
|
220
|
+
"FSAG-4001": {
|
|
221
|
+
httpStatus: 404,
|
|
222
|
+
category: "Business",
|
|
223
|
+
recovery: "auto_refund",
|
|
224
|
+
summary: "Pool not found",
|
|
225
|
+
userMessage: "The specified pool does not exist.",
|
|
226
|
+
actionHint: "Verify the pool ID is correct. Your funds will be automatically refunded.",
|
|
227
|
+
isRetryable: false,
|
|
228
|
+
},
|
|
229
|
+
"FSAG-4002": {
|
|
230
|
+
httpStatus: 404,
|
|
231
|
+
category: "Business",
|
|
232
|
+
recovery: "none",
|
|
233
|
+
summary: "Host not found",
|
|
234
|
+
userMessage: "The specified host namespace does not exist.",
|
|
235
|
+
actionHint: "Verify the host namespace is correct.",
|
|
236
|
+
isRetryable: false,
|
|
237
|
+
},
|
|
238
|
+
"FSAG-4101": {
|
|
239
|
+
httpStatus: 404,
|
|
240
|
+
category: "Business",
|
|
241
|
+
recovery: "none",
|
|
242
|
+
summary: "Auth session not found",
|
|
243
|
+
userMessage: "Your authentication session was not found or has expired.",
|
|
244
|
+
actionHint: "Start a new authentication flow.",
|
|
245
|
+
isRetryable: true,
|
|
246
|
+
},
|
|
247
|
+
"FSAG-4102": {
|
|
248
|
+
httpStatus: 400,
|
|
249
|
+
category: "Business",
|
|
250
|
+
recovery: "none",
|
|
251
|
+
summary: "Incorrect authentication flow",
|
|
252
|
+
userMessage: "The authentication flow was not followed correctly.",
|
|
253
|
+
actionHint: "Complete the authentication steps in the correct order.",
|
|
254
|
+
isRetryable: true,
|
|
255
|
+
},
|
|
256
|
+
"FSAG-4201": {
|
|
257
|
+
httpStatus: 400,
|
|
258
|
+
category: "Business",
|
|
259
|
+
recovery: "auto_refund",
|
|
260
|
+
summary: "Insufficient liquidity",
|
|
261
|
+
userMessage: "The pool doesn't have enough liquidity to complete this swap.",
|
|
262
|
+
actionHint: "Try a smaller amount or wait for more liquidity. Your funds will be automatically refunded.",
|
|
263
|
+
isRetryable: true,
|
|
264
|
+
},
|
|
265
|
+
"FSAG-4202": {
|
|
266
|
+
httpStatus: 400,
|
|
267
|
+
category: "Business",
|
|
268
|
+
recovery: "auto_refund",
|
|
269
|
+
summary: "Slippage exceeded",
|
|
270
|
+
userMessage: "The price moved more than your allowed slippage tolerance.",
|
|
271
|
+
actionHint: "Try increasing slippage tolerance, reducing trade size, or waiting for less volatile conditions. Your funds will be automatically refunded.",
|
|
272
|
+
isRetryable: true,
|
|
273
|
+
},
|
|
274
|
+
"FSAG-4203": {
|
|
275
|
+
httpStatus: 409,
|
|
276
|
+
category: "Business",
|
|
277
|
+
recovery: "auto_refund",
|
|
278
|
+
summary: "Operation not allowed in current phase",
|
|
279
|
+
userMessage: "This operation cannot be performed while the pool is in its current phase.",
|
|
280
|
+
actionHint: "Wait for the pool to transition to the appropriate phase. Your funds will be automatically refunded.",
|
|
281
|
+
isRetryable: true,
|
|
282
|
+
},
|
|
283
|
+
"FSAG-4204": {
|
|
284
|
+
httpStatus: 400,
|
|
285
|
+
category: "Business",
|
|
286
|
+
recovery: "none",
|
|
287
|
+
summary: "Insufficient LP tokens",
|
|
288
|
+
userMessage: "You don't have enough LP tokens to complete this withdrawal.",
|
|
289
|
+
actionHint: "Check your LP token balance and reduce the withdrawal amount.",
|
|
290
|
+
isRetryable: false,
|
|
291
|
+
},
|
|
292
|
+
"FSAG-4301": {
|
|
293
|
+
httpStatus: 400,
|
|
294
|
+
category: "Business",
|
|
295
|
+
recovery: "none",
|
|
296
|
+
summary: "Invalid fee configuration",
|
|
297
|
+
userMessage: "The fee configuration is invalid.",
|
|
298
|
+
actionHint: "Check that fee rates are within acceptable bounds.",
|
|
299
|
+
isRetryable: false,
|
|
300
|
+
},
|
|
301
|
+
"FSAG-4401": {
|
|
302
|
+
httpStatus: 409,
|
|
303
|
+
category: "Business",
|
|
304
|
+
recovery: "none",
|
|
305
|
+
summary: "Transfer ID already used",
|
|
306
|
+
userMessage: "This Spark transfer has already been used in an operation.",
|
|
307
|
+
actionHint: "Each transfer can only be used once. Use a new transfer for this operation.",
|
|
308
|
+
isRetryable: false,
|
|
309
|
+
},
|
|
310
|
+
// ===== System/Service Errors (5000-5999) - Clawback Required =====
|
|
311
|
+
"FSAG-5001": {
|
|
312
|
+
httpStatus: 500,
|
|
313
|
+
category: "System",
|
|
314
|
+
recovery: "clawback_required",
|
|
315
|
+
summary: "Failed to generate unique ID",
|
|
316
|
+
userMessage: "An internal error occurred while processing your request.",
|
|
317
|
+
actionHint: "Please try again. If you sent funds, initiate a clawback.",
|
|
318
|
+
isRetryable: true,
|
|
319
|
+
},
|
|
320
|
+
"FSAG-5002": {
|
|
321
|
+
httpStatus: 501,
|
|
322
|
+
category: "System",
|
|
323
|
+
recovery: "none",
|
|
324
|
+
summary: "Feature not implemented",
|
|
325
|
+
userMessage: "This feature is not yet available.",
|
|
326
|
+
actionHint: "This operation is not currently supported.",
|
|
327
|
+
isRetryable: false,
|
|
328
|
+
},
|
|
329
|
+
"FSAG-5003": {
|
|
330
|
+
httpStatus: 500,
|
|
331
|
+
category: "System",
|
|
332
|
+
recovery: "clawback_required",
|
|
333
|
+
summary: "Internal state inconsistent",
|
|
334
|
+
userMessage: "An internal error occurred. Please contact support if this persists.",
|
|
335
|
+
actionHint: "If you sent funds, initiate a clawback and contact support.",
|
|
336
|
+
isRetryable: false,
|
|
337
|
+
},
|
|
338
|
+
"FSAG-5004": {
|
|
339
|
+
httpStatus: 500,
|
|
340
|
+
category: "System",
|
|
341
|
+
recovery: "clawback_required",
|
|
342
|
+
summary: "Invalid configuration parameter",
|
|
343
|
+
userMessage: "A system configuration error occurred.",
|
|
344
|
+
actionHint: "This is a server-side issue. If you sent funds, initiate a clawback.",
|
|
345
|
+
isRetryable: false,
|
|
346
|
+
},
|
|
347
|
+
"FSAG-5100": {
|
|
348
|
+
httpStatus: 500,
|
|
349
|
+
category: "System",
|
|
350
|
+
recovery: "clawback_required",
|
|
351
|
+
summary: "Unexpected panic",
|
|
352
|
+
userMessage: "An unexpected error occurred on the server.",
|
|
353
|
+
actionHint: "Please try again later. If you sent funds, initiate a clawback immediately.",
|
|
354
|
+
isRetryable: false,
|
|
355
|
+
},
|
|
356
|
+
};
|
|
357
|
+
// ===== Helper Functions =====
|
|
358
|
+
/**
|
|
359
|
+
* Check if a string is a valid FlashnetErrorCode
|
|
360
|
+
*/
|
|
361
|
+
function isFlashnetErrorCode(code) {
|
|
362
|
+
return code in ERROR_CODE_METADATA;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Get error category from error code
|
|
366
|
+
*/
|
|
367
|
+
function getErrorCategory(code) {
|
|
368
|
+
return ERROR_CODE_METADATA[code].category;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Get recovery strategy from error code
|
|
372
|
+
*/
|
|
373
|
+
function getErrorRecovery(code) {
|
|
374
|
+
return ERROR_CODE_METADATA[code].recovery;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Get metadata for an error code
|
|
378
|
+
*/
|
|
379
|
+
function getErrorMetadata(code) {
|
|
380
|
+
return ERROR_CODE_METADATA[code];
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Determine category from error code prefix (for unknown codes)
|
|
384
|
+
*/
|
|
385
|
+
function getCategoryFromCodeRange(code) {
|
|
386
|
+
const match = code.match(/^FSAG-(\d)/);
|
|
387
|
+
if (!match) {
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
const prefix = match[1];
|
|
391
|
+
switch (prefix) {
|
|
392
|
+
case "1":
|
|
393
|
+
return "Validation";
|
|
394
|
+
case "2":
|
|
395
|
+
return "Security";
|
|
396
|
+
case "3":
|
|
397
|
+
return "Infrastructure";
|
|
398
|
+
case "4":
|
|
399
|
+
return "Business";
|
|
400
|
+
case "5":
|
|
401
|
+
return "System";
|
|
402
|
+
default:
|
|
403
|
+
return null;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Error class for Flashnet AMM Gateway errors
|
|
408
|
+
*
|
|
409
|
+
* Provides:
|
|
410
|
+
* - Typed error codes with full metadata
|
|
411
|
+
* - Recovery strategy information
|
|
412
|
+
* - Human-readable messages
|
|
413
|
+
* - Transfer tracking for clawback operations
|
|
414
|
+
*/
|
|
415
|
+
class FlashnetError extends Error {
|
|
416
|
+
/** The FSAG error code (e.g., "FSAG-4202") */
|
|
417
|
+
errorCode;
|
|
418
|
+
/** Error category */
|
|
419
|
+
category;
|
|
420
|
+
/** Recovery strategy for this error */
|
|
421
|
+
recovery;
|
|
422
|
+
/** HTTP status code */
|
|
423
|
+
httpStatus;
|
|
424
|
+
/** Unique request ID for debugging */
|
|
425
|
+
requestId;
|
|
426
|
+
/** ISO timestamp when error occurred */
|
|
427
|
+
timestamp;
|
|
428
|
+
/** Service that generated the error */
|
|
429
|
+
service;
|
|
430
|
+
/** Error severity */
|
|
431
|
+
severity;
|
|
432
|
+
/** Additional error details */
|
|
433
|
+
details;
|
|
434
|
+
/** Server-provided remediation hint */
|
|
435
|
+
remediation;
|
|
436
|
+
/** Transfer IDs that may need clawback (unrecovered transfers) */
|
|
437
|
+
transferIds;
|
|
438
|
+
/** LP identity public key for clawback operations */
|
|
439
|
+
lpIdentityPublicKey;
|
|
440
|
+
/** Summary of automatic clawback attempts (if any were made) */
|
|
441
|
+
clawbackSummary;
|
|
442
|
+
/** Whether this error type is generally retryable */
|
|
443
|
+
isRetryable;
|
|
444
|
+
/** Human-readable summary */
|
|
445
|
+
summary;
|
|
446
|
+
/** User-friendly message explaining the error */
|
|
447
|
+
userMessage;
|
|
448
|
+
/** Suggested action for the user */
|
|
449
|
+
actionHint;
|
|
450
|
+
constructor(message, options = {}) {
|
|
451
|
+
super(message);
|
|
452
|
+
this.name = "FlashnetError";
|
|
453
|
+
const response = options.response;
|
|
454
|
+
const rawCode = response?.errorCode ?? "UNKNOWN";
|
|
455
|
+
// Determine if we have a known error code
|
|
456
|
+
if (isFlashnetErrorCode(rawCode)) {
|
|
457
|
+
this.errorCode = rawCode;
|
|
458
|
+
const metadata = ERROR_CODE_METADATA[rawCode];
|
|
459
|
+
this.category = metadata.category;
|
|
460
|
+
this.recovery = metadata.recovery;
|
|
461
|
+
this.httpStatus = options.httpStatus ?? metadata.httpStatus;
|
|
462
|
+
this.isRetryable = metadata.isRetryable;
|
|
463
|
+
this.summary = metadata.summary;
|
|
464
|
+
this.userMessage = metadata.userMessage;
|
|
465
|
+
// Prefer remediation from response (e.g., after successful auto-clawback)
|
|
466
|
+
this.actionHint = response?.remediation ?? metadata.actionHint;
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
// Unknown error code - try to determine category from range
|
|
470
|
+
this.errorCode = rawCode;
|
|
471
|
+
this.category = getCategoryFromCodeRange(rawCode) ?? "System";
|
|
472
|
+
this.httpStatus = options.httpStatus ?? 500;
|
|
473
|
+
// Default recovery based on category
|
|
474
|
+
switch (this.category) {
|
|
475
|
+
case "Validation":
|
|
476
|
+
case "Security":
|
|
477
|
+
case "System":
|
|
478
|
+
this.recovery = "clawback_required";
|
|
479
|
+
break;
|
|
480
|
+
case "Infrastructure":
|
|
481
|
+
this.recovery = "clawback_recommended";
|
|
482
|
+
break;
|
|
483
|
+
case "Business":
|
|
484
|
+
this.recovery = "auto_refund";
|
|
485
|
+
break;
|
|
486
|
+
default:
|
|
487
|
+
this.recovery = "clawback_required";
|
|
488
|
+
}
|
|
489
|
+
this.isRetryable = this.category === "Infrastructure";
|
|
490
|
+
this.summary = response?.message ?? "Unknown error";
|
|
491
|
+
this.userMessage = response?.message ?? "An unexpected error occurred.";
|
|
492
|
+
this.actionHint =
|
|
493
|
+
response?.remediation ?? "Please try again or contact support.";
|
|
494
|
+
}
|
|
495
|
+
this.requestId = response?.requestId ?? "";
|
|
496
|
+
this.timestamp = response?.timestamp ?? new Date().toISOString();
|
|
497
|
+
this.service = response?.service ?? "unknown";
|
|
498
|
+
this.severity = response?.severity ?? "Error";
|
|
499
|
+
this.details = response?.details;
|
|
500
|
+
this.remediation = response?.remediation;
|
|
501
|
+
this.transferIds = options.transferIds ?? [];
|
|
502
|
+
this.lpIdentityPublicKey = options.lpIdentityPublicKey;
|
|
503
|
+
this.clawbackSummary = options.clawbackSummary;
|
|
504
|
+
// Maintain proper prototype chain
|
|
505
|
+
Object.setPrototypeOf(this, FlashnetError.prototype);
|
|
506
|
+
// Capture stack trace
|
|
507
|
+
if (Error.captureStackTrace) {
|
|
508
|
+
Error.captureStackTrace(this, FlashnetError);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
// ===== Recovery Status Methods =====
|
|
512
|
+
/**
|
|
513
|
+
* Returns true if funds were sent and clawback is required
|
|
514
|
+
*/
|
|
515
|
+
isClawbackRequired() {
|
|
516
|
+
return this.recovery === "clawback_required" && this.transferIds.length > 0;
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Returns true if clawback is recommended (infrastructure errors)
|
|
520
|
+
*/
|
|
521
|
+
isClawbackRecommended() {
|
|
522
|
+
return (this.recovery === "clawback_recommended" && this.transferIds.length > 0);
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Returns true if clawback should be attempted (required or recommended)
|
|
526
|
+
*/
|
|
527
|
+
shouldClawback() {
|
|
528
|
+
return this.isClawbackRequired() || this.isClawbackRecommended();
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Returns true if funds will be automatically refunded
|
|
532
|
+
*/
|
|
533
|
+
willAutoRefund() {
|
|
534
|
+
return this.recovery === "auto_refund";
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Returns true if this error has associated transfers that may need recovery
|
|
538
|
+
*/
|
|
539
|
+
hasTransfersAtRisk() {
|
|
540
|
+
return this.transferIds.length > 0 && this.recovery !== "auto_refund";
|
|
541
|
+
}
|
|
542
|
+
// ===== Category Check Methods =====
|
|
543
|
+
isValidationError() {
|
|
544
|
+
return this.category === "Validation";
|
|
545
|
+
}
|
|
546
|
+
isSecurityError() {
|
|
547
|
+
return this.category === "Security";
|
|
548
|
+
}
|
|
549
|
+
isInfrastructureError() {
|
|
550
|
+
return this.category === "Infrastructure";
|
|
551
|
+
}
|
|
552
|
+
isBusinessError() {
|
|
553
|
+
return this.category === "Business";
|
|
554
|
+
}
|
|
555
|
+
isSystemError() {
|
|
556
|
+
return this.category === "System";
|
|
557
|
+
}
|
|
558
|
+
// ===== Specific Error Checks =====
|
|
559
|
+
isSlippageError() {
|
|
560
|
+
return this.errorCode === "FSAG-4202";
|
|
561
|
+
}
|
|
562
|
+
isInsufficientLiquidityError() {
|
|
563
|
+
return this.errorCode === "FSAG-4201";
|
|
564
|
+
}
|
|
565
|
+
isAuthError() {
|
|
566
|
+
return this.errorCode === "FSAG-2003" || this.errorCode === "FSAG-2004";
|
|
567
|
+
}
|
|
568
|
+
isPoolNotFoundError() {
|
|
569
|
+
return this.errorCode === "FSAG-4001";
|
|
570
|
+
}
|
|
571
|
+
isTransferAlreadyUsedError() {
|
|
572
|
+
return this.errorCode === "FSAG-4401";
|
|
573
|
+
}
|
|
574
|
+
// ===== Clawback Status Methods =====
|
|
575
|
+
/**
|
|
576
|
+
* Returns true if automatic clawback was attempted
|
|
577
|
+
*/
|
|
578
|
+
wasClawbackAttempted() {
|
|
579
|
+
return this.clawbackSummary?.attempted ?? false;
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Returns true if all transfers were successfully recovered via clawback
|
|
583
|
+
*/
|
|
584
|
+
wereAllTransfersRecovered() {
|
|
585
|
+
if (!this.clawbackSummary?.attempted) {
|
|
586
|
+
return false;
|
|
587
|
+
}
|
|
588
|
+
return this.clawbackSummary.failureCount === 0;
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Returns true if some (but not all) transfers were recovered
|
|
592
|
+
*/
|
|
593
|
+
werePartialTransfersRecovered() {
|
|
594
|
+
if (!this.clawbackSummary?.attempted) {
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
597
|
+
return (this.clawbackSummary.successCount > 0 &&
|
|
598
|
+
this.clawbackSummary.failureCount > 0);
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Get the number of transfers that were successfully recovered
|
|
602
|
+
*/
|
|
603
|
+
getRecoveredTransferCount() {
|
|
604
|
+
return this.clawbackSummary?.successCount ?? 0;
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Get the transfer IDs that were successfully recovered
|
|
608
|
+
*/
|
|
609
|
+
getRecoveredTransferIds() {
|
|
610
|
+
return this.clawbackSummary?.recoveredTransferIds ?? [];
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Get the transfer IDs that failed to recover (still at risk)
|
|
614
|
+
*/
|
|
615
|
+
getUnrecoveredTransferIds() {
|
|
616
|
+
return this.clawbackSummary?.unrecoveredTransferIds ?? this.transferIds;
|
|
617
|
+
}
|
|
618
|
+
// ===== Formatting Methods =====
|
|
619
|
+
/**
|
|
620
|
+
* Get a formatted string for logging
|
|
621
|
+
*/
|
|
622
|
+
toLogString() {
|
|
623
|
+
const parts = [
|
|
624
|
+
`[${this.errorCode}]`,
|
|
625
|
+
this.message,
|
|
626
|
+
`(requestId: ${this.requestId})`,
|
|
627
|
+
];
|
|
628
|
+
if (this.transferIds.length > 0) {
|
|
629
|
+
parts.push(`transferIds: [${this.transferIds.join(", ")}]`);
|
|
630
|
+
}
|
|
631
|
+
return parts.join(" ");
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Get a user-friendly error description
|
|
635
|
+
*/
|
|
636
|
+
getUserFriendlyMessage() {
|
|
637
|
+
const parts = [this.userMessage];
|
|
638
|
+
if (this.shouldClawback()) {
|
|
639
|
+
parts.push("Your funds may need to be recovered via clawback.");
|
|
640
|
+
}
|
|
641
|
+
else if (this.willAutoRefund()) {
|
|
642
|
+
parts.push("Your funds will be automatically refunded.");
|
|
643
|
+
}
|
|
644
|
+
return parts.join(" ");
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Convert to a plain object for serialization
|
|
648
|
+
*/
|
|
649
|
+
toJSON() {
|
|
650
|
+
return {
|
|
651
|
+
name: this.name,
|
|
652
|
+
message: this.message,
|
|
653
|
+
errorCode: this.errorCode,
|
|
654
|
+
category: this.category,
|
|
655
|
+
recovery: this.recovery,
|
|
656
|
+
httpStatus: this.httpStatus,
|
|
657
|
+
requestId: this.requestId,
|
|
658
|
+
timestamp: this.timestamp,
|
|
659
|
+
service: this.service,
|
|
660
|
+
severity: this.severity,
|
|
661
|
+
details: this.details,
|
|
662
|
+
remediation: this.remediation,
|
|
663
|
+
transferIds: this.transferIds,
|
|
664
|
+
lpIdentityPublicKey: this.lpIdentityPublicKey,
|
|
665
|
+
clawbackSummary: this.clawbackSummary,
|
|
666
|
+
isRetryable: this.isRetryable,
|
|
667
|
+
summary: this.summary,
|
|
668
|
+
userMessage: this.userMessage,
|
|
669
|
+
actionHint: this.actionHint,
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Create a FlashnetError from an API error response
|
|
674
|
+
*/
|
|
675
|
+
static fromResponse(response, httpStatus, options) {
|
|
676
|
+
return new FlashnetError(response.message, {
|
|
677
|
+
response,
|
|
678
|
+
httpStatus,
|
|
679
|
+
transferIds: options?.transferIds,
|
|
680
|
+
lpIdentityPublicKey: options?.lpIdentityPublicKey,
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Create a FlashnetError from an unknown error
|
|
685
|
+
*/
|
|
686
|
+
static fromUnknown(error, options) {
|
|
687
|
+
if (error instanceof FlashnetError) {
|
|
688
|
+
// If already a FlashnetError, preserve its state
|
|
689
|
+
// Don't override transferIds if the error indicates auto_refund (funds already safe)
|
|
690
|
+
const shouldPreserveTransferIds = error.recovery === "auto_refund";
|
|
691
|
+
if (options?.lpIdentityPublicKey && !error.lpIdentityPublicKey) {
|
|
692
|
+
return new FlashnetError(error.message, {
|
|
693
|
+
response: {
|
|
694
|
+
errorCode: error.errorCode,
|
|
695
|
+
errorCategory: error.category,
|
|
696
|
+
message: error.message,
|
|
697
|
+
details: error.details,
|
|
698
|
+
requestId: error.requestId,
|
|
699
|
+
timestamp: error.timestamp,
|
|
700
|
+
service: error.service,
|
|
701
|
+
severity: error.severity,
|
|
702
|
+
remediation: error.remediation,
|
|
703
|
+
},
|
|
704
|
+
httpStatus: error.httpStatus,
|
|
705
|
+
transferIds: shouldPreserveTransferIds
|
|
706
|
+
? error.transferIds
|
|
707
|
+
: (options.transferIds ?? error.transferIds),
|
|
708
|
+
lpIdentityPublicKey: options.lpIdentityPublicKey ?? error.lpIdentityPublicKey,
|
|
709
|
+
cause: error,
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
return error;
|
|
713
|
+
}
|
|
714
|
+
if (error instanceof Error) {
|
|
715
|
+
// Check if it's an API error with response data
|
|
716
|
+
const apiError = error;
|
|
717
|
+
if (apiError.response?.data &&
|
|
718
|
+
typeof apiError.response.data === "object") {
|
|
719
|
+
const data = apiError.response.data;
|
|
720
|
+
if (data.errorCode &&
|
|
721
|
+
typeof data.errorCode === "string" &&
|
|
722
|
+
typeof data.message === "string" &&
|
|
723
|
+
typeof data.requestId === "string") {
|
|
724
|
+
return FlashnetError.fromResponse(data, apiError.response.status ?? apiError.status ?? 500, options);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
// Generic error
|
|
728
|
+
return new FlashnetError(error.message, {
|
|
729
|
+
httpStatus: apiError.status ?? 500,
|
|
730
|
+
transferIds: options?.transferIds,
|
|
731
|
+
lpIdentityPublicKey: options?.lpIdentityPublicKey,
|
|
732
|
+
cause: error,
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
// Unknown error type
|
|
736
|
+
return new FlashnetError(String(error), {
|
|
737
|
+
httpStatus: 500,
|
|
738
|
+
transferIds: options?.transferIds,
|
|
739
|
+
lpIdentityPublicKey: options?.lpIdentityPublicKey,
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Type guard to check if an error is a FlashnetError
|
|
745
|
+
*/
|
|
746
|
+
function isFlashnetError(error) {
|
|
747
|
+
return error instanceof FlashnetError;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
exports.ERROR_CODE_METADATA = ERROR_CODE_METADATA;
|
|
751
|
+
exports.FlashnetError = FlashnetError;
|
|
752
|
+
exports.getCategoryFromCodeRange = getCategoryFromCodeRange;
|
|
753
|
+
exports.getErrorCategory = getErrorCategory;
|
|
754
|
+
exports.getErrorMetadata = getErrorMetadata;
|
|
755
|
+
exports.getErrorRecovery = getErrorRecovery;
|
|
756
|
+
exports.isFlashnetError = isFlashnetError;
|
|
757
|
+
exports.isFlashnetErrorCode = isFlashnetErrorCode;
|
|
758
|
+
//# sourceMappingURL=errors.js.map
|