@talismn/chaindata-provider 0.7.0 → 0.8.1

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 (77) hide show
  1. package/dist/declarations/src/ChaindataProvider.d.ts +90 -17
  2. package/dist/declarations/src/TalismanChaindataDatabase.d.ts +9 -0
  3. package/dist/declarations/src/constants.d.ts +26 -0
  4. package/dist/declarations/src/index.d.ts +5 -2
  5. package/dist/declarations/src/init/chains.d.ts +243 -0
  6. package/dist/declarations/src/init/evm-networks.d.ts +61 -0
  7. package/dist/declarations/src/init/index.d.ts +5 -0
  8. package/dist/declarations/src/init/mini-metadatas.d.ts +21 -0
  9. package/dist/declarations/src/init/tokens.d.ts +103 -0
  10. package/dist/declarations/src/log.d.ts +2 -0
  11. package/dist/declarations/src/net.d.ts +8 -0
  12. package/dist/declarations/src/types/Chain.d.ts +42 -5
  13. package/dist/declarations/src/types/ChaindataProviderInterface.d.ts +42 -0
  14. package/dist/declarations/src/types/EvmNetwork.d.ts +17 -4
  15. package/dist/declarations/src/types/Token/EvmErc20Token.d.ts +15 -0
  16. package/dist/declarations/src/types/Token/EvmNativeToken.d.ts +10 -0
  17. package/dist/declarations/src/types/Token/EvmUniswapV2Token.d.ts +22 -0
  18. package/dist/declarations/src/types/Token/SubstrateAssetsToken.d.ts +12 -0
  19. package/dist/declarations/src/types/Token/SubstrateEquilibriumToken.d.ts +11 -0
  20. package/dist/declarations/src/types/Token/SubstrateForeignAssetsToken.d.ts +12 -0
  21. package/dist/declarations/src/types/Token/SubstrateNativeToken.d.ts +13 -0
  22. package/dist/declarations/src/types/Token/SubstratePsp22Token.d.ts +11 -0
  23. package/dist/declarations/src/types/Token/SubstrateTokensToken.d.ts +11 -0
  24. package/dist/declarations/src/types/Token/index.d.ts +26 -0
  25. package/dist/declarations/src/types/Token/types.d.ts +27 -0
  26. package/dist/declarations/src/types/index.d.ts +1 -0
  27. package/dist/declarations/src/upgrades/2024-01-25-upgradeAddIsDefaultToExistingChains.d.ts +2 -0
  28. package/dist/declarations/src/upgrades/2024-01-25-upgradeRemoveSymbolFromNativeTokenId.d.ts +2 -0
  29. package/dist/declarations/src/upgrades/index.d.ts +1 -0
  30. package/dist/declarations/src/util.d.ts +27 -0
  31. package/dist/net-BE0MfrDv.cjs.dev.js +89 -0
  32. package/dist/net-BE0MfrDv.cjs.prod.js +89 -0
  33. package/dist/net-il4EYhJN.esm.js +55 -0
  34. package/dist/talismn-chaindata-provider.cjs.dev.js +912 -23
  35. package/dist/talismn-chaindata-provider.cjs.prod.js +912 -23
  36. package/dist/talismn-chaindata-provider.esm.js +858 -12
  37. package/init/chains/dist/talismn-chaindata-provider-init-chains.cjs.d.ts +1 -0
  38. package/init/chains/dist/talismn-chaindata-provider-init-chains.cjs.dev.js +934 -0
  39. package/init/chains/dist/talismn-chaindata-provider-init-chains.cjs.js +7 -0
  40. package/init/chains/dist/talismn-chaindata-provider-init-chains.cjs.prod.js +934 -0
  41. package/init/chains/dist/talismn-chaindata-provider-init-chains.esm.js +932 -0
  42. package/init/chains/package.json +4 -0
  43. package/init/evm-networks/dist/talismn-chaindata-provider-init-evm-networks.cjs.d.ts +1 -0
  44. package/init/evm-networks/dist/talismn-chaindata-provider-init-evm-networks.cjs.dev.js +69 -0
  45. package/init/evm-networks/dist/talismn-chaindata-provider-init-evm-networks.cjs.js +7 -0
  46. package/init/evm-networks/dist/talismn-chaindata-provider-init-evm-networks.cjs.prod.js +69 -0
  47. package/init/evm-networks/dist/talismn-chaindata-provider-init-evm-networks.esm.js +67 -0
  48. package/init/evm-networks/package.json +4 -0
  49. package/init/mini-metadatas/dist/talismn-chaindata-provider-init-mini-metadatas.cjs.d.ts +1 -0
  50. package/init/mini-metadatas/dist/talismn-chaindata-provider-init-mini-metadatas.cjs.dev.js +311 -0
  51. package/init/mini-metadatas/dist/talismn-chaindata-provider-init-mini-metadatas.cjs.js +7 -0
  52. package/init/mini-metadatas/dist/talismn-chaindata-provider-init-mini-metadatas.cjs.prod.js +311 -0
  53. package/init/mini-metadatas/dist/talismn-chaindata-provider-init-mini-metadatas.esm.js +309 -0
  54. package/init/mini-metadatas/package.json +4 -0
  55. package/init/tokens/dist/talismn-chaindata-provider-init-tokens.cjs.d.ts +1 -0
  56. package/init/tokens/dist/talismn-chaindata-provider-init-tokens.cjs.dev.js +406 -0
  57. package/init/tokens/dist/talismn-chaindata-provider-init-tokens.cjs.js +7 -0
  58. package/init/tokens/dist/talismn-chaindata-provider-init-tokens.cjs.prod.js +406 -0
  59. package/init/tokens/dist/talismn-chaindata-provider-init-tokens.esm.js +404 -0
  60. package/init/tokens/package.json +4 -0
  61. package/net/dist/talismn-chaindata-provider-net.cjs.d.ts +1 -0
  62. package/net/dist/talismn-chaindata-provider-net.cjs.dev.js +14 -0
  63. package/net/dist/talismn-chaindata-provider-net.cjs.js +7 -0
  64. package/net/dist/talismn-chaindata-provider-net.cjs.prod.js +14 -0
  65. package/net/dist/talismn-chaindata-provider-net.esm.js +1 -0
  66. package/net/package.json +4 -0
  67. package/package.json +27 -14
  68. package/CHANGELOG.md +0 -104
  69. package/dist/declarations/src/github.d.ts +0 -11
  70. package/dist/declarations/src/plugins.d.ts +0 -17
  71. package/dist/declarations/src/types/Token.d.ts +0 -48
  72. package/plugins/dist/talismn-chaindata-provider-plugins.cjs.d.ts +0 -1
  73. package/plugins/dist/talismn-chaindata-provider-plugins.cjs.dev.js +0 -2
  74. package/plugins/dist/talismn-chaindata-provider-plugins.cjs.js +0 -7
  75. package/plugins/dist/talismn-chaindata-provider-plugins.cjs.prod.js +0 -2
  76. package/plugins/dist/talismn-chaindata-provider-plugins.esm.js +0 -1
  77. package/plugins/package.json +0 -4
@@ -1,25 +1,914 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- const githubChaindataBranch = "v3";
6
- const githubChaindataBaseUrl = `https://raw.githubusercontent.com/TalismanSociety/chaindata/${githubChaindataBranch}`;
7
- const githubChainsUrl = `${githubChaindataBaseUrl}/chaindata.json`;
8
- const githubTestnetChainsUrl = `${githubChaindataBaseUrl}/testnets-chaindata.json`;
9
- const githubEvmNetworksUrl = `${githubChaindataBaseUrl}/evm-networks.json`;
10
- const githubTokensUrl = `${githubChaindataBaseUrl}/tokens.json`;
11
- const githubChainLogoUrl = chainId => `${githubChaindataBaseUrl}/assets/chains/${chainId}.svg`;
12
- const githubEvmNetworkLogoUrl = networkId => `${githubChaindataBaseUrl}/assets/chains/${networkId}.svg`;
13
- const githubTokenLogoUrl = tokenId => `${githubChaindataBaseUrl}/assets/tokens/${tokenId}.svg`;
14
- const githubUnknownTokenLogoUrl = githubTokenLogoUrl("unknown");
15
-
16
- exports.githubChainLogoUrl = githubChainLogoUrl;
17
- exports.githubChaindataBaseUrl = githubChaindataBaseUrl;
18
- exports.githubChaindataBranch = githubChaindataBranch;
19
- exports.githubChainsUrl = githubChainsUrl;
20
- exports.githubEvmNetworkLogoUrl = githubEvmNetworkLogoUrl;
21
- exports.githubEvmNetworksUrl = githubEvmNetworksUrl;
22
- exports.githubTestnetChainsUrl = githubTestnetChainsUrl;
23
- exports.githubTokenLogoUrl = githubTokenLogoUrl;
24
- exports.githubTokensUrl = githubTokensUrl;
25
- exports.githubUnknownTokenLogoUrl = githubUnknownTokenLogoUrl;
3
+ var net_dist_talismnChaindataProviderNet = require('./net-BE0MfrDv.cjs.prod.js');
4
+ var init_chains_dist_talismnChaindataProviderInitChains = require('../init/chains/dist/talismn-chaindata-provider-init-chains.cjs.prod.js');
5
+ var init_evmNetworks_dist_talismnChaindataProviderInitEvmNetworks = require('../init/evm-networks/dist/talismn-chaindata-provider-init-evm-networks.cjs.prod.js');
6
+ var init_miniMetadatas_dist_talismnChaindataProviderInitMiniMetadatas = require('../init/mini-metadatas/dist/talismn-chaindata-provider-init-mini-metadatas.cjs.prod.js');
7
+ var init_tokens_dist_talismnChaindataProviderInitTokens = require('../init/tokens/dist/talismn-chaindata-provider-init-tokens.cjs.prod.js');
8
+ var rxjs = require('rxjs');
9
+ var dexie = require('dexie');
10
+ var anylogger = require('anylogger');
11
+
12
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
+
14
+ var anylogger__default = /*#__PURE__*/_interopDefault(anylogger);
15
+
16
+ // The init files imported in this module are generated by a script.
17
+ //
18
+ // They are used in two places:
19
+ // 1. As fallbacks for fresh installations who are unable to pull an initial set of data from the upstream chaindata repo.
20
+ // 2. As mock data for tests.
21
+ //
22
+ // They should be periodically updated with the latest state of chaindata.
23
+ // You can update them by running the following command:
24
+ // `pnpm chore:generate-init-data`
25
+
26
+ const fetchInitChains = async () => init_chains_dist_talismnChaindataProviderInitChains.chains;
27
+ const fetchInitEvmNetworks = async () => init_evmNetworks_dist_talismnChaindataProviderInitEvmNetworks.evmNetworks;
28
+ const fetchInitSubstrateTokens = async () => init_tokens_dist_talismnChaindataProviderInitTokens.tokens;
29
+
30
+ // TODO: Move `fetchMiniMetadatas` into `@talismn/balances`,
31
+ // so that we don't have a circular import between `@talismn/balances` and `@talismn/chaindata-provider`.
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
+ const fetchInitMiniMetadatas = async () => init_miniMetadatas_dist_talismnChaindataProviderInitMiniMetadatas.miniMetadatas;
34
+
35
+ /**
36
+ * Util to add our onfinality api key to any public onfinality RPC urls in an array of chains.
37
+ */
38
+ const addCustomChainRpcs = (chains, onfinalityApiKey) => chains.map(chain => {
39
+ // copy chain instead of mutating
40
+ const chainWithCustomRpcs = {
41
+ ...chain
42
+ };
43
+ if (typeof onfinalityApiKey !== "string" || !onfinalityApiKey) return chainWithCustomRpcs;
44
+
45
+ // add rpcs
46
+ chainWithCustomRpcs.rpcs = (chainWithCustomRpcs.rpcs || []
47
+ // convert public onfinality rpc endpoints to private onfinality rpc endpoints
48
+ ).map(rpc => {
49
+ rpc.url = rpc.url.replace(/^wss:\/\/([A-z-]+)\.api\.onfinality\.io\/public-ws\/?$/, `wss://$1.api.onfinality.io/ws?apikey=${onfinalityApiKey}`);
50
+ return rpc;
51
+ })
52
+ // prioritise onfinality rpcs
53
+ .sort((a, b) => {
54
+ if (a.url.includes("api.onfinality.io")) return -1;
55
+ if (b.url.includes("api.onfinality.io")) return 1;
56
+ return 0;
57
+ });
58
+
59
+ // return copy
60
+ return chainWithCustomRpcs;
61
+ });
62
+
63
+ //
64
+ // Utils for parsing chaindata tokens.json
65
+ //
66
+
67
+ const parseTokensResponse = tokens => tokens.filter(isTokenPartial).filter(isToken);
68
+ const isTokenPartial = token => typeof token === "object" && token !== null;
69
+ const isToken = token => {
70
+ const id = token.id;
71
+ if (typeof id !== "string") return false;
72
+ const type = token.type;
73
+ if (typeof type !== "string") return false;
74
+ const isTestnet = token.isTestnet;
75
+ if (typeof isTestnet !== "boolean") return false;
76
+ const symbol = token.symbol;
77
+ if (typeof symbol !== "string") return false;
78
+ const decimals = token.decimals;
79
+ if (typeof decimals !== "number") return false;
80
+ const logo = token.logo;
81
+ if (typeof logo !== "string") return false;
82
+
83
+ // coingeckoId can be undefined
84
+ // const coingeckoId = token.coingeckoId
85
+ // if (typeof coingeckoId !== "string") return false
86
+
87
+ return true;
88
+ };
89
+
90
+ //
91
+ // map from Item[] to another type
92
+ //
93
+
94
+ const itemsToIds = items => items.map(({
95
+ id
96
+ }) => id);
97
+ const itemsToMapById = items => Object.fromEntries(items.map(item => [item.id, item]));
98
+ const itemsToMapByGenesisHash = items => Object.fromEntries(items.flatMap(item => item.genesisHash ? [[item.genesisHash, item]] : []));
99
+
100
+ //
101
+ // filters for Item[] where Item.isCustom == true
102
+ //
103
+
104
+ const customChainsFilter = chains => chains.filter(chain => "isCustom" in chain && chain.isCustom);
105
+ const customEvmNetworksFilter = evmNetworks => evmNetworks.filter(evmNetwork => "isCustom" in evmNetwork && evmNetwork.isCustom);
106
+ const customTokensFilter = tokens => tokens.filter(token => "isCustom" in token && token.isCustom);
107
+
108
+ //
109
+ // Utils to wrap Observable methods with one-shot Promise methods
110
+ //
111
+
112
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
+ const wrapObservableWithGetter = async (errorReason, observable) => {
114
+ return await withErrorReason(errorReason, () => rxjs.firstValueFrom(observable));
115
+ };
116
+ const withErrorReason = async (reason, task) => {
117
+ try {
118
+ return await task();
119
+ } catch (cause) {
120
+ throw new Error(reason, {
121
+ cause
122
+ });
123
+ }
124
+ };
125
+
126
+ //
127
+ // Utils which aren't used by this package, but are helpful for other packages
128
+ //
129
+
130
+ const isCustomChain = chain => {
131
+ return "isCustom" in chain && chain.isCustom === true;
132
+ };
133
+ const isCustomEvmNetwork = evmNetwork => {
134
+ return "isCustom" in evmNetwork && evmNetwork.isCustom === true;
135
+ };
136
+
137
+ var packageJson = {
138
+ name: "@talismn/chaindata-provider",
139
+ version: "0.8.1",
140
+ author: "Talisman",
141
+ homepage: "https://talisman.xyz",
142
+ license: "GPL-3.0-or-later",
143
+ publishConfig: {
144
+ access: "public"
145
+ },
146
+ repository: {
147
+ directory: "packages/chaindata-provider",
148
+ type: "git",
149
+ url: "https://github.com/talismansociety/talisman.git"
150
+ },
151
+ main: "dist/talismn-chaindata-provider.cjs.js",
152
+ module: "dist/talismn-chaindata-provider.esm.js",
153
+ files: [
154
+ "/dist",
155
+ "/init",
156
+ "/net"
157
+ ],
158
+ engines: {
159
+ node: ">=18"
160
+ },
161
+ scripts: {
162
+ test: "jest",
163
+ lint: "eslint src --max-warnings 0",
164
+ "chore:generate-init-data": "ts-node scripts/generateInitData.ts",
165
+ clean: "rm -rf dist init/*/dist net/dist .turbo node_modules"
166
+ },
167
+ dependencies: {
168
+ anylogger: "^1.0.11",
169
+ dexie: "^4.0.9",
170
+ rxjs: "^7.8.1"
171
+ },
172
+ devDependencies: {
173
+ "@talismn/eslint-config": "workspace:*",
174
+ "@talismn/tsconfig": "workspace:*",
175
+ "@types/jest": "^29.5.14",
176
+ eslint: "^8.57.1",
177
+ jest: "^29.7.0",
178
+ prettier: "^3.3.3",
179
+ "ts-jest": "^29.2.5",
180
+ "ts-node": "^10.9.2",
181
+ typescript: "^5.6.3"
182
+ },
183
+ preconstruct: {
184
+ entrypoints: [
185
+ "index.ts",
186
+ "init/chains.ts",
187
+ "init/evm-networks.ts",
188
+ "init/mini-metadatas.ts",
189
+ "init/tokens.ts",
190
+ "net.ts"
191
+ ]
192
+ },
193
+ eslintConfig: {
194
+ root: true,
195
+ "extends": [
196
+ "@talismn/eslint-config/base"
197
+ ]
198
+ }
199
+ };
200
+
201
+ var log = anylogger__default.default(packageJson.name);
202
+
203
+ const subNativeTokenId = chainId => `${chainId}-substrate-native`.toLowerCase().replace(/ /g, "-");
204
+ const evmNativeTokenId = chainId => `${chainId}-evm-native`.toLowerCase().replace(/ /g, "-");
205
+
206
+ // for DB version 2, Wallet version 1.21.0
207
+ const upgradeRemoveSymbolFromNativeTokenId = async tx => {
208
+ const tokensTable = tx.table("tokens");
209
+ const chainsTable = tx.table("chains");
210
+ const evmNetworksTable = tx.table("evmNetworks");
211
+ const nativeTokens = (await tokensTable.toArray()).filter(t => ["substrate-native", "evm-native"].includes(t.type));
212
+ const chains = await chainsTable.toArray();
213
+ const evmNetworks = await evmNetworksTable.toArray();
214
+ const tokenIdsToDelete = [];
215
+ const tokensToUpsert = [];
216
+ const chainsToUpsert = [];
217
+ const evmNetworksToUpsert = [];
218
+ for (const nativeToken of nativeTokens) {
219
+ const networkId = nativeToken.chain?.id || nativeToken.evmNetwork?.id;
220
+ if (!networkId) continue;
221
+ const id = nativeToken.type === "substrate-native" ? subNativeTokenId(networkId) : nativeToken.type === "evm-native" ? evmNativeTokenId(networkId) : undefined;
222
+ if (!id) continue;
223
+ const chain = chains.find(({
224
+ id
225
+ }) => id === networkId);
226
+ const evmNetwork = evmNetworks.find(({
227
+ id
228
+ }) => id === networkId);
229
+ tokenIdsToDelete.push(nativeToken.id);
230
+ tokensToUpsert.push({
231
+ ...nativeToken,
232
+ id
233
+ });
234
+ if (chain) chainsToUpsert.push({
235
+ ...chain,
236
+ nativeToken: {
237
+ id
238
+ }
239
+ });
240
+ if (evmNetwork) evmNetworksToUpsert.push({
241
+ ...evmNetwork,
242
+ nativeToken: {
243
+ id
244
+ }
245
+ });
246
+ }
247
+ await tokensTable.bulkPut(tokensToUpsert);
248
+ await chainsTable.bulkPut(chainsToUpsert);
249
+ await evmNetworksTable.bulkPut(evmNetworksToUpsert);
250
+ await tokensTable.bulkDelete(tokenIdsToDelete);
251
+ };
252
+
253
+ // for DB version 2, Wallet version 1.21.0
254
+ const upgradeAddIsDefaultToExistingChains = async tx => {
255
+ const chainsTable = tx.table("chains");
256
+ const evmNetworksTable = tx.table("evmNetworks");
257
+ const tokensTable = tx.table("tokens");
258
+ await chainsTable.toCollection().modify(chain => {
259
+ if ("isCustom" in chain && chain.isCustom) return;
260
+ chain.isDefault = true;
261
+ });
262
+ await evmNetworksTable.toCollection().modify(evmNetwork => {
263
+ if ("isCustom" in evmNetwork && evmNetwork.isCustom) return;
264
+ evmNetwork.isDefault = true;
265
+ });
266
+ await tokensTable.toCollection().modify(token => {
267
+ if ("isCustom" in token && token.isCustom) return;
268
+ token.isDefault = true;
269
+ });
270
+ };
271
+
272
+ class TalismanChaindataDatabase extends dexie.Dexie {
273
+ constructor() {
274
+ super("TalismanChaindata");
275
+
276
+ // https://dexie.org/docs/Tutorial/Design#database-versioning
277
+ this.version(2).stores({
278
+ // You only need to specify properties that you wish to index.
279
+ // The object store will allow any properties on your stored objects but you can only query them by indexed properties
280
+ // https://dexie.org/docs/API-Reference#declare-database
281
+ //
282
+ // Never index properties containing images, movies or large (huge) strings. Store them in IndexedDB, yes! but just don’t index them!
283
+ // https://dexie.org/docs/Version/Version.stores()#warning
284
+ chains: "id, genesisHash, name",
285
+ evmNetworks: "id, name",
286
+ tokens: "id, type, symbol, coingeckoId, dcentName, contractAddress"
287
+ }).upgrade(upgradeRemoveSymbolFromNativeTokenId).upgrade(upgradeAddIsDefaultToExistingChains);
288
+ }
289
+ }
290
+ new TalismanChaindataDatabase();
291
+
292
+ // removes the need to reference @talismn/balances in this package. should we ?
293
+ const getNativeTokenId = (chainId, moduleType) => `${chainId}-${moduleType}`.toLowerCase().replace(/ /g, "-");
294
+ const minimumHydrationInterval = 300_000; // 300_000ms = 300s = 5 minutes
295
+
296
+ class ChaindataProvider {
297
+ #db;
298
+ #onfinalityApiKey;
299
+ #liveQueries;
300
+ #lastHydratedChainsAt = 0;
301
+ #lastHydratedEvmNetworksAt = 0;
302
+ #lastHydratedTokensAt = 0;
303
+ constructor(options) {
304
+ this.#db = new TalismanChaindataDatabase();
305
+ this.#onfinalityApiKey = options?.onfinalityApiKey ?? undefined;
306
+ this.#liveQueries = [dexie.liveQuery(() => this.#db.chains.toArray()).subscribe(this.chainsObservable), dexie.liveQuery(() => this.#db.evmNetworks.toArray()).subscribe(this.evmNetworksObservable), dexie.liveQuery(() => this.#db.tokens.toArray()).subscribe(this.tokensObservable)];
307
+ }
308
+ destroy() {
309
+ this.#liveQueries.forEach(subscription => subscription.unsubscribe());
310
+ }
311
+ setOnfinalityApiKey(apiKey) {
312
+ this.#onfinalityApiKey = apiKey;
313
+ }
314
+
315
+ //
316
+ // base items
317
+ //
318
+
319
+ chainsObservable = new rxjs.ReplaySubject(1);
320
+ async chains() {
321
+ return await wrapObservableWithGetter("Failed to get chains", this.chainsObservable);
322
+ }
323
+ evmNetworksObservable = new rxjs.ReplaySubject(1);
324
+ async evmNetworks() {
325
+ return await wrapObservableWithGetter("Failed to get evmNetworks", this.evmNetworksObservable);
326
+ }
327
+ tokensObservable = new rxjs.ReplaySubject(1);
328
+ async tokens() {
329
+ return await wrapObservableWithGetter("Failed to get tokens", this.tokensObservable);
330
+ }
331
+
332
+ //
333
+ // custom item observables
334
+ //
335
+
336
+ get customChainsObservable() {
337
+ return this.chainsObservable.pipe(rxjs.map(customChainsFilter));
338
+ }
339
+ async customChains() {
340
+ return await wrapObservableWithGetter("Failed to get custom chains", this.customChainsObservable);
341
+ }
342
+ get customEvmNetworksObservable() {
343
+ return this.evmNetworksObservable.pipe(rxjs.map(customEvmNetworksFilter));
344
+ }
345
+ async customEvmNetworks() {
346
+ return await wrapObservableWithGetter("Failed to get custom evmNetworks", this.customEvmNetworksObservable);
347
+ }
348
+ get customTokensObservable() {
349
+ return this.tokensObservable.pipe(rxjs.map(customTokensFilter));
350
+ }
351
+ async customTokens() {
352
+ return await wrapObservableWithGetter("Failed to get custom tokens", this.customTokensObservable);
353
+ }
354
+
355
+ //
356
+ // item ids
357
+ //
358
+
359
+ get chainIdsObservable() {
360
+ return this.chainsObservable.pipe(rxjs.map(itemsToIds));
361
+ }
362
+ async chainIds() {
363
+ return await wrapObservableWithGetter("Failed to get chainIds", this.chainIdsObservable);
364
+ }
365
+ get evmNetworkIdsObservable() {
366
+ return this.evmNetworksObservable.pipe(rxjs.map(itemsToIds));
367
+ }
368
+ async evmNetworkIds() {
369
+ return await wrapObservableWithGetter("Failed to get evmNetworkIds", this.evmNetworkIdsObservable);
370
+ }
371
+ get tokenIdsObservable() {
372
+ return this.tokensObservable.pipe(rxjs.map(itemsToIds));
373
+ }
374
+ async tokenIds() {
375
+ return await wrapObservableWithGetter("Failed to get tokenIds", this.tokenIdsObservable);
376
+ }
377
+
378
+ //
379
+ // items by id
380
+ //
381
+
382
+ get chainsByIdObservable() {
383
+ return this.chainsObservable.pipe(rxjs.map(itemsToMapById));
384
+ }
385
+ async chainsById() {
386
+ return await wrapObservableWithGetter("Failed to get chains by id", this.chainsByIdObservable);
387
+ }
388
+ get evmNetworksByIdObservable() {
389
+ return this.evmNetworksObservable.pipe(rxjs.map(itemsToMapById));
390
+ }
391
+ async evmNetworksById() {
392
+ return await wrapObservableWithGetter("Failed to get evmNetworks by id", this.evmNetworksByIdObservable);
393
+ }
394
+ get tokensByIdObservable() {
395
+ return this.tokensObservable.pipe(rxjs.map(itemsToMapById));
396
+ }
397
+ async tokensById() {
398
+ return await wrapObservableWithGetter("Failed to get tokens by id", this.tokensByIdObservable);
399
+ }
400
+ async tokensByIdForType(type) {
401
+ const tokensByIdForTypeObservable = this.tokensObservable.pipe(rxjs.map(tokens => tokens.filter(token => token.type === type))).pipe(rxjs.map(itemsToMapById));
402
+ return await wrapObservableWithGetter("Failed to get tokenIds", tokensByIdForTypeObservable);
403
+ }
404
+
405
+ //
406
+ // items by genesisHash
407
+ //
408
+
409
+ get chainsByGenesisHashObservable() {
410
+ return this.chainsObservable.pipe(rxjs.map(itemsToMapByGenesisHash));
411
+ }
412
+ async chainsByGenesisHash() {
413
+ return await wrapObservableWithGetter("Failed to get chains by genesisHash", this.chainsByGenesisHashObservable);
414
+ }
415
+
416
+ //
417
+ // filters for a single item
418
+ //
419
+
420
+ async chainById(chainId) {
421
+ return await withErrorReason("Failed to get chain by id", async () => (await this.chainsById())[chainId] ?? null);
422
+ }
423
+ async chainByGenesisHash(genesisHash) {
424
+ return await withErrorReason("Failed to get chain by genesisHash", async () => (await this.chainsByGenesisHash())[genesisHash] ?? null);
425
+ }
426
+ async evmNetworkById(evmNetworkId) {
427
+ return await withErrorReason("Failed to get evmNetwork by id", async () => (await this.evmNetworksById())[evmNetworkId] ?? null);
428
+ }
429
+ async tokenById(tokenId) {
430
+ return await withErrorReason("Failed to get token by id", async () => (await this.tokensById())[tokenId] ?? null);
431
+ }
432
+
433
+ //
434
+ // mutations / methods with side-effects
435
+ //
436
+
437
+ async addCustomChain(customChain) {
438
+ try {
439
+ if (!("isCustom" in customChain && customChain.isCustom)) return;
440
+ return await this.#db.chains.put(customChain);
441
+ } catch (cause) {
442
+ throw new Error("Failed to add custom chain", {
443
+ cause
444
+ });
445
+ }
446
+ }
447
+ async removeCustomChain(chainId) {
448
+ try {
449
+ return await this.#db.chains
450
+ // only affect custom chains
451
+ .filter(chain => "isCustom" in chain && chain.isCustom)
452
+ // only affect the provided chainId
453
+ .filter(chain => chain.id === chainId)
454
+ // delete the chain (if exists)
455
+ .delete();
456
+ } catch (cause) {
457
+ throw new Error("Failed to remove custom chain", {
458
+ cause
459
+ });
460
+ }
461
+ }
462
+ async setCustomChains(chains) {
463
+ return await this.#db.transaction("rw", this.#db.chains, async () => {
464
+ const keys = await this.#db.chains.filter(chain => "isCustom" in chain && chain.isCustom).primaryKeys();
465
+ await this.#db.chains.bulkDelete(keys);
466
+ await this.#db.chains.bulkPut(chains.filter(chain => chain.isCustom));
467
+ });
468
+ }
469
+ async resetChain(chainId) {
470
+ const builtInChain = await net_dist_talismnChaindataProviderNet.fetchChain(chainId);
471
+ if (!builtInChain) throw new Error("Cannot reset non-built-in chain");
472
+ if (!builtInChain.nativeToken?.id) throw new Error("Failed to lookup native token (no token exists for chain)");
473
+ const builtInNativeToken = await net_dist_talismnChaindataProviderNet.fetchSubstrateToken(builtInChain?.nativeToken?.id);
474
+ if (!isTokenPartial(builtInNativeToken)) throw new Error("Failed to lookup native token");
475
+ if (!isToken(builtInNativeToken)) throw new Error("Failed to lookup native token (isToken test failed)");
476
+ try {
477
+ return await this.#db.transaction("rw", this.#db.chains, this.#db.tokens, async () => {
478
+ // delete chain and its native tokens (ensures cleanup of tokens with legacy ids)
479
+ await this.#db.tokens.filter(token => token.type === "substrate-native" && token.chain?.id === chainId).delete();
480
+ await this.#db.chains.delete(chainId);
481
+
482
+ // reprovision them from subsquid data
483
+ await this.#db.chains.put(builtInChain);
484
+ await this.#db.tokens.put(builtInNativeToken);
485
+ });
486
+ } catch (cause) {
487
+ throw new Error("Failed to reset chain", {
488
+ cause
489
+ });
490
+ }
491
+ }
492
+ async addCustomEvmNetwork(customEvmNetwork) {
493
+ try {
494
+ if (!("isCustom" in customEvmNetwork && customEvmNetwork.isCustom)) return Promise.resolve();
495
+ return await this.#db.evmNetworks.put(customEvmNetwork);
496
+ } catch (cause) {
497
+ throw new Error("Failed to add custom evm network", {
498
+ cause
499
+ });
500
+ }
501
+ }
502
+ async removeCustomEvmNetwork(evmNetworkId) {
503
+ if (await this.getIsBuiltInEvmNetwork(evmNetworkId)) throw new Error("Cannot remove built-in EVM network");
504
+ try {
505
+ return this.#db.transaction("rw", [this.#db.evmNetworks, this.#db.tokens], async () => {
506
+ await this.#db.evmNetworks.delete(evmNetworkId);
507
+ await this.#db.tokens.filter(token => token.evmNetwork?.id === evmNetworkId).delete();
508
+ });
509
+ } catch (cause) {
510
+ throw new Error("Failed to remove custom evm network", {
511
+ cause
512
+ });
513
+ }
514
+ }
515
+ async setCustomEvmNetworks(networks) {
516
+ return await this.#db.transaction("rw", this.#db.evmNetworks, async () => {
517
+ const keys = await this.#db.evmNetworks.filter(network => "isCustom" in network && network.isCustom).primaryKeys();
518
+ await this.#db.evmNetworks.bulkDelete(keys);
519
+ await this.#db.evmNetworks.bulkPut(networks.filter(network => network.isCustom));
520
+ });
521
+ }
522
+ async resetEvmNetwork(evmNetworkId) {
523
+ const builtInEvmNetwork = await net_dist_talismnChaindataProviderNet.fetchEvmNetwork(evmNetworkId);
524
+ if (!builtInEvmNetwork) throw new Error("Cannot reset non-built-in EVM network");
525
+ const nativeModule = builtInEvmNetwork.balancesConfig.find(c => c.moduleType === "evm-native");
526
+ if (!nativeModule?.moduleConfig) throw new Error("Failed to lookup native token (no token exists for network)");
527
+ const {
528
+ symbol,
529
+ decimals,
530
+ coingeckoId,
531
+ logo,
532
+ mirrorOf,
533
+ dcentName,
534
+ noDiscovery
535
+ } = nativeModule.moduleConfig;
536
+ if (!symbol) throw new Error("Missing native token symbol");
537
+ if (!decimals) throw new Error("Missing native token decimals");
538
+ const builtInNativeToken = {
539
+ id: getNativeTokenId(evmNetworkId, "evm-native"),
540
+ type: "evm-native",
541
+ evmNetwork: {
542
+ id: evmNetworkId
543
+ },
544
+ isTestnet: builtInEvmNetwork.isTestnet ?? false,
545
+ isDefault: true,
546
+ symbol,
547
+ decimals,
548
+ coingeckoId,
549
+ logo
550
+ };
551
+ if (mirrorOf) builtInNativeToken.mirrorOf = mirrorOf;
552
+ if (dcentName) builtInNativeToken.dcentName = dcentName;
553
+ if (noDiscovery) builtInNativeToken.noDiscovery = noDiscovery;
554
+ builtInEvmNetwork.nativeToken = {
555
+ id: builtInNativeToken.id
556
+ };
557
+ try {
558
+ return await this.#db.transaction("rw", this.#db.evmNetworks, this.#db.tokens, async () => {
559
+ // delete chain and its native tokens (ensures cleanup of tokens with legacy ids)
560
+ await this.#db.tokens.filter(token => token.type === "evm-native" && token.evmNetwork?.id === evmNetworkId).delete();
561
+ const networkToDelete = await this.#db.evmNetworks.get(evmNetworkId);
562
+ if (networkToDelete?.nativeToken?.id) await this.#db.tokens.delete(networkToDelete.nativeToken.id);
563
+ await this.#db.evmNetworks.delete(evmNetworkId);
564
+
565
+ // reprovision them from chaindata
566
+ await this.#db.evmNetworks.put(builtInEvmNetwork);
567
+ await this.#db.tokens.put(builtInNativeToken);
568
+ });
569
+ } catch (cause) {
570
+ throw new Error("Failed to reset evm network", {
571
+ cause
572
+ });
573
+ }
574
+ }
575
+ async addCustomToken(customToken) {
576
+ try {
577
+ if (!("isCustom" in customToken && customToken.isCustom)) return Promise.resolve();
578
+ return await this.#db.tokens.put(customToken);
579
+ } catch (cause) {
580
+ throw new Error("Failed to add custom token", {
581
+ cause
582
+ });
583
+ }
584
+ }
585
+ async removeCustomToken(tokenId) {
586
+ try {
587
+ return await this.#db.tokens
588
+ // only affect custom tokens
589
+ .filter(token => "isCustom" in token && Boolean(token.isCustom))
590
+ // only affect the provided token
591
+ .filter(token => token.id === tokenId)
592
+ // delete the token (if exists)
593
+ .delete();
594
+ } catch (cause) {
595
+ throw new Error("Failed to remove custom token", {
596
+ cause
597
+ });
598
+ }
599
+ }
600
+ async setCustomTokens(tokens) {
601
+ // TODO custom tokens have to go into localstorage
602
+ return await this.#db.transaction("rw", this.#db.tokens, async () => {
603
+ const keys = await this.#db.tokens.filter(token => "isCustom" in token && Boolean(token.isCustom)).primaryKeys();
604
+ await this.#db.tokens.bulkDelete(keys);
605
+ await this.#db.tokens.bulkPut(tokens.filter(token => "isCustom" in token && token.isCustom));
606
+ });
607
+ }
608
+ async removeToken(tokenId) {
609
+ try {
610
+ return await this.#db.tokens.delete(tokenId);
611
+ } catch (cause) {
612
+ throw new Error("Failed to remove token", {
613
+ cause
614
+ });
615
+ }
616
+ }
617
+
618
+ /**
619
+ * Hydrate the db with the latest chaindata from subsquid.
620
+ *
621
+ * @returns A promise which resolves to true if any db table has been hydrated, or false if all hydration has been skipped.
622
+ */
623
+ async hydrate({
624
+ // chainsArgs, // hydrateChains has no args
625
+ // evmNetworksArgs, // hydrateEvmNetworks has no args
626
+ tokensArgs
627
+ } = {}) {
628
+ return (await Promise.all([
629
+ // call inner hydration methods
630
+ this.hydrateChains(), this.hydrateEvmNetworks(), this.hydrateSubstrateTokens(...(tokensArgs ? tokensArgs : []))])
631
+
632
+ // return true if any hydration occurred
633
+ ).some(Boolean);
634
+ }
635
+
636
+ /**
637
+ * Hydrate the db with the latest chains from subsquid.
638
+ * Hydration is skipped when the last successful hydration was less than minimumHydrationInterval ms ago.
639
+ *
640
+ * @returns A promise which resolves to true if the db has been hydrated, or false if the hydration was skipped.
641
+ */
642
+ async hydrateChains() {
643
+ const now = Date.now();
644
+ if (now - this.#lastHydratedChainsAt < minimumHydrationInterval) return false;
645
+ const dbHasChains = (await this.#db.chains.count()) > 0;
646
+ try {
647
+ try {
648
+ var chains = addCustomChainRpcs(await net_dist_talismnChaindataProviderNet.fetchChains(), this.#onfinalityApiKey); // eslint-disable-line no-var
649
+ if (chains.length <= 0) throw new Error("Ignoring empty chaindata chains response");
650
+ } catch (error) {
651
+ if (dbHasChains) throw error;
652
+
653
+ // On first start-up (db is empty), if we fail to fetch chains then we should
654
+ // initialize the DB with the list of chains inside our init/chains.json file.
655
+ // This data will represent a relatively recent copy of what's in the squid,
656
+ // which will be better for our users than to have nothing at all.
657
+ var chains = addCustomChainRpcs(await fetchInitChains(), this.#onfinalityApiKey); // eslint-disable-line no-var
658
+ }
659
+
660
+ // TODO check if alec is this the right way to set native token
661
+ // note : many chains don't have a native module provisionned from chaindata => breaks edit network screen and probably send funds and tx screens
662
+ for (const chain of chains) {
663
+ const nativeTokenModule = chain.balancesConfig.find(c => c.moduleType === "substrate-native");
664
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
665
+ const symbol = nativeTokenModule?.moduleConfig?.symbol;
666
+ if (!symbol) continue;
667
+ chain.nativeToken = {
668
+ id: getNativeTokenId(chain.id, "substrate-native")
669
+ };
670
+ }
671
+ await this.#db.transaction("rw", this.#db.chains, async () => {
672
+ await this.#db.chains.filter(chain => !("isCustom" in chain && chain.isCustom)).delete();
673
+
674
+ // add all except ones matching custom existing ones (user may customize built-in chains)
675
+ const customChainIds = (await this.#db.chains.toArray()).map(chain => chain.id);
676
+ const newChains = chains.filter(chain => !customChainIds.includes(chain.id));
677
+ await this.#db.chains.bulkPut(newChains);
678
+ });
679
+ this.#lastHydratedChainsAt = now;
680
+ return true;
681
+ } catch (error) {
682
+ log.warn(`Failed to hydrate chains from chaindata`, error);
683
+ return false;
684
+ }
685
+ }
686
+
687
+ /**
688
+ * Hydrate the db with the latest evmNetworks from subsquid.
689
+ * Hydration is skipped when the last successful hydration was less than minimumHydrationInterval ms ago.
690
+ *
691
+ * @returns A promise which resolves to true if the db has been hydrated, or false if the hydration was skipped.
692
+ */
693
+ async hydrateEvmNetworks() {
694
+ const now = Date.now();
695
+ if (now - this.#lastHydratedEvmNetworksAt < minimumHydrationInterval) return false;
696
+ const dbHasEvmNetworks = (await this.#db.evmNetworks.count()) > 0;
697
+ try {
698
+ try {
699
+ var evmNetworks = await net_dist_talismnChaindataProviderNet.fetchEvmNetworks(); // eslint-disable-line no-var
700
+ if (evmNetworks.length <= 0) throw new Error("Ignoring empty chaindata evmNetworks response");
701
+ } catch (error) {
702
+ if (dbHasEvmNetworks) throw error;
703
+
704
+ // On first start-up (db is empty), if we fail to fetch evmNetworks then we should
705
+ // initialize the DB with the list of evmNetworks inside our init/evm-networks.json file.
706
+ // This data will represent a relatively recent copy of what's in the squid,
707
+ // which will be better for our users than to have nothing at all.
708
+ var evmNetworks = await fetchInitEvmNetworks(); // eslint-disable-line no-var
709
+ }
710
+
711
+ // set native token
712
+ for (const evmNetwork of evmNetworks) {
713
+ evmNetwork.nativeToken = {
714
+ id: getNativeTokenId(evmNetwork.id, "evm-native")
715
+ };
716
+ }
717
+ await this.#db.transaction("rw", this.#db.evmNetworks, async () => {
718
+ await this.#db.evmNetworks.filter(network => !("isCustom" in network && network.isCustom)).delete();
719
+
720
+ // remaining entries are custom networks
721
+ const existingCustomNetworks = await this.#db.evmNetworks.toArray();
722
+ const existingCustomNetworksById = Object.fromEntries(existingCustomNetworks.map(network => [network.id, network]));
723
+
724
+ // dont override custom networks, except for the balancesConfig property
725
+ const newNetworks = evmNetworks.map(network => {
726
+ const existing = existingCustomNetworksById[network.id];
727
+ return existing ? Object.assign({}, existing, {
728
+ balancesConfig: network.balancesConfig
729
+ }) : network;
730
+ });
731
+ await this.#db.evmNetworks.bulkPut(newNetworks);
732
+ });
733
+ this.#lastHydratedEvmNetworksAt = now;
734
+ return true;
735
+ } catch (error) {
736
+ log.warn(`Failed to hydrate evmNetworks from chaindata`, error);
737
+ return false;
738
+ }
739
+ }
740
+ async updateChainTokens(chainId, source, newTokens, availableTokenLogoFilenames) {
741
+ // TODO: Test logos and fall back to unknown token logo url
742
+ // (Maybe put the test into each balance module itself)
743
+
744
+ const existingChainTokens = await this.#db.tokens.filter(token => token.chain?.id === chainId && token.type === source).toArray();
745
+ newTokens.forEach(token => {
746
+ if (token.logo) return;
747
+ const symbolLogo = token.symbol.toLowerCase().replace(/ /g, "_");
748
+ if (availableTokenLogoFilenames.includes(`${symbolLogo}.svg`)) {
749
+ return token.logo = net_dist_talismnChaindataProviderNet.githubTokenLogoUrl(symbolLogo);
750
+ }
751
+
752
+ // TODO: Use coingeckoId logo if exists
753
+
754
+ return token.logo = net_dist_talismnChaindataProviderNet.githubUnknownTokenLogoUrl;
755
+ });
756
+ const notCustomTokenIds = existingChainTokens.filter(token => !("isCustom" in token && token.isCustom)).map(token => token.id);
757
+ const customTokenIds = existingChainTokens.filter(token => "isCustom" in token && token.isCustom).map(token => token.id);
758
+ await this.#db.transaction("rw", this.#db.tokens, this.#db.chains, async () => {
759
+ await this.#db.tokens.bulkDelete(notCustomTokenIds);
760
+ await this.#db.tokens.bulkPut(newTokens.filter(token => !customTokenIds.includes(token.id)));
761
+ //if (chain && shouldUpdateChain) await this.#db.chains.put(chain)
762
+ });
763
+ }
764
+ async updateEvmNetworkTokens(newTokens) {
765
+ const existingEvmNetworkTokens = await this.#db.tokens.filter(t => t.type.startsWith("evm-")).toArray();
766
+ const isCustomToken = token => "isCustom" in token && token.isCustom;
767
+
768
+ // don't override custom tokens
769
+ const customTokenIds = new Set();
770
+
771
+ // delete non-custom tokens which aren't in `newTokens`
772
+ const deleteTokenIds = new Set();
773
+ for (const token of existingEvmNetworkTokens) {
774
+ if (isCustomToken(token)) customTokenIds.add(token.id);else deleteTokenIds.add(token.id);
775
+ }
776
+ const tokensToUpdate = newTokens.filter(token => {
777
+ deleteTokenIds.delete(token.id);
778
+ return !customTokenIds.has(token.id);
779
+ });
780
+ this.#db.transaction("rw", this.#db.tokens, async () => {
781
+ // delete all existing non custom tokens
782
+ await this.#db.tokens.bulkDelete([...deleteTokenIds]);
783
+
784
+ // force update on all non custom tokens
785
+ await this.#db.tokens.bulkPut(tokensToUpdate);
786
+ });
787
+ }
788
+
789
+ /**
790
+ * Hydrate the db with the latest tokens from subsquid.
791
+ * Hydration is skipped when the last successful hydration was less than minimumHydrationInterval ms ago.
792
+ *
793
+ * @returns A promise which resolves to true if the db has been hydrated, or false if the hydration was skipped.
794
+ */
795
+ async hydrateSubstrateTokens(chainIdFilter) {
796
+ const now = Date.now();
797
+ if (now - this.#lastHydratedTokensAt < minimumHydrationInterval) return false;
798
+ const dbHasTokens = (await this.#db.tokens.count()) > 0;
799
+ try {
800
+ try {
801
+ var tokens = parseTokensResponse(await net_dist_talismnChaindataProviderNet.fetchSubstrateTokens()); // eslint-disable-line no-var
802
+ if (tokens.length <= 0) throw new Error("Ignoring empty chaindata tokens response");
803
+ } catch (error) {
804
+ if (dbHasTokens) throw error;
805
+
806
+ // On first start-up (db is empty), if we fail to fetch tokens then we should
807
+ // initialize the DB with the list of tokens inside our init/tokens.json file.
808
+ // This data will represent a relatively recent copy of what's in the squid,
809
+ // which will be better for our users than to have nothing at all.
810
+ var tokens = parseTokensResponse(await fetchInitSubstrateTokens()); // eslint-disable-line no-var
811
+ }
812
+ await this.#db.transaction("rw", this.#db.tokens, async () => {
813
+ const deleteChains = chainIdFilter ? new Set(chainIdFilter) : undefined;
814
+ const tokensToDelete = (await this.#db.tokens.toArray()).filter(token => {
815
+ // don't delete custom tokens
816
+ if ("isCustom" in token && token.isCustom) return false;
817
+
818
+ // delete all other tokens if chainIdFilter is not specified
819
+ if (deleteChains === undefined) return true;
820
+
821
+ // delete tokens on chainIdFilter chains is it is specified
822
+ if (token.chain?.id && deleteChains.has(token.chain.id)) return true;
823
+ return false;
824
+ }).map(token => token.id);
825
+ if (tokensToDelete.length) await this.#db.tokens.bulkDelete(tokensToDelete);
826
+
827
+ // add all except ones matching custom existing ones (user may customize built-in tokens)
828
+ const customTokenIds = (await this.#db.tokens.toArray()).map(token => token.id);
829
+ const newTokens = tokens.filter(token => {
830
+ // don't replace custom tokens
831
+ if (customTokenIds.includes(token.id)) return false;
832
+ if (deleteChains === undefined) return true;
833
+ if (!token.chain?.id) return true;
834
+ if (deleteChains.has(token.chain.id)) return true;
835
+ return false;
836
+ });
837
+ await this.#db.tokens.bulkPut(newTokens);
838
+ });
839
+ this.#lastHydratedTokensAt = now;
840
+ return true;
841
+ } catch (error) {
842
+ log.warn(`Failed to hydrate tokens from chaindata`, error);
843
+ return false;
844
+ }
845
+ }
846
+ async getIsBuiltInChain(chainId) {
847
+ const chain = await net_dist_talismnChaindataProviderNet.fetchChain(chainId);
848
+ return !!chain;
849
+ }
850
+ async getIsBuiltInEvmNetwork(evmNetworkId) {
851
+ try {
852
+ const evmNetwork = await net_dist_talismnChaindataProviderNet.fetchEvmNetwork(evmNetworkId);
853
+ return !!evmNetwork;
854
+ } catch (e) {
855
+ return false;
856
+ }
857
+ }
858
+ async transaction(mode, tables, scope) {
859
+ return await this.#db.transaction(mode, tables, scope);
860
+ }
861
+ }
862
+
863
+ exports.availableTokenLogoFilenames = net_dist_talismnChaindataProviderNet.availableTokenLogoFilenames;
864
+ exports.chaindataChainByGenesisHashUrl = net_dist_talismnChaindataProviderNet.chaindataChainByGenesisHashUrl;
865
+ exports.chaindataChainByIdUrl = net_dist_talismnChaindataProviderNet.chaindataChainByIdUrl;
866
+ exports.chaindataChainsAllUrl = net_dist_talismnChaindataProviderNet.chaindataChainsAllUrl;
867
+ exports.chaindataChainsSummaryUrl = net_dist_talismnChaindataProviderNet.chaindataChainsSummaryUrl;
868
+ exports.chaindataEvmNetworkByIdUrl = net_dist_talismnChaindataProviderNet.chaindataEvmNetworkByIdUrl;
869
+ exports.chaindataEvmNetworksAllUrl = net_dist_talismnChaindataProviderNet.chaindataEvmNetworksAllUrl;
870
+ exports.chaindataEvmNetworksSummaryUrl = net_dist_talismnChaindataProviderNet.chaindataEvmNetworksSummaryUrl;
871
+ exports.chaindataMiniMetadatasAllUrl = net_dist_talismnChaindataProviderNet.chaindataMiniMetadatasAllUrl;
872
+ exports.chaindataTokenByIdUrl = net_dist_talismnChaindataProviderNet.chaindataTokenByIdUrl;
873
+ exports.chaindataTokensAllUrl = net_dist_talismnChaindataProviderNet.chaindataTokensAllUrl;
874
+ exports.fetchChain = net_dist_talismnChaindataProviderNet.fetchChain;
875
+ exports.fetchChains = net_dist_talismnChaindataProviderNet.fetchChains;
876
+ exports.fetchEvmNetwork = net_dist_talismnChaindataProviderNet.fetchEvmNetwork;
877
+ exports.fetchEvmNetworks = net_dist_talismnChaindataProviderNet.fetchEvmNetworks;
878
+ exports.fetchMiniMetadatas = net_dist_talismnChaindataProviderNet.fetchMiniMetadatas;
879
+ exports.fetchSubstrateToken = net_dist_talismnChaindataProviderNet.fetchSubstrateToken;
880
+ exports.fetchSubstrateTokens = net_dist_talismnChaindataProviderNet.fetchSubstrateTokens;
881
+ exports.githubApi = net_dist_talismnChaindataProviderNet.githubApi;
882
+ exports.githubCdn = net_dist_talismnChaindataProviderNet.githubCdn;
883
+ exports.githubChainLogoUrl = net_dist_talismnChaindataProviderNet.githubChainLogoUrl;
884
+ exports.githubChaindataBaseUrl = net_dist_talismnChaindataProviderNet.githubChaindataBaseUrl;
885
+ exports.githubChaindataBranch = net_dist_talismnChaindataProviderNet.githubChaindataBranch;
886
+ exports.githubChaindataChainsAssetsDir = net_dist_talismnChaindataProviderNet.githubChaindataChainsAssetsDir;
887
+ exports.githubChaindataDistDir = net_dist_talismnChaindataProviderNet.githubChaindataDistDir;
888
+ exports.githubChaindataDistUrl = net_dist_talismnChaindataProviderNet.githubChaindataDistUrl;
889
+ exports.githubChaindataOrg = net_dist_talismnChaindataProviderNet.githubChaindataOrg;
890
+ exports.githubChaindataRepo = net_dist_talismnChaindataProviderNet.githubChaindataRepo;
891
+ exports.githubChaindataTokensAssetsDir = net_dist_talismnChaindataProviderNet.githubChaindataTokensAssetsDir;
892
+ exports.githubEvmNetworkLogoUrl = net_dist_talismnChaindataProviderNet.githubEvmNetworkLogoUrl;
893
+ exports.githubTokenLogoUrl = net_dist_talismnChaindataProviderNet.githubTokenLogoUrl;
894
+ exports.githubUnknownChainLogoUrl = net_dist_talismnChaindataProviderNet.githubUnknownChainLogoUrl;
895
+ exports.githubUnknownTokenLogoUrl = net_dist_talismnChaindataProviderNet.githubUnknownTokenLogoUrl;
896
+ exports.ChaindataProvider = ChaindataProvider;
897
+ exports.addCustomChainRpcs = addCustomChainRpcs;
898
+ exports.customChainsFilter = customChainsFilter;
899
+ exports.customEvmNetworksFilter = customEvmNetworksFilter;
900
+ exports.customTokensFilter = customTokensFilter;
901
+ exports.fetchInitChains = fetchInitChains;
902
+ exports.fetchInitEvmNetworks = fetchInitEvmNetworks;
903
+ exports.fetchInitMiniMetadatas = fetchInitMiniMetadatas;
904
+ exports.fetchInitSubstrateTokens = fetchInitSubstrateTokens;
905
+ exports.isCustomChain = isCustomChain;
906
+ exports.isCustomEvmNetwork = isCustomEvmNetwork;
907
+ exports.isToken = isToken;
908
+ exports.isTokenPartial = isTokenPartial;
909
+ exports.itemsToIds = itemsToIds;
910
+ exports.itemsToMapByGenesisHash = itemsToMapByGenesisHash;
911
+ exports.itemsToMapById = itemsToMapById;
912
+ exports.parseTokensResponse = parseTokensResponse;
913
+ exports.withErrorReason = withErrorReason;
914
+ exports.wrapObservableWithGetter = wrapObservableWithGetter;