@metamask/assets-controllers 7.0.0 → 9.0.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 +67 -1
- package/dist/AccountTrackerController.d.ts +22 -6
- package/dist/AccountTrackerController.d.ts.map +1 -1
- package/dist/AccountTrackerController.js +32 -7
- package/dist/AccountTrackerController.js.map +1 -1
- package/dist/AssetsContractController.d.ts +6 -3
- package/dist/AssetsContractController.d.ts.map +1 -1
- package/dist/AssetsContractController.js +4 -2
- package/dist/AssetsContractController.js.map +1 -1
- package/dist/NftController.d.ts +62 -13
- package/dist/NftController.d.ts.map +1 -1
- package/dist/NftController.js +101 -4
- package/dist/NftController.js.map +1 -1
- package/dist/NftDetectionController.d.ts +5 -4
- package/dist/NftDetectionController.d.ts.map +1 -1
- package/dist/NftDetectionController.js +5 -6
- package/dist/NftDetectionController.js.map +1 -1
- package/dist/TokenDetectionController.d.ts +2 -1
- package/dist/TokenDetectionController.d.ts.map +1 -1
- package/dist/TokenDetectionController.js.map +1 -1
- package/dist/TokenListController.d.ts +6 -5
- package/dist/TokenListController.d.ts.map +1 -1
- package/dist/TokenListController.js +8 -16
- package/dist/TokenListController.js.map +1 -1
- package/dist/TokenRatesController.d.ts +7 -4
- package/dist/TokenRatesController.d.ts.map +1 -1
- package/dist/TokenRatesController.js +4 -3
- package/dist/TokenRatesController.js.map +1 -1
- package/dist/TokensController.d.ts +26 -71
- package/dist/TokensController.d.ts.map +1 -1
- package/dist/TokensController.js +26 -135
- package/dist/TokensController.js.map +1 -1
- package/dist/assetsUtil.d.ts +10 -8
- package/dist/assetsUtil.d.ts.map +1 -1
- package/dist/assetsUtil.js +13 -14
- package/dist/assetsUtil.js.map +1 -1
- package/dist/token-service.d.ts +3 -2
- package/dist/token-service.d.ts.map +1 -1
- package/dist/token-service.js +2 -2
- package/dist/token-service.js.map +1 -1
- package/package.json +15 -13
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,70 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [9.0.0]
|
|
10
|
+
### Added
|
|
11
|
+
- **BREAKING**: Add required options `getSelectedAddress` and `getMultiAccountBalancesEnabled` to AccountTrackerController constructor and make use of them when refreshing account balances ([#1146](https://github.com/MetaMask/core/pull/1146))
|
|
12
|
+
- Previously, the controller would refresh all account balances, but these options can be used to only refresh the currently selected account
|
|
13
|
+
- **BREAKING:** Add logic to support validating and adding ERC721 and ERC1155 tokens to NFTController state via `wallet_watchAsset` API. ([#1173](https://github.com/MetaMask/core/pull/1173), [#1406](https://github.com/MetaMask/core/pull/1406))
|
|
14
|
+
- The `NFTController` now has a new `watchNFT` method that can be called to send a message to the `ApprovalController` and prompt the user to add an NFT to their wallet state.
|
|
15
|
+
- The `NFTController` now requires an instance of a ControllerMessenger to be passed to its constructor. This is messenger is used to pass the `watchNFT` message to the `ApprovalController`.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Add dependency on `@ethersproject/address` ([#1173](https://github.com/MetaMask/core.git/pull/1173))
|
|
19
|
+
- Replace `eth-rpc-errors` with `@metamask/rpc-errors` ([#1173](https://github.com/MetaMask/core.git/pull/1173))
|
|
20
|
+
|
|
21
|
+
## [8.0.0]
|
|
22
|
+
### Added
|
|
23
|
+
- Support NFT detection on Ethereum Mainnet custom RPC endpoints ([#1360](https://github.com/MetaMask/core/pull/1360))
|
|
24
|
+
- Enable token detection for the Aurora network ([#1327](https://github.com/MetaMask/core/pull/1327))
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- **BREAKING:** Bump to Node 16 ([#1262](https://github.com/MetaMask/core/pull/1262))
|
|
28
|
+
- **BREAKING:** Change format of chain ID in state to 0x-prefixed hex string ([#1367](https://github.com/MetaMask/core/pull/1367))
|
|
29
|
+
- The functions `isTokenDetectionSupportedForNetwork` and `formatIconUrlWithProxy` now expect a chain ID as type `Hex` rather than as a decimal `string`
|
|
30
|
+
- The assets contract controller now expects the `chainId` configuration entry and constructor parameter as type `Hex` rather than decimal `string`
|
|
31
|
+
- The NFT controller now expects the `chainId` configuration entry and constructor parameter as type `Hex` rather than decimal `string`
|
|
32
|
+
- The NFT controller methods `addNft`, `checkAndUpdateSingleNftOwnershipStatus`, `findNftByAddressAndTokenId`, `updateNft`, and `resetNftTransactionStatusByTransactionId` now expect the chain ID to be type `Hex` rather than a decimal `string`
|
|
33
|
+
- The NFT controller state properties `allNftContracts` and `allNfts` are now keyed by address and `Hex` chain ID, rather than by address and decimal `string` chain ID
|
|
34
|
+
- This requires a state migration
|
|
35
|
+
- The NFT detection controller now expects the `chainId` configuration entry and constructor parameter as type `Hex` rather than decimal `string`
|
|
36
|
+
- The token detection controller now expects the `chainId` configuration entry as type `Hex` rather than decimal `string`
|
|
37
|
+
- The token list controller now expects the `chainId` constructor parameter as type `Hex` rather than decimal `string`
|
|
38
|
+
- The token list controller state property `tokensChainsCache` is now keyed by `Hex` chain ID rather than by decimal `string` chain ID.
|
|
39
|
+
- This requires a state migration
|
|
40
|
+
- The token rates controller now expects the `chainId` configuration entry and constructor parameter as type `Hex` rather than decimal `string`
|
|
41
|
+
- The token rates controller `chainId` setter now expects the chain ID as `Hex` rather than as a decimal string
|
|
42
|
+
- The tokens controller now expects the `chainId` configuration entry and constructor parameter as type `Hex` rather than decimal `string`
|
|
43
|
+
- The tokens controller `addDetectedTokens` method now accepts the `chainId` property of the `detectionDetails` parameter to be of type `Hex` rather than decimal `string`.
|
|
44
|
+
- The tokens controller state properties `allTokens`, `allIgnoredTokens`, and `allDetectedTokens` are now keyed by chain ID in `Hex` format rather than decimal `string`.
|
|
45
|
+
- This requires a state migration
|
|
46
|
+
- **BREAKING**: Use approval controller for suggested assets ([#1261](https://github.com/MetaMask/core/pull/1261), [#1268](https://github.com/MetaMask/core/pull/1268))
|
|
47
|
+
- The actions `ApprovalController:acceptRequest` and `ApprovalController:rejectRequest` are no longer required by the token controller messenger.
|
|
48
|
+
- The `suggestedAssets` state has been removed, which means that suggested assets are no longer persisted in state
|
|
49
|
+
- The return type for `watchAsset` has changed. It now returns a Promise that settles after the request has been confirmed or rejected.
|
|
50
|
+
- **BREAKING:** Initialize controllers with the current network ([#1361](https://github.com/MetaMask/core/pull/1361))
|
|
51
|
+
- The following controllers now have a new `chainId` required constructor parameter:
|
|
52
|
+
* `AssetsContractController`
|
|
53
|
+
* `NftController`
|
|
54
|
+
* `NftDetectionController`
|
|
55
|
+
* `TokenRatesController`
|
|
56
|
+
* `TokensController`
|
|
57
|
+
- **BREAKING:** The token list controller messenger requires the `NetworkController:stateChange` event instead of the `NetworkController:providerConfigChange` event ([#1329](https://github.com/MetaMask/core/pull/1329))
|
|
58
|
+
- **BREAKING:** The token list controller `onNetworkStateChange` option now has a more restrictive type ([#1329](https://github.com/MetaMask/core/pull/1329))
|
|
59
|
+
- The event handler parameter type has been changed from `NetworkState | ProviderConfig` to `NetworkState`
|
|
60
|
+
- **BREAKING:** Update the account tracker controller `provider` type ([#1266](https://github.com/MetaMask/core/pull/1266))
|
|
61
|
+
- The `provider` setter and the `provider` config entry now use our `Provider` type from `eth-query` rather than `any`
|
|
62
|
+
- **BREAKING:** Update`@metamask/preferences-controller` dependency and add it as a peer dependency ([#1393](https://github.com/MetaMask/core/pull/1393))
|
|
63
|
+
- **BREAKING:** Update `@metamask/approval-controller` and `@metamask/network-controller` dependencies and peer dependencies
|
|
64
|
+
- Bump @metamask/abi-utils from 1.1.0 to 1.2.0 ([#1287](https://github.com/MetaMask/core/pull/1287))
|
|
65
|
+
- Bump @metamask/utils from 5.0.1 to 5.0.2 ([#1271](https://github.com/MetaMask/core/pull/1271))
|
|
66
|
+
|
|
67
|
+
### Removed
|
|
68
|
+
- **BREAKING:** Remove the `networkType` configuration option from the NFT detection controller, NFT controller, and tokens controller ([#1360](https://github.com/MetaMask/core/pull/1360), [#1359](https://github.com/MetaMask/core/pull/1359))
|
|
69
|
+
- **BREAKING:** Remove the `SuggestedAssetMeta` and `SuggestedAssetMetaBase` types from the token controller ([#1268](https://github.com/MetaMask/core/pull/1268))
|
|
70
|
+
- **BREAKING:** Remove the `acceptWatchAsset` and `rejectWatchAsset` methods from the token controller ([#1268](https://github.com/MetaMask/core/pull/1268))
|
|
71
|
+
- Suggested assets can be accepted or rejected using the approval controller instead
|
|
72
|
+
|
|
9
73
|
## [7.0.0]
|
|
10
74
|
### Changed
|
|
11
75
|
- **BREAKING**: peerDeps: @metamask/network-controller@6.0.0->8.0.0 ([#1196](https://github.com/MetaMask/core/pull/1196))
|
|
@@ -96,7 +160,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
96
160
|
### Changed
|
|
97
161
|
- Use Ethers for AssetsContractController ([#845](https://github.com/MetaMask/core/pull/845))
|
|
98
162
|
|
|
99
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@
|
|
163
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@9.0.0...HEAD
|
|
164
|
+
[9.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@8.0.0...@metamask/assets-controllers@9.0.0
|
|
165
|
+
[8.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@7.0.0...@metamask/assets-controllers@8.0.0
|
|
100
166
|
[7.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@6.0.0...@metamask/assets-controllers@7.0.0
|
|
101
167
|
[6.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@5.1.0...@metamask/assets-controllers@6.0.0
|
|
102
168
|
[5.1.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@5.0.1...@metamask/assets-controllers@5.1.0
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Provider } from 'eth-query';
|
|
1
2
|
import { BaseConfig, BaseController, BaseState } from '@metamask/base-controller';
|
|
2
3
|
import { PreferencesState } from '@metamask/preferences-controller';
|
|
3
4
|
/**
|
|
@@ -17,7 +18,7 @@ export interface AccountInformation {
|
|
|
17
18
|
*/
|
|
18
19
|
export interface AccountTrackerConfig extends BaseConfig {
|
|
19
20
|
interval: number;
|
|
20
|
-
provider?:
|
|
21
|
+
provider?: Provider;
|
|
21
22
|
}
|
|
22
23
|
/**
|
|
23
24
|
* @type AccountTrackerState
|
|
@@ -34,7 +35,7 @@ export interface AccountTrackerState extends BaseState {
|
|
|
34
35
|
* Controller that tracks the network balances for all user accounts.
|
|
35
36
|
*/
|
|
36
37
|
export declare class AccountTrackerController extends BaseController<AccountTrackerConfig, AccountTrackerState> {
|
|
37
|
-
private ethQuery
|
|
38
|
+
private ethQuery?;
|
|
38
39
|
private mutex;
|
|
39
40
|
private handle?;
|
|
40
41
|
private syncAccounts;
|
|
@@ -43,18 +44,24 @@ export declare class AccountTrackerController extends BaseController<AccountTrac
|
|
|
43
44
|
*/
|
|
44
45
|
name: string;
|
|
45
46
|
private getIdentities;
|
|
47
|
+
private getSelectedAddress;
|
|
48
|
+
private getMultiAccountBalancesEnabled;
|
|
46
49
|
/**
|
|
47
50
|
* Creates an AccountTracker instance.
|
|
48
51
|
*
|
|
49
52
|
* @param options - The controller options.
|
|
50
53
|
* @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.
|
|
51
54
|
* @param options.getIdentities - Gets the identities from the Preferences store.
|
|
55
|
+
* @param options.getSelectedAddress - Gets the selected address from the Preferences store.
|
|
56
|
+
* @param options.getMultiAccountBalancesEnabled - Gets the multi account balances enabled flag from the Preferences store.
|
|
52
57
|
* @param config - Initial options used to configure this controller.
|
|
53
58
|
* @param state - Initial state to set on this controller.
|
|
54
59
|
*/
|
|
55
|
-
constructor({ onPreferencesStateChange, getIdentities, }: {
|
|
60
|
+
constructor({ onPreferencesStateChange, getIdentities, getSelectedAddress, getMultiAccountBalancesEnabled, }: {
|
|
56
61
|
onPreferencesStateChange: (listener: (preferencesState: PreferencesState) => void) => void;
|
|
57
62
|
getIdentities: () => PreferencesState['identities'];
|
|
63
|
+
getSelectedAddress: () => PreferencesState['selectedAddress'];
|
|
64
|
+
getMultiAccountBalancesEnabled: () => PreferencesState['isMultiAccountBalancesEnabled'];
|
|
58
65
|
}, config?: Partial<AccountTrackerConfig>, state?: Partial<AccountTrackerState>);
|
|
59
66
|
/**
|
|
60
67
|
* Sets a new provider.
|
|
@@ -63,8 +70,8 @@ export declare class AccountTrackerController extends BaseController<AccountTrac
|
|
|
63
70
|
*
|
|
64
71
|
* @param provider - Provider used to create a new underlying EthQuery instance.
|
|
65
72
|
*/
|
|
66
|
-
set provider(provider:
|
|
67
|
-
get provider():
|
|
73
|
+
set provider(provider: Provider);
|
|
74
|
+
get provider(): Provider;
|
|
68
75
|
/**
|
|
69
76
|
* Starts a new polling interval.
|
|
70
77
|
*
|
|
@@ -72,9 +79,18 @@ export declare class AccountTrackerController extends BaseController<AccountTrac
|
|
|
72
79
|
*/
|
|
73
80
|
poll(interval?: number): Promise<void>;
|
|
74
81
|
/**
|
|
75
|
-
* Refreshes
|
|
82
|
+
* Refreshes the balances of the accounts depending on the multi-account setting.
|
|
83
|
+
* If multi-account is disabled, only updates the selected account balance.
|
|
84
|
+
* If multi-account is enabled, updates balances for all accounts.
|
|
76
85
|
*/
|
|
77
86
|
refresh: () => Promise<void>;
|
|
87
|
+
/**
|
|
88
|
+
* Fetches the balance of a given address from the blockchain.
|
|
89
|
+
*
|
|
90
|
+
* @param address - The account address to fetch the balance for.
|
|
91
|
+
* @returns A promise that resolves to the balance in a hex string format.
|
|
92
|
+
*/
|
|
93
|
+
private getBalanceFromChain;
|
|
78
94
|
/**
|
|
79
95
|
* Sync accounts balances with some additional addresses.
|
|
80
96
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountTrackerController.d.ts","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AccountTrackerController.d.ts","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EACL,UAAU,EACV,cAAc,EACd,SAAS,EACV,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAOpE;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAqB,SAAQ,UAAU;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAoB,SAAQ,SAAS;IACpD,QAAQ,EAAE;QAAE,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,CAAA;KAAE,CAAC;CACrD;AAED;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,cAAc,CAC1D,oBAAoB,EACpB,mBAAmB,CACpB;IACC,OAAO,CAAC,QAAQ,CAAC,CAAW;IAE5B,OAAO,CAAC,KAAK,CAAe;IAE5B,OAAO,CAAC,MAAM,CAAC,CAAgC;IAE/C,OAAO,CAAC,YAAY;IAoBpB;;OAEG;IACM,IAAI,SAA8B;IAE3C,OAAO,CAAC,aAAa,CAAuC;IAE5D,OAAO,CAAC,kBAAkB,CAA4C;IAEtE,OAAO,CAAC,8BAA8B,CAA0D;IAEhG;;;;;;;;;;OAUG;gBAED,EACE,wBAAwB,EACxB,aAAa,EACb,kBAAkB,EAClB,8BAA8B,GAC/B,EAAE;QACD,wBAAwB,EAAE,CACxB,QAAQ,EAAE,CAAC,gBAAgB,EAAE,gBAAgB,KAAK,IAAI,KACnD,IAAI,CAAC;QACV,aAAa,EAAE,MAAM,gBAAgB,CAAC,YAAY,CAAC,CAAC;QACpD,kBAAkB,EAAE,MAAM,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;QAC9D,8BAA8B,EAAE,MAAM,gBAAgB,CAAC,+BAA+B,CAAC,CAAC;KACzF,EACD,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,EACtC,KAAK,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAiBtC;;;;;;OAMG;IACH,IAAI,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAE9B;IAED,IAAI,QAAQ,IAJW,QAAQ,CAM9B;IAED;;;;OAIG;IACG,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5C;;;;OAIG;IACH,OAAO,sBAgBL;IAEF;;;;;OAKG;YACW,mBAAmB;IASjC;;;;;OAKG;IACG,wBAAwB,CAC5B,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAyBhD;AAED,eAAe,wBAAwB,CAAC"}
|
|
@@ -16,6 +16,7 @@ exports.AccountTrackerController = void 0;
|
|
|
16
16
|
const eth_query_1 = __importDefault(require("eth-query"));
|
|
17
17
|
const async_mutex_1 = require("async-mutex");
|
|
18
18
|
const base_controller_1 = require("@metamask/base-controller");
|
|
19
|
+
const utils_1 = require("@metamask/utils");
|
|
19
20
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
20
21
|
/**
|
|
21
22
|
* Controller that tracks the network balances for all user accounts.
|
|
@@ -27,10 +28,12 @@ class AccountTrackerController extends base_controller_1.BaseController {
|
|
|
27
28
|
* @param options - The controller options.
|
|
28
29
|
* @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.
|
|
29
30
|
* @param options.getIdentities - Gets the identities from the Preferences store.
|
|
31
|
+
* @param options.getSelectedAddress - Gets the selected address from the Preferences store.
|
|
32
|
+
* @param options.getMultiAccountBalancesEnabled - Gets the multi account balances enabled flag from the Preferences store.
|
|
30
33
|
* @param config - Initial options used to configure this controller.
|
|
31
34
|
* @param state - Initial state to set on this controller.
|
|
32
35
|
*/
|
|
33
|
-
constructor({ onPreferencesStateChange, getIdentities, }, config, state) {
|
|
36
|
+
constructor({ onPreferencesStateChange, getIdentities, getSelectedAddress, getMultiAccountBalancesEnabled, }, config, state) {
|
|
34
37
|
super(config, state);
|
|
35
38
|
this.mutex = new async_mutex_1.Mutex();
|
|
36
39
|
/**
|
|
@@ -38,16 +41,21 @@ class AccountTrackerController extends base_controller_1.BaseController {
|
|
|
38
41
|
*/
|
|
39
42
|
this.name = 'AccountTrackerController';
|
|
40
43
|
/**
|
|
41
|
-
* Refreshes
|
|
44
|
+
* Refreshes the balances of the accounts depending on the multi-account setting.
|
|
45
|
+
* If multi-account is disabled, only updates the selected account balance.
|
|
46
|
+
* If multi-account is enabled, updates balances for all accounts.
|
|
42
47
|
*/
|
|
43
48
|
this.refresh = () => __awaiter(this, void 0, void 0, function* () {
|
|
44
49
|
this.syncAccounts();
|
|
45
50
|
const accounts = Object.assign({}, this.state.accounts);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
const isMultiAccountBalancesEnabled = this.getMultiAccountBalancesEnabled();
|
|
52
|
+
const accountsToUpdate = isMultiAccountBalancesEnabled
|
|
53
|
+
? Object.keys(accounts)
|
|
54
|
+
: [this.getSelectedAddress()];
|
|
55
|
+
for (const address of accountsToUpdate) {
|
|
56
|
+
accounts[address] = {
|
|
57
|
+
balance: (0, controller_utils_1.BNToHex)(yield this.getBalanceFromChain(address)),
|
|
58
|
+
};
|
|
51
59
|
}
|
|
52
60
|
this.update({ accounts });
|
|
53
61
|
});
|
|
@@ -57,6 +65,8 @@ class AccountTrackerController extends base_controller_1.BaseController {
|
|
|
57
65
|
this.defaultState = { accounts: {} };
|
|
58
66
|
this.initialize();
|
|
59
67
|
this.getIdentities = getIdentities;
|
|
68
|
+
this.getSelectedAddress = getSelectedAddress;
|
|
69
|
+
this.getMultiAccountBalancesEnabled = getMultiAccountBalancesEnabled;
|
|
60
70
|
onPreferencesStateChange(() => {
|
|
61
71
|
this.refresh();
|
|
62
72
|
});
|
|
@@ -106,6 +116,20 @@ class AccountTrackerController extends base_controller_1.BaseController {
|
|
|
106
116
|
}, this.config.interval);
|
|
107
117
|
});
|
|
108
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Fetches the balance of a given address from the blockchain.
|
|
121
|
+
*
|
|
122
|
+
* @param address - The account address to fetch the balance for.
|
|
123
|
+
* @returns A promise that resolves to the balance in a hex string format.
|
|
124
|
+
*/
|
|
125
|
+
getBalanceFromChain(address) {
|
|
126
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
127
|
+
return yield (0, controller_utils_1.safelyExecuteWithTimeout)(() => __awaiter(this, void 0, void 0, function* () {
|
|
128
|
+
(0, utils_1.assert)(this.ethQuery, 'Provider not set.');
|
|
129
|
+
return yield (0, controller_utils_1.query)(this.ethQuery, 'getBalance', [address]);
|
|
130
|
+
}));
|
|
131
|
+
});
|
|
132
|
+
}
|
|
109
133
|
/**
|
|
110
134
|
* Sync accounts balances with some additional addresses.
|
|
111
135
|
*
|
|
@@ -116,6 +140,7 @@ class AccountTrackerController extends base_controller_1.BaseController {
|
|
|
116
140
|
return __awaiter(this, void 0, void 0, function* () {
|
|
117
141
|
return yield Promise.all(addresses.map((address) => {
|
|
118
142
|
return (0, controller_utils_1.safelyExecuteWithTimeout)(() => __awaiter(this, void 0, void 0, function* () {
|
|
143
|
+
(0, utils_1.assert)(this.ethQuery, 'Provider not set.');
|
|
119
144
|
const balance = yield (0, controller_utils_1.query)(this.ethQuery, 'getBalance', [address]);
|
|
120
145
|
return [address, balance];
|
|
121
146
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountTrackerController.js","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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","sourcesContent":["import EthQuery from 'eth-query';\nimport { Mutex } from 'async-mutex';\nimport {\n BaseConfig,\n BaseController,\n BaseState,\n} from '@metamask/base-controller';\nimport { PreferencesState } from '@metamask/preferences-controller';\nimport {\n BNToHex,\n query,\n safelyExecuteWithTimeout,\n} from '@metamask/controller-utils';\n\n/**\n * @type AccountInformation\n *\n * Account information object\n * @property balance - Hex string of an account balancec in wei\n */\nexport interface AccountInformation {\n balance: string;\n}\n\n/**\n * @type AccountTrackerConfig\n *\n * Account tracker controller configuration\n * @property provider - Provider used to create a new underlying EthQuery instance\n */\nexport interface AccountTrackerConfig extends BaseConfig {\n interval: number;\n provider?: any;\n}\n\n/**\n * @type AccountTrackerState\n *\n * Account tracker controller state\n * @property accounts - Map of addresses to account information\n */\nexport interface AccountTrackerState extends BaseState {\n accounts: { [address: string]: AccountInformation };\n}\n\n/**\n * Controller that tracks the network balances for all user accounts.\n */\nexport class AccountTrackerController extends BaseController<\n AccountTrackerConfig,\n AccountTrackerState\n> {\n private ethQuery: any;\n\n private mutex = new Mutex();\n\n private handle?: ReturnType<typeof setTimeout>;\n\n private syncAccounts() {\n const { accounts } = this.state;\n const addresses = Object.keys(this.getIdentities());\n const existing = Object.keys(accounts);\n const newAddresses = addresses.filter(\n (address) => existing.indexOf(address) === -1,\n );\n const oldAddresses = existing.filter(\n (address) => addresses.indexOf(address) === -1,\n );\n newAddresses.forEach((address) => {\n accounts[address] = { balance: '0x0' };\n });\n\n oldAddresses.forEach((address) => {\n delete accounts[address];\n });\n this.update({ accounts: { ...accounts } });\n }\n\n /**\n * Name of this controller used during composition\n */\n override name = 'AccountTrackerController';\n\n private getIdentities: () => PreferencesState['identities'];\n\n /**\n * Creates an AccountTracker instance.\n *\n * @param options - The controller options.\n * @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.\n * @param options.getIdentities - Gets the identities from the Preferences store.\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(\n {\n onPreferencesStateChange,\n getIdentities,\n }: {\n onPreferencesStateChange: (\n listener: (preferencesState: PreferencesState) => void,\n ) => void;\n getIdentities: () => PreferencesState['identities'];\n },\n config?: Partial<AccountTrackerConfig>,\n state?: Partial<AccountTrackerState>,\n ) {\n super(config, state);\n this.defaultConfig = {\n interval: 10000,\n };\n this.defaultState = { accounts: {} };\n this.initialize();\n this.getIdentities = getIdentities;\n onPreferencesStateChange(() => {\n this.refresh();\n });\n this.poll();\n }\n\n /**\n * Sets a new provider.\n *\n * TODO: Replace this wth a method.\n *\n * @param provider - Provider used to create a new underlying EthQuery instance.\n */\n set provider(provider: any) {\n this.ethQuery = new EthQuery(provider);\n }\n\n get provider() {\n throw new Error('Property only used for setting');\n }\n\n /**\n * Starts a new polling interval.\n *\n * @param interval - Polling interval trigger a 'refresh'.\n */\n async poll(interval?: number): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n interval && this.configure({ interval }, false, false);\n this.handle && clearTimeout(this.handle);\n await this.refresh();\n this.handle = setTimeout(() => {\n releaseLock();\n this.poll(this.config.interval);\n }, this.config.interval);\n }\n\n /**\n * Refreshes all accounts in the current keychain.\n */\n refresh = async () => {\n this.syncAccounts();\n const accounts = { ...this.state.accounts };\n for (const address in accounts) {\n await safelyExecuteWithTimeout(async () => {\n const balance = await query(this.ethQuery, 'getBalance', [address]);\n accounts[address] = { balance: BNToHex(balance) };\n });\n }\n this.update({ accounts });\n };\n\n /**\n * Sync accounts balances with some additional addresses.\n *\n * @param addresses - the additional addresses, may be hardware wallet addresses.\n * @returns accounts - addresses with synced balance\n */\n async syncBalanceWithAddresses(\n addresses: string[],\n ): Promise<Record<string, { balance: string }>> {\n return await Promise.all(\n addresses.map((address): Promise<[string, string] | undefined> => {\n return safelyExecuteWithTimeout(async () => {\n const balance = await query(this.ethQuery, 'getBalance', [address]);\n return [address, balance];\n });\n }),\n ).then((value) => {\n return value.reduce((obj, item) => {\n if (!item) {\n return obj;\n }\n\n const [address, balance] = item;\n return {\n ...obj,\n [address]: {\n balance,\n },\n };\n }, {});\n });\n }\n}\n\nexport default AccountTrackerController;\n"]}
|
|
1
|
+
{"version":3,"file":"AccountTrackerController.js","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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","sourcesContent":["import EthQuery from 'eth-query';\nimport type { Provider } from 'eth-query';\nimport { Mutex } from 'async-mutex';\nimport {\n BaseConfig,\n BaseController,\n BaseState,\n} from '@metamask/base-controller';\nimport { assert } from '@metamask/utils';\nimport { PreferencesState } from '@metamask/preferences-controller';\nimport {\n BNToHex,\n query,\n safelyExecuteWithTimeout,\n} from '@metamask/controller-utils';\n\n/**\n * @type AccountInformation\n *\n * Account information object\n * @property balance - Hex string of an account balancec in wei\n */\nexport interface AccountInformation {\n balance: string;\n}\n\n/**\n * @type AccountTrackerConfig\n *\n * Account tracker controller configuration\n * @property provider - Provider used to create a new underlying EthQuery instance\n */\nexport interface AccountTrackerConfig extends BaseConfig {\n interval: number;\n provider?: Provider;\n}\n\n/**\n * @type AccountTrackerState\n *\n * Account tracker controller state\n * @property accounts - Map of addresses to account information\n */\nexport interface AccountTrackerState extends BaseState {\n accounts: { [address: string]: AccountInformation };\n}\n\n/**\n * Controller that tracks the network balances for all user accounts.\n */\nexport class AccountTrackerController extends BaseController<\n AccountTrackerConfig,\n AccountTrackerState\n> {\n private ethQuery?: EthQuery;\n\n private mutex = new Mutex();\n\n private handle?: ReturnType<typeof setTimeout>;\n\n private syncAccounts() {\n const { accounts } = this.state;\n const addresses = Object.keys(this.getIdentities());\n const existing = Object.keys(accounts);\n const newAddresses = addresses.filter(\n (address) => existing.indexOf(address) === -1,\n );\n const oldAddresses = existing.filter(\n (address) => addresses.indexOf(address) === -1,\n );\n newAddresses.forEach((address) => {\n accounts[address] = { balance: '0x0' };\n });\n\n oldAddresses.forEach((address) => {\n delete accounts[address];\n });\n this.update({ accounts: { ...accounts } });\n }\n\n /**\n * Name of this controller used during composition\n */\n override name = 'AccountTrackerController';\n\n private getIdentities: () => PreferencesState['identities'];\n\n private getSelectedAddress: () => PreferencesState['selectedAddress'];\n\n private getMultiAccountBalancesEnabled: () => PreferencesState['isMultiAccountBalancesEnabled'];\n\n /**\n * Creates an AccountTracker instance.\n *\n * @param options - The controller options.\n * @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.\n * @param options.getIdentities - Gets the identities from the Preferences store.\n * @param options.getSelectedAddress - Gets the selected address from the Preferences store.\n * @param options.getMultiAccountBalancesEnabled - Gets the multi account balances enabled flag from the Preferences store.\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(\n {\n onPreferencesStateChange,\n getIdentities,\n getSelectedAddress,\n getMultiAccountBalancesEnabled,\n }: {\n onPreferencesStateChange: (\n listener: (preferencesState: PreferencesState) => void,\n ) => void;\n getIdentities: () => PreferencesState['identities'];\n getSelectedAddress: () => PreferencesState['selectedAddress'];\n getMultiAccountBalancesEnabled: () => PreferencesState['isMultiAccountBalancesEnabled'];\n },\n config?: Partial<AccountTrackerConfig>,\n state?: Partial<AccountTrackerState>,\n ) {\n super(config, state);\n this.defaultConfig = {\n interval: 10000,\n };\n this.defaultState = { accounts: {} };\n this.initialize();\n this.getIdentities = getIdentities;\n this.getSelectedAddress = getSelectedAddress;\n this.getMultiAccountBalancesEnabled = getMultiAccountBalancesEnabled;\n onPreferencesStateChange(() => {\n this.refresh();\n });\n this.poll();\n }\n\n /**\n * Sets a new provider.\n *\n * TODO: Replace this wth a method.\n *\n * @param provider - Provider used to create a new underlying EthQuery instance.\n */\n set provider(provider: Provider) {\n this.ethQuery = new EthQuery(provider);\n }\n\n get provider() {\n throw new Error('Property only used for setting');\n }\n\n /**\n * Starts a new polling interval.\n *\n * @param interval - Polling interval trigger a 'refresh'.\n */\n async poll(interval?: number): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n interval && this.configure({ interval }, false, false);\n this.handle && clearTimeout(this.handle);\n await this.refresh();\n this.handle = setTimeout(() => {\n releaseLock();\n this.poll(this.config.interval);\n }, this.config.interval);\n }\n\n /**\n * Refreshes the balances of the accounts depending on the multi-account setting.\n * If multi-account is disabled, only updates the selected account balance.\n * If multi-account is enabled, updates balances for all accounts.\n */\n refresh = async () => {\n this.syncAccounts();\n const accounts = { ...this.state.accounts };\n const isMultiAccountBalancesEnabled = this.getMultiAccountBalancesEnabled();\n\n const accountsToUpdate = isMultiAccountBalancesEnabled\n ? Object.keys(accounts)\n : [this.getSelectedAddress()];\n\n for (const address of accountsToUpdate) {\n accounts[address] = {\n balance: BNToHex(await this.getBalanceFromChain(address)),\n };\n }\n\n this.update({ accounts });\n };\n\n /**\n * Fetches the balance of a given address from the blockchain.\n *\n * @param address - The account address to fetch the balance for.\n * @returns A promise that resolves to the balance in a hex string format.\n */\n private async getBalanceFromChain(\n address: string,\n ): Promise<string | undefined> {\n return await safelyExecuteWithTimeout(async () => {\n assert(this.ethQuery, 'Provider not set.');\n return await query(this.ethQuery, 'getBalance', [address]);\n });\n }\n\n /**\n * Sync accounts balances with some additional addresses.\n *\n * @param addresses - the additional addresses, may be hardware wallet addresses.\n * @returns accounts - addresses with synced balance\n */\n async syncBalanceWithAddresses(\n addresses: string[],\n ): Promise<Record<string, { balance: string }>> {\n return await Promise.all(\n addresses.map((address): Promise<[string, string] | undefined> => {\n return safelyExecuteWithTimeout(async () => {\n assert(this.ethQuery, 'Provider not set.');\n const balance = await query(this.ethQuery, 'getBalance', [address]);\n return [address, balance];\n });\n }),\n ).then((value) => {\n return value.reduce((obj, item) => {\n if (!item) {\n return obj;\n }\n\n const [address, balance] = item;\n return {\n ...obj,\n [address]: {\n balance,\n },\n };\n }, {});\n });\n }\n}\n\nexport default AccountTrackerController;\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { BN } from 'ethereumjs-util';
|
|
3
|
+
import type { Hex } from '@metamask/utils';
|
|
3
4
|
import { BaseController, BaseConfig, BaseState } from '@metamask/base-controller';
|
|
4
5
|
import type { PreferencesState } from '@metamask/preferences-controller';
|
|
5
6
|
import { NetworkState } from '@metamask/network-controller';
|
|
@@ -9,7 +10,7 @@ import { NetworkState } from '@metamask/network-controller';
|
|
|
9
10
|
* @param chainId - ChainID of network
|
|
10
11
|
* @returns Whether the current network supports token detection
|
|
11
12
|
*/
|
|
12
|
-
export declare const SINGLE_CALL_BALANCES_ADDRESS_BY_CHAINID: Record<
|
|
13
|
+
export declare const SINGLE_CALL_BALANCES_ADDRESS_BY_CHAINID: Record<Hex, string>;
|
|
13
14
|
export declare const MISSING_PROVIDER_ERROR = "AssetsContractController failed to set the provider correctly. A provider must be set for this method to be available";
|
|
14
15
|
/**
|
|
15
16
|
* @type AssetsContractConfig
|
|
@@ -20,7 +21,7 @@ export declare const MISSING_PROVIDER_ERROR = "AssetsContractController failed t
|
|
|
20
21
|
export interface AssetsContractConfig extends BaseConfig {
|
|
21
22
|
provider: any;
|
|
22
23
|
ipfsGateway: string;
|
|
23
|
-
chainId:
|
|
24
|
+
chainId: Hex;
|
|
24
25
|
}
|
|
25
26
|
/**
|
|
26
27
|
* @type BalanceMap
|
|
@@ -47,12 +48,14 @@ export declare class AssetsContractController extends BaseController<AssetsContr
|
|
|
47
48
|
* Creates a AssetsContractController instance.
|
|
48
49
|
*
|
|
49
50
|
* @param options - The controller options.
|
|
51
|
+
* @param options.chainId - The chain ID of the current network.
|
|
50
52
|
* @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.
|
|
51
53
|
* @param options.onNetworkStateChange - Allows subscribing to network controller state changes.
|
|
52
54
|
* @param config - Initial options used to configure this controller.
|
|
53
55
|
* @param state - Initial state to set on this controller.
|
|
54
56
|
*/
|
|
55
|
-
constructor({ onPreferencesStateChange, onNetworkStateChange, }: {
|
|
57
|
+
constructor({ chainId: initialChainId, onPreferencesStateChange, onNetworkStateChange, }: {
|
|
58
|
+
chainId: Hex;
|
|
56
59
|
onPreferencesStateChange: (listener: (preferencesState: PreferencesState) => void) => void;
|
|
57
60
|
onNetworkStateChange: (listener: (networkState: NetworkState) => void) => void;
|
|
58
61
|
}, config?: Partial<AssetsContractConfig>, state?: Partial<BaseState>);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetsContractController.d.ts","sourceRoot":"","sources":["../src/AssetsContractController.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAIrC,OAAO,EACL,cAAc,EACd,UAAU,EACV,SAAS,EACV,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAM5D;;;;;GAKG;AACH,eAAO,MAAM,uCAAuC,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"AssetsContractController.d.ts","sourceRoot":"","sources":["../src/AssetsContractController.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,6 +33,7 @@ exports.SINGLE_CALL_BALANCES_ADDRESS_BY_CHAINID = {
|
|
|
33
33
|
[assetsUtil_1.SupportedTokenDetectionNetworks.bsc]: '0x2352c63A83f9Fd126af8676146721Fa00924d7e4',
|
|
34
34
|
[assetsUtil_1.SupportedTokenDetectionNetworks.polygon]: '0x2352c63A83f9Fd126af8676146721Fa00924d7e4',
|
|
35
35
|
[assetsUtil_1.SupportedTokenDetectionNetworks.avax]: '0xD023D153a0DFa485130ECFdE2FAA7e612EF94818',
|
|
36
|
+
[assetsUtil_1.SupportedTokenDetectionNetworks.aurora]: '0x1286415D333855237f89Df27D388127181448538',
|
|
36
37
|
};
|
|
37
38
|
exports.MISSING_PROVIDER_ERROR = 'AssetsContractController failed to set the provider correctly. A provider must be set for this method to be available';
|
|
38
39
|
/**
|
|
@@ -43,12 +44,13 @@ class AssetsContractController extends base_controller_1.BaseController {
|
|
|
43
44
|
* Creates a AssetsContractController instance.
|
|
44
45
|
*
|
|
45
46
|
* @param options - The controller options.
|
|
47
|
+
* @param options.chainId - The chain ID of the current network.
|
|
46
48
|
* @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.
|
|
47
49
|
* @param options.onNetworkStateChange - Allows subscribing to network controller state changes.
|
|
48
50
|
* @param config - Initial options used to configure this controller.
|
|
49
51
|
* @param state - Initial state to set on this controller.
|
|
50
52
|
*/
|
|
51
|
-
constructor({ onPreferencesStateChange, onNetworkStateChange, }, config, state) {
|
|
53
|
+
constructor({ chainId: initialChainId, onPreferencesStateChange, onNetworkStateChange, }, config, state) {
|
|
52
54
|
super(config, state);
|
|
53
55
|
/**
|
|
54
56
|
* Name of this controller used during composition
|
|
@@ -57,7 +59,7 @@ class AssetsContractController extends base_controller_1.BaseController {
|
|
|
57
59
|
this.defaultConfig = {
|
|
58
60
|
provider: undefined,
|
|
59
61
|
ipfsGateway: controller_utils_1.IPFS_DEFAULT_GATEWAY_URL,
|
|
60
|
-
chainId:
|
|
62
|
+
chainId: initialChainId,
|
|
61
63
|
};
|
|
62
64
|
this.initialize();
|
|
63
65
|
onPreferencesStateChange(({ ipfsGateway }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetsContractController.js","sourceRoot":"","sources":["../src/AssetsContractController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BN } from 'ethereumjs-util';\nimport abiSingleCallBalancesContract from 'single-call-balance-checker-abi';\nimport { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport {\n BaseController,\n BaseConfig,\n BaseState,\n} from '@metamask/base-controller';\nimport type { PreferencesState } from '@metamask/preferences-controller';\nimport { IPFS_DEFAULT_GATEWAY_URL } from '@metamask/controller-utils';\nimport { NetworkState } from '@metamask/network-controller';\nimport { SupportedTokenDetectionNetworks } from './assetsUtil';\nimport { ERC721Standard } from './Standards/NftStandards/ERC721/ERC721Standard';\nimport { ERC1155Standard } from './Standards/NftStandards/ERC1155/ERC1155Standard';\nimport { ERC20Standard } from './Standards/ERC20Standard';\n\n/**\n * Check if token detection is enabled for certain networks\n *\n * @param chainId - ChainID of network\n * @returns Whether the current network supports token detection\n */\nexport const SINGLE_CALL_BALANCES_ADDRESS_BY_CHAINID: Record<string, string> = {\n [SupportedTokenDetectionNetworks.mainnet]:\n '0xb1f8e55c7f64d203c1400b9d8555d050f94adf39',\n [SupportedTokenDetectionNetworks.bsc]:\n '0x2352c63A83f9Fd126af8676146721Fa00924d7e4',\n [SupportedTokenDetectionNetworks.polygon]:\n '0x2352c63A83f9Fd126af8676146721Fa00924d7e4',\n [SupportedTokenDetectionNetworks.avax]:\n '0xD023D153a0DFa485130ECFdE2FAA7e612EF94818',\n};\n\nexport const MISSING_PROVIDER_ERROR =\n 'AssetsContractController failed to set the provider correctly. A provider must be set for this method to be available';\n\n/**\n * @type AssetsContractConfig\n *\n * Assets Contract controller configuration\n * @property provider - Provider used to create a new web3 instance\n */\nexport interface AssetsContractConfig extends BaseConfig {\n provider: any;\n ipfsGateway: string;\n chainId: string;\n}\n\n/**\n * @type BalanceMap\n *\n * Key value object containing the balance for each tokenAddress\n * @property [tokenAddress] - Address of the token\n */\nexport interface BalanceMap {\n [tokenAddress: string]: BN;\n}\n\n/**\n * Controller that interacts with contracts on mainnet through web3\n */\nexport class AssetsContractController extends BaseController<\n AssetsContractConfig,\n BaseState\n> {\n private _provider?: Web3Provider;\n\n private erc721Standard?: ERC721Standard;\n\n private erc1155Standard?: ERC1155Standard;\n\n private erc20Standard?: ERC20Standard;\n\n /**\n * Name of this controller used during composition\n */\n override name = 'AssetsContractController';\n\n /**\n * Creates a AssetsContractController instance.\n *\n * @param options - The controller options.\n * @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.\n * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(\n {\n onPreferencesStateChange,\n onNetworkStateChange,\n }: {\n onPreferencesStateChange: (\n listener: (preferencesState: PreferencesState) => void,\n ) => void;\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n },\n config?: Partial<AssetsContractConfig>,\n state?: Partial<BaseState>,\n ) {\n super(config, state);\n this.defaultConfig = {\n provider: undefined,\n ipfsGateway: IPFS_DEFAULT_GATEWAY_URL,\n chainId: SupportedTokenDetectionNetworks.mainnet,\n };\n this.initialize();\n\n onPreferencesStateChange(({ ipfsGateway }) => {\n this.configure({ ipfsGateway });\n });\n\n onNetworkStateChange((networkState) => {\n if (this.config.chainId !== networkState.providerConfig.chainId) {\n this.configure({\n chainId: networkState.providerConfig.chainId,\n });\n }\n });\n }\n\n /**\n * Sets a new provider.\n *\n * TODO: Replace this wth a method.\n *\n * @property provider - Provider used to create a new underlying Web3 instance\n */\n set provider(provider: any) {\n this._provider = new Web3Provider(provider);\n this.erc721Standard = new ERC721Standard(this._provider);\n this.erc1155Standard = new ERC1155Standard(this._provider);\n this.erc20Standard = new ERC20Standard(this._provider);\n }\n\n get provider() {\n throw new Error('Property only used for setting');\n }\n\n /**\n * Get balance or count for current account on specific asset contract.\n *\n * @param address - Asset ERC20 contract address.\n * @param selectedAddress - Current account public address.\n * @returns Promise resolving to BN object containing balance for current account on specific asset contract.\n */\n async getERC20BalanceOf(\n address: string,\n selectedAddress: string,\n ): Promise<BN> {\n if (!this.erc20Standard) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc20Standard.getBalanceOf(address, selectedAddress);\n }\n\n /**\n * Query for the decimals for a given ERC20 asset.\n *\n * @param address - ERC20 asset contract address.\n * @returns Promise resolving to the 'decimals'.\n */\n async getERC20TokenDecimals(address: string): Promise<string> {\n if (this.erc20Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return await this.erc20Standard.getTokenDecimals(address);\n }\n\n /**\n * Enumerate assets assigned to an owner.\n *\n * @param address - ERC721 asset contract address.\n * @param selectedAddress - Current account public address.\n * @param index - An NFT counter less than `balanceOf(selectedAddress)`.\n * @returns Promise resolving to token identifier for the 'index'th asset assigned to 'selectedAddress'.\n */\n getERC721NftTokenId(\n address: string,\n selectedAddress: string,\n index: number,\n ): Promise<string> {\n if (this.erc721Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc721Standard.getNftTokenId(address, selectedAddress, index);\n }\n\n /**\n * Enumerate assets assigned to an owner.\n *\n * @param tokenAddress - ERC721 asset contract address.\n * @param userAddress - Current account public address.\n * @param tokenId - ERC721 asset identifier.\n * @returns Promise resolving to an object containing the token standard and a set of details which depend on which standard the token supports.\n */\n async getTokenStandardAndDetails(\n tokenAddress: string,\n userAddress?: string,\n tokenId?: string,\n ): Promise<{\n standard: string;\n tokenURI?: string | undefined;\n symbol?: string | undefined;\n name?: string | undefined;\n decimals?: string | undefined;\n balance?: BN | undefined;\n }> {\n if (\n this.erc721Standard === undefined ||\n this.erc1155Standard === undefined ||\n this.erc20Standard === undefined\n ) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n\n const { ipfsGateway } = this.config;\n\n // ERC721\n try {\n return {\n ...(await this.erc721Standard.getDetails(\n tokenAddress,\n ipfsGateway,\n tokenId,\n )),\n };\n } catch {\n // Ignore\n }\n\n // ERC1155\n try {\n return {\n ...(await this.erc1155Standard.getDetails(\n tokenAddress,\n ipfsGateway,\n tokenId,\n )),\n };\n } catch {\n // Ignore\n }\n\n // ERC20\n try {\n return {\n ...(await this.erc20Standard.getDetails(tokenAddress, userAddress)),\n };\n } catch {\n // Ignore\n }\n\n throw new Error('Unable to determine contract standard');\n }\n\n /**\n * Query for tokenURI for a given ERC721 asset.\n *\n * @param address - ERC721 asset contract address.\n * @param tokenId - ERC721 asset identifier.\n * @returns Promise resolving to the 'tokenURI'.\n */\n async getERC721TokenURI(address: string, tokenId: string): Promise<string> {\n if (this.erc721Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc721Standard.getTokenURI(address, tokenId);\n }\n\n /**\n * Query for name for a given asset.\n *\n * @param address - ERC721 or ERC20 asset contract address.\n * @returns Promise resolving to the 'name'.\n */\n async getERC721AssetName(address: string): Promise<string> {\n if (this.erc721Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc721Standard.getAssetName(address);\n }\n\n /**\n * Query for symbol for a given asset.\n *\n * @param address - ERC721 or ERC20 asset contract address.\n * @returns Promise resolving to the 'symbol'.\n */\n async getERC721AssetSymbol(address: string): Promise<string> {\n if (this.erc721Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc721Standard.getAssetSymbol(address);\n }\n\n /**\n * Query for owner for a given ERC721 asset.\n *\n * @param address - ERC721 asset contract address.\n * @param tokenId - ERC721 asset identifier.\n * @returns Promise resolving to the owner address.\n */\n async getERC721OwnerOf(address: string, tokenId: string): Promise<string> {\n if (this.erc721Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc721Standard.getOwnerOf(address, tokenId);\n }\n\n /**\n * Query for tokenURI for a given asset.\n *\n * @param address - ERC1155 asset contract address.\n * @param tokenId - ERC1155 asset identifier.\n * @returns Promise resolving to the 'tokenURI'.\n */\n async getERC1155TokenURI(address: string, tokenId: string): Promise<string> {\n if (this.erc1155Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc1155Standard.getTokenURI(address, tokenId);\n }\n\n /**\n * Query for balance of a given ERC 1155 token.\n *\n * @param userAddress - Wallet public address.\n * @param nftAddress - ERC1155 asset contract address.\n * @param nftId - ERC1155 asset identifier.\n * @returns Promise resolving to the 'balanceOf'.\n */\n async getERC1155BalanceOf(\n userAddress: string,\n nftAddress: string,\n nftId: string,\n ): Promise<BN> {\n if (this.erc1155Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return await this.erc1155Standard.getBalanceOf(\n nftAddress,\n userAddress,\n nftId,\n );\n }\n\n /**\n * Transfer single ERC1155 token.\n *\n * @param nftAddress - ERC1155 token address.\n * @param senderAddress - ERC1155 token sender.\n * @param recipientAddress - ERC1155 token recipient.\n * @param nftId - ERC1155 token id.\n * @param qty - Quantity of tokens to be sent.\n * @returns Promise resolving to the 'transferSingle' ERC1155 token.\n */\n async transferSingleERC1155(\n nftAddress: string,\n senderAddress: string,\n recipientAddress: string,\n nftId: string,\n qty: string,\n ): Promise<void> {\n if (this.erc1155Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return await this.erc1155Standard.transferSingle(\n nftAddress,\n senderAddress,\n recipientAddress,\n nftId,\n qty,\n );\n }\n\n /**\n * Get the token balance for a list of token addresses in a single call. Only non-zero balances\n * are returned.\n *\n * @param selectedAddress - The address to check token balances for.\n * @param tokensToDetect - The token addresses to detect balances for.\n * @returns The list of non-zero token balances.\n */\n async getBalancesInSingleCall(\n selectedAddress: string,\n tokensToDetect: string[],\n ) {\n if (!(this.config.chainId in SINGLE_CALL_BALANCES_ADDRESS_BY_CHAINID)) {\n // Only fetch balance if contract address exists\n return {};\n }\n const contractAddress =\n SINGLE_CALL_BALANCES_ADDRESS_BY_CHAINID[this.config.chainId];\n\n const contract = new Contract(\n contractAddress,\n abiSingleCallBalancesContract,\n this._provider,\n );\n const result = await contract.balances([selectedAddress], tokensToDetect);\n const nonZeroBalances: BalanceMap = {};\n /* istanbul ignore else */\n if (result.length > 0) {\n tokensToDetect.forEach((tokenAddress, index) => {\n const balance: BN = result[index];\n /* istanbul ignore else */\n if (String(balance) !== '0') {\n nonZeroBalances[tokenAddress] = balance;\n }\n });\n }\n return nonZeroBalances;\n }\n}\n\nexport default AssetsContractController;\n"]}
|
|
1
|
+
{"version":3,"file":"AssetsContractController.js","sourceRoot":"","sources":["../src/AssetsContractController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BN } from 'ethereumjs-util';\nimport abiSingleCallBalancesContract from 'single-call-balance-checker-abi';\nimport { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport type { Hex } from '@metamask/utils';\nimport {\n BaseController,\n BaseConfig,\n BaseState,\n} from '@metamask/base-controller';\nimport type { PreferencesState } from '@metamask/preferences-controller';\nimport { IPFS_DEFAULT_GATEWAY_URL } from '@metamask/controller-utils';\nimport { NetworkState } from '@metamask/network-controller';\nimport { SupportedTokenDetectionNetworks } from './assetsUtil';\nimport { ERC721Standard } from './Standards/NftStandards/ERC721/ERC721Standard';\nimport { ERC1155Standard } from './Standards/NftStandards/ERC1155/ERC1155Standard';\nimport { ERC20Standard } from './Standards/ERC20Standard';\n\n/**\n * Check if token detection is enabled for certain networks\n *\n * @param chainId - ChainID of network\n * @returns Whether the current network supports token detection\n */\nexport const SINGLE_CALL_BALANCES_ADDRESS_BY_CHAINID: Record<Hex, string> = {\n [SupportedTokenDetectionNetworks.mainnet]:\n '0xb1f8e55c7f64d203c1400b9d8555d050f94adf39',\n [SupportedTokenDetectionNetworks.bsc]:\n '0x2352c63A83f9Fd126af8676146721Fa00924d7e4',\n [SupportedTokenDetectionNetworks.polygon]:\n '0x2352c63A83f9Fd126af8676146721Fa00924d7e4',\n [SupportedTokenDetectionNetworks.avax]:\n '0xD023D153a0DFa485130ECFdE2FAA7e612EF94818',\n [SupportedTokenDetectionNetworks.aurora]:\n '0x1286415D333855237f89Df27D388127181448538',\n};\n\nexport const MISSING_PROVIDER_ERROR =\n 'AssetsContractController failed to set the provider correctly. A provider must be set for this method to be available';\n\n/**\n * @type AssetsContractConfig\n *\n * Assets Contract controller configuration\n * @property provider - Provider used to create a new web3 instance\n */\nexport interface AssetsContractConfig extends BaseConfig {\n provider: any;\n ipfsGateway: string;\n chainId: Hex;\n}\n\n/**\n * @type BalanceMap\n *\n * Key value object containing the balance for each tokenAddress\n * @property [tokenAddress] - Address of the token\n */\nexport interface BalanceMap {\n [tokenAddress: string]: BN;\n}\n\n/**\n * Controller that interacts with contracts on mainnet through web3\n */\nexport class AssetsContractController extends BaseController<\n AssetsContractConfig,\n BaseState\n> {\n private _provider?: Web3Provider;\n\n private erc721Standard?: ERC721Standard;\n\n private erc1155Standard?: ERC1155Standard;\n\n private erc20Standard?: ERC20Standard;\n\n /**\n * Name of this controller used during composition\n */\n override name = 'AssetsContractController';\n\n /**\n * Creates a AssetsContractController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.\n * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(\n {\n chainId: initialChainId,\n onPreferencesStateChange,\n onNetworkStateChange,\n }: {\n chainId: Hex;\n onPreferencesStateChange: (\n listener: (preferencesState: PreferencesState) => void,\n ) => void;\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n },\n config?: Partial<AssetsContractConfig>,\n state?: Partial<BaseState>,\n ) {\n super(config, state);\n this.defaultConfig = {\n provider: undefined,\n ipfsGateway: IPFS_DEFAULT_GATEWAY_URL,\n chainId: initialChainId,\n };\n this.initialize();\n\n onPreferencesStateChange(({ ipfsGateway }) => {\n this.configure({ ipfsGateway });\n });\n\n onNetworkStateChange((networkState) => {\n if (this.config.chainId !== networkState.providerConfig.chainId) {\n this.configure({\n chainId: networkState.providerConfig.chainId,\n });\n }\n });\n }\n\n /**\n * Sets a new provider.\n *\n * TODO: Replace this wth a method.\n *\n * @property provider - Provider used to create a new underlying Web3 instance\n */\n set provider(provider: any) {\n this._provider = new Web3Provider(provider);\n this.erc721Standard = new ERC721Standard(this._provider);\n this.erc1155Standard = new ERC1155Standard(this._provider);\n this.erc20Standard = new ERC20Standard(this._provider);\n }\n\n get provider() {\n throw new Error('Property only used for setting');\n }\n\n /**\n * Get balance or count for current account on specific asset contract.\n *\n * @param address - Asset ERC20 contract address.\n * @param selectedAddress - Current account public address.\n * @returns Promise resolving to BN object containing balance for current account on specific asset contract.\n */\n async getERC20BalanceOf(\n address: string,\n selectedAddress: string,\n ): Promise<BN> {\n if (!this.erc20Standard) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc20Standard.getBalanceOf(address, selectedAddress);\n }\n\n /**\n * Query for the decimals for a given ERC20 asset.\n *\n * @param address - ERC20 asset contract address.\n * @returns Promise resolving to the 'decimals'.\n */\n async getERC20TokenDecimals(address: string): Promise<string> {\n if (this.erc20Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return await this.erc20Standard.getTokenDecimals(address);\n }\n\n /**\n * Enumerate assets assigned to an owner.\n *\n * @param address - ERC721 asset contract address.\n * @param selectedAddress - Current account public address.\n * @param index - An NFT counter less than `balanceOf(selectedAddress)`.\n * @returns Promise resolving to token identifier for the 'index'th asset assigned to 'selectedAddress'.\n */\n getERC721NftTokenId(\n address: string,\n selectedAddress: string,\n index: number,\n ): Promise<string> {\n if (this.erc721Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc721Standard.getNftTokenId(address, selectedAddress, index);\n }\n\n /**\n * Enumerate assets assigned to an owner.\n *\n * @param tokenAddress - ERC721 asset contract address.\n * @param userAddress - Current account public address.\n * @param tokenId - ERC721 asset identifier.\n * @returns Promise resolving to an object containing the token standard and a set of details which depend on which standard the token supports.\n */\n async getTokenStandardAndDetails(\n tokenAddress: string,\n userAddress?: string,\n tokenId?: string,\n ): Promise<{\n standard: string;\n tokenURI?: string | undefined;\n symbol?: string | undefined;\n name?: string | undefined;\n decimals?: string | undefined;\n balance?: BN | undefined;\n }> {\n if (\n this.erc721Standard === undefined ||\n this.erc1155Standard === undefined ||\n this.erc20Standard === undefined\n ) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n\n const { ipfsGateway } = this.config;\n\n // ERC721\n try {\n return {\n ...(await this.erc721Standard.getDetails(\n tokenAddress,\n ipfsGateway,\n tokenId,\n )),\n };\n } catch {\n // Ignore\n }\n\n // ERC1155\n try {\n return {\n ...(await this.erc1155Standard.getDetails(\n tokenAddress,\n ipfsGateway,\n tokenId,\n )),\n };\n } catch {\n // Ignore\n }\n\n // ERC20\n try {\n return {\n ...(await this.erc20Standard.getDetails(tokenAddress, userAddress)),\n };\n } catch {\n // Ignore\n }\n\n throw new Error('Unable to determine contract standard');\n }\n\n /**\n * Query for tokenURI for a given ERC721 asset.\n *\n * @param address - ERC721 asset contract address.\n * @param tokenId - ERC721 asset identifier.\n * @returns Promise resolving to the 'tokenURI'.\n */\n async getERC721TokenURI(address: string, tokenId: string): Promise<string> {\n if (this.erc721Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc721Standard.getTokenURI(address, tokenId);\n }\n\n /**\n * Query for name for a given asset.\n *\n * @param address - ERC721 or ERC20 asset contract address.\n * @returns Promise resolving to the 'name'.\n */\n async getERC721AssetName(address: string): Promise<string> {\n if (this.erc721Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc721Standard.getAssetName(address);\n }\n\n /**\n * Query for symbol for a given asset.\n *\n * @param address - ERC721 or ERC20 asset contract address.\n * @returns Promise resolving to the 'symbol'.\n */\n async getERC721AssetSymbol(address: string): Promise<string> {\n if (this.erc721Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc721Standard.getAssetSymbol(address);\n }\n\n /**\n * Query for owner for a given ERC721 asset.\n *\n * @param address - ERC721 asset contract address.\n * @param tokenId - ERC721 asset identifier.\n * @returns Promise resolving to the owner address.\n */\n async getERC721OwnerOf(address: string, tokenId: string): Promise<string> {\n if (this.erc721Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc721Standard.getOwnerOf(address, tokenId);\n }\n\n /**\n * Query for tokenURI for a given asset.\n *\n * @param address - ERC1155 asset contract address.\n * @param tokenId - ERC1155 asset identifier.\n * @returns Promise resolving to the 'tokenURI'.\n */\n async getERC1155TokenURI(address: string, tokenId: string): Promise<string> {\n if (this.erc1155Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return this.erc1155Standard.getTokenURI(address, tokenId);\n }\n\n /**\n * Query for balance of a given ERC 1155 token.\n *\n * @param userAddress - Wallet public address.\n * @param nftAddress - ERC1155 asset contract address.\n * @param nftId - ERC1155 asset identifier.\n * @returns Promise resolving to the 'balanceOf'.\n */\n async getERC1155BalanceOf(\n userAddress: string,\n nftAddress: string,\n nftId: string,\n ): Promise<BN> {\n if (this.erc1155Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return await this.erc1155Standard.getBalanceOf(\n nftAddress,\n userAddress,\n nftId,\n );\n }\n\n /**\n * Transfer single ERC1155 token.\n *\n * @param nftAddress - ERC1155 token address.\n * @param senderAddress - ERC1155 token sender.\n * @param recipientAddress - ERC1155 token recipient.\n * @param nftId - ERC1155 token id.\n * @param qty - Quantity of tokens to be sent.\n * @returns Promise resolving to the 'transferSingle' ERC1155 token.\n */\n async transferSingleERC1155(\n nftAddress: string,\n senderAddress: string,\n recipientAddress: string,\n nftId: string,\n qty: string,\n ): Promise<void> {\n if (this.erc1155Standard === undefined) {\n throw new Error(MISSING_PROVIDER_ERROR);\n }\n return await this.erc1155Standard.transferSingle(\n nftAddress,\n senderAddress,\n recipientAddress,\n nftId,\n qty,\n );\n }\n\n /**\n * Get the token balance for a list of token addresses in a single call. Only non-zero balances\n * are returned.\n *\n * @param selectedAddress - The address to check token balances for.\n * @param tokensToDetect - The token addresses to detect balances for.\n * @returns The list of non-zero token balances.\n */\n async getBalancesInSingleCall(\n selectedAddress: string,\n tokensToDetect: string[],\n ) {\n if (!(this.config.chainId in SINGLE_CALL_BALANCES_ADDRESS_BY_CHAINID)) {\n // Only fetch balance if contract address exists\n return {};\n }\n const contractAddress =\n SINGLE_CALL_BALANCES_ADDRESS_BY_CHAINID[this.config.chainId];\n\n const contract = new Contract(\n contractAddress,\n abiSingleCallBalancesContract,\n this._provider,\n );\n const result = await contract.balances([selectedAddress], tokensToDetect);\n const nonZeroBalances: BalanceMap = {};\n /* istanbul ignore else */\n if (result.length > 0) {\n tokensToDetect.forEach((tokenAddress, index) => {\n const balance: BN = result[index];\n /* istanbul ignore else */\n if (String(balance) !== '0') {\n nonZeroBalances[tokenAddress] = balance;\n }\n });\n }\n return nonZeroBalances;\n }\n}\n\nexport default AssetsContractController;\n"]}
|