@sereel/sdk 0.1.5 → 0.2.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.
package/dist/index.js CHANGED
@@ -13,12 +13,18 @@ var SereelSdkError = class extends Error {
13
13
  };
14
14
  var InvalidConfigurationError = class extends SereelSdkError {
15
15
  };
16
+ var NetworkError = class extends SereelSdkError {
17
+ };
16
18
  var HttpError = class extends SereelSdkError {
17
19
  };
18
20
  var UnauthorizedError = class extends HttpError {
19
21
  };
22
+ var ForbiddenError = class extends HttpError {
23
+ };
20
24
  var NotFoundError = class extends HttpError {
21
25
  };
26
+ var RateLimitError = class extends HttpError {
27
+ };
22
28
  var ServerError = class extends HttpError {
23
29
  };
24
30
  var TimeoutError = class extends SereelSdkError {
@@ -123,14 +129,30 @@ function toHttpError(status, body) {
123
129
  if (status === 401) {
124
130
  return new UnauthorizedError(message, options);
125
131
  }
132
+ if (status === 403) {
133
+ return new ForbiddenError(message, options);
134
+ }
126
135
  if (status === 404) {
127
136
  return new NotFoundError(message, options);
128
137
  }
138
+ if (status === 429) {
139
+ return new RateLimitError(message, options);
140
+ }
129
141
  if (status >= 500) {
130
142
  return new ServerError(message, options);
131
143
  }
132
144
  return new HttpError(message, options);
133
145
  }
146
+ function isAbortError(error) {
147
+ return error instanceof Error && (error.name === "AbortError" || error.constructor.name === "AbortError");
148
+ }
149
+ function wrapNetworkError(error) {
150
+ if (error instanceof NetworkError) {
151
+ return error;
152
+ }
153
+ const message = error instanceof Error ? error.message : typeof error === "string" ? error : "Network request failed.";
154
+ return new NetworkError(message, { cause: error });
155
+ }
134
156
  async function requestJson(config, path, validate) {
135
157
  const { signal, cleanup } = createTimeoutSignal(config.timeoutMs);
136
158
  try {
@@ -148,16 +170,16 @@ async function requestJson(config, path, validate) {
148
170
  }
149
171
  return validate(body);
150
172
  } catch (error) {
151
- if (error instanceof HttpError || error instanceof MalformedResponseError) {
173
+ if (error instanceof HttpError || error instanceof MalformedResponseError || error instanceof NetworkError) {
152
174
  throw error;
153
175
  }
154
- if (error instanceof Error && error.name === "AbortError") {
176
+ if (isAbortError(error)) {
155
177
  throw new TimeoutError(
156
178
  `Request timed out after ${config.timeoutMs}ms.`,
157
179
  { cause: error }
158
180
  );
159
181
  }
160
- throw error;
182
+ throw wrapNetworkError(error);
161
183
  } finally {
162
184
  cleanup();
163
185
  }
@@ -179,47 +201,237 @@ function isFiniteNumber(value) {
179
201
  function isBoolean(value) {
180
202
  return typeof value === "boolean";
181
203
  }
182
- function isProspectus(value) {
183
- return isRecord(value) && isString(value.name) && isString(value.url);
204
+ var ValidationContext = class {
205
+ failures = [];
206
+ check(condition, path, expected, received) {
207
+ if (!condition) {
208
+ this.failures.push({ path, expected, received });
209
+ }
210
+ return condition;
211
+ }
212
+ };
213
+ function asRecord(value) {
214
+ return isRecord(value) ? value : void 0;
184
215
  }
185
- function isTokenPartner(value) {
186
- return isRecord(value) && isString(value.partner_name) && isString(value.partner_logo) && isString(value.partner_role);
216
+ function isProspectus(value, ctx, path) {
217
+ const v = asRecord(value);
218
+ if (!ctx.check(v !== void 0, path, "object", value)) return false;
219
+ ctx.check(isString(v.name), `${path}.name`, "string", v.name);
220
+ ctx.check(isString(v.url), `${path}.url`, "string", v.url);
221
+ return true;
187
222
  }
188
- function isRuleSummary(value) {
189
- return isRecord(value) && isString(value.rule_address) && isString(value.rule_type);
223
+ function isTokenPartner(value, ctx, path) {
224
+ const v = asRecord(value);
225
+ if (!ctx.check(v !== void 0, path, "object", value)) return false;
226
+ ctx.check(
227
+ isString(v.partner_name),
228
+ `${path}.partner_name`,
229
+ "string",
230
+ v.partner_name
231
+ );
232
+ ctx.check(
233
+ isString(v.partner_logo),
234
+ `${path}.partner_logo`,
235
+ "string",
236
+ v.partner_logo
237
+ );
238
+ ctx.check(
239
+ isString(v.partner_role),
240
+ `${path}.partner_role`,
241
+ "string",
242
+ v.partner_role
243
+ );
244
+ return true;
190
245
  }
191
- function isRuleEngineSummary(value) {
192
- return isRecord(value) && isString(value.name) && isString(value.rule_engine_address) && Array.isArray(value.rules) && value.rules.every(isRuleSummary);
246
+ function isRuleSummary(value, ctx, path) {
247
+ const v = asRecord(value);
248
+ if (!ctx.check(v !== void 0, path, "object", value)) return false;
249
+ ctx.check(
250
+ isString(v.rule_address),
251
+ `${path}.rule_address`,
252
+ "string",
253
+ v.rule_address
254
+ );
255
+ ctx.check(
256
+ isString(v.rule_type),
257
+ `${path}.rule_type`,
258
+ "string",
259
+ v.rule_type
260
+ );
261
+ return true;
193
262
  }
194
- function isSecurityDetails(value) {
195
- if (!isRecord(value)) return false;
196
- const hasRequiredStrings = isString(value.token_address) && isString(value.token_name) && isString(value.token_symbol) && isString(value.token_decimal) && isString(value.network_id) && isString(value.token_type) && isString(value.admin);
197
- if (!hasRequiredStrings) return false;
198
- if (!isNullableString(value.icon_url)) return false;
199
- if (!isNullableString(value.created_at)) return false;
200
- if (value.prospectus !== null && value.prospectus !== void 0) {
201
- if (!isProspectus(value.prospectus)) return false;
202
- }
203
- if (value.partners !== null && value.partners !== void 0) {
204
- if (!Array.isArray(value.partners) || !value.partners.every(isTokenPartner))
205
- return false;
206
- }
207
- if (value.rule_engine !== null && value.rule_engine !== void 0) {
208
- if (!isRuleEngineSummary(value.rule_engine)) return false;
263
+ function isRuleEngineSummary(value, ctx, path) {
264
+ const v = asRecord(value);
265
+ if (!ctx.check(v !== void 0, path, "object", value)) return false;
266
+ ctx.check(isString(v.name), `${path}.name`, "string", v.name);
267
+ ctx.check(
268
+ isString(v.rule_engine_address),
269
+ `${path}.rule_engine_address`,
270
+ "string",
271
+ v.rule_engine_address
272
+ );
273
+ const rulesOk = ctx.check(
274
+ Array.isArray(v.rules),
275
+ `${path}.rules`,
276
+ "array",
277
+ v.rules
278
+ );
279
+ if (rulesOk) {
280
+ v.rules.forEach(
281
+ (rule, i) => isRuleSummary(rule, ctx, `${path}.rules[${i}]`)
282
+ );
209
283
  }
210
284
  return true;
211
285
  }
212
- function isIssuerSummary(value) {
213
- return isRecord(value) && isString(value.id) && isString(value.legal_name) && isNullableString(value.display_name) && isString(value.jurisdiction) && isNullableString(value.website) && isNullableString(value.logo_url);
286
+ function isIssuerSummary(value, ctx, path) {
287
+ const v = asRecord(value);
288
+ if (!ctx.check(v !== void 0, path, "object", value)) return false;
289
+ ctx.check(isString(v.id), `${path}.id`, "string", v.id);
290
+ ctx.check(
291
+ isString(v.legal_name),
292
+ `${path}.legal_name`,
293
+ "string",
294
+ v.legal_name
295
+ );
296
+ ctx.check(
297
+ isNullableString(v.display_name),
298
+ `${path}.display_name`,
299
+ "string | null",
300
+ v.display_name
301
+ );
302
+ ctx.check(
303
+ isString(v.jurisdiction),
304
+ `${path}.jurisdiction`,
305
+ "string",
306
+ v.jurisdiction
307
+ );
308
+ ctx.check(
309
+ isNullableString(v.website),
310
+ `${path}.website`,
311
+ "string | null",
312
+ v.website
313
+ );
314
+ ctx.check(
315
+ isNullableString(v.logo_url),
316
+ `${path}.logo_url`,
317
+ "string | null",
318
+ v.logo_url
319
+ );
320
+ return true;
214
321
  }
215
- function isNativeCurrency(value) {
216
- return isRecord(value) && isString(value.symbol) && isString(value.name) && isFiniteNumber(value.decimals);
322
+ function isNativeCurrency(value, ctx, path) {
323
+ const v = asRecord(value);
324
+ if (!ctx.check(v !== void 0, path, "object", value)) return false;
325
+ ctx.check(isString(v.symbol), `${path}.symbol`, "string", v.symbol);
326
+ ctx.check(isString(v.name), `${path}.name`, "string", v.name);
327
+ ctx.check(
328
+ isFiniteNumber(v.decimals),
329
+ `${path}.decimals`,
330
+ "finite number",
331
+ v.decimals
332
+ );
333
+ return true;
217
334
  }
218
- function isNetworkDetails(value) {
219
- return isRecord(value) && isString(value.network_id) && isString(value.name) && isString(value.family) && (isFiniteNumber(value.chain_id) || value.chain_id === null) && isNativeCurrency(value.native_currency) && isString(value.rpc_endpoint) && Array.isArray(value.explorer_urls) && value.explorer_urls.every(isString) && isBoolean(value.can_deploy_cmtat_token) && isBoolean(value.can_deploy_trex_token) && isBoolean(value.is_testnet) && isBoolean(value.is_supported);
335
+ function isNetworkDetails(value, ctx, path) {
336
+ const v = asRecord(value);
337
+ if (!ctx.check(v !== void 0, path, "object", value)) return false;
338
+ ctx.check(
339
+ isString(v.network_id),
340
+ `${path}.network_id`,
341
+ "string",
342
+ v.network_id
343
+ );
344
+ ctx.check(isString(v.name), `${path}.name`, "string", v.name);
345
+ ctx.check(isString(v.family), `${path}.family`, "string", v.family);
346
+ ctx.check(
347
+ isFiniteNumber(v.chain_id) || v.chain_id === null,
348
+ `${path}.chain_id`,
349
+ "number | null",
350
+ v.chain_id
351
+ );
352
+ isNativeCurrency(v.native_currency, ctx, `${path}.native_currency`);
353
+ ctx.check(
354
+ isString(v.rpc_endpoint),
355
+ `${path}.rpc_endpoint`,
356
+ "string",
357
+ v.rpc_endpoint
358
+ );
359
+ const explorerOk = ctx.check(
360
+ Array.isArray(v.explorer_urls),
361
+ `${path}.explorer_urls`,
362
+ "string[]",
363
+ v.explorer_urls
364
+ );
365
+ if (explorerOk) {
366
+ v.explorer_urls.forEach(
367
+ (url, i) => ctx.check(
368
+ isString(url),
369
+ `${path}.explorer_urls[${i}]`,
370
+ "string",
371
+ url
372
+ )
373
+ );
374
+ }
375
+ ctx.check(
376
+ isBoolean(v.is_testnet),
377
+ `${path}.is_testnet`,
378
+ "boolean",
379
+ v.is_testnet
380
+ );
381
+ return true;
220
382
  }
221
- function isFundConfig(value) {
222
- return isRecord(value) && isString(value.nav_staleness_threshold) && isString(value.min_subscription) && isString(value.min_redemption) && isString(value.entry_fee_bps) && isString(value.exit_fee_bps) && isFiniteNumber(value.dealing_mode) && isString(value.redemption_gate_bps) && isString(value.protocol_subscription_fee_bps) && isString(value.protocol_fee_recipient) && isString(value.management_fee_bps_per_annum);
383
+ function isFundConfig(value, ctx, path) {
384
+ const v = asRecord(value);
385
+ if (!ctx.check(v !== void 0, path, "object", value)) return false;
386
+ ctx.check(
387
+ isString(v.nav_staleness_threshold),
388
+ `${path}.nav_staleness_threshold`,
389
+ "string",
390
+ v.nav_staleness_threshold
391
+ );
392
+ ctx.check(
393
+ isString(v.min_subscription),
394
+ `${path}.min_subscription`,
395
+ "string",
396
+ v.min_subscription
397
+ );
398
+ ctx.check(
399
+ isString(v.min_redemption),
400
+ `${path}.min_redemption`,
401
+ "string",
402
+ v.min_redemption
403
+ );
404
+ ctx.check(
405
+ isString(v.entry_fee_bps),
406
+ `${path}.entry_fee_bps`,
407
+ "string",
408
+ v.entry_fee_bps
409
+ );
410
+ ctx.check(
411
+ isString(v.exit_fee_bps),
412
+ `${path}.exit_fee_bps`,
413
+ "string",
414
+ v.exit_fee_bps
415
+ );
416
+ ctx.check(
417
+ isFiniteNumber(v.dealing_mode),
418
+ `${path}.dealing_mode`,
419
+ "finite number",
420
+ v.dealing_mode
421
+ );
422
+ ctx.check(
423
+ isString(v.redemption_gate_bps),
424
+ `${path}.redemption_gate_bps`,
425
+ "string",
426
+ v.redemption_gate_bps
427
+ );
428
+ ctx.check(
429
+ isString(v.management_fee_bps_per_annum),
430
+ `${path}.management_fee_bps_per_annum`,
431
+ "string",
432
+ v.management_fee_bps_per_annum
433
+ );
434
+ return true;
223
435
  }
224
436
  var ISSUANCE_STATUSES = /* @__PURE__ */ new Set([
225
437
  "OPEN",
@@ -228,30 +440,248 @@ var ISSUANCE_STATUSES = /* @__PURE__ */ new Set([
228
440
  "SETTLED",
229
441
  "CANCELLED"
230
442
  ]);
231
- function isIssuanceStatus(value) {
232
- return isString(value) && ISSUANCE_STATUSES.has(value);
443
+ function isIssuanceStatus(value, ctx, path) {
444
+ return ctx.check(
445
+ isString(value) && ISSUANCE_STATUSES.has(value),
446
+ path,
447
+ `one of ${[...ISSUANCE_STATUSES].join(", ")}`,
448
+ value
449
+ );
233
450
  }
234
- function isBookSummary(value) {
235
- return isRecord(value) && (isString(value.id) || value.id === null) && isString(value.organization_id) && isNullableString(value.name) && isNullableString(value.book_type) && isString(value.token_address) && isString(value.fund_token) && isString(value.network_id) && isString(value.settlement_token) && isNullableString(value.factory_address) && isNullableString(value.deployment_txn_hash) && isString(value.order_book_address) && isString(value.fund_address) && isString(value.fund_id) && isString(value.initial_nav) && isFundConfig(value.fund_config) && isIssuanceStatus(value.status) && isNullableString(value.created_at) && isNullableString(value.updated_at);
451
+ function isBookSummary(value, ctx, path) {
452
+ const v = asRecord(value);
453
+ if (!ctx.check(v !== void 0, path, "object", value)) return false;
454
+ ctx.check(
455
+ isString(v.id) || v.id === null,
456
+ `${path}.id`,
457
+ "string | null",
458
+ v.id
459
+ );
460
+ ctx.check(
461
+ isString(v.organization_id),
462
+ `${path}.organization_id`,
463
+ "string",
464
+ v.organization_id
465
+ );
466
+ ctx.check(
467
+ isNullableString(v.name),
468
+ `${path}.name`,
469
+ "string | null",
470
+ v.name
471
+ );
472
+ ctx.check(
473
+ isNullableString(v.book_type),
474
+ `${path}.book_type`,
475
+ "string | null",
476
+ v.book_type
477
+ );
478
+ ctx.check(
479
+ isString(v.token_address),
480
+ `${path}.token_address`,
481
+ "string",
482
+ v.token_address
483
+ );
484
+ ctx.check(
485
+ isString(v.network_id),
486
+ `${path}.network_id`,
487
+ "string",
488
+ v.network_id
489
+ );
490
+ ctx.check(
491
+ isString(v.settlement_token),
492
+ `${path}.settlement_token`,
493
+ "string",
494
+ v.settlement_token
495
+ );
496
+ ctx.check(
497
+ isString(v.order_book_address),
498
+ `${path}.order_book_address`,
499
+ "string",
500
+ v.order_book_address
501
+ );
502
+ ctx.check(
503
+ isString(v.fund_address),
504
+ `${path}.fund_address`,
505
+ "string",
506
+ v.fund_address
507
+ );
508
+ ctx.check(
509
+ isString(v.fund_id),
510
+ `${path}.fund_id`,
511
+ "string",
512
+ v.fund_id
513
+ );
514
+ ctx.check(
515
+ isString(v.initial_nav),
516
+ `${path}.initial_nav`,
517
+ "string",
518
+ v.initial_nav
519
+ );
520
+ isFundConfig(v.fund_config, ctx, `${path}.fund_config`);
521
+ isIssuanceStatus(v.status, ctx, `${path}.status`);
522
+ ctx.check(
523
+ isNullableString(v.created_at),
524
+ `${path}.created_at`,
525
+ "string | null",
526
+ v.created_at
527
+ );
528
+ return true;
236
529
  }
237
- function isAssetRecord(value) {
238
- return isRecord(value) && isSecurityDetails(value.security) && isIssuerSummary(value.issuer) && Array.isArray(value.books) && value.books.every(isBookSummary) && isNetworkDetails(value.network);
530
+ function isSecurityDetails(value, ctx, path) {
531
+ const v = asRecord(value);
532
+ if (!ctx.check(v !== void 0, path, "object", value)) return false;
533
+ ctx.check(
534
+ isString(v.token_address),
535
+ `${path}.token_address`,
536
+ "string",
537
+ v.token_address
538
+ );
539
+ ctx.check(
540
+ isString(v.token_name),
541
+ `${path}.token_name`,
542
+ "string",
543
+ v.token_name
544
+ );
545
+ ctx.check(
546
+ isString(v.token_symbol),
547
+ `${path}.token_symbol`,
548
+ "string",
549
+ v.token_symbol
550
+ );
551
+ ctx.check(
552
+ isString(v.token_decimal),
553
+ `${path}.token_decimal`,
554
+ "string",
555
+ v.token_decimal
556
+ );
557
+ ctx.check(
558
+ isString(v.network_id),
559
+ `${path}.network_id`,
560
+ "string",
561
+ v.network_id
562
+ );
563
+ ctx.check(
564
+ isString(v.token_type),
565
+ `${path}.token_type`,
566
+ "string",
567
+ v.token_type
568
+ );
569
+ ctx.check(isString(v.admin), `${path}.admin`, "string", v.admin);
570
+ ctx.check(
571
+ isNullableString(v.icon_url),
572
+ `${path}.icon_url`,
573
+ "string | null",
574
+ v.icon_url
575
+ );
576
+ ctx.check(
577
+ isNullableString(v.created_at),
578
+ `${path}.created_at`,
579
+ "string | null",
580
+ v.created_at
581
+ );
582
+ if (v.prospectus !== null && v.prospectus !== void 0) {
583
+ isProspectus(v.prospectus, ctx, `${path}.prospectus`);
584
+ }
585
+ if (v.issuer !== null && v.issuer !== void 0) {
586
+ isIssuerSummary(v.issuer, ctx, `${path}.issuer`);
587
+ }
588
+ if (v.book !== null && v.book !== void 0) {
589
+ isBookSummary(v.book, ctx, `${path}.book`);
590
+ }
591
+ if (v.partners !== null && v.partners !== void 0) {
592
+ const partnersOk = ctx.check(
593
+ Array.isArray(v.partners),
594
+ `${path}.partners`,
595
+ "array",
596
+ v.partners
597
+ );
598
+ if (partnersOk) {
599
+ v.partners.forEach(
600
+ (partner, i) => isTokenPartner(partner, ctx, `${path}.partners[${i}]`)
601
+ );
602
+ }
603
+ }
604
+ if (v.rule_engine !== null && v.rule_engine !== void 0) {
605
+ isRuleEngineSummary(v.rule_engine, ctx, `${path}.rule_engine`);
606
+ }
607
+ isNetworkDetails(v.network, ctx, `${path}.network`);
608
+ if (v.trex_claim_topics !== null && v.trex_claim_topics !== void 0) {
609
+ const topicsOk = ctx.check(
610
+ Array.isArray(v.trex_claim_topics),
611
+ `${path}.trex_claim_topics`,
612
+ "number[]",
613
+ v.trex_claim_topics
614
+ );
615
+ if (topicsOk) {
616
+ v.trex_claim_topics.forEach(
617
+ (topic, i) => ctx.check(
618
+ isFiniteNumber(topic),
619
+ `${path}.trex_claim_topics[${i}]`,
620
+ "finite number",
621
+ topic
622
+ )
623
+ );
624
+ }
625
+ }
626
+ if (v.trex_issuers !== null && v.trex_issuers !== void 0) {
627
+ const issuersOk = ctx.check(
628
+ Array.isArray(v.trex_issuers),
629
+ `${path}.trex_issuers`,
630
+ "string[]",
631
+ v.trex_issuers
632
+ );
633
+ if (issuersOk) {
634
+ v.trex_issuers.forEach(
635
+ (issuer, i) => ctx.check(
636
+ isString(issuer),
637
+ `${path}.trex_issuers[${i}]`,
638
+ "string",
639
+ issuer
640
+ )
641
+ );
642
+ }
643
+ }
644
+ return true;
645
+ }
646
+ function buildValidationError(value, failures) {
647
+ const summary = failures.slice(0, 5).map(
648
+ (f) => `${f.path}: expected ${f.expected}, got ${JSON.stringify(f.received)}`
649
+ ).join("; ");
650
+ const message = failures.length > 5 ? `Received an invalid SDK response shape (${failures.length} issues). First 5: ${summary}` : `Received an invalid SDK response shape. ${summary}`;
651
+ return new MalformedResponseError(message, {
652
+ details: { failures: failures.slice(0, 20), value }
653
+ });
239
654
  }
240
655
  function validateSdkAssetsResponse(value) {
241
- if (!isRecord(value) || !Array.isArray(value.data) || !isFiniteNumber(value.count) || !value.data.every(isAssetRecord)) {
242
- throw new MalformedResponseError(
243
- "Received an invalid SDK assets response shape.",
244
- { details: value }
656
+ const ctx = new ValidationContext();
657
+ ctx.check(isRecord(value), "<root>", "object", value);
658
+ if (isRecord(value)) {
659
+ ctx.check(Array.isArray(value.data), "<root>.data", "array", value.data);
660
+ ctx.check(
661
+ isFiniteNumber(value.count),
662
+ "<root>.count",
663
+ "finite number",
664
+ value.count
245
665
  );
666
+ if (Array.isArray(value.data)) {
667
+ value.data.forEach(
668
+ (item, i) => isSecurityDetails(item, ctx, `<root>.data[${i}]`)
669
+ );
670
+ }
671
+ }
672
+ if (ctx.failures.length > 0) {
673
+ throw buildValidationError(value, ctx.failures);
246
674
  }
247
675
  return value;
248
676
  }
249
677
  function validateSdkAssetResponse(value) {
250
- if (!isRecord(value) || !isAssetRecord(value.data)) {
251
- throw new MalformedResponseError(
252
- "Received an invalid SDK asset response shape.",
253
- { details: value }
254
- );
678
+ const ctx = new ValidationContext();
679
+ ctx.check(isRecord(value), "<root>", "object", value);
680
+ if (isRecord(value)) {
681
+ isSecurityDetails(value.data, ctx, "<root>.data");
682
+ }
683
+ if (ctx.failures.length > 0) {
684
+ throw buildValidationError(value, ctx.failures);
255
685
  }
256
686
  return value;
257
687
  }
@@ -291,10 +721,13 @@ function createClient(config) {
291
721
  }
292
722
  export {
293
723
  ENVIRONMENT_BASE_URLS,
724
+ ForbiddenError,
294
725
  HttpError,
295
726
  InvalidConfigurationError,
296
727
  MalformedResponseError,
728
+ NetworkError,
297
729
  NotFoundError,
730
+ RateLimitError,
298
731
  SereelSdkError,
299
732
  ServerError,
300
733
  TimeoutError,