@routstr/sdk 0.2.3 → 0.2.5

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.
Files changed (38) hide show
  1. package/README.md +9 -0
  2. package/dist/client/index.d.mts +21 -8
  3. package/dist/client/index.d.ts +21 -8
  4. package/dist/client/index.js +1406 -69
  5. package/dist/client/index.js.map +1 -1
  6. package/dist/client/index.mjs +1406 -70
  7. package/dist/client/index.mjs.map +1 -1
  8. package/dist/discovery/index.d.mts +2 -2
  9. package/dist/discovery/index.d.ts +2 -2
  10. package/dist/discovery/index.js +1 -4
  11. package/dist/discovery/index.js.map +1 -1
  12. package/dist/discovery/index.mjs +1 -4
  13. package/dist/discovery/index.mjs.map +1 -1
  14. package/dist/index.d.mts +15 -19
  15. package/dist/index.d.ts +15 -19
  16. package/dist/index.js +2385 -1574
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.mjs +2380 -1575
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/{interfaces-DGdP8fQp.d.mts → interfaces-BWJJTCXO.d.mts} +1 -1
  21. package/dist/{interfaces-CC0LT9p9.d.ts → interfaces-BxDEka72.d.ts} +1 -1
  22. package/dist/{interfaces-B85Wx7ni.d.mts → interfaces-C6Dr6hKy.d.mts} +1 -1
  23. package/dist/{interfaces-BVNyAmKu.d.ts → interfaces-CluftN4z.d.ts} +1 -1
  24. package/dist/storage/index.d.mts +56 -34
  25. package/dist/storage/index.d.ts +56 -34
  26. package/dist/storage/index.js +500 -51
  27. package/dist/storage/index.js.map +1 -1
  28. package/dist/storage/index.mjs +497 -52
  29. package/dist/storage/index.mjs.map +1 -1
  30. package/dist/{types-BlHjmWRK.d.mts → types-BYj_8c5c.d.mts} +3 -0
  31. package/dist/{types-BlHjmWRK.d.ts → types-BYj_8c5c.d.ts} +3 -0
  32. package/dist/wallet/index.d.mts +9 -5
  33. package/dist/wallet/index.d.ts +9 -5
  34. package/dist/wallet/index.js +54 -22
  35. package/dist/wallet/index.js.map +1 -1
  36. package/dist/wallet/index.mjs +54 -22
  37. package/dist/wallet/index.mjs.map +1 -1
  38. package/package.json +1 -1
@@ -300,8 +300,439 @@ var SDK_STORAGE_KEYS = {
300
300
  CLIENT_IDS: "client_ids"
301
301
  };
302
302
 
303
- // storage/store.ts
303
+ // storage/usageTracking/indexedDB.ts
304
+ var DEFAULT_DB_NAME = "routstr-sdk";
305
+ var DEFAULT_STORE_NAME = "usage_tracking";
306
+ var MIGRATION_MARKER_KEY = "usage_tracking_migration_v1";
307
+ var isBrowser2 = typeof indexedDB !== "undefined";
304
308
  var normalizeBaseUrl = (baseUrl) => baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
309
+ var openDatabase2 = (dbName, storeName) => {
310
+ if (!isBrowser2) {
311
+ return Promise.reject(new Error("IndexedDB is not available"));
312
+ }
313
+ return new Promise((resolve, reject) => {
314
+ const request = indexedDB.open(dbName, 1);
315
+ request.onupgradeneeded = () => {
316
+ const db = request.result;
317
+ if (!db.objectStoreNames.contains(storeName)) {
318
+ const store = db.createObjectStore(storeName, { keyPath: "id" });
319
+ store.createIndex("timestamp", "timestamp", { unique: false });
320
+ store.createIndex("modelId", "modelId", { unique: false });
321
+ store.createIndex("baseUrl", "baseUrl", { unique: false });
322
+ store.createIndex("sessionId", "sessionId", { unique: false });
323
+ store.createIndex("client", "client", { unique: false });
324
+ }
325
+ };
326
+ request.onsuccess = () => resolve(request.result);
327
+ request.onerror = () => reject(request.error);
328
+ });
329
+ };
330
+ var matchesFilters = (entry, options = {}) => {
331
+ if (typeof options.before === "number" && entry.timestamp >= options.before) {
332
+ return false;
333
+ }
334
+ if (typeof options.after === "number" && entry.timestamp <= options.after) {
335
+ return false;
336
+ }
337
+ if (options.modelId && entry.modelId !== options.modelId) {
338
+ return false;
339
+ }
340
+ if (options.baseUrl && normalizeBaseUrl(entry.baseUrl) !== normalizeBaseUrl(options.baseUrl)) {
341
+ return false;
342
+ }
343
+ if (options.sessionId && entry.sessionId !== options.sessionId) {
344
+ return false;
345
+ }
346
+ if (options.client && entry.client !== options.client) {
347
+ return false;
348
+ }
349
+ return true;
350
+ };
351
+ var createIndexedDBUsageTrackingDriver = (options = {}) => {
352
+ const dbName = options.dbName || DEFAULT_DB_NAME;
353
+ const storeName = options.storeName || DEFAULT_STORE_NAME;
354
+ const legacyStorageDriver = options.legacyStorageDriver;
355
+ let dbPromise = null;
356
+ let migrationPromise = null;
357
+ const getDb = () => {
358
+ if (!dbPromise) {
359
+ dbPromise = openDatabase2(dbName, storeName);
360
+ }
361
+ return dbPromise;
362
+ };
363
+ const putMany = async (entries) => {
364
+ if (entries.length === 0) return;
365
+ const db = await getDb();
366
+ await new Promise((resolve, reject) => {
367
+ const tx = db.transaction(storeName, "readwrite");
368
+ const store = tx.objectStore(storeName);
369
+ for (const entry of entries) {
370
+ store.put({ ...entry, baseUrl: normalizeBaseUrl(entry.baseUrl) });
371
+ }
372
+ tx.oncomplete = () => resolve();
373
+ tx.onerror = () => reject(tx.error);
374
+ });
375
+ };
376
+ const ensureMigrated = async () => {
377
+ if (!legacyStorageDriver) return;
378
+ if (!migrationPromise) {
379
+ migrationPromise = (async () => {
380
+ const migrated = await legacyStorageDriver.getItem(
381
+ MIGRATION_MARKER_KEY,
382
+ false
383
+ );
384
+ if (migrated) return;
385
+ const legacyEntries = await legacyStorageDriver.getItem(
386
+ SDK_STORAGE_KEYS.USAGE_TRACKING,
387
+ []
388
+ );
389
+ if (legacyEntries.length > 0) {
390
+ await putMany(legacyEntries);
391
+ await legacyStorageDriver.removeItem(SDK_STORAGE_KEYS.USAGE_TRACKING);
392
+ }
393
+ await legacyStorageDriver.setItem(MIGRATION_MARKER_KEY, true);
394
+ })();
395
+ }
396
+ await migrationPromise;
397
+ };
398
+ return {
399
+ async migrate() {
400
+ await ensureMigrated();
401
+ },
402
+ async append(entry) {
403
+ await ensureMigrated();
404
+ await putMany([entry]);
405
+ },
406
+ async appendMany(entries) {
407
+ await ensureMigrated();
408
+ await putMany(entries);
409
+ },
410
+ async list(options2 = {}) {
411
+ await ensureMigrated();
412
+ const db = await getDb();
413
+ return new Promise((resolve, reject) => {
414
+ const tx = db.transaction(storeName, "readonly");
415
+ const store = tx.objectStore(storeName);
416
+ const index = store.index("timestamp");
417
+ const direction = "prev";
418
+ const request = index.openCursor(null, direction);
419
+ const results = [];
420
+ const limit = options2.limit;
421
+ request.onsuccess = () => {
422
+ const cursor = request.result;
423
+ if (!cursor) {
424
+ resolve(results);
425
+ return;
426
+ }
427
+ const value = cursor.value;
428
+ if (matchesFilters(value, options2)) {
429
+ results.push(value);
430
+ if (typeof limit === "number" && results.length >= limit) {
431
+ resolve(results);
432
+ return;
433
+ }
434
+ }
435
+ cursor.continue();
436
+ };
437
+ request.onerror = () => reject(request.error);
438
+ });
439
+ },
440
+ async count(options2 = {}) {
441
+ const results = await this.list(options2);
442
+ return results.length;
443
+ },
444
+ async deleteOlderThan(timestamp) {
445
+ await ensureMigrated();
446
+ const db = await getDb();
447
+ return new Promise((resolve, reject) => {
448
+ const tx = db.transaction(storeName, "readwrite");
449
+ const store = tx.objectStore(storeName);
450
+ const index = store.index("timestamp");
451
+ const range = IDBKeyRange.upperBound(timestamp, true);
452
+ const request = index.openCursor(range);
453
+ let deleted = 0;
454
+ request.onsuccess = () => {
455
+ const cursor = request.result;
456
+ if (!cursor) {
457
+ resolve(deleted);
458
+ return;
459
+ }
460
+ deleted += 1;
461
+ cursor.delete();
462
+ cursor.continue();
463
+ };
464
+ request.onerror = () => reject(request.error);
465
+ });
466
+ },
467
+ async clear() {
468
+ await ensureMigrated();
469
+ const db = await getDb();
470
+ await new Promise((resolve, reject) => {
471
+ const tx = db.transaction(storeName, "readwrite");
472
+ tx.objectStore(storeName).clear();
473
+ tx.oncomplete = () => resolve();
474
+ tx.onerror = () => reject(tx.error);
475
+ });
476
+ }
477
+ };
478
+ };
479
+
480
+ // storage/usageTracking/sqlite.ts
481
+ var MIGRATION_MARKER_KEY2 = "usage_tracking_migration_v1";
482
+ var normalizeBaseUrl2 = (baseUrl) => baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
483
+ var isBun2 = () => {
484
+ return typeof process.versions.bun !== "undefined";
485
+ };
486
+ var createDatabase2 = (dbPath) => {
487
+ if (isBun2()) {
488
+ throw new Error(
489
+ "SQLite driver not supported in Bun. Use createMemoryDriver() instead."
490
+ );
491
+ }
492
+ let Database = null;
493
+ try {
494
+ Database = __require("better-sqlite3");
495
+ } catch (error) {
496
+ throw new Error(
497
+ `better-sqlite3 is required for sqlite usage tracking. Install it to use sqlite storage. (${error})`
498
+ );
499
+ }
500
+ return new Database(dbPath);
501
+ };
502
+ var buildWhereClause = (options = {}) => {
503
+ const clauses = [];
504
+ const params = [];
505
+ if (typeof options.before === "number") {
506
+ clauses.push("timestamp < ?");
507
+ params.push(options.before);
508
+ }
509
+ if (typeof options.after === "number") {
510
+ clauses.push("timestamp > ?");
511
+ params.push(options.after);
512
+ }
513
+ if (options.modelId) {
514
+ clauses.push("model_id = ?");
515
+ params.push(options.modelId);
516
+ }
517
+ if (options.baseUrl) {
518
+ clauses.push("base_url = ?");
519
+ params.push(normalizeBaseUrl2(options.baseUrl));
520
+ }
521
+ if (options.sessionId) {
522
+ clauses.push("session_id = ?");
523
+ params.push(options.sessionId);
524
+ }
525
+ if (options.client) {
526
+ clauses.push("client = ?");
527
+ params.push(options.client);
528
+ }
529
+ return {
530
+ sql: clauses.length > 0 ? `WHERE ${clauses.join(" AND ")}` : "",
531
+ params
532
+ };
533
+ };
534
+ var createSqliteUsageTrackingDriver = (options = {}) => {
535
+ const dbPath = options.dbPath || "routstr.sqlite";
536
+ const tableName = options.tableName || "usage_tracking";
537
+ const db = createDatabase2(dbPath);
538
+ const legacyStorageDriver = options.legacyStorageDriver;
539
+ db.exec(`
540
+ CREATE TABLE IF NOT EXISTS ${tableName} (
541
+ id TEXT PRIMARY KEY,
542
+ timestamp INTEGER NOT NULL,
543
+ model_id TEXT NOT NULL,
544
+ base_url TEXT NOT NULL,
545
+ request_id TEXT NOT NULL,
546
+ cost REAL NOT NULL,
547
+ sats_cost REAL NOT NULL,
548
+ prompt_tokens INTEGER NOT NULL,
549
+ completion_tokens INTEGER NOT NULL,
550
+ total_tokens INTEGER NOT NULL,
551
+ client TEXT,
552
+ session_id TEXT,
553
+ tags TEXT
554
+ );
555
+ CREATE INDEX IF NOT EXISTS idx_${tableName}_timestamp ON ${tableName}(timestamp);
556
+ CREATE INDEX IF NOT EXISTS idx_${tableName}_model_id ON ${tableName}(model_id);
557
+ CREATE INDEX IF NOT EXISTS idx_${tableName}_base_url ON ${tableName}(base_url);
558
+ CREATE INDEX IF NOT EXISTS idx_${tableName}_session_id ON ${tableName}(session_id);
559
+ CREATE INDEX IF NOT EXISTS idx_${tableName}_client ON ${tableName}(client);
560
+ `);
561
+ const insertStmt = db.prepare(`
562
+ INSERT OR REPLACE INTO ${tableName} (
563
+ id, timestamp, model_id, base_url, request_id,
564
+ cost, sats_cost, prompt_tokens, completion_tokens, total_tokens,
565
+ client, session_id, tags
566
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
567
+ `);
568
+ let migrationComplete = false;
569
+ const appendOne = (entry) => {
570
+ insertStmt.run(
571
+ entry.id,
572
+ entry.timestamp,
573
+ entry.modelId,
574
+ normalizeBaseUrl2(entry.baseUrl),
575
+ entry.requestId,
576
+ entry.cost,
577
+ entry.satsCost,
578
+ entry.promptTokens,
579
+ entry.completionTokens,
580
+ entry.totalTokens,
581
+ entry.client ?? null,
582
+ entry.sessionId ?? null,
583
+ JSON.stringify(entry.tags ?? [])
584
+ );
585
+ };
586
+ const ensureMigrated = async () => {
587
+ if (!legacyStorageDriver || migrationComplete) return;
588
+ const migrated = await legacyStorageDriver.getItem(
589
+ MIGRATION_MARKER_KEY2,
590
+ false
591
+ );
592
+ if (migrated) {
593
+ migrationComplete = true;
594
+ return;
595
+ }
596
+ const legacyEntries = await legacyStorageDriver.getItem(
597
+ SDK_STORAGE_KEYS.USAGE_TRACKING,
598
+ []
599
+ );
600
+ for (const entry of legacyEntries) {
601
+ appendOne(entry);
602
+ }
603
+ if (legacyEntries.length > 0) {
604
+ await legacyStorageDriver.removeItem(SDK_STORAGE_KEYS.USAGE_TRACKING);
605
+ }
606
+ await legacyStorageDriver.setItem(MIGRATION_MARKER_KEY2, true);
607
+ migrationComplete = true;
608
+ };
609
+ const mapRow = (row) => ({
610
+ id: row.id,
611
+ timestamp: row.timestamp,
612
+ modelId: row.model_id,
613
+ baseUrl: row.base_url,
614
+ requestId: row.request_id,
615
+ cost: row.cost,
616
+ satsCost: row.sats_cost,
617
+ promptTokens: row.prompt_tokens,
618
+ completionTokens: row.completion_tokens,
619
+ totalTokens: row.total_tokens,
620
+ client: row.client ?? void 0,
621
+ sessionId: row.session_id ?? void 0,
622
+ tags: typeof row.tags === "string" ? JSON.parse(row.tags) : void 0
623
+ });
624
+ return {
625
+ async migrate() {
626
+ await ensureMigrated();
627
+ },
628
+ async append(entry) {
629
+ await ensureMigrated();
630
+ appendOne(entry);
631
+ },
632
+ async appendMany(entries) {
633
+ await ensureMigrated();
634
+ for (const entry of entries) {
635
+ appendOne(entry);
636
+ }
637
+ },
638
+ async list(options2 = {}) {
639
+ await ensureMigrated();
640
+ const { sql, params } = buildWhereClause(options2);
641
+ const limitSql = typeof options2.limit === "number" ? " LIMIT ?" : "";
642
+ const stmt = db.prepare(
643
+ `SELECT * FROM ${tableName} ${sql} ORDER BY timestamp DESC${limitSql}`
644
+ );
645
+ const rows = stmt.all(
646
+ ...typeof options2.limit === "number" ? [...params, options2.limit] : params
647
+ );
648
+ return rows.map(mapRow);
649
+ },
650
+ async count(options2 = {}) {
651
+ await ensureMigrated();
652
+ const { sql, params } = buildWhereClause(options2);
653
+ const stmt = db.prepare(`SELECT COUNT(*) as count FROM ${tableName} ${sql}`);
654
+ const row = stmt.get(...params);
655
+ return Number(row?.count ?? 0);
656
+ },
657
+ async deleteOlderThan(timestamp) {
658
+ await ensureMigrated();
659
+ const stmt = db.prepare(`DELETE FROM ${tableName} WHERE timestamp < ?`);
660
+ const result = stmt.run(timestamp);
661
+ return result.changes;
662
+ },
663
+ async clear() {
664
+ await ensureMigrated();
665
+ db.prepare(`DELETE FROM ${tableName}`).run();
666
+ }
667
+ };
668
+ };
669
+
670
+ // storage/usageTracking/memory.ts
671
+ var normalizeBaseUrl3 = (baseUrl) => baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
672
+ var matchesFilters2 = (entry, options = {}) => {
673
+ if (typeof options.before === "number" && entry.timestamp >= options.before) {
674
+ return false;
675
+ }
676
+ if (typeof options.after === "number" && entry.timestamp <= options.after) {
677
+ return false;
678
+ }
679
+ if (options.modelId && entry.modelId !== options.modelId) {
680
+ return false;
681
+ }
682
+ if (options.baseUrl && normalizeBaseUrl3(entry.baseUrl) !== normalizeBaseUrl3(options.baseUrl)) {
683
+ return false;
684
+ }
685
+ if (options.sessionId && entry.sessionId !== options.sessionId) {
686
+ return false;
687
+ }
688
+ if (options.client && entry.client !== options.client) {
689
+ return false;
690
+ }
691
+ return true;
692
+ };
693
+ var createMemoryUsageTrackingDriver = (seed = []) => {
694
+ const store = /* @__PURE__ */ new Map();
695
+ for (const entry of seed) {
696
+ store.set(entry.id, { ...entry, baseUrl: normalizeBaseUrl3(entry.baseUrl) });
697
+ }
698
+ return {
699
+ async migrate() {
700
+ return;
701
+ },
702
+ async append(entry) {
703
+ store.set(entry.id, { ...entry, baseUrl: normalizeBaseUrl3(entry.baseUrl) });
704
+ },
705
+ async appendMany(entries) {
706
+ for (const entry of entries) {
707
+ store.set(entry.id, { ...entry, baseUrl: normalizeBaseUrl3(entry.baseUrl) });
708
+ }
709
+ },
710
+ async list(options = {}) {
711
+ const entries = [...store.values()].filter((entry) => matchesFilters2(entry, options)).sort((a, b) => b.timestamp - a.timestamp);
712
+ if (typeof options.limit === "number") {
713
+ return entries.slice(0, options.limit);
714
+ }
715
+ return entries;
716
+ },
717
+ async count(options = {}) {
718
+ return (await this.list(options)).length;
719
+ },
720
+ async deleteOlderThan(timestamp) {
721
+ let deleted = 0;
722
+ for (const [id, entry] of store.entries()) {
723
+ if (entry.timestamp < timestamp) {
724
+ store.delete(id);
725
+ deleted += 1;
726
+ }
727
+ }
728
+ return deleted;
729
+ },
730
+ async clear() {
731
+ store.clear();
732
+ }
733
+ };
734
+ };
735
+ var normalizeBaseUrl4 = (baseUrl) => baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
305
736
  var getCashuTokenBalance = (token) => {
306
737
  try {
307
738
  const decoded = cashuTs.getDecodedToken(token);
@@ -330,12 +761,11 @@ var createEmptyStore = (driver) => vanilla.createStore((set, get) => ({
330
761
  routstr21Models: [],
331
762
  lastRoutstr21ModelsUpdate: null,
332
763
  cachedReceiveTokens: [],
333
- usageTracking: [],
334
764
  clientIds: [],
335
765
  setModelsFromAllProviders: (value) => {
336
766
  const normalized = {};
337
767
  for (const [baseUrl, models] of Object.entries(value)) {
338
- normalized[normalizeBaseUrl(baseUrl)] = models;
768
+ normalized[normalizeBaseUrl4(baseUrl)] = models;
339
769
  }
340
770
  void driver.setItem(
341
771
  SDK_STORAGE_KEYS.MODELS_FROM_ALL_PROVIDERS,
@@ -348,7 +778,7 @@ var createEmptyStore = (driver) => vanilla.createStore((set, get) => ({
348
778
  set({ lastUsedModel: value });
349
779
  },
350
780
  setBaseUrlsList: (value) => {
351
- const normalized = value.map((url) => normalizeBaseUrl(url));
781
+ const normalized = value.map((url) => normalizeBaseUrl4(url));
352
782
  void driver.setItem(SDK_STORAGE_KEYS.BASE_URLS_LIST, normalized);
353
783
  set({ baseUrlsList: normalized });
354
784
  },
@@ -357,14 +787,14 @@ var createEmptyStore = (driver) => vanilla.createStore((set, get) => ({
357
787
  set({ lastBaseUrlsUpdate: value });
358
788
  },
359
789
  setDisabledProviders: (value) => {
360
- const normalized = value.map((url) => normalizeBaseUrl(url));
790
+ const normalized = value.map((url) => normalizeBaseUrl4(url));
361
791
  void driver.setItem(SDK_STORAGE_KEYS.DISABLED_PROVIDERS, normalized);
362
792
  set({ disabledProviders: normalized });
363
793
  },
364
794
  setMintsFromAllProviders: (value) => {
365
795
  const normalized = {};
366
796
  for (const [baseUrl, mints] of Object.entries(value)) {
367
- normalized[normalizeBaseUrl(baseUrl)] = mints.map(
797
+ normalized[normalizeBaseUrl4(baseUrl)] = mints.map(
368
798
  (mint) => mint.endsWith("/") ? mint.slice(0, -1) : mint
369
799
  );
370
800
  }
@@ -377,7 +807,7 @@ var createEmptyStore = (driver) => vanilla.createStore((set, get) => ({
377
807
  setInfoFromAllProviders: (value) => {
378
808
  const normalized = {};
379
809
  for (const [baseUrl, info] of Object.entries(value)) {
380
- normalized[normalizeBaseUrl(baseUrl)] = info;
810
+ normalized[normalizeBaseUrl4(baseUrl)] = info;
381
811
  }
382
812
  void driver.setItem(SDK_STORAGE_KEYS.INFO_FROM_ALL_PROVIDERS, normalized);
383
813
  set({ infoFromAllProviders: normalized });
@@ -385,7 +815,7 @@ var createEmptyStore = (driver) => vanilla.createStore((set, get) => ({
385
815
  setLastModelsUpdate: (value) => {
386
816
  const normalized = {};
387
817
  for (const [baseUrl, timestamp] of Object.entries(value)) {
388
- normalized[normalizeBaseUrl(baseUrl)] = timestamp;
818
+ normalized[normalizeBaseUrl4(baseUrl)] = timestamp;
389
819
  }
390
820
  void driver.setItem(SDK_STORAGE_KEYS.LAST_MODELS_UPDATE, normalized);
391
821
  set({ lastModelsUpdate: normalized });
@@ -395,7 +825,7 @@ var createEmptyStore = (driver) => vanilla.createStore((set, get) => ({
395
825
  const updates = typeof value === "function" ? value(state.cachedTokens) : value;
396
826
  const normalized = updates.map((entry) => ({
397
827
  ...entry,
398
- baseUrl: normalizeBaseUrl(entry.baseUrl),
828
+ baseUrl: normalizeBaseUrl4(entry.baseUrl),
399
829
  balance: typeof entry.balance === "number" ? entry.balance : getCashuTokenBalance(entry.token),
400
830
  lastUsed: entry.lastUsed ?? null
401
831
  }));
@@ -408,7 +838,7 @@ var createEmptyStore = (driver) => vanilla.createStore((set, get) => ({
408
838
  const updates = typeof value === "function" ? value(state.apiKeys) : value;
409
839
  const normalized = updates.map((entry) => ({
410
840
  ...entry,
411
- baseUrl: normalizeBaseUrl(entry.baseUrl),
841
+ baseUrl: normalizeBaseUrl4(entry.baseUrl),
412
842
  balance: entry.balance ?? 0,
413
843
  lastUsed: entry.lastUsed ?? null
414
844
  }));
@@ -420,7 +850,7 @@ var createEmptyStore = (driver) => vanilla.createStore((set, get) => ({
420
850
  set((state) => {
421
851
  const updates = typeof value === "function" ? value(state.childKeys) : value;
422
852
  const normalized = updates.map((entry) => ({
423
- parentBaseUrl: normalizeBaseUrl(entry.parentBaseUrl),
853
+ parentBaseUrl: normalizeBaseUrl4(entry.parentBaseUrl),
424
854
  childKey: entry.childKey,
425
855
  balance: entry.balance ?? 0,
426
856
  balanceLimit: entry.balanceLimit,
@@ -449,10 +879,6 @@ var createEmptyStore = (driver) => vanilla.createStore((set, get) => ({
449
879
  void driver.setItem(SDK_STORAGE_KEYS.CACHED_RECEIVE_TOKENS, normalized);
450
880
  set({ cachedReceiveTokens: normalized });
451
881
  },
452
- setUsageTracking: (value) => {
453
- void driver.setItem(SDK_STORAGE_KEYS.USAGE_TRACKING, value);
454
- set({ usageTracking: value });
455
- },
456
882
  setClientIds: (value) => {
457
883
  set((state) => {
458
884
  const updates = typeof value === "function" ? value(state.clientIds) : value;
@@ -482,7 +908,6 @@ var hydrateStoreFromDriver = async (store, driver) => {
482
908
  rawRoutstr21Models,
483
909
  rawLastRoutstr21ModelsUpdate,
484
910
  rawCachedReceiveTokens,
485
- rawUsageTracking,
486
911
  rawClientIds
487
912
  ] = await Promise.all([
488
913
  driver.getItem(
@@ -514,51 +939,50 @@ var hydrateStoreFromDriver = async (store, driver) => {
514
939
  null
515
940
  ),
516
941
  driver.getItem(SDK_STORAGE_KEYS.CACHED_RECEIVE_TOKENS, []),
517
- driver.getItem(SDK_STORAGE_KEYS.USAGE_TRACKING, []),
518
942
  driver.getItem(SDK_STORAGE_KEYS.CLIENT_IDS, [])
519
943
  ]);
520
944
  const modelsFromAllProviders = Object.fromEntries(
521
945
  Object.entries(rawModels).map(([baseUrl, models]) => [
522
- normalizeBaseUrl(baseUrl),
946
+ normalizeBaseUrl4(baseUrl),
523
947
  models
524
948
  ])
525
949
  );
526
- const baseUrlsList = rawBaseUrls.map((url) => normalizeBaseUrl(url));
950
+ const baseUrlsList = rawBaseUrls.map((url) => normalizeBaseUrl4(url));
527
951
  const disabledProviders = rawDisabledProviders.map(
528
- (url) => normalizeBaseUrl(url)
952
+ (url) => normalizeBaseUrl4(url)
529
953
  );
530
954
  const mintsFromAllProviders = Object.fromEntries(
531
955
  Object.entries(rawMints).map(([baseUrl, mints]) => [
532
- normalizeBaseUrl(baseUrl),
956
+ normalizeBaseUrl4(baseUrl),
533
957
  mints.map((mint) => mint.endsWith("/") ? mint.slice(0, -1) : mint)
534
958
  ])
535
959
  );
536
960
  const infoFromAllProviders = Object.fromEntries(
537
961
  Object.entries(rawInfo).map(([baseUrl, info]) => [
538
- normalizeBaseUrl(baseUrl),
962
+ normalizeBaseUrl4(baseUrl),
539
963
  info
540
964
  ])
541
965
  );
542
966
  const lastModelsUpdate = Object.fromEntries(
543
967
  Object.entries(rawLastModelsUpdate).map(([baseUrl, timestamp]) => [
544
- normalizeBaseUrl(baseUrl),
968
+ normalizeBaseUrl4(baseUrl),
545
969
  timestamp
546
970
  ])
547
971
  );
548
972
  const cachedTokens = rawCachedTokens.map((entry) => ({
549
973
  ...entry,
550
- baseUrl: normalizeBaseUrl(entry.baseUrl),
974
+ baseUrl: normalizeBaseUrl4(entry.baseUrl),
551
975
  balance: typeof entry.balance === "number" ? entry.balance : getCashuTokenBalance(entry.token),
552
976
  lastUsed: entry.lastUsed ?? null
553
977
  }));
554
978
  const apiKeys = rawApiKeys.map((entry) => ({
555
979
  ...entry,
556
- baseUrl: normalizeBaseUrl(entry.baseUrl),
980
+ baseUrl: normalizeBaseUrl4(entry.baseUrl),
557
981
  balance: entry.balance ?? 0,
558
982
  lastUsed: entry.lastUsed ?? null
559
983
  }));
560
984
  const childKeys = rawChildKeys.map((entry) => ({
561
- parentBaseUrl: normalizeBaseUrl(entry.parentBaseUrl),
985
+ parentBaseUrl: normalizeBaseUrl4(entry.parentBaseUrl),
562
986
  childKey: entry.childKey,
563
987
  balance: entry.balance ?? 0,
564
988
  balanceLimit: entry.balanceLimit,
@@ -573,7 +997,6 @@ var hydrateStoreFromDriver = async (store, driver) => {
573
997
  unit: entry.unit || "sat",
574
998
  createdAt: entry.createdAt ?? Date.now()
575
999
  }));
576
- const usageTracking = rawUsageTracking;
577
1000
  const clientIds = rawClientIds.map((entry) => ({
578
1001
  ...entry,
579
1002
  createdAt: entry.createdAt ?? Date.now(),
@@ -594,7 +1017,6 @@ var hydrateStoreFromDriver = async (store, driver) => {
594
1017
  routstr21Models,
595
1018
  lastRoutstr21ModelsUpdate,
596
1019
  cachedReceiveTokens,
597
- usageTracking,
598
1020
  clientIds
599
1021
  });
600
1022
  };
@@ -615,12 +1037,12 @@ var createDiscoveryAdapterFromStore = (store) => ({
615
1037
  getCachedProviderInfo: () => store.getState().infoFromAllProviders,
616
1038
  setCachedProviderInfo: (info) => store.getState().setInfoFromAllProviders(info),
617
1039
  getProviderLastUpdate: (baseUrl) => {
618
- const normalized = normalizeBaseUrl(baseUrl);
1040
+ const normalized = normalizeBaseUrl4(baseUrl);
619
1041
  const timestamps = store.getState().lastModelsUpdate;
620
1042
  return timestamps[normalized] || null;
621
1043
  },
622
1044
  setProviderLastUpdate: (baseUrl, timestamp) => {
623
- const normalized = normalizeBaseUrl(baseUrl);
1045
+ const normalized = normalizeBaseUrl4(baseUrl);
624
1046
  const timestamps = { ...store.getState().lastModelsUpdate };
625
1047
  timestamps[normalized] = timestamp;
626
1048
  store.getState().setLastModelsUpdate(timestamps);
@@ -639,7 +1061,7 @@ var createDiscoveryAdapterFromStore = (store) => ({
639
1061
  });
640
1062
  var createStorageAdapterFromStore = (store) => ({
641
1063
  getToken: (baseUrl) => {
642
- const normalized = normalizeBaseUrl(baseUrl);
1064
+ const normalized = normalizeBaseUrl4(baseUrl);
643
1065
  const entry = store.getState().cachedTokens.find((token) => token.baseUrl === normalized);
644
1066
  if (!entry) return null;
645
1067
  const next = store.getState().cachedTokens.map(
@@ -649,7 +1071,7 @@ var createStorageAdapterFromStore = (store) => ({
649
1071
  return entry.token;
650
1072
  },
651
1073
  setToken: (baseUrl, token) => {
652
- const normalized = normalizeBaseUrl(baseUrl);
1074
+ const normalized = normalizeBaseUrl4(baseUrl);
653
1075
  const tokens = store.getState().cachedTokens;
654
1076
  const balance = getCashuTokenBalance(token);
655
1077
  const existingIndex = tokens.findIndex(
@@ -668,12 +1090,12 @@ var createStorageAdapterFromStore = (store) => ({
668
1090
  store.getState().setCachedTokens(next);
669
1091
  },
670
1092
  removeToken: (baseUrl) => {
671
- const normalized = normalizeBaseUrl(baseUrl);
1093
+ const normalized = normalizeBaseUrl4(baseUrl);
672
1094
  const next = store.getState().cachedTokens.filter((entry) => entry.baseUrl !== normalized);
673
1095
  store.getState().setCachedTokens(next);
674
1096
  },
675
1097
  updateTokenBalance: (baseUrl, balance) => {
676
- const normalized = normalizeBaseUrl(baseUrl);
1098
+ const normalized = normalizeBaseUrl4(baseUrl);
677
1099
  const tokens = store.getState().cachedTokens;
678
1100
  const next = tokens.map(
679
1101
  (entry) => entry.baseUrl === normalized ? { ...entry, balance } : entry
@@ -703,18 +1125,18 @@ var createStorageAdapterFromStore = (store) => ({
703
1125
  return Object.entries(distributionMap).map(([baseUrl, amt]) => ({ baseUrl, amount: amt })).sort((a, b) => b.amount - a.amount);
704
1126
  },
705
1127
  saveProviderInfo: (baseUrl, info) => {
706
- const normalized = normalizeBaseUrl(baseUrl);
1128
+ const normalized = normalizeBaseUrl4(baseUrl);
707
1129
  const next = { ...store.getState().infoFromAllProviders };
708
1130
  next[normalized] = info;
709
1131
  store.getState().setInfoFromAllProviders(next);
710
1132
  },
711
1133
  getProviderInfo: (baseUrl) => {
712
- const normalized = normalizeBaseUrl(baseUrl);
1134
+ const normalized = normalizeBaseUrl4(baseUrl);
713
1135
  return store.getState().infoFromAllProviders[normalized] || null;
714
1136
  },
715
1137
  // ========== API Keys (for apikeys mode) ==========
716
1138
  getApiKey: (baseUrl) => {
717
- const normalized = normalizeBaseUrl(baseUrl);
1139
+ const normalized = normalizeBaseUrl4(baseUrl);
718
1140
  const entry = store.getState().apiKeys.find((key) => key.baseUrl === normalized);
719
1141
  if (!entry) return null;
720
1142
  const next = store.getState().apiKeys.map(
@@ -724,7 +1146,7 @@ var createStorageAdapterFromStore = (store) => ({
724
1146
  return entry;
725
1147
  },
726
1148
  setApiKey: (baseUrl, key) => {
727
- const normalized = normalizeBaseUrl(baseUrl);
1149
+ const normalized = normalizeBaseUrl4(baseUrl);
728
1150
  const keys = store.getState().apiKeys;
729
1151
  const existingIndex = keys.findIndex(
730
1152
  (entry) => entry.baseUrl === normalized
@@ -742,7 +1164,7 @@ var createStorageAdapterFromStore = (store) => ({
742
1164
  store.getState().setApiKeys(next);
743
1165
  },
744
1166
  updateApiKeyBalance: (baseUrl, balance) => {
745
- const normalized = normalizeBaseUrl(baseUrl);
1167
+ const normalized = normalizeBaseUrl4(baseUrl);
746
1168
  const keys = store.getState().apiKeys;
747
1169
  const next = keys.map(
748
1170
  (entry) => entry.baseUrl === normalized ? { ...entry, balance } : entry
@@ -750,7 +1172,7 @@ var createStorageAdapterFromStore = (store) => ({
750
1172
  store.getState().setApiKeys(next);
751
1173
  },
752
1174
  removeApiKey: (baseUrl) => {
753
- const normalized = normalizeBaseUrl(baseUrl);
1175
+ const normalized = normalizeBaseUrl4(baseUrl);
754
1176
  const next = store.getState().apiKeys.filter((entry) => entry.baseUrl !== normalized);
755
1177
  store.getState().setApiKeys(next);
756
1178
  },
@@ -764,7 +1186,7 @@ var createStorageAdapterFromStore = (store) => ({
764
1186
  },
765
1187
  // ========== Child Keys ==========
766
1188
  getChildKey: (parentBaseUrl) => {
767
- const normalized = normalizeBaseUrl(parentBaseUrl);
1189
+ const normalized = normalizeBaseUrl4(parentBaseUrl);
768
1190
  const entry = store.getState().childKeys.find((key) => key.parentBaseUrl === normalized);
769
1191
  if (!entry) return null;
770
1192
  return {
@@ -777,7 +1199,7 @@ var createStorageAdapterFromStore = (store) => ({
777
1199
  };
778
1200
  },
779
1201
  setChildKey: (parentBaseUrl, childKey, balance, validityDate, balanceLimit) => {
780
- const normalized = normalizeBaseUrl(parentBaseUrl);
1202
+ const normalized = normalizeBaseUrl4(parentBaseUrl);
781
1203
  const keys = store.getState().childKeys;
782
1204
  const existingIndex = keys.findIndex(
783
1205
  (entry) => entry.parentBaseUrl === normalized
@@ -808,7 +1230,7 @@ var createStorageAdapterFromStore = (store) => ({
808
1230
  }
809
1231
  },
810
1232
  updateChildKeyBalance: (parentBaseUrl, balance) => {
811
- const normalized = normalizeBaseUrl(parentBaseUrl);
1233
+ const normalized = normalizeBaseUrl4(parentBaseUrl);
812
1234
  const keys = store.getState().childKeys;
813
1235
  const next = keys.map(
814
1236
  (entry) => entry.parentBaseUrl === normalized ? { ...entry, balance } : entry
@@ -816,7 +1238,7 @@ var createStorageAdapterFromStore = (store) => ({
816
1238
  store.getState().setChildKeys(next);
817
1239
  },
818
1240
  removeChildKey: (parentBaseUrl) => {
819
- const normalized = normalizeBaseUrl(parentBaseUrl);
1241
+ const normalized = normalizeBaseUrl4(parentBaseUrl);
820
1242
  const next = store.getState().childKeys.filter((entry) => entry.parentBaseUrl !== normalized);
821
1243
  store.getState().setChildKeys(next);
822
1244
  },
@@ -839,16 +1261,16 @@ var createStorageAdapterFromStore = (store) => ({
839
1261
  });
840
1262
  var createProviderRegistryFromStore = (store) => ({
841
1263
  getModelsForProvider: (baseUrl) => {
842
- const normalized = normalizeBaseUrl(baseUrl);
1264
+ const normalized = normalizeBaseUrl4(baseUrl);
843
1265
  return store.getState().modelsFromAllProviders[normalized] || [];
844
1266
  },
845
1267
  getDisabledProviders: () => store.getState().disabledProviders,
846
1268
  getProviderMints: (baseUrl) => {
847
- const normalized = normalizeBaseUrl(baseUrl);
1269
+ const normalized = normalizeBaseUrl4(baseUrl);
848
1270
  return store.getState().mintsFromAllProviders[normalized] || [];
849
1271
  },
850
1272
  getProviderInfo: async (baseUrl) => {
851
- const normalized = normalizeBaseUrl(baseUrl);
1273
+ const normalized = normalizeBaseUrl4(baseUrl);
852
1274
  const cached = store.getState().infoFromAllProviders[normalized];
853
1275
  if (cached) return cached;
854
1276
  try {
@@ -870,7 +1292,7 @@ var createProviderRegistryFromStore = (store) => ({
870
1292
  });
871
1293
 
872
1294
  // storage/index.ts
873
- var isBrowser2 = () => {
1295
+ var isBrowser3 = () => {
874
1296
  try {
875
1297
  return typeof window !== "undefined" && typeof window.localStorage !== "undefined";
876
1298
  } catch {
@@ -885,16 +1307,16 @@ var isNode = () => {
885
1307
  }
886
1308
  };
887
1309
  var defaultDriver = null;
888
- var isBun2 = () => {
1310
+ var isBun3 = () => {
889
1311
  return typeof process.versions.bun !== "undefined";
890
1312
  };
891
1313
  var getDefaultSdkDriver = () => {
892
1314
  if (defaultDriver) return defaultDriver;
893
- if (isBrowser2()) {
1315
+ if (isBrowser3()) {
894
1316
  defaultDriver = localStorageDriver;
895
1317
  return defaultDriver;
896
1318
  }
897
- if (isBun2()) {
1319
+ if (isBun3()) {
898
1320
  defaultDriver = createMemoryDriver();
899
1321
  return defaultDriver;
900
1322
  }
@@ -906,12 +1328,35 @@ var getDefaultSdkDriver = () => {
906
1328
  return defaultDriver;
907
1329
  };
908
1330
  var defaultStore = null;
1331
+ var defaultUsageTrackingDriver = null;
909
1332
  var getDefaultSdkStore = () => {
910
1333
  if (!defaultStore) {
911
1334
  defaultStore = createSdkStore({ driver: getDefaultSdkDriver() });
912
1335
  }
913
1336
  return defaultStore.hydrate.then(() => defaultStore.store);
914
1337
  };
1338
+ var getDefaultUsageTrackingDriver = () => {
1339
+ if (defaultUsageTrackingDriver) return defaultUsageTrackingDriver;
1340
+ const storageDriver = getDefaultSdkDriver();
1341
+ if (isBrowser3()) {
1342
+ defaultUsageTrackingDriver = createIndexedDBUsageTrackingDriver({
1343
+ legacyStorageDriver: storageDriver
1344
+ });
1345
+ return defaultUsageTrackingDriver;
1346
+ }
1347
+ if (isBun3()) {
1348
+ defaultUsageTrackingDriver = createMemoryUsageTrackingDriver();
1349
+ return defaultUsageTrackingDriver;
1350
+ }
1351
+ if (isNode()) {
1352
+ defaultUsageTrackingDriver = createSqliteUsageTrackingDriver({
1353
+ legacyStorageDriver: storageDriver
1354
+ });
1355
+ return defaultUsageTrackingDriver;
1356
+ }
1357
+ defaultUsageTrackingDriver = createMemoryUsageTrackingDriver();
1358
+ return defaultUsageTrackingDriver;
1359
+ };
915
1360
  var getDefaultDiscoveryAdapter = async () => createDiscoveryAdapterFromStore(await getDefaultSdkStore());
916
1361
  var getDefaultStorageAdapter = async () => createStorageAdapterFromStore(await getDefaultSdkStore());
917
1362
  var getDefaultProviderRegistry = async () => createProviderRegistryFromStore(await getDefaultSdkStore());
@@ -919,16 +1364,20 @@ var getDefaultProviderRegistry = async () => createProviderRegistryFromStore(awa
919
1364
  exports.SDK_STORAGE_KEYS = SDK_STORAGE_KEYS;
920
1365
  exports.createDiscoveryAdapterFromStore = createDiscoveryAdapterFromStore;
921
1366
  exports.createIndexedDBDriver = createIndexedDBDriver;
1367
+ exports.createIndexedDBUsageTrackingDriver = createIndexedDBUsageTrackingDriver;
922
1368
  exports.createMemoryDriver = createMemoryDriver;
1369
+ exports.createMemoryUsageTrackingDriver = createMemoryUsageTrackingDriver;
923
1370
  exports.createProviderRegistryFromStore = createProviderRegistryFromStore;
924
1371
  exports.createSdkStore = createSdkStore;
925
1372
  exports.createSqliteDriver = createSqliteDriver;
1373
+ exports.createSqliteUsageTrackingDriver = createSqliteUsageTrackingDriver;
926
1374
  exports.createStorageAdapterFromStore = createStorageAdapterFromStore;
927
1375
  exports.getDefaultDiscoveryAdapter = getDefaultDiscoveryAdapter;
928
1376
  exports.getDefaultProviderRegistry = getDefaultProviderRegistry;
929
1377
  exports.getDefaultSdkDriver = getDefaultSdkDriver;
930
1378
  exports.getDefaultSdkStore = getDefaultSdkStore;
931
1379
  exports.getDefaultStorageAdapter = getDefaultStorageAdapter;
1380
+ exports.getDefaultUsageTrackingDriver = getDefaultUsageTrackingDriver;
932
1381
  exports.localStorageDriver = localStorageDriver;
933
1382
  //# sourceMappingURL=index.js.map
934
1383
  //# sourceMappingURL=index.js.map