@talismn/balances-react 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +54 -0
- package/dist/declarations/src/hooks/index.d.ts +2 -2
- package/dist/declarations/src/hooks/useBalanceModules.d.ts +3 -3
- package/dist/declarations/src/hooks/useBalancesStatus.d.ts +1 -2
- package/dist/talismn-balances-react.cjs.dev.js +37 -46
- package/dist/talismn-balances-react.cjs.prod.js +37 -46
- package/dist/talismn-balances-react.esm.js +38 -47
- package/package.json +12 -12
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,59 @@
|
|
1
1
|
# @talismn/balances-react
|
2
2
|
|
3
|
+
## 0.5.0
|
4
|
+
|
5
|
+
### Minor Changes
|
6
|
+
|
7
|
+
- eebb640d: Synchronise chains, networks & tokens config with Talisman extension
|
8
|
+
|
9
|
+
### Patch Changes
|
10
|
+
|
11
|
+
- Updated dependencies [eebb640d]
|
12
|
+
- @talismn/chaindata-provider-extension@0.6.0
|
13
|
+
- @talismn/balances@0.5.0
|
14
|
+
- @talismn/chain-connector@0.6.0
|
15
|
+
- @talismn/chain-connector-evm@0.6.0
|
16
|
+
- @talismn/chaindata-provider@0.6.0
|
17
|
+
- @talismn/connection-meta@0.0.5
|
18
|
+
- @talismn/token-rates@0.1.18
|
19
|
+
|
20
|
+
## 0.4.2
|
21
|
+
|
22
|
+
### Patch Changes
|
23
|
+
|
24
|
+
- Updated dependencies [1a2fdc73]
|
25
|
+
- Updated dependencies [eebb640d]
|
26
|
+
- @talismn/chaindata-provider-extension@0.5.0
|
27
|
+
- @talismn/chaindata-provider@0.5.0
|
28
|
+
- @talismn/balances@0.5.0
|
29
|
+
- @talismn/chain-connector@0.5.0
|
30
|
+
- @talismn/chain-connector-evm@0.5.0
|
31
|
+
- @talismn/connection-meta@0.0.4
|
32
|
+
- @talismn/token-rates@0.1.17
|
33
|
+
|
34
|
+
## 0.4.1
|
35
|
+
|
36
|
+
### Patch Changes
|
37
|
+
|
38
|
+
- fb8ee962: feat: proxy dapp websocket requests to talisman wallet backend when available
|
39
|
+
- f7aca48b: eslint rules
|
40
|
+
- 01bf239b: feat: crowdloan and nom pool balances
|
41
|
+
- 48f0222e: fix: removed some explicit `any`s
|
42
|
+
- 01bf239b: fix: packages publishing with incorrect interdependency versions
|
43
|
+
- Updated dependencies [fb8ee962]
|
44
|
+
- Updated dependencies [c898da98]
|
45
|
+
- Updated dependencies [f7aca48b]
|
46
|
+
- Updated dependencies [01bf239b]
|
47
|
+
- Updated dependencies [48f0222e]
|
48
|
+
- Updated dependencies [01bf239b]
|
49
|
+
- @talismn/balances@0.4.1
|
50
|
+
- @talismn/chain-connector@0.4.4
|
51
|
+
- @talismn/chaindata-provider-extension@0.4.4
|
52
|
+
- @talismn/chain-connector-evm@0.4.4
|
53
|
+
- @talismn/chaindata-provider@0.4.4
|
54
|
+
- @talismn/connection-meta@0.0.3
|
55
|
+
- @talismn/token-rates@0.1.16
|
56
|
+
|
3
57
|
## 0.4.0
|
4
58
|
|
5
59
|
### Minor Changes
|
@@ -12,10 +12,10 @@ export * from "./useEvmNetworks";
|
|
12
12
|
export * from "./useTokenRates";
|
13
13
|
export * from "./useTokens";
|
14
14
|
export * from "./useWithTestnets";
|
15
|
-
import {
|
15
|
+
import { AnyBalanceModule, Hydrate } from "@talismn/balances";
|
16
16
|
import { ReactNode } from "react";
|
17
17
|
export type BalancesProviderProps = {
|
18
|
-
balanceModules: Array<(hydrate: Hydrate) =>
|
18
|
+
balanceModules: Array<(hydrate: Hydrate) => AnyBalanceModule>;
|
19
19
|
onfinalityApiKey?: string;
|
20
20
|
withTestnets?: boolean;
|
21
21
|
children?: ReactNode;
|
@@ -1,8 +1,8 @@
|
|
1
1
|
/// <reference types="react" />
|
2
|
-
import {
|
2
|
+
import { AnyBalanceModule, Hydrate } from "@talismn/balances";
|
3
3
|
export type BalanceModulesProviderOptions = {
|
4
|
-
balanceModules: Array<(hydrate: Hydrate) =>
|
4
|
+
balanceModules: Array<(hydrate: Hydrate) => AnyBalanceModule>;
|
5
5
|
};
|
6
6
|
export declare const BalanceModulesProvider: import("react").FC<BalanceModulesProviderOptions & {
|
7
7
|
children?: import("react").ReactNode;
|
8
|
-
}>, useBalanceModules: () =>
|
8
|
+
}>, useBalanceModules: () => AnyBalanceModule[];
|
@@ -11,9 +11,8 @@ export type BalancesStatus = {
|
|
11
11
|
* Given a collection of `Balances`, this hook returns a `BalancesStatus` summary for the collection.
|
12
12
|
*
|
13
13
|
* @param balances The collection of balances to get the status from.
|
14
|
-
* @param isLoadingLocks Because the wallet currently fetches locks outside of the balances api, this param can be used to indicate that the locks are still loading, even if the `Balances` collection is not.
|
15
14
|
* @returns An instance of `BalancesStatus` which represents the status of the balances collection.
|
16
15
|
|
17
16
|
*/
|
18
|
-
export declare const useBalancesStatus: (balances: Balances
|
17
|
+
export declare const useBalancesStatus: (balances: Balances) => BalancesStatus;
|
19
18
|
export declare const getStaleChains: (balances: Balances) => string[];
|
@@ -121,21 +121,6 @@ const DEFAULT_VALUE = {
|
|
121
121
|
};
|
122
122
|
const consolidateDbCache = (chainsMap, evmNetworksMap, tokensMap, tokenRates, allBalances) => {
|
123
123
|
if (!chainsMap || !evmNetworksMap || !tokensMap || !tokenRates || !allBalances) return DEFAULT_VALUE;
|
124
|
-
|
125
|
-
// BEGIN: temp hack to indicate that
|
126
|
-
// - EVM GLMR is a mirror of substrate GLMR
|
127
|
-
// - EVM MOVR is a mirror of substrate MOVR
|
128
|
-
// - EVM DEV is a mirror of substrate DEV
|
129
|
-
// - EVM ACA is a mirror of substrate ACA
|
130
|
-
const mirrorTokenIds = {
|
131
|
-
"1284-evm-native-glmr": "moonbeam-substrate-native-glmr",
|
132
|
-
"1285-evm-native-movr": "moonriver-substrate-native-movr",
|
133
|
-
"1287-evm-native-dev": "moonbase-alpha-testnet-substrate-native-dev",
|
134
|
-
"787-evm-native-aca": "acala-substrate-native-aca"
|
135
|
-
};
|
136
|
-
Object.entries(mirrorTokenIds).filter(([mirrorToken]) => tokensMap[mirrorToken]).forEach(([mirrorToken, mirrorOf]) => tokensMap[mirrorToken].mirrorOf = mirrorOf);
|
137
|
-
// END: temp hack
|
138
|
-
|
139
124
|
const chainsWithTestnets = Object.values(chainsMap);
|
140
125
|
const chainsWithoutTestnets = chainsWithTestnets.filter(filterNoTestnet);
|
141
126
|
const chainsWithoutTestnetsMap = Object.fromEntries(chainsWithoutTestnets.map(network => [network.id, network]));
|
@@ -184,7 +169,7 @@ const useDbCacheProvider = () => {
|
|
184
169
|
// debounce every 500ms to prevent hammering UI with updates
|
185
170
|
reactUse.useDebounce(() => {
|
186
171
|
setDbData(consolidateDbCache(chainList, evmNetworkList, tokenList, tokenRates$1, rawBalances));
|
187
|
-
}, 500, [chainList, evmNetworkList, tokenList,
|
172
|
+
}, 500, [chainList, evmNetworkList, tokenList, tokenRates$1, rawBalances]);
|
188
173
|
const refInitialized = react.useRef(false);
|
189
174
|
|
190
175
|
// force an update as soon as all datasources are fetched, so UI can display data ASAP
|
@@ -193,14 +178,14 @@ const useDbCacheProvider = () => {
|
|
193
178
|
setDbData(consolidateDbCache(chainList, evmNetworkList, tokenList, tokenRates$1, rawBalances));
|
194
179
|
refInitialized.current = true;
|
195
180
|
}
|
196
|
-
}, [chainList, evmNetworkList,
|
181
|
+
}, [chainList, evmNetworkList, tokenList, tokenRates$1, rawBalances]);
|
197
182
|
return dbData;
|
198
183
|
};
|
199
184
|
const [DbCacheProvider, useDbCache] = provideContext(useDbCacheProvider);
|
200
185
|
|
201
186
|
var packageJson = {
|
202
187
|
name: "@talismn/balances-react",
|
203
|
-
version: "0.
|
188
|
+
version: "0.5.0",
|
204
189
|
author: "Talisman",
|
205
190
|
homepage: "https://talisman.xyz",
|
206
191
|
license: "UNLICENSED",
|
@@ -222,27 +207,27 @@ var packageJson = {
|
|
222
207
|
},
|
223
208
|
scripts: {
|
224
209
|
test: "jest",
|
225
|
-
lint: "eslint
|
210
|
+
lint: "eslint src --max-warnings 0",
|
226
211
|
clean: "rm -rf dist && rm -rf .turbo rm -rf node_modules"
|
227
212
|
},
|
228
213
|
dependencies: {
|
229
|
-
"@talismn/balances": "workspace
|
230
|
-
"@talismn/chain-connector": "workspace
|
231
|
-
"@talismn/chain-connector-evm": "workspace
|
232
|
-
"@talismn/chaindata-provider": "workspace
|
233
|
-
"@talismn/chaindata-provider-extension": "workspace
|
234
|
-
"@talismn/connection-meta": "workspace
|
235
|
-
"@talismn/token-rates": "workspace
|
214
|
+
"@talismn/balances": "workspace:*",
|
215
|
+
"@talismn/chain-connector": "workspace:*",
|
216
|
+
"@talismn/chain-connector-evm": "workspace:*",
|
217
|
+
"@talismn/chaindata-provider": "workspace:*",
|
218
|
+
"@talismn/chaindata-provider-extension": "workspace:*",
|
219
|
+
"@talismn/connection-meta": "workspace:*",
|
220
|
+
"@talismn/token-rates": "workspace:*",
|
236
221
|
anylogger: "^1.0.11",
|
237
222
|
"blueimp-md5": "2.19.0",
|
238
223
|
dexie: "^3.2.3",
|
239
224
|
"dexie-react-hooks": "^1.1.3",
|
240
225
|
"react-use": "^17.4.0",
|
241
|
-
rxjs: "^7.8.
|
226
|
+
rxjs: "^7.8.1"
|
242
227
|
},
|
243
228
|
devDependencies: {
|
244
|
-
"@talismn/eslint-config": "workspace
|
245
|
-
"@talismn/tsconfig": "workspace
|
229
|
+
"@talismn/eslint-config": "workspace:*",
|
230
|
+
"@talismn/tsconfig": "workspace:*",
|
246
231
|
"@types/jest": "^27.5.1",
|
247
232
|
"@types/react": "^18.0.17",
|
248
233
|
eslint: "^8.4.0",
|
@@ -503,10 +488,25 @@ const subscribeBalances = (tokens, addresses, balanceModules) => {
|
|
503
488
|
id
|
504
489
|
}) => id);
|
505
490
|
const addressesByToken = Object.fromEntries(tokenIds.map(tokenId => [tokenId, addresses]));
|
491
|
+
const subscriptionId = balances.createSubscriptionId();
|
492
|
+
|
493
|
+
// TODO: Create subscriptions in a service worker, where we can detect page closes
|
494
|
+
// and therefore reliably delete the subscriptionId when the user closes our dapp
|
495
|
+
//
|
496
|
+
// For more information, check out https://developer.chrome.com/blog/page-lifecycle-api/#faqs
|
497
|
+
// and scroll down to:
|
498
|
+
// - `What is the back/forward cache?`, and
|
499
|
+
// - `If I can't run asynchronous APIs in the frozen or terminated states, how can I save data to IndexedDB?
|
500
|
+
//
|
501
|
+
// For now, we'll just last-ditch remove the subscriptionId (it works surprisingly well!) in the beforeunload event
|
502
|
+
window.onbeforeunload = () => {
|
503
|
+
balances.deleteSubscriptionId();
|
504
|
+
};
|
506
505
|
const updateDb = balances$1 => {
|
507
506
|
const putBalances = Object.entries(balances$1.toJSON()).map(([id, balance]) => ({
|
508
507
|
id,
|
509
|
-
...balance
|
508
|
+
...balance,
|
509
|
+
status: balances.BalanceStatusLive(subscriptionId)
|
510
510
|
}));
|
511
511
|
balances.db.transaction("rw", balances.db.balances, async () => await balances.db.balances.bulkPut(putBalances));
|
512
512
|
};
|
@@ -525,7 +525,7 @@ const subscribeBalances = (tokens, addresses, balanceModules) => {
|
|
525
525
|
const unsub = balances.balances(balanceModule, addressesByModuleToken, (error, balances$1) => {
|
526
526
|
// log errors
|
527
527
|
if (error) {
|
528
|
-
if (error?.type === "STALE_RPC_ERROR") return balances.db.balances.where({
|
528
|
+
if (error?.type === "STALE_RPC_ERROR" || error?.type === "WEBSOCKET_ALLOCATION_EXHAUSTED_ERROR") return balances.db.balances.where({
|
529
529
|
source: balanceModule.type,
|
530
530
|
chainId: error.chainId
|
531
531
|
}).filter(balance => {
|
@@ -548,15 +548,7 @@ const subscribeBalances = (tokens, addresses, balanceModules) => {
|
|
548
548
|
unsub.then(unsubscribe => {
|
549
549
|
setTimeout(unsubscribe, 2_000);
|
550
550
|
});
|
551
|
-
balances.
|
552
|
-
source: balanceModule.type
|
553
|
-
}).filter(balance => {
|
554
|
-
if (!Object.keys(addressesByModuleToken).includes(balance.tokenId)) return false;
|
555
|
-
if (!addressesByModuleToken[balance.tokenId].includes(balance.address)) return false;
|
556
|
-
return true;
|
557
|
-
}).modify({
|
558
|
-
status: "cache"
|
559
|
-
});
|
551
|
+
balances.deleteSubscriptionId();
|
560
552
|
};
|
561
553
|
});
|
562
554
|
const unsubscribeAll = () => {
|
@@ -645,7 +637,7 @@ function useBalances(addressesByToken) {
|
|
645
637
|
balances: balances$1
|
646
638
|
} = useDbCache();
|
647
639
|
const hydrate = useBalancesHydrate();
|
648
|
-
return react.useMemo(() => new balances.Balances(balances$1.filter(balance => {
|
640
|
+
return react.useMemo(() => new balances.Balances(balances.deriveStatuses([...balances.getValidSubscriptionIds()], balances$1.filter(balance => {
|
649
641
|
// check that this balance is included in our queried balance modules
|
650
642
|
if (!balanceModules.map(({
|
651
643
|
type
|
@@ -662,7 +654,7 @@ function useBalances(addressesByToken) {
|
|
662
654
|
|
663
655
|
// keep this balance
|
664
656
|
return true;
|
665
|
-
}),
|
657
|
+
})),
|
666
658
|
// hydrate balance chains, evmNetworks, tokens and tokenRates
|
667
659
|
hydrate), [balances$1, hydrate, balanceModules, addressesByToken]);
|
668
660
|
}
|
@@ -671,11 +663,10 @@ function useBalances(addressesByToken) {
|
|
671
663
|
* Given a collection of `Balances`, this hook returns a `BalancesStatus` summary for the collection.
|
672
664
|
*
|
673
665
|
* @param balances The collection of balances to get the status from.
|
674
|
-
* @param isLoadingLocks Because the wallet currently fetches locks outside of the balances api, this param can be used to indicate that the locks are still loading, even if the `Balances` collection is not.
|
675
666
|
* @returns An instance of `BalancesStatus` which represents the status of the balances collection.
|
676
667
|
|
677
668
|
*/
|
678
|
-
const useBalancesStatus =
|
669
|
+
const useBalancesStatus = balances => react.useMemo(() => {
|
679
670
|
// stale
|
680
671
|
const staleChains = getStaleChains(balances);
|
681
672
|
if (staleChains.length > 0) return {
|
@@ -685,7 +676,7 @@ const useBalancesStatus = (balances, isLoadingLocks) => react.useMemo(() => {
|
|
685
676
|
|
686
677
|
// fetching
|
687
678
|
const hasCachedBalances = balances.each.some(b => b.status === "cache");
|
688
|
-
if (hasCachedBalances
|
679
|
+
if (hasCachedBalances) return {
|
689
680
|
status: "fetching"
|
690
681
|
};
|
691
682
|
|
@@ -693,7 +684,7 @@ const useBalancesStatus = (balances, isLoadingLocks) => react.useMemo(() => {
|
|
693
684
|
return {
|
694
685
|
status: "live"
|
695
686
|
};
|
696
|
-
}, [balances
|
687
|
+
}, [balances]);
|
697
688
|
const getStaleChains = balances => [...new Set(balances.sorted.filter(b => b.status === "stale").map(b => b.chain?.name ?? b.chainId ?? "Unknown"))];
|
698
689
|
|
699
690
|
const BalancesProvider = ({
|
@@ -121,21 +121,6 @@ const DEFAULT_VALUE = {
|
|
121
121
|
};
|
122
122
|
const consolidateDbCache = (chainsMap, evmNetworksMap, tokensMap, tokenRates, allBalances) => {
|
123
123
|
if (!chainsMap || !evmNetworksMap || !tokensMap || !tokenRates || !allBalances) return DEFAULT_VALUE;
|
124
|
-
|
125
|
-
// BEGIN: temp hack to indicate that
|
126
|
-
// - EVM GLMR is a mirror of substrate GLMR
|
127
|
-
// - EVM MOVR is a mirror of substrate MOVR
|
128
|
-
// - EVM DEV is a mirror of substrate DEV
|
129
|
-
// - EVM ACA is a mirror of substrate ACA
|
130
|
-
const mirrorTokenIds = {
|
131
|
-
"1284-evm-native-glmr": "moonbeam-substrate-native-glmr",
|
132
|
-
"1285-evm-native-movr": "moonriver-substrate-native-movr",
|
133
|
-
"1287-evm-native-dev": "moonbase-alpha-testnet-substrate-native-dev",
|
134
|
-
"787-evm-native-aca": "acala-substrate-native-aca"
|
135
|
-
};
|
136
|
-
Object.entries(mirrorTokenIds).filter(([mirrorToken]) => tokensMap[mirrorToken]).forEach(([mirrorToken, mirrorOf]) => tokensMap[mirrorToken].mirrorOf = mirrorOf);
|
137
|
-
// END: temp hack
|
138
|
-
|
139
124
|
const chainsWithTestnets = Object.values(chainsMap);
|
140
125
|
const chainsWithoutTestnets = chainsWithTestnets.filter(filterNoTestnet);
|
141
126
|
const chainsWithoutTestnetsMap = Object.fromEntries(chainsWithoutTestnets.map(network => [network.id, network]));
|
@@ -184,7 +169,7 @@ const useDbCacheProvider = () => {
|
|
184
169
|
// debounce every 500ms to prevent hammering UI with updates
|
185
170
|
reactUse.useDebounce(() => {
|
186
171
|
setDbData(consolidateDbCache(chainList, evmNetworkList, tokenList, tokenRates$1, rawBalances));
|
187
|
-
}, 500, [chainList, evmNetworkList, tokenList,
|
172
|
+
}, 500, [chainList, evmNetworkList, tokenList, tokenRates$1, rawBalances]);
|
188
173
|
const refInitialized = react.useRef(false);
|
189
174
|
|
190
175
|
// force an update as soon as all datasources are fetched, so UI can display data ASAP
|
@@ -193,14 +178,14 @@ const useDbCacheProvider = () => {
|
|
193
178
|
setDbData(consolidateDbCache(chainList, evmNetworkList, tokenList, tokenRates$1, rawBalances));
|
194
179
|
refInitialized.current = true;
|
195
180
|
}
|
196
|
-
}, [chainList, evmNetworkList,
|
181
|
+
}, [chainList, evmNetworkList, tokenList, tokenRates$1, rawBalances]);
|
197
182
|
return dbData;
|
198
183
|
};
|
199
184
|
const [DbCacheProvider, useDbCache] = provideContext(useDbCacheProvider);
|
200
185
|
|
201
186
|
var packageJson = {
|
202
187
|
name: "@talismn/balances-react",
|
203
|
-
version: "0.
|
188
|
+
version: "0.5.0",
|
204
189
|
author: "Talisman",
|
205
190
|
homepage: "https://talisman.xyz",
|
206
191
|
license: "UNLICENSED",
|
@@ -222,27 +207,27 @@ var packageJson = {
|
|
222
207
|
},
|
223
208
|
scripts: {
|
224
209
|
test: "jest",
|
225
|
-
lint: "eslint
|
210
|
+
lint: "eslint src --max-warnings 0",
|
226
211
|
clean: "rm -rf dist && rm -rf .turbo rm -rf node_modules"
|
227
212
|
},
|
228
213
|
dependencies: {
|
229
|
-
"@talismn/balances": "workspace
|
230
|
-
"@talismn/chain-connector": "workspace
|
231
|
-
"@talismn/chain-connector-evm": "workspace
|
232
|
-
"@talismn/chaindata-provider": "workspace
|
233
|
-
"@talismn/chaindata-provider-extension": "workspace
|
234
|
-
"@talismn/connection-meta": "workspace
|
235
|
-
"@talismn/token-rates": "workspace
|
214
|
+
"@talismn/balances": "workspace:*",
|
215
|
+
"@talismn/chain-connector": "workspace:*",
|
216
|
+
"@talismn/chain-connector-evm": "workspace:*",
|
217
|
+
"@talismn/chaindata-provider": "workspace:*",
|
218
|
+
"@talismn/chaindata-provider-extension": "workspace:*",
|
219
|
+
"@talismn/connection-meta": "workspace:*",
|
220
|
+
"@talismn/token-rates": "workspace:*",
|
236
221
|
anylogger: "^1.0.11",
|
237
222
|
"blueimp-md5": "2.19.0",
|
238
223
|
dexie: "^3.2.3",
|
239
224
|
"dexie-react-hooks": "^1.1.3",
|
240
225
|
"react-use": "^17.4.0",
|
241
|
-
rxjs: "^7.8.
|
226
|
+
rxjs: "^7.8.1"
|
242
227
|
},
|
243
228
|
devDependencies: {
|
244
|
-
"@talismn/eslint-config": "workspace
|
245
|
-
"@talismn/tsconfig": "workspace
|
229
|
+
"@talismn/eslint-config": "workspace:*",
|
230
|
+
"@talismn/tsconfig": "workspace:*",
|
246
231
|
"@types/jest": "^27.5.1",
|
247
232
|
"@types/react": "^18.0.17",
|
248
233
|
eslint: "^8.4.0",
|
@@ -503,10 +488,25 @@ const subscribeBalances = (tokens, addresses, balanceModules) => {
|
|
503
488
|
id
|
504
489
|
}) => id);
|
505
490
|
const addressesByToken = Object.fromEntries(tokenIds.map(tokenId => [tokenId, addresses]));
|
491
|
+
const subscriptionId = balances.createSubscriptionId();
|
492
|
+
|
493
|
+
// TODO: Create subscriptions in a service worker, where we can detect page closes
|
494
|
+
// and therefore reliably delete the subscriptionId when the user closes our dapp
|
495
|
+
//
|
496
|
+
// For more information, check out https://developer.chrome.com/blog/page-lifecycle-api/#faqs
|
497
|
+
// and scroll down to:
|
498
|
+
// - `What is the back/forward cache?`, and
|
499
|
+
// - `If I can't run asynchronous APIs in the frozen or terminated states, how can I save data to IndexedDB?
|
500
|
+
//
|
501
|
+
// For now, we'll just last-ditch remove the subscriptionId (it works surprisingly well!) in the beforeunload event
|
502
|
+
window.onbeforeunload = () => {
|
503
|
+
balances.deleteSubscriptionId();
|
504
|
+
};
|
506
505
|
const updateDb = balances$1 => {
|
507
506
|
const putBalances = Object.entries(balances$1.toJSON()).map(([id, balance]) => ({
|
508
507
|
id,
|
509
|
-
...balance
|
508
|
+
...balance,
|
509
|
+
status: balances.BalanceStatusLive(subscriptionId)
|
510
510
|
}));
|
511
511
|
balances.db.transaction("rw", balances.db.balances, async () => await balances.db.balances.bulkPut(putBalances));
|
512
512
|
};
|
@@ -525,7 +525,7 @@ const subscribeBalances = (tokens, addresses, balanceModules) => {
|
|
525
525
|
const unsub = balances.balances(balanceModule, addressesByModuleToken, (error, balances$1) => {
|
526
526
|
// log errors
|
527
527
|
if (error) {
|
528
|
-
if (error?.type === "STALE_RPC_ERROR") return balances.db.balances.where({
|
528
|
+
if (error?.type === "STALE_RPC_ERROR" || error?.type === "WEBSOCKET_ALLOCATION_EXHAUSTED_ERROR") return balances.db.balances.where({
|
529
529
|
source: balanceModule.type,
|
530
530
|
chainId: error.chainId
|
531
531
|
}).filter(balance => {
|
@@ -548,15 +548,7 @@ const subscribeBalances = (tokens, addresses, balanceModules) => {
|
|
548
548
|
unsub.then(unsubscribe => {
|
549
549
|
setTimeout(unsubscribe, 2_000);
|
550
550
|
});
|
551
|
-
balances.
|
552
|
-
source: balanceModule.type
|
553
|
-
}).filter(balance => {
|
554
|
-
if (!Object.keys(addressesByModuleToken).includes(balance.tokenId)) return false;
|
555
|
-
if (!addressesByModuleToken[balance.tokenId].includes(balance.address)) return false;
|
556
|
-
return true;
|
557
|
-
}).modify({
|
558
|
-
status: "cache"
|
559
|
-
});
|
551
|
+
balances.deleteSubscriptionId();
|
560
552
|
};
|
561
553
|
});
|
562
554
|
const unsubscribeAll = () => {
|
@@ -645,7 +637,7 @@ function useBalances(addressesByToken) {
|
|
645
637
|
balances: balances$1
|
646
638
|
} = useDbCache();
|
647
639
|
const hydrate = useBalancesHydrate();
|
648
|
-
return react.useMemo(() => new balances.Balances(balances$1.filter(balance => {
|
640
|
+
return react.useMemo(() => new balances.Balances(balances.deriveStatuses([...balances.getValidSubscriptionIds()], balances$1.filter(balance => {
|
649
641
|
// check that this balance is included in our queried balance modules
|
650
642
|
if (!balanceModules.map(({
|
651
643
|
type
|
@@ -662,7 +654,7 @@ function useBalances(addressesByToken) {
|
|
662
654
|
|
663
655
|
// keep this balance
|
664
656
|
return true;
|
665
|
-
}),
|
657
|
+
})),
|
666
658
|
// hydrate balance chains, evmNetworks, tokens and tokenRates
|
667
659
|
hydrate), [balances$1, hydrate, balanceModules, addressesByToken]);
|
668
660
|
}
|
@@ -671,11 +663,10 @@ function useBalances(addressesByToken) {
|
|
671
663
|
* Given a collection of `Balances`, this hook returns a `BalancesStatus` summary for the collection.
|
672
664
|
*
|
673
665
|
* @param balances The collection of balances to get the status from.
|
674
|
-
* @param isLoadingLocks Because the wallet currently fetches locks outside of the balances api, this param can be used to indicate that the locks are still loading, even if the `Balances` collection is not.
|
675
666
|
* @returns An instance of `BalancesStatus` which represents the status of the balances collection.
|
676
667
|
|
677
668
|
*/
|
678
|
-
const useBalancesStatus =
|
669
|
+
const useBalancesStatus = balances => react.useMemo(() => {
|
679
670
|
// stale
|
680
671
|
const staleChains = getStaleChains(balances);
|
681
672
|
if (staleChains.length > 0) return {
|
@@ -685,7 +676,7 @@ const useBalancesStatus = (balances, isLoadingLocks) => react.useMemo(() => {
|
|
685
676
|
|
686
677
|
// fetching
|
687
678
|
const hasCachedBalances = balances.each.some(b => b.status === "cache");
|
688
|
-
if (hasCachedBalances
|
679
|
+
if (hasCachedBalances) return {
|
689
680
|
status: "fetching"
|
690
681
|
};
|
691
682
|
|
@@ -693,7 +684,7 @@ const useBalancesStatus = (balances, isLoadingLocks) => react.useMemo(() => {
|
|
693
684
|
return {
|
694
685
|
status: "live"
|
695
686
|
};
|
696
|
-
}, [balances
|
687
|
+
}, [balances]);
|
697
688
|
const getStaleChains = balances => [...new Set(balances.sorted.filter(b => b.status === "stale").map(b => b.chain?.name ?? b.chainId ?? "Unknown"))];
|
698
689
|
|
699
690
|
const BalancesProvider = ({
|
@@ -4,7 +4,7 @@ import { ChainConnector } from '@talismn/chain-connector';
|
|
4
4
|
import { ChainConnectorEvm } from '@talismn/chain-connector-evm';
|
5
5
|
import { connectionMetaDb } from '@talismn/connection-meta';
|
6
6
|
import { ChaindataProviderExtension } from '@talismn/chaindata-provider-extension';
|
7
|
-
import { db as db$1, balances, Balances } from '@talismn/balances';
|
7
|
+
import { db as db$1, createSubscriptionId, deleteSubscriptionId, balances, BalanceStatusLive, Balances, deriveStatuses, getValidSubscriptionIds } from '@talismn/balances';
|
8
8
|
import { db, fetchTokenRates } from '@talismn/token-rates';
|
9
9
|
import { useLiveQuery } from 'dexie-react-hooks';
|
10
10
|
import { useDebounce } from 'react-use';
|
@@ -112,21 +112,6 @@ const DEFAULT_VALUE = {
|
|
112
112
|
};
|
113
113
|
const consolidateDbCache = (chainsMap, evmNetworksMap, tokensMap, tokenRates, allBalances) => {
|
114
114
|
if (!chainsMap || !evmNetworksMap || !tokensMap || !tokenRates || !allBalances) return DEFAULT_VALUE;
|
115
|
-
|
116
|
-
// BEGIN: temp hack to indicate that
|
117
|
-
// - EVM GLMR is a mirror of substrate GLMR
|
118
|
-
// - EVM MOVR is a mirror of substrate MOVR
|
119
|
-
// - EVM DEV is a mirror of substrate DEV
|
120
|
-
// - EVM ACA is a mirror of substrate ACA
|
121
|
-
const mirrorTokenIds = {
|
122
|
-
"1284-evm-native-glmr": "moonbeam-substrate-native-glmr",
|
123
|
-
"1285-evm-native-movr": "moonriver-substrate-native-movr",
|
124
|
-
"1287-evm-native-dev": "moonbase-alpha-testnet-substrate-native-dev",
|
125
|
-
"787-evm-native-aca": "acala-substrate-native-aca"
|
126
|
-
};
|
127
|
-
Object.entries(mirrorTokenIds).filter(([mirrorToken]) => tokensMap[mirrorToken]).forEach(([mirrorToken, mirrorOf]) => tokensMap[mirrorToken].mirrorOf = mirrorOf);
|
128
|
-
// END: temp hack
|
129
|
-
|
130
115
|
const chainsWithTestnets = Object.values(chainsMap);
|
131
116
|
const chainsWithoutTestnets = chainsWithTestnets.filter(filterNoTestnet);
|
132
117
|
const chainsWithoutTestnetsMap = Object.fromEntries(chainsWithoutTestnets.map(network => [network.id, network]));
|
@@ -175,7 +160,7 @@ const useDbCacheProvider = () => {
|
|
175
160
|
// debounce every 500ms to prevent hammering UI with updates
|
176
161
|
useDebounce(() => {
|
177
162
|
setDbData(consolidateDbCache(chainList, evmNetworkList, tokenList, tokenRates, rawBalances));
|
178
|
-
}, 500, [chainList, evmNetworkList, tokenList,
|
163
|
+
}, 500, [chainList, evmNetworkList, tokenList, tokenRates, rawBalances]);
|
179
164
|
const refInitialized = useRef(false);
|
180
165
|
|
181
166
|
// force an update as soon as all datasources are fetched, so UI can display data ASAP
|
@@ -184,14 +169,14 @@ const useDbCacheProvider = () => {
|
|
184
169
|
setDbData(consolidateDbCache(chainList, evmNetworkList, tokenList, tokenRates, rawBalances));
|
185
170
|
refInitialized.current = true;
|
186
171
|
}
|
187
|
-
}, [chainList, evmNetworkList,
|
172
|
+
}, [chainList, evmNetworkList, tokenList, tokenRates, rawBalances]);
|
188
173
|
return dbData;
|
189
174
|
};
|
190
175
|
const [DbCacheProvider, useDbCache] = provideContext(useDbCacheProvider);
|
191
176
|
|
192
177
|
var packageJson = {
|
193
178
|
name: "@talismn/balances-react",
|
194
|
-
version: "0.
|
179
|
+
version: "0.5.0",
|
195
180
|
author: "Talisman",
|
196
181
|
homepage: "https://talisman.xyz",
|
197
182
|
license: "UNLICENSED",
|
@@ -213,27 +198,27 @@ var packageJson = {
|
|
213
198
|
},
|
214
199
|
scripts: {
|
215
200
|
test: "jest",
|
216
|
-
lint: "eslint
|
201
|
+
lint: "eslint src --max-warnings 0",
|
217
202
|
clean: "rm -rf dist && rm -rf .turbo rm -rf node_modules"
|
218
203
|
},
|
219
204
|
dependencies: {
|
220
|
-
"@talismn/balances": "workspace
|
221
|
-
"@talismn/chain-connector": "workspace
|
222
|
-
"@talismn/chain-connector-evm": "workspace
|
223
|
-
"@talismn/chaindata-provider": "workspace
|
224
|
-
"@talismn/chaindata-provider-extension": "workspace
|
225
|
-
"@talismn/connection-meta": "workspace
|
226
|
-
"@talismn/token-rates": "workspace
|
205
|
+
"@talismn/balances": "workspace:*",
|
206
|
+
"@talismn/chain-connector": "workspace:*",
|
207
|
+
"@talismn/chain-connector-evm": "workspace:*",
|
208
|
+
"@talismn/chaindata-provider": "workspace:*",
|
209
|
+
"@talismn/chaindata-provider-extension": "workspace:*",
|
210
|
+
"@talismn/connection-meta": "workspace:*",
|
211
|
+
"@talismn/token-rates": "workspace:*",
|
227
212
|
anylogger: "^1.0.11",
|
228
213
|
"blueimp-md5": "2.19.0",
|
229
214
|
dexie: "^3.2.3",
|
230
215
|
"dexie-react-hooks": "^1.1.3",
|
231
216
|
"react-use": "^17.4.0",
|
232
|
-
rxjs: "^7.8.
|
217
|
+
rxjs: "^7.8.1"
|
233
218
|
},
|
234
219
|
devDependencies: {
|
235
|
-
"@talismn/eslint-config": "workspace
|
236
|
-
"@talismn/tsconfig": "workspace
|
220
|
+
"@talismn/eslint-config": "workspace:*",
|
221
|
+
"@talismn/tsconfig": "workspace:*",
|
237
222
|
"@types/jest": "^27.5.1",
|
238
223
|
"@types/react": "^18.0.17",
|
239
224
|
eslint: "^8.4.0",
|
@@ -494,10 +479,25 @@ const subscribeBalances = (tokens, addresses, balanceModules) => {
|
|
494
479
|
id
|
495
480
|
}) => id);
|
496
481
|
const addressesByToken = Object.fromEntries(tokenIds.map(tokenId => [tokenId, addresses]));
|
482
|
+
const subscriptionId = createSubscriptionId();
|
483
|
+
|
484
|
+
// TODO: Create subscriptions in a service worker, where we can detect page closes
|
485
|
+
// and therefore reliably delete the subscriptionId when the user closes our dapp
|
486
|
+
//
|
487
|
+
// For more information, check out https://developer.chrome.com/blog/page-lifecycle-api/#faqs
|
488
|
+
// and scroll down to:
|
489
|
+
// - `What is the back/forward cache?`, and
|
490
|
+
// - `If I can't run asynchronous APIs in the frozen or terminated states, how can I save data to IndexedDB?
|
491
|
+
//
|
492
|
+
// For now, we'll just last-ditch remove the subscriptionId (it works surprisingly well!) in the beforeunload event
|
493
|
+
window.onbeforeunload = () => {
|
494
|
+
deleteSubscriptionId();
|
495
|
+
};
|
497
496
|
const updateDb = balances => {
|
498
497
|
const putBalances = Object.entries(balances.toJSON()).map(([id, balance]) => ({
|
499
498
|
id,
|
500
|
-
...balance
|
499
|
+
...balance,
|
500
|
+
status: BalanceStatusLive(subscriptionId)
|
501
501
|
}));
|
502
502
|
db$1.transaction("rw", db$1.balances, async () => await db$1.balances.bulkPut(putBalances));
|
503
503
|
};
|
@@ -516,7 +516,7 @@ const subscribeBalances = (tokens, addresses, balanceModules) => {
|
|
516
516
|
const unsub = balances(balanceModule, addressesByModuleToken, (error, balances) => {
|
517
517
|
// log errors
|
518
518
|
if (error) {
|
519
|
-
if (error?.type === "STALE_RPC_ERROR") return db$1.balances.where({
|
519
|
+
if (error?.type === "STALE_RPC_ERROR" || error?.type === "WEBSOCKET_ALLOCATION_EXHAUSTED_ERROR") return db$1.balances.where({
|
520
520
|
source: balanceModule.type,
|
521
521
|
chainId: error.chainId
|
522
522
|
}).filter(balance => {
|
@@ -539,15 +539,7 @@ const subscribeBalances = (tokens, addresses, balanceModules) => {
|
|
539
539
|
unsub.then(unsubscribe => {
|
540
540
|
setTimeout(unsubscribe, 2_000);
|
541
541
|
});
|
542
|
-
|
543
|
-
source: balanceModule.type
|
544
|
-
}).filter(balance => {
|
545
|
-
if (!Object.keys(addressesByModuleToken).includes(balance.tokenId)) return false;
|
546
|
-
if (!addressesByModuleToken[balance.tokenId].includes(balance.address)) return false;
|
547
|
-
return true;
|
548
|
-
}).modify({
|
549
|
-
status: "cache"
|
550
|
-
});
|
542
|
+
deleteSubscriptionId();
|
551
543
|
};
|
552
544
|
});
|
553
545
|
const unsubscribeAll = () => {
|
@@ -636,7 +628,7 @@ function useBalances(addressesByToken) {
|
|
636
628
|
balances
|
637
629
|
} = useDbCache();
|
638
630
|
const hydrate = useBalancesHydrate();
|
639
|
-
return useMemo(() => new Balances(balances.filter(balance => {
|
631
|
+
return useMemo(() => new Balances(deriveStatuses([...getValidSubscriptionIds()], balances.filter(balance => {
|
640
632
|
// check that this balance is included in our queried balance modules
|
641
633
|
if (!balanceModules.map(({
|
642
634
|
type
|
@@ -653,7 +645,7 @@ function useBalances(addressesByToken) {
|
|
653
645
|
|
654
646
|
// keep this balance
|
655
647
|
return true;
|
656
|
-
}),
|
648
|
+
})),
|
657
649
|
// hydrate balance chains, evmNetworks, tokens and tokenRates
|
658
650
|
hydrate), [balances, hydrate, balanceModules, addressesByToken]);
|
659
651
|
}
|
@@ -662,11 +654,10 @@ function useBalances(addressesByToken) {
|
|
662
654
|
* Given a collection of `Balances`, this hook returns a `BalancesStatus` summary for the collection.
|
663
655
|
*
|
664
656
|
* @param balances The collection of balances to get the status from.
|
665
|
-
* @param isLoadingLocks Because the wallet currently fetches locks outside of the balances api, this param can be used to indicate that the locks are still loading, even if the `Balances` collection is not.
|
666
657
|
* @returns An instance of `BalancesStatus` which represents the status of the balances collection.
|
667
658
|
|
668
659
|
*/
|
669
|
-
const useBalancesStatus =
|
660
|
+
const useBalancesStatus = balances => useMemo(() => {
|
670
661
|
// stale
|
671
662
|
const staleChains = getStaleChains(balances);
|
672
663
|
if (staleChains.length > 0) return {
|
@@ -676,7 +667,7 @@ const useBalancesStatus = (balances, isLoadingLocks) => useMemo(() => {
|
|
676
667
|
|
677
668
|
// fetching
|
678
669
|
const hasCachedBalances = balances.each.some(b => b.status === "cache");
|
679
|
-
if (hasCachedBalances
|
670
|
+
if (hasCachedBalances) return {
|
680
671
|
status: "fetching"
|
681
672
|
};
|
682
673
|
|
@@ -684,7 +675,7 @@ const useBalancesStatus = (balances, isLoadingLocks) => useMemo(() => {
|
|
684
675
|
return {
|
685
676
|
status: "live"
|
686
677
|
};
|
687
|
-
}, [balances
|
678
|
+
}, [balances]);
|
688
679
|
const getStaleChains = balances => [...new Set(balances.sorted.filter(b => b.status === "stale").map(b => b.chain?.name ?? b.chainId ?? "Unknown"))];
|
689
680
|
|
690
681
|
const BalancesProvider = ({
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@talismn/balances-react",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.5.0",
|
4
4
|
"author": "Talisman",
|
5
5
|
"homepage": "https://talisman.xyz",
|
6
6
|
"license": "UNLICENSED",
|
@@ -22,27 +22,27 @@
|
|
22
22
|
},
|
23
23
|
"scripts": {
|
24
24
|
"test": "jest",
|
25
|
-
"lint": "eslint
|
25
|
+
"lint": "eslint src --max-warnings 0",
|
26
26
|
"clean": "rm -rf dist && rm -rf .turbo rm -rf node_modules"
|
27
27
|
},
|
28
28
|
"dependencies": {
|
29
|
-
"@talismn/balances": "
|
30
|
-
"@talismn/chain-connector": "
|
31
|
-
"@talismn/chain-connector-evm": "
|
32
|
-
"@talismn/chaindata-provider": "
|
33
|
-
"@talismn/chaindata-provider-extension": "
|
34
|
-
"@talismn/connection-meta": "
|
35
|
-
"@talismn/token-rates": "
|
29
|
+
"@talismn/balances": "0.5.0",
|
30
|
+
"@talismn/chain-connector": "0.6.0",
|
31
|
+
"@talismn/chain-connector-evm": "0.6.0",
|
32
|
+
"@talismn/chaindata-provider": "0.6.0",
|
33
|
+
"@talismn/chaindata-provider-extension": "0.6.0",
|
34
|
+
"@talismn/connection-meta": "0.0.5",
|
35
|
+
"@talismn/token-rates": "0.1.18",
|
36
36
|
"anylogger": "^1.0.11",
|
37
37
|
"blueimp-md5": "2.19.0",
|
38
38
|
"dexie": "^3.2.3",
|
39
39
|
"dexie-react-hooks": "^1.1.3",
|
40
40
|
"react-use": "^17.4.0",
|
41
|
-
"rxjs": "^7.8.
|
41
|
+
"rxjs": "^7.8.1"
|
42
42
|
},
|
43
43
|
"devDependencies": {
|
44
|
-
"@talismn/eslint-config": "
|
45
|
-
"@talismn/tsconfig": "
|
44
|
+
"@talismn/eslint-config": "0.0.2",
|
45
|
+
"@talismn/tsconfig": "0.0.2",
|
46
46
|
"@types/jest": "^27.5.1",
|
47
47
|
"@types/react": "^18.0.17",
|
48
48
|
"eslint": "^8.4.0",
|