@keplr-wallet/stores-eth 0.13.32 → 0.13.34
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/build/queries/erc20-balance-batch.d.ts +26 -0
- package/build/queries/erc20-balance-batch.js +262 -0
- package/build/queries/erc20-balance-batch.js.map +1 -0
- package/build/queries/erc20-balance-batch.spec.d.ts +1 -0
- package/build/queries/erc20-balance-batch.spec.js +157 -0
- package/build/queries/erc20-balance-batch.spec.js.map +1 -0
- package/build/queries/erc20-balance.d.ts +21 -6
- package/build/queries/erc20-balance.js +118 -27
- package/build/queries/erc20-balance.js.map +1 -1
- package/build/queries/erc20-balance.spec.d.ts +1 -0
- package/build/queries/erc20-balance.spec.js +90 -0
- package/build/queries/erc20-balance.spec.js.map +1 -0
- package/build/queries/erc20-balances.d.ts +18 -4
- package/build/queries/erc20-balances.js +200 -25
- package/build/queries/erc20-balances.js.map +1 -1
- package/build/queries/erc20-balances.spec.d.ts +1 -0
- package/build/queries/erc20-balances.spec.js +150 -0
- package/build/queries/erc20-balances.spec.js.map +1 -0
- package/build/queries/erc20-batch-parent-store.d.ts +8 -0
- package/build/queries/erc20-batch-parent-store.js +21 -0
- package/build/queries/erc20-batch-parent-store.js.map +1 -0
- package/build/queries/index.d.ts +1 -3
- package/build/queries/index.js +6 -5
- package/build/queries/index.js.map +1 -1
- package/jest.config.js +8 -1
- package/package.json +8 -8
- package/src/queries/erc20-balance-batch.spec.ts +192 -0
- package/src/queries/erc20-balance-batch.ts +273 -0
- package/src/queries/erc20-balance.spec.ts +129 -0
- package/src/queries/erc20-balance.ts +122 -36
- package/src/queries/erc20-balances.spec.ts +194 -0
- package/src/queries/erc20-balances.ts +220 -37
- package/src/queries/erc20-batch-parent-store.ts +28 -0
- package/src/queries/index.ts +8 -15
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { DenomHelper } from "@keplr-wallet/common";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
computed,
|
|
4
|
+
IReactionDisposer,
|
|
5
|
+
makeObservable,
|
|
6
|
+
observable,
|
|
7
|
+
onBecomeObserved,
|
|
8
|
+
onBecomeUnobserved,
|
|
9
|
+
reaction,
|
|
10
|
+
runInAction,
|
|
11
|
+
} from "mobx";
|
|
3
12
|
import { CoinPretty, Int } from "@keplr-wallet/unit";
|
|
4
13
|
import { AppCurrency } from "@keplr-wallet/types";
|
|
5
14
|
import {
|
|
@@ -11,11 +20,13 @@ import {
|
|
|
11
20
|
QueryResponse,
|
|
12
21
|
QuerySharedContext,
|
|
13
22
|
} from "@keplr-wallet/stores";
|
|
23
|
+
import bigInteger from "big-integer";
|
|
14
24
|
import { EthereumAccountBase } from "../account";
|
|
25
|
+
import { ObservableQueryEthereumERC20BalancesBatchParent } from "./erc20-balance-batch";
|
|
26
|
+
import { ERC20BalanceBatchParentStore } from "./erc20-batch-parent-store";
|
|
15
27
|
|
|
16
28
|
const thirdparySupportedChainIdMap: Record<string, string> = {
|
|
17
29
|
"eip155:1": "eth",
|
|
18
|
-
"eip155:10": "opt",
|
|
19
30
|
"eip155:137": "polygon",
|
|
20
31
|
"eip155:8453": "base",
|
|
21
32
|
"eip155:42161": "arb",
|
|
@@ -32,7 +43,7 @@ interface ThirdpartyERC20TokenBalance {
|
|
|
32
43
|
} | null;
|
|
33
44
|
}[];
|
|
34
45
|
// TODO: Support pagination.
|
|
35
|
-
pageKey
|
|
46
|
+
pageKey?: string;
|
|
36
47
|
}
|
|
37
48
|
|
|
38
49
|
export class ObservableQueryThirdpartyERC20BalancesImplParent extends ObservableJsonRPCQuery<ThirdpartyERC20TokenBalance> {
|
|
@@ -42,11 +53,15 @@ export class ObservableQueryThirdpartyERC20BalancesImplParent extends Observable
|
|
|
42
53
|
// so fetch should not be overridden in this parent class.
|
|
43
54
|
public duplicatedFetchResolver?: Promise<void>;
|
|
44
55
|
|
|
56
|
+
@observable.shallow
|
|
57
|
+
protected alchemyContractSet: Set<string> = new Set();
|
|
58
|
+
|
|
45
59
|
constructor(
|
|
46
60
|
sharedContext: QuerySharedContext,
|
|
47
61
|
protected readonly chainId: string,
|
|
48
62
|
protected readonly chainGetter: ChainGetter,
|
|
49
|
-
protected readonly ethereumHexAddress: string
|
|
63
|
+
protected readonly ethereumHexAddress: string,
|
|
64
|
+
public readonly batchParent: ObservableQueryEthereumERC20BalancesBatchParent
|
|
50
65
|
) {
|
|
51
66
|
const tokenAPIURL = `https://evm-${chainId.replace(
|
|
52
67
|
"eip155:",
|
|
@@ -79,22 +94,49 @@ export class ObservableQueryThirdpartyERC20BalancesImplParent extends Observable
|
|
|
79
94
|
super.onReceiveResponse(response);
|
|
80
95
|
|
|
81
96
|
const mcInfo = this.chainGetter.getModularChain(this.chainId);
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
97
|
+
const next = new Set<string>();
|
|
98
|
+
const erc20Denoms: string[] = [];
|
|
99
|
+
for (const tokenBalance of response.data.tokenBalances) {
|
|
100
|
+
if (tokenBalance.tokenBalance != null) {
|
|
101
|
+
next.add(tokenBalance.contractAddress.toLowerCase());
|
|
102
|
+
if (BigInt(tokenBalance.tokenBalance) > 0) {
|
|
103
|
+
erc20Denoms.push(`erc20:${tokenBalance.contractAddress}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
runInAction(() => {
|
|
108
|
+
this.alchemyContractSet = next;
|
|
109
|
+
});
|
|
110
|
+
if (erc20Denoms.length > 0) {
|
|
90
111
|
mcInfo.addUnknownDenoms(...erc20Denoms);
|
|
91
112
|
}
|
|
92
113
|
}
|
|
114
|
+
|
|
115
|
+
hasAlchemyBalance(contract: string): boolean {
|
|
116
|
+
return this.alchemyContractSet.has(contract.toLowerCase());
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
getAlchemyTokenBalance(
|
|
120
|
+
contract: string
|
|
121
|
+
): ThirdpartyERC20TokenBalance["tokenBalances"][number] | undefined {
|
|
122
|
+
return this.response?.data.tokenBalances.find(
|
|
123
|
+
(bal) => bal.contractAddress.toLowerCase() === contract.toLowerCase()
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
resolvesAlchemyBalance(contract: string): boolean {
|
|
128
|
+
return this.getAlchemyTokenBalance(contract)?.tokenBalance != null;
|
|
129
|
+
}
|
|
93
130
|
}
|
|
94
131
|
|
|
95
132
|
export class ObservableQueryThirdpartyERC20BalancesImpl
|
|
96
133
|
implements IObservableQueryBalanceImpl
|
|
97
134
|
{
|
|
135
|
+
protected batchReactionDisposer?: IReactionDisposer;
|
|
136
|
+
@observable
|
|
137
|
+
protected isInBatch = false;
|
|
138
|
+
protected observedProps = 0;
|
|
139
|
+
|
|
98
140
|
constructor(
|
|
99
141
|
protected readonly parent: ObservableQueryThirdpartyERC20BalancesImplParent,
|
|
100
142
|
protected readonly chainId: string,
|
|
@@ -102,26 +144,86 @@ export class ObservableQueryThirdpartyERC20BalancesImpl
|
|
|
102
144
|
protected readonly denomHelper: DenomHelper
|
|
103
145
|
) {
|
|
104
146
|
makeObservable(this);
|
|
147
|
+
|
|
148
|
+
const contract = denomHelper.contractAddress;
|
|
149
|
+
// Readiness gates in hooks-evm can early-return on `response` before
|
|
150
|
+
// reading `balance`, so track observation across both to register the
|
|
151
|
+
// contract with the batch parent when needed.
|
|
152
|
+
const installReaction = () => {
|
|
153
|
+
// Register to batch only when Alchemy can't cover the contract, to avoid
|
|
154
|
+
// duplicate eth_call against tokens Alchemy already returns.
|
|
155
|
+
this.batchReactionDisposer = reaction(
|
|
156
|
+
() => {
|
|
157
|
+
// Alchemy error forces fallback even when a stale `response` still
|
|
158
|
+
// advertises the contract as covered.
|
|
159
|
+
if (parent.error) return "missing";
|
|
160
|
+
if (!parent.response) return "pending";
|
|
161
|
+
if (parent.resolvesAlchemyBalance(contract)) return "covered";
|
|
162
|
+
return "missing";
|
|
163
|
+
},
|
|
164
|
+
(status) => {
|
|
165
|
+
if (status === "missing" && !this.isInBatch) {
|
|
166
|
+
runInAction(() => {
|
|
167
|
+
this.isInBatch = true;
|
|
168
|
+
});
|
|
169
|
+
parent.batchParent.addContract(contract);
|
|
170
|
+
} else if (status !== "missing" && this.isInBatch) {
|
|
171
|
+
runInAction(() => {
|
|
172
|
+
this.isInBatch = false;
|
|
173
|
+
});
|
|
174
|
+
parent.batchParent.removeContract(contract);
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
{ fireImmediately: true }
|
|
178
|
+
);
|
|
179
|
+
};
|
|
180
|
+
const teardownReaction = () => {
|
|
181
|
+
this.batchReactionDisposer?.();
|
|
182
|
+
this.batchReactionDisposer = undefined;
|
|
183
|
+
if (this.isInBatch) {
|
|
184
|
+
runInAction(() => {
|
|
185
|
+
this.isInBatch = false;
|
|
186
|
+
});
|
|
187
|
+
parent.batchParent.removeContract(contract);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
const attach = (prop: "balance" | "response" | "error") => {
|
|
191
|
+
onBecomeObserved(this, prop, () => {
|
|
192
|
+
if (this.observedProps++ === 0) installReaction();
|
|
193
|
+
});
|
|
194
|
+
onBecomeUnobserved(this, prop, () => {
|
|
195
|
+
if (--this.observedProps === 0) teardownReaction();
|
|
196
|
+
});
|
|
197
|
+
};
|
|
198
|
+
attach("balance");
|
|
199
|
+
attach("response");
|
|
200
|
+
attach("error");
|
|
105
201
|
}
|
|
106
202
|
|
|
107
203
|
@computed
|
|
108
204
|
get balance(): CoinPretty {
|
|
109
205
|
const currency = this.currency;
|
|
206
|
+
const contract = this.denomHelper.contractAddress;
|
|
110
207
|
|
|
111
|
-
if (
|
|
112
|
-
|
|
208
|
+
if (this.alchemyResolvesBalance) {
|
|
209
|
+
const tokenBalance = this.parent.getAlchemyTokenBalance(contract);
|
|
210
|
+
if (tokenBalance?.tokenBalance != null) {
|
|
211
|
+
return new CoinPretty(
|
|
212
|
+
currency,
|
|
213
|
+
new Int(BigInt(tokenBalance.tokenBalance))
|
|
214
|
+
);
|
|
215
|
+
}
|
|
113
216
|
}
|
|
114
217
|
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return new CoinPretty(currency, new Int(0)).ready(false);
|
|
218
|
+
const raw = this.parent.batchParent.getBalance(contract);
|
|
219
|
+
if (raw !== undefined) {
|
|
220
|
+
return new CoinPretty(
|
|
221
|
+
currency,
|
|
222
|
+
new Int(bigInteger(raw.replace("0x", ""), 16).toString())
|
|
223
|
+
);
|
|
122
224
|
}
|
|
123
225
|
|
|
124
|
-
return new CoinPretty(currency, new Int(
|
|
226
|
+
return new CoinPretty(currency, new Int(0)).ready(false);
|
|
125
227
|
}
|
|
126
228
|
|
|
127
229
|
@computed
|
|
@@ -133,10 +235,39 @@ export class ObservableQueryThirdpartyERC20BalancesImpl
|
|
|
133
235
|
.forceFindCurrency(denom);
|
|
134
236
|
}
|
|
135
237
|
|
|
238
|
+
// Whether the contract is currently sourced from a healthy Alchemy response.
|
|
239
|
+
// Derived from actual data/error state so imperative callers (which never
|
|
240
|
+
// flip `isInBatch`) observe the same semantics as the reaction path.
|
|
241
|
+
@computed
|
|
242
|
+
protected get alchemyResolvesBalance(): boolean {
|
|
243
|
+
return (
|
|
244
|
+
!this.parent.error &&
|
|
245
|
+
!!this.parent.response &&
|
|
246
|
+
this.parent.resolvesAlchemyBalance(this.denomHelper.contractAddress)
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
@computed
|
|
136
251
|
get error(): Readonly<QueryError<unknown>> | undefined {
|
|
137
|
-
|
|
252
|
+
if (this.alchemyResolvesBalance) return undefined;
|
|
253
|
+
const contract = this.denomHelper.contractAddress;
|
|
254
|
+
const batchErr = this.parent.batchParent.getError(contract);
|
|
255
|
+
if (batchErr) return batchErr;
|
|
256
|
+
// Batch has valid data — suppress any lingering Alchemy error.
|
|
257
|
+
if (this.parent.batchParent.getBalance(contract) !== undefined) {
|
|
258
|
+
return undefined;
|
|
259
|
+
}
|
|
260
|
+
// Still loading — stay quiet until the fallback settles.
|
|
261
|
+
return undefined;
|
|
138
262
|
}
|
|
139
263
|
get isFetching(): boolean {
|
|
264
|
+
if (!this.alchemyResolvesBalance) {
|
|
265
|
+
return (
|
|
266
|
+
this.parent.batchParent.isFetchingContract(
|
|
267
|
+
this.denomHelper.contractAddress
|
|
268
|
+
) || this.parent.isFetching
|
|
269
|
+
);
|
|
270
|
+
}
|
|
140
271
|
return this.parent.isFetching;
|
|
141
272
|
}
|
|
142
273
|
get isObserved(): boolean {
|
|
@@ -145,10 +276,28 @@ export class ObservableQueryThirdpartyERC20BalancesImpl
|
|
|
145
276
|
get isStarted(): boolean {
|
|
146
277
|
return this.parent.isStarted;
|
|
147
278
|
}
|
|
279
|
+
@computed
|
|
148
280
|
get response():
|
|
149
281
|
| Readonly<QueryResponse<ThirdpartyERC20TokenBalance>>
|
|
150
282
|
| undefined {
|
|
151
|
-
|
|
283
|
+
// Readiness must gate on actual data availability, not the
|
|
284
|
+
// observation-driven `isInBatch` flag, so imperative callers also see
|
|
285
|
+
// batch-backed readiness for tokens missing from Alchemy.
|
|
286
|
+
if (this.alchemyResolvesBalance) return this.parent.response;
|
|
287
|
+
const raw = this.parent.batchParent.getBalance(
|
|
288
|
+
this.denomHelper.contractAddress
|
|
289
|
+
);
|
|
290
|
+
if (raw === undefined) return undefined;
|
|
291
|
+
return {
|
|
292
|
+
data: {
|
|
293
|
+
address: "",
|
|
294
|
+
tokenBalances: [],
|
|
295
|
+
pageKey: "",
|
|
296
|
+
},
|
|
297
|
+
staled: false,
|
|
298
|
+
local: false,
|
|
299
|
+
timestamp: 0,
|
|
300
|
+
};
|
|
152
301
|
}
|
|
153
302
|
|
|
154
303
|
fetch(): Promise<void> {
|
|
@@ -175,20 +324,54 @@ export class ObservableQueryThirdpartyERC20BalancesImpl
|
|
|
175
324
|
})();
|
|
176
325
|
}
|
|
177
326
|
);
|
|
178
|
-
return this.parent.duplicatedFetchResolver;
|
|
179
327
|
}
|
|
328
|
+
const alchemyFetch = this.parent.duplicatedFetchResolver;
|
|
329
|
+
return alchemyFetch.then(() => this.awaitFallbackIfMissing());
|
|
330
|
+
}
|
|
180
331
|
|
|
181
|
-
|
|
332
|
+
// After Alchemy resolves, check Alchemy coverage directly (not via the
|
|
333
|
+
// observation-driven reaction) so imperative callers also exercise the
|
|
334
|
+
// batch fallback for tokens missing from Alchemy.
|
|
335
|
+
protected async awaitFallbackIfMissing(): Promise<void> {
|
|
336
|
+
// balanceImplMap doesn't evict on currency removal.
|
|
337
|
+
if (!this.isCurrencyRegistered()) return;
|
|
338
|
+
const contract = this.denomHelper.contractAddress;
|
|
339
|
+
// Mirror the reaction: an Alchemy error forces fallback even when a
|
|
340
|
+
// stale response still advertises the contract as covered.
|
|
341
|
+
const coveredByAlchemy =
|
|
342
|
+
!this.parent.error &&
|
|
343
|
+
!!this.parent.response &&
|
|
344
|
+
this.parent.resolvesAlchemyBalance(contract);
|
|
345
|
+
if (coveredByAlchemy) return;
|
|
346
|
+
this.parent.batchParent.addContract(contract);
|
|
347
|
+
try {
|
|
348
|
+
await this.parent.batchParent.waitFreshResponse();
|
|
349
|
+
} finally {
|
|
350
|
+
this.parent.batchParent.removeContract(contract);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
protected isCurrencyRegistered(): boolean {
|
|
355
|
+
const target = DenomHelper.normalizeDenom(this.denomHelper.denom);
|
|
356
|
+
return this.chainGetter
|
|
357
|
+
.getModularChain(this.chainId)
|
|
358
|
+
.currencies.some(
|
|
359
|
+
(c) => DenomHelper.normalizeDenom(c.coinMinimalDenom) === target
|
|
360
|
+
);
|
|
182
361
|
}
|
|
183
362
|
|
|
184
363
|
async waitFreshResponse(): Promise<
|
|
185
364
|
Readonly<QueryResponse<unknown>> | undefined
|
|
186
365
|
> {
|
|
187
|
-
|
|
366
|
+
await this.parent.waitFreshResponse();
|
|
367
|
+
await this.awaitFallbackIfMissing();
|
|
368
|
+
return this.response;
|
|
188
369
|
}
|
|
189
370
|
|
|
190
371
|
async waitResponse(): Promise<Readonly<QueryResponse<unknown>> | undefined> {
|
|
191
|
-
|
|
372
|
+
await this.parent.waitResponse();
|
|
373
|
+
await this.awaitFallbackIfMissing();
|
|
374
|
+
return this.response;
|
|
192
375
|
}
|
|
193
376
|
}
|
|
194
377
|
|
|
@@ -202,12 +385,7 @@ export class ObservableQueryThirdpartyERC20BalanceRegistry
|
|
|
202
385
|
|
|
203
386
|
constructor(
|
|
204
387
|
protected readonly sharedContext: QuerySharedContext,
|
|
205
|
-
protected readonly
|
|
206
|
-
chainId: string,
|
|
207
|
-
chainGetter: ChainGetter,
|
|
208
|
-
address: string,
|
|
209
|
-
minimalDenom: string
|
|
210
|
-
) => boolean
|
|
388
|
+
protected readonly batchParentStore: ERC20BalanceBatchParentStore
|
|
211
389
|
) {}
|
|
212
390
|
|
|
213
391
|
getBalanceImpl(
|
|
@@ -224,21 +402,26 @@ export class ObservableQueryThirdpartyERC20BalanceRegistry
|
|
|
224
402
|
!Object.keys(thirdparySupportedChainIdMap).includes(chainId) ||
|
|
225
403
|
denomHelper.type !== "erc20" ||
|
|
226
404
|
!isHexAddress ||
|
|
227
|
-
(mcInfo.type !== "evm" && mcInfo.type !== "ethermint")
|
|
228
|
-
this.forceNativeERC20Query(chainId, chainGetter, address, minimalDenom)
|
|
405
|
+
(mcInfo.type !== "evm" && mcInfo.type !== "ethermint")
|
|
229
406
|
) {
|
|
230
407
|
return;
|
|
231
408
|
}
|
|
232
409
|
const key = `${chainId}/${address}`;
|
|
233
410
|
|
|
234
411
|
if (!this.parentMap.has(key)) {
|
|
412
|
+
const batchParent = this.batchParentStore.getOrCreate(
|
|
413
|
+
chainId,
|
|
414
|
+
chainGetter,
|
|
415
|
+
address
|
|
416
|
+
);
|
|
235
417
|
this.parentMap.set(
|
|
236
418
|
key,
|
|
237
419
|
new ObservableQueryThirdpartyERC20BalancesImplParent(
|
|
238
420
|
this.sharedContext,
|
|
239
421
|
chainId,
|
|
240
422
|
chainGetter,
|
|
241
|
-
address
|
|
423
|
+
address,
|
|
424
|
+
batchParent
|
|
242
425
|
)
|
|
243
426
|
);
|
|
244
427
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ChainGetter, QuerySharedContext } from "@keplr-wallet/stores";
|
|
2
|
+
import { ObservableQueryEthereumERC20BalancesBatchParent } from "./erc20-balance-batch";
|
|
3
|
+
|
|
4
|
+
export class ERC20BalanceBatchParentStore {
|
|
5
|
+
protected map: Map<string, ObservableQueryEthereumERC20BalancesBatchParent> =
|
|
6
|
+
new Map();
|
|
7
|
+
|
|
8
|
+
constructor(protected readonly sharedContext: QuerySharedContext) {}
|
|
9
|
+
|
|
10
|
+
getOrCreate(
|
|
11
|
+
chainId: string,
|
|
12
|
+
chainGetter: ChainGetter,
|
|
13
|
+
ethereumHexAddress: string
|
|
14
|
+
): ObservableQueryEthereumERC20BalancesBatchParent {
|
|
15
|
+
const key = `${chainId}/${ethereumHexAddress.toLowerCase()}`;
|
|
16
|
+
let p = this.map.get(key);
|
|
17
|
+
if (!p) {
|
|
18
|
+
p = new ObservableQueryEthereumERC20BalancesBatchParent(
|
|
19
|
+
this.sharedContext,
|
|
20
|
+
chainId,
|
|
21
|
+
chainGetter,
|
|
22
|
+
ethereumHexAddress
|
|
23
|
+
);
|
|
24
|
+
this.map.set(key, p);
|
|
25
|
+
}
|
|
26
|
+
return p;
|
|
27
|
+
}
|
|
28
|
+
}
|
package/src/queries/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { ObservableQueryEthereumMaxPriorityFee } from "./max-priority-fee";
|
|
|
13
13
|
import { ObservableQueryThirdpartyERC20BalanceRegistry } from "./erc20-balances";
|
|
14
14
|
import { ObservableQueryCoingeckoTokenInfo } from "./coingecko-token-info";
|
|
15
15
|
import { ObservableQueryEthereumERC20BalanceRegistry } from "./erc20-balance";
|
|
16
|
+
import { ERC20BalanceBatchParentStore } from "./erc20-batch-parent-store";
|
|
16
17
|
import { ObservableQueryEthereumGasPrice } from "./gas-price";
|
|
17
18
|
import { ObservableQueryEthereumTxReceipt } from "./tx-receipt";
|
|
18
19
|
|
|
@@ -24,12 +25,6 @@ export const EthereumQueries = {
|
|
|
24
25
|
use(options: {
|
|
25
26
|
coingeckoAPIBaseURL: string;
|
|
26
27
|
coingeckoAPIURI: string;
|
|
27
|
-
forceNativeERC20Query: (
|
|
28
|
-
chainId: string,
|
|
29
|
-
chainGetter: ChainGetter,
|
|
30
|
-
address: string,
|
|
31
|
-
minimalDenom: string
|
|
32
|
-
) => boolean;
|
|
33
28
|
}): (
|
|
34
29
|
queriesSetBase: QueriesSetBase,
|
|
35
30
|
sharedContext: QuerySharedContext,
|
|
@@ -46,7 +41,6 @@ export const EthereumQueries = {
|
|
|
46
41
|
ethereum: new EthereumQueriesImpl(
|
|
47
42
|
queriesSetBase,
|
|
48
43
|
sharedContext,
|
|
49
|
-
options.forceNativeERC20Query,
|
|
50
44
|
chainId,
|
|
51
45
|
chainGetter,
|
|
52
46
|
options.coingeckoAPIBaseURL,
|
|
@@ -70,24 +64,23 @@ export class EthereumQueriesImpl {
|
|
|
70
64
|
constructor(
|
|
71
65
|
base: QueriesSetBase,
|
|
72
66
|
sharedContext: QuerySharedContext,
|
|
73
|
-
protected readonly forceNativeERC20Query: (
|
|
74
|
-
chainId: string,
|
|
75
|
-
chainGetter: ChainGetter,
|
|
76
|
-
address: string,
|
|
77
|
-
minimalDenom: string
|
|
78
|
-
) => boolean,
|
|
79
67
|
protected chainId: string,
|
|
80
68
|
protected chainGetter: ChainGetter,
|
|
81
69
|
protected coingeckoAPIBaseURL: string,
|
|
82
70
|
protected coingeckoAPIURI: string
|
|
83
71
|
) {
|
|
72
|
+
const batchParentStore = new ERC20BalanceBatchParentStore(sharedContext);
|
|
73
|
+
|
|
84
74
|
base.queryBalances.addBalanceRegistry(
|
|
85
|
-
new ObservableQueryEthereumERC20BalanceRegistry(
|
|
75
|
+
new ObservableQueryEthereumERC20BalanceRegistry(
|
|
76
|
+
sharedContext,
|
|
77
|
+
batchParentStore
|
|
78
|
+
)
|
|
86
79
|
);
|
|
87
80
|
base.queryBalances.addBalanceRegistry(
|
|
88
81
|
new ObservableQueryThirdpartyERC20BalanceRegistry(
|
|
89
82
|
sharedContext,
|
|
90
|
-
|
|
83
|
+
batchParentStore
|
|
91
84
|
)
|
|
92
85
|
);
|
|
93
86
|
base.queryBalances.addBalanceRegistry(
|