@riftresearch/sdk 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -32,7 +32,8 @@ interface Currency {
32
32
  */
33
33
  interface SpecifiedAmount {
34
34
  currency: Currency;
35
- amount: U256;
35
+ /** Expected amount (exact, as specified by the user) */
36
+ expected: U256;
36
37
  }
37
38
  /**
38
39
  * A calculated output amount for exact_input mode.
@@ -41,7 +42,7 @@ interface SpecifiedAmount {
41
42
  interface CalculatedOutputAmount {
42
43
  currency: Currency;
43
44
  /** Expected output based on current market conditions */
44
- amount: U256;
45
+ expected: U256;
45
46
  /** Minimum guaranteed output after slippage (optional - not all routes provide this) */
46
47
  minimum?: U256;
47
48
  }
@@ -52,7 +53,7 @@ interface CalculatedOutputAmount {
52
53
  interface CalculatedInputAmount {
53
54
  currency: Currency;
54
55
  /** Expected input based on current market conditions */
55
- amount: U256;
56
+ expected: U256;
56
57
  /** Maximum input required after slippage (optional - not all routes provide this) */
57
58
  maximum?: U256;
58
59
  }
@@ -234,11 +235,1044 @@ declare const Currencies: {
234
235
  };
235
236
  import { Treaty } from "@elysiajs/eden";
236
237
  import { Elysia } from "elysia";
237
- import { RiftOtcApi } from "../lib";
238
- import { SwapRequest as SwapRequest2 } from "../../../common/types";
239
- import { CachedQuote, ISwapMappingStore } from "../../../lib/cache";
240
- import { OtcClient as OtcClient2 } from "../../../lib/rift-otc-api";
241
- import { SwapperClient } from "../../../lib/rift-swapper-api";
238
+ import { Static } from "elysia";
239
+ import { TString as TString_4i3c6z } from "@sinclair/typebox";
240
+ import { TObject as TObject_6obbkd } from "@sinclair/typebox";
241
+ import { TLiteral as TLiteral_yes1tx } from "@sinclair/typebox";
242
+ import { TNumber as TNumber_6uuzwj } from "@sinclair/typebox";
243
+ import { TUnion as TUnion_twkt9h } from "@sinclair/typebox";
244
+ import { TOptional as TOptional_p2zzfw } from "@sinclair/typebox";
245
+ declare const QuoteRequestSchema: TObject_6obbkd<{
246
+ type: TString_4i3c6z;
247
+ from: TObject_6obbkd<{
248
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
249
+ kind: TLiteral_yes1tx<"BITCOIN">;
250
+ }>, TObject_6obbkd<{
251
+ kind: TLiteral_yes1tx<"EVM">;
252
+ chainId: TNumber_6uuzwj;
253
+ }>]>;
254
+ token: TUnion_twkt9h<[TObject_6obbkd<{
255
+ kind: TLiteral_yes1tx<"NATIVE">;
256
+ decimals: TNumber_6uuzwj;
257
+ }>, TObject_6obbkd<{
258
+ kind: TLiteral_yes1tx<"TOKEN">;
259
+ address: TString_4i3c6z;
260
+ decimals: TNumber_6uuzwj;
261
+ }>]>;
262
+ }>;
263
+ to: TObject_6obbkd<{
264
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
265
+ kind: TLiteral_yes1tx<"BITCOIN">;
266
+ }>, TObject_6obbkd<{
267
+ kind: TLiteral_yes1tx<"EVM">;
268
+ chainId: TNumber_6uuzwj;
269
+ }>]>;
270
+ token: TUnion_twkt9h<[TObject_6obbkd<{
271
+ kind: TLiteral_yes1tx<"NATIVE">;
272
+ decimals: TNumber_6uuzwj;
273
+ }>, TObject_6obbkd<{
274
+ kind: TLiteral_yes1tx<"TOKEN">;
275
+ address: TString_4i3c6z;
276
+ decimals: TNumber_6uuzwj;
277
+ }>]>;
278
+ }>;
279
+ amount: TString_4i3c6z;
280
+ slippageBps: TNumber_6uuzwj;
281
+ quoteQuality: TOptional_p2zzfw<TString_4i3c6z>;
282
+ }>;
283
+ /**
284
+ * Discriminated union of quote responses.
285
+ */
286
+ declare const QuoteResponseSchema: TUnion_twkt9h<[TObject_6obbkd<{
287
+ from: TObject_6obbkd<{
288
+ currency: TObject_6obbkd<{
289
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
290
+ kind: TLiteral_yes1tx<"BITCOIN">;
291
+ }>, TObject_6obbkd<{
292
+ kind: TLiteral_yes1tx<"EVM">;
293
+ chainId: TNumber_6uuzwj;
294
+ }>]>;
295
+ token: TUnion_twkt9h<[TObject_6obbkd<{
296
+ kind: TLiteral_yes1tx<"NATIVE">;
297
+ decimals: TNumber_6uuzwj;
298
+ }>, TObject_6obbkd<{
299
+ kind: TLiteral_yes1tx<"TOKEN">;
300
+ address: TString_4i3c6z;
301
+ decimals: TNumber_6uuzwj;
302
+ }>]>;
303
+ }>;
304
+ expected: TString_4i3c6z;
305
+ }>;
306
+ to: TObject_6obbkd<{
307
+ currency: TObject_6obbkd<{
308
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
309
+ kind: TLiteral_yes1tx<"BITCOIN">;
310
+ }>, TObject_6obbkd<{
311
+ kind: TLiteral_yes1tx<"EVM">;
312
+ chainId: TNumber_6uuzwj;
313
+ }>]>;
314
+ token: TUnion_twkt9h<[TObject_6obbkd<{
315
+ kind: TLiteral_yes1tx<"NATIVE">;
316
+ decimals: TNumber_6uuzwj;
317
+ }>, TObject_6obbkd<{
318
+ kind: TLiteral_yes1tx<"TOKEN">;
319
+ address: TString_4i3c6z;
320
+ decimals: TNumber_6uuzwj;
321
+ }>]>;
322
+ }>;
323
+ expected: TString_4i3c6z;
324
+ minimum: TOptional_p2zzfw<TString_4i3c6z>;
325
+ }>;
326
+ id: TString_4i3c6z;
327
+ fees: TObject_6obbkd<{
328
+ preswap: TOptional_p2zzfw<TObject_6obbkd<{
329
+ amount: TString_4i3c6z;
330
+ currency: TObject_6obbkd<{
331
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
332
+ kind: TLiteral_yes1tx<"BITCOIN">;
333
+ }>, TObject_6obbkd<{
334
+ kind: TLiteral_yes1tx<"EVM">;
335
+ chainId: TNumber_6uuzwj;
336
+ }>]>;
337
+ token: TUnion_twkt9h<[TObject_6obbkd<{
338
+ kind: TLiteral_yes1tx<"NATIVE">;
339
+ decimals: TNumber_6uuzwj;
340
+ }>, TObject_6obbkd<{
341
+ kind: TLiteral_yes1tx<"TOKEN">;
342
+ address: TString_4i3c6z;
343
+ decimals: TNumber_6uuzwj;
344
+ }>]>;
345
+ }>;
346
+ usd: TNumber_6uuzwj;
347
+ }>>;
348
+ rift: TOptional_p2zzfw<TObject_6obbkd<{
349
+ network: TObject_6obbkd<{
350
+ amount: TString_4i3c6z;
351
+ currency: TObject_6obbkd<{
352
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
353
+ kind: TLiteral_yes1tx<"BITCOIN">;
354
+ }>, TObject_6obbkd<{
355
+ kind: TLiteral_yes1tx<"EVM">;
356
+ chainId: TNumber_6uuzwj;
357
+ }>]>;
358
+ token: TUnion_twkt9h<[TObject_6obbkd<{
359
+ kind: TLiteral_yes1tx<"NATIVE">;
360
+ decimals: TNumber_6uuzwj;
361
+ }>, TObject_6obbkd<{
362
+ kind: TLiteral_yes1tx<"TOKEN">;
363
+ address: TString_4i3c6z;
364
+ decimals: TNumber_6uuzwj;
365
+ }>]>;
366
+ }>;
367
+ usd: TNumber_6uuzwj;
368
+ }>;
369
+ liquidity: TObject_6obbkd<{
370
+ amount: TString_4i3c6z;
371
+ currency: TObject_6obbkd<{
372
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
373
+ kind: TLiteral_yes1tx<"BITCOIN">;
374
+ }>, TObject_6obbkd<{
375
+ kind: TLiteral_yes1tx<"EVM">;
376
+ chainId: TNumber_6uuzwj;
377
+ }>]>;
378
+ token: TUnion_twkt9h<[TObject_6obbkd<{
379
+ kind: TLiteral_yes1tx<"NATIVE">;
380
+ decimals: TNumber_6uuzwj;
381
+ }>, TObject_6obbkd<{
382
+ kind: TLiteral_yes1tx<"TOKEN">;
383
+ address: TString_4i3c6z;
384
+ decimals: TNumber_6uuzwj;
385
+ }>]>;
386
+ }>;
387
+ usd: TNumber_6uuzwj;
388
+ }>;
389
+ protocol: TObject_6obbkd<{
390
+ amount: TString_4i3c6z;
391
+ currency: TObject_6obbkd<{
392
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
393
+ kind: TLiteral_yes1tx<"BITCOIN">;
394
+ }>, TObject_6obbkd<{
395
+ kind: TLiteral_yes1tx<"EVM">;
396
+ chainId: TNumber_6uuzwj;
397
+ }>]>;
398
+ token: TUnion_twkt9h<[TObject_6obbkd<{
399
+ kind: TLiteral_yes1tx<"NATIVE">;
400
+ decimals: TNumber_6uuzwj;
401
+ }>, TObject_6obbkd<{
402
+ kind: TLiteral_yes1tx<"TOKEN">;
403
+ address: TString_4i3c6z;
404
+ decimals: TNumber_6uuzwj;
405
+ }>]>;
406
+ }>;
407
+ usd: TNumber_6uuzwj;
408
+ }>;
409
+ }>>;
410
+ postswap: TOptional_p2zzfw<TObject_6obbkd<{
411
+ amount: TString_4i3c6z;
412
+ currency: TObject_6obbkd<{
413
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
414
+ kind: TLiteral_yes1tx<"BITCOIN">;
415
+ }>, TObject_6obbkd<{
416
+ kind: TLiteral_yes1tx<"EVM">;
417
+ chainId: TNumber_6uuzwj;
418
+ }>]>;
419
+ token: TUnion_twkt9h<[TObject_6obbkd<{
420
+ kind: TLiteral_yes1tx<"NATIVE">;
421
+ decimals: TNumber_6uuzwj;
422
+ }>, TObject_6obbkd<{
423
+ kind: TLiteral_yes1tx<"TOKEN">;
424
+ address: TString_4i3c6z;
425
+ decimals: TNumber_6uuzwj;
426
+ }>]>;
427
+ }>;
428
+ usd: TNumber_6uuzwj;
429
+ }>>;
430
+ totalUsd: TNumber_6uuzwj;
431
+ }>;
432
+ expiresAt: TString_4i3c6z;
433
+ mode: TLiteral_yes1tx<"exact_input">;
434
+ }>, TObject_6obbkd<{
435
+ from: TObject_6obbkd<{
436
+ currency: TObject_6obbkd<{
437
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
438
+ kind: TLiteral_yes1tx<"BITCOIN">;
439
+ }>, TObject_6obbkd<{
440
+ kind: TLiteral_yes1tx<"EVM">;
441
+ chainId: TNumber_6uuzwj;
442
+ }>]>;
443
+ token: TUnion_twkt9h<[TObject_6obbkd<{
444
+ kind: TLiteral_yes1tx<"NATIVE">;
445
+ decimals: TNumber_6uuzwj;
446
+ }>, TObject_6obbkd<{
447
+ kind: TLiteral_yes1tx<"TOKEN">;
448
+ address: TString_4i3c6z;
449
+ decimals: TNumber_6uuzwj;
450
+ }>]>;
451
+ }>;
452
+ expected: TString_4i3c6z;
453
+ maximum: TOptional_p2zzfw<TString_4i3c6z>;
454
+ }>;
455
+ to: TObject_6obbkd<{
456
+ currency: TObject_6obbkd<{
457
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
458
+ kind: TLiteral_yes1tx<"BITCOIN">;
459
+ }>, TObject_6obbkd<{
460
+ kind: TLiteral_yes1tx<"EVM">;
461
+ chainId: TNumber_6uuzwj;
462
+ }>]>;
463
+ token: TUnion_twkt9h<[TObject_6obbkd<{
464
+ kind: TLiteral_yes1tx<"NATIVE">;
465
+ decimals: TNumber_6uuzwj;
466
+ }>, TObject_6obbkd<{
467
+ kind: TLiteral_yes1tx<"TOKEN">;
468
+ address: TString_4i3c6z;
469
+ decimals: TNumber_6uuzwj;
470
+ }>]>;
471
+ }>;
472
+ expected: TString_4i3c6z;
473
+ }>;
474
+ id: TString_4i3c6z;
475
+ fees: TObject_6obbkd<{
476
+ preswap: TOptional_p2zzfw<TObject_6obbkd<{
477
+ amount: TString_4i3c6z;
478
+ currency: TObject_6obbkd<{
479
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
480
+ kind: TLiteral_yes1tx<"BITCOIN">;
481
+ }>, TObject_6obbkd<{
482
+ kind: TLiteral_yes1tx<"EVM">;
483
+ chainId: TNumber_6uuzwj;
484
+ }>]>;
485
+ token: TUnion_twkt9h<[TObject_6obbkd<{
486
+ kind: TLiteral_yes1tx<"NATIVE">;
487
+ decimals: TNumber_6uuzwj;
488
+ }>, TObject_6obbkd<{
489
+ kind: TLiteral_yes1tx<"TOKEN">;
490
+ address: TString_4i3c6z;
491
+ decimals: TNumber_6uuzwj;
492
+ }>]>;
493
+ }>;
494
+ usd: TNumber_6uuzwj;
495
+ }>>;
496
+ rift: TOptional_p2zzfw<TObject_6obbkd<{
497
+ network: TObject_6obbkd<{
498
+ amount: TString_4i3c6z;
499
+ currency: TObject_6obbkd<{
500
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
501
+ kind: TLiteral_yes1tx<"BITCOIN">;
502
+ }>, TObject_6obbkd<{
503
+ kind: TLiteral_yes1tx<"EVM">;
504
+ chainId: TNumber_6uuzwj;
505
+ }>]>;
506
+ token: TUnion_twkt9h<[TObject_6obbkd<{
507
+ kind: TLiteral_yes1tx<"NATIVE">;
508
+ decimals: TNumber_6uuzwj;
509
+ }>, TObject_6obbkd<{
510
+ kind: TLiteral_yes1tx<"TOKEN">;
511
+ address: TString_4i3c6z;
512
+ decimals: TNumber_6uuzwj;
513
+ }>]>;
514
+ }>;
515
+ usd: TNumber_6uuzwj;
516
+ }>;
517
+ liquidity: TObject_6obbkd<{
518
+ amount: TString_4i3c6z;
519
+ currency: TObject_6obbkd<{
520
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
521
+ kind: TLiteral_yes1tx<"BITCOIN">;
522
+ }>, TObject_6obbkd<{
523
+ kind: TLiteral_yes1tx<"EVM">;
524
+ chainId: TNumber_6uuzwj;
525
+ }>]>;
526
+ token: TUnion_twkt9h<[TObject_6obbkd<{
527
+ kind: TLiteral_yes1tx<"NATIVE">;
528
+ decimals: TNumber_6uuzwj;
529
+ }>, TObject_6obbkd<{
530
+ kind: TLiteral_yes1tx<"TOKEN">;
531
+ address: TString_4i3c6z;
532
+ decimals: TNumber_6uuzwj;
533
+ }>]>;
534
+ }>;
535
+ usd: TNumber_6uuzwj;
536
+ }>;
537
+ protocol: TObject_6obbkd<{
538
+ amount: TString_4i3c6z;
539
+ currency: TObject_6obbkd<{
540
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
541
+ kind: TLiteral_yes1tx<"BITCOIN">;
542
+ }>, TObject_6obbkd<{
543
+ kind: TLiteral_yes1tx<"EVM">;
544
+ chainId: TNumber_6uuzwj;
545
+ }>]>;
546
+ token: TUnion_twkt9h<[TObject_6obbkd<{
547
+ kind: TLiteral_yes1tx<"NATIVE">;
548
+ decimals: TNumber_6uuzwj;
549
+ }>, TObject_6obbkd<{
550
+ kind: TLiteral_yes1tx<"TOKEN">;
551
+ address: TString_4i3c6z;
552
+ decimals: TNumber_6uuzwj;
553
+ }>]>;
554
+ }>;
555
+ usd: TNumber_6uuzwj;
556
+ }>;
557
+ }>>;
558
+ postswap: TOptional_p2zzfw<TObject_6obbkd<{
559
+ amount: TString_4i3c6z;
560
+ currency: TObject_6obbkd<{
561
+ chain: TUnion_twkt9h<[TObject_6obbkd<{
562
+ kind: TLiteral_yes1tx<"BITCOIN">;
563
+ }>, TObject_6obbkd<{
564
+ kind: TLiteral_yes1tx<"EVM">;
565
+ chainId: TNumber_6uuzwj;
566
+ }>]>;
567
+ token: TUnion_twkt9h<[TObject_6obbkd<{
568
+ kind: TLiteral_yes1tx<"NATIVE">;
569
+ decimals: TNumber_6uuzwj;
570
+ }>, TObject_6obbkd<{
571
+ kind: TLiteral_yes1tx<"TOKEN">;
572
+ address: TString_4i3c6z;
573
+ decimals: TNumber_6uuzwj;
574
+ }>]>;
575
+ }>;
576
+ usd: TNumber_6uuzwj;
577
+ }>>;
578
+ totalUsd: TNumber_6uuzwj;
579
+ }>;
580
+ expiresAt: TString_4i3c6z;
581
+ mode: TLiteral_yes1tx<"exact_output">;
582
+ }>]>;
583
+ declare const SwapRequestSchema: TObject_6obbkd<{
584
+ id: TString_4i3c6z;
585
+ destinationAddress: TString_4i3c6z;
586
+ refundAddress: TString_4i3c6z;
587
+ integratorName: TOptional_p2zzfw<TString_4i3c6z>;
588
+ approvalMode: TOptional_p2zzfw<TString_4i3c6z>;
589
+ }>;
590
+ type QuoteRequest2 = Static<typeof QuoteRequestSchema>;
591
+ type QuoteResponse2 = Static<typeof QuoteResponseSchema>;
592
+ type SwapRequest2 = Static<typeof SwapRequestSchema>;
593
+ /** Supported DEX provider identifiers */
594
+ type DexProviderId = "oneinch" | "spandex" | "fabric" | "kyberswap" | "lifi" | "relay";
595
+ /** Routing preference for quote requests */
596
+ type RoutingPreference = "BEST_PRICE" | "FASTEST";
597
+ /**
598
+ * Shared types between RFQ and OTC APIs.
599
+ * These types match the Rust definitions in otc-models crate.
600
+ */
601
+ type ChainType = "bitcoin" | "ethereum" | "base";
602
+ /**
603
+ * Token identifier - either native chain token or contract address.
604
+ * Uses serde's adjacently tagged representation: { type, data? }
605
+ */
606
+ type TokenIdentifier2 = {
607
+ type: "Native";
608
+ } | {
609
+ type: "Address";
610
+ data: string;
611
+ };
612
+ interface Currency3 {
613
+ chain: ChainType;
614
+ token: TokenIdentifier2;
615
+ decimals: number;
616
+ }
617
+ interface Lot2 {
618
+ currency: Currency3;
619
+ amount: string;
620
+ }
621
+ /**
622
+ * Swap computation mode - determines whether input or output is the fixed value.
623
+ * Uses serde's internally tagged representation with amount.
624
+ */
625
+ type SwapMode = {
626
+ type: "exact_input";
627
+ amount: number;
628
+ } | {
629
+ type: "exact_output";
630
+ amount: number;
631
+ };
632
+ /**
633
+ * Rate parameters for computing swap fees.
634
+ * Basis point fees are additive and applied to the gross input amount.
635
+ */
636
+ interface SwapRates2 {
637
+ /** MM liquidity fee spread in bps (e.g., 13 = 0.13%) */
638
+ liquidity_fee_bps: number;
639
+ /** Protocol fee spread in bps (e.g., 10 = 0.10%) */
640
+ protocol_fee_bps: number;
641
+ /** Base gas/network fee in sats*/
642
+ network_fee_sats: number;
643
+ }
644
+ /**
645
+ * Fee amounts for a quote (exact quoted amount).
646
+ * All values are U256 as decimal strings.
647
+ */
648
+ interface Fees {
649
+ liquidity_fee: string;
650
+ protocol_fee: string;
651
+ network_fee: string;
652
+ }
653
+ /**
654
+ * A quote that defines the terms for a swap.
655
+ *
656
+ * Contains:
657
+ * - Exact quoted amounts (`from`/`to` lots) for the requested input/output
658
+ * - Valid deposit bounds (`min_input`/`max_input`) - user can deposit any amount within
659
+ * - Rate parameters (`rates`) to compute realized amounts for any deposit
660
+ * - Fee breakdown (`fees`) for the exact quoted amount
661
+ */
662
+ interface Quote {
663
+ id: string;
664
+ market_maker_id: string;
665
+ /** What the user sends (currency + exact quoted amount) */
666
+ from: Lot2;
667
+ /** What the user receives (currency + exact quoted amount) */
668
+ to: Lot2;
669
+ /** Rate parameters used for computation */
670
+ rates: SwapRates2;
671
+ /** Fee breakdown for the exact quoted amount */
672
+ fees: Fees;
673
+ /** Minimum input amount allowed (in from currency smallest unit) */
674
+ min_input: string;
675
+ /** Maximum input amount allowed (in from currency smallest unit) */
676
+ max_input: string;
677
+ /** Optional affiliate identifier that determined the protocol fee rate */
678
+ affiliate?: string;
679
+ expires_at: string;
680
+ created_at: string;
681
+ }
682
+ interface QuoteRequest3 {
683
+ from: Currency3;
684
+ to: Currency3;
685
+ /** Swap mode: exact_input or exact_output with the specified amount */
686
+ mode: SwapMode;
687
+ /** Optional affiliate identifier for custom protocol fee rates */
688
+ affiliate?: string;
689
+ }
690
+ type SwapStatus2 = "waiting_user_deposit_initiated" | "waiting_user_deposit_confirmed" | "waiting_mm_deposit_initiated" | "waiting_mm_deposit_confirmed" | "settled" | "refunding_user" | "failed";
691
+ type RefundSwapReason = "UserInitiatedEarlyRefund" | "MarketMakerNeverInitiatedDeposit" | "MarketMakerDepositNeverConfirmed" | "UserInitiatedRefundAgain";
692
+ /** Computed amounts when user deposit is detected and validated */
693
+ interface RealizedSwap2 {
694
+ /** Actual amount the user deposited */
695
+ user_input: string;
696
+ /** Amount the MM must send to the user */
697
+ mm_output: string;
698
+ /** Protocol's cut (collected during settlement) */
699
+ protocol_fee: string;
700
+ /** MM's spread/profit */
701
+ liquidity_fee: string;
702
+ /** Fixed gas/network costs */
703
+ network_fee: string;
704
+ }
705
+ /** Status of user's deposit */
706
+ interface UserDepositStatus2 {
707
+ tx_hash: string;
708
+ amount: string;
709
+ deposit_detected_at: string;
710
+ confirmations: number;
711
+ last_checked: string;
712
+ confirmed_at?: string;
713
+ }
714
+ /** Status of market maker's deposit */
715
+ interface MMDepositStatus2 {
716
+ tx_hash: string;
717
+ amount: string;
718
+ deposit_detected_at: string;
719
+ confirmations: number;
720
+ last_checked: string;
721
+ }
722
+ /** Status of settlement */
723
+ interface SettlementStatus2 {
724
+ tx_hash: string;
725
+ broadcast_at: string;
726
+ confirmations: number;
727
+ completed_at?: string;
728
+ fee?: string;
729
+ }
730
+ /** Latest refund information */
731
+ interface LatestRefund2 {
732
+ timestamp: string;
733
+ recipient_address: string;
734
+ }
735
+ /** Full swap object returned by the API */
736
+ interface Swap2 {
737
+ id: string;
738
+ market_maker_id: string;
739
+ /** The rate-based quote for this swap */
740
+ quote: Quote;
741
+ metadata: Metadata;
742
+ /** Realized amounts computed when user deposit is detected */
743
+ realized?: RealizedSwap2;
744
+ /** Salt for deterministic wallet generation (64 hex characters, no 0x prefix) */
745
+ deposit_vault_salt: string;
746
+ /** Cached deposit vault address */
747
+ deposit_vault_address: string;
748
+ /** Nonce for the market maker to embed in their payment address (32 hex characters, no 0x prefix) */
749
+ mm_nonce: string;
750
+ /** Destination address for receiving funds */
751
+ destination_address: string;
752
+ /** Refund address */
753
+ refund_address: string;
754
+ /** Core status */
755
+ status: SwapStatus2;
756
+ /** Deposit tracking */
757
+ user_deposit_status?: UserDepositStatus2;
758
+ mm_deposit_status?: MMDepositStatus2;
759
+ /** Settlement tracking */
760
+ settlement_status?: SettlementStatus2;
761
+ /** Refund tracking */
762
+ latest_refund?: LatestRefund2;
763
+ /** Failure/timeout tracking */
764
+ failure_reason?: string;
765
+ failure_at?: string;
766
+ /** MM coordination */
767
+ mm_notified_at?: string;
768
+ mm_private_key_sent_at?: string;
769
+ created_at: string;
770
+ updated_at: string;
771
+ }
772
+ interface Metadata {
773
+ start_asset?: string;
774
+ end_asset?: string;
775
+ integrator_name?: string;
776
+ }
777
+ interface BaseClientConfig {
778
+ baseUrl: string;
779
+ timeout?: number;
780
+ /** Optional headers to include with every request */
781
+ defaultHeaders?: Record<string, string>;
782
+ }
783
+ /** Unwrapped quote response for convenience (quote is extracted from Result) */
784
+ interface QuoteResponse3 {
785
+ request_id: string;
786
+ quote: Quote;
787
+ /** Raw JSON string of the quote, preserved for hash-sensitive operations */
788
+ quoteRawJson: string;
789
+ total_quotes_received: number;
790
+ market_makers_contacted: number;
791
+ }
792
+ interface RfqStatus2 {
793
+ status: string;
794
+ version: string;
795
+ connected_market_makers: string[];
796
+ }
797
+ /**
798
+ * Liquidity information for a specific trading pair
799
+ */
800
+ interface TradingPairLiquidity {
801
+ from: Currency3;
802
+ to: Currency3;
803
+ /** Maximum from_amount the MM can handle */
804
+ max_amount: string;
805
+ }
806
+ interface MarketMakerLiquidity {
807
+ market_maker_id: string;
808
+ trading_pairs: TradingPairLiquidity[];
809
+ }
810
+ interface LiquidityResponse {
811
+ market_makers: MarketMakerLiquidity[];
812
+ timestamp: string;
813
+ }
814
+ /** Optional screening headers for address risk checks */
815
+ interface ScreeningHeaders {
816
+ userAddress?: string;
817
+ destinationAddress?: string;
818
+ }
819
+ /**
820
+ * TypeScript client for the RFQ server API (v2)
821
+ * Provides access to quote aggregation and market maker information
822
+ */
823
+ declare class RfqClient2 {
824
+ private readonly baseUrl;
825
+ private readonly timeout;
826
+ private readonly headers;
827
+ constructor(config: BaseClientConfig);
828
+ private fetchAttempt;
829
+ private fetchWithRetry;
830
+ /** Get server status and version information */
831
+ getStatus(): Promise<RfqStatus2>;
832
+ /**
833
+ * Request quotes from connected market makers.
834
+ * Unwraps the RFQResult and throws on non-success responses.
835
+ * Preserves the raw quote JSON to avoid hash mismatches when forwarding to OTC.
836
+ */
837
+ requestQuote(request: QuoteRequest3, screeningHeaders?: ScreeningHeaders): Promise<QuoteResponse3>;
838
+ /**
839
+ * Extract the exact raw quote JSON substring from the response text.
840
+ * Preserves the original formatting/ordering to maintain hash consistency.
841
+ */
842
+ private extractQuoteJson;
843
+ /** Get liquidity information from all market makers */
844
+ getLiquidity(): Promise<LiquidityResponse>;
845
+ /** Health check endpoint */
846
+ healthCheck(): Promise<boolean>;
847
+ /** Get count of connected market makers */
848
+ getConnectedMarketMakersCount(): Promise<number>;
849
+ }
850
+ /** Request to create a new swap from a quote */
851
+ interface CreateSwapRequest {
852
+ /** The quote to create a swap from */
853
+ quote: Quote;
854
+ /** Destination address for receiving funds */
855
+ destination_address: string;
856
+ /** Legacy field name expected by OTC (kept for compatibility) */
857
+ user_destination_address?: string;
858
+ /** Refund address for receiving their "from" currency if the swap fails */
859
+ refund_address: string;
860
+ /** Optional metadata describing the swap source */
861
+ metadata?: Metadata;
862
+ }
863
+ /** Request to create a new swap using raw quote JSON (preserves hash) */
864
+ interface CreateSwapRequestRaw {
865
+ /** Raw JSON string of the quote, exactly as received from RFQ */
866
+ quoteRawJson: string;
867
+ /** Destination address for receiving funds */
868
+ destination_address: string;
869
+ /** Legacy field name expected by OTC (kept for compatibility) */
870
+ user_destination_address?: string;
871
+ /** Refund address for receiving their "from" currency if the swap fails */
872
+ refund_address: string;
873
+ /** Optional metadata describing the swap source */
874
+ metadata?: Metadata;
875
+ }
876
+ /** Response after refunding a swap */
877
+ interface RefundSwapResponse {
878
+ /** The refunded swap ID */
879
+ swap_id: string;
880
+ /** The reason the refund was allowed */
881
+ reason: RefundSwapReason;
882
+ /** The "ready to be broadcast" signed transaction data as a hex string */
883
+ tx_data: string;
884
+ /** The chain the transaction needs to be broadcast on */
885
+ tx_chain: ChainType;
886
+ }
887
+ /** Response for chain tip block hash */
888
+ interface BlockHashResponse {
889
+ block_hash: string;
890
+ }
891
+ /** List of suspended market makers */
892
+ interface SuspendedMarketMakersResponse {
893
+ suspended_market_makers: string[];
894
+ }
895
+ /** OTC server status */
896
+ interface OtcStatus2 {
897
+ status: string;
898
+ version: string;
899
+ connected_market_makers: string[];
900
+ }
901
+ /** TDX quote response from dstack */
902
+ interface TdxQuoteResponse {
903
+ quote: string;
904
+ }
905
+ /** TDX info response from dstack */
906
+ interface TdxInfoResponse {
907
+ version: string;
908
+ attestation_enabled: boolean;
909
+ }
910
+ /**
911
+ * TypeScript client for the OTC server API (v2)
912
+ * Provides access to swap creation, monitoring, and chain information
913
+ */
914
+ declare class OtcClient2 {
915
+ private readonly baseUrl;
916
+ private readonly timeout;
917
+ private readonly headers;
918
+ constructor(config: BaseClientConfig);
919
+ private fetchAttempt;
920
+ private fetchWithRetry;
921
+ /** Get server status and version information */
922
+ getStatus(): Promise<OtcStatus2>;
923
+ /** Create a new swap from a quote */
924
+ createSwap(request: CreateSwapRequest): Promise<Swap2>;
925
+ /**
926
+ * Create a new swap using raw quote JSON.
927
+ * Parses the raw quote JSON into a structured body for the OTC API.
928
+ */
929
+ createSwapWithRawQuote(request: CreateSwapRequestRaw): Promise<Swap2>;
930
+ /** Get swap status and details */
931
+ getSwap(swapId: string): Promise<Swap2>;
932
+ /** Request a refund for a swap */
933
+ refundSwap(swapId: string): Promise<RefundSwapResponse>;
934
+ /** Get the latest Bitcoin block hash */
935
+ getBitcoinTip(): Promise<BlockHashResponse>;
936
+ /** Get the latest Ethereum block hash */
937
+ getEthereumTip(): Promise<BlockHashResponse>;
938
+ /** Get the latest Base block hash */
939
+ getBaseTip(): Promise<BlockHashResponse>;
940
+ /** Get block hash for a specific chain */
941
+ getChainTip(chain: ChainType): Promise<BlockHashResponse>;
942
+ /** Get list of suspended market makers */
943
+ getSuspendedMarketMakers(): Promise<SuspendedMarketMakersResponse>;
944
+ /** Get TDX attestation quote */
945
+ getTdxQuote(challengeHex: string): Promise<TdxQuoteResponse>;
946
+ /** Get TDX info */
947
+ getTdxInfo(): Promise<TdxInfoResponse>;
948
+ /** Health check endpoint */
949
+ healthCheck(): Promise<boolean>;
950
+ /**
951
+ * Poll a swap until it reaches a terminal state or timeout.
952
+ * Returns the final swap.
953
+ */
954
+ pollSwapUntilComplete(swapId: string, options?: {
955
+ pollIntervalMs?: number;
956
+ maxWaitMs?: number;
957
+ onStatusChange?: (status: SwapStatus2) => void;
958
+ }): Promise<Swap2>;
959
+ }
960
+ /**
961
+ * Swapper API Client
962
+ * Single-file, zero-dependency TypeScript client for the TEE Swapper API
963
+ */
964
+ type SupportedChainId = 1 | 8453;
965
+ type TokenAddress = `0x${string}`;
966
+ type Token = {
967
+ type: "erc20";
968
+ address: TokenAddress;
969
+ } | {
970
+ type: "ether";
971
+ };
972
+ type SwapStatus3 = "pending_deposit" | "executing" | "complete" | "failed" | "expired" | "refund_pending" | "refunded";
973
+ interface QuoteRequest4 {
974
+ chainId: SupportedChainId;
975
+ buyToken: Token;
976
+ sellAmount: string;
977
+ }
978
+ interface CreateSwapRequest2 {
979
+ chainId: SupportedChainId;
980
+ buyToken: Token;
981
+ recipientAddress: TokenAddress;
982
+ refundAddress: TokenAddress;
983
+ }
984
+ interface HealthResponse2 {
985
+ status: "ok";
986
+ timestamp: number;
987
+ }
988
+ interface QuoteResponse4 {
989
+ quoteId: string;
990
+ chainId: SupportedChainId;
991
+ buyToken: Token;
992
+ sellAmount: string;
993
+ buyAmountEstimate: string;
994
+ expiresAt: number;
995
+ canFill: boolean;
996
+ }
997
+ interface QuoteErrorResponse {
998
+ error: string;
999
+ canFill: false;
1000
+ }
1001
+ interface CreateSwapResponse {
1002
+ swapId: string;
1003
+ vaultAddress: TokenAddress;
1004
+ chainId: SupportedChainId;
1005
+ buyToken: Token;
1006
+ recipientAddress: TokenAddress;
1007
+ refundAddress: TokenAddress;
1008
+ expiresAt: number;
1009
+ status: SwapStatus3;
1010
+ }
1011
+ interface SwapStatusResponse2 {
1012
+ swapId: string;
1013
+ chainId: SupportedChainId;
1014
+ vaultAddress: TokenAddress;
1015
+ buyToken: Token;
1016
+ recipientAddress: TokenAddress;
1017
+ refundAddress: TokenAddress;
1018
+ status: SwapStatus3;
1019
+ createdAt: number;
1020
+ expiresAt: number;
1021
+ depositTxHash?: string;
1022
+ depositAmount?: string;
1023
+ settlementTxHash?: string;
1024
+ actualBuyAmount?: string;
1025
+ failureReason?: string;
1026
+ refundTxHash?: string;
1027
+ refundAmount?: string;
1028
+ }
1029
+ interface SwapperClientOptions {
1030
+ /** Base URL of the swapper API (e.g., "https://swapper.example.com") */
1031
+ baseUrl: string;
1032
+ /** Optional fetch implementation (defaults to global fetch) */
1033
+ fetch?: typeof fetch;
1034
+ /** Optional headers to include with every request */
1035
+ headers?: Record<string, string>;
1036
+ }
1037
+ declare class SwapperClient {
1038
+ private readonly baseUrl;
1039
+ private readonly fetch;
1040
+ private readonly headers;
1041
+ constructor(options: SwapperClientOptions);
1042
+ private request;
1043
+ /**
1044
+ * Check API health status
1045
+ */
1046
+ health(): Promise<HealthResponse2>;
1047
+ /**
1048
+ * Get a quote for swapping CBBTC to another token
1049
+ *
1050
+ * @param request - Quote parameters
1051
+ * @returns Quote with estimated output amount, or error if quote unavailable
1052
+ */
1053
+ quote(request: QuoteRequest4): Promise<QuoteResponse4 | QuoteErrorResponse>;
1054
+ /**
1055
+ * Create a new swap
1056
+ *
1057
+ * @param request - Swap parameters including chain, token, and addresses
1058
+ * @returns Swap details including the vault address to deposit CBBTC to
1059
+ */
1060
+ createSwap(request: CreateSwapRequest2): Promise<CreateSwapResponse>;
1061
+ /**
1062
+ * Get the current status of a swap
1063
+ *
1064
+ * @param swapId - The swap ID returned from createSwap
1065
+ * @returns Current swap status and details
1066
+ * @throws SwapperClientError with status 404 if swap not found
1067
+ */
1068
+ getSwapStatus(swapId: string): Promise<SwapStatusResponse2>;
1069
+ /**
1070
+ * Poll for swap completion
1071
+ *
1072
+ * @param swapId - The swap ID to poll
1073
+ * @param options - Polling options
1074
+ * @returns Final swap status when complete, failed, expired, or refunded
1075
+ */
1076
+ waitForSwap(swapId: string, options?: {
1077
+ /** Polling interval in milliseconds (default: 5000) */
1078
+ intervalMs?: number;
1079
+ /** Maximum time to wait in milliseconds (default: 600000 / 10 minutes) */
1080
+ timeoutMs?: number;
1081
+ /** Callback on each poll */
1082
+ onPoll?: (status: SwapStatusResponse2) => void;
1083
+ }): Promise<SwapStatusResponse2>;
1084
+ }
1085
+ /**
1086
+ * Data needed to create a Swapper swap from a cached chained quote.
1087
+ */
1088
+ interface ChainedSwapQuoteData {
1089
+ chainId: SupportedChainId;
1090
+ buyToken: Token;
1091
+ buyTokenDecimals: number;
1092
+ sellAmount: string;
1093
+ buyAmountEstimate: string;
1094
+ expiresAt: number;
1095
+ }
1096
+ /**
1097
+ * Data needed to create a DEX preswap for ERC20 → BTC.
1098
+ */
1099
+ interface DexPreswapQuoteData {
1100
+ provider: DexProviderId;
1101
+ /** Underlying spanDEX provider (e.g. kyberswap) when provider is spandex */
1102
+ subprovider?: string;
1103
+ /** Analytics-friendly label (e.g. spandex.kyberswap) */
1104
+ providerLabel?: string;
1105
+ chainId: number;
1106
+ sellToken: string;
1107
+ buyToken: string;
1108
+ sellAmount: string;
1109
+ buyAmountMin: string;
1110
+ buyAmountEstimate: string;
1111
+ slippageBps: number;
1112
+ routingPreference?: RoutingPreference;
1113
+ }
1114
+ /**
1115
+ * Data needed to create a mono-chain DEX swap for EVM → EVM swaps.
1116
+ */
1117
+ interface DexMonochainQuoteData {
1118
+ provider: DexProviderId;
1119
+ /** Underlying spanDEX provider (e.g. kyberswap) when provider is spandex */
1120
+ subprovider?: string;
1121
+ /** Analytics-friendly label (e.g. spandex.kyberswap) */
1122
+ providerLabel?: string;
1123
+ chainId: number;
1124
+ sellToken: string;
1125
+ buyToken: string;
1126
+ sellAmount: string;
1127
+ buyAmountMin: string;
1128
+ buyAmountEstimate: string;
1129
+ slippageBps: number;
1130
+ routingPreference?: RoutingPreference;
1131
+ }
1132
+ /**
1133
+ * Cached quote entry containing both the parsed object and raw JSON.
1134
+ * The raw JSON is preserved to avoid hash mismatches when forwarding to OTC.
1135
+ * For mono-chain swaps, quote and rawJson are empty placeholders since there's no OTC involved.
1136
+ */
1137
+ interface CachedQuote {
1138
+ /** Parsed quote object for inspection (empty for mono-chain swaps) */
1139
+ quote: Quote;
1140
+ /** Raw JSON string exactly as received from RFQ server (empty for mono-chain swaps) */
1141
+ rawJson: string;
1142
+ /** Normalized quote response matching /quote output */
1143
+ normalizedQuote?: QuoteResponse;
1144
+ /** Swapper quote data for chained swaps (BTC → non-cbBTC ERC-20) */
1145
+ chainedSwap?: ChainedSwapQuoteData;
1146
+ /** DEX preswap data for ERC20 → BTC swaps */
1147
+ dexPreswap?: DexPreswapQuoteData;
1148
+ /** DEX swap data for mono-chain EVM → EVM swaps */
1149
+ dexMonochain?: DexMonochainQuoteData;
1150
+ /** Legacy field kept for backward compatibility */
1151
+ oneinchSwap?: DexMonochainQuoteData;
1152
+ }
1153
+ /**
1154
+ * Metadata for chained swaps needed to transform responses.
1155
+ */
1156
+ interface ChainedSwapMetadata {
1157
+ swapperSwapId: string;
1158
+ /** Actual ERC-20 destination (not the Swapper vault) */
1159
+ destination: string;
1160
+ /** Final token the user receives */
1161
+ finalToken: {
1162
+ chainId: number;
1163
+ address: string;
1164
+ decimals: number;
1165
+ };
1166
+ /** Estimated amount of final token */
1167
+ buyAmountEstimate: string;
1168
+ }
1169
+ /**
1170
+ * Metadata for DEX preswap swaps (ERC20 → BTC).
1171
+ */
1172
+ interface DexPreswapMetadata {
1173
+ /** Chosen DEX provider */
1174
+ provider: DexProviderId;
1175
+ /** Underlying spanDEX provider selected at quote time */
1176
+ subprovider?: string;
1177
+ /** Analytics-friendly label selected at quote time */
1178
+ providerLabel?: string;
1179
+ /** The sell token address */
1180
+ sellToken: string;
1181
+ /** Chain ID for the preswap */
1182
+ chainId: number;
1183
+ /** Optional DEX swap tx hash (best-effort analytics) */
1184
+ swapTxHash?: string;
1185
+ /** Expected DEX swap transaction (for callback validation) */
1186
+ expectedSwapTx?: OneInchExpectedSwapTx;
1187
+ /** Underlying spanDEX provider selected at execution time */
1188
+ executionSubprovider?: string;
1189
+ /** Analytics-friendly execution label (e.g. spandex.kyberswap) */
1190
+ executionProviderLabel?: string;
1191
+ }
1192
+ /**
1193
+ * Metadata for DEX mono-chain swaps (EVM → EVM).
1194
+ */
1195
+ interface DexMonochainMetadata {
1196
+ /** Chosen DEX provider */
1197
+ provider: DexProviderId;
1198
+ /** Underlying spanDEX provider selected at quote time */
1199
+ subprovider?: string;
1200
+ /** Analytics-friendly label selected at quote time */
1201
+ providerLabel?: string;
1202
+ /** The sell token address */
1203
+ sellToken: string;
1204
+ /** Chain ID for the swap */
1205
+ chainId: number;
1206
+ /** Optional DEX swap tx hash (best-effort analytics) */
1207
+ swapTxHash?: string;
1208
+ /** Expected DEX swap transaction (for callback validation) */
1209
+ expectedSwapTx?: OneInchExpectedSwapTx;
1210
+ /** Timestamp when swap transaction was confirmed on-chain */
1211
+ swapConfirmedAt?: string;
1212
+ /** Timestamp when swap transaction was confirmed failed */
1213
+ swapFailedAt?: string;
1214
+ /** Underlying spanDEX provider selected at execution time */
1215
+ executionSubprovider?: string;
1216
+ /** Analytics-friendly execution label (e.g. spandex.kyberswap) */
1217
+ executionProviderLabel?: string;
1218
+ }
1219
+ /**
1220
+ * Legacy metadata shape for oneinch_monochain records created before provider was persisted.
1221
+ */
1222
+ type LegacyOneInchMonochainMetadata = Omit<DexMonochainMetadata, "provider"> & Partial<Pick<DexMonochainMetadata, "provider">>;
1223
+ interface OneInchExpectedSwapTx {
1224
+ chainId: number;
1225
+ from: string;
1226
+ to: string;
1227
+ data: string;
1228
+ value: string;
1229
+ }
1230
+ interface OrderStatusMetadata {
1231
+ destinationAddress: string;
1232
+ quote: QuoteResponse;
1233
+ }
1234
+ /**
1235
+ * Mapping stored for each swap to track its type and related data.
1236
+ */
1237
+ type SwapMapping = ({
1238
+ type: "direct";
1239
+ } & OrderStatusMetadata) | ({
1240
+ type: "chained";
1241
+ } & ChainedSwapMetadata & OrderStatusMetadata) | ({
1242
+ type: "dex_preswap";
1243
+ } & DexPreswapMetadata & OrderStatusMetadata) | ({
1244
+ type: "oneinch_preswap";
1245
+ } & DexPreswapMetadata & OrderStatusMetadata) | ({
1246
+ type: "dex_monochain";
1247
+ } & DexMonochainMetadata & OrderStatusMetadata) | ({
1248
+ type: "oneinch_monochain";
1249
+ } & LegacyOneInchMonochainMetadata & OrderStatusMetadata);
1250
+ /**
1251
+ * Store for swap mappings (OTC swap ID → swap type + Swapper swap ID).
1252
+ */
1253
+ interface ISwapMappingStore {
1254
+ get(otcSwapId: string): Promise<SwapMapping | null>;
1255
+ set(otcSwapId: string, mapping: SwapMapping): Promise<void>;
1256
+ delete(otcSwapId: string): Promise<void>;
1257
+ }
1258
+ interface IQuoteCache {
1259
+ get(id: string): Promise<CachedQuote | null>;
1260
+ /** Atomically fetch and delete a quote to prevent reuse */
1261
+ consume(id: string): Promise<CachedQuote | null>;
1262
+ /** Store quote with its raw JSON representation and optional extension data */
1263
+ set(id: string, quote: Quote, rawJson: string, options?: {
1264
+ normalizedQuote?: QuoteResponse;
1265
+ chainedSwap?: ChainedSwapQuoteData;
1266
+ dexPreswap?: DexPreswapQuoteData;
1267
+ dexMonochain?: DexMonochainQuoteData;
1268
+ oneinchSwap?: DexMonochainQuoteData;
1269
+ }): Promise<void>;
1270
+ delete(id: string): Promise<void>;
1271
+ /** Graceful shutdown - close underlying connections */
1272
+ close(): Promise<void>;
1273
+ /** Health check for readiness probes */
1274
+ ping(): Promise<boolean>;
1275
+ }
242
1276
  /**
243
1277
  * Pure order service - no framework dependencies.
244
1278
  * Handles order creation and retrieval via OTC client.
@@ -248,6 +1282,8 @@ declare class OrderService {
248
1282
  private readonly otcClient;
249
1283
  private readonly swapperClient;
250
1284
  private readonly swapMappingStore;
1285
+ private readonly spandexProvider;
1286
+ private readonly dexRouter;
251
1287
  constructor(otcClient: OtcClient2, swapperClient: SwapperClient | null, swapMappingStore: ISwapMappingStore);
252
1288
  /**
253
1289
  * Create a swap using the cached quote with raw JSON.
@@ -265,15 +1301,15 @@ declare class OrderService {
265
1301
  */
266
1302
  private createChainedSwapOrder;
267
1303
  /**
268
- * Create a 1inch preswap order: ERC20 → cbBTC → BTC.
269
- * Returns execution steps: Approval + 1inch swap tx.
1304
+ * Create a DEX preswap order: ERC20 → cbBTC → BTC.
1305
+ * Returns execution steps: Approval + DEX swap tx.
270
1306
  */
271
- private createOneInchPreswapOrder;
1307
+ private createDexPreswapOrder;
272
1308
  /**
273
- * Create a mono-chain swap order: EVM → EVM via 1inch.
274
- * Returns execution steps: Approval (if needed) + 1inch swap tx.
1309
+ * Create a mono-chain swap order: EVM → EVM via selected DEX provider.
1310
+ * Returns execution steps: Approval (if needed) + DEX swap tx.
275
1311
  */
276
- private createOneInchMonochainOrder;
1312
+ private createDexMonochainOrder;
277
1313
  /**
278
1314
  * Build steps for BTC transfer (BTC → cbBTC or BTC → ERC20).
279
1315
  */
@@ -283,18 +1319,35 @@ declare class OrderService {
283
1319
  * No approval needed - just a direct ERC20 transfer.
284
1320
  */
285
1321
  private buildCbbtcTransferSteps;
286
- private buildOneInchSwapStep;
1322
+ private buildDexSwapStep;
1323
+ /**
1324
+ * Legacy provider IDs now route through spanDEX.
1325
+ * Keeps older cached quotes executable after migration.
1326
+ */
1327
+ private resolveExecutionProvider;
1328
+ private resolveExecutionSubprovider;
1329
+ /**
1330
+ * Select the first swap candidate that passes on-chain simulation.
1331
+ * This runs in /swap flow only (never in /quote).
1332
+ */
1333
+ private selectSimulatedSwapTxCandidate;
1334
+ private simulateSwapTx;
1335
+ private buildAllowanceStateOverride;
1336
+ private computeAllowanceStateSlots;
1337
+ private isStateOverrideUnsupported;
1338
+ private formatSimulationError;
1339
+ private describeSwapCandidate;
287
1340
  /**
288
- * Build steps for 1inch preswap (ERC20/ETH → cbBTC → BTC).
1341
+ * Build steps for DEX preswap (ERC20/ETH → cbBTC → BTC).
289
1342
  */
290
- private buildOneInchPreswapSteps;
1343
+ private buildDexPreswapSteps;
291
1344
  /**
292
- * Build steps for mono-chain 1inch swap (EVM → EVM).
1345
+ * Build steps for mono-chain DEX swap (EVM → EVM).
293
1346
  */
294
- private buildOneInchMonochainSteps;
1347
+ private buildDexMonochainSteps;
295
1348
  private resolveEvmSenderAddress;
296
1349
  private isEvmAddress;
297
- private extractExpectedOneInchSwap;
1350
+ private extractExpectedDexSwap;
298
1351
  private isNativeToken;
299
1352
  private getTxConfirmationStatus;
300
1353
  /**
@@ -314,10 +1367,6 @@ declare class OrderService {
314
1367
  private normalizeTxHash;
315
1368
  private isEvmChain;
316
1369
  }
317
- import { QuoteRequest as QuoteRequest2, QuoteResponse as QuoteResponse2 } from "../../../common/types";
318
- import { CachedQuote as CachedQuote2, IQuoteCache } from "../../../lib/cache";
319
- import { RfqClient as RfqClient2 } from "../../../lib/rift-otc-api";
320
- import { SwapperClient as SwapperClient2 } from "../../../lib/rift-swapper-api";
321
1370
  /**
322
1371
  * Pure quote service - no framework dependencies.
323
1372
  * Handles quote generation and caching.
@@ -327,13 +1376,13 @@ declare class QuoteService {
327
1376
  private readonly rfqClient;
328
1377
  private readonly swapperClient;
329
1378
  private readonly priceOracle;
330
- private readonly oneinchProvider;
331
- constructor(quoteCache: IQuoteCache, rfqClient: RfqClient2, swapperClient: SwapperClient2 | null);
1379
+ private readonly dexPreswapRouter;
1380
+ constructor(quoteCache: IQuoteCache, rfqClient: RfqClient2, swapperClient: SwapperClient | null);
332
1381
  getQuote(request: QuoteRequest2): Promise<QuoteResponse2>;
333
1382
  /** Get the cached quote with raw JSON for order creation */
334
- getCachedQuoteById(id: string): Promise<CachedQuote2 | null>;
1383
+ getCachedQuoteById(id: string): Promise<CachedQuote | null>;
335
1384
  /** Atomically consume a cached quote to prevent reuse */
336
- consumeCachedQuoteById(id: string): Promise<CachedQuote2 | null>;
1385
+ consumeCachedQuoteById(id: string): Promise<CachedQuote | null>;
337
1386
  private generateQuote;
338
1387
  /**
339
1388
  * Quote a direct BTC <-> cbBTC swap via Rift OTC.
@@ -349,22 +1398,26 @@ declare class QuoteService {
349
1398
  */
350
1399
  private quoteChainedSwap;
351
1400
  /**
352
- * Quote a mono-chain EVM → EVM swap via 1inch.
1401
+ * Quote a mono-chain EVM → EVM swap via DEX router.
353
1402
  */
354
- private quoteOneInchMonochain;
1403
+ private quoteDexMonochain;
355
1404
  /**
356
- * Quote a 1inch preswap: non-cbBTC ERC20 -> cbBTC (1inch) -> BTC (Rift OTC).
1405
+ * Quote a DEX preswap: non-cbBTC ERC20 -> cbBTC (DEX) -> BTC (Rift OTC).
357
1406
  *
358
- * 1. Get 1inch quote for ERC20 -> cbBTC
1407
+ * 1. Get best DEX quote for ERC20 -> cbBTC
359
1408
  * 2. Get OTC quote for cbBTC -> BTC
360
1409
  * 3. Cache both quotes linked together
361
1410
  * 4. Return combined quote showing ERC20 -> BTC
362
1411
  */
363
- private quoteOneInchThenRift;
1412
+ private quoteDexPreswapThenRift;
364
1413
  /**
365
1414
  * exact_input: ERC20 (known) -> cbBTC -> BTC (calculated)
366
1415
  */
367
- private quoteOneInchThenRiftExactInput;
1416
+ private quoteDexPreswapThenRiftExactInput;
1417
+ /**
1418
+ * exact_output: ERC20 (calculated) -> cbBTC -> BTC (known)
1419
+ */
1420
+ private quoteDexPreswapThenRiftExactOutput;
368
1421
  }
369
1422
  import { TModule as TModule_7fcqhs } from "@sinclair/typebox";
370
1423
  declare const app: Elysia<"", {
@@ -373,9 +1426,9 @@ declare const app: Elysia<"", {
373
1426
  } & {
374
1427
  orderService: OrderService;
375
1428
  } & {
376
- rfqClient: RiftOtcApi.RfqClient;
1429
+ rfqClient: exports_index_d.RfqClient;
377
1430
  } & {
378
- otcClient: RiftOtcApi.OtcClient;
1431
+ otcClient: exports_index_d.OtcClient;
379
1432
  };
380
1433
  store: {};
381
1434
  derive: {};
@@ -483,6 +1536,7 @@ declare const app: Elysia<"", {
483
1536
  quote: {
484
1537
  post: {
485
1538
  body: {
1539
+ quoteQuality?: string | undefined;
486
1540
  amount: string;
487
1541
  type: string;
488
1542
  from: {
@@ -517,6 +1571,7 @@ declare const app: Elysia<"", {
517
1571
  address: string;
518
1572
  };
519
1573
  };
1574
+ slippageBps: number;
520
1575
  };
521
1576
  params: {};
522
1577
  query: unknown;
@@ -540,7 +1595,7 @@ declare const app: Elysia<"", {
540
1595
  address: string;
541
1596
  };
542
1597
  };
543
- amount: string;
1598
+ expected: string;
544
1599
  };
545
1600
  to: {
546
1601
  minimum?: string | undefined;
@@ -560,7 +1615,7 @@ declare const app: Elysia<"", {
560
1615
  address: string;
561
1616
  };
562
1617
  };
563
- amount: string;
1618
+ expected: string;
564
1619
  };
565
1620
  mode: "exact_input";
566
1621
  id: string;
@@ -689,7 +1744,7 @@ declare const app: Elysia<"", {
689
1744
  address: string;
690
1745
  };
691
1746
  };
692
- amount: string;
1747
+ expected: string;
693
1748
  };
694
1749
  to: {
695
1750
  currency: {
@@ -708,7 +1763,7 @@ declare const app: Elysia<"", {
708
1763
  address: string;
709
1764
  };
710
1765
  };
711
- amount: string;
1766
+ expected: string;
712
1767
  };
713
1768
  mode: "exact_output";
714
1769
  id: string;
@@ -864,7 +1919,7 @@ declare const app: Elysia<"", {
864
1919
  address: string;
865
1920
  };
866
1921
  };
867
- amount: string;
1922
+ expected: string;
868
1923
  };
869
1924
  to: {
870
1925
  minimum?: string | undefined;
@@ -884,7 +1939,7 @@ declare const app: Elysia<"", {
884
1939
  address: string;
885
1940
  };
886
1941
  };
887
- amount: string;
1942
+ expected: string;
888
1943
  };
889
1944
  mode: "exact_input";
890
1945
  id: string;
@@ -1013,7 +2068,7 @@ declare const app: Elysia<"", {
1013
2068
  address: string;
1014
2069
  };
1015
2070
  };
1016
- amount: string;
2071
+ expected: string;
1017
2072
  };
1018
2073
  to: {
1019
2074
  currency: {
@@ -1032,7 +2087,7 @@ declare const app: Elysia<"", {
1032
2087
  address: string;
1033
2088
  };
1034
2089
  };
1035
- amount: string;
2090
+ expected: string;
1036
2091
  };
1037
2092
  mode: "exact_output";
1038
2093
  id: string;
@@ -1149,7 +2204,7 @@ declare const app: Elysia<"", {
1149
2204
  value?: string | undefined;
1150
2205
  tokenAddress?: string | undefined;
1151
2206
  spenderAddress?: string | undefined;
1152
- kind: "approval" | "transfer_erc20" | "oneinch_swap";
2207
+ kind: "approval" | "transfer_erc20" | "oneinch_swap" | "dex_swap";
1153
2208
  chainId: number;
1154
2209
  to: string;
1155
2210
  id: string;
@@ -1215,7 +2270,7 @@ declare const app: Elysia<"", {
1215
2270
  address: string;
1216
2271
  };
1217
2272
  };
1218
- amount: string;
2273
+ expected: string;
1219
2274
  };
1220
2275
  to: {
1221
2276
  minimum?: string | undefined;
@@ -1235,7 +2290,7 @@ declare const app: Elysia<"", {
1235
2290
  address: string;
1236
2291
  };
1237
2292
  };
1238
- amount: string;
2293
+ expected: string;
1239
2294
  };
1240
2295
  mode: "exact_input";
1241
2296
  id: string;
@@ -1364,7 +2419,7 @@ declare const app: Elysia<"", {
1364
2419
  address: string;
1365
2420
  };
1366
2421
  };
1367
- amount: string;
2422
+ expected: string;
1368
2423
  };
1369
2424
  to: {
1370
2425
  currency: {
@@ -1383,7 +2438,7 @@ declare const app: Elysia<"", {
1383
2438
  address: string;
1384
2439
  };
1385
2440
  };
1386
- amount: string;
2441
+ expected: string;
1387
2442
  };
1388
2443
  mode: "exact_output";
1389
2444
  id: string;
@@ -1587,6 +2642,7 @@ declare class SwapRouterApiError extends Error {
1587
2642
  * token: { kind: 'TOKEN', address: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', decimals: 8 },
1588
2643
  * },
1589
2644
  * amount: '100000', // 0.001 BTC in sats
2645
+ * slippageBps: 100, // 1%
1590
2646
  * })
1591
2647
  *
1592
2648
  * if (error) {
@@ -1595,7 +2651,7 @@ declare class SwapRouterApiError extends Error {
1595
2651
  * }
1596
2652
  *
1597
2653
  * console.log('Quote ID:', quote.id)
1598
- * console.log('You will receive:', quote.to.amount)
2654
+ * console.log('You will receive:', quote.to.expected)
1599
2655
  *
1600
2656
  * // Create a swap from the quote
1601
2657
  * const { data: swap, error: swapError } = await api.swap.post({
@@ -1666,6 +2722,13 @@ interface QuoteParameters {
1666
2722
  amount: string;
1667
2723
  /** Whether amount refers to input or output */
1668
2724
  mode: "exact_input" | "exact_output";
2725
+ /**
2726
+ * Slippage tolerance in basis points (1% = 100).
2727
+ *
2728
+ * Required for all quotes. Used for DEX-backed routes to compute
2729
+ * `minimum`/`maximum` bounds; direct OTC routes may ignore it.
2730
+ */
2731
+ slippageBps: number;
1669
2732
  /** Optional DEX quote quality target for DEX-backed routes. */
1670
2733
  quoteQuality?: QuoteQuality;
1671
2734
  /**
@@ -1717,10 +2780,10 @@ interface GetQuoteResult {
1717
2780
  }
1718
2781
  interface SwapResult {
1719
2782
  swapId: string;
1720
- status: SwapStatus2;
2783
+ status: SwapStatus4;
1721
2784
  rift: RiftSwap;
1722
2785
  }
1723
- type SwapStatus2 = SwapStatus;
2786
+ type SwapStatus4 = SwapStatus;
1724
2787
  /**
1725
2788
  * Function type for sending Bitcoin.
1726
2789
  * Implementers provide this function to handle BTC transactions in their app.
@@ -1791,9 +2854,10 @@ declare class RiftSdk {
1791
2854
  * to: Currencies.Bitcoin.BTC,
1792
2855
  * amount: '100000000', // 1 cbBTC
1793
2856
  * mode: 'exact_input',
2857
+ * slippageBps: 100, // 1%
1794
2858
  * })
1795
2859
  *
1796
- * console.log(`You'll receive: ${quote.to.amount} sats`)
2860
+ * console.log(`You'll receive: ${quote.to.expected} sats`)
1797
2861
  * const swap = await executeSwap({
1798
2862
  * destinationAddress: 'bc1q...',
1799
2863
  * publicClient,
@@ -1832,4 +2896,4 @@ declare class RiftSdk {
1832
2896
  getSwapStatus(swapId: string): Promise<SwapStatusResponse>;
1833
2897
  }
1834
2898
  declare function createRiftSdk(options: RiftSdkOptions): RiftSdk;
1835
- export { getSupportedModes, detectRoute, createRiftSdk, createCurrency, createClient, TokenIdentifier, SwapStatus2 as SwapStatus, SwapRouterApiError, SwapRoute, SwapResult, SwapResponse, SupportedModes, SendBitcoinFn, RiftSwap, RiftSdkOptions, RiftSdk, RiftClient, QuoteResult, QuoteQuality, QuoteParameters, NativeToken, GetQuoteResult, ExecutionStep, ExecutionAction, ExecuteSwapOptions, EvmChain, EvmCallStep, EvmCallKind, Erc20Token, Currency, Currencies, Chain, BtcTransferStep, BtcTransferKind, BitcoinChain, App };
2899
+ export { getSupportedModes, detectRoute, createRiftSdk, createCurrency, createClient, TokenIdentifier, SwapStatus4 as SwapStatus, SwapRouterApiError, SwapRoute, SwapResult, SwapResponse, SupportedModes, SendBitcoinFn, RiftSwap, RiftSdkOptions, RiftSdk, RiftClient, QuoteResult, QuoteQuality, QuoteParameters, NativeToken, GetQuoteResult, ExecutionStep, ExecutionAction, ExecuteSwapOptions, EvmChain, EvmCallStep, EvmCallKind, Erc20Token, Currency, Currencies, Chain, BtcTransferStep, BtcTransferKind, BitcoinChain, App };