@talismn/balances-react 0.0.0-pr2131-20250807071252 → 0.0.0-pr2134-20250813092023

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.
@@ -92,6 +92,31 @@ export declare const chaindataAtom: import("jotai").Atom<{
92
92
  "evm-erc20"?: undefined;
93
93
  "evm-uniswapv2"?: undefined;
94
94
  } | undefined;
95
+ } | {
96
+ id: string;
97
+ name: string;
98
+ nativeTokenId: string;
99
+ nativeCurrency: {
100
+ decimals: number;
101
+ symbol: string;
102
+ name: string;
103
+ coingeckoId?: string | undefined;
104
+ mirrorOf?: string | undefined;
105
+ logo?: string | undefined;
106
+ };
107
+ blockExplorerUrls: string[];
108
+ platform: "solana";
109
+ genesisHash: string;
110
+ rpcs: string[];
111
+ isTestnet?: boolean | undefined;
112
+ isDefault?: boolean | undefined;
113
+ forceScan?: boolean | undefined;
114
+ logo?: string | undefined;
115
+ themeColor?: string | undefined;
116
+ balancesConfig?: {
117
+ "sol-native"?: undefined;
118
+ "sol-spl"?: undefined;
119
+ } | undefined;
95
120
  })[];
96
121
  tokens: ({
97
122
  id: string;
@@ -237,6 +262,33 @@ export declare const chaindataAtom: import("jotai").Atom<{
237
262
  coingeckoId?: string | undefined;
238
263
  noDiscovery?: boolean | undefined;
239
264
  mirrorOf?: string | undefined;
265
+ } | {
266
+ id: string;
267
+ networkId: string;
268
+ decimals: number;
269
+ symbol: string;
270
+ type: "sol-native";
271
+ platform: "solana";
272
+ isDefault?: boolean | undefined;
273
+ name?: string | undefined;
274
+ logo?: string | undefined;
275
+ coingeckoId?: string | undefined;
276
+ noDiscovery?: boolean | undefined;
277
+ mirrorOf?: string | undefined;
278
+ } | {
279
+ id: string;
280
+ networkId: string;
281
+ decimals: number;
282
+ symbol: string;
283
+ type: "sol-spl";
284
+ platform: "solana";
285
+ mintAddress: string;
286
+ isDefault?: boolean | undefined;
287
+ name?: string | undefined;
288
+ logo?: string | undefined;
289
+ coingeckoId?: string | undefined;
290
+ noDiscovery?: boolean | undefined;
291
+ mirrorOf?: string | undefined;
240
292
  })[];
241
293
  } | Promise<{
242
294
  networks: ({
@@ -332,6 +384,31 @@ export declare const chaindataAtom: import("jotai").Atom<{
332
384
  "evm-erc20"?: undefined;
333
385
  "evm-uniswapv2"?: undefined;
334
386
  } | undefined;
387
+ } | {
388
+ id: string;
389
+ name: string;
390
+ nativeTokenId: string;
391
+ nativeCurrency: {
392
+ decimals: number;
393
+ symbol: string;
394
+ name: string;
395
+ coingeckoId?: string | undefined;
396
+ mirrorOf?: string | undefined;
397
+ logo?: string | undefined;
398
+ };
399
+ blockExplorerUrls: string[];
400
+ platform: "solana";
401
+ genesisHash: string;
402
+ rpcs: string[];
403
+ isTestnet?: boolean | undefined;
404
+ isDefault?: boolean | undefined;
405
+ forceScan?: boolean | undefined;
406
+ logo?: string | undefined;
407
+ themeColor?: string | undefined;
408
+ balancesConfig?: {
409
+ "sol-native"?: undefined;
410
+ "sol-spl"?: undefined;
411
+ } | undefined;
335
412
  })[];
336
413
  tokens: ({
337
414
  id: string;
@@ -477,6 +554,33 @@ export declare const chaindataAtom: import("jotai").Atom<{
477
554
  coingeckoId?: string | undefined;
478
555
  noDiscovery?: boolean | undefined;
479
556
  mirrorOf?: string | undefined;
557
+ } | {
558
+ id: string;
559
+ networkId: string;
560
+ decimals: number;
561
+ symbol: string;
562
+ type: "sol-native";
563
+ platform: "solana";
564
+ isDefault?: boolean | undefined;
565
+ name?: string | undefined;
566
+ logo?: string | undefined;
567
+ coingeckoId?: string | undefined;
568
+ noDiscovery?: boolean | undefined;
569
+ mirrorOf?: string | undefined;
570
+ } | {
571
+ id: string;
572
+ networkId: string;
573
+ decimals: number;
574
+ symbol: string;
575
+ type: "sol-spl";
576
+ platform: "solana";
577
+ mintAddress: string;
578
+ isDefault?: boolean | undefined;
579
+ name?: string | undefined;
580
+ logo?: string | undefined;
581
+ coingeckoId?: string | undefined;
582
+ noDiscovery?: boolean | undefined;
583
+ mirrorOf?: string | undefined;
480
584
  })[];
481
585
  }>>;
482
586
  export declare const tokensAtom: import("jotai").Atom<Promise<({
@@ -623,6 +727,33 @@ export declare const tokensAtom: import("jotai").Atom<Promise<({
623
727
  coingeckoId?: string | undefined;
624
728
  noDiscovery?: boolean | undefined;
625
729
  mirrorOf?: string | undefined;
730
+ } | {
731
+ id: string;
732
+ networkId: string;
733
+ decimals: number;
734
+ symbol: string;
735
+ type: "sol-native";
736
+ platform: "solana";
737
+ isDefault?: boolean | undefined;
738
+ name?: string | undefined;
739
+ logo?: string | undefined;
740
+ coingeckoId?: string | undefined;
741
+ noDiscovery?: boolean | undefined;
742
+ mirrorOf?: string | undefined;
743
+ } | {
744
+ id: string;
745
+ networkId: string;
746
+ decimals: number;
747
+ symbol: string;
748
+ type: "sol-spl";
749
+ platform: "solana";
750
+ mintAddress: string;
751
+ isDefault?: boolean | undefined;
752
+ name?: string | undefined;
753
+ logo?: string | undefined;
754
+ coingeckoId?: string | undefined;
755
+ noDiscovery?: boolean | undefined;
756
+ mirrorOf?: string | undefined;
626
757
  })[]>>;
627
758
  export declare const networksAtom: import("jotai").Atom<Promise<({
628
759
  id: string;
@@ -717,4 +848,29 @@ export declare const networksAtom: import("jotai").Atom<Promise<({
717
848
  "evm-erc20"?: undefined;
718
849
  "evm-uniswapv2"?: undefined;
719
850
  } | undefined;
851
+ } | {
852
+ id: string;
853
+ name: string;
854
+ nativeTokenId: string;
855
+ nativeCurrency: {
856
+ decimals: number;
857
+ symbol: string;
858
+ name: string;
859
+ coingeckoId?: string | undefined;
860
+ mirrorOf?: string | undefined;
861
+ logo?: string | undefined;
862
+ };
863
+ blockExplorerUrls: string[];
864
+ platform: "solana";
865
+ genesisHash: string;
866
+ rpcs: string[];
867
+ isTestnet?: boolean | undefined;
868
+ isDefault?: boolean | undefined;
869
+ forceScan?: boolean | undefined;
870
+ logo?: string | undefined;
871
+ themeColor?: string | undefined;
872
+ balancesConfig?: {
873
+ "sol-native"?: undefined;
874
+ "sol-spl"?: undefined;
875
+ } | undefined;
720
876
  })[]>>;
@@ -1,3 +1 @@
1
- export declare const tokenRatesAtom: import("jotai").Atom<Promise<{
2
- [k: string]: import("@talismn/token-rates").TokenRates;
3
- }>>;
1
+ export declare const tokenRatesAtom: import("jotai").Atom<Promise<import("@talismn/token-rates").TokenRatesList>>;
@@ -94,6 +94,31 @@ export declare const useChaindata: () => {
94
94
  "evm-erc20"?: undefined;
95
95
  "evm-uniswapv2"?: undefined;
96
96
  } | undefined;
97
+ } | {
98
+ id: string;
99
+ name: string;
100
+ nativeTokenId: string;
101
+ nativeCurrency: {
102
+ decimals: number;
103
+ symbol: string;
104
+ name: string;
105
+ coingeckoId?: string | undefined;
106
+ mirrorOf?: string | undefined;
107
+ logo?: string | undefined;
108
+ };
109
+ blockExplorerUrls: string[];
110
+ platform: "solana";
111
+ genesisHash: string;
112
+ rpcs: string[];
113
+ isTestnet?: boolean | undefined;
114
+ isDefault?: boolean | undefined;
115
+ forceScan?: boolean | undefined;
116
+ logo?: string | undefined;
117
+ themeColor?: string | undefined;
118
+ balancesConfig?: {
119
+ "sol-native"?: undefined;
120
+ "sol-spl"?: undefined;
121
+ } | undefined;
97
122
  })[];
98
123
  tokens: ({
99
124
  id: string;
@@ -239,6 +264,33 @@ export declare const useChaindata: () => {
239
264
  coingeckoId?: string | undefined;
240
265
  noDiscovery?: boolean | undefined;
241
266
  mirrorOf?: string | undefined;
267
+ } | {
268
+ id: string;
269
+ networkId: string;
270
+ decimals: number;
271
+ symbol: string;
272
+ type: "sol-native";
273
+ platform: "solana";
274
+ isDefault?: boolean | undefined;
275
+ name?: string | undefined;
276
+ logo?: string | undefined;
277
+ coingeckoId?: string | undefined;
278
+ noDiscovery?: boolean | undefined;
279
+ mirrorOf?: string | undefined;
280
+ } | {
281
+ id: string;
282
+ networkId: string;
283
+ decimals: number;
284
+ symbol: string;
285
+ type: "sol-spl";
286
+ platform: "solana";
287
+ mintAddress: string;
288
+ isDefault?: boolean | undefined;
289
+ name?: string | undefined;
290
+ logo?: string | undefined;
291
+ coingeckoId?: string | undefined;
292
+ noDiscovery?: boolean | undefined;
293
+ mirrorOf?: string | undefined;
242
294
  })[];
243
295
  };
244
296
  export declare const useNetworks: () => ({
@@ -334,6 +386,31 @@ export declare const useNetworks: () => ({
334
386
  "evm-erc20"?: undefined;
335
387
  "evm-uniswapv2"?: undefined;
336
388
  } | undefined;
389
+ } | {
390
+ id: string;
391
+ name: string;
392
+ nativeTokenId: string;
393
+ nativeCurrency: {
394
+ decimals: number;
395
+ symbol: string;
396
+ name: string;
397
+ coingeckoId?: string | undefined;
398
+ mirrorOf?: string | undefined;
399
+ logo?: string | undefined;
400
+ };
401
+ blockExplorerUrls: string[];
402
+ platform: "solana";
403
+ genesisHash: string;
404
+ rpcs: string[];
405
+ isTestnet?: boolean | undefined;
406
+ isDefault?: boolean | undefined;
407
+ forceScan?: boolean | undefined;
408
+ logo?: string | undefined;
409
+ themeColor?: string | undefined;
410
+ balancesConfig?: {
411
+ "sol-native"?: undefined;
412
+ "sol-spl"?: undefined;
413
+ } | undefined;
337
414
  })[];
338
415
  export declare const useNetworksById: () => import("lodash").Dictionary<{
339
416
  id: string;
@@ -428,6 +505,31 @@ export declare const useNetworksById: () => import("lodash").Dictionary<{
428
505
  "evm-erc20"?: undefined;
429
506
  "evm-uniswapv2"?: undefined;
430
507
  } | undefined;
508
+ } | {
509
+ id: string;
510
+ name: string;
511
+ nativeTokenId: string;
512
+ nativeCurrency: {
513
+ decimals: number;
514
+ symbol: string;
515
+ name: string;
516
+ coingeckoId?: string | undefined;
517
+ mirrorOf?: string | undefined;
518
+ logo?: string | undefined;
519
+ };
520
+ blockExplorerUrls: string[];
521
+ platform: "solana";
522
+ genesisHash: string;
523
+ rpcs: string[];
524
+ isTestnet?: boolean | undefined;
525
+ isDefault?: boolean | undefined;
526
+ forceScan?: boolean | undefined;
527
+ logo?: string | undefined;
528
+ themeColor?: string | undefined;
529
+ balancesConfig?: {
530
+ "sol-native"?: undefined;
531
+ "sol-spl"?: undefined;
532
+ } | undefined;
431
533
  }>;
432
534
  export declare const useNetwork: (networkId?: NetworkId) => {
433
535
  id: string;
@@ -522,6 +624,31 @@ export declare const useNetwork: (networkId?: NetworkId) => {
522
624
  "evm-erc20"?: undefined;
523
625
  "evm-uniswapv2"?: undefined;
524
626
  } | undefined;
627
+ } | {
628
+ id: string;
629
+ name: string;
630
+ nativeTokenId: string;
631
+ nativeCurrency: {
632
+ decimals: number;
633
+ symbol: string;
634
+ name: string;
635
+ coingeckoId?: string | undefined;
636
+ mirrorOf?: string | undefined;
637
+ logo?: string | undefined;
638
+ };
639
+ blockExplorerUrls: string[];
640
+ platform: "solana";
641
+ genesisHash: string;
642
+ rpcs: string[];
643
+ isTestnet?: boolean | undefined;
644
+ isDefault?: boolean | undefined;
645
+ forceScan?: boolean | undefined;
646
+ logo?: string | undefined;
647
+ themeColor?: string | undefined;
648
+ balancesConfig?: {
649
+ "sol-native"?: undefined;
650
+ "sol-spl"?: undefined;
651
+ } | undefined;
525
652
  };
526
653
  export declare const useTokens: () => ({
527
654
  id: string;
@@ -667,6 +794,33 @@ export declare const useTokens: () => ({
667
794
  coingeckoId?: string | undefined;
668
795
  noDiscovery?: boolean | undefined;
669
796
  mirrorOf?: string | undefined;
797
+ } | {
798
+ id: string;
799
+ networkId: string;
800
+ decimals: number;
801
+ symbol: string;
802
+ type: "sol-native";
803
+ platform: "solana";
804
+ isDefault?: boolean | undefined;
805
+ name?: string | undefined;
806
+ logo?: string | undefined;
807
+ coingeckoId?: string | undefined;
808
+ noDiscovery?: boolean | undefined;
809
+ mirrorOf?: string | undefined;
810
+ } | {
811
+ id: string;
812
+ networkId: string;
813
+ decimals: number;
814
+ symbol: string;
815
+ type: "sol-spl";
816
+ platform: "solana";
817
+ mintAddress: string;
818
+ isDefault?: boolean | undefined;
819
+ name?: string | undefined;
820
+ logo?: string | undefined;
821
+ coingeckoId?: string | undefined;
822
+ noDiscovery?: boolean | undefined;
823
+ mirrorOf?: string | undefined;
670
824
  })[];
671
825
  export declare const useTokensById: () => import("lodash").Dictionary<{
672
826
  id: string;
@@ -812,6 +966,33 @@ export declare const useTokensById: () => import("lodash").Dictionary<{
812
966
  coingeckoId?: string | undefined;
813
967
  noDiscovery?: boolean | undefined;
814
968
  mirrorOf?: string | undefined;
969
+ } | {
970
+ id: string;
971
+ networkId: string;
972
+ decimals: number;
973
+ symbol: string;
974
+ type: "sol-native";
975
+ platform: "solana";
976
+ isDefault?: boolean | undefined;
977
+ name?: string | undefined;
978
+ logo?: string | undefined;
979
+ coingeckoId?: string | undefined;
980
+ noDiscovery?: boolean | undefined;
981
+ mirrorOf?: string | undefined;
982
+ } | {
983
+ id: string;
984
+ networkId: string;
985
+ decimals: number;
986
+ symbol: string;
987
+ type: "sol-spl";
988
+ platform: "solana";
989
+ mintAddress: string;
990
+ isDefault?: boolean | undefined;
991
+ name?: string | undefined;
992
+ logo?: string | undefined;
993
+ coingeckoId?: string | undefined;
994
+ noDiscovery?: boolean | undefined;
995
+ mirrorOf?: string | undefined;
815
996
  }>;
816
997
  export declare const useToken: (tokenId?: TokenId) => {
817
998
  id: string;
@@ -957,4 +1138,31 @@ export declare const useToken: (tokenId?: TokenId) => {
957
1138
  coingeckoId?: string | undefined;
958
1139
  noDiscovery?: boolean | undefined;
959
1140
  mirrorOf?: string | undefined;
1141
+ } | {
1142
+ id: string;
1143
+ networkId: string;
1144
+ decimals: number;
1145
+ symbol: string;
1146
+ type: "sol-native";
1147
+ platform: "solana";
1148
+ isDefault?: boolean | undefined;
1149
+ name?: string | undefined;
1150
+ logo?: string | undefined;
1151
+ coingeckoId?: string | undefined;
1152
+ noDiscovery?: boolean | undefined;
1153
+ mirrorOf?: string | undefined;
1154
+ } | {
1155
+ id: string;
1156
+ networkId: string;
1157
+ decimals: number;
1158
+ symbol: string;
1159
+ type: "sol-spl";
1160
+ platform: "solana";
1161
+ mintAddress: string;
1162
+ isDefault?: boolean | undefined;
1163
+ name?: string | undefined;
1164
+ logo?: string | undefined;
1165
+ coingeckoId?: string | undefined;
1166
+ noDiscovery?: boolean | undefined;
1167
+ mirrorOf?: string | undefined;
960
1168
  };
@@ -1,5 +1,3 @@
1
1
  import { TokenId } from "@talismn/chaindata-provider";
2
- export declare const useTokenRates: () => {
3
- [k: string]: import("@talismn/token-rates").TokenRates;
4
- };
2
+ export declare const useTokenRates: () => import("@talismn/token-rates").TokenRatesList;
5
3
  export declare const useTokenRate: (tokenId?: TokenId) => import("@talismn/token-rates").TokenRates;
@@ -8,13 +8,11 @@ var chaindataProvider = require('@talismn/chaindata-provider');
8
8
  var balances = require('@talismn/balances');
9
9
  var jotaiEffect = require('jotai-effect');
10
10
  var lodashEs = require('lodash-es');
11
- var chainConnector = require('@talismn/chain-connector');
12
- var chainConnectorEvm = require('@talismn/chain-connector-evm');
11
+ var chainConnectors = require('@talismn/chain-connectors');
13
12
  var connectionMeta = require('@talismn/connection-meta');
14
13
  var util = require('@talismn/util');
15
14
  var utils = require('jotai/utils');
16
15
  var rxjs = require('rxjs');
17
- var dexie = require('dexie');
18
16
  var anylogger = require('anylogger');
19
17
  var utilCrypto = require('@polkadot/util-crypto');
20
18
 
@@ -34,16 +32,20 @@ const enabledTokensAtom = jotai.atom(undefined);
34
32
  const allAddressesAtom = jotai.atom([]);
35
33
 
36
34
  const chaindataProviderAtom = jotai.atom(() => {
37
- return new chaindataProvider.ChaindataProvider({});
35
+ return new chaindataProvider.ChaindataProvider({
36
+ // TODO pass persistedStorage
37
+ });
38
38
  });
39
39
 
40
40
  const chainConnectorsAtom = jotai.atom(get => {
41
41
  const chaindataProvider = get(chaindataProviderAtom);
42
- const substrate = new chainConnector.ChainConnector(chaindataProvider, connectionMeta.connectionMetaDb);
43
- const evm = new chainConnectorEvm.ChainConnectorEvm(chaindataProvider);
42
+ const substrate = new chainConnectors.ChainConnectorDot(chaindataProvider, connectionMeta.connectionMetaDb);
43
+ const evm = new chainConnectors.ChainConnectorEth(chaindataProvider);
44
+ const solana = new chainConnectors.ChainConnectorSol(chaindataProvider);
44
45
  return {
45
46
  substrate,
46
- evm
47
+ evm,
48
+ solana
47
49
  };
48
50
  });
49
51
 
@@ -85,32 +87,17 @@ var packageJson = {
85
87
 
86
88
  var log = anylogger__default.default(packageJson.name);
87
89
 
88
- /**
89
- * Converts a dexie Observable into an rxjs Observable.
90
- */
91
- function dexieToRxjs(o) {
92
- return new rxjs.Observable(observer => {
93
- const subscription = o.subscribe({
94
- next: value => observer.next(value),
95
- error: error => observer.error(error)
96
- });
97
- return () => subscription.unsubscribe();
98
- });
99
- }
100
-
101
90
  const tokenRatesAtom = jotai.atom(async get => {
102
91
  // runs a timer to keep tokenRates up to date
103
92
  get(tokenRatesFetcherAtomEffect);
104
- return await get(tokenRatesDbAtom);
93
+ return (await get(tokenRatesDbAtom)).tokenRates;
105
94
  });
106
- const tokenRatesDbAtom = utils.atomWithObservable(() => {
107
- const dbRatesToMap = dbRates => Object.fromEntries(dbRates.map(({
108
- tokenId,
109
- rates
110
- }) => [tokenId, rates]));
111
95
 
112
- // retrieve fetched tokenRates from the db
113
- return dexieToRxjs(dexie.liveQuery(() => tokenRates.db.tokenRates.toArray())).pipe(rxjs.map(dbRatesToMap));
96
+ // TODO: Persist to storage
97
+ const tokenRates$ = new rxjs.ReplaySubject(1);
98
+ const tokenRatesDbAtom = utils.atomWithObservable(() => {
99
+ tokenRates.tryToDeleteOldTokenRatesDb();
100
+ return tokenRates$.asObservable();
114
101
  });
115
102
  const tokenRatesFetcherAtomEffect = jotaiEffect.atomEffect(get => {
116
103
  // lets us tear down the existing timer when the effect is restarted
@@ -121,7 +108,6 @@ const tokenRatesFetcherAtomEffect = jotaiEffect.atomEffect(get => {
121
108
  const tokensPromise = get(tokensAtom);
122
109
  (async () => {
123
110
  const tokensById = lodashEs.keyBy(await tokensPromise, "id");
124
- const tokenIds = Object.keys(tokensById);
125
111
  const loopMs = 300_000; // 300_000ms = 300s = 5 minutes
126
112
  const retryTimeout = 5_000; // 5_000ms = 5 seconds
127
113
 
@@ -129,21 +115,11 @@ const tokenRatesFetcherAtomEffect = jotaiEffect.atomEffect(get => {
129
115
  try {
130
116
  if (abort.signal.aborted) return; // don't fetch if aborted
131
117
  const tokenRates$1 = await tokenRates.fetchTokenRates(tokensById, tokenRates.ALL_CURRENCY_IDS, coinsApiConfig);
132
- const putTokenRates = Object.entries(tokenRates$1).map(([tokenId, rates]) => ({
133
- tokenId,
134
- rates
135
- }));
118
+ const putTokenRates = {
119
+ tokenRates: tokenRates$1
120
+ };
136
121
  if (abort.signal.aborted) return; // don't insert into db if aborted
137
- await tokenRates.db.transaction("rw", tokenRates.db.tokenRates, async () => {
138
- // override all tokenRates
139
- await tokenRates.db.tokenRates.bulkPut(putTokenRates);
140
-
141
- // delete tokenRates for tokens which no longer exist
142
- const validTokenIds = new Set(tokenIds);
143
- const tokenRatesIds = await tokenRates.db.tokenRates.toCollection().primaryKeys();
144
- const deleteIds = tokenRatesIds.filter(id => !validTokenIds.has(id));
145
- if (deleteIds.length > 0) await tokenRates.db.tokenRates.bulkDelete(deleteIds);
146
- });
122
+ tokenRates$.next(putTokenRates);
147
123
  if (abort.signal.aborted) return; // don't schedule next loop if aborted
148
124
  setTimeout(hydrate, loopMs);
149
125
  } catch (error) {
@@ -8,13 +8,11 @@ var chaindataProvider = require('@talismn/chaindata-provider');
8
8
  var balances = require('@talismn/balances');
9
9
  var jotaiEffect = require('jotai-effect');
10
10
  var lodashEs = require('lodash-es');
11
- var chainConnector = require('@talismn/chain-connector');
12
- var chainConnectorEvm = require('@talismn/chain-connector-evm');
11
+ var chainConnectors = require('@talismn/chain-connectors');
13
12
  var connectionMeta = require('@talismn/connection-meta');
14
13
  var util = require('@talismn/util');
15
14
  var utils = require('jotai/utils');
16
15
  var rxjs = require('rxjs');
17
- var dexie = require('dexie');
18
16
  var anylogger = require('anylogger');
19
17
  var utilCrypto = require('@polkadot/util-crypto');
20
18
 
@@ -34,16 +32,20 @@ const enabledTokensAtom = jotai.atom(undefined);
34
32
  const allAddressesAtom = jotai.atom([]);
35
33
 
36
34
  const chaindataProviderAtom = jotai.atom(() => {
37
- return new chaindataProvider.ChaindataProvider({});
35
+ return new chaindataProvider.ChaindataProvider({
36
+ // TODO pass persistedStorage
37
+ });
38
38
  });
39
39
 
40
40
  const chainConnectorsAtom = jotai.atom(get => {
41
41
  const chaindataProvider = get(chaindataProviderAtom);
42
- const substrate = new chainConnector.ChainConnector(chaindataProvider, connectionMeta.connectionMetaDb);
43
- const evm = new chainConnectorEvm.ChainConnectorEvm(chaindataProvider);
42
+ const substrate = new chainConnectors.ChainConnectorDot(chaindataProvider, connectionMeta.connectionMetaDb);
43
+ const evm = new chainConnectors.ChainConnectorEth(chaindataProvider);
44
+ const solana = new chainConnectors.ChainConnectorSol(chaindataProvider);
44
45
  return {
45
46
  substrate,
46
- evm
47
+ evm,
48
+ solana
47
49
  };
48
50
  });
49
51
 
@@ -85,32 +87,17 @@ var packageJson = {
85
87
 
86
88
  var log = anylogger__default.default(packageJson.name);
87
89
 
88
- /**
89
- * Converts a dexie Observable into an rxjs Observable.
90
- */
91
- function dexieToRxjs(o) {
92
- return new rxjs.Observable(observer => {
93
- const subscription = o.subscribe({
94
- next: value => observer.next(value),
95
- error: error => observer.error(error)
96
- });
97
- return () => subscription.unsubscribe();
98
- });
99
- }
100
-
101
90
  const tokenRatesAtom = jotai.atom(async get => {
102
91
  // runs a timer to keep tokenRates up to date
103
92
  get(tokenRatesFetcherAtomEffect);
104
- return await get(tokenRatesDbAtom);
93
+ return (await get(tokenRatesDbAtom)).tokenRates;
105
94
  });
106
- const tokenRatesDbAtom = utils.atomWithObservable(() => {
107
- const dbRatesToMap = dbRates => Object.fromEntries(dbRates.map(({
108
- tokenId,
109
- rates
110
- }) => [tokenId, rates]));
111
95
 
112
- // retrieve fetched tokenRates from the db
113
- return dexieToRxjs(dexie.liveQuery(() => tokenRates.db.tokenRates.toArray())).pipe(rxjs.map(dbRatesToMap));
96
+ // TODO: Persist to storage
97
+ const tokenRates$ = new rxjs.ReplaySubject(1);
98
+ const tokenRatesDbAtom = utils.atomWithObservable(() => {
99
+ tokenRates.tryToDeleteOldTokenRatesDb();
100
+ return tokenRates$.asObservable();
114
101
  });
115
102
  const tokenRatesFetcherAtomEffect = jotaiEffect.atomEffect(get => {
116
103
  // lets us tear down the existing timer when the effect is restarted
@@ -121,7 +108,6 @@ const tokenRatesFetcherAtomEffect = jotaiEffect.atomEffect(get => {
121
108
  const tokensPromise = get(tokensAtom);
122
109
  (async () => {
123
110
  const tokensById = lodashEs.keyBy(await tokensPromise, "id");
124
- const tokenIds = Object.keys(tokensById);
125
111
  const loopMs = 300_000; // 300_000ms = 300s = 5 minutes
126
112
  const retryTimeout = 5_000; // 5_000ms = 5 seconds
127
113
 
@@ -129,21 +115,11 @@ const tokenRatesFetcherAtomEffect = jotaiEffect.atomEffect(get => {
129
115
  try {
130
116
  if (abort.signal.aborted) return; // don't fetch if aborted
131
117
  const tokenRates$1 = await tokenRates.fetchTokenRates(tokensById, tokenRates.ALL_CURRENCY_IDS, coinsApiConfig);
132
- const putTokenRates = Object.entries(tokenRates$1).map(([tokenId, rates]) => ({
133
- tokenId,
134
- rates
135
- }));
118
+ const putTokenRates = {
119
+ tokenRates: tokenRates$1
120
+ };
136
121
  if (abort.signal.aborted) return; // don't insert into db if aborted
137
- await tokenRates.db.transaction("rw", tokenRates.db.tokenRates, async () => {
138
- // override all tokenRates
139
- await tokenRates.db.tokenRates.bulkPut(putTokenRates);
140
-
141
- // delete tokenRates for tokens which no longer exist
142
- const validTokenIds = new Set(tokenIds);
143
- const tokenRatesIds = await tokenRates.db.tokenRates.toCollection().primaryKeys();
144
- const deleteIds = tokenRatesIds.filter(id => !validTokenIds.has(id));
145
- if (deleteIds.length > 0) await tokenRates.db.tokenRates.bulkDelete(deleteIds);
146
- });
122
+ tokenRates$.next(putTokenRates);
147
123
  if (abort.signal.aborted) return; // don't schedule next loop if aborted
148
124
  setTimeout(hydrate, loopMs);
149
125
  } catch (error) {
@@ -1,19 +1,17 @@
1
1
  import { atom, useSetAtom, useAtomValue } from 'jotai';
2
2
  import { useMemo, useEffect } from 'react';
3
- import { DEFAULT_COINSAPI_CONFIG, db, fetchTokenRates, ALL_CURRENCY_IDS } from '@talismn/token-rates';
3
+ import { DEFAULT_COINSAPI_CONFIG, tryToDeleteOldTokenRatesDb, fetchTokenRates, ALL_CURRENCY_IDS } from '@talismn/token-rates';
4
4
  import { jsx, Fragment } from 'react/jsx-runtime';
5
5
  import { ChaindataProvider } from '@talismn/chaindata-provider';
6
6
  export { evmErc20TokenId, evmNativeTokenId, subAssetTokenId, subNativeTokenId, subPsp22TokenId, subTokensTokenId } from '@talismn/chaindata-provider';
7
7
  import { BalancesProvider as BalancesProvider$1, Balances } from '@talismn/balances';
8
8
  import { atomEffect } from 'jotai-effect';
9
9
  import { keyBy, fromPairs } from 'lodash-es';
10
- import { ChainConnector } from '@talismn/chain-connector';
11
- import { ChainConnectorEvm } from '@talismn/chain-connector-evm';
10
+ import { ChainConnectorDot, ChainConnectorEth, ChainConnectorSol } from '@talismn/chain-connectors';
12
11
  import { connectionMetaDb } from '@talismn/connection-meta';
13
12
  import { firstThenDebounce, isTruthy, isAbortError } from '@talismn/util';
14
13
  import { atomWithObservable } from 'jotai/utils';
15
- import { combineLatest, Observable, map } from 'rxjs';
16
- import { liveQuery } from 'dexie';
14
+ import { combineLatest, ReplaySubject } from 'rxjs';
17
15
  import anylogger from 'anylogger';
18
16
  import { cryptoWaitReady } from '@polkadot/util-crypto';
19
17
 
@@ -29,16 +27,20 @@ const enabledTokensAtom = atom(undefined);
29
27
  const allAddressesAtom = atom([]);
30
28
 
31
29
  const chaindataProviderAtom = atom(() => {
32
- return new ChaindataProvider({});
30
+ return new ChaindataProvider({
31
+ // TODO pass persistedStorage
32
+ });
33
33
  });
34
34
 
35
35
  const chainConnectorsAtom = atom(get => {
36
36
  const chaindataProvider = get(chaindataProviderAtom);
37
- const substrate = new ChainConnector(chaindataProvider, connectionMetaDb);
38
- const evm = new ChainConnectorEvm(chaindataProvider);
37
+ const substrate = new ChainConnectorDot(chaindataProvider, connectionMetaDb);
38
+ const evm = new ChainConnectorEth(chaindataProvider);
39
+ const solana = new ChainConnectorSol(chaindataProvider);
39
40
  return {
40
41
  substrate,
41
- evm
42
+ evm,
43
+ solana
42
44
  };
43
45
  });
44
46
 
@@ -80,32 +82,17 @@ var packageJson = {
80
82
 
81
83
  var log = anylogger(packageJson.name);
82
84
 
83
- /**
84
- * Converts a dexie Observable into an rxjs Observable.
85
- */
86
- function dexieToRxjs(o) {
87
- return new Observable(observer => {
88
- const subscription = o.subscribe({
89
- next: value => observer.next(value),
90
- error: error => observer.error(error)
91
- });
92
- return () => subscription.unsubscribe();
93
- });
94
- }
95
-
96
85
  const tokenRatesAtom = atom(async get => {
97
86
  // runs a timer to keep tokenRates up to date
98
87
  get(tokenRatesFetcherAtomEffect);
99
- return await get(tokenRatesDbAtom);
88
+ return (await get(tokenRatesDbAtom)).tokenRates;
100
89
  });
101
- const tokenRatesDbAtom = atomWithObservable(() => {
102
- const dbRatesToMap = dbRates => Object.fromEntries(dbRates.map(({
103
- tokenId,
104
- rates
105
- }) => [tokenId, rates]));
106
90
 
107
- // retrieve fetched tokenRates from the db
108
- return dexieToRxjs(liveQuery(() => db.tokenRates.toArray())).pipe(map(dbRatesToMap));
91
+ // TODO: Persist to storage
92
+ const tokenRates$ = new ReplaySubject(1);
93
+ const tokenRatesDbAtom = atomWithObservable(() => {
94
+ tryToDeleteOldTokenRatesDb();
95
+ return tokenRates$.asObservable();
109
96
  });
110
97
  const tokenRatesFetcherAtomEffect = atomEffect(get => {
111
98
  // lets us tear down the existing timer when the effect is restarted
@@ -116,7 +103,6 @@ const tokenRatesFetcherAtomEffect = atomEffect(get => {
116
103
  const tokensPromise = get(tokensAtom);
117
104
  (async () => {
118
105
  const tokensById = keyBy(await tokensPromise, "id");
119
- const tokenIds = Object.keys(tokensById);
120
106
  const loopMs = 300_000; // 300_000ms = 300s = 5 minutes
121
107
  const retryTimeout = 5_000; // 5_000ms = 5 seconds
122
108
 
@@ -124,21 +110,11 @@ const tokenRatesFetcherAtomEffect = atomEffect(get => {
124
110
  try {
125
111
  if (abort.signal.aborted) return; // don't fetch if aborted
126
112
  const tokenRates = await fetchTokenRates(tokensById, ALL_CURRENCY_IDS, coinsApiConfig);
127
- const putTokenRates = Object.entries(tokenRates).map(([tokenId, rates]) => ({
128
- tokenId,
129
- rates
130
- }));
113
+ const putTokenRates = {
114
+ tokenRates
115
+ };
131
116
  if (abort.signal.aborted) return; // don't insert into db if aborted
132
- await db.transaction("rw", db.tokenRates, async () => {
133
- // override all tokenRates
134
- await db.tokenRates.bulkPut(putTokenRates);
135
-
136
- // delete tokenRates for tokens which no longer exist
137
- const validTokenIds = new Set(tokenIds);
138
- const tokenRatesIds = await db.tokenRates.toCollection().primaryKeys();
139
- const deleteIds = tokenRatesIds.filter(id => !validTokenIds.has(id));
140
- if (deleteIds.length > 0) await db.tokenRates.bulkDelete(deleteIds);
141
- });
117
+ tokenRates$.next(putTokenRates);
142
118
  if (abort.signal.aborted) return; // don't schedule next loop if aborted
143
119
  setTimeout(hydrate, loopMs);
144
120
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@talismn/balances-react",
3
- "version": "0.0.0-pr2131-20250807071252",
3
+ "version": "0.0.0-pr2134-20250813092023",
4
4
  "author": "Talisman",
5
5
  "homepage": "https://talisman.xyz",
6
6
  "license": "GPL-3.0-or-later",
@@ -23,21 +23,18 @@
23
23
  "dependencies": {
24
24
  "anylogger": "^1.0.11",
25
25
  "blueimp-md5": "2.19.0",
26
- "dexie": "^4.0.9",
27
- "dexie-react-hooks": "^1.1.7",
28
26
  "jotai": "~2",
29
27
  "jotai-effect": "~1",
30
28
  "lodash-es": "4.17.21",
31
29
  "react-use": "^17.5.1",
32
30
  "rxjs": "^7.8.1",
33
- "@talismn/balances": "0.0.0-pr2131-20250807071252",
34
- "@talismn/chain-connector": "0.0.0-pr2131-20250807071252",
35
- "@talismn/chain-connector-evm": "0.0.0-pr2131-20250807071252",
36
- "@talismn/chaindata-provider": "0.0.0-pr2131-20250807071252",
37
- "@talismn/connection-meta": "0.0.0-pr2131-20250807071252",
38
- "@talismn/scale": "0.2.0",
39
- "@talismn/token-rates": "0.0.0-pr2131-20250807071252",
40
- "@talismn/util": "0.5.0"
31
+ "@talismn/balances": "0.0.0-pr2134-20250813092023",
32
+ "@talismn/chain-connectors": "0.0.0-pr2134-20250813092023",
33
+ "@talismn/chaindata-provider": "0.0.0-pr2134-20250813092023",
34
+ "@talismn/connection-meta": "0.0.0-pr2134-20250813092023",
35
+ "@talismn/util": "0.0.0-pr2134-20250813092023",
36
+ "@talismn/token-rates": "0.0.0-pr2134-20250813092023",
37
+ "@talismn/scale": "0.2.0"
41
38
  },
42
39
  "devDependencies": {
43
40
  "@types/jest": "^29.5.14",
@@ -1,6 +0,0 @@
1
- import { Observable as DexieObservable } from "dexie";
2
- import { Observable as RxjsObservable } from "rxjs";
3
- /**
4
- * Converts a dexie Observable into an rxjs Observable.
5
- */
6
- export declare function dexieToRxjs<T>(o: DexieObservable<T>): RxjsObservable<T>;