@sereel/sdk 0.1.2 → 0.1.4

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/README.md CHANGED
@@ -1,11 +1,15 @@
1
1
  # Sereel TypeScript SDK
2
2
 
3
- TypeScript SDK for the Sereel SDK-facing REST asset endpoints.
3
+ TypeScript SDK for the Sereel marketplace REST endpoints. Use it to browse
4
+ security tokens listed on the Sereel marketplace, inspect their compliance
5
+ rule engines, and filter by issuer.
4
6
 
5
7
  ## Install
6
8
 
7
9
  ```bash
8
10
  npm install @sereel/sdk
11
+ # or
12
+ pnpm add @sereel/sdk
9
13
  ```
10
14
 
11
15
  ## Quickstart
@@ -18,104 +22,285 @@ const client = createClient({
18
22
  apiKey: process.env.SEREEL_SDK_API_KEY!,
19
23
  });
20
24
 
25
+ // All listed assets
21
26
  const assets = await client.getAssets();
22
- const asset = await client.getAssetByTokenAddress("0x123");
27
+
28
+ // Single asset by token address
29
+ const asset = await client.getAssetByTokenAddress("0xabc…");
30
+
31
+ // All assets issued by a specific issuer
32
+ const issuerAssets = await client.getAssetsByIssuer("64f1a2b3c4d5e6f7a8b9c0d1");
23
33
  ```
24
34
 
25
35
  ## Authentication
26
36
 
27
- The SDK sends your API key in the `x-api-key` header.
28
-
29
- Only MATATA-issued API keys are supported right now.
37
+ The SDK sends your API key in the `x-api-key` header.
38
+ Only MATATA-issued API keys are supported.
30
39
 
31
40
  ```ts
32
- import { createClient } from "@sereel/sdk";
33
-
34
41
  const client = createClient({
35
42
  environment: "testnet",
36
43
  apiKey: process.env.SEREEL_SDK_API_KEY!,
37
44
  });
38
-
39
- const assets = await client.getAssets();
40
45
  ```
41
46
 
42
47
  ## Environments
43
48
 
44
- The SDK resolves the API base URL from the configured environment so callers do not need to pass a raw URL in normal usage.
45
-
46
- - `devnet` => `https://api-lazer.sereel.com`
47
- - `testnet` => `https://api-lazer-v2.sereel.com`
48
- - `mainnet` => `https://cahokia.sereel.com`
49
+ | Key | Base URL |
50
+ |-----|----------|
51
+ | `devnet` | `https://api-lazer.sereel.com` |
52
+ | `testnet` | `https://api-lazer-v2.sereel.com` |
53
+ | `mainnet` | `https://cahokia.sereel.com` |
49
54
 
50
55
  ## Client API
51
56
 
52
- ### `createClient`
57
+ ### `createClient(config)`
53
58
 
54
59
  ```ts
55
60
  import { createClient } from "@sereel/sdk";
56
61
 
57
62
  const client = createClient({
58
- environment: "testnet",
59
- apiKey: process.env.SEREEL_SDK_API_KEY!,
60
- timeoutMs: 10_000,
63
+ environment: "testnet", // required
64
+ apiKey: "sk_matata_…", // required
65
+ timeoutMs: 10_000, // optional, default: 30 000
66
+ baseUrl: "http://localhost:8080", // optional – overrides environment URL
61
67
  });
62
68
  ```
63
69
 
64
- Advanced option:
70
+ ---
71
+
72
+ ### `client.getAssets()`
65
73
 
66
- `baseUrl` can be provided as an explicit override for local integration testing or temporary pre-release environments, but `environment` remains the primary and recommended path.
74
+ `GET /sdk/assets` returns all publicly listed security tokens.
67
75
 
68
76
  ```ts
69
- const client = createClient({
70
- environment: "devnet",
71
- apiKey: process.env.SEREEL_SDK_API_KEY!,
72
- baseUrl: "http://localhost:8080",
73
- });
77
+ const { data, count } = await client.getAssets();
78
+
79
+ for (const record of data) {
80
+ console.log(record.security.token_name, record.issuer.legal_name);
81
+ }
74
82
  ```
75
83
 
76
- ### `client.getAssets()`
84
+ ---
85
+
86
+ ### `client.getAssetByTokenAddress(tokenAddress)`
77
87
 
78
- Fetches `GET /sdk/assets`.
88
+ `GET /sdk/assets/{token_address}` — returns a single asset by its on-chain
89
+ token address.
79
90
 
80
91
  ```ts
81
- const assets = await client.getAssets();
92
+ const { data } = await client.getAssetByTokenAddress("0xabc…");
82
93
 
83
- console.log(assets.count);
84
- console.log(assets.data[0]?.security.token_symbol);
94
+ console.log(data.security.token_name);
95
+ console.log(data.security.rule_engine?.name); // present if token has compliance rules
96
+ console.log(data.books.length);
85
97
  ```
86
98
 
87
- ### `client.getAssetByTokenAddress(tokenAddress)`
99
+ ---
100
+
101
+ ### `client.getAssetsByIssuer(issuerId)`
88
102
 
89
- Fetches `GET /sdk/assets/{token_address}`.
103
+ `GET /sdk/assets/issuer/{issuer_id}` — returns all assets belonging to a
104
+ specific issuer. The `issuerId` is the `id` field from `SdkIssuerSummary`
105
+ (the issuer's hex-encoded MongoDB ObjectId).
90
106
 
91
107
  ```ts
92
- const asset = await client.getAssetByTokenAddress("0x123");
108
+ const { data, count } = await client.getAssetsByIssuer("64f1a2b3c4d5e6f7a8b9c0d1");
93
109
 
94
- console.log(asset.data.security.token_name);
95
- console.log(asset.data.books.length);
110
+ console.log(`${count} tokens from this issuer`);
111
+ data.forEach(record => console.log(record.security.token_symbol));
96
112
  ```
97
113
 
114
+ ---
115
+
98
116
  ## Response shape
99
117
 
100
- The SDK models the backend SDK DTOs and returns joined asset records with:
118
+ Every API method returns one or more `SdkAssetRecord` objects.
119
+
120
+ ```ts
121
+ interface SdkAssetRecord {
122
+ security: SdkSecurityDetails;
123
+ issuer: SdkIssuerSummary;
124
+ books: SdkBookSummary[];
125
+ network: NetworkDetails;
126
+ }
127
+ ```
128
+
129
+ ### `SdkSecurityDetails`
130
+
131
+ Full token details. Internal and sensitive fields are intentionally excluded
132
+ (`id`, `org_id`, `deployment_txn_hash`, `token_program_id`, `engines` (raw),
133
+ `extra_information_attributes`, `allowlist_manager`, `iota_*` fields,
134
+ `individual_token_price`, `rule_engine_id`, `updated_at`).
135
+
136
+ ```ts
137
+ interface SdkSecurityDetails {
138
+ token_address: string;
139
+ token_name: string;
140
+ token_symbol: string;
141
+ token_decimal: string;
142
+ network_id: string;
143
+ token_type: string; // e.g. "cmtat_standard" | "cmtat_debt" | …
144
+ admin: string; // token admin wallet address
145
+ icon_url: string | null;
146
+ prospectus: SdkTokenProspectus | null;
147
+ partners: SdkTokenPartner[] | null;
148
+ rule_engine: SdkRuleEngineSummary | null; // present when token has compliance rules
149
+ created_at: string | null;
150
+ }
151
+ ```
152
+
153
+ ### `SdkRuleEngineSummary`
101
154
 
102
- - `security`
103
- - `seller_organization`
104
- - `books`
155
+ When a token has an associated compliance rule engine, it is joined into the
156
+ security details. Only the name, address, and a slim view of each linked rule
157
+ are exposed.
105
158
 
106
- Token price fields are intentionally not included in the SDK types.
159
+ ```ts
160
+ interface SdkRuleEngineSummary {
161
+ name: string;
162
+ rule_engine_address: string;
163
+ rules: SdkRuleSummary[];
164
+ }
165
+
166
+ interface SdkRuleSummary {
167
+ rule_address: string;
168
+ rule_type: string; // e.g. "whitelist" | "blacklist" | "sanctions_list" | …
169
+ }
170
+ ```
171
+
172
+ Rule types:
173
+
174
+ | Value | Description |
175
+ |-------|-------------|
176
+ | `whitelist` | Only allow-listed addresses can hold the token |
177
+ | `blacklist` | Blocked addresses cannot hold the token |
178
+ | `sanctions_list` | Integrates with an external sanctions oracle |
179
+ | `conditional_transfer_light` | Light conditional transfer checks |
180
+ | `erc2980` | ERC-2980 royalty enforcement |
181
+ | `identity_registry` | On-chain identity linking |
182
+ | `max_total_supply` | Total supply cap |
183
+ | `spender_whitelist` | Approved spenders only |
184
+ | `whitelist_wrapper` | Enhanced whitelist variant |
185
+
186
+ ### `SdkIssuerSummary`
187
+
188
+ Public-facing details about the organisation that issued the token.
189
+
190
+ ```ts
191
+ interface SdkIssuerSummary {
192
+ id: string;
193
+ legal_name: string;
194
+ display_name: string | null;
195
+ jurisdiction: string;
196
+ website: string | null;
197
+ logo_url: string | null;
198
+ }
199
+ ```
200
+
201
+ ### `SdkBookSummary`
202
+
203
+ Fund details attached to the token.
204
+
205
+ ```ts
206
+ interface SdkFundConfig {
207
+ nav_staleness_threshold: string;
208
+ min_subscription: string;
209
+ min_redemption: string;
210
+ entry_fee_bps: string;
211
+ exit_fee_bps: string;
212
+ dealing_mode: number;
213
+ redemption_gate_bps: string;
214
+ protocol_subscription_fee_bps: string;
215
+ protocol_fee_recipient: string;
216
+ management_fee_bps_per_annum: string;
217
+ }
218
+
219
+ interface SdkBookSummary {
220
+ id: string;
221
+ order_book_address: string;
222
+ fund_address: string;
223
+ fund_id: string;
224
+ fund_token: string;
225
+ settlement_token: string;
226
+ owner_wallet: string;
227
+ manager_wallet: string;
228
+ initial_nav: string;
229
+ fund_config: SdkFundConfig;
230
+ status: string;
231
+ book_type: string | null;
232
+ network_id: string;
233
+ }
234
+ ```
235
+
236
+ ### `NetworkDetails`
237
+
238
+ On-chain network the token is deployed on.
239
+
240
+ ```ts
241
+ interface NetworkDetails {
242
+ network_id: string;
243
+ name: string;
244
+ family: string; // e.g. "ethereum" | "solana" | "iota"
245
+ chain_id: number | null;
246
+ native_currency: NativeCurrency;
247
+ rpc_endpoint: string;
248
+ explorer_urls: string[];
249
+ can_deploy_token: boolean;
250
+ is_testnet: boolean;
251
+ is_supported: boolean;
252
+ }
253
+ ```
254
+
255
+ ---
107
256
 
108
257
  ## Errors
109
258
 
110
- The SDK throws typed errors for common failure cases:
259
+ All errors extend `SereelSdkError`.
260
+
261
+ | Class | When thrown |
262
+ |-------|-------------|
263
+ | `InvalidConfigurationError` | Bad `createClient` options or empty method arguments |
264
+ | `UnauthorizedError` | API key missing or invalid (HTTP 401) |
265
+ | `NotFoundError` | Token address or issuer ID not found (HTTP 404) |
266
+ | `ServerError` | Unexpected server error (HTTP 5xx) |
267
+ | `TimeoutError` | Request exceeded `timeoutMs` |
268
+ | `MalformedResponseError` | Response body doesn't match the expected shape |
269
+
270
+ ```ts
271
+ import {
272
+ NotFoundError,
273
+ UnauthorizedError,
274
+ createClient,
275
+ } from "@sereel/sdk";
276
+
277
+ try {
278
+ const asset = await client.getAssetByTokenAddress("0xmissing");
279
+ } catch (err) {
280
+ if (err instanceof NotFoundError) {
281
+ console.log("Token not found");
282
+ } else if (err instanceof UnauthorizedError) {
283
+ console.log("Check your API key");
284
+ } else {
285
+ throw err;
286
+ }
287
+ }
288
+ ```
111
289
 
112
- - `InvalidConfigurationError`
113
- - `UnauthorizedError`
114
- - `NotFoundError`
115
- - `ServerError`
116
- - `TimeoutError`
117
- - `MalformedResponseError`
290
+ ---
118
291
 
119
292
  ## Runtime support
120
293
 
121
- The SDK is framework-agnostic and uses the platform `fetch` API. In runtimes without a global `fetch`, pass a compatible implementation through `createClient({ fetch })`.
294
+ The SDK is framework-agnostic and relies on the platform `fetch` API
295
+ (Node ≥ 18, Deno, Bun, browsers). In older runtimes, pass a compatible
296
+ implementation:
297
+
298
+ ```ts
299
+ import fetch from "node-fetch";
300
+
301
+ const client = createClient({
302
+ environment: "testnet",
303
+ apiKey: process.env.SEREEL_SDK_API_KEY!,
304
+ fetch: fetch as unknown as typeof globalThis.fetch,
305
+ });
306
+ ```
package/dist/index.cjs CHANGED
@@ -252,10 +252,13 @@ function isNativeCurrency(value) {
252
252
  return isRecord(value) && isString(value.symbol) && isString(value.name) && isFiniteNumber(value.decimals);
253
253
  }
254
254
  function isNetworkDetails(value) {
255
- 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_token) && isBoolean(value.is_testnet) && isBoolean(value.is_supported);
255
+ 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);
256
+ }
257
+ function isFundConfig(value) {
258
+ 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);
256
259
  }
257
260
  function isBookSummary(value) {
258
- return isRecord(value) && isString(value.id) && isString(value.order_book_address) && isString(value.status) && isString(value.network_id) && isFiniteNumber(value.subscription_start) && isFiniteNumber(value.subscription_end) && isString(value.prospectus_file_url);
261
+ return isRecord(value) && isString(value.id) && isString(value.order_book_address) && isString(value.fund_address) && isString(value.fund_id) && isString(value.fund_token) && isString(value.settlement_token) && isString(value.owner_wallet) && isString(value.manager_wallet) && isString(value.initial_nav) && isFundConfig(value.fund_config) && isString(value.status) && isString(value.network_id);
259
262
  }
260
263
  function isAssetRecord(value) {
261
264
  return isRecord(value) && isSecurityDetails(value.security) && isIssuerSummary(value.issuer) && Array.isArray(value.books) && value.books.every(isBookSummary) && isNetworkDetails(value.network);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/config.ts","../src/transport.ts","../src/validation.ts","../src/client.ts"],"sourcesContent":["export { createClient } from \"./client\";\nexport { ENVIRONMENT_BASE_URLS, resolveBaseUrl } from \"./config\";\nexport {\n HttpError,\n InvalidConfigurationError,\n MalformedResponseError,\n NotFoundError,\n ServerError,\n SereelSdkError,\n TimeoutError,\n UnauthorizedError,\n} from \"./errors\";\nexport type {\n ClientConfig,\n NativeCurrency,\n NetworkDetails,\n SdkAssetRecord,\n SdkAssetResponse,\n SdkAssetsResponse,\n SdkBookSummary,\n SdkIssuerSummary,\n SdkRuleEngineSummary,\n SdkRuleSummary,\n SdkSecurityDetails,\n SdkTokenPartner,\n SdkTokenProspectus,\n SereelEnvironment,\n SereelSdkClient,\n} from \"./types\";\n","export interface SereelSdkErrorOptions {\n status?: number;\n code?: string;\n cause?: unknown;\n details?: unknown;\n}\n\nexport class SereelSdkError extends Error {\n readonly status: number | undefined;\n readonly code: string | undefined;\n readonly details?: unknown;\n\n constructor(message: string, options: SereelSdkErrorOptions = {}) {\n super(message, options.cause ? { cause: options.cause } : undefined);\n this.name = new.target.name;\n this.status = options.status;\n this.code = options.code;\n this.details = options.details;\n }\n}\n\nexport class InvalidConfigurationError extends SereelSdkError {}\n\nexport class HttpError extends SereelSdkError {}\n\nexport class UnauthorizedError extends HttpError {}\n\nexport class NotFoundError extends HttpError {}\n\nexport class ServerError extends HttpError {}\n\nexport class TimeoutError extends SereelSdkError {}\n\nexport class MalformedResponseError extends SereelSdkError {}\n","import { InvalidConfigurationError } from \"./errors\";\nimport type { ClientConfig, SereelEnvironment } from \"./types\";\n\nexport const ENVIRONMENT_BASE_URLS: Record<SereelEnvironment, string> = {\n devnet: \"https://api-lazer.sereel.com\",\n testnet: \"https://api-lazer-v2.sereel.com\",\n mainnet: \"https://cahokia.sereel.com\",\n};\n\nexport interface ResolvedClientConfig {\n environment: SereelEnvironment;\n apiKey: string;\n timeoutMs: number;\n baseUrl: string;\n fetch: typeof fetch;\n}\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nfunction getFetchImplementation(\n providedFetch: ClientConfig[\"fetch\"],\n): typeof fetch {\n if (providedFetch) {\n return providedFetch;\n }\n\n if (typeof globalThis.fetch === \"function\") {\n return globalThis.fetch.bind(globalThis);\n }\n\n throw new InvalidConfigurationError(\n \"No fetch implementation is available. Provide config.fetch in this runtime.\",\n );\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n const trimmed = baseUrl.trim();\n\n if (!trimmed) {\n throw new InvalidConfigurationError(\"baseUrl must not be empty when provided.\");\n }\n\n try {\n return new URL(trimmed).toString().replace(/\\/+$/, \"\");\n } catch (cause) {\n throw new InvalidConfigurationError(\"baseUrl must be a valid absolute URL.\", {\n cause,\n });\n }\n}\n\nexport function resolveBaseUrl(\n environment: SereelEnvironment,\n baseUrl?: string,\n): string {\n if (baseUrl) {\n return normalizeBaseUrl(baseUrl);\n }\n\n return ENVIRONMENT_BASE_URLS[environment];\n}\n\nexport function resolveClientConfig(config: ClientConfig): ResolvedClientConfig {\n const apiKey = config.apiKey.trim();\n\n if (!apiKey) {\n throw new InvalidConfigurationError(\"apiKey must not be empty.\");\n }\n\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new InvalidConfigurationError(\"timeoutMs must be a positive number.\");\n }\n\n return {\n environment: config.environment,\n apiKey,\n timeoutMs,\n baseUrl: resolveBaseUrl(config.environment, config.baseUrl),\n fetch: getFetchImplementation(config.fetch),\n };\n}\n","import {\n HttpError,\n MalformedResponseError,\n NotFoundError,\n ServerError,\n TimeoutError,\n UnauthorizedError,\n} from \"./errors\";\nimport type { ResolvedClientConfig } from \"./config\";\n\ninterface ApiErrorBody {\n error?: string;\n message?: string;\n}\n\nfunction createTimeoutSignal(timeoutMs: number): {\n signal: AbortSignal;\n cleanup: () => void;\n} {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n return {\n signal: controller.signal,\n cleanup: () => clearTimeout(timeout),\n };\n}\n\nasync function parseBody(response: Response): Promise<unknown> {\n const text = await response.text();\n if (!text) {\n return null;\n }\n\n try {\n return JSON.parse(text) as unknown;\n } catch (cause) {\n throw new MalformedResponseError(\"Received a non-JSON response body.\", {\n cause,\n status: response.status,\n details: text,\n });\n }\n}\n\nfunction getErrorMessage(status: number, body: unknown): string {\n if (body && typeof body === \"object\") {\n const apiError = body as ApiErrorBody;\n if (typeof apiError.error === \"string\" && apiError.error.trim()) {\n return apiError.error;\n }\n if (typeof apiError.message === \"string\" && apiError.message.trim()) {\n return apiError.message;\n }\n }\n\n return `Request failed with status ${status}.`;\n}\n\nfunction toHttpError(status: number, body: unknown): HttpError {\n const message = getErrorMessage(status, body);\n const options = { status, details: body };\n\n if (status === 401) {\n return new UnauthorizedError(message, options);\n }\n if (status === 404) {\n return new NotFoundError(message, options);\n }\n if (status >= 500) {\n return new ServerError(message, options);\n }\n\n return new HttpError(message, options);\n}\n\nexport async function requestJson<T>(\n config: ResolvedClientConfig,\n path: string,\n validate: (value: unknown) => T,\n): Promise<T> {\n const { signal, cleanup } = createTimeoutSignal(config.timeoutMs);\n\n try {\n const response = await config.fetch(`${config.baseUrl}${path}`, {\n method: \"GET\",\n signal,\n headers: {\n accept: \"application/json\",\n \"x-api-key\": config.apiKey,\n },\n });\n\n const body = await parseBody(response);\n if (!response.ok) {\n throw toHttpError(response.status, body);\n }\n\n return validate(body);\n } catch (error) {\n if (error instanceof HttpError || error instanceof MalformedResponseError) {\n throw error;\n }\n\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new TimeoutError(\n `Request timed out after ${config.timeoutMs}ms.`,\n { cause: error },\n );\n }\n\n throw error;\n } finally {\n cleanup();\n }\n}\n","import { MalformedResponseError } from \"./errors\";\nimport type {\n NativeCurrency,\n NetworkDetails,\n SdkAssetRecord,\n SdkAssetResponse,\n SdkAssetsResponse,\n SdkBookSummary,\n SdkIssuerSummary,\n SdkRuleEngineSummary,\n SdkRuleSummary,\n SdkSecurityDetails,\n SdkTokenPartner,\n SdkTokenProspectus,\n} from \"./types\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isString(value: unknown): value is string {\n return typeof value === \"string\";\n}\n\nfunction isNullableString(value: unknown): value is string | null {\n return typeof value === \"string\" || value === null;\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction isBoolean(value: unknown): value is boolean {\n return typeof value === \"boolean\";\n}\n\nfunction isProspectus(value: unknown): value is SdkTokenProspectus {\n return isRecord(value) && isString(value.name) && isString(value.url);\n}\n\nfunction isTokenPartner(value: unknown): value is SdkTokenPartner {\n return (\n isRecord(value) &&\n isString(value.partner_name) &&\n isString(value.partner_logo) &&\n isString(value.partner_role)\n );\n}\n\nfunction isRuleSummary(value: unknown): value is SdkRuleSummary {\n return (\n isRecord(value) &&\n isString(value.rule_address) &&\n isString(value.rule_type)\n );\n}\n\nfunction isRuleEngineSummary(value: unknown): value is SdkRuleEngineSummary {\n return (\n isRecord(value) &&\n isString(value.name) &&\n isString(value.rule_engine_address) &&\n Array.isArray(value.rules) &&\n (value.rules as unknown[]).every(isRuleSummary)\n );\n}\n\nfunction isSecurityDetails(value: unknown): value is SdkSecurityDetails {\n if (!isRecord(value)) return false;\n\n const hasRequiredStrings =\n isString(value.token_address) &&\n isString(value.token_name) &&\n isString(value.token_symbol) &&\n isString(value.token_decimal) &&\n isString(value.network_id) &&\n isString(value.token_type) &&\n isString(value.admin);\n\n if (!hasRequiredStrings) return false;\n\n if (!isNullableString(value.icon_url)) return false;\n if (!isNullableString(value.created_at)) return false;\n\n if (value.prospectus !== null && value.prospectus !== undefined) {\n if (!isProspectus(value.prospectus)) return false;\n }\n\n if (value.partners !== null && value.partners !== undefined) {\n if (\n !Array.isArray(value.partners) ||\n !(value.partners as unknown[]).every(isTokenPartner)\n )\n return false;\n }\n\n if (value.rule_engine !== null && value.rule_engine !== undefined) {\n if (!isRuleEngineSummary(value.rule_engine)) return false;\n }\n\n return true;\n}\n\nfunction isIssuerSummary(value: unknown): value is SdkIssuerSummary {\n return (\n isRecord(value) &&\n isString(value.id) &&\n isString(value.legal_name) &&\n isNullableString(value.display_name) &&\n isString(value.jurisdiction) &&\n isNullableString(value.website) &&\n isNullableString(value.logo_url)\n );\n}\n\nfunction isNativeCurrency(value: unknown): value is NativeCurrency {\n return (\n isRecord(value) &&\n isString(value.symbol) &&\n isString(value.name) &&\n isFiniteNumber(value.decimals)\n );\n}\n\nfunction isNetworkDetails(value: unknown): value is NetworkDetails {\n return (\n isRecord(value) &&\n isString(value.network_id) &&\n isString(value.name) &&\n isString(value.family) &&\n (isFiniteNumber(value.chain_id) || value.chain_id === null) &&\n isNativeCurrency(value.native_currency) &&\n isString(value.rpc_endpoint) &&\n Array.isArray(value.explorer_urls) &&\n (value.explorer_urls as unknown[]).every(isString) &&\n isBoolean(value.can_deploy_token) &&\n isBoolean(value.is_testnet) &&\n isBoolean(value.is_supported)\n );\n}\n\nfunction isBookSummary(value: unknown): value is SdkBookSummary {\n return (\n isRecord(value) &&\n isString(value.id) &&\n isString(value.order_book_address) &&\n isString(value.status) &&\n isString(value.network_id) &&\n isFiniteNumber(value.subscription_start) &&\n isFiniteNumber(value.subscription_end) &&\n isString(value.prospectus_file_url)\n );\n}\n\nfunction isAssetRecord(value: unknown): value is SdkAssetRecord {\n return (\n isRecord(value) &&\n isSecurityDetails(value.security) &&\n isIssuerSummary(value.issuer) &&\n Array.isArray(value.books) &&\n value.books.every(isBookSummary) &&\n isNetworkDetails(value.network)\n );\n}\n\nexport function validateSdkAssetsResponse(value: unknown): SdkAssetsResponse {\n if (\n !isRecord(value) ||\n !Array.isArray(value.data) ||\n !isFiniteNumber(value.count) ||\n !value.data.every(isAssetRecord)\n ) {\n throw new MalformedResponseError(\n \"Received an invalid SDK assets response shape.\",\n { details: value },\n );\n }\n\n return value as unknown as SdkAssetsResponse;\n}\n\nexport function validateSdkAssetResponse(value: unknown): SdkAssetResponse {\n if (!isRecord(value) || !isAssetRecord(value.data)) {\n throw new MalformedResponseError(\n \"Received an invalid SDK asset response shape.\",\n { details: value },\n );\n }\n\n return value as unknown as SdkAssetResponse;\n}\n","import { resolveClientConfig } from \"./config\";\nimport { InvalidConfigurationError } from \"./errors\";\nimport { requestJson } from \"./transport\";\nimport type {\n ClientConfig,\n SdkAssetResponse,\n SdkAssetsResponse,\n SereelSdkClient,\n} from \"./types\";\nimport {\n validateSdkAssetResponse,\n validateSdkAssetsResponse,\n} from \"./validation\";\n\nexport function createClient(config: ClientConfig): SereelSdkClient {\n const resolved = resolveClientConfig(config);\n\n return {\n getAssets(): Promise<SdkAssetsResponse> {\n return requestJson(resolved, \"/sdk/assets\", validateSdkAssetsResponse);\n },\n\n getAssetByTokenAddress(tokenAddress: string): Promise<SdkAssetResponse> {\n const trimmedTokenAddress = tokenAddress.trim();\n if (!trimmedTokenAddress) {\n throw new InvalidConfigurationError(\n \"tokenAddress must not be empty.\",\n );\n }\n\n return requestJson(\n resolved,\n `/sdk/assets/${encodeURIComponent(trimmedTokenAddress)}`,\n validateSdkAssetResponse,\n );\n },\n\n getAssetsByIssuer(issuerId: string): Promise<SdkAssetsResponse> {\n const trimmedIssuerId = issuerId.trim();\n if (!trimmedIssuerId) {\n throw new InvalidConfigurationError(\"issuerId must not be empty.\");\n }\n\n return requestJson(\n resolved,\n `/sdk/assets/issuer/${encodeURIComponent(trimmedIssuerId)}`,\n validateSdkAssetsResponse,\n );\n },\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/config.ts","../src/transport.ts","../src/validation.ts","../src/client.ts"],"sourcesContent":["export { createClient } from \"./client\";\nexport { ENVIRONMENT_BASE_URLS, resolveBaseUrl } from \"./config\";\nexport {\n HttpError,\n InvalidConfigurationError,\n MalformedResponseError,\n NotFoundError,\n ServerError,\n SereelSdkError,\n TimeoutError,\n UnauthorizedError,\n} from \"./errors\";\nexport type {\n ClientConfig,\n NativeCurrency,\n NetworkDetails,\n SdkAssetRecord,\n SdkAssetResponse,\n SdkAssetsResponse,\n SdkBookSummary,\n SdkFundConfig,\n SdkIssuerSummary,\n SdkRuleEngineSummary,\n SdkRuleSummary,\n SdkSecurityDetails,\n SdkTokenPartner,\n SdkTokenProspectus,\n SereelEnvironment,\n SereelSdkClient,\n} from \"./types\";\n","export interface SereelSdkErrorOptions {\n status?: number;\n code?: string;\n cause?: unknown;\n details?: unknown;\n}\n\nexport class SereelSdkError extends Error {\n readonly status: number | undefined;\n readonly code: string | undefined;\n readonly details?: unknown;\n\n constructor(message: string, options: SereelSdkErrorOptions = {}) {\n super(message, options.cause ? { cause: options.cause } : undefined);\n this.name = new.target.name;\n this.status = options.status;\n this.code = options.code;\n this.details = options.details;\n }\n}\n\nexport class InvalidConfigurationError extends SereelSdkError {}\n\nexport class HttpError extends SereelSdkError {}\n\nexport class UnauthorizedError extends HttpError {}\n\nexport class NotFoundError extends HttpError {}\n\nexport class ServerError extends HttpError {}\n\nexport class TimeoutError extends SereelSdkError {}\n\nexport class MalformedResponseError extends SereelSdkError {}\n","import { InvalidConfigurationError } from \"./errors\";\nimport type { ClientConfig, SereelEnvironment } from \"./types\";\n\nexport const ENVIRONMENT_BASE_URLS: Record<SereelEnvironment, string> = {\n devnet: \"https://api-lazer.sereel.com\",\n testnet: \"https://api-lazer-v2.sereel.com\",\n mainnet: \"https://cahokia.sereel.com\",\n};\n\nexport interface ResolvedClientConfig {\n environment: SereelEnvironment;\n apiKey: string;\n timeoutMs: number;\n baseUrl: string;\n fetch: typeof fetch;\n}\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nfunction getFetchImplementation(\n providedFetch: ClientConfig[\"fetch\"],\n): typeof fetch {\n if (providedFetch) {\n return providedFetch;\n }\n\n if (typeof globalThis.fetch === \"function\") {\n return globalThis.fetch.bind(globalThis);\n }\n\n throw new InvalidConfigurationError(\n \"No fetch implementation is available. Provide config.fetch in this runtime.\",\n );\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n const trimmed = baseUrl.trim();\n\n if (!trimmed) {\n throw new InvalidConfigurationError(\"baseUrl must not be empty when provided.\");\n }\n\n try {\n return new URL(trimmed).toString().replace(/\\/+$/, \"\");\n } catch (cause) {\n throw new InvalidConfigurationError(\"baseUrl must be a valid absolute URL.\", {\n cause,\n });\n }\n}\n\nexport function resolveBaseUrl(\n environment: SereelEnvironment,\n baseUrl?: string,\n): string {\n if (baseUrl) {\n return normalizeBaseUrl(baseUrl);\n }\n\n return ENVIRONMENT_BASE_URLS[environment];\n}\n\nexport function resolveClientConfig(config: ClientConfig): ResolvedClientConfig {\n const apiKey = config.apiKey.trim();\n\n if (!apiKey) {\n throw new InvalidConfigurationError(\"apiKey must not be empty.\");\n }\n\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new InvalidConfigurationError(\"timeoutMs must be a positive number.\");\n }\n\n return {\n environment: config.environment,\n apiKey,\n timeoutMs,\n baseUrl: resolveBaseUrl(config.environment, config.baseUrl),\n fetch: getFetchImplementation(config.fetch),\n };\n}\n","import {\n HttpError,\n MalformedResponseError,\n NotFoundError,\n ServerError,\n TimeoutError,\n UnauthorizedError,\n} from \"./errors\";\nimport type { ResolvedClientConfig } from \"./config\";\n\ninterface ApiErrorBody {\n error?: string;\n message?: string;\n}\n\nfunction createTimeoutSignal(timeoutMs: number): {\n signal: AbortSignal;\n cleanup: () => void;\n} {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n return {\n signal: controller.signal,\n cleanup: () => clearTimeout(timeout),\n };\n}\n\nasync function parseBody(response: Response): Promise<unknown> {\n const text = await response.text();\n if (!text) {\n return null;\n }\n\n try {\n return JSON.parse(text) as unknown;\n } catch (cause) {\n throw new MalformedResponseError(\"Received a non-JSON response body.\", {\n cause,\n status: response.status,\n details: text,\n });\n }\n}\n\nfunction getErrorMessage(status: number, body: unknown): string {\n if (body && typeof body === \"object\") {\n const apiError = body as ApiErrorBody;\n if (typeof apiError.error === \"string\" && apiError.error.trim()) {\n return apiError.error;\n }\n if (typeof apiError.message === \"string\" && apiError.message.trim()) {\n return apiError.message;\n }\n }\n\n return `Request failed with status ${status}.`;\n}\n\nfunction toHttpError(status: number, body: unknown): HttpError {\n const message = getErrorMessage(status, body);\n const options = { status, details: body };\n\n if (status === 401) {\n return new UnauthorizedError(message, options);\n }\n if (status === 404) {\n return new NotFoundError(message, options);\n }\n if (status >= 500) {\n return new ServerError(message, options);\n }\n\n return new HttpError(message, options);\n}\n\nexport async function requestJson<T>(\n config: ResolvedClientConfig,\n path: string,\n validate: (value: unknown) => T,\n): Promise<T> {\n const { signal, cleanup } = createTimeoutSignal(config.timeoutMs);\n\n try {\n const response = await config.fetch(`${config.baseUrl}${path}`, {\n method: \"GET\",\n signal,\n headers: {\n accept: \"application/json\",\n \"x-api-key\": config.apiKey,\n },\n });\n\n const body = await parseBody(response);\n if (!response.ok) {\n throw toHttpError(response.status, body);\n }\n\n return validate(body);\n } catch (error) {\n if (error instanceof HttpError || error instanceof MalformedResponseError) {\n throw error;\n }\n\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new TimeoutError(\n `Request timed out after ${config.timeoutMs}ms.`,\n { cause: error },\n );\n }\n\n throw error;\n } finally {\n cleanup();\n }\n}\n","import { MalformedResponseError } from \"./errors\";\nimport type {\n NativeCurrency,\n NetworkDetails,\n SdkAssetRecord,\n SdkAssetResponse,\n SdkAssetsResponse,\n SdkBookSummary,\n SdkFundConfig,\n SdkIssuerSummary,\n SdkRuleEngineSummary,\n SdkRuleSummary,\n SdkSecurityDetails,\n SdkTokenPartner,\n SdkTokenProspectus,\n} from \"./types\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isString(value: unknown): value is string {\n return typeof value === \"string\";\n}\n\nfunction isNullableString(value: unknown): value is string | null {\n return typeof value === \"string\" || value === null;\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction isBoolean(value: unknown): value is boolean {\n return typeof value === \"boolean\";\n}\n\nfunction isProspectus(value: unknown): value is SdkTokenProspectus {\n return isRecord(value) && isString(value.name) && isString(value.url);\n}\n\nfunction isTokenPartner(value: unknown): value is SdkTokenPartner {\n return (\n isRecord(value) &&\n isString(value.partner_name) &&\n isString(value.partner_logo) &&\n isString(value.partner_role)\n );\n}\n\nfunction isRuleSummary(value: unknown): value is SdkRuleSummary {\n return (\n isRecord(value) &&\n isString(value.rule_address) &&\n isString(value.rule_type)\n );\n}\n\nfunction isRuleEngineSummary(value: unknown): value is SdkRuleEngineSummary {\n return (\n isRecord(value) &&\n isString(value.name) &&\n isString(value.rule_engine_address) &&\n Array.isArray(value.rules) &&\n (value.rules as unknown[]).every(isRuleSummary)\n );\n}\n\nfunction isSecurityDetails(value: unknown): value is SdkSecurityDetails {\n if (!isRecord(value)) return false;\n\n const hasRequiredStrings =\n isString(value.token_address) &&\n isString(value.token_name) &&\n isString(value.token_symbol) &&\n isString(value.token_decimal) &&\n isString(value.network_id) &&\n isString(value.token_type) &&\n isString(value.admin);\n\n if (!hasRequiredStrings) return false;\n\n if (!isNullableString(value.icon_url)) return false;\n if (!isNullableString(value.created_at)) return false;\n\n if (value.prospectus !== null && value.prospectus !== undefined) {\n if (!isProspectus(value.prospectus)) return false;\n }\n\n if (value.partners !== null && value.partners !== undefined) {\n if (\n !Array.isArray(value.partners) ||\n !(value.partners as unknown[]).every(isTokenPartner)\n )\n return false;\n }\n\n if (value.rule_engine !== null && value.rule_engine !== undefined) {\n if (!isRuleEngineSummary(value.rule_engine)) return false;\n }\n\n return true;\n}\n\nfunction isIssuerSummary(value: unknown): value is SdkIssuerSummary {\n return (\n isRecord(value) &&\n isString(value.id) &&\n isString(value.legal_name) &&\n isNullableString(value.display_name) &&\n isString(value.jurisdiction) &&\n isNullableString(value.website) &&\n isNullableString(value.logo_url)\n );\n}\n\nfunction isNativeCurrency(value: unknown): value is NativeCurrency {\n return (\n isRecord(value) &&\n isString(value.symbol) &&\n isString(value.name) &&\n isFiniteNumber(value.decimals)\n );\n}\n\nfunction isNetworkDetails(value: unknown): value is NetworkDetails {\n return (\n isRecord(value) &&\n isString(value.network_id) &&\n isString(value.name) &&\n isString(value.family) &&\n (isFiniteNumber(value.chain_id) || value.chain_id === null) &&\n isNativeCurrency(value.native_currency) &&\n isString(value.rpc_endpoint) &&\n Array.isArray(value.explorer_urls) &&\n (value.explorer_urls as unknown[]).every(isString) &&\n isBoolean(value.can_deploy_cmtat_token) &&\n isBoolean(value.can_deploy_trex_token) &&\n isBoolean(value.is_testnet) &&\n isBoolean(value.is_supported)\n );\n}\n\nfunction isFundConfig(value: unknown): value is SdkFundConfig {\n return (\n isRecord(value) &&\n isString(value.nav_staleness_threshold) &&\n isString(value.min_subscription) &&\n isString(value.min_redemption) &&\n isString(value.entry_fee_bps) &&\n isString(value.exit_fee_bps) &&\n isFiniteNumber(value.dealing_mode) &&\n isString(value.redemption_gate_bps) &&\n isString(value.protocol_subscription_fee_bps) &&\n isString(value.protocol_fee_recipient) &&\n isString(value.management_fee_bps_per_annum)\n );\n}\n\nfunction isBookSummary(value: unknown): value is SdkBookSummary {\n return (\n isRecord(value) &&\n isString(value.id) &&\n isString(value.order_book_address) &&\n isString(value.fund_address) &&\n isString(value.fund_id) &&\n isString(value.fund_token) &&\n isString(value.settlement_token) &&\n isString(value.owner_wallet) &&\n isString(value.manager_wallet) &&\n isString(value.initial_nav) &&\n isFundConfig(value.fund_config) &&\n isString(value.status) &&\n isString(value.network_id)\n );\n}\n\nfunction isAssetRecord(value: unknown): value is SdkAssetRecord {\n return (\n isRecord(value) &&\n isSecurityDetails(value.security) &&\n isIssuerSummary(value.issuer) &&\n Array.isArray(value.books) &&\n value.books.every(isBookSummary) &&\n isNetworkDetails(value.network)\n );\n}\n\nexport function validateSdkAssetsResponse(value: unknown): SdkAssetsResponse {\n if (\n !isRecord(value) ||\n !Array.isArray(value.data) ||\n !isFiniteNumber(value.count) ||\n !value.data.every(isAssetRecord)\n ) {\n throw new MalformedResponseError(\n \"Received an invalid SDK assets response shape.\",\n { details: value },\n );\n }\n\n return value as unknown as SdkAssetsResponse;\n}\n\nexport function validateSdkAssetResponse(value: unknown): SdkAssetResponse {\n if (!isRecord(value) || !isAssetRecord(value.data)) {\n throw new MalformedResponseError(\n \"Received an invalid SDK asset response shape.\",\n { details: value },\n );\n }\n\n return value as unknown as SdkAssetResponse;\n}\n","import { resolveClientConfig } from \"./config\";\nimport { InvalidConfigurationError } from \"./errors\";\nimport { requestJson } from \"./transport\";\nimport type {\n ClientConfig,\n SdkAssetResponse,\n SdkAssetsResponse,\n SereelSdkClient,\n} from \"./types\";\nimport {\n validateSdkAssetResponse,\n validateSdkAssetsResponse,\n} from \"./validation\";\n\nexport function createClient(config: ClientConfig): SereelSdkClient {\n const resolved = resolveClientConfig(config);\n\n return {\n getAssets(): Promise<SdkAssetsResponse> {\n return requestJson(resolved, \"/sdk/assets\", validateSdkAssetsResponse);\n },\n\n getAssetByTokenAddress(tokenAddress: string): Promise<SdkAssetResponse> {\n const trimmedTokenAddress = tokenAddress.trim();\n if (!trimmedTokenAddress) {\n throw new InvalidConfigurationError(\n \"tokenAddress must not be empty.\",\n );\n }\n\n return requestJson(\n resolved,\n `/sdk/assets/${encodeURIComponent(trimmedTokenAddress)}`,\n validateSdkAssetResponse,\n );\n },\n\n getAssetsByIssuer(issuerId: string): Promise<SdkAssetsResponse> {\n const trimmedIssuerId = issuerId.trim();\n if (!trimmedIssuerId) {\n throw new InvalidConfigurationError(\"issuerId must not be empty.\");\n }\n\n return requestJson(\n resolved,\n `/sdk/assets/issuer/${encodeURIComponent(trimmedIssuerId)}`,\n validateSdkAssetsResponse,\n );\n },\n };\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -19,7 +19,8 @@ interface NetworkDetails {
19
19
  native_currency: NativeCurrency;
20
20
  rpc_endpoint: string;
21
21
  explorer_urls: string[];
22
- can_deploy_token: boolean;
22
+ can_deploy_cmtat_token: boolean;
23
+ can_deploy_trex_token: boolean;
23
24
  is_testnet: boolean;
24
25
  is_supported: boolean;
25
26
  }
@@ -55,6 +56,8 @@ interface SdkSecurityDetails {
55
56
  partners: SdkTokenPartner[] | null;
56
57
  rule_engine: SdkRuleEngineSummary | null;
57
58
  created_at: string | null;
59
+ trex_claim_topics: number[] | null;
60
+ trex_issuers: string[] | null;
58
61
  }
59
62
  interface SdkIssuerSummary {
60
63
  id: string;
@@ -64,14 +67,32 @@ interface SdkIssuerSummary {
64
67
  website: string | null;
65
68
  logo_url: string | null;
66
69
  }
70
+ interface SdkFundConfig {
71
+ nav_staleness_threshold: string;
72
+ min_subscription: string;
73
+ min_redemption: string;
74
+ entry_fee_bps: string;
75
+ exit_fee_bps: string;
76
+ dealing_mode: number;
77
+ redemption_gate_bps: string;
78
+ protocol_subscription_fee_bps: string;
79
+ protocol_fee_recipient: string;
80
+ management_fee_bps_per_annum: string;
81
+ }
67
82
  interface SdkBookSummary {
68
83
  id: string;
69
84
  order_book_address: string;
85
+ fund_address: string;
86
+ fund_id: string;
87
+ fund_token: string;
88
+ settlement_token: string;
89
+ owner_wallet: string;
90
+ manager_wallet: string;
91
+ initial_nav: string;
92
+ fund_config: SdkFundConfig;
70
93
  status: string;
94
+ book_type: string | null;
71
95
  network_id: string;
72
- subscription_start: number;
73
- subscription_end: number;
74
- prospectus_file_url: string;
75
96
  }
76
97
  interface SdkAssetRecord {
77
98
  security: SdkSecurityDetails;
@@ -124,4 +145,4 @@ declare class TimeoutError extends SereelSdkError {
124
145
  declare class MalformedResponseError extends SereelSdkError {
125
146
  }
126
147
 
127
- export { type ClientConfig, ENVIRONMENT_BASE_URLS, HttpError, InvalidConfigurationError, MalformedResponseError, type NativeCurrency, type NetworkDetails, NotFoundError, type SdkAssetRecord, type SdkAssetResponse, type SdkAssetsResponse, type SdkBookSummary, type SdkIssuerSummary, type SdkRuleEngineSummary, type SdkRuleSummary, type SdkSecurityDetails, type SdkTokenPartner, type SdkTokenProspectus, type SereelEnvironment, type SereelSdkClient, SereelSdkError, ServerError, TimeoutError, UnauthorizedError, createClient, resolveBaseUrl };
148
+ export { type ClientConfig, ENVIRONMENT_BASE_URLS, HttpError, InvalidConfigurationError, MalformedResponseError, type NativeCurrency, type NetworkDetails, NotFoundError, type SdkAssetRecord, type SdkAssetResponse, type SdkAssetsResponse, type SdkBookSummary, type SdkFundConfig, type SdkIssuerSummary, type SdkRuleEngineSummary, type SdkRuleSummary, type SdkSecurityDetails, type SdkTokenPartner, type SdkTokenProspectus, type SereelEnvironment, type SereelSdkClient, SereelSdkError, ServerError, TimeoutError, UnauthorizedError, createClient, resolveBaseUrl };
package/dist/index.d.ts CHANGED
@@ -19,7 +19,8 @@ interface NetworkDetails {
19
19
  native_currency: NativeCurrency;
20
20
  rpc_endpoint: string;
21
21
  explorer_urls: string[];
22
- can_deploy_token: boolean;
22
+ can_deploy_cmtat_token: boolean;
23
+ can_deploy_trex_token: boolean;
23
24
  is_testnet: boolean;
24
25
  is_supported: boolean;
25
26
  }
@@ -55,6 +56,8 @@ interface SdkSecurityDetails {
55
56
  partners: SdkTokenPartner[] | null;
56
57
  rule_engine: SdkRuleEngineSummary | null;
57
58
  created_at: string | null;
59
+ trex_claim_topics: number[] | null;
60
+ trex_issuers: string[] | null;
58
61
  }
59
62
  interface SdkIssuerSummary {
60
63
  id: string;
@@ -64,14 +67,32 @@ interface SdkIssuerSummary {
64
67
  website: string | null;
65
68
  logo_url: string | null;
66
69
  }
70
+ interface SdkFundConfig {
71
+ nav_staleness_threshold: string;
72
+ min_subscription: string;
73
+ min_redemption: string;
74
+ entry_fee_bps: string;
75
+ exit_fee_bps: string;
76
+ dealing_mode: number;
77
+ redemption_gate_bps: string;
78
+ protocol_subscription_fee_bps: string;
79
+ protocol_fee_recipient: string;
80
+ management_fee_bps_per_annum: string;
81
+ }
67
82
  interface SdkBookSummary {
68
83
  id: string;
69
84
  order_book_address: string;
85
+ fund_address: string;
86
+ fund_id: string;
87
+ fund_token: string;
88
+ settlement_token: string;
89
+ owner_wallet: string;
90
+ manager_wallet: string;
91
+ initial_nav: string;
92
+ fund_config: SdkFundConfig;
70
93
  status: string;
94
+ book_type: string | null;
71
95
  network_id: string;
72
- subscription_start: number;
73
- subscription_end: number;
74
- prospectus_file_url: string;
75
96
  }
76
97
  interface SdkAssetRecord {
77
98
  security: SdkSecurityDetails;
@@ -124,4 +145,4 @@ declare class TimeoutError extends SereelSdkError {
124
145
  declare class MalformedResponseError extends SereelSdkError {
125
146
  }
126
147
 
127
- export { type ClientConfig, ENVIRONMENT_BASE_URLS, HttpError, InvalidConfigurationError, MalformedResponseError, type NativeCurrency, type NetworkDetails, NotFoundError, type SdkAssetRecord, type SdkAssetResponse, type SdkAssetsResponse, type SdkBookSummary, type SdkIssuerSummary, type SdkRuleEngineSummary, type SdkRuleSummary, type SdkSecurityDetails, type SdkTokenPartner, type SdkTokenProspectus, type SereelEnvironment, type SereelSdkClient, SereelSdkError, ServerError, TimeoutError, UnauthorizedError, createClient, resolveBaseUrl };
148
+ export { type ClientConfig, ENVIRONMENT_BASE_URLS, HttpError, InvalidConfigurationError, MalformedResponseError, type NativeCurrency, type NetworkDetails, NotFoundError, type SdkAssetRecord, type SdkAssetResponse, type SdkAssetsResponse, type SdkBookSummary, type SdkFundConfig, type SdkIssuerSummary, type SdkRuleEngineSummary, type SdkRuleSummary, type SdkSecurityDetails, type SdkTokenPartner, type SdkTokenProspectus, type SereelEnvironment, type SereelSdkClient, SereelSdkError, ServerError, TimeoutError, UnauthorizedError, createClient, resolveBaseUrl };
package/dist/index.js CHANGED
@@ -216,10 +216,13 @@ function isNativeCurrency(value) {
216
216
  return isRecord(value) && isString(value.symbol) && isString(value.name) && isFiniteNumber(value.decimals);
217
217
  }
218
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_token) && isBoolean(value.is_testnet) && isBoolean(value.is_supported);
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);
220
+ }
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);
220
223
  }
221
224
  function isBookSummary(value) {
222
- return isRecord(value) && isString(value.id) && isString(value.order_book_address) && isString(value.status) && isString(value.network_id) && isFiniteNumber(value.subscription_start) && isFiniteNumber(value.subscription_end) && isString(value.prospectus_file_url);
225
+ return isRecord(value) && isString(value.id) && isString(value.order_book_address) && isString(value.fund_address) && isString(value.fund_id) && isString(value.fund_token) && isString(value.settlement_token) && isString(value.owner_wallet) && isString(value.manager_wallet) && isString(value.initial_nav) && isFundConfig(value.fund_config) && isString(value.status) && isString(value.network_id);
223
226
  }
224
227
  function isAssetRecord(value) {
225
228
  return isRecord(value) && isSecurityDetails(value.security) && isIssuerSummary(value.issuer) && Array.isArray(value.books) && value.books.every(isBookSummary) && isNetworkDetails(value.network);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/config.ts","../src/transport.ts","../src/validation.ts","../src/client.ts"],"sourcesContent":["export interface SereelSdkErrorOptions {\n status?: number;\n code?: string;\n cause?: unknown;\n details?: unknown;\n}\n\nexport class SereelSdkError extends Error {\n readonly status: number | undefined;\n readonly code: string | undefined;\n readonly details?: unknown;\n\n constructor(message: string, options: SereelSdkErrorOptions = {}) {\n super(message, options.cause ? { cause: options.cause } : undefined);\n this.name = new.target.name;\n this.status = options.status;\n this.code = options.code;\n this.details = options.details;\n }\n}\n\nexport class InvalidConfigurationError extends SereelSdkError {}\n\nexport class HttpError extends SereelSdkError {}\n\nexport class UnauthorizedError extends HttpError {}\n\nexport class NotFoundError extends HttpError {}\n\nexport class ServerError extends HttpError {}\n\nexport class TimeoutError extends SereelSdkError {}\n\nexport class MalformedResponseError extends SereelSdkError {}\n","import { InvalidConfigurationError } from \"./errors\";\nimport type { ClientConfig, SereelEnvironment } from \"./types\";\n\nexport const ENVIRONMENT_BASE_URLS: Record<SereelEnvironment, string> = {\n devnet: \"https://api-lazer.sereel.com\",\n testnet: \"https://api-lazer-v2.sereel.com\",\n mainnet: \"https://cahokia.sereel.com\",\n};\n\nexport interface ResolvedClientConfig {\n environment: SereelEnvironment;\n apiKey: string;\n timeoutMs: number;\n baseUrl: string;\n fetch: typeof fetch;\n}\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nfunction getFetchImplementation(\n providedFetch: ClientConfig[\"fetch\"],\n): typeof fetch {\n if (providedFetch) {\n return providedFetch;\n }\n\n if (typeof globalThis.fetch === \"function\") {\n return globalThis.fetch.bind(globalThis);\n }\n\n throw new InvalidConfigurationError(\n \"No fetch implementation is available. Provide config.fetch in this runtime.\",\n );\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n const trimmed = baseUrl.trim();\n\n if (!trimmed) {\n throw new InvalidConfigurationError(\"baseUrl must not be empty when provided.\");\n }\n\n try {\n return new URL(trimmed).toString().replace(/\\/+$/, \"\");\n } catch (cause) {\n throw new InvalidConfigurationError(\"baseUrl must be a valid absolute URL.\", {\n cause,\n });\n }\n}\n\nexport function resolveBaseUrl(\n environment: SereelEnvironment,\n baseUrl?: string,\n): string {\n if (baseUrl) {\n return normalizeBaseUrl(baseUrl);\n }\n\n return ENVIRONMENT_BASE_URLS[environment];\n}\n\nexport function resolveClientConfig(config: ClientConfig): ResolvedClientConfig {\n const apiKey = config.apiKey.trim();\n\n if (!apiKey) {\n throw new InvalidConfigurationError(\"apiKey must not be empty.\");\n }\n\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new InvalidConfigurationError(\"timeoutMs must be a positive number.\");\n }\n\n return {\n environment: config.environment,\n apiKey,\n timeoutMs,\n baseUrl: resolveBaseUrl(config.environment, config.baseUrl),\n fetch: getFetchImplementation(config.fetch),\n };\n}\n","import {\n HttpError,\n MalformedResponseError,\n NotFoundError,\n ServerError,\n TimeoutError,\n UnauthorizedError,\n} from \"./errors\";\nimport type { ResolvedClientConfig } from \"./config\";\n\ninterface ApiErrorBody {\n error?: string;\n message?: string;\n}\n\nfunction createTimeoutSignal(timeoutMs: number): {\n signal: AbortSignal;\n cleanup: () => void;\n} {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n return {\n signal: controller.signal,\n cleanup: () => clearTimeout(timeout),\n };\n}\n\nasync function parseBody(response: Response): Promise<unknown> {\n const text = await response.text();\n if (!text) {\n return null;\n }\n\n try {\n return JSON.parse(text) as unknown;\n } catch (cause) {\n throw new MalformedResponseError(\"Received a non-JSON response body.\", {\n cause,\n status: response.status,\n details: text,\n });\n }\n}\n\nfunction getErrorMessage(status: number, body: unknown): string {\n if (body && typeof body === \"object\") {\n const apiError = body as ApiErrorBody;\n if (typeof apiError.error === \"string\" && apiError.error.trim()) {\n return apiError.error;\n }\n if (typeof apiError.message === \"string\" && apiError.message.trim()) {\n return apiError.message;\n }\n }\n\n return `Request failed with status ${status}.`;\n}\n\nfunction toHttpError(status: number, body: unknown): HttpError {\n const message = getErrorMessage(status, body);\n const options = { status, details: body };\n\n if (status === 401) {\n return new UnauthorizedError(message, options);\n }\n if (status === 404) {\n return new NotFoundError(message, options);\n }\n if (status >= 500) {\n return new ServerError(message, options);\n }\n\n return new HttpError(message, options);\n}\n\nexport async function requestJson<T>(\n config: ResolvedClientConfig,\n path: string,\n validate: (value: unknown) => T,\n): Promise<T> {\n const { signal, cleanup } = createTimeoutSignal(config.timeoutMs);\n\n try {\n const response = await config.fetch(`${config.baseUrl}${path}`, {\n method: \"GET\",\n signal,\n headers: {\n accept: \"application/json\",\n \"x-api-key\": config.apiKey,\n },\n });\n\n const body = await parseBody(response);\n if (!response.ok) {\n throw toHttpError(response.status, body);\n }\n\n return validate(body);\n } catch (error) {\n if (error instanceof HttpError || error instanceof MalformedResponseError) {\n throw error;\n }\n\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new TimeoutError(\n `Request timed out after ${config.timeoutMs}ms.`,\n { cause: error },\n );\n }\n\n throw error;\n } finally {\n cleanup();\n }\n}\n","import { MalformedResponseError } from \"./errors\";\nimport type {\n NativeCurrency,\n NetworkDetails,\n SdkAssetRecord,\n SdkAssetResponse,\n SdkAssetsResponse,\n SdkBookSummary,\n SdkIssuerSummary,\n SdkRuleEngineSummary,\n SdkRuleSummary,\n SdkSecurityDetails,\n SdkTokenPartner,\n SdkTokenProspectus,\n} from \"./types\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isString(value: unknown): value is string {\n return typeof value === \"string\";\n}\n\nfunction isNullableString(value: unknown): value is string | null {\n return typeof value === \"string\" || value === null;\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction isBoolean(value: unknown): value is boolean {\n return typeof value === \"boolean\";\n}\n\nfunction isProspectus(value: unknown): value is SdkTokenProspectus {\n return isRecord(value) && isString(value.name) && isString(value.url);\n}\n\nfunction isTokenPartner(value: unknown): value is SdkTokenPartner {\n return (\n isRecord(value) &&\n isString(value.partner_name) &&\n isString(value.partner_logo) &&\n isString(value.partner_role)\n );\n}\n\nfunction isRuleSummary(value: unknown): value is SdkRuleSummary {\n return (\n isRecord(value) &&\n isString(value.rule_address) &&\n isString(value.rule_type)\n );\n}\n\nfunction isRuleEngineSummary(value: unknown): value is SdkRuleEngineSummary {\n return (\n isRecord(value) &&\n isString(value.name) &&\n isString(value.rule_engine_address) &&\n Array.isArray(value.rules) &&\n (value.rules as unknown[]).every(isRuleSummary)\n );\n}\n\nfunction isSecurityDetails(value: unknown): value is SdkSecurityDetails {\n if (!isRecord(value)) return false;\n\n const hasRequiredStrings =\n isString(value.token_address) &&\n isString(value.token_name) &&\n isString(value.token_symbol) &&\n isString(value.token_decimal) &&\n isString(value.network_id) &&\n isString(value.token_type) &&\n isString(value.admin);\n\n if (!hasRequiredStrings) return false;\n\n if (!isNullableString(value.icon_url)) return false;\n if (!isNullableString(value.created_at)) return false;\n\n if (value.prospectus !== null && value.prospectus !== undefined) {\n if (!isProspectus(value.prospectus)) return false;\n }\n\n if (value.partners !== null && value.partners !== undefined) {\n if (\n !Array.isArray(value.partners) ||\n !(value.partners as unknown[]).every(isTokenPartner)\n )\n return false;\n }\n\n if (value.rule_engine !== null && value.rule_engine !== undefined) {\n if (!isRuleEngineSummary(value.rule_engine)) return false;\n }\n\n return true;\n}\n\nfunction isIssuerSummary(value: unknown): value is SdkIssuerSummary {\n return (\n isRecord(value) &&\n isString(value.id) &&\n isString(value.legal_name) &&\n isNullableString(value.display_name) &&\n isString(value.jurisdiction) &&\n isNullableString(value.website) &&\n isNullableString(value.logo_url)\n );\n}\n\nfunction isNativeCurrency(value: unknown): value is NativeCurrency {\n return (\n isRecord(value) &&\n isString(value.symbol) &&\n isString(value.name) &&\n isFiniteNumber(value.decimals)\n );\n}\n\nfunction isNetworkDetails(value: unknown): value is NetworkDetails {\n return (\n isRecord(value) &&\n isString(value.network_id) &&\n isString(value.name) &&\n isString(value.family) &&\n (isFiniteNumber(value.chain_id) || value.chain_id === null) &&\n isNativeCurrency(value.native_currency) &&\n isString(value.rpc_endpoint) &&\n Array.isArray(value.explorer_urls) &&\n (value.explorer_urls as unknown[]).every(isString) &&\n isBoolean(value.can_deploy_token) &&\n isBoolean(value.is_testnet) &&\n isBoolean(value.is_supported)\n );\n}\n\nfunction isBookSummary(value: unknown): value is SdkBookSummary {\n return (\n isRecord(value) &&\n isString(value.id) &&\n isString(value.order_book_address) &&\n isString(value.status) &&\n isString(value.network_id) &&\n isFiniteNumber(value.subscription_start) &&\n isFiniteNumber(value.subscription_end) &&\n isString(value.prospectus_file_url)\n );\n}\n\nfunction isAssetRecord(value: unknown): value is SdkAssetRecord {\n return (\n isRecord(value) &&\n isSecurityDetails(value.security) &&\n isIssuerSummary(value.issuer) &&\n Array.isArray(value.books) &&\n value.books.every(isBookSummary) &&\n isNetworkDetails(value.network)\n );\n}\n\nexport function validateSdkAssetsResponse(value: unknown): SdkAssetsResponse {\n if (\n !isRecord(value) ||\n !Array.isArray(value.data) ||\n !isFiniteNumber(value.count) ||\n !value.data.every(isAssetRecord)\n ) {\n throw new MalformedResponseError(\n \"Received an invalid SDK assets response shape.\",\n { details: value },\n );\n }\n\n return value as unknown as SdkAssetsResponse;\n}\n\nexport function validateSdkAssetResponse(value: unknown): SdkAssetResponse {\n if (!isRecord(value) || !isAssetRecord(value.data)) {\n throw new MalformedResponseError(\n \"Received an invalid SDK asset response shape.\",\n { details: value },\n );\n }\n\n return value as unknown as SdkAssetResponse;\n}\n","import { resolveClientConfig } from \"./config\";\nimport { InvalidConfigurationError } from \"./errors\";\nimport { requestJson } from \"./transport\";\nimport type {\n ClientConfig,\n SdkAssetResponse,\n SdkAssetsResponse,\n SereelSdkClient,\n} from \"./types\";\nimport {\n validateSdkAssetResponse,\n validateSdkAssetsResponse,\n} from \"./validation\";\n\nexport function createClient(config: ClientConfig): SereelSdkClient {\n const resolved = resolveClientConfig(config);\n\n return {\n getAssets(): Promise<SdkAssetsResponse> {\n return requestJson(resolved, \"/sdk/assets\", validateSdkAssetsResponse);\n },\n\n getAssetByTokenAddress(tokenAddress: string): Promise<SdkAssetResponse> {\n const trimmedTokenAddress = tokenAddress.trim();\n if (!trimmedTokenAddress) {\n throw new InvalidConfigurationError(\n \"tokenAddress must not be empty.\",\n );\n }\n\n return requestJson(\n resolved,\n `/sdk/assets/${encodeURIComponent(trimmedTokenAddress)}`,\n validateSdkAssetResponse,\n );\n },\n\n getAssetsByIssuer(issuerId: string): Promise<SdkAssetsResponse> {\n const trimmedIssuerId = issuerId.trim();\n if (!trimmedIssuerId) {\n throw new InvalidConfigurationError(\"issuerId must not be empty.\");\n }\n\n return requestJson(\n resolved,\n `/sdk/assets/issuer/${encodeURIComponent(trimmedIssuerId)}`,\n validateSdkAssetsResponse,\n );\n },\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/config.ts","../src/transport.ts","../src/validation.ts","../src/client.ts"],"sourcesContent":["export interface SereelSdkErrorOptions {\n status?: number;\n code?: string;\n cause?: unknown;\n details?: unknown;\n}\n\nexport class SereelSdkError extends Error {\n readonly status: number | undefined;\n readonly code: string | undefined;\n readonly details?: unknown;\n\n constructor(message: string, options: SereelSdkErrorOptions = {}) {\n super(message, options.cause ? { cause: options.cause } : undefined);\n this.name = new.target.name;\n this.status = options.status;\n this.code = options.code;\n this.details = options.details;\n }\n}\n\nexport class InvalidConfigurationError extends SereelSdkError {}\n\nexport class HttpError extends SereelSdkError {}\n\nexport class UnauthorizedError extends HttpError {}\n\nexport class NotFoundError extends HttpError {}\n\nexport class ServerError extends HttpError {}\n\nexport class TimeoutError extends SereelSdkError {}\n\nexport class MalformedResponseError extends SereelSdkError {}\n","import { InvalidConfigurationError } from \"./errors\";\nimport type { ClientConfig, SereelEnvironment } from \"./types\";\n\nexport const ENVIRONMENT_BASE_URLS: Record<SereelEnvironment, string> = {\n devnet: \"https://api-lazer.sereel.com\",\n testnet: \"https://api-lazer-v2.sereel.com\",\n mainnet: \"https://cahokia.sereel.com\",\n};\n\nexport interface ResolvedClientConfig {\n environment: SereelEnvironment;\n apiKey: string;\n timeoutMs: number;\n baseUrl: string;\n fetch: typeof fetch;\n}\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nfunction getFetchImplementation(\n providedFetch: ClientConfig[\"fetch\"],\n): typeof fetch {\n if (providedFetch) {\n return providedFetch;\n }\n\n if (typeof globalThis.fetch === \"function\") {\n return globalThis.fetch.bind(globalThis);\n }\n\n throw new InvalidConfigurationError(\n \"No fetch implementation is available. Provide config.fetch in this runtime.\",\n );\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n const trimmed = baseUrl.trim();\n\n if (!trimmed) {\n throw new InvalidConfigurationError(\"baseUrl must not be empty when provided.\");\n }\n\n try {\n return new URL(trimmed).toString().replace(/\\/+$/, \"\");\n } catch (cause) {\n throw new InvalidConfigurationError(\"baseUrl must be a valid absolute URL.\", {\n cause,\n });\n }\n}\n\nexport function resolveBaseUrl(\n environment: SereelEnvironment,\n baseUrl?: string,\n): string {\n if (baseUrl) {\n return normalizeBaseUrl(baseUrl);\n }\n\n return ENVIRONMENT_BASE_URLS[environment];\n}\n\nexport function resolveClientConfig(config: ClientConfig): ResolvedClientConfig {\n const apiKey = config.apiKey.trim();\n\n if (!apiKey) {\n throw new InvalidConfigurationError(\"apiKey must not be empty.\");\n }\n\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new InvalidConfigurationError(\"timeoutMs must be a positive number.\");\n }\n\n return {\n environment: config.environment,\n apiKey,\n timeoutMs,\n baseUrl: resolveBaseUrl(config.environment, config.baseUrl),\n fetch: getFetchImplementation(config.fetch),\n };\n}\n","import {\n HttpError,\n MalformedResponseError,\n NotFoundError,\n ServerError,\n TimeoutError,\n UnauthorizedError,\n} from \"./errors\";\nimport type { ResolvedClientConfig } from \"./config\";\n\ninterface ApiErrorBody {\n error?: string;\n message?: string;\n}\n\nfunction createTimeoutSignal(timeoutMs: number): {\n signal: AbortSignal;\n cleanup: () => void;\n} {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n return {\n signal: controller.signal,\n cleanup: () => clearTimeout(timeout),\n };\n}\n\nasync function parseBody(response: Response): Promise<unknown> {\n const text = await response.text();\n if (!text) {\n return null;\n }\n\n try {\n return JSON.parse(text) as unknown;\n } catch (cause) {\n throw new MalformedResponseError(\"Received a non-JSON response body.\", {\n cause,\n status: response.status,\n details: text,\n });\n }\n}\n\nfunction getErrorMessage(status: number, body: unknown): string {\n if (body && typeof body === \"object\") {\n const apiError = body as ApiErrorBody;\n if (typeof apiError.error === \"string\" && apiError.error.trim()) {\n return apiError.error;\n }\n if (typeof apiError.message === \"string\" && apiError.message.trim()) {\n return apiError.message;\n }\n }\n\n return `Request failed with status ${status}.`;\n}\n\nfunction toHttpError(status: number, body: unknown): HttpError {\n const message = getErrorMessage(status, body);\n const options = { status, details: body };\n\n if (status === 401) {\n return new UnauthorizedError(message, options);\n }\n if (status === 404) {\n return new NotFoundError(message, options);\n }\n if (status >= 500) {\n return new ServerError(message, options);\n }\n\n return new HttpError(message, options);\n}\n\nexport async function requestJson<T>(\n config: ResolvedClientConfig,\n path: string,\n validate: (value: unknown) => T,\n): Promise<T> {\n const { signal, cleanup } = createTimeoutSignal(config.timeoutMs);\n\n try {\n const response = await config.fetch(`${config.baseUrl}${path}`, {\n method: \"GET\",\n signal,\n headers: {\n accept: \"application/json\",\n \"x-api-key\": config.apiKey,\n },\n });\n\n const body = await parseBody(response);\n if (!response.ok) {\n throw toHttpError(response.status, body);\n }\n\n return validate(body);\n } catch (error) {\n if (error instanceof HttpError || error instanceof MalformedResponseError) {\n throw error;\n }\n\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new TimeoutError(\n `Request timed out after ${config.timeoutMs}ms.`,\n { cause: error },\n );\n }\n\n throw error;\n } finally {\n cleanup();\n }\n}\n","import { MalformedResponseError } from \"./errors\";\nimport type {\n NativeCurrency,\n NetworkDetails,\n SdkAssetRecord,\n SdkAssetResponse,\n SdkAssetsResponse,\n SdkBookSummary,\n SdkFundConfig,\n SdkIssuerSummary,\n SdkRuleEngineSummary,\n SdkRuleSummary,\n SdkSecurityDetails,\n SdkTokenPartner,\n SdkTokenProspectus,\n} from \"./types\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isString(value: unknown): value is string {\n return typeof value === \"string\";\n}\n\nfunction isNullableString(value: unknown): value is string | null {\n return typeof value === \"string\" || value === null;\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction isBoolean(value: unknown): value is boolean {\n return typeof value === \"boolean\";\n}\n\nfunction isProspectus(value: unknown): value is SdkTokenProspectus {\n return isRecord(value) && isString(value.name) && isString(value.url);\n}\n\nfunction isTokenPartner(value: unknown): value is SdkTokenPartner {\n return (\n isRecord(value) &&\n isString(value.partner_name) &&\n isString(value.partner_logo) &&\n isString(value.partner_role)\n );\n}\n\nfunction isRuleSummary(value: unknown): value is SdkRuleSummary {\n return (\n isRecord(value) &&\n isString(value.rule_address) &&\n isString(value.rule_type)\n );\n}\n\nfunction isRuleEngineSummary(value: unknown): value is SdkRuleEngineSummary {\n return (\n isRecord(value) &&\n isString(value.name) &&\n isString(value.rule_engine_address) &&\n Array.isArray(value.rules) &&\n (value.rules as unknown[]).every(isRuleSummary)\n );\n}\n\nfunction isSecurityDetails(value: unknown): value is SdkSecurityDetails {\n if (!isRecord(value)) return false;\n\n const hasRequiredStrings =\n isString(value.token_address) &&\n isString(value.token_name) &&\n isString(value.token_symbol) &&\n isString(value.token_decimal) &&\n isString(value.network_id) &&\n isString(value.token_type) &&\n isString(value.admin);\n\n if (!hasRequiredStrings) return false;\n\n if (!isNullableString(value.icon_url)) return false;\n if (!isNullableString(value.created_at)) return false;\n\n if (value.prospectus !== null && value.prospectus !== undefined) {\n if (!isProspectus(value.prospectus)) return false;\n }\n\n if (value.partners !== null && value.partners !== undefined) {\n if (\n !Array.isArray(value.partners) ||\n !(value.partners as unknown[]).every(isTokenPartner)\n )\n return false;\n }\n\n if (value.rule_engine !== null && value.rule_engine !== undefined) {\n if (!isRuleEngineSummary(value.rule_engine)) return false;\n }\n\n return true;\n}\n\nfunction isIssuerSummary(value: unknown): value is SdkIssuerSummary {\n return (\n isRecord(value) &&\n isString(value.id) &&\n isString(value.legal_name) &&\n isNullableString(value.display_name) &&\n isString(value.jurisdiction) &&\n isNullableString(value.website) &&\n isNullableString(value.logo_url)\n );\n}\n\nfunction isNativeCurrency(value: unknown): value is NativeCurrency {\n return (\n isRecord(value) &&\n isString(value.symbol) &&\n isString(value.name) &&\n isFiniteNumber(value.decimals)\n );\n}\n\nfunction isNetworkDetails(value: unknown): value is NetworkDetails {\n return (\n isRecord(value) &&\n isString(value.network_id) &&\n isString(value.name) &&\n isString(value.family) &&\n (isFiniteNumber(value.chain_id) || value.chain_id === null) &&\n isNativeCurrency(value.native_currency) &&\n isString(value.rpc_endpoint) &&\n Array.isArray(value.explorer_urls) &&\n (value.explorer_urls as unknown[]).every(isString) &&\n isBoolean(value.can_deploy_cmtat_token) &&\n isBoolean(value.can_deploy_trex_token) &&\n isBoolean(value.is_testnet) &&\n isBoolean(value.is_supported)\n );\n}\n\nfunction isFundConfig(value: unknown): value is SdkFundConfig {\n return (\n isRecord(value) &&\n isString(value.nav_staleness_threshold) &&\n isString(value.min_subscription) &&\n isString(value.min_redemption) &&\n isString(value.entry_fee_bps) &&\n isString(value.exit_fee_bps) &&\n isFiniteNumber(value.dealing_mode) &&\n isString(value.redemption_gate_bps) &&\n isString(value.protocol_subscription_fee_bps) &&\n isString(value.protocol_fee_recipient) &&\n isString(value.management_fee_bps_per_annum)\n );\n}\n\nfunction isBookSummary(value: unknown): value is SdkBookSummary {\n return (\n isRecord(value) &&\n isString(value.id) &&\n isString(value.order_book_address) &&\n isString(value.fund_address) &&\n isString(value.fund_id) &&\n isString(value.fund_token) &&\n isString(value.settlement_token) &&\n isString(value.owner_wallet) &&\n isString(value.manager_wallet) &&\n isString(value.initial_nav) &&\n isFundConfig(value.fund_config) &&\n isString(value.status) &&\n isString(value.network_id)\n );\n}\n\nfunction isAssetRecord(value: unknown): value is SdkAssetRecord {\n return (\n isRecord(value) &&\n isSecurityDetails(value.security) &&\n isIssuerSummary(value.issuer) &&\n Array.isArray(value.books) &&\n value.books.every(isBookSummary) &&\n isNetworkDetails(value.network)\n );\n}\n\nexport function validateSdkAssetsResponse(value: unknown): SdkAssetsResponse {\n if (\n !isRecord(value) ||\n !Array.isArray(value.data) ||\n !isFiniteNumber(value.count) ||\n !value.data.every(isAssetRecord)\n ) {\n throw new MalformedResponseError(\n \"Received an invalid SDK assets response shape.\",\n { details: value },\n );\n }\n\n return value as unknown as SdkAssetsResponse;\n}\n\nexport function validateSdkAssetResponse(value: unknown): SdkAssetResponse {\n if (!isRecord(value) || !isAssetRecord(value.data)) {\n throw new MalformedResponseError(\n \"Received an invalid SDK asset response shape.\",\n { details: value },\n );\n }\n\n return value as unknown as SdkAssetResponse;\n}\n","import { resolveClientConfig } from \"./config\";\nimport { InvalidConfigurationError } from \"./errors\";\nimport { requestJson } from \"./transport\";\nimport type {\n ClientConfig,\n SdkAssetResponse,\n SdkAssetsResponse,\n SereelSdkClient,\n} from \"./types\";\nimport {\n validateSdkAssetResponse,\n validateSdkAssetsResponse,\n} from \"./validation\";\n\nexport function createClient(config: ClientConfig): SereelSdkClient {\n const resolved = resolveClientConfig(config);\n\n return {\n getAssets(): Promise<SdkAssetsResponse> {\n return requestJson(resolved, \"/sdk/assets\", validateSdkAssetsResponse);\n },\n\n getAssetByTokenAddress(tokenAddress: string): Promise<SdkAssetResponse> {\n const trimmedTokenAddress = tokenAddress.trim();\n if (!trimmedTokenAddress) {\n throw new InvalidConfigurationError(\n \"tokenAddress must not be empty.\",\n );\n }\n\n return requestJson(\n resolved,\n `/sdk/assets/${encodeURIComponent(trimmedTokenAddress)}`,\n validateSdkAssetResponse,\n );\n },\n\n getAssetsByIssuer(issuerId: string): Promise<SdkAssetsResponse> {\n const trimmedIssuerId = issuerId.trim();\n if (!trimmedIssuerId) {\n throw new InvalidConfigurationError(\"issuerId must not be empty.\");\n }\n\n return requestJson(\n resolved,\n `/sdk/assets/issuer/${encodeURIComponent(trimmedIssuerId)}`,\n validateSdkAssetsResponse,\n );\n },\n };\n}\n"],"mappings":";AAOO,IAAM,iBAAN,cAA6B,MAAM;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAAiB,UAAiC,CAAC,GAAG;AAChE,UAAM,SAAS,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,MAAS;AACnE,SAAK,OAAO,WAAW;AACvB,SAAK,SAAS,QAAQ;AACtB,SAAK,OAAO,QAAQ;AACpB,SAAK,UAAU,QAAQ;AAAA,EACzB;AACF;AAEO,IAAM,4BAAN,cAAwC,eAAe;AAAC;AAExD,IAAM,YAAN,cAAwB,eAAe;AAAC;AAExC,IAAM,oBAAN,cAAgC,UAAU;AAAC;AAE3C,IAAM,gBAAN,cAA4B,UAAU;AAAC;AAEvC,IAAM,cAAN,cAA0B,UAAU;AAAC;AAErC,IAAM,eAAN,cAA2B,eAAe;AAAC;AAE3C,IAAM,yBAAN,cAAqC,eAAe;AAAC;;;AC9BrD,IAAM,wBAA2D;AAAA,EACtE,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AACX;AAUA,IAAM,qBAAqB;AAE3B,SAAS,uBACP,eACc;AACd,MAAI,eAAe;AACjB,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,WAAW,UAAU,YAAY;AAC1C,WAAO,WAAW,MAAM,KAAK,UAAU;AAAA,EACzC;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,SAAyB;AACjD,QAAM,UAAU,QAAQ,KAAK;AAE7B,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,0BAA0B,0CAA0C;AAAA,EAChF;AAEA,MAAI;AACF,WAAO,IAAI,IAAI,OAAO,EAAE,SAAS,EAAE,QAAQ,QAAQ,EAAE;AAAA,EACvD,SAAS,OAAO;AACd,UAAM,IAAI,0BAA0B,yCAAyC;AAAA,MAC3E;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,SAAS,eACd,aACA,SACQ;AACR,MAAI,SAAS;AACX,WAAO,iBAAiB,OAAO;AAAA,EACjC;AAEA,SAAO,sBAAsB,WAAW;AAC1C;AAEO,SAAS,oBAAoB,QAA4C;AAC9E,QAAM,SAAS,OAAO,OAAO,KAAK;AAElC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,0BAA0B,2BAA2B;AAAA,EACjE;AAEA,QAAM,YAAY,OAAO,aAAa;AACtC,MAAI,CAAC,OAAO,SAAS,SAAS,KAAK,aAAa,GAAG;AACjD,UAAM,IAAI,0BAA0B,sCAAsC;AAAA,EAC5E;AAEA,SAAO;AAAA,IACL,aAAa,OAAO;AAAA,IACpB;AAAA,IACA;AAAA,IACA,SAAS,eAAe,OAAO,aAAa,OAAO,OAAO;AAAA,IAC1D,OAAO,uBAAuB,OAAO,KAAK;AAAA,EAC5C;AACF;;;AClEA,SAAS,oBAAoB,WAG3B;AACA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,SAAS;AAE9D,SAAO;AAAA,IACL,QAAQ,WAAW;AAAA,IACnB,SAAS,MAAM,aAAa,OAAO;AAAA,EACrC;AACF;AAEA,eAAe,UAAU,UAAsC;AAC7D,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,SAAS,OAAO;AACd,UAAM,IAAI,uBAAuB,sCAAsC;AAAA,MACrE;AAAA,MACA,QAAQ,SAAS;AAAA,MACjB,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;AAEA,SAAS,gBAAgB,QAAgB,MAAuB;AAC9D,MAAI,QAAQ,OAAO,SAAS,UAAU;AACpC,UAAM,WAAW;AACjB,QAAI,OAAO,SAAS,UAAU,YAAY,SAAS,MAAM,KAAK,GAAG;AAC/D,aAAO,SAAS;AAAA,IAClB;AACA,QAAI,OAAO,SAAS,YAAY,YAAY,SAAS,QAAQ,KAAK,GAAG;AACnE,aAAO,SAAS;AAAA,IAClB;AAAA,EACF;AAEA,SAAO,8BAA8B,MAAM;AAC7C;AAEA,SAAS,YAAY,QAAgB,MAA0B;AAC7D,QAAM,UAAU,gBAAgB,QAAQ,IAAI;AAC5C,QAAM,UAAU,EAAE,QAAQ,SAAS,KAAK;AAExC,MAAI,WAAW,KAAK;AAClB,WAAO,IAAI,kBAAkB,SAAS,OAAO;AAAA,EAC/C;AACA,MAAI,WAAW,KAAK;AAClB,WAAO,IAAI,cAAc,SAAS,OAAO;AAAA,EAC3C;AACA,MAAI,UAAU,KAAK;AACjB,WAAO,IAAI,YAAY,SAAS,OAAO;AAAA,EACzC;AAEA,SAAO,IAAI,UAAU,SAAS,OAAO;AACvC;AAEA,eAAsB,YACpB,QACA,MACA,UACY;AACZ,QAAM,EAAE,QAAQ,QAAQ,IAAI,oBAAoB,OAAO,SAAS;AAEhE,MAAI;AACF,UAAM,WAAW,MAAM,OAAO,MAAM,GAAG,OAAO,OAAO,GAAG,IAAI,IAAI;AAAA,MAC9D,QAAQ;AAAA,MACR;AAAA,MACA,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,aAAa,OAAO;AAAA,MACtB;AAAA,IACF,CAAC;AAED,UAAM,OAAO,MAAM,UAAU,QAAQ;AACrC,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,SAAS,QAAQ,IAAI;AAAA,IACzC;AAEA,WAAO,SAAS,IAAI;AAAA,EACtB,SAAS,OAAO;AACd,QAAI,iBAAiB,aAAa,iBAAiB,wBAAwB;AACzE,YAAM;AAAA,IACR;AAEA,QAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,YAAM,IAAI;AAAA,QACR,2BAA2B,OAAO,SAAS;AAAA,QAC3C,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AAEA,UAAM;AAAA,EACR,UAAE;AACA,YAAQ;AAAA,EACV;AACF;;;AClGA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,SAAS,OAAiC;AACjD,SAAO,OAAO,UAAU;AAC1B;AAEA,SAAS,iBAAiB,OAAwC;AAChE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,eAAe,OAAiC;AACvD,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAC3D;AAEA,SAAS,UAAU,OAAkC;AACnD,SAAO,OAAO,UAAU;AAC1B;AAEA,SAAS,aAAa,OAA6C;AACjE,SAAO,SAAS,KAAK,KAAK,SAAS,MAAM,IAAI,KAAK,SAAS,MAAM,GAAG;AACtE;AAEA,SAAS,eAAe,OAA0C;AAChE,SACE,SAAS,KAAK,KACd,SAAS,MAAM,YAAY,KAC3B,SAAS,MAAM,YAAY,KAC3B,SAAS,MAAM,YAAY;AAE/B;AAEA,SAAS,cAAc,OAAyC;AAC9D,SACE,SAAS,KAAK,KACd,SAAS,MAAM,YAAY,KAC3B,SAAS,MAAM,SAAS;AAE5B;AAEA,SAAS,oBAAoB,OAA+C;AAC1E,SACE,SAAS,KAAK,KACd,SAAS,MAAM,IAAI,KACnB,SAAS,MAAM,mBAAmB,KAClC,MAAM,QAAQ,MAAM,KAAK,KACxB,MAAM,MAAoB,MAAM,aAAa;AAElD;AAEA,SAAS,kBAAkB,OAA6C;AACtE,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAE7B,QAAM,qBACJ,SAAS,MAAM,aAAa,KAC5B,SAAS,MAAM,UAAU,KACzB,SAAS,MAAM,YAAY,KAC3B,SAAS,MAAM,aAAa,KAC5B,SAAS,MAAM,UAAU,KACzB,SAAS,MAAM,UAAU,KACzB,SAAS,MAAM,KAAK;AAEtB,MAAI,CAAC,mBAAoB,QAAO;AAEhC,MAAI,CAAC,iBAAiB,MAAM,QAAQ,EAAG,QAAO;AAC9C,MAAI,CAAC,iBAAiB,MAAM,UAAU,EAAG,QAAO;AAEhD,MAAI,MAAM,eAAe,QAAQ,MAAM,eAAe,QAAW;AAC/D,QAAI,CAAC,aAAa,MAAM,UAAU,EAAG,QAAO;AAAA,EAC9C;AAEA,MAAI,MAAM,aAAa,QAAQ,MAAM,aAAa,QAAW;AAC3D,QACE,CAAC,MAAM,QAAQ,MAAM,QAAQ,KAC7B,CAAE,MAAM,SAAuB,MAAM,cAAc;AAEnD,aAAO;AAAA,EACX;AAEA,MAAI,MAAM,gBAAgB,QAAQ,MAAM,gBAAgB,QAAW;AACjE,QAAI,CAAC,oBAAoB,MAAM,WAAW,EAAG,QAAO;AAAA,EACtD;AAEA,SAAO;AACT;AAEA,SAAS,gBAAgB,OAA2C;AAClE,SACE,SAAS,KAAK,KACd,SAAS,MAAM,EAAE,KACjB,SAAS,MAAM,UAAU,KACzB,iBAAiB,MAAM,YAAY,KACnC,SAAS,MAAM,YAAY,KAC3B,iBAAiB,MAAM,OAAO,KAC9B,iBAAiB,MAAM,QAAQ;AAEnC;AAEA,SAAS,iBAAiB,OAAyC;AACjE,SACE,SAAS,KAAK,KACd,SAAS,MAAM,MAAM,KACrB,SAAS,MAAM,IAAI,KACnB,eAAe,MAAM,QAAQ;AAEjC;AAEA,SAAS,iBAAiB,OAAyC;AACjE,SACE,SAAS,KAAK,KACd,SAAS,MAAM,UAAU,KACzB,SAAS,MAAM,IAAI,KACnB,SAAS,MAAM,MAAM,MACpB,eAAe,MAAM,QAAQ,KAAK,MAAM,aAAa,SACtD,iBAAiB,MAAM,eAAe,KACtC,SAAS,MAAM,YAAY,KAC3B,MAAM,QAAQ,MAAM,aAAa,KAChC,MAAM,cAA4B,MAAM,QAAQ,KACjD,UAAU,MAAM,sBAAsB,KACtC,UAAU,MAAM,qBAAqB,KACrC,UAAU,MAAM,UAAU,KAC1B,UAAU,MAAM,YAAY;AAEhC;AAEA,SAAS,aAAa,OAAwC;AAC5D,SACE,SAAS,KAAK,KACd,SAAS,MAAM,uBAAuB,KACtC,SAAS,MAAM,gBAAgB,KAC/B,SAAS,MAAM,cAAc,KAC7B,SAAS,MAAM,aAAa,KAC5B,SAAS,MAAM,YAAY,KAC3B,eAAe,MAAM,YAAY,KACjC,SAAS,MAAM,mBAAmB,KAClC,SAAS,MAAM,6BAA6B,KAC5C,SAAS,MAAM,sBAAsB,KACrC,SAAS,MAAM,4BAA4B;AAE/C;AAEA,SAAS,cAAc,OAAyC;AAC9D,SACE,SAAS,KAAK,KACd,SAAS,MAAM,EAAE,KACjB,SAAS,MAAM,kBAAkB,KACjC,SAAS,MAAM,YAAY,KAC3B,SAAS,MAAM,OAAO,KACtB,SAAS,MAAM,UAAU,KACzB,SAAS,MAAM,gBAAgB,KAC/B,SAAS,MAAM,YAAY,KAC3B,SAAS,MAAM,cAAc,KAC7B,SAAS,MAAM,WAAW,KAC1B,aAAa,MAAM,WAAW,KAC9B,SAAS,MAAM,MAAM,KACrB,SAAS,MAAM,UAAU;AAE7B;AAEA,SAAS,cAAc,OAAyC;AAC9D,SACE,SAAS,KAAK,KACd,kBAAkB,MAAM,QAAQ,KAChC,gBAAgB,MAAM,MAAM,KAC5B,MAAM,QAAQ,MAAM,KAAK,KACzB,MAAM,MAAM,MAAM,aAAa,KAC/B,iBAAiB,MAAM,OAAO;AAElC;AAEO,SAAS,0BAA0B,OAAmC;AAC3E,MACE,CAAC,SAAS,KAAK,KACf,CAAC,MAAM,QAAQ,MAAM,IAAI,KACzB,CAAC,eAAe,MAAM,KAAK,KAC3B,CAAC,MAAM,KAAK,MAAM,aAAa,GAC/B;AACA,UAAM,IAAI;AAAA,MACR;AAAA,MACA,EAAE,SAAS,MAAM;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,yBAAyB,OAAkC;AACzE,MAAI,CAAC,SAAS,KAAK,KAAK,CAAC,cAAc,MAAM,IAAI,GAAG;AAClD,UAAM,IAAI;AAAA,MACR;AAAA,MACA,EAAE,SAAS,MAAM;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AACT;;;ACvMO,SAAS,aAAa,QAAuC;AAClE,QAAM,WAAW,oBAAoB,MAAM;AAE3C,SAAO;AAAA,IACL,YAAwC;AACtC,aAAO,YAAY,UAAU,eAAe,yBAAyB;AAAA,IACvE;AAAA,IAEA,uBAAuB,cAAiD;AACtE,YAAM,sBAAsB,aAAa,KAAK;AAC9C,UAAI,CAAC,qBAAqB;AACxB,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL;AAAA,QACA,eAAe,mBAAmB,mBAAmB,CAAC;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AAAA,IAEA,kBAAkB,UAA8C;AAC9D,YAAM,kBAAkB,SAAS,KAAK;AACtC,UAAI,CAAC,iBAAiB;AACpB,cAAM,IAAI,0BAA0B,6BAA6B;AAAA,MACnE;AAEA,aAAO;AAAA,QACL;AAAA,QACA,sBAAsB,mBAAmB,eAAe,CAAC;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sereel/sdk",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "TypeScript SDK for Sereel asset read endpoints",
5
5
  "license": "MIT",
6
6
  "type": "module",