@olympex-io/olympex-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,824 @@
1
+ /**
2
+ * Severity levels for SDK log calls, ordered debug < info < warn < error.
3
+ *
4
+ * @remarks Used by {@link OlympexLogger} and {@link createConsoleLogger} to filter output.
5
+ *
6
+ * @see docs/logging.md
7
+ */
8
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
9
+ /**
10
+ * Caller-provided logging surface. The SDK calls `log` at transport and
11
+ * method boundaries when a logger is wired at {@link InitializeOptions.logger}.
12
+ *
13
+ * @remarks Implementations MUST NOT throw — use {@link createConsoleLogger} for a safe default.
14
+ * When no logger is provided, the SDK emits no log output (silent-by-default).
15
+ *
16
+ * @see docs/logging.md
17
+ */
18
+ interface OlympexLogger {
19
+ log(level: LogLevel, message: string, metadata?: Record<string, unknown>): void;
20
+ }
21
+ /**
22
+ * Configuration passed to {@link initialize} to create an {@link OlympexClient}.
23
+ *
24
+ * @remarks Server-side only. Keep `apiSecret` and `passphrase` in trusted backend runtimes
25
+ * (BFF, server, or serverless functions) and never expose them in browser bundles.
26
+ * Optional fee defaults in `defaultFees` are forwarded to the backend; the SDK does not calculate
27
+ * fee amounts locally.
28
+ *
29
+ * @property apiKey - API key for request authentication.
30
+ * @property apiSecret - Signing secret used for GraphQL requests.
31
+ * @property passphrase - Account passphrase validated during authentication.
32
+ * @property defaultFees - Optional client-level {@link FeeOptions} applied to all quote/swap calls.
33
+ * @property logger - Optional {@link OlympexLogger}; omitted means silent-by-default.
34
+ *
35
+ * @see docs/getting-started.md
36
+ * @see docs/authentication.md
37
+ */
38
+ interface InitializeOptions {
39
+ apiKey: string;
40
+ apiSecret: string;
41
+ passphrase: string;
42
+ defaultFees?: FeeOptions;
43
+ headers?: Record<string, string>;
44
+ /** Optional logger; when omitted the SDK emits no log output (silent-by-default). */
45
+ logger?: OlympexLogger;
46
+ timeoutMs?: number;
47
+ }
48
+ /**
49
+ * Public SDK client bound to an API key.
50
+ *
51
+ * @remarks Returned by {@link initialize}. All methods forward parameters to the backend GraphQL API.
52
+ * The SDK does not compute routes, fees, or swap calldata locally. Backend routing is resolved from
53
+ * `OLYMPEX_BACKEND_URL` at call time (see docs/getting-started.md).
54
+ *
55
+ * @property apiKey - Authenticated API key (read-only).
56
+ *
57
+ * @see docs/getting-started.md
58
+ */
59
+ interface OlympexClient {
60
+ readonly apiKey: string;
61
+ /**
62
+ * Creates API credentials via REST onboarding.
63
+ *
64
+ * @remarks Uses the backend base URL resolved from `OLYMPEX_BACKEND_URL`. For static usage
65
+ * without initializing the SDK client, use the top-level `createAccount` export with
66
+ * {@link CreateAccountOptions}.
67
+ * @param input - Required onboarding fields.
68
+ * @returns Freshly created credentials ({@link CreateAccountResponse}).
69
+ * @throws {OlympexConfigError} When `name` or `password` is empty.
70
+ * @throws {OlympexNetworkError} When REST onboarding fails, returns invalid JSON, or omits credentials.
71
+ *
72
+ * @see docs/authentication.md
73
+ */
74
+ createAccount(input: CreateAccountInput): Promise<CreateAccountResponse>;
75
+ /**
76
+ * Returns the SDK package version string.
77
+ *
78
+ * @remarks Delegates to the standalone {@link getVersion} export.
79
+ * @returns Semantic version of the installed SDK (e.g. `'0.0.0'`).
80
+ *
81
+ * @see docs/getting-started.md
82
+ */
83
+ getVersion(): string;
84
+ /**
85
+ * Fetches a swap quote for single-chain or cross-chain routes.
86
+ *
87
+ * @remarks Forwards params unchanged to the backend. Does not compute routes or fees locally.
88
+ * Per-request {@link FeeOptions} in `input.fees` override {@link InitializeOptions.defaultFees}.
89
+ * @param input - Discriminated by {@link QuoteRequest.mode | mode}.
90
+ * @returns {@link QuoteResult} normalized for the selected mode.
91
+ * @throws {OlympexConfigError} Local validation failure (e.g. invalid {@link FeeOptions.feeBps}).
92
+ * @throws {OlympexDomainError} Backend `success: false` domain response.
93
+ * @throws {OlympexGraphQLError} GraphQL errors in an otherwise successful HTTP response.
94
+ * @throws {OlympexNetworkError} Network, timeout, or non-2xx HTTP failure.
95
+ *
96
+ * @example Single-chain quote with fee options
97
+ * ```ts
98
+ * const result = await client.quote({
99
+ * mode: 'single-chain',
100
+ * params: {
101
+ * chainId: 1,
102
+ * inTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
103
+ * outTokenAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
104
+ * amount: '1000000',
105
+ * slippage: '0.5',
106
+ * gasPrice: '20000000000',
107
+ * },
108
+ * fees: { feeBps: 25, feeRecipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb' },
109
+ * });
110
+ * ```
111
+ *
112
+ * @example Cross-chain bridge quote
113
+ * ```ts
114
+ * const result = await client.quote({
115
+ * mode: 'cross-chain',
116
+ * params: {
117
+ * fromTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
118
+ * toTokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
119
+ * fromChainId: 1,
120
+ * toChainId: 42161,
121
+ * amount: '1000000',
122
+ * slippage: '0.5',
123
+ * },
124
+ * });
125
+ * ```
126
+ *
127
+ * @see docs/methods/quote.md
128
+ */
129
+ quote(input: QuoteRequest): Promise<QuoteResult>;
130
+ /**
131
+ * Checks whether a chain ID is supported by the backend.
132
+ *
133
+ * @remarks Chain enablement is backend-authoritative; the SDK forwards the query unchanged.
134
+ * Use before {@link OlympexClient.quote} or {@link OlympexClient.swap} to validate `chainId`.
135
+ * @param chainId - EVM chain ID as number or string.
136
+ * @returns `true` when the chain is enabled for quotes and swaps.
137
+ * @throws {OlympexDomainError} Backend domain failure on unsupported or invalid chain.
138
+ * @throws {OlympexGraphQLError} GraphQL errors in an otherwise successful HTTP response.
139
+ * @throws {OlympexNetworkError} Network, timeout, or non-2xx HTTP failure.
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const supported = await client.supportChain(42161);
144
+ * if (!supported) {
145
+ * throw new Error('Arbitrum not enabled for this account');
146
+ * }
147
+ * ```
148
+ *
149
+ * @see docs/methods/support-chain.md
150
+ */
151
+ supportChain(chainId: string | number): Promise<boolean>;
152
+ /**
153
+ * Builds swap calldata from a prior quote's `aggregatorId`.
154
+ *
155
+ * @remarks Forwards params unchanged to the backend. Does not compute swap data locally.
156
+ * @param input - Discriminated by {@link SwapRequest.mode | mode}.
157
+ * @returns {@link SwapResult} with executable calldata for the selected mode.
158
+ * @throws {OlympexConfigError} Local validation failure (e.g. invalid {@link FeeOptions.feeBps}).
159
+ * @throws {OlympexDomainError} Backend `success: false` domain response.
160
+ * @throws {OlympexGraphQLError} GraphQL errors in an otherwise successful HTTP response.
161
+ * @throws {OlympexNetworkError} Network, timeout, or non-2xx HTTP failure.
162
+ *
163
+ * @example Single-chain swap
164
+ * ```ts
165
+ * const { swap } = await client.swap({
166
+ * mode: 'single-chain',
167
+ * params: {
168
+ * chainId: 1,
169
+ * inTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
170
+ * outTokenAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
171
+ * amount: '1000000',
172
+ * slippage: '0.5',
173
+ * gasPrice: '20000000000',
174
+ * account: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
175
+ * aggregatorId: quote.quote.aggregatorId,
176
+ * },
177
+ * });
178
+ * ```
179
+ *
180
+ * @example Cross-chain swap
181
+ * ```ts
182
+ * const { swap } = await client.swap({
183
+ * mode: 'cross-chain',
184
+ * params: {
185
+ * account: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
186
+ * fromChainId: 1,
187
+ * toChainId: 42161,
188
+ * inTokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
189
+ * outTokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
190
+ * amount: '1000000',
191
+ * slippage: '0.5',
192
+ * aggregatorId: quote.quote.aggregatorId,
193
+ * },
194
+ * });
195
+ * ```
196
+ *
197
+ * @see docs/methods/swap.md
198
+ */
199
+ swap(input: SwapRequest): Promise<SwapResult>;
200
+ /**
201
+ * Polls cross-chain transaction status after a cross-chain swap.
202
+ *
203
+ * @remarks Requires `hash`, `chainId`, and `dexHash` from the originating cross-chain swap.
204
+ * @param input - Transaction identifiers from {@link CrossChainSwap.dexHash} and related fields.
205
+ * @returns Current bridge status and chain pair metadata.
206
+ * @throws {OlympexDomainError} Backend domain failure or invalid status payload.
207
+ * @throws {OlympexGraphQLError} GraphQL errors in an otherwise successful HTTP response.
208
+ * @throws {OlympexNetworkError} Network, timeout, or non-2xx HTTP failure.
209
+ *
210
+ * @example
211
+ * ```ts
212
+ * const status = await client.txStatus({
213
+ * hash: '0xabc...',
214
+ * chainId: '1',
215
+ * dexHash: swap.dexHash,
216
+ * });
217
+ * console.log(status.status, status.detailStatus);
218
+ * ```
219
+ *
220
+ * @see docs/methods/tx-status.md
221
+ */
222
+ txStatus(input: TxStatusInput): Promise<TxStatus>;
223
+ }
224
+ /**
225
+ * Input for {@link OlympexClient.createAccount}.
226
+ *
227
+ * @remarks Use the top-level `createAccount` export with {@link CreateAccountOptions} when you
228
+ * need onboarding without calling {@link initialize}.
229
+ *
230
+ * @property name - Human-readable account display name.
231
+ * @property password - Passphrase/password used for account authentication.
232
+ *
233
+ * @see docs/authentication.md
234
+ */
235
+ interface CreateAccountInput {
236
+ readonly name: string;
237
+ readonly password: string;
238
+ }
239
+ /**
240
+ * Input for static onboarding via top-level `createAccount` export.
241
+ *
242
+ * @remarks This shape is server-side only and does not require {@link initialize}.
243
+ *
244
+ * @property name - Human-readable account display name.
245
+ * @property password - Passphrase/password used for account authentication.
246
+ *
247
+ * @see docs/authentication.md
248
+ */
249
+ type CreateAccountOptions = CreateAccountInput;
250
+ /**
251
+ * Response payload from account onboarding.
252
+ *
253
+ * @remarks `secretKey` is returned once by onboarding flows. Store it securely.
254
+ *
255
+ * @property apiKey - API key identifier ({@link InitializeOptions.apiKey}).
256
+ * @property secretKey - Signing secret ({@link InitializeOptions.apiSecret}).
257
+ *
258
+ * @see docs/authentication.md
259
+ */
260
+ interface CreateAccountResponse {
261
+ readonly apiKey: string;
262
+ readonly secretKey: string;
263
+ }
264
+ /**
265
+ * Gas urgency preset forwarded to the {@link OlympexClient.quote} backend.
266
+ *
267
+ * @remarks Maps to backend gas estimation multipliers; does not affect local SDK behavior.
268
+ *
269
+ * @see docs/methods/quote.md
270
+ */
271
+ type GasMultiplier = 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH';
272
+ /**
273
+ * Sort order for quote route ranking on the {@link OlympexClient.quote} backend.
274
+ *
275
+ * @remarks The SDK forwards this value unchanged; route selection is backend-authoritative.
276
+ *
277
+ * @see docs/methods/quote.md
278
+ */
279
+ type QuoteOrderBy = 'MAX_OUT_AMOUNT' | 'MAX_ESTIMATE_GAS' | 'MIN_ESTIMATE_GAS';
280
+ /**
281
+ * Fee options forwarded to the backend on {@link OlympexClient.quote} and
282
+ * {@link OlympexClient.swap} calls.
283
+ *
284
+ * @remarks The SDK does not calculate fee amounts. Values are validated locally then
285
+ * serialized to the backend, which is authoritative for final fee application.
286
+ *
287
+ * @property feeBps - Optional margin in basis points (0–100). Backend is authoritative.
288
+ * @property feeRecipient - EVM address that receives the fee portion.
289
+ *
290
+ * @example Per-request fees and client-level defaults
291
+ * ```ts
292
+ * const client = initialize({
293
+ * apiKey: '...',
294
+ * apiSecret: '...',
295
+ * passphrase: '...',
296
+ * defaultFees: { feeBps: 10, feeRecipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb' },
297
+ * });
298
+ *
299
+ * // Per-request override:
300
+ * await client.quote({
301
+ * mode: 'single-chain',
302
+ * params: { ... },
303
+ * fees: { feeBps: 25 },
304
+ * });
305
+ * ```
306
+ *
307
+ * @see docs/fees.md
308
+ */
309
+ interface FeeOptions {
310
+ readonly feeBps?: number;
311
+ readonly feeRecipient?: string;
312
+ }
313
+ /**
314
+ * Single-chain quote parameters for one EVM network.
315
+ *
316
+ * @remarks Passed to {@link OlympexClient.quote} with `mode: 'single-chain'`.
317
+ *
318
+ * @property mode - Discriminator; must be `'single-chain'`.
319
+ * @property params - Token, amount, and slippage fields for the source chain.
320
+ * @property fees - Optional per-request {@link FeeOptions} override.
321
+ *
322
+ * @see docs/methods/quote.md
323
+ */
324
+ interface SingleChainQuoteInput {
325
+ readonly mode: 'single-chain';
326
+ readonly params: {
327
+ readonly chainId: number;
328
+ readonly inTokenAddress: string;
329
+ readonly outTokenAddress: string;
330
+ readonly amount: string;
331
+ readonly slippage: string;
332
+ readonly gasPrice: string;
333
+ readonly excludeMetaAggregatorId?: readonly string[];
334
+ readonly includeGasInfo?: boolean;
335
+ readonly orderBy?: QuoteOrderBy;
336
+ readonly gasMultiplier?: GasMultiplier;
337
+ };
338
+ readonly fees?: FeeOptions;
339
+ }
340
+ /**
341
+ * Cross-chain quote parameters spanning two EVM networks.
342
+ *
343
+ * @remarks Passed to {@link OlympexClient.quote} with `mode: 'cross-chain'`.
344
+ *
345
+ * @property mode - Discriminator; must be `'cross-chain'`.
346
+ * @property params - Source and destination chain/token fields for the bridge quote.
347
+ * @property fees - Optional per-request {@link FeeOptions} override.
348
+ *
349
+ * @see docs/methods/quote.md
350
+ */
351
+ interface CrossChainQuoteInput {
352
+ readonly mode: 'cross-chain';
353
+ readonly params: {
354
+ readonly fromTokenAddress: string;
355
+ readonly toTokenAddress: string;
356
+ readonly fromChainId: number;
357
+ readonly toChainId: number;
358
+ readonly amount: string;
359
+ readonly slippage: string;
360
+ };
361
+ readonly fees?: FeeOptions;
362
+ }
363
+ /**
364
+ * Quote request discriminated by {@link SingleChainQuoteInput.mode | mode}.
365
+ *
366
+ * @remarks Use `mode: 'single-chain'` for on-chain swaps on one network;
367
+ * `mode: 'cross-chain'` for bridge/cross-chain quotes. Passed to {@link OlympexClient.quote}.
368
+ *
369
+ * @see docs/methods/quote.md
370
+ */
371
+ type QuoteRequest = SingleChainQuoteInput | CrossChainQuoteInput;
372
+ /**
373
+ * Single-chain swap parameters for one EVM network.
374
+ *
375
+ * @remarks Passed to {@link OlympexClient.swap} with `mode: 'single-chain'`.
376
+ *
377
+ * @property mode - Discriminator; must be `'single-chain'`.
378
+ * @property params - Token, account, and `aggregatorId` from a prior {@link SingleChainQuote}.
379
+ * @property fees - Optional per-request {@link FeeOptions} override.
380
+ *
381
+ * @see docs/methods/swap.md
382
+ */
383
+ interface SingleChainSwapInput {
384
+ readonly mode: 'single-chain';
385
+ readonly params: {
386
+ readonly chainId: number;
387
+ readonly inTokenAddress: string;
388
+ readonly outTokenAddress: string;
389
+ readonly amount: string;
390
+ readonly slippage: string;
391
+ readonly gasPrice: string;
392
+ readonly account: string;
393
+ readonly aggregatorId: string;
394
+ };
395
+ readonly fees?: FeeOptions;
396
+ }
397
+ /**
398
+ * Cross-chain swap parameters spanning two EVM networks.
399
+ *
400
+ * @remarks Passed to {@link OlympexClient.swap} with `mode: 'cross-chain'`.
401
+ *
402
+ * @property mode - Discriminator; must be `'cross-chain'`.
403
+ * @property params - Bridge tokens, account, and `aggregatorId` from a prior {@link CrossChainQuote}.
404
+ * @property fees - Optional per-request {@link FeeOptions} override.
405
+ *
406
+ * @see docs/methods/swap.md
407
+ */
408
+ interface CrossChainSwapInput {
409
+ readonly mode: 'cross-chain';
410
+ readonly params: {
411
+ readonly account: string;
412
+ readonly fromChainId: number;
413
+ readonly toChainId: number;
414
+ readonly inTokenAddress: string;
415
+ readonly outTokenAddress: string;
416
+ readonly amount: string;
417
+ readonly slippage: string;
418
+ readonly aggregatorId: string;
419
+ };
420
+ readonly fees?: FeeOptions;
421
+ }
422
+ /**
423
+ * Swap request discriminated by {@link SingleChainSwapInput.mode | mode}.
424
+ *
425
+ * @remarks Use `mode: 'single-chain'` for on-chain execution; `mode: 'cross-chain'` for bridge swaps.
426
+ * `aggregatorId` must come from a matching prior {@link OlympexClient.quote} result.
427
+ *
428
+ * @see docs/methods/swap.md
429
+ */
430
+ type SwapRequest = SingleChainSwapInput | CrossChainSwapInput;
431
+ /**
432
+ * Quote response discriminated by `mode` — matches the originating {@link QuoteRequest}.
433
+ *
434
+ * @remarks Branch on `result.mode` to access mode-specific quote fields from
435
+ * {@link SingleChainQuote} or {@link CrossChainQuote}.
436
+ *
437
+ * @example
438
+ * ```ts
439
+ * const result = await client.quote({ mode: 'single-chain', params: { ... } });
440
+ *
441
+ * if (result.mode === 'single-chain') {
442
+ * console.log(result.quote.outAmount, result.quote.aggregatorId);
443
+ * } else {
444
+ * console.log(result.quote.toTokenAmount, result.quote.estimatedTime);
445
+ * }
446
+ * ```
447
+ *
448
+ * @see docs/methods/quote.md
449
+ */
450
+ type QuoteResult = {
451
+ readonly mode: 'single-chain';
452
+ readonly quote: SingleChainQuote;
453
+ } | {
454
+ readonly mode: 'cross-chain';
455
+ readonly quote: CrossChainQuote;
456
+ };
457
+ /**
458
+ * Swap response discriminated by `mode` — matches the originating {@link SwapRequest}.
459
+ *
460
+ * @remarks Branch on `result.mode` to access {@link SingleChainSwap} calldata or
461
+ * {@link CrossChainSwap} bridge data.
462
+ *
463
+ * @see docs/methods/swap.md
464
+ */
465
+ type SwapResult = {
466
+ readonly mode: 'single-chain';
467
+ readonly swap: SingleChainSwap;
468
+ } | {
469
+ readonly mode: 'cross-chain';
470
+ readonly swap: CrossChainSwap;
471
+ };
472
+ /**
473
+ * Single-chain quote payload from the backend aggregator.
474
+ *
475
+ * @remarks Nested under {@link QuoteResult} when `mode` is `'single-chain'`.
476
+ *
477
+ * @property outAmount - Estimated output token amount.
478
+ * @property aggregatorId - Backend route identifier; required for {@link OlympexClient.swap}.
479
+ * @property routes - Route splits returned by the aggregator.
480
+ *
481
+ * @see docs/methods/quote.md
482
+ */
483
+ interface SingleChainQuote {
484
+ readonly outAmount: string;
485
+ readonly estimatedGas?: string | null;
486
+ readonly aggregatorId: string;
487
+ readonly aggregatorOrder?: readonly string[] | null;
488
+ readonly market?: readonly QuoteMarket[] | null;
489
+ readonly routes: readonly QuoteRoute[];
490
+ readonly dataFeeTransaction?: DataFeeTransaction | null;
491
+ readonly gasMultiplier?: string | null;
492
+ }
493
+ /** DEX market slice in a single-chain quote response (field details may change pre-beta). */
494
+ interface QuoteMarket {
495
+ readonly dexName?: string | null;
496
+ readonly swapAmount?: string | null;
497
+ readonly dexImageURL?: string | null;
498
+ }
499
+ /** Route split with percentage allocation in a single-chain quote. */
500
+ interface QuoteRoute {
501
+ readonly percentage: number;
502
+ readonly subRoutes: readonly QuoteSubRoute[];
503
+ }
504
+ /** Sub-route segment within a {@link QuoteRoute}. */
505
+ interface QuoteSubRoute {
506
+ readonly from: string;
507
+ readonly to: string;
508
+ readonly dexes: readonly QuoteDex[];
509
+ }
510
+ /** DEX entry within a {@link QuoteSubRoute}. */
511
+ interface QuoteDex {
512
+ readonly name?: string | null;
513
+ readonly percentage?: number | null;
514
+ }
515
+ /** Fee and gas metadata attached to a single-chain quote. */
516
+ interface DataFeeTransaction {
517
+ readonly effectiveGasPrice?: string | null;
518
+ readonly nativePrice?: string | null;
519
+ readonly transactionFee?: string | null;
520
+ readonly transactionFeeInUSD?: string | null;
521
+ readonly tokenPrice?: string | null;
522
+ readonly transactionFeeInTokenIn?: string | null;
523
+ readonly valueToApprove?: string | null;
524
+ }
525
+ /**
526
+ * Single-chain swap calldata and approval data from the backend.
527
+ *
528
+ * @remarks Nested under {@link SwapResult} when `mode` is `'single-chain'`.
529
+ *
530
+ * @property data - Encoded swap calldata for the wallet transaction.
531
+ * @property minOutAmount - Minimum output amount after slippage.
532
+ * @property outAmount - Expected output amount.
533
+ * @property approveTransaction - ERC-20 approval calldata when required.
534
+ *
535
+ * @see docs/methods/swap.md
536
+ */
537
+ interface SingleChainSwap {
538
+ readonly data: string;
539
+ readonly estimatedGas?: string | null;
540
+ readonly minOutAmount: string;
541
+ readonly outAmount: string;
542
+ readonly value: string;
543
+ readonly approveTransaction: string;
544
+ }
545
+ /**
546
+ * Cross-chain quote payload including bridge cost and timing estimates.
547
+ *
548
+ * @remarks Nested under {@link QuoteResult} when `mode` is `'cross-chain'`.
549
+ *
550
+ * @property aggregatorId - Backend bridge route identifier; required for {@link OlympexClient.swap}.
551
+ * @property fromTokenAmount - Source-chain input amount.
552
+ * @property toTokenAmount - Destination-chain estimated output.
553
+ * @property estimateCostInUSD - Estimated bridge cost in USD.
554
+ *
555
+ * @see docs/methods/quote.md
556
+ */
557
+ interface CrossChainQuote {
558
+ readonly aggregatorId: string;
559
+ readonly estimatedGas?: string | null;
560
+ readonly estimatedTime?: string | null;
561
+ readonly estimateCostInUSD: string;
562
+ readonly fromTokenAmount: string;
563
+ readonly toTokenAmount: string;
564
+ readonly minimumReceived: string;
565
+ readonly bridgeInfo: {
566
+ readonly icon?: string | null;
567
+ readonly displayName?: string | null;
568
+ };
569
+ readonly middlewareRoute?: {
570
+ readonly chainFrom?: readonly CrossChainRouteAssetPair[] | null;
571
+ readonly chainTo?: readonly CrossChainRouteAssetPair[] | null;
572
+ } | null;
573
+ }
574
+ /** Asset pair in a cross-chain middleware route. */
575
+ interface CrossChainRouteAssetPair {
576
+ readonly fromAsset?: CrossChainRouteAsset | null;
577
+ readonly toAsset?: CrossChainRouteAsset | null;
578
+ }
579
+ /** Token asset reference in a cross-chain route. */
580
+ interface CrossChainRouteAsset {
581
+ readonly address?: string | null;
582
+ readonly decimals?: number | null;
583
+ readonly symbol?: string | null;
584
+ }
585
+ /**
586
+ * Cross-chain swap calldata including bridge transaction hash.
587
+ *
588
+ * @remarks Nested under {@link SwapResult} when `mode` is `'cross-chain'`.
589
+ * Use {@link CrossChainSwap.dexHash} with {@link OlympexClient.txStatus}.
590
+ *
591
+ * @property calldata - Encoded bridge swap calldata.
592
+ * @property dexHash - Bridge transaction identifier for status polling.
593
+ * @property approveTransaction - ERC-20 approval calldata when required.
594
+ *
595
+ * @see docs/methods/swap.md
596
+ */
597
+ interface CrossChainSwap {
598
+ readonly calldata: string;
599
+ readonly value: string;
600
+ readonly approveTransaction: string;
601
+ readonly dexHash: string;
602
+ }
603
+ /**
604
+ * Input for {@link OlympexClient.txStatus} cross-chain status polling.
605
+ *
606
+ * @property hash - Source-chain transaction hash.
607
+ * @property chainId - Source chain ID as string.
608
+ * @property dexHash - Bridge identifier from {@link CrossChainSwap.dexHash}.
609
+ *
610
+ * @see docs/methods/tx-status.md
611
+ */
612
+ interface TxStatusInput {
613
+ readonly hash: string;
614
+ readonly chainId: string;
615
+ readonly dexHash: string;
616
+ }
617
+ /**
618
+ * Cross-chain transaction status returned by the backend.
619
+ *
620
+ * @remarks Poll via {@link OlympexClient.txStatus} after a {@link CrossChainSwap} until
621
+ * `status` reaches a terminal state.
622
+ *
623
+ * @property toChainId - Destination chain ID.
624
+ * @property fromChainId - Source chain ID.
625
+ * @property detailStatus - Granular bridge status from the backend.
626
+ * @property status - High-level bridge status.
627
+ *
628
+ * @see docs/methods/tx-status.md
629
+ */
630
+ interface TxStatus {
631
+ readonly toChainId: string;
632
+ readonly fromChainId: string;
633
+ readonly detailStatus: string;
634
+ readonly status: string;
635
+ }
636
+
637
+ /**
638
+ * Creates an {@link OlympexClient} bound to an API key.
639
+ *
640
+ * @remarks Logging is silent-by-default unless {@link InitializeOptions.logger} is provided.
641
+ * Fee defaults in `defaultFees` are validated locally then forwarded to the backend.
642
+ * Backend routing is resolved from `OLYMPEX_BACKEND_URL` at call time.
643
+ * @param options - {@link InitializeOptions} configuration.
644
+ * @returns Configured {@link OlympexClient} ready for quote, swap, and status calls.
645
+ * @throws {OlympexConfigError} When auth credentials are empty, `OLYMPEX_BACKEND_URL` is invalid, or `defaultFees` fail validation.
646
+ *
647
+ * @example Minimal bootstrap
648
+ * ```ts
649
+ * import { initialize } from '@olympex-io/olympex-sdk';
650
+ *
651
+ * const client = initialize({
652
+ * apiKey: process.env.OLYMPEX_API_KEY!,
653
+ * apiSecret: process.env.OLYMPEX_API_SECRET!,
654
+ * passphrase: process.env.OLYMPEX_PASSPHRASE!,
655
+ * });
656
+ * ```
657
+ *
658
+ * @example With opt-in console logging
659
+ * ```ts
660
+ * import { initialize, createConsoleLogger } from '@olympex-io/olympex-sdk';
661
+ *
662
+ * const client = initialize({
663
+ * apiKey: process.env.OLYMPEX_API_KEY!,
664
+ * apiSecret: process.env.OLYMPEX_API_SECRET!,
665
+ * passphrase: process.env.OLYMPEX_PASSPHRASE!,
666
+ * logger: createConsoleLogger({ minLevel: 'debug' }),
667
+ * });
668
+ * ```
669
+ *
670
+ * @see docs/getting-started.md
671
+ */
672
+ declare function initialize(options: InitializeOptions): OlympexClient;
673
+
674
+ /**
675
+ * Options for {@link createConsoleLogger}.
676
+ *
677
+ * @property minLevel - Minimum {@link LogLevel} to emit; defaults to `'info'`.
678
+ */
679
+ interface CreateConsoleLoggerOptions {
680
+ readonly minLevel?: LogLevel;
681
+ }
682
+ /**
683
+ * Returns a safe {@link OlympexLogger} that writes to `console` at the configured minimum level.
684
+ *
685
+ * @remarks Implementations never throw. Messages below `minLevel` are filtered out.
686
+ * @param options - Optional {@link CreateConsoleLoggerOptions}; `minLevel` defaults to `'info'`.
687
+ * @returns Frozen {@link OlympexLogger} suitable for {@link InitializeOptions.logger}.
688
+ *
689
+ * @example
690
+ * ```ts
691
+ * import { createConsoleLogger } from '@olympex-io/olympex-sdk';
692
+ *
693
+ * const logger = createConsoleLogger({ minLevel: 'warn' });
694
+ * logger.log('info', 'filtered out');
695
+ * logger.log('warn', 'visible', { requestId: 'abc' });
696
+ * ```
697
+ *
698
+ * @see docs/logging.md
699
+ */
700
+ declare function createConsoleLogger(options?: CreateConsoleLoggerOptions): OlympexLogger;
701
+
702
+ /**
703
+ * Returns the SDK package version string (standalone export).
704
+ *
705
+ * @remarks Prefer {@link OlympexClient.getVersion} on an initialized client for the same value.
706
+ * @returns Semantic version of the installed SDK (e.g. `'0.0.0'`).
707
+ *
708
+ * @see docs/getting-started.md
709
+ */
710
+ declare function getVersion(): string;
711
+
712
+ /**
713
+ * Creates API credentials via public REST onboarding.
714
+ *
715
+ * @remarks Server-side only. Does not require {@link initialize}. Store returned `secretKey`
716
+ * securely; it is shown once by the backend. Backend routing is resolved from
717
+ * `OLYMPEX_BACKEND_URL` at call time.
718
+ * @param options - {@link CreateAccountOptions} with onboarding fields.
719
+ * @returns Fresh {@link CreateAccountResponse} credentials for subsequent {@link initialize}.
720
+ * @throws {OlympexConfigError} When `name` or `password` is empty, or `OLYMPEX_BACKEND_URL` is invalid.
721
+ * @throws {OlympexNetworkError} When REST onboarding fails or omits credentials.
722
+ *
723
+ * @see docs/authentication.md
724
+ */
725
+ declare function createAccount({ name, password, }: CreateAccountOptions): Promise<CreateAccountResponse>;
726
+
727
+ /**
728
+ * Base error for all SDK-thrown failures. Subclasses map to specific failure modes.
729
+ *
730
+ * @remarks Every SDK error exposes a stable `code` string and optional `metadata`.
731
+ * Catch by `instanceof` or compare `error.code` for transport-agnostic handling.
732
+ * See {@link OlympexConfigError}, {@link OlympexDomainError}, {@link OlympexGraphQLError},
733
+ * {@link OlympexNetworkError}, and {@link OlympexNotImplementedError}.
734
+ *
735
+ * @example
736
+ * ```ts
737
+ * import {
738
+ * OlympexSdkError,
739
+ * OlympexConfigError,
740
+ * OlympexDomainError,
741
+ * } from '@olympex-io/olympex-sdk';
742
+ *
743
+ * try {
744
+ * await client.quote({ mode: 'single-chain', params: { ... } });
745
+ * } catch (error) {
746
+ * if (error instanceof OlympexConfigError) {
747
+ * console.error('Invalid input:', error.code, error.message);
748
+ * } else if (error instanceof OlympexDomainError) {
749
+ * console.error('Backend rejected:', error.code, error.metadata);
750
+ * } else if (error instanceof OlympexSdkError) {
751
+ * console.error('SDK error:', error.code);
752
+ * }
753
+ * }
754
+ * ```
755
+ */
756
+ declare class OlympexSdkError extends Error {
757
+ readonly code: string;
758
+ readonly metadata: Record<string, unknown> | undefined;
759
+ constructor(message: string, code?: string, metadata?: Record<string, unknown>);
760
+ }
761
+
762
+ /**
763
+ * Thrown when SDK configuration or caller input fails local validation before a network call.
764
+ *
765
+ * @remarks Extends {@link OlympexSdkError}. Safe to catch by `instanceof` or `error.code`
766
+ * (`OLYMPEX_CONFIG_ERROR`). Examples: empty `apiKey`, invalid `OLYMPEX_BACKEND_URL`, invalid
767
+ * {@link FeeOptions.feeBps | feeBps}.
768
+ *
769
+ * @see docs/errors.md
770
+ */
771
+ declare class OlympexConfigError extends OlympexSdkError {
772
+ constructor(message: string, metadata?: Record<string, unknown>);
773
+ }
774
+
775
+ /**
776
+ * Thrown when the backend returns a domain-level `success: false` response.
777
+ *
778
+ * @remarks Extends {@link OlympexSdkError}. The HTTP request succeeded but the payload
779
+ * indicates a business-rule or validation failure. Inspect `error.message` and `error.metadata`
780
+ * for backend-provided context.
781
+ *
782
+ * @see docs/errors.md
783
+ */
784
+ declare class OlympexDomainError extends OlympexSdkError {
785
+ constructor(message: string, metadata?: Record<string, unknown>);
786
+ }
787
+
788
+ /**
789
+ * Thrown when the GraphQL response contains an `errors[]` array on an otherwise successful HTTP 200.
790
+ *
791
+ * @remarks Extends {@link OlympexSdkError}. Distinct from {@link OlympexNetworkError} — the
792
+ * transport succeeded but the GraphQL layer reported execution or validation failures.
793
+ *
794
+ * @see docs/errors.md
795
+ */
796
+ declare class OlympexGraphQLError extends OlympexSdkError {
797
+ constructor(message: string, metadata?: Record<string, unknown>);
798
+ }
799
+
800
+ /**
801
+ * Thrown on network failures: timeouts, fetch errors, or non-2xx HTTP responses.
802
+ *
803
+ * @remarks Extends {@link OlympexSdkError}. Retry logic should consider exponential backoff;
804
+ * inspect `error.metadata` for status codes when available.
805
+ *
806
+ * @see docs/errors.md
807
+ */
808
+ declare class OlympexNetworkError extends OlympexSdkError {
809
+ constructor(message: string, metadata?: Record<string, unknown>);
810
+ }
811
+
812
+ /**
813
+ * Thrown when a public method is not yet backed by a live backend contract.
814
+ *
815
+ * @remarks Extends {@link OlympexSdkError}. Use when exposing explicitly unsupported
816
+ * temporary paths while backend contracts are still in progress.
817
+ *
818
+ * @see docs/errors.md
819
+ */
820
+ declare class OlympexNotImplementedError extends OlympexSdkError {
821
+ constructor(message: string, metadata?: Record<string, unknown>);
822
+ }
823
+
824
+ export { type CreateAccountInput, type CreateAccountOptions, type CreateAccountResponse, type CrossChainQuote, type CrossChainQuoteInput, type CrossChainRouteAsset, type CrossChainRouteAssetPair, type CrossChainSwap, type CrossChainSwapInput, type DataFeeTransaction, type FeeOptions, type GasMultiplier, type InitializeOptions, type LogLevel, type OlympexClient, OlympexConfigError, OlympexDomainError, OlympexGraphQLError, type OlympexLogger, OlympexNetworkError, OlympexNotImplementedError, OlympexSdkError, type QuoteDex, type QuoteMarket, type QuoteOrderBy, type QuoteRequest, type QuoteResult, type QuoteRoute, type QuoteSubRoute, type SingleChainQuote, type SingleChainQuoteInput, type SingleChainSwap, type SingleChainSwapInput, type SwapRequest, type SwapResult, type TxStatus, type TxStatusInput, createAccount, createConsoleLogger, getVersion, initialize };