@breeztech/breez-sdk-spark 0.16.1-dev1 → 0.17.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.
@@ -490,7 +490,7 @@ class MigrationManager {
490
490
  // Add deposit_vout to distinguish deposits sharing a funding tx. The
491
491
  // new field is carried inside the JSON `details` blob. We can't safely
492
492
  // backfill vout on the existing blobs: we never stored the original SSP
493
- // output_index, and vout=0 is a valid output index defaulting would
493
+ // output_index, and vout=0 is a valid output index, so defaulting would
494
494
  // silently mislabel. Instead we clear `details` on legacy deposit blobs
495
495
  // so the read path returns `details: None` (matches what the SQL
496
496
  // backends do by leaving the payments row but having no matching
@@ -545,6 +545,47 @@ class MigrationManager {
545
545
  }
546
546
  },
547
547
  },
548
+ {
549
+ name: "Backfill conversion_info type discriminator for serde tagged enum",
550
+ upgrade: (db, transaction) => {
551
+ if (db.objectStoreNames.contains("payment_metadata")) {
552
+ const store = transaction.objectStore("payment_metadata");
553
+ const request = store.openCursor();
554
+ request.onsuccess = (event) => {
555
+ const cursor = event.target.result;
556
+ if (cursor) {
557
+ const record = cursor.value;
558
+ if (record.conversionInfo) {
559
+ try {
560
+ const ci = typeof record.conversionInfo === "string"
561
+ ? JSON.parse(record.conversionInfo)
562
+ : record.conversionInfo;
563
+ if (!ci.type) {
564
+ ci.type = "amm";
565
+ record.conversionInfo = JSON.stringify(ci);
566
+ cursor.update(record);
567
+ }
568
+ } catch (e) {
569
+ // Skip unparseable records
570
+ }
571
+ }
572
+ cursor.continue();
573
+ }
574
+ };
575
+ }
576
+ },
577
+ },
578
+ {
579
+ // listActiveCrossChainSwaps scans and filters.
580
+ name: "Create cross_chain_swaps store",
581
+ upgrade: (db) => {
582
+ if (!db.objectStoreNames.contains("cross_chain_swaps")) {
583
+ db.createObjectStore("cross_chain_swaps", {
584
+ keyPath: ["provider", "id"],
585
+ });
586
+ }
587
+ },
588
+ },
548
589
  ];
549
590
  }
550
591
  }
@@ -573,7 +614,7 @@ class IndexedDBStorage {
573
614
  // so existing databases depend on indices never shifting. Never insert,
574
615
  // reorder, or delete a migration — only append. dbVersion MUST equal the
575
616
  // number of migrations (enforced by the guard in initialize()).
576
- this.dbVersion = 18; // Current schema version (= migration count)
617
+ this.dbVersion = 20; // Current schema version (= migration count)
577
618
  }
578
619
 
579
620
  /**
@@ -2190,6 +2231,77 @@ class IndexedDBStorage {
2190
2231
  });
2191
2232
  }
2192
2233
 
2234
+ // ===== Cross-Chain Swap Operations =====
2235
+
2236
+ async setCrossChainSwap(swap) {
2237
+ if (!this.db) {
2238
+ throw new StorageError("Database not initialized");
2239
+ }
2240
+
2241
+ return new Promise((resolve, reject) => {
2242
+ const transaction = this.db.transaction("cross_chain_swaps", "readwrite");
2243
+ const store = transaction.objectStore("cross_chain_swaps");
2244
+ // IndexedDB stores nested objects natively, so `data` is kept as-is.
2245
+ const request = store.put(swap);
2246
+ request.onsuccess = () => resolve();
2247
+ request.onerror = () => {
2248
+ reject(
2249
+ new StorageError(
2250
+ `Failed to set cross-chain swap '${swap.provider}:${swap.id}': ${request.error?.message || "Unknown error"}`,
2251
+ request.error
2252
+ )
2253
+ );
2254
+ };
2255
+ });
2256
+ }
2257
+
2258
+ async getCrossChainSwap(provider, id) {
2259
+ if (!this.db) {
2260
+ throw new StorageError("Database not initialized");
2261
+ }
2262
+
2263
+ return new Promise((resolve, reject) => {
2264
+ const transaction = this.db.transaction("cross_chain_swaps", "readonly");
2265
+ const store = transaction.objectStore("cross_chain_swaps");
2266
+ const request = store.get([provider, id]);
2267
+ request.onsuccess = () => resolve(request.result || null);
2268
+ request.onerror = () => {
2269
+ reject(
2270
+ new StorageError(
2271
+ `Failed to get cross-chain swap '${provider}:${id}': ${request.error?.message || "Unknown error"}`,
2272
+ request.error
2273
+ )
2274
+ );
2275
+ };
2276
+ });
2277
+ }
2278
+
2279
+ async listActiveCrossChainSwaps(provider) {
2280
+ if (!this.db) {
2281
+ throw new StorageError("Database not initialized");
2282
+ }
2283
+
2284
+ return new Promise((resolve, reject) => {
2285
+ const transaction = this.db.transaction("cross_chain_swaps", "readonly");
2286
+ const store = transaction.objectStore("cross_chain_swaps");
2287
+ const request = store.getAll();
2288
+ request.onsuccess = () => {
2289
+ const all = request.result || [];
2290
+ resolve(
2291
+ all.filter((swap) => swap.provider === provider && !swap.isTerminal)
2292
+ );
2293
+ };
2294
+ request.onerror = () => {
2295
+ reject(
2296
+ new StorageError(
2297
+ `Failed to list active cross-chain swaps for '${provider}': ${request.error?.message || "Unknown error"}`,
2298
+ request.error
2299
+ )
2300
+ );
2301
+ };
2302
+ });
2303
+ }
2304
+
2193
2305
  // ===== Private Helper Methods =====
2194
2306
 
2195
2307
  _paymentToStore(payment) {
@@ -2265,6 +2377,10 @@ class IndexedDBStorage {
2265
2377
  // Filter by payment details. If any filter matches, we include the payment
2266
2378
  let paymentDetailsFilterMatches = false;
2267
2379
  for (const paymentDetailsFilter of request.paymentDetailsFilter) {
2380
+ // Base type check: the payment's details type must match the filter type
2381
+ if (details.type !== paymentDetailsFilter.type) {
2382
+ continue;
2383
+ }
2268
2384
  // Filter by HTLC status (Spark or Lightning)
2269
2385
  if (
2270
2386
  (paymentDetailsFilter.type === "spark" ||
@@ -2282,11 +2398,12 @@ class IndexedDBStorage {
2282
2398
  continue;
2283
2399
  }
2284
2400
  }
2285
- // Filter by token conversion info presence
2401
+ // Filter by conversion type + status
2286
2402
  if (
2287
2403
  (paymentDetailsFilter.type === "spark" ||
2288
- paymentDetailsFilter.type === "token") &&
2289
- paymentDetailsFilter.conversionRefundNeeded != null
2404
+ paymentDetailsFilter.type === "token" ||
2405
+ paymentDetailsFilter.type === "lightning") &&
2406
+ paymentDetailsFilter.conversionFilter != null
2290
2407
  ) {
2291
2408
  if (
2292
2409
  details.type !== paymentDetailsFilter.type ||
@@ -2295,11 +2412,20 @@ class IndexedDBStorage {
2295
2412
  continue;
2296
2413
  }
2297
2414
 
2298
- if (
2299
- paymentDetailsFilter.conversionRefundNeeded ===
2300
- (details.conversionInfo.status !== "refundNeeded")
2301
- ) {
2302
- continue;
2415
+ const ci = details.conversionInfo;
2416
+ if (paymentDetailsFilter.conversionFilter === "ammRefundNeeded") {
2417
+ if (ci.type !== "amm" || ci.status !== "refundNeeded") {
2418
+ continue;
2419
+ }
2420
+ } else if (paymentDetailsFilter.conversionFilter === "orchestraPending") {
2421
+ if (ci.type !== "orchestra" || ["completed", "failed", "refunded"].includes(ci.status)) {
2422
+ continue;
2423
+ }
2424
+ } else if (paymentDetailsFilter.conversionFilter === "boltzPending") {
2425
+ // Boltz conversion lives on the Lightning leg.
2426
+ if (ci.type !== "boltz" || ["completed", "failed", "refunded"].includes(ci.status)) {
2427
+ continue;
2428
+ }
2303
2429
  }
2304
2430
  }
2305
2431
  // Filter by token transaction hash
@@ -2440,17 +2566,23 @@ class IndexedDBStorage {
2440
2566
  );
2441
2567
  }
2442
2568
  }
2443
- } else if (details.type == "spark" || details.type == "token") {
2444
- // If conversionInfo exists, parse and add to details
2445
- if (metadata.conversionInfo) {
2446
- try {
2447
- details.conversionInfo = JSON.parse(metadata.conversionInfo);
2448
- } catch (e) {
2449
- throw new StorageError(
2450
- `Failed to parse conversionInfo JSON for payment ${payment.id}: ${e.message}`,
2451
- e
2452
- );
2453
- }
2569
+ }
2570
+
2571
+ // conversionInfo is surfaced on Lightning (Boltz hold-invoice pay),
2572
+ // Spark, and Token details — every variant that can carry a conversion.
2573
+ if (
2574
+ (details.type == "lightning" ||
2575
+ details.type == "spark" ||
2576
+ details.type == "token") &&
2577
+ metadata.conversionInfo
2578
+ ) {
2579
+ try {
2580
+ details.conversionInfo = JSON.parse(metadata.conversionInfo);
2581
+ } catch (e) {
2582
+ throw new StorageError(
2583
+ `Failed to parse conversionInfo JSON for payment ${payment.id}: ${e.message}`,
2584
+ e
2585
+ );
2454
2586
  }
2455
2587
  }
2456
2588
  }
@@ -605,6 +605,7 @@ export interface Config {
605
605
  maxConcurrentClaims: number;
606
606
  sparkConfig?: SparkConfig;
607
607
  backgroundTasksEnabled: boolean;
608
+ crossChainConfig?: CrossChainConfig;
608
609
  }
609
610
 
610
611
  export interface ConnectRequest {
@@ -621,10 +622,23 @@ export interface Contact {
621
622
  updatedAt: number;
622
623
  }
623
624
 
625
+ export interface Conversion {
626
+ provider: ConversionProvider;
627
+ status: ConversionStatus;
628
+ from: ConversionSide;
629
+ to: ConversionSide;
630
+ amountAdjustment?: AmountAdjustmentReason;
631
+ }
632
+
633
+ export interface ConversionAsset {
634
+ ticker: string;
635
+ identifier?: string;
636
+ decimals: number;
637
+ }
638
+
624
639
  export interface ConversionDetails {
625
640
  status: ConversionStatus;
626
- from?: ConversionStep;
627
- to?: ConversionStep;
641
+ conversions?: Conversion[];
628
642
  }
629
643
 
630
644
  export interface ConversionEstimate {
@@ -635,28 +649,17 @@ export interface ConversionEstimate {
635
649
  amountAdjustment?: AmountAdjustmentReason;
636
650
  }
637
651
 
638
- export interface ConversionInfo {
639
- poolId: string;
640
- conversionId: string;
641
- status: ConversionStatus;
642
- fee?: string;
643
- purpose?: ConversionPurpose;
644
- amountAdjustment?: AmountAdjustmentReason;
645
- }
646
-
647
652
  export interface ConversionOptions {
648
653
  conversionType: ConversionType;
649
654
  maxSlippageBps?: number;
650
655
  completionTimeoutSecs?: number;
651
656
  }
652
657
 
653
- export interface ConversionStep {
654
- paymentId: string;
655
- amount: bigint;
656
- fee: bigint;
657
- method: PaymentMethod;
658
- tokenMetadata?: TokenMetadata;
659
- amountAdjustment?: AmountAdjustmentReason;
658
+ export interface ConversionSide {
659
+ chain: ConversionChain;
660
+ asset: ConversionAsset;
661
+ amount: string;
662
+ fee: string;
660
663
  }
661
664
 
662
665
  export interface CreateIssuerTokenRequest {
@@ -672,6 +675,30 @@ export interface Credentials {
672
675
  password: string;
673
676
  }
674
677
 
678
+ export interface CrossChainAddressDetails {
679
+ address: string;
680
+ addressFamily: CrossChainAddressFamily;
681
+ contractAddress?: string;
682
+ chainId?: number;
683
+ amount?: bigint;
684
+ }
685
+
686
+ export interface CrossChainConfig {
687
+ defaultSlippageBps?: number;
688
+ defaultTargetOverpayBps?: number;
689
+ }
690
+
691
+ export interface CrossChainRoutePair {
692
+ provider: CrossChainProvider;
693
+ chain: string;
694
+ chainId?: string;
695
+ asset: string;
696
+ contractAddress?: string;
697
+ decimals: number;
698
+ exactOutEligible: boolean;
699
+ supportedSources: SourceAsset[];
700
+ }
701
+
675
702
  export interface CurrencyInfo {
676
703
  name: string;
677
704
  fractionSize: number;
@@ -1208,7 +1235,7 @@ export interface PrepareLnurlPayResponse {
1208
1235
  }
1209
1236
 
1210
1237
  export interface PrepareSendPaymentRequest {
1211
- paymentRequest: string;
1238
+ paymentRequest: PaymentRequest;
1212
1239
  amount?: bigint;
1213
1240
  tokenIdentifier?: string;
1214
1241
  conversionOptions?: ConversionOptions;
@@ -1429,6 +1456,7 @@ export interface SparkSigningOperator {
1429
1456
  identifier: string;
1430
1457
  address: string;
1431
1458
  identityPublicKey: string;
1459
+ caCertPem?: string;
1432
1460
  }
1433
1461
 
1434
1462
  export interface SparkSspConfig {
@@ -1481,6 +1509,9 @@ export interface Storage {
1481
1509
  getContact: (id: string) => Promise<Contact>;
1482
1510
  insertContact: (contact: Contact) => Promise<void>;
1483
1511
  deleteContact: (id: string) => Promise<void>;
1512
+ setCrossChainSwap: (swap: StoredCrossChainSwap) => Promise<void>;
1513
+ getCrossChainSwap: (provider: string, id: string) => Promise<StoredCrossChainSwap | null>;
1514
+ listActiveCrossChainSwaps: (provider: string) => Promise<StoredCrossChainSwap[]>;
1484
1515
  syncAddOutgoingChange: (record: UnversionedRecordChange) => Promise<number>;
1485
1516
  syncCompleteOutgoingSync: (record: Record) => Promise<void>;
1486
1517
  syncGetPendingOutgoingChanges: (limit: number) => Promise<OutgoingChange[]>;
@@ -1504,6 +1535,15 @@ export interface StorageListPaymentsRequest {
1504
1535
  sortAscending?: boolean;
1505
1536
  }
1506
1537
 
1538
+ export interface StoredCrossChainSwap {
1539
+ provider: string;
1540
+ id: string;
1541
+ isTerminal: boolean;
1542
+ updatedAt: number;
1543
+ data: string;
1544
+ secrets: string;
1545
+ }
1546
+
1507
1547
  export interface Symbol {
1508
1548
  grapheme?: string;
1509
1549
  template?: string;
@@ -1637,12 +1677,30 @@ export type BuyBitcoinRequest = { type: "moonpay"; lockedAmountSat?: number; red
1637
1677
 
1638
1678
  export type ChainApiType = "esplora" | "mempoolSpace";
1639
1679
 
1680
+ export type ConversionChain = { type: "spark" } | { type: "lightning" } | { type: "external"; name: string; chainId?: string };
1681
+
1682
+ export type ConversionFilter = "ammRefundNeeded" | "orchestraPending" | "boltzPending";
1683
+
1684
+ export type ConversionInfo = { type: "amm"; poolId: string; conversionId: string; status: ConversionStatus; fee?: string; purpose?: ConversionPurpose; amountAdjustment?: AmountAdjustmentReason } | { type: "orchestra"; chain: string; chainId?: string; asset?: string; assetContract?: string; recipientAddress: string; assetAmountIn?: string; estimatedOut: string; deliveredAmount?: string; status: ConversionStatus; feeAmount?: string; serviceFeeAmount?: string; serviceFeeAsset?: string; assetDecimals: number; orderId: string; quoteId: string; readToken?: string } | { type: "boltz"; chain: string; chainId?: string; asset?: string; assetContract?: string; recipientAddress: string; assetAmountIn?: string; estimatedOut: string; deliveredAmount?: string; status: ConversionStatus; feeAmount?: string; serviceFeeAmount?: string; serviceFeeAsset?: string; assetDecimals: number; swapId: string; invoice: string; invoiceAmountSats: number; bridgeRef?: string; maxSlippageBps: number; quoteDegraded?: boolean };
1685
+
1686
+ export type ConversionProvider = "amm" | "orchestra" | "boltz";
1687
+
1640
1688
  export type ConversionPurpose = { type: "ongoingPayment"; paymentRequest: string } | { type: "selfTransfer" } | { type: "autoConversion" };
1641
1689
 
1642
1690
  export type ConversionStatus = "pending" | "completed" | "failed" | "refundNeeded" | "refunded";
1643
1691
 
1644
1692
  export type ConversionType = { type: "fromBitcoin" } | { type: "toBitcoin"; fromTokenIdentifier: string };
1645
1693
 
1694
+ export type CrossChainAddressFamily = "evm" | "solana" | "tron";
1695
+
1696
+ export type CrossChainFeeMode = "feesExcluded" | "feesIncluded";
1697
+
1698
+ export type CrossChainProvider = "orchestra" | "boltz";
1699
+
1700
+ export type CrossChainProviderContext = { type: "orchestra"; quoteId: string; depositAddress: string; depositAmount?: string } | { type: "boltz"; swapId: string; invoice: string; invoiceAmountSats?: number; maxSlippageBps: number };
1701
+
1702
+ export type CrossChainRouteFilter = { type: "send"; addressDetails: CrossChainAddressDetails } | { type: "receive"; contractAddress?: string };
1703
+
1646
1704
  export type DepositClaimError = { type: "maxDepositClaimFeeExceeded"; tx: string; vout: number; maxFee?: Fee; requiredFeeSats: number; requiredFeeRateSatPerVbyte: number } | { type: "missingUtxo"; tx: string; vout: number } | { type: "generic"; message: string };
1647
1705
 
1648
1706
  export type ExternalFrostDerivation = { type: "signingLeaf"; leafId: ExternalTreeNodeId } | { type: "staticDeposit"; index: number } | { type: "htlcPreimage" } | { type: "identity" };
@@ -1655,7 +1713,7 @@ export type Fee = { type: "fixed"; amount: number } | { type: "rate"; satPerVbyt
1655
1713
 
1656
1714
  export type FeePolicy = "feesExcluded" | "feesIncluded";
1657
1715
 
1658
- export type InputType = ({ type: "bitcoinAddress" } & BitcoinAddressDetails) | ({ type: "bolt11Invoice" } & Bolt11InvoiceDetails) | ({ type: "bolt12Invoice" } & Bolt12InvoiceDetails) | ({ type: "bolt12Offer" } & Bolt12OfferDetails) | ({ type: "lightningAddress" } & LightningAddressDetails) | ({ type: "lnurlPay" } & LnurlPayRequestDetails) | ({ type: "silentPaymentAddress" } & SilentPaymentAddressDetails) | ({ type: "lnurlAuth" } & LnurlAuthRequestDetails) | ({ type: "url" } & string) | ({ type: "bip21" } & Bip21Details) | ({ type: "bolt12InvoiceRequest" } & Bolt12InvoiceRequestDetails) | ({ type: "lnurlWithdraw" } & LnurlWithdrawRequestDetails) | ({ type: "sparkAddress" } & SparkAddressDetails) | ({ type: "sparkInvoice" } & SparkInvoiceDetails);
1716
+ export type InputType = ({ type: "bitcoinAddress" } & BitcoinAddressDetails) | ({ type: "bolt11Invoice" } & Bolt11InvoiceDetails) | ({ type: "bolt12Invoice" } & Bolt12InvoiceDetails) | ({ type: "bolt12Offer" } & Bolt12OfferDetails) | ({ type: "lightningAddress" } & LightningAddressDetails) | ({ type: "lnurlPay" } & LnurlPayRequestDetails) | ({ type: "silentPaymentAddress" } & SilentPaymentAddressDetails) | ({ type: "lnurlAuth" } & LnurlAuthRequestDetails) | ({ type: "url" } & string) | ({ type: "bip21" } & Bip21Details) | ({ type: "bolt12InvoiceRequest" } & Bolt12InvoiceRequestDetails) | ({ type: "lnurlWithdraw" } & LnurlWithdrawRequestDetails) | ({ type: "sparkAddress" } & SparkAddressDetails) | ({ type: "sparkInvoice" } & SparkInvoiceDetails) | ({ type: "crossChainAddress" } & CrossChainAddressDetails);
1659
1717
 
1660
1718
  export type LnurlCallbackStatus = { type: "ok" } | { type: "errorStatus"; errorDetails: LnurlErrorDetails };
1661
1719
 
@@ -1669,12 +1727,14 @@ export type OptimizationMode = "full" | "singleRound";
1669
1727
 
1670
1728
  export type OptimizationOutcome = { type: "completed"; roundsExecuted: number } | { type: "inProgress" };
1671
1729
 
1672
- export type PaymentDetails = { type: "spark"; invoiceDetails?: SparkInvoicePaymentDetails; htlcDetails?: SparkHtlcDetails; conversionInfo?: ConversionInfo } | { type: "token"; metadata: TokenMetadata; txHash: string; txType: TokenTransactionType; invoiceDetails?: SparkInvoicePaymentDetails; conversionInfo?: ConversionInfo } | { type: "lightning"; description?: string; invoice: string; destinationPubkey: string; htlcDetails: SparkHtlcDetails; lnurlPayInfo?: LnurlPayInfo; lnurlWithdrawInfo?: LnurlWithdrawInfo; lnurlReceiveMetadata?: LnurlReceiveMetadata } | { type: "withdraw"; txId: string } | { type: "deposit"; txId: string; vout: number };
1730
+ export type PaymentDetails = { type: "spark"; invoiceDetails?: SparkInvoicePaymentDetails; htlcDetails?: SparkHtlcDetails; conversionInfo?: ConversionInfo } | { type: "token"; metadata: TokenMetadata; txHash: string; txType: TokenTransactionType; invoiceDetails?: SparkInvoicePaymentDetails; conversionInfo?: ConversionInfo } | { type: "lightning"; description?: string; invoice: string; destinationPubkey: string; htlcDetails: SparkHtlcDetails; lnurlPayInfo?: LnurlPayInfo; lnurlWithdrawInfo?: LnurlWithdrawInfo; lnurlReceiveMetadata?: LnurlReceiveMetadata; conversionInfo?: ConversionInfo } | { type: "withdraw"; txId: string } | { type: "deposit"; txId: string; vout: number };
1673
1731
 
1674
1732
  export type PaymentDetailsFilter = { type: "spark"; htlcStatus?: SparkHtlcStatus[]; conversionRefundNeeded?: boolean } | { type: "token"; conversionRefundNeeded?: boolean; txHash?: string; txType?: TokenTransactionType } | { type: "lightning"; htlcStatus?: SparkHtlcStatus[] };
1675
1733
 
1676
1734
  export type PaymentMethod = "lightning" | "spark" | "token" | "deposit" | "withdraw" | "unknown";
1677
1735
 
1736
+ export type PaymentRequest = { type: "input"; input: string } | { type: "crossChain"; address: string; route: CrossChainRoutePair; maxSlippageBps?: number; targetOverpayBps?: number };
1737
+
1678
1738
  export type PaymentStatus = "completed" | "pending" | "failed";
1679
1739
 
1680
1740
  export type PaymentType = "send" | "receive";
@@ -1687,7 +1747,7 @@ export type SdkEvent = { type: "synced" } | { type: "unclaimedDeposits"; unclaim
1687
1747
 
1688
1748
  export type Seed = { type: "mnemonic"; mnemonic: string; passphrase?: string } | ({ type: "entropy" } & number[]);
1689
1749
 
1690
- export type SendPaymentMethod = { type: "bitcoinAddress"; address: BitcoinAddressDetails; feeQuote: SendOnchainFeeQuote } | { type: "bolt11Invoice"; invoiceDetails: Bolt11InvoiceDetails; sparkTransferFeeSats?: number; lightningFeeSats: number } | { type: "sparkAddress"; address: string; fee: string; tokenIdentifier?: string } | { type: "sparkInvoice"; sparkInvoiceDetails: SparkInvoiceDetails; fee: string; tokenIdentifier?: string };
1750
+ export type SendPaymentMethod = { type: "bitcoinAddress"; address: BitcoinAddressDetails; feeQuote: SendOnchainFeeQuote } | { type: "bolt11Invoice"; invoiceDetails: Bolt11InvoiceDetails; sparkTransferFeeSats?: number; lightningFeeSats: number } | { type: "sparkAddress"; address: string; fee: string; tokenIdentifier?: string } | { type: "sparkInvoice"; sparkInvoiceDetails: SparkInvoiceDetails; fee: string; tokenIdentifier?: string } | { type: "crossChainAddress"; route: CrossChainRoutePair; recipientAddress: string; amountIn: string; assetAmountIn: string; estimatedOut: string; feeAmount: string; serviceFeeAmount: string; serviceFeeAsset?: string; sourceTransferFeeSats: number; feeMode: CrossChainFeeMode; expiresAt: string; providerContext: CrossChainProviderContext };
1691
1751
 
1692
1752
  export type SendPaymentOptions = { type: "bitcoinAddress"; confirmationSpeed: OnchainConfirmationSpeed } | { type: "bolt11Invoice"; preferSpark: boolean; completionTimeoutSecs?: number } | { type: "sparkAddress"; htlcOptions?: SparkHtlcOptions };
1693
1753
 
@@ -1695,11 +1755,13 @@ export type ServiceStatus = "operational" | "degraded" | "partial" | "unknown" |
1695
1755
 
1696
1756
  export type SessionStoreError = { type: "notFound" } | ({ type: "generic" } & string);
1697
1757
 
1758
+ export type SourceAsset = { type: "bitcoin" } | { type: "token"; tokenIdentifier: string };
1759
+
1698
1760
  export type SparkHtlcStatus = "waitingForPreimage" | "preimageShared" | "returned";
1699
1761
 
1700
1762
  export type StableBalanceActiveLabel = { type: "set"; label: string } | { type: "unset" };
1701
1763
 
1702
- export type StoragePaymentDetailsFilter = { type: "spark"; htlcStatus?: SparkHtlcStatus[]; conversionRefundNeeded?: boolean } | { type: "token"; conversionRefundNeeded?: boolean; txHash?: string; txType?: TokenTransactionType } | { type: "lightning"; htlcStatus?: SparkHtlcStatus[] };
1764
+ export type StoragePaymentDetailsFilter = { type: "spark"; htlcStatus?: SparkHtlcStatus[]; conversionFilter?: ConversionFilter } | { type: "token"; conversionFilter?: ConversionFilter; txHash?: string; txType?: TokenTransactionType } | { type: "lightning"; htlcStatus?: SparkHtlcStatus[]; conversionFilter?: ConversionFilter };
1703
1765
 
1704
1766
  export type SuccessAction = { type: "aes"; data: AesSuccessActionData } | { type: "message"; data: MessageSuccessActionData } | { type: "url"; data: UrlSuccessActionData };
1705
1767
 
@@ -1748,6 +1810,7 @@ export class BreezSdk {
1748
1810
  deleteLightningAddress(): Promise<void>;
1749
1811
  disconnect(): Promise<void>;
1750
1812
  fetchConversionLimits(request: FetchConversionLimitsRequest): Promise<FetchConversionLimitsResponse>;
1813
+ getCrossChainRoutes(filter: CrossChainRouteFilter): Promise<CrossChainRoutePair[]>;
1751
1814
  getInfo(request: GetInfoRequest): Promise<GetInfoResponse>;
1752
1815
  getLightningAddress(): Promise<LightningAddressInfo | undefined>;
1753
1816
  getPayment(request: GetPaymentRequest): Promise<GetPaymentResponse>;
@@ -2092,6 +2155,14 @@ export function newSharedSdkContext(config: WasmSdkContextConfig): Promise<WasmS
2092
2155
  */
2093
2156
  export function postgresStorage(config: PostgresStorageConfig): WasmStorageConfig;
2094
2157
 
2158
+ /**
2159
+ * Runs automatically when the wasm module is instantiated. Installs the
2160
+ * panic hook so Rust panics surface as readable `console.error` output
2161
+ * (with the panic message + `file.rs:line`) instead of a bare
2162
+ * `RuntimeError: unreachable`.
2163
+ */
2164
+ export function start(): void;
2165
+
2095
2166
  /**
2096
2167
  * Entry point invoked by JavaScript in a worker.
2097
2168
  */