@coinlist-co/react 0.11.0 → 0.11.1-rc.22d81d4
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/chunk-AQIHCFW4.js +279 -0
- package/dist/chunk-AQIHCFW4.js.map +1 -0
- package/dist/{chunk-B2HCVPCQ.js → chunk-PRG3EDQJ.js} +25 -10
- package/dist/chunk-PRG3EDQJ.js.map +1 -0
- package/dist/{chunk-UIIXXLA7.js → chunk-ZVB6KWZ2.js} +484 -141
- package/dist/chunk-ZVB6KWZ2.js.map +1 -0
- package/dist/client/index.cjs +1307 -461
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +216 -211
- package/dist/client/index.d.ts +216 -211
- package/dist/client/index.js +464 -108
- package/dist/client/index.js.map +1 -1
- package/dist/collections-DrJFEDHl.d.cts +116 -0
- package/dist/collections-pLtrj6fw.d.ts +116 -0
- package/dist/{config-B5mwS_2l.d.cts → config-C6vlghJY.d.cts} +713 -22
- package/dist/{config-B5mwS_2l.d.ts → config-C6vlghJY.d.ts} +713 -22
- package/dist/server/index.cjs +766 -209
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +80 -3
- package/dist/server/index.d.ts +80 -3
- package/dist/server/index.js +120 -51
- package/dist/server/index.js.map +1 -1
- package/dist/shared/index.cjs +486 -123
- package/dist/shared/index.cjs.map +1 -1
- package/dist/shared/index.d.cts +18 -5
- package/dist/shared/index.d.ts +18 -5
- package/dist/shared/index.js +8 -2
- package/package.json +3 -2
- package/dist/chunk-B2HCVPCQ.js.map +0 -1
- package/dist/chunk-KDGNDAHA.js +0 -146
- package/dist/chunk-KDGNDAHA.js.map +0 -1
- package/dist/chunk-UIIXXLA7.js.map +0 -1
- package/dist/collections-BhDkYmzV.d.cts +0 -65
- package/dist/collections-CZhHoQHr.d.ts +0 -65
package/dist/server/index.cjs
CHANGED
|
@@ -24,7 +24,9 @@ __export(server_exports, {
|
|
|
24
24
|
ServerOffersNamespaceImpl: () => ServerOffersNamespaceImpl,
|
|
25
25
|
ServerRequirementsNamespaceImpl: () => ServerRequirementsNamespaceImpl,
|
|
26
26
|
WritableSessionStoreRequiredError: () => WritableSessionStoreRequiredError,
|
|
27
|
-
createCoinListServer: () => createCoinListServer
|
|
27
|
+
createCoinListServer: () => createCoinListServer,
|
|
28
|
+
emptySessionStore: () => emptySessionStore,
|
|
29
|
+
pinoServerLogger: () => pinoServerLogger
|
|
28
30
|
});
|
|
29
31
|
module.exports = __toCommonJS(server_exports);
|
|
30
32
|
|
|
@@ -55,6 +57,8 @@ var retryAttempt = (attempt) => ({
|
|
|
55
57
|
var renewAttempted = (value) => ({
|
|
56
58
|
renewAttempted: value
|
|
57
59
|
});
|
|
60
|
+
var requestId = (id) => ({ requestId: id });
|
|
61
|
+
var getRequestId = (attrs) => attrs?.requestId ?? null;
|
|
58
62
|
var isProtected = (attrs) => attrs?.protected === true;
|
|
59
63
|
var needUserAgent = (attrs) => attrs?.userAgent === true;
|
|
60
64
|
var isIdempotent = (attrs) => attrs?.idempotencyKey === true;
|
|
@@ -76,7 +80,9 @@ var Attributes = {
|
|
|
76
80
|
renewAttempted,
|
|
77
81
|
wasRenewAttempted,
|
|
78
82
|
clientCredentials,
|
|
79
|
-
getClientCredentials
|
|
83
|
+
getClientCredentials,
|
|
84
|
+
requestId,
|
|
85
|
+
getRequestId
|
|
80
86
|
};
|
|
81
87
|
|
|
82
88
|
// src/shared/api/http.ts
|
|
@@ -86,7 +92,24 @@ var HttpError = class extends Error {
|
|
|
86
92
|
this.name = "HttpError";
|
|
87
93
|
this.response = response;
|
|
88
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Correlates this failure with the `[HTTP]` log lines for the same request,
|
|
97
|
+
* which carry the method, the URL, the duration and every retry. `null` when
|
|
98
|
+
* the response did not come from an {@link HttpClient}.
|
|
99
|
+
*
|
|
100
|
+
* Worth quoting in a bug report: it is what makes a log excerpt readable.
|
|
101
|
+
*/
|
|
102
|
+
get requestId() {
|
|
103
|
+
return this.response.requestId ?? null;
|
|
104
|
+
}
|
|
89
105
|
};
|
|
106
|
+
function apiErrorCode(error) {
|
|
107
|
+
if (!(error instanceof HttpError)) return null;
|
|
108
|
+
const body = error.response.body;
|
|
109
|
+
if (typeof body !== "object" || body === null) return null;
|
|
110
|
+
const code = body.code;
|
|
111
|
+
return typeof code === "string" ? code : null;
|
|
112
|
+
}
|
|
90
113
|
async function makeRequest(request) {
|
|
91
114
|
const headers = {
|
|
92
115
|
Accept: "application/json",
|
|
@@ -192,11 +215,185 @@ var HEADER_API_VERSION = "X-API-Version";
|
|
|
192
215
|
var HEADER_IDEMPOTENCY_KEY = "Idempotency-Key";
|
|
193
216
|
var API_VERSION = "2025-10-17";
|
|
194
217
|
|
|
218
|
+
// src/shared/types/errors.ts
|
|
219
|
+
var NotImplementedError = class extends Error {
|
|
220
|
+
constructor(message = "Not implemented yet") {
|
|
221
|
+
super(message);
|
|
222
|
+
this.name = "NotImplementedError";
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
var NotAuthenticatedError = class extends Error {
|
|
226
|
+
constructor(message = "The user is not authenticated. Go through the OAuth flow first!") {
|
|
227
|
+
super(message);
|
|
228
|
+
this.name = "NotAuthenticatedError";
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
var ValidationError = class extends Error {
|
|
232
|
+
constructor(message) {
|
|
233
|
+
super(message);
|
|
234
|
+
this.name = "ValidationError";
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
var InvariantError = class extends Error {
|
|
238
|
+
constructor(message) {
|
|
239
|
+
super(message);
|
|
240
|
+
this.name = "InvariantError";
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
// src/shared/core/observability/log-cause.ts
|
|
245
|
+
function classifyLogCause(error) {
|
|
246
|
+
if (error instanceof HttpError) {
|
|
247
|
+
return httpCause(error);
|
|
248
|
+
}
|
|
249
|
+
if (error instanceof ValidationError) {
|
|
250
|
+
return { type: "validation", message: error.message };
|
|
251
|
+
}
|
|
252
|
+
if (error instanceof InvariantError) {
|
|
253
|
+
return { type: "invariant", message: error.message };
|
|
254
|
+
}
|
|
255
|
+
if (error instanceof NotAuthenticatedError) {
|
|
256
|
+
return { type: "not-authenticated" };
|
|
257
|
+
}
|
|
258
|
+
if (error instanceof NotImplementedError) {
|
|
259
|
+
return { type: "not-implemented" };
|
|
260
|
+
}
|
|
261
|
+
return { type: "generic-error", name: errorName(error) };
|
|
262
|
+
}
|
|
263
|
+
function describeErrorUnredacted(error) {
|
|
264
|
+
if (error instanceof HttpError) {
|
|
265
|
+
return describeHttpErrorRedacted(error);
|
|
266
|
+
}
|
|
267
|
+
if (error instanceof Error) {
|
|
268
|
+
return `${error.name}: ${error.message}`;
|
|
269
|
+
}
|
|
270
|
+
return `thrown non-error: ${stringifyUnredacted(error)}`;
|
|
271
|
+
}
|
|
272
|
+
function stringifyUnredacted(value) {
|
|
273
|
+
if (value === void 0) return "";
|
|
274
|
+
try {
|
|
275
|
+
return JSON.stringify(
|
|
276
|
+
value,
|
|
277
|
+
(_key, item) => typeof item === "bigint" ? `${item}` : item
|
|
278
|
+
) ?? String(value);
|
|
279
|
+
} catch (_) {
|
|
280
|
+
return "<unserializable>";
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function describeHttpErrorRedacted(error) {
|
|
284
|
+
const code = apiErrorCode(error);
|
|
285
|
+
const status = error.response.status;
|
|
286
|
+
return code === null ? `HttpError ${status}` : `HttpError ${status} (${code})`;
|
|
287
|
+
}
|
|
288
|
+
function errorName(error) {
|
|
289
|
+
return error instanceof Error ? error.name : `non-error ${typeof error}`;
|
|
290
|
+
}
|
|
291
|
+
function httpCause(error) {
|
|
292
|
+
return {
|
|
293
|
+
type: "http",
|
|
294
|
+
requestId: error.requestId,
|
|
295
|
+
status: error.response.status,
|
|
296
|
+
code: apiErrorCode(error),
|
|
297
|
+
eventId: apiErrorEventId(error)
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function apiErrorEventId(error) {
|
|
301
|
+
const body = error.response.body;
|
|
302
|
+
if (typeof body !== "object" || body === null) return null;
|
|
303
|
+
const eventId = body.event_id;
|
|
304
|
+
return typeof eventId === "string" ? eventId : null;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// src/shared/core/observability/internal-logger.ts
|
|
308
|
+
function internalLogger(logger, scope) {
|
|
309
|
+
return logger ? scopedLogger(logger, scope, {}) : noopInternalLogger;
|
|
310
|
+
}
|
|
311
|
+
var LEVEL_RANK = {
|
|
312
|
+
none: 0,
|
|
313
|
+
error: 1,
|
|
314
|
+
warn: 2,
|
|
315
|
+
info: 3,
|
|
316
|
+
debug: 4
|
|
317
|
+
};
|
|
318
|
+
function scopedLogger(logger, scope, bindings) {
|
|
319
|
+
const admits = (level) => LEVEL_RANK[logger.level()] >= LEVEL_RANK[level];
|
|
320
|
+
const safe = (event) => ({
|
|
321
|
+
msg: event.msg,
|
|
322
|
+
scope,
|
|
323
|
+
bindings,
|
|
324
|
+
fields: event.fields ?? {},
|
|
325
|
+
...event.cause === void 0 ? {} : { cause: event.cause }
|
|
326
|
+
});
|
|
327
|
+
const unredacted = (event) => ({
|
|
328
|
+
msg: event.msg,
|
|
329
|
+
scope,
|
|
330
|
+
bindings,
|
|
331
|
+
fields: event.fields ?? {}
|
|
332
|
+
});
|
|
333
|
+
const self = {
|
|
334
|
+
child: (binding) => scopedLogger(logger, scope, { ...bindings, ...binding }),
|
|
335
|
+
debug: (event) => {
|
|
336
|
+
if (admits("debug")) logger.debug(() => unredacted(event()));
|
|
337
|
+
},
|
|
338
|
+
info: (event) => {
|
|
339
|
+
if (admits("info")) logger.info(() => safe(event()));
|
|
340
|
+
},
|
|
341
|
+
warn: (event) => {
|
|
342
|
+
if (admits("warn")) logger.warn(() => safe(event()));
|
|
343
|
+
},
|
|
344
|
+
error: (event) => {
|
|
345
|
+
if (admits("error")) logger.error(() => safe(event()));
|
|
346
|
+
},
|
|
347
|
+
failure: (event, error) => {
|
|
348
|
+
if (admits("debug"))
|
|
349
|
+
logger.debug(() => unredacted(verbatim(event(), error)));
|
|
350
|
+
if (admits("error")) logger.error(() => safe(classified(event(), error)));
|
|
351
|
+
},
|
|
352
|
+
warning: (event, error) => {
|
|
353
|
+
if (admits("debug"))
|
|
354
|
+
logger.debug(() => unredacted(verbatim(event(), error)));
|
|
355
|
+
if (admits("warn")) logger.warn(() => safe(classified(event(), error)));
|
|
356
|
+
},
|
|
357
|
+
wrap: async (op, params, run) => {
|
|
358
|
+
const opLog = self.child({ op });
|
|
359
|
+
opLog.debug(() => ({ msg: "call", fields: { params } }));
|
|
360
|
+
try {
|
|
361
|
+
return await run();
|
|
362
|
+
} catch (error) {
|
|
363
|
+
opLog.failure(() => ({ msg: "call failed" }), error);
|
|
364
|
+
throw error;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
return self;
|
|
369
|
+
}
|
|
370
|
+
function verbatim(event, error) {
|
|
371
|
+
return {
|
|
372
|
+
msg: event.msg,
|
|
373
|
+
fields: { ...event.fields, error: describeErrorUnredacted(error) }
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
function classified(event, error) {
|
|
377
|
+
return { ...event, cause: event.cause ?? classifyLogCause(error) };
|
|
378
|
+
}
|
|
379
|
+
var noopInternalLogger = {
|
|
380
|
+
child: () => noopInternalLogger,
|
|
381
|
+
debug: () => void 0,
|
|
382
|
+
info: () => void 0,
|
|
383
|
+
warn: () => void 0,
|
|
384
|
+
error: () => void 0,
|
|
385
|
+
failure: () => void 0,
|
|
386
|
+
warning: () => void 0,
|
|
387
|
+
wrap: (_op, _params, run) => run()
|
|
388
|
+
};
|
|
389
|
+
|
|
195
390
|
// src/shared/api/http-client.ts
|
|
196
391
|
var HttpClient = class {
|
|
197
|
-
constructor(config, middleware = {}) {
|
|
392
|
+
constructor(config, middleware = {}, logger = null, options = {}) {
|
|
198
393
|
this.config = config;
|
|
199
394
|
this.middleware = middleware;
|
|
395
|
+
this.log = internalLogger(logger, "HTTP");
|
|
396
|
+
this.makeRequestId = options.makeRequestId ?? defaultMakeRequestId;
|
|
200
397
|
}
|
|
201
398
|
async send(request) {
|
|
202
399
|
return this.runRequestWithAfterMiddleware(request);
|
|
@@ -232,7 +429,13 @@ var HttpClient = class {
|
|
|
232
429
|
return {
|
|
233
430
|
...request,
|
|
234
431
|
url,
|
|
235
|
-
headers
|
|
432
|
+
headers,
|
|
433
|
+
// Only when absent: a retry or a post-renewal re-send arrives with the
|
|
434
|
+
// first attempt's id already on it, and keeping it is the whole point.
|
|
435
|
+
attributes: Attributes.getRequestId(request.attributes) === null ? Attributes.concat(
|
|
436
|
+
request.attributes ?? Attributes.empty,
|
|
437
|
+
Attributes.requestId(this.makeRequestId())
|
|
438
|
+
) : request.attributes
|
|
236
439
|
};
|
|
237
440
|
}
|
|
238
441
|
/**
|
|
@@ -256,10 +459,89 @@ var HttpClient = class {
|
|
|
256
459
|
}
|
|
257
460
|
return request;
|
|
258
461
|
}
|
|
259
|
-
|
|
260
|
-
|
|
462
|
+
/**
|
|
463
|
+
* One physical attempt, logged as one line.
|
|
464
|
+
*
|
|
465
|
+
* A non-2xx is a `warn` rather than an `error` because the wire does not
|
|
466
|
+
* know whether it is a failure: the retry middleware may turn a 503 into a
|
|
467
|
+
* success, and the token registry reads a 404 as "not listed". The namespace
|
|
468
|
+
* above decides, and logs the `error` when it does.
|
|
469
|
+
*/
|
|
470
|
+
async executeRequest(request) {
|
|
471
|
+
const requestId2 = Attributes.getRequestId(request.attributes);
|
|
472
|
+
const log = requestId2 === null ? this.log : this.log.child({ requestId: requestId2 });
|
|
473
|
+
const attempt = Attributes.getRetryAttempt(request.attributes) + 1;
|
|
474
|
+
const startedAt = Date.now();
|
|
475
|
+
log.debug(() => ({
|
|
476
|
+
msg: "request sent",
|
|
477
|
+
fields: describeRequestUnredacted(request)
|
|
478
|
+
}));
|
|
479
|
+
try {
|
|
480
|
+
const response = await makeRequest(request);
|
|
481
|
+
const elapsed = Date.now() - startedAt;
|
|
482
|
+
const outcome = () => ({
|
|
483
|
+
msg: "request completed",
|
|
484
|
+
fields: {
|
|
485
|
+
...identifyRequest(request),
|
|
486
|
+
"http.response.status_code": response.status,
|
|
487
|
+
duration_ms: elapsed,
|
|
488
|
+
attempt
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
if (response.status >= 200 && response.status < 300) {
|
|
492
|
+
log.info(outcome);
|
|
493
|
+
} else {
|
|
494
|
+
log.warn(outcome);
|
|
495
|
+
}
|
|
496
|
+
log.debug(() => ({
|
|
497
|
+
msg: "response received",
|
|
498
|
+
fields: { body: response.body }
|
|
499
|
+
}));
|
|
500
|
+
return requestId2 === null ? response : { ...response, requestId: requestId2 };
|
|
501
|
+
} catch (error) {
|
|
502
|
+
const elapsed = Date.now() - startedAt;
|
|
503
|
+
log.warning(
|
|
504
|
+
() => ({
|
|
505
|
+
msg: "request threw",
|
|
506
|
+
fields: {
|
|
507
|
+
...identifyRequest(request),
|
|
508
|
+
duration_ms: elapsed,
|
|
509
|
+
attempt
|
|
510
|
+
}
|
|
511
|
+
}),
|
|
512
|
+
error
|
|
513
|
+
);
|
|
514
|
+
throw error;
|
|
515
|
+
}
|
|
261
516
|
}
|
|
262
517
|
};
|
|
518
|
+
function identifyRequest(request) {
|
|
519
|
+
const { host, path } = splitUrl(request.url);
|
|
520
|
+
return {
|
|
521
|
+
"http.request.method": request.method,
|
|
522
|
+
"server.address": host,
|
|
523
|
+
"url.path": path
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
function splitUrl(url) {
|
|
527
|
+
try {
|
|
528
|
+
const parsed = new URL(url);
|
|
529
|
+
return { host: parsed.host, path: parsed.pathname };
|
|
530
|
+
} catch (_) {
|
|
531
|
+
return { host: null, path: url };
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
function defaultMakeRequestId() {
|
|
535
|
+
return Math.random().toString(36).slice(2, 10).padEnd(8, "0");
|
|
536
|
+
}
|
|
537
|
+
function describeRequestUnredacted(request) {
|
|
538
|
+
return {
|
|
539
|
+
"http.request.method": request.method,
|
|
540
|
+
"url.full": buildUrlWithQueryParams(request.url, request.queryParams),
|
|
541
|
+
headers: request.headers,
|
|
542
|
+
...request.method === "POST" ? { body: request.body } : {}
|
|
543
|
+
};
|
|
544
|
+
}
|
|
263
545
|
|
|
264
546
|
// src/shared/api/middleware/attach-session-middleware.ts
|
|
265
547
|
function attachSessionMiddleware(fetchAccessToken) {
|
|
@@ -390,18 +672,22 @@ function renewSessionMiddleware(fetchAccessToken) {
|
|
|
390
672
|
|
|
391
673
|
// src/shared/api/authenticated-api-client.ts
|
|
392
674
|
var AuthenticatedApiClient = class {
|
|
393
|
-
constructor(config, fetchAccessToken, additionalBeforeRequest = []) {
|
|
394
|
-
this.httpClient = new HttpClient(
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
675
|
+
constructor(config, fetchAccessToken, additionalBeforeRequest = [], logger = null) {
|
|
676
|
+
this.httpClient = new HttpClient(
|
|
677
|
+
config,
|
|
678
|
+
{
|
|
679
|
+
beforeRequest: [
|
|
680
|
+
attachSessionMiddleware(fetchAccessToken),
|
|
681
|
+
...additionalBeforeRequest,
|
|
682
|
+
idempotencyKeyMiddleware
|
|
683
|
+
],
|
|
684
|
+
afterRequest: [
|
|
685
|
+
renewSessionMiddleware(fetchAccessToken),
|
|
686
|
+
requestRetryMiddleware
|
|
687
|
+
]
|
|
688
|
+
},
|
|
689
|
+
logger
|
|
690
|
+
);
|
|
405
691
|
}
|
|
406
692
|
async send(request) {
|
|
407
693
|
const response = await this.httpClient.send(request);
|
|
@@ -415,8 +701,13 @@ var AuthenticatedApiClient = class {
|
|
|
415
701
|
|
|
416
702
|
// src/server/core/api/api-client.ts
|
|
417
703
|
var ApiClient = class {
|
|
418
|
-
constructor(config, fetchAccessToken) {
|
|
419
|
-
this.client = new AuthenticatedApiClient(
|
|
704
|
+
constructor(config, fetchAccessToken, logger = null) {
|
|
705
|
+
this.client = new AuthenticatedApiClient(
|
|
706
|
+
config,
|
|
707
|
+
fetchAccessToken,
|
|
708
|
+
[],
|
|
709
|
+
logger
|
|
710
|
+
);
|
|
420
711
|
}
|
|
421
712
|
async send(request) {
|
|
422
713
|
return this.client.send(request);
|
|
@@ -448,33 +739,43 @@ var OAuthSession = {
|
|
|
448
739
|
};
|
|
449
740
|
|
|
450
741
|
// src/server/core/server-auth-namespace.ts
|
|
742
|
+
function emptySessionStore() {
|
|
743
|
+
return { getSession: async () => null };
|
|
744
|
+
}
|
|
451
745
|
var ServerAuthNamespaceImpl = class {
|
|
452
746
|
constructor(api, config) {
|
|
453
747
|
this.api = api;
|
|
454
748
|
this.config = config;
|
|
749
|
+
this.log = internalLogger(config.logger ?? null, "AUTH");
|
|
455
750
|
}
|
|
456
|
-
async completeOAuth({
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
751
|
+
async completeOAuth(params) {
|
|
752
|
+
return this.log.wrap("completeOAuth", void 0, async () => {
|
|
753
|
+
const setSession = this.writableSessionStore();
|
|
754
|
+
const sessionDto = await this.api.send({
|
|
755
|
+
method: "POST",
|
|
756
|
+
url: `/oauth/token`,
|
|
757
|
+
body: {
|
|
758
|
+
grant_type: "authorization_code",
|
|
759
|
+
code: params.code,
|
|
760
|
+
redirect_uri: this.config.redirectUri,
|
|
761
|
+
client_id: this.config.clientId,
|
|
762
|
+
client_secret: this.config.clientSecret,
|
|
763
|
+
code_verifier: params.codeVerifier
|
|
764
|
+
}
|
|
765
|
+
});
|
|
766
|
+
const session = OAuthSession.fromDto(sessionDto);
|
|
767
|
+
await setSession(session);
|
|
768
|
+
return session;
|
|
472
769
|
});
|
|
473
|
-
const session = OAuthSession.fromDto(sessionDto);
|
|
474
|
-
await setSession(session);
|
|
475
|
-
return session;
|
|
476
770
|
}
|
|
477
771
|
async getAccessToken() {
|
|
772
|
+
return this.log.wrap(
|
|
773
|
+
"getAccessToken",
|
|
774
|
+
void 0,
|
|
775
|
+
() => this.readAccessToken()
|
|
776
|
+
);
|
|
777
|
+
}
|
|
778
|
+
async readAccessToken() {
|
|
478
779
|
const sessionStore = this.config.sessionStore;
|
|
479
780
|
const session = await sessionStore.getSession();
|
|
480
781
|
if (session == null) return null;
|
|
@@ -486,12 +787,19 @@ var ServerAuthNamespaceImpl = class {
|
|
|
486
787
|
}
|
|
487
788
|
const setSession = sessionStore.setSession?.bind(sessionStore);
|
|
488
789
|
if (!setSession) {
|
|
790
|
+
this.log.child({ op: "getAccessToken" }).warn(() => ({
|
|
791
|
+
msg: "serving an expired token: the session store is read-only, so it cannot be refreshed"
|
|
792
|
+
}));
|
|
489
793
|
return session.accessToken;
|
|
490
794
|
}
|
|
491
795
|
return this.refreshSession(session.refreshToken, setSession);
|
|
492
796
|
}
|
|
493
797
|
async refreshSession(refreshToken, setSession) {
|
|
798
|
+
const log = this.log.child({ op: "refresh" });
|
|
494
799
|
if (!refreshToken) {
|
|
800
|
+
log.warn(() => ({
|
|
801
|
+
msg: "clearing the session: it carries no refresh token"
|
|
802
|
+
}));
|
|
495
803
|
await setSession(null);
|
|
496
804
|
return null;
|
|
497
805
|
}
|
|
@@ -508,26 +816,36 @@ var ServerAuthNamespaceImpl = class {
|
|
|
508
816
|
});
|
|
509
817
|
const newSession = OAuthSession.fromDto(sessionDto);
|
|
510
818
|
await setSession(newSession);
|
|
819
|
+
log.info(() => ({ msg: "session renewed" }));
|
|
511
820
|
return newSession.accessToken;
|
|
512
|
-
} catch {
|
|
821
|
+
} catch (error) {
|
|
822
|
+
log.failure(
|
|
823
|
+
() => ({ msg: "refresh failed; clearing the session" }),
|
|
824
|
+
error
|
|
825
|
+
);
|
|
513
826
|
await setSession(null);
|
|
514
827
|
return null;
|
|
515
828
|
}
|
|
516
829
|
}
|
|
517
830
|
async clientCredentials() {
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
831
|
+
return this.log.wrap("clientCredentials", void 0, async () => {
|
|
832
|
+
const sessionDto = await this.api.send({
|
|
833
|
+
method: "POST",
|
|
834
|
+
url: `/oauth/token`,
|
|
835
|
+
body: {
|
|
836
|
+
grant_type: "client_credentials",
|
|
837
|
+
client_id: this.config.clientId,
|
|
838
|
+
client_secret: this.config.clientSecret
|
|
839
|
+
}
|
|
840
|
+
});
|
|
841
|
+
const session = OAuthSession.fromDto(sessionDto);
|
|
842
|
+
return ClientCredentialsOAuth(session.accessToken);
|
|
526
843
|
});
|
|
527
|
-
const session = OAuthSession.fromDto(sessionDto);
|
|
528
|
-
return ClientCredentialsOAuth(session.accessToken);
|
|
529
844
|
}
|
|
530
845
|
async logout() {
|
|
846
|
+
return this.log.wrap("logout", void 0, () => this.revokeAndClear());
|
|
847
|
+
}
|
|
848
|
+
async revokeAndClear() {
|
|
531
849
|
const setSession = this.writableSessionStore();
|
|
532
850
|
const session = await this.config.sessionStore.getSession();
|
|
533
851
|
if (session == null) return;
|
|
@@ -545,6 +863,9 @@ var ServerAuthNamespaceImpl = class {
|
|
|
545
863
|
if (!(err instanceof HttpError) || this.config.strict) {
|
|
546
864
|
throw err;
|
|
547
865
|
}
|
|
866
|
+
this.log.child({ op: "logout" }).warn(() => ({
|
|
867
|
+
msg: "the token was not revoked upstream; the local session is cleared regardless"
|
|
868
|
+
}));
|
|
548
869
|
}
|
|
549
870
|
await setSession(null);
|
|
550
871
|
}
|
|
@@ -578,48 +899,6 @@ async function fetchAllPages(fetchPage, baseParams) {
|
|
|
578
899
|
return items;
|
|
579
900
|
}
|
|
580
901
|
|
|
581
|
-
// src/shared/types/offer.ts
|
|
582
|
-
var OfferId = (value) => value;
|
|
583
|
-
var OfferSlug = (value) => value;
|
|
584
|
-
var Offer = {
|
|
585
|
-
fromDto: (dto) => ({
|
|
586
|
-
id: OfferId(dto.id),
|
|
587
|
-
slug: OfferSlug(dto.slug),
|
|
588
|
-
type: dto.type,
|
|
589
|
-
tagline: dto.tagline,
|
|
590
|
-
bannerUrl: dto.banner_url,
|
|
591
|
-
logoUrl: dto.logo_url,
|
|
592
|
-
startsAt: new Date(dto.starts_at),
|
|
593
|
-
endsAt: dto.ends_at ? new Date(dto.ends_at) : null
|
|
594
|
-
})
|
|
595
|
-
};
|
|
596
|
-
|
|
597
|
-
// src/shared/types/asset.ts
|
|
598
|
-
var AssetId = (value) => value;
|
|
599
|
-
var AssetCode = (value) => value;
|
|
600
|
-
var Asset = {
|
|
601
|
-
fromDto: (dto) => ({
|
|
602
|
-
id: AssetId(dto.id),
|
|
603
|
-
code: AssetCode(dto.code),
|
|
604
|
-
name: dto.name,
|
|
605
|
-
fractionalDigits: dto.fractional_digits
|
|
606
|
-
})
|
|
607
|
-
};
|
|
608
|
-
|
|
609
|
-
// src/shared/types/errors.ts
|
|
610
|
-
var NotAuthenticatedError = class extends Error {
|
|
611
|
-
constructor(message = "The user is not authenticated. Go through the OAuth flow first!") {
|
|
612
|
-
super(message);
|
|
613
|
-
this.name = "NotAuthenticatedError";
|
|
614
|
-
}
|
|
615
|
-
};
|
|
616
|
-
var ValidationError = class extends Error {
|
|
617
|
-
constructor(message) {
|
|
618
|
-
super(message);
|
|
619
|
-
this.name = "ValidationError";
|
|
620
|
-
}
|
|
621
|
-
};
|
|
622
|
-
|
|
623
902
|
// src/shared/types/blockchain/core.ts
|
|
624
903
|
var ETHEREUM_CHAINS = {
|
|
625
904
|
ethereum_mainnet: true,
|
|
@@ -660,11 +939,14 @@ var STABLE_DECIMALS = AssetDecimals(6);
|
|
|
660
939
|
var DecimalString = (value) => value;
|
|
661
940
|
var MAX_UINT_256 = 2n ** 256n - 1n;
|
|
662
941
|
var assertUint256 = (value) => {
|
|
663
|
-
if (value
|
|
664
|
-
|
|
665
|
-
}
|
|
666
|
-
return value;
|
|
942
|
+
if (isUint256(value)) return value;
|
|
943
|
+
throw new InvariantError(`Value out of uint256 bounds: ${value}`);
|
|
667
944
|
};
|
|
945
|
+
var parseUint256 = (value, label) => {
|
|
946
|
+
if (isUint256(value)) return value;
|
|
947
|
+
throw new ValidationError(`${label}: out of uint256 bounds (${value})`);
|
|
948
|
+
};
|
|
949
|
+
var isUint256 = (value) => value >= 0n && value <= MAX_UINT_256;
|
|
668
950
|
var BlockchainAmount = Object.assign(
|
|
669
951
|
(value) => value,
|
|
670
952
|
{
|
|
@@ -674,43 +956,100 @@ var BlockchainAmount = Object.assign(
|
|
|
674
956
|
);
|
|
675
957
|
function combineAmounts(a, b, op) {
|
|
676
958
|
if (a.decimals !== b.decimals) {
|
|
677
|
-
throw new
|
|
959
|
+
throw new InvariantError(
|
|
678
960
|
`Cannot combine BlockchainAmounts with different decimals: ${a.decimals} vs ${b.decimals}`
|
|
679
961
|
);
|
|
680
962
|
}
|
|
681
963
|
const raw = op(a.raw, b.raw);
|
|
682
964
|
if (raw < 0n || raw > MAX_UINT_256) {
|
|
683
|
-
throw new
|
|
965
|
+
throw new InvariantError(`BlockchainAmount out of uint256 bounds: ${raw}`);
|
|
684
966
|
}
|
|
685
967
|
return BlockchainAmount({ raw, decimals: a.decimals });
|
|
686
968
|
}
|
|
687
969
|
var AssetSymbol = (value) => value;
|
|
688
970
|
|
|
971
|
+
// src/shared/types/offer.ts
|
|
972
|
+
var OfferId = (value) => value;
|
|
973
|
+
var OfferSlug = (value) => value;
|
|
974
|
+
var Offer = {
|
|
975
|
+
fromDto: (dto) => {
|
|
976
|
+
if (!Array.isArray(dto.tokens)) {
|
|
977
|
+
throw new ValidationError(
|
|
978
|
+
`Offer.tokens: expected an array, got ${typeof dto.tokens}`
|
|
979
|
+
);
|
|
980
|
+
}
|
|
981
|
+
return {
|
|
982
|
+
id: OfferId(dto.id),
|
|
983
|
+
slug: OfferSlug(dto.slug),
|
|
984
|
+
type: dto.type,
|
|
985
|
+
tagline: dto.tagline,
|
|
986
|
+
bannerUrl: dto.banner_url,
|
|
987
|
+
logoUrl: dto.logo_url,
|
|
988
|
+
startsAt: new Date(dto.starts_at),
|
|
989
|
+
endsAt: dto.ends_at ? new Date(dto.ends_at) : null,
|
|
990
|
+
tokens: dto.tokens.map(OfferToken.fromDto)
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
};
|
|
994
|
+
var OfferToken = {
|
|
995
|
+
fromDto: (dto) => ({
|
|
996
|
+
role: dto.role,
|
|
997
|
+
chain: Chain(dto.chain),
|
|
998
|
+
address: EvmContractAddress(dto.address)
|
|
999
|
+
})
|
|
1000
|
+
};
|
|
1001
|
+
|
|
1002
|
+
// src/shared/types/asset.ts
|
|
1003
|
+
var AssetId = (value) => value;
|
|
1004
|
+
var AssetCode = (value) => value;
|
|
1005
|
+
var Asset = {
|
|
1006
|
+
fromDto: (dto) => ({
|
|
1007
|
+
id: AssetId(dto.id),
|
|
1008
|
+
code: AssetCode(dto.code),
|
|
1009
|
+
name: dto.name,
|
|
1010
|
+
fractionalDigits: dto.fractional_digits
|
|
1011
|
+
})
|
|
1012
|
+
};
|
|
1013
|
+
|
|
689
1014
|
// src/shared/types/offer-detail.ts
|
|
690
1015
|
var OfferOptionId = (value) => value;
|
|
691
1016
|
var OfferOptionSlug = (value) => value;
|
|
692
1017
|
var OfferDetail = {
|
|
693
1018
|
fromDto: (dto) => {
|
|
694
1019
|
if (!Array.isArray(dto.funding_assets)) {
|
|
695
|
-
throw new
|
|
1020
|
+
throw new ValidationError(
|
|
1021
|
+
`OfferDetail.funding_assets: expected an array, got ${typeof dto.funding_assets}`
|
|
1022
|
+
);
|
|
696
1023
|
}
|
|
697
1024
|
if (!Array.isArray(dto.options)) {
|
|
698
|
-
throw new
|
|
1025
|
+
throw new ValidationError(
|
|
1026
|
+
`OfferDetail.options: expected an array, got ${typeof dto.options}`
|
|
1027
|
+
);
|
|
699
1028
|
}
|
|
700
1029
|
if (!Array.isArray(dto.terms)) {
|
|
701
|
-
throw new
|
|
1030
|
+
throw new ValidationError(
|
|
1031
|
+
`OfferDetail.terms: expected an array, got ${typeof dto.terms}`
|
|
1032
|
+
);
|
|
702
1033
|
}
|
|
703
1034
|
if (!Array.isArray(dto.links)) {
|
|
704
|
-
throw new
|
|
1035
|
+
throw new ValidationError(
|
|
1036
|
+
`OfferDetail.links: expected an array, got ${typeof dto.links}`
|
|
1037
|
+
);
|
|
705
1038
|
}
|
|
706
1039
|
if (!Array.isArray(dto.faqs)) {
|
|
707
|
-
throw new
|
|
1040
|
+
throw new ValidationError(
|
|
1041
|
+
`OfferDetail.faqs: expected an array, got ${typeof dto.faqs}`
|
|
1042
|
+
);
|
|
708
1043
|
}
|
|
709
1044
|
if (!Array.isArray(dto.milestones)) {
|
|
710
|
-
throw new
|
|
1045
|
+
throw new ValidationError(
|
|
1046
|
+
`OfferDetail.milestones: expected an array, got ${typeof dto.milestones}`
|
|
1047
|
+
);
|
|
711
1048
|
}
|
|
712
1049
|
if (!Array.isArray(dto.tokens)) {
|
|
713
|
-
throw new
|
|
1050
|
+
throw new ValidationError(
|
|
1051
|
+
`OfferDetail.tokens: expected an array, got ${typeof dto.tokens}`
|
|
1052
|
+
);
|
|
714
1053
|
}
|
|
715
1054
|
return {
|
|
716
1055
|
id: OfferId(dto.id),
|
|
@@ -772,13 +1111,6 @@ var Milestone = {
|
|
|
772
1111
|
status: dto.status
|
|
773
1112
|
})
|
|
774
1113
|
};
|
|
775
|
-
var OfferToken = {
|
|
776
|
-
fromDto: (dto) => ({
|
|
777
|
-
role: dto.role,
|
|
778
|
-
chain: Chain(dto.chain),
|
|
779
|
-
address: EvmContractAddress(dto.address)
|
|
780
|
-
})
|
|
781
|
-
};
|
|
782
1114
|
|
|
783
1115
|
// src/shared/types/pagination.ts
|
|
784
1116
|
var Cursor = (value) => value;
|
|
@@ -838,18 +1170,25 @@ async function fetchOfferDetails(api, id, clientCreds) {
|
|
|
838
1170
|
var ServerOffersNamespaceImpl = class {
|
|
839
1171
|
constructor(ctx) {
|
|
840
1172
|
this.ctx = ctx;
|
|
1173
|
+
this.log = internalLogger(ctx.logger, "OFFERS");
|
|
841
1174
|
}
|
|
842
1175
|
async list(clientCreds) {
|
|
843
|
-
|
|
844
|
-
|
|
1176
|
+
return this.log.wrap("list", clientCreds, async () => {
|
|
1177
|
+
await this.ctx.ensureAuthenticated(clientCreds);
|
|
1178
|
+
return fetchOffers(this.ctx.api, clientCreds);
|
|
1179
|
+
});
|
|
845
1180
|
}
|
|
846
1181
|
async listPage(params, clientCreds) {
|
|
847
|
-
|
|
848
|
-
|
|
1182
|
+
return this.log.wrap("listPage", { params, clientCreds }, async () => {
|
|
1183
|
+
await this.ctx.ensureAuthenticated(clientCreds);
|
|
1184
|
+
return fetchOffersPage(this.ctx.api, params, clientCreds);
|
|
1185
|
+
});
|
|
849
1186
|
}
|
|
850
1187
|
async get(id, clientCreds) {
|
|
851
|
-
|
|
852
|
-
|
|
1188
|
+
return this.log.wrap("get", { id, clientCreds }, async () => {
|
|
1189
|
+
await this.ctx.ensureAuthenticated(clientCreds);
|
|
1190
|
+
return fetchOfferDetails(this.ctx.api, id, clientCreds);
|
|
1191
|
+
});
|
|
853
1192
|
}
|
|
854
1193
|
};
|
|
855
1194
|
|
|
@@ -982,38 +1321,49 @@ async function fetchPii(api) {
|
|
|
982
1321
|
var RequirementsNamespaceImpl = class {
|
|
983
1322
|
constructor(ctx) {
|
|
984
1323
|
this.ctx = ctx;
|
|
1324
|
+
this.log = internalLogger(ctx.logger, "REQUIREMENTS");
|
|
985
1325
|
}
|
|
986
1326
|
async forOffer(offerId) {
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
1327
|
+
return this.log.wrap("forOffer", offerId, async () => {
|
|
1328
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1329
|
+
return fetchOfferRequirements(
|
|
1330
|
+
this.ctx.api,
|
|
1331
|
+
offerId,
|
|
1332
|
+
void 0
|
|
1333
|
+
);
|
|
1334
|
+
});
|
|
993
1335
|
}
|
|
994
1336
|
async statuses(offerId) {
|
|
995
|
-
|
|
996
|
-
|
|
1337
|
+
return this.log.wrap("statuses", offerId, async () => {
|
|
1338
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1339
|
+
return fetchRequirementStatuses(this.ctx.api, offerId);
|
|
1340
|
+
});
|
|
997
1341
|
}
|
|
998
1342
|
async createKycToken(params) {
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1343
|
+
return this.log.wrap("createKycToken", params, async () => {
|
|
1344
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1345
|
+
return createKycToken(
|
|
1346
|
+
this.ctx.api,
|
|
1347
|
+
params?.levelName,
|
|
1348
|
+
params?.reset
|
|
1349
|
+
);
|
|
1350
|
+
});
|
|
1005
1351
|
}
|
|
1006
1352
|
async getPii() {
|
|
1007
|
-
|
|
1008
|
-
|
|
1353
|
+
return this.log.wrap("getPii", void 0, async () => {
|
|
1354
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1355
|
+
return fetchPii(this.ctx.api);
|
|
1356
|
+
});
|
|
1009
1357
|
}
|
|
1010
1358
|
async submitDocument(params) {
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1359
|
+
return this.log.wrap("submitDocument", params, async () => {
|
|
1360
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1361
|
+
return submitDocument(
|
|
1362
|
+
this.ctx.api,
|
|
1363
|
+
params.documentType,
|
|
1364
|
+
params.fields
|
|
1365
|
+
);
|
|
1366
|
+
});
|
|
1017
1367
|
}
|
|
1018
1368
|
};
|
|
1019
1369
|
|
|
@@ -1024,12 +1374,14 @@ var ServerRequirementsNamespaceImpl = class extends RequirementsNamespaceImpl {
|
|
|
1024
1374
|
this.serverCtx = serverCtx;
|
|
1025
1375
|
}
|
|
1026
1376
|
async forOffer(offerId, clientCreds) {
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1377
|
+
return this.log.wrap("forOffer", { offerId, clientCreds }, async () => {
|
|
1378
|
+
await this.serverCtx.ensureAuthenticated(clientCreds);
|
|
1379
|
+
return fetchOfferRequirements(
|
|
1380
|
+
this.serverCtx.api,
|
|
1381
|
+
offerId,
|
|
1382
|
+
clientCreds
|
|
1383
|
+
);
|
|
1384
|
+
});
|
|
1033
1385
|
}
|
|
1034
1386
|
};
|
|
1035
1387
|
|
|
@@ -1044,25 +1396,31 @@ var SwapAuthorization = {
|
|
|
1044
1396
|
};
|
|
1045
1397
|
var SwapPreview = {
|
|
1046
1398
|
fromDto: (dto) => ({
|
|
1047
|
-
inputAmount:
|
|
1048
|
-
|
|
1049
|
-
|
|
1399
|
+
inputAmount: parseUint256(
|
|
1400
|
+
BigInt(dto.pay_input_amount),
|
|
1401
|
+
"SwapPreview.pay_input_amount"
|
|
1402
|
+
),
|
|
1403
|
+
fee: parseUint256(BigInt(dto.fee), "SwapPreview.fee"),
|
|
1404
|
+
outputAmount: parseUint256(
|
|
1405
|
+
BigInt(dto.receive_output_amount),
|
|
1406
|
+
"SwapPreview.receive_output_amount"
|
|
1407
|
+
)
|
|
1050
1408
|
})
|
|
1051
1409
|
};
|
|
1052
1410
|
var SwapStatus = {
|
|
1053
1411
|
fromDto: (dto) => ({
|
|
1054
|
-
stopped:
|
|
1055
|
-
swapLevel:
|
|
1412
|
+
stopped: parseUint256(BigInt(dto.stopped), "SwapStatus.stopped"),
|
|
1413
|
+
swapLevel: parseUint256(BigInt(dto.swap_level), "SwapStatus.swap_level")
|
|
1056
1414
|
})
|
|
1057
1415
|
};
|
|
1058
1416
|
var TokenAllowance = {
|
|
1059
1417
|
fromDto: (dto) => ({
|
|
1060
|
-
allowance:
|
|
1418
|
+
allowance: parseUint256(BigInt(dto.allowance), "TokenAllowance.allowance")
|
|
1061
1419
|
})
|
|
1062
1420
|
};
|
|
1063
1421
|
var TokenBalance = {
|
|
1064
1422
|
fromDto: (dto) => ({
|
|
1065
|
-
balance:
|
|
1423
|
+
balance: parseUint256(BigInt(dto.balance), "TokenBalance.balance")
|
|
1066
1424
|
})
|
|
1067
1425
|
};
|
|
1068
1426
|
var AllowWalletResponse = {
|
|
@@ -1191,14 +1549,19 @@ function toErc20Asset(dto) {
|
|
|
1191
1549
|
var Erc20NamespaceImpl = class {
|
|
1192
1550
|
constructor(ctx) {
|
|
1193
1551
|
this.ctx = ctx;
|
|
1552
|
+
this.log = internalLogger(ctx.logger, "ERC20");
|
|
1194
1553
|
}
|
|
1195
1554
|
async getAllowance(params) {
|
|
1196
|
-
|
|
1197
|
-
|
|
1555
|
+
return this.log.wrap("getAllowance", params, async () => {
|
|
1556
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1557
|
+
return getTokenAllowance(this.ctx.api, params);
|
|
1558
|
+
});
|
|
1198
1559
|
}
|
|
1199
1560
|
async getBalance(params) {
|
|
1200
|
-
|
|
1201
|
-
|
|
1561
|
+
return this.log.wrap("getBalance", params, async () => {
|
|
1562
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1563
|
+
return getTokenBalance(this.ctx.api, params);
|
|
1564
|
+
});
|
|
1202
1565
|
}
|
|
1203
1566
|
};
|
|
1204
1567
|
|
|
@@ -1287,22 +1650,31 @@ async function createParticipation(api, params) {
|
|
|
1287
1650
|
var CoinListTokenSaleNamespaceImpl = class {
|
|
1288
1651
|
constructor(ctx) {
|
|
1289
1652
|
this.ctx = ctx;
|
|
1653
|
+
this.log = internalLogger(ctx.logger, "TOKEN_SALE");
|
|
1290
1654
|
}
|
|
1291
1655
|
async list(offerId) {
|
|
1292
|
-
|
|
1293
|
-
|
|
1656
|
+
return this.log.wrap("list", offerId, async () => {
|
|
1657
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1658
|
+
return fetchParticipations(this.ctx.api, offerId);
|
|
1659
|
+
});
|
|
1294
1660
|
}
|
|
1295
1661
|
async listPage(params) {
|
|
1296
|
-
|
|
1297
|
-
|
|
1662
|
+
return this.log.wrap("listPage", params, async () => {
|
|
1663
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1664
|
+
return fetchParticipationsPage(this.ctx.api, params);
|
|
1665
|
+
});
|
|
1298
1666
|
}
|
|
1299
1667
|
async get(id) {
|
|
1300
|
-
|
|
1301
|
-
|
|
1668
|
+
return this.log.wrap("get", id, async () => {
|
|
1669
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1670
|
+
return fetchParticipation(this.ctx.api, id);
|
|
1671
|
+
});
|
|
1302
1672
|
}
|
|
1303
1673
|
async createParticipation(params) {
|
|
1304
|
-
|
|
1305
|
-
|
|
1674
|
+
return this.log.wrap("createParticipation", params, async () => {
|
|
1675
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1676
|
+
return createParticipation(this.ctx.api, params);
|
|
1677
|
+
});
|
|
1306
1678
|
}
|
|
1307
1679
|
};
|
|
1308
1680
|
|
|
@@ -1520,18 +1892,25 @@ function sizeParam(params) {
|
|
|
1520
1892
|
var OndoNamespaceImpl = class {
|
|
1521
1893
|
constructor(ctx) {
|
|
1522
1894
|
this.ctx = ctx;
|
|
1895
|
+
this.log = internalLogger(ctx.logger, "ONDO");
|
|
1523
1896
|
}
|
|
1524
1897
|
async getTradingStatus(params) {
|
|
1525
|
-
|
|
1526
|
-
|
|
1898
|
+
return this.log.wrap("getTradingStatus", params, async () => {
|
|
1899
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1900
|
+
return getOndoTradingStatus(this.ctx.api, params);
|
|
1901
|
+
});
|
|
1527
1902
|
}
|
|
1528
1903
|
async getQuote(params) {
|
|
1529
|
-
|
|
1530
|
-
|
|
1904
|
+
return this.log.wrap("getQuote", params, async () => {
|
|
1905
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1906
|
+
return getOndoQuote(this.ctx.api, params);
|
|
1907
|
+
});
|
|
1531
1908
|
}
|
|
1532
1909
|
async buildSwapTransaction(params) {
|
|
1533
|
-
|
|
1534
|
-
|
|
1910
|
+
return this.log.wrap("buildSwapTransaction", params, async () => {
|
|
1911
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1912
|
+
return buildOndoSwapTransaction(this.ctx.api, params);
|
|
1913
|
+
});
|
|
1535
1914
|
}
|
|
1536
1915
|
};
|
|
1537
1916
|
|
|
@@ -1539,26 +1918,37 @@ var OndoNamespaceImpl = class {
|
|
|
1539
1918
|
var SuperstateSwapNamespaceImpl = class {
|
|
1540
1919
|
constructor(ctx) {
|
|
1541
1920
|
this.ctx = ctx;
|
|
1921
|
+
this.log = internalLogger(ctx.logger, "SUPERSTATE");
|
|
1542
1922
|
}
|
|
1543
1923
|
async getAuthorization(params) {
|
|
1544
|
-
|
|
1545
|
-
|
|
1924
|
+
return this.log.wrap("getAuthorization", params, async () => {
|
|
1925
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1926
|
+
return getSwapAuthorization(this.ctx.api, params);
|
|
1927
|
+
});
|
|
1546
1928
|
}
|
|
1547
1929
|
async getPreview(params) {
|
|
1548
|
-
|
|
1549
|
-
|
|
1930
|
+
return this.log.wrap("getPreview", params, async () => {
|
|
1931
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1932
|
+
return getSwapPreview(this.ctx.api, params);
|
|
1933
|
+
});
|
|
1550
1934
|
}
|
|
1551
1935
|
async getStatus(params) {
|
|
1552
|
-
|
|
1553
|
-
|
|
1936
|
+
return this.log.wrap("getStatus", params, async () => {
|
|
1937
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1938
|
+
return getSwapStatus(this.ctx.api, params);
|
|
1939
|
+
});
|
|
1554
1940
|
}
|
|
1555
1941
|
async getOutputToken(params) {
|
|
1556
|
-
|
|
1557
|
-
|
|
1942
|
+
return this.log.wrap("getOutputToken", params, async () => {
|
|
1943
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1944
|
+
return getSwapOutputToken(this.ctx.api, params);
|
|
1945
|
+
});
|
|
1558
1946
|
}
|
|
1559
1947
|
async allowWallet(params) {
|
|
1560
|
-
|
|
1561
|
-
|
|
1948
|
+
return this.log.wrap("allowWallet", params, async () => {
|
|
1949
|
+
await this.ctx.ensureUserAuthenticated();
|
|
1950
|
+
return allowWallet(this.ctx.api, params);
|
|
1951
|
+
});
|
|
1562
1952
|
}
|
|
1563
1953
|
};
|
|
1564
1954
|
|
|
@@ -1629,8 +2019,8 @@ var resolveLogoUrl = (url, baseUrl) => TokenLogoUrl(
|
|
|
1629
2019
|
);
|
|
1630
2020
|
|
|
1631
2021
|
// src/shared/api/nabu/tokens.ts
|
|
1632
|
-
function createNabuApiClient(baseUrl) {
|
|
1633
|
-
return new HttpClient({ baseUrl });
|
|
2022
|
+
function createNabuApiClient(baseUrl, logger = null) {
|
|
2023
|
+
return new HttpClient({ baseUrl }, {}, logger);
|
|
1634
2024
|
}
|
|
1635
2025
|
async function fetchTokenMetadata(client, token) {
|
|
1636
2026
|
const address = checksummed(token.address);
|
|
@@ -1703,14 +2093,23 @@ var TokensNamespaceImpl = class {
|
|
|
1703
2093
|
* registry is unauthenticated and on its own host, so the frontline sender
|
|
1704
2094
|
* and the auth check would both be dead weight here.
|
|
1705
2095
|
*/
|
|
1706
|
-
constructor(baseUrl) {
|
|
1707
|
-
this.api = createNabuApiClient(baseUrl);
|
|
2096
|
+
constructor(baseUrl, logger = null) {
|
|
2097
|
+
this.api = createNabuApiClient(baseUrl, logger);
|
|
2098
|
+
this.log = internalLogger(logger, "TOKENS");
|
|
1708
2099
|
}
|
|
1709
2100
|
get(token) {
|
|
1710
|
-
return
|
|
2101
|
+
return this.log.wrap(
|
|
2102
|
+
"get",
|
|
2103
|
+
token,
|
|
2104
|
+
() => fetchTokenMetadata(this.api, token)
|
|
2105
|
+
);
|
|
1711
2106
|
}
|
|
1712
2107
|
list(chain) {
|
|
1713
|
-
return
|
|
2108
|
+
return this.log.wrap(
|
|
2109
|
+
"list",
|
|
2110
|
+
chain,
|
|
2111
|
+
() => fetchTokensMetadata(this.api, chain)
|
|
2112
|
+
);
|
|
1714
2113
|
}
|
|
1715
2114
|
};
|
|
1716
2115
|
|
|
@@ -1816,33 +2215,42 @@ async function removeOptionAddress(api, offerId, addressId) {
|
|
|
1816
2215
|
var WalletsNamespaceImpl = class {
|
|
1817
2216
|
constructor(ctx) {
|
|
1818
2217
|
this.ctx = ctx;
|
|
2218
|
+
this.log = internalLogger(ctx.logger, "WALLETS");
|
|
1819
2219
|
}
|
|
1820
2220
|
async createOwnershipChallenge(params) {
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
2221
|
+
return this.log.wrap("createOwnershipChallenge", params, async () => {
|
|
2222
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2223
|
+
return createWalletOwnershipChallenge(
|
|
2224
|
+
this.ctx.api,
|
|
2225
|
+
params
|
|
2226
|
+
);
|
|
2227
|
+
});
|
|
1826
2228
|
}
|
|
1827
2229
|
async connectExternal(params) {
|
|
1828
|
-
|
|
1829
|
-
|
|
2230
|
+
return this.log.wrap("connectExternal", params, async () => {
|
|
2231
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2232
|
+
return connectExternalWallet(this.ctx.api, params);
|
|
2233
|
+
});
|
|
1830
2234
|
}
|
|
1831
2235
|
async list(params) {
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
2236
|
+
return this.log.wrap("list", params, async () => {
|
|
2237
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2238
|
+
return listOptionAddresses(
|
|
2239
|
+
this.ctx.api,
|
|
2240
|
+
params.offerId,
|
|
2241
|
+
params.offerOptionId
|
|
2242
|
+
);
|
|
2243
|
+
});
|
|
1838
2244
|
}
|
|
1839
2245
|
async remove(params) {
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
2246
|
+
return this.log.wrap("remove", params, async () => {
|
|
2247
|
+
await this.ctx.ensureUserAuthenticated();
|
|
2248
|
+
return removeOptionAddress(
|
|
2249
|
+
this.ctx.api,
|
|
2250
|
+
params.offerId,
|
|
2251
|
+
params.addressId
|
|
2252
|
+
);
|
|
2253
|
+
});
|
|
1846
2254
|
}
|
|
1847
2255
|
};
|
|
1848
2256
|
|
|
@@ -1851,6 +2259,7 @@ var ACCESS_TOKEN_EXPIRY_BUFFER_SECONDS = 60;
|
|
|
1851
2259
|
var CoinListServerImpl = class {
|
|
1852
2260
|
constructor(_config) {
|
|
1853
2261
|
this._config = _config;
|
|
2262
|
+
const logger = _config.logger ?? null;
|
|
1854
2263
|
this.api = new ApiClient(
|
|
1855
2264
|
{
|
|
1856
2265
|
baseUrl: _config.baseUrl ?? PUBLIC_API_BASE_URL,
|
|
@@ -1860,7 +2269,8 @@ var CoinListServerImpl = class {
|
|
|
1860
2269
|
// fresh token. A read-only store cannot persist a new session, so return
|
|
1861
2270
|
// null immediately — this tells the middleware to skip the retry rather
|
|
1862
2271
|
// than re-sending with the same expired token and wasting a round-trip.
|
|
1863
|
-
(refresh) => refresh && !this._config.sessionStore.setSession ? Promise.resolve(null) : this.auth.getAccessToken()
|
|
2272
|
+
(refresh) => refresh && !this._config.sessionStore.setSession ? Promise.resolve(null) : this.auth.getAccessToken(),
|
|
2273
|
+
logger
|
|
1864
2274
|
);
|
|
1865
2275
|
this.auth = new ServerAuthNamespaceImpl(this.api, {
|
|
1866
2276
|
..._config,
|
|
@@ -1869,6 +2279,7 @@ var CoinListServerImpl = class {
|
|
|
1869
2279
|
});
|
|
1870
2280
|
const ctx = {
|
|
1871
2281
|
api: this.api,
|
|
2282
|
+
logger,
|
|
1872
2283
|
ensureUserAuthenticated: () => this.ensureAuthenticated(void 0),
|
|
1873
2284
|
ensureAuthenticated: (clientCreds) => this.ensureAuthenticated(clientCreds)
|
|
1874
2285
|
};
|
|
@@ -1880,7 +2291,8 @@ var CoinListServerImpl = class {
|
|
|
1880
2291
|
this.superstate = new SuperstateSwapNamespaceImpl(ctx);
|
|
1881
2292
|
this.ondo = new OndoNamespaceImpl(ctx);
|
|
1882
2293
|
this.tokens = new TokensNamespaceImpl(
|
|
1883
|
-
_config.tokensBaseUrl ?? NABU_BASE_URL
|
|
2294
|
+
_config.tokensBaseUrl ?? NABU_BASE_URL,
|
|
2295
|
+
logger
|
|
1884
2296
|
);
|
|
1885
2297
|
}
|
|
1886
2298
|
/**
|
|
@@ -1898,12 +2310,157 @@ var CoinListServerImpl = class {
|
|
|
1898
2310
|
function createCoinListServer(config) {
|
|
1899
2311
|
return new CoinListServerImpl(config);
|
|
1900
2312
|
}
|
|
2313
|
+
|
|
2314
|
+
// src/server/core/observability/pino-server-logger.ts
|
|
2315
|
+
var import_pino = require("pino");
|
|
2316
|
+
|
|
2317
|
+
// src/shared/core/observability/pino-logger.ts
|
|
2318
|
+
function toPinoRecord(event) {
|
|
2319
|
+
try {
|
|
2320
|
+
const record = {};
|
|
2321
|
+
for (const key of ownKeys(event.fields)) {
|
|
2322
|
+
record[key] = readProperty(event.fields, key, 0, /* @__PURE__ */ new WeakSet());
|
|
2323
|
+
}
|
|
2324
|
+
const cause = "cause" in event ? event.cause : void 0;
|
|
2325
|
+
if (cause !== void 0) {
|
|
2326
|
+
record.cause = sanitize(cause, 0, /* @__PURE__ */ new WeakSet());
|
|
2327
|
+
}
|
|
2328
|
+
return { ...record, scope: event.scope, ...event.bindings };
|
|
2329
|
+
} catch (_) {
|
|
2330
|
+
return { "log.render": "<unrenderable event>" };
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
var PINO_LEVEL = {
|
|
2334
|
+
none: "silent",
|
|
2335
|
+
error: "error",
|
|
2336
|
+
warn: "warn",
|
|
2337
|
+
info: "info",
|
|
2338
|
+
debug: "debug"
|
|
2339
|
+
};
|
|
2340
|
+
var MAX_DEPTH = 8;
|
|
2341
|
+
function sanitize(value, depth, seen) {
|
|
2342
|
+
switch (typeof value) {
|
|
2343
|
+
case "string":
|
|
2344
|
+
case "boolean":
|
|
2345
|
+
return value;
|
|
2346
|
+
case "number":
|
|
2347
|
+
return Number.isFinite(value) ? value : String(value);
|
|
2348
|
+
case "bigint":
|
|
2349
|
+
return value.toString();
|
|
2350
|
+
case "undefined":
|
|
2351
|
+
return "<undefined>";
|
|
2352
|
+
case "function":
|
|
2353
|
+
return "<function>";
|
|
2354
|
+
case "symbol":
|
|
2355
|
+
return value.toString();
|
|
2356
|
+
case "object":
|
|
2357
|
+
return value === null ? null : sanitizeObject(value, depth, seen);
|
|
2358
|
+
default:
|
|
2359
|
+
return "<unrenderable>";
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
function sanitizeObject(value, depth, seen) {
|
|
2363
|
+
if (seen.has(value)) return "<circular>";
|
|
2364
|
+
if (depth >= MAX_DEPTH) return "<max depth>";
|
|
2365
|
+
if (value instanceof Error) return describeError(value);
|
|
2366
|
+
if (value instanceof Date) return describeDate(value);
|
|
2367
|
+
seen.add(value);
|
|
2368
|
+
try {
|
|
2369
|
+
if (Array.isArray(value)) {
|
|
2370
|
+
return value.map(
|
|
2371
|
+
(_item, index) => readProperty(value, String(index), depth, seen)
|
|
2372
|
+
);
|
|
2373
|
+
}
|
|
2374
|
+
const out = {};
|
|
2375
|
+
for (const key of ownKeys(value)) {
|
|
2376
|
+
out[key] = readProperty(value, key, depth, seen);
|
|
2377
|
+
}
|
|
2378
|
+
return out;
|
|
2379
|
+
} finally {
|
|
2380
|
+
seen.delete(value);
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
function readProperty(owner, key, depth, seen) {
|
|
2384
|
+
try {
|
|
2385
|
+
return sanitize(owner[key], depth + 1, seen);
|
|
2386
|
+
} catch (_) {
|
|
2387
|
+
return "<unreadable>";
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
function ownKeys(value) {
|
|
2391
|
+
try {
|
|
2392
|
+
return Object.keys(value);
|
|
2393
|
+
} catch (_) {
|
|
2394
|
+
return [];
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
function describeError(error) {
|
|
2398
|
+
return {
|
|
2399
|
+
name: safeRead(() => error.name),
|
|
2400
|
+
message: safeRead(() => error.message),
|
|
2401
|
+
stack: safeRead(() => error.stack)
|
|
2402
|
+
};
|
|
2403
|
+
}
|
|
2404
|
+
function describeDate(date) {
|
|
2405
|
+
return safeRead(() => date.toISOString());
|
|
2406
|
+
}
|
|
2407
|
+
function safeRead(read) {
|
|
2408
|
+
try {
|
|
2409
|
+
const value = read();
|
|
2410
|
+
return typeof value === "string" ? value : "<unreadable>";
|
|
2411
|
+
} catch (_) {
|
|
2412
|
+
return "<unreadable>";
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
var SDK_LOGGER_NAME = "@coinlist-co/react";
|
|
2416
|
+
function loggerOverPino(sink, level) {
|
|
2417
|
+
return {
|
|
2418
|
+
level: () => level,
|
|
2419
|
+
debug: (event) => emit(sink, "debug", event),
|
|
2420
|
+
info: (event) => emit(sink, "info", event),
|
|
2421
|
+
warn: (event) => emit(sink, "warn", event),
|
|
2422
|
+
error: (event) => emit(sink, "error", event)
|
|
2423
|
+
};
|
|
2424
|
+
}
|
|
2425
|
+
function emit(sink, method, event) {
|
|
2426
|
+
try {
|
|
2427
|
+
const value = event();
|
|
2428
|
+
sink[method](toPinoRecord(value), value.msg);
|
|
2429
|
+
} catch (error) {
|
|
2430
|
+
reportRenderFailure(sink, error);
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
function reportRenderFailure(sink, error) {
|
|
2434
|
+
try {
|
|
2435
|
+
sink.error(
|
|
2436
|
+
{ "error.type": error instanceof Error ? error.name : typeof error },
|
|
2437
|
+
"log event failed to render"
|
|
2438
|
+
);
|
|
2439
|
+
} catch (_) {
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
// src/server/core/observability/pino-server-logger.ts
|
|
2444
|
+
function pinoServerLogger(options) {
|
|
2445
|
+
return loggerOverPino(
|
|
2446
|
+
// `name` as a child binding rather than pino's `name` option: the option
|
|
2447
|
+
// is honoured by pino's node build and silently dropped by its browser
|
|
2448
|
+
// build, so a binding is the only spelling that identifies the SDK in
|
|
2449
|
+
// both environments.
|
|
2450
|
+
(0, import_pino.pino)({
|
|
2451
|
+
level: PINO_LEVEL[options.level]
|
|
2452
|
+
}).child({ name: SDK_LOGGER_NAME }),
|
|
2453
|
+
options.level
|
|
2454
|
+
);
|
|
2455
|
+
}
|
|
1901
2456
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1902
2457
|
0 && (module.exports = {
|
|
1903
2458
|
ServerAuthNamespaceImpl,
|
|
1904
2459
|
ServerOffersNamespaceImpl,
|
|
1905
2460
|
ServerRequirementsNamespaceImpl,
|
|
1906
2461
|
WritableSessionStoreRequiredError,
|
|
1907
|
-
createCoinListServer
|
|
2462
|
+
createCoinListServer,
|
|
2463
|
+
emptySessionStore,
|
|
2464
|
+
pinoServerLogger
|
|
1908
2465
|
});
|
|
1909
2466
|
//# sourceMappingURL=index.cjs.map
|