@metamask-previews/assets-controllers 32.0.0-preview-0f65e9e → 33.0.0-preview-b09c2ed
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 +53 -1
- package/dist/AccountTrackerController.js +2 -2
- package/dist/AccountTrackerController.mjs +1 -1
- package/dist/NftDetectionController.js +2 -2
- package/dist/NftDetectionController.mjs +1 -1
- package/dist/TokenRatesController.js +2 -2
- package/dist/TokenRatesController.mjs +1 -1
- package/dist/chunk-2IIQTSLV.mjs +236 -0
- package/dist/chunk-2IIQTSLV.mjs.map +1 -0
- package/dist/chunk-354SINOH.js +236 -0
- package/dist/chunk-354SINOH.js.map +1 -0
- package/dist/{chunk-22BFLX4O.js → chunk-FGAZXVKS.js} +8 -4
- package/dist/chunk-FGAZXVKS.js.map +1 -0
- package/dist/chunk-HVOIBGYN.js +282 -0
- package/dist/chunk-HVOIBGYN.js.map +1 -0
- package/dist/{chunk-VVI7QTCA.mjs → chunk-P3O5CVAH.mjs} +8 -4
- package/dist/chunk-P3O5CVAH.mjs.map +1 -0
- package/dist/chunk-Z7RMCHD4.mjs +282 -0
- package/dist/chunk-Z7RMCHD4.mjs.map +1 -0
- package/dist/index.js +4 -4
- package/dist/index.mjs +3 -3
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/AccountTrackerController.d.ts +50 -66
- package/dist/types/AccountTrackerController.d.ts.map +1 -1
- package/dist/types/NftDetectionController.d.ts +5 -17
- package/dist/types/NftDetectionController.d.ts.map +1 -1
- package/dist/types/TokenRatesController.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +5 -5
- package/dist/chunk-22BFLX4O.js.map +0 -1
- package/dist/chunk-42CNLFP5.js +0 -261
- package/dist/chunk-42CNLFP5.js.map +0 -1
- package/dist/chunk-526TATMH.mjs +0 -254
- package/dist/chunk-526TATMH.mjs.map +0 -1
- package/dist/chunk-AZ6SRJVI.js +0 -254
- package/dist/chunk-AZ6SRJVI.js.map +0 -1
- package/dist/chunk-RQDP72T7.mjs +0 -261
- package/dist/chunk-RQDP72T7.mjs.map +0 -1
- package/dist/chunk-VVI7QTCA.mjs.map +0 -1
package/dist/chunk-42CNLFP5.js
DELETED
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var _chunkZ4BLTVTBjs = require('./chunk-Z4BLTVTB.js');
|
|
7
|
-
|
|
8
|
-
// src/NftDetectionController.ts
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
var _controllerutils = require('@metamask/controller-utils');
|
|
17
|
-
var _pollingcontroller = require('@metamask/polling-controller');
|
|
18
|
-
var DEFAULT_INTERVAL = 18e4;
|
|
19
|
-
var controllerName = "NftDetectionController";
|
|
20
|
-
var BlockaidResultType = /* @__PURE__ */ ((BlockaidResultType2) => {
|
|
21
|
-
BlockaidResultType2["Benign"] = "Benign";
|
|
22
|
-
BlockaidResultType2["Spam"] = "Spam";
|
|
23
|
-
BlockaidResultType2["Warning"] = "Warning";
|
|
24
|
-
BlockaidResultType2["Malicious"] = "Malicious";
|
|
25
|
-
return BlockaidResultType2;
|
|
26
|
-
})(BlockaidResultType || {});
|
|
27
|
-
var _intervalId, _interval, _disabled, _addNft, _getNftState, _stopPolling, stopPolling_fn, _startPolling, startPolling_fn, _onPreferencesControllerStateChange, onPreferencesControllerStateChange_fn, _getOwnerNftApi, getOwnerNftApi_fn, _getOwnerNfts, getOwnerNfts_fn;
|
|
28
|
-
var NftDetectionController = class extends _pollingcontroller.StaticIntervalPollingController {
|
|
29
|
-
/**
|
|
30
|
-
* The controller options
|
|
31
|
-
*
|
|
32
|
-
* @param options - The controller options.
|
|
33
|
-
* @param options.interval - The pooling interval.
|
|
34
|
-
* @param options.messenger - A reference to the messaging system.
|
|
35
|
-
* @param options.disabled - Represents previous value of useNftDetection. Used to detect changes of useNftDetection. Default value is true.
|
|
36
|
-
* @param options.addNft - Add an NFT.
|
|
37
|
-
* @param options.getNftState - Gets the current state of the Assets controller.
|
|
38
|
-
*/
|
|
39
|
-
constructor({
|
|
40
|
-
interval = DEFAULT_INTERVAL,
|
|
41
|
-
messenger,
|
|
42
|
-
disabled = false,
|
|
43
|
-
addNft,
|
|
44
|
-
getNftState
|
|
45
|
-
}) {
|
|
46
|
-
super({
|
|
47
|
-
name: controllerName,
|
|
48
|
-
messenger,
|
|
49
|
-
metadata: {},
|
|
50
|
-
state: {}
|
|
51
|
-
});
|
|
52
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _stopPolling);
|
|
53
|
-
/**
|
|
54
|
-
* Starts a new polling interval.
|
|
55
|
-
*
|
|
56
|
-
*/
|
|
57
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _startPolling);
|
|
58
|
-
/**
|
|
59
|
-
* Handles the state change of the preference controller.
|
|
60
|
-
* @param preferencesState - The new state of the preference controller.
|
|
61
|
-
* @param preferencesState.useNftDetection - Boolean indicating user preference on NFT detection.
|
|
62
|
-
*/
|
|
63
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _onPreferencesControllerStateChange);
|
|
64
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _getOwnerNftApi);
|
|
65
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _getOwnerNfts);
|
|
66
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _intervalId, void 0);
|
|
67
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _interval, void 0);
|
|
68
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _disabled, void 0);
|
|
69
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _addNft, void 0);
|
|
70
|
-
_chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _getNftState, void 0);
|
|
71
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _interval, interval);
|
|
72
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _disabled, disabled);
|
|
73
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _getNftState, getNftState);
|
|
74
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _addNft, addNft);
|
|
75
|
-
this.messagingSystem.subscribe(
|
|
76
|
-
"PreferencesController:stateChange",
|
|
77
|
-
_chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _onPreferencesControllerStateChange, onPreferencesControllerStateChange_fn).bind(this)
|
|
78
|
-
);
|
|
79
|
-
this.setIntervalLength(_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _interval));
|
|
80
|
-
}
|
|
81
|
-
async _executePoll(networkClientId, options) {
|
|
82
|
-
await this.detectNfts({ networkClientId, userAddress: options.address });
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Start polling for the currency rate.
|
|
86
|
-
*/
|
|
87
|
-
async start() {
|
|
88
|
-
if (!this.isMainnet() || _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _disabled)) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
await _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _startPolling, startPolling_fn).call(this);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Stop polling for the currency rate.
|
|
95
|
-
*/
|
|
96
|
-
stop() {
|
|
97
|
-
_chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _stopPolling, stopPolling_fn).call(this);
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Checks whether network is mainnet or not.
|
|
101
|
-
*
|
|
102
|
-
* @returns Whether current network is mainnet.
|
|
103
|
-
*/
|
|
104
|
-
isMainnet() {
|
|
105
|
-
const { selectedNetworkClientId } = this.messagingSystem.call(
|
|
106
|
-
"NetworkController:getState"
|
|
107
|
-
);
|
|
108
|
-
const {
|
|
109
|
-
configuration: { chainId }
|
|
110
|
-
} = this.messagingSystem.call(
|
|
111
|
-
"NetworkController:getNetworkClientById",
|
|
112
|
-
selectedNetworkClientId
|
|
113
|
-
);
|
|
114
|
-
return chainId === _controllerutils.ChainId.mainnet;
|
|
115
|
-
}
|
|
116
|
-
isMainnetByNetworkClientId(networkClient) {
|
|
117
|
-
return networkClient.configuration.chainId === _controllerutils.ChainId.mainnet;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Triggers asset ERC721 token auto detection on mainnet. Any newly detected NFTs are
|
|
121
|
-
* added.
|
|
122
|
-
*
|
|
123
|
-
* @param options - Options bag.
|
|
124
|
-
* @param options.networkClientId - The network client ID to detect NFTs on.
|
|
125
|
-
* @param options.userAddress - The address to detect NFTs for.
|
|
126
|
-
*/
|
|
127
|
-
async detectNfts(options) {
|
|
128
|
-
const userAddress = options?.userAddress ?? this.messagingSystem.call("AccountsController:getSelectedAccount").address;
|
|
129
|
-
if (!this.isMainnet() || _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _disabled)) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
if (!userAddress) {
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
const apiNfts = await _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _getOwnerNfts, getOwnerNfts_fn).call(this, userAddress);
|
|
136
|
-
const addNftPromises = apiNfts.map(async (nft) => {
|
|
137
|
-
const {
|
|
138
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
139
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
140
|
-
tokenId: token_id,
|
|
141
|
-
contract,
|
|
142
|
-
kind,
|
|
143
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
144
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
145
|
-
image: image_url,
|
|
146
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
147
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
148
|
-
imageSmall: image_thumbnail_url,
|
|
149
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
150
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
151
|
-
metadata: { imageOriginal: image_original_url } = {},
|
|
152
|
-
name,
|
|
153
|
-
description,
|
|
154
|
-
attributes,
|
|
155
|
-
topBid,
|
|
156
|
-
lastSale,
|
|
157
|
-
rarityRank,
|
|
158
|
-
rarityScore,
|
|
159
|
-
collection
|
|
160
|
-
} = nft.token;
|
|
161
|
-
let ignored;
|
|
162
|
-
const { ignoredNfts } = _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _getNftState).call(this);
|
|
163
|
-
if (ignoredNfts.length > 0) {
|
|
164
|
-
ignored = ignoredNfts.find((c) => {
|
|
165
|
-
return c.address === _controllerutils.toChecksumHexAddress.call(void 0, contract) && c.tokenId === token_id;
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
if (!ignored) {
|
|
169
|
-
const nftMetadata = Object.assign(
|
|
170
|
-
{},
|
|
171
|
-
{ name },
|
|
172
|
-
description && { description },
|
|
173
|
-
image_url && { image: image_url },
|
|
174
|
-
image_thumbnail_url && { imageThumbnail: image_thumbnail_url },
|
|
175
|
-
image_original_url && { imageOriginal: image_original_url },
|
|
176
|
-
kind && { standard: kind.toUpperCase() },
|
|
177
|
-
lastSale && { lastSale },
|
|
178
|
-
attributes && { attributes },
|
|
179
|
-
topBid && { topBid },
|
|
180
|
-
rarityRank && { rarityRank },
|
|
181
|
-
rarityScore && { rarityScore },
|
|
182
|
-
collection && { collection }
|
|
183
|
-
);
|
|
184
|
-
await _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _addNft).call(this, contract, token_id, {
|
|
185
|
-
nftMetadata,
|
|
186
|
-
userAddress,
|
|
187
|
-
source: "detected" /* Detected */,
|
|
188
|
-
networkClientId: options?.networkClientId
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
await Promise.all(addNftPromises);
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
_intervalId = new WeakMap();
|
|
196
|
-
_interval = new WeakMap();
|
|
197
|
-
_disabled = new WeakMap();
|
|
198
|
-
_addNft = new WeakMap();
|
|
199
|
-
_getNftState = new WeakMap();
|
|
200
|
-
_stopPolling = new WeakSet();
|
|
201
|
-
stopPolling_fn = function() {
|
|
202
|
-
if (_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _intervalId)) {
|
|
203
|
-
clearInterval(_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _intervalId));
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
_startPolling = new WeakSet();
|
|
207
|
-
startPolling_fn = async function() {
|
|
208
|
-
_chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _stopPolling, stopPolling_fn).call(this);
|
|
209
|
-
await this.detectNfts();
|
|
210
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _intervalId, setInterval(async () => {
|
|
211
|
-
await this.detectNfts();
|
|
212
|
-
}, _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _interval)));
|
|
213
|
-
};
|
|
214
|
-
_onPreferencesControllerStateChange = new WeakSet();
|
|
215
|
-
onPreferencesControllerStateChange_fn = function({ useNftDetection }) {
|
|
216
|
-
if (!useNftDetection !== _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _disabled)) {
|
|
217
|
-
_chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _disabled, !useNftDetection);
|
|
218
|
-
if (useNftDetection) {
|
|
219
|
-
this.start();
|
|
220
|
-
} else {
|
|
221
|
-
this.stop();
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
_getOwnerNftApi = new WeakSet();
|
|
226
|
-
getOwnerNftApi_fn = function({ address, next }) {
|
|
227
|
-
return `${_controllerutils.NFT_API_BASE_URL}/users/${address}/tokens?chainIds=1&limit=50&includeTopBid=true&continuation=${next ?? ""}`;
|
|
228
|
-
};
|
|
229
|
-
_getOwnerNfts = new WeakSet();
|
|
230
|
-
getOwnerNfts_fn = async function(address) {
|
|
231
|
-
let nftApiResponse;
|
|
232
|
-
let nfts = [];
|
|
233
|
-
let next;
|
|
234
|
-
do {
|
|
235
|
-
nftApiResponse = await _controllerutils.fetchWithErrorHandling.call(void 0, {
|
|
236
|
-
url: _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _getOwnerNftApi, getOwnerNftApi_fn).call(this, { address, next }),
|
|
237
|
-
options: {
|
|
238
|
-
headers: {
|
|
239
|
-
Version: _controllerutils.NFT_API_VERSION
|
|
240
|
-
}
|
|
241
|
-
},
|
|
242
|
-
timeout: _controllerutils.NFT_API_TIMEOUT
|
|
243
|
-
});
|
|
244
|
-
if (!nftApiResponse) {
|
|
245
|
-
return nfts;
|
|
246
|
-
}
|
|
247
|
-
const newNfts = nftApiResponse.tokens?.filter(
|
|
248
|
-
(elm) => elm.token.isSpam === false && (elm.blockaidResult?.result_type ? elm.blockaidResult?.result_type === "Benign" /* Benign */ : true)
|
|
249
|
-
) ?? [];
|
|
250
|
-
nfts = [...nfts, ...newNfts];
|
|
251
|
-
} while (next = nftApiResponse.continuation);
|
|
252
|
-
return nfts;
|
|
253
|
-
};
|
|
254
|
-
var NftDetectionController_default = NftDetectionController;
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
exports.BlockaidResultType = BlockaidResultType; exports.NftDetectionController = NftDetectionController; exports.NftDetectionController_default = NftDetectionController_default;
|
|
261
|
-
//# sourceMappingURL=chunk-42CNLFP5.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/NftDetectionController.ts"],"names":["BlockaidResultType"],"mappings":"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","sourcesContent":["import type { AccountsControllerGetSelectedAccountAction } from '@metamask/accounts-controller';\nimport type { AddApprovalRequest } from '@metamask/approval-controller';\nimport type { RestrictedControllerMessenger } from '@metamask/base-controller';\nimport {\n fetchWithErrorHandling,\n toChecksumHexAddress,\n ChainId,\n NFT_API_BASE_URL,\n NFT_API_VERSION,\n NFT_API_TIMEOUT,\n} from '@metamask/controller-utils';\nimport type {\n NetworkClientId,\n NetworkClient,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerStateChangeEvent,\n NetworkControllerGetStateAction,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n PreferencesControllerGetStateAction,\n PreferencesControllerStateChangeEvent,\n PreferencesState,\n} from '@metamask/preferences-controller';\n\nimport { Source } from './constants';\nimport {\n type NftController,\n type NftControllerState,\n type NftMetadata,\n} from './NftController';\n\nconst DEFAULT_INTERVAL = 180000;\n\nconst controllerName = 'NftDetectionController';\n\nexport type AllowedActions =\n | AddApprovalRequest\n | NetworkControllerGetStateAction\n | NetworkControllerGetNetworkClientByIdAction\n | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction;\n\nexport type AllowedEvents =\n | PreferencesControllerStateChangeEvent\n | NetworkControllerStateChangeEvent;\n\nexport type NftDetectionControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n AllowedActions,\n AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * @type ApiNft\n *\n * NFT object coming from OpenSea api\n * @property token_id - The NFT identifier\n * @property num_sales - Number of sales\n * @property background_color - The background color to be displayed with the item\n * @property image_url - URI of an image associated with this NFT\n * @property image_preview_url - URI of a smaller image associated with this NFT\n * @property image_thumbnail_url - URI of a thumbnail image associated with this NFT\n * @property image_original_url - URI of the original image associated with this NFT\n * @property animation_url - URI of a animation associated with this NFT\n * @property animation_original_url - URI of the original animation associated with this NFT\n * @property name - The NFT name\n * @property description - The NFT description\n * @property external_link - External link containing additional information\n * @property assetContract - The NFT contract information object\n * @property creator - The NFT owner information object\n * @property lastSale - When this item was last sold\n */\nexport type ApiNft = {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n token_id: string;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n num_sales: number | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n background_color: string | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n image_url: string | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n image_preview_url: string | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n image_thumbnail_url: string | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n image_original_url: string | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n animation_url: string | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n animation_original_url: string | null;\n name: string | null;\n description: string | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n external_link: string | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_contract: ApiNftContract;\n creator: ApiNftCreator;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n last_sale: ApiNftLastSale | null;\n};\n\n/**\n * @type ApiNftContract\n *\n * NFT contract object coming from OpenSea api\n * @property address - Address of the NFT contract\n * @property asset_contract_type - The NFT type, it could be `semi-fungible` or `non-fungible`\n * @property created_date - Creation date\n * @property collection - Object containing the contract name and URI of an image associated\n * @property schema_name - The schema followed by the contract, it could be `ERC721` or `ERC1155`\n * @property symbol - The NFT contract symbol\n * @property total_supply - Total supply of NFTs\n * @property description - The NFT contract description\n * @property external_link - External link containing additional information\n */\nexport type ApiNftContract = {\n address: string;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_contract_type: string | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n created_date: string | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n schema_name: string | null;\n symbol: string | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n total_supply: string | null;\n description: string | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n external_link: string | null;\n collection: {\n name: string | null;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n image_url?: string | null;\n tokenCount?: string | null;\n };\n};\n\n/**\n * @type ApiNftLastSale\n *\n * NFT sale object coming from OpenSea api\n * @property event_timestamp - Object containing a `username`\n * @property total_price - URI of NFT image associated with this owner\n * @property transaction - Object containing transaction_hash and block_hash\n */\nexport type ApiNftLastSale = {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n event_timestamp: string;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n total_price: string;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n transaction: { transaction_hash: string; block_hash: string };\n};\n\n/**\n * @type ApiNftCreator\n *\n * NFT creator object coming from OpenSea api\n * @property user - Object containing a `username`\n * @property profile_img_url - URI of NFT image associated with this owner\n * @property address - The owner address\n */\nexport type ApiNftCreator = {\n user: { username: string };\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n profile_img_url: string;\n address: string;\n};\n\nexport type ReservoirResponse = {\n tokens: TokensResponse[];\n continuation?: string;\n};\n\nexport type TokensResponse = {\n token: TokenResponse;\n ownership: Ownership;\n market?: Market;\n blockaidResult?: Blockaid;\n};\n\nexport enum BlockaidResultType {\n Benign = 'Benign',\n Spam = 'Spam',\n Warning = 'Warning',\n Malicious = 'Malicious',\n}\n\nexport type Blockaid = {\n contract: string;\n chainId: number;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n result_type: BlockaidResultType;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n malicious_score: string;\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n attack_types: object;\n};\n\nexport type Market = {\n floorAsk?: FloorAsk;\n topBid?: TopBid;\n};\n\nexport type TokenResponse = {\n chainId: number;\n contract: string;\n tokenId: string;\n kind?: string;\n name?: string;\n image?: string;\n imageSmall?: string;\n imageLarge?: string;\n metadata?: Metadata;\n description?: string;\n supply?: number;\n remainingSupply?: number;\n rarityScore?: number;\n rarity?: number;\n rarityRank?: number;\n media?: string;\n isFlagged?: boolean;\n isSpam?: boolean;\n isNsfw?: boolean;\n metadataDisabled?: boolean;\n lastFlagUpdate?: string;\n lastFlagChange?: string;\n collection?: Collection;\n lastSale?: LastSale;\n topBid?: TopBid;\n lastAppraisalValue?: number;\n attributes?: Attributes[];\n};\n\nexport type TopBid = {\n id?: string;\n price?: Price;\n source?: {\n id?: string;\n domain?: string;\n name?: string;\n icon?: string;\n url?: string;\n };\n};\n\nexport type LastSale = {\n saleId?: string;\n token?: {\n contract?: string;\n tokenId?: string;\n name?: string;\n image?: string;\n collection?: {\n id?: string;\n name?: string;\n };\n };\n orderSource?: string;\n orderSide?: 'ask' | 'bid';\n orderKind?: string;\n orderId?: string;\n from?: string;\n to?: string;\n amount?: string;\n fillSource?: string;\n block?: number;\n txHash?: string;\n logIndex?: number;\n batchIndex?: number;\n timestamp?: number;\n price?: Price;\n washTradingScore?: number;\n royaltyFeeBps?: number;\n marketplaceFeeBps?: number;\n paidFullRoyalty?: boolean;\n feeBreakdown?: FeeBreakdown[];\n isDeleted?: boolean;\n createdAt?: string;\n updatedAt?: string;\n};\n\nexport type FeeBreakdown = {\n kind?: string;\n bps?: number;\n recipient?: string;\n source?: string;\n rawAmount?: string;\n};\n\nexport type Attributes = {\n key?: string;\n kind?: string;\n value: string;\n tokenCount?: number;\n onSaleCount?: number;\n floorAskPrice?: Price | null;\n topBidValue?: number | null;\n createdAt?: string;\n};\n\nexport type Collection = {\n id?: string;\n name?: string;\n slug?: string;\n symbol?: string;\n imageUrl?: string;\n image?: string;\n isSpam?: boolean;\n isNsfw?: boolean;\n creator?: string;\n tokenCount?: string;\n metadataDisabled?: boolean;\n openseaVerificationStatus?: string;\n floorAskPrice?: Price;\n royaltiesBps?: number;\n royalties?: Royalties[];\n};\n\nexport type Royalties = {\n bps?: number;\n recipient?: string;\n};\n\nexport type Ownership = {\n tokenCount?: string;\n onSaleCount?: string;\n floorAsk?: FloorAsk;\n acquiredAt?: string;\n};\n\nexport type FloorAsk = {\n id?: string;\n price?: Price;\n maker?: string;\n kind?: string;\n validFrom?: number;\n validUntil?: number;\n source?: Source;\n rawData?: Metadata;\n isNativeOffChainCancellable?: boolean;\n};\n\nexport type Price = {\n currency?: {\n contract?: string;\n name?: string;\n symbol?: string;\n decimals?: number;\n chainId?: number;\n };\n amount?: {\n raw?: string;\n decimal?: number;\n usd?: number;\n native?: number;\n };\n netAmount?: {\n raw?: string;\n decimal?: number;\n usd?: number;\n native?: number;\n };\n};\n\nexport type Metadata = {\n imageOriginal?: string;\n tokenURI?: string;\n};\n\n/**\n * Controller that passively polls on a set interval for NFT auto detection\n */\nexport class NftDetectionController extends StaticIntervalPollingController<\n typeof controllerName,\n Record<never, never>,\n NftDetectionControllerMessenger\n> {\n #intervalId?: ReturnType<typeof setTimeout>;\n\n #interval: number;\n\n #disabled: boolean;\n\n readonly #addNft: NftController['addNft'];\n\n readonly #getNftState: () => NftControllerState;\n\n /**\n * The controller options\n *\n * @param options - The controller options.\n * @param options.interval - The pooling interval.\n * @param options.messenger - A reference to the messaging system.\n * @param options.disabled - Represents previous value of useNftDetection. Used to detect changes of useNftDetection. Default value is true.\n * @param options.addNft - Add an NFT.\n * @param options.getNftState - Gets the current state of the Assets controller.\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n messenger,\n disabled = false,\n addNft,\n getNftState,\n }: {\n interval?: number;\n messenger: NftDetectionControllerMessenger;\n disabled: boolean;\n addNft: NftController['addNft'];\n getNftState: () => NftControllerState;\n }) {\n super({\n name: controllerName,\n messenger,\n metadata: {},\n state: {},\n });\n this.#interval = interval;\n this.#disabled = disabled;\n\n this.#getNftState = getNftState;\n this.#addNft = addNft;\n\n this.messagingSystem.subscribe(\n 'PreferencesController:stateChange',\n this.#onPreferencesControllerStateChange.bind(this),\n );\n\n this.setIntervalLength(this.#interval);\n }\n\n async _executePoll(\n networkClientId: string,\n options: { address: string },\n ): Promise<void> {\n await this.detectNfts({ networkClientId, userAddress: options.address });\n }\n\n /**\n * Start polling for the currency rate.\n */\n async start() {\n if (!this.isMainnet() || this.#disabled) {\n return;\n }\n\n await this.#startPolling();\n }\n\n /**\n * Stop polling for the currency rate.\n */\n stop() {\n this.#stopPolling();\n }\n\n #stopPolling() {\n if (this.#intervalId) {\n clearInterval(this.#intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n *\n */\n async #startPolling(): Promise<void> {\n this.#stopPolling();\n await this.detectNfts();\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#intervalId = setInterval(async () => {\n await this.detectNfts();\n }, this.#interval);\n }\n\n /**\n * Checks whether network is mainnet or not.\n *\n * @returns Whether current network is mainnet.\n */\n isMainnet(): boolean {\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n return chainId === ChainId.mainnet;\n }\n\n isMainnetByNetworkClientId(networkClient: NetworkClient): boolean {\n return networkClient.configuration.chainId === ChainId.mainnet;\n }\n\n /**\n * Handles the state change of the preference controller.\n * @param preferencesState - The new state of the preference controller.\n * @param preferencesState.useNftDetection - Boolean indicating user preference on NFT detection.\n */\n #onPreferencesControllerStateChange({ useNftDetection }: PreferencesState) {\n if (!useNftDetection !== this.#disabled) {\n this.#disabled = !useNftDetection;\n if (useNftDetection) {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.start();\n } else {\n this.stop();\n }\n }\n }\n\n #getOwnerNftApi({ address, next }: { address: string; next?: string }) {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `${NFT_API_BASE_URL}/users/${address}/tokens?chainIds=1&limit=50&includeTopBid=true&continuation=${\n next ?? ''\n }`;\n }\n\n async #getOwnerNfts(address: string) {\n let nftApiResponse: ReservoirResponse;\n let nfts: TokensResponse[] = [];\n let next;\n\n do {\n nftApiResponse = await fetchWithErrorHandling({\n url: this.#getOwnerNftApi({ address, next }),\n options: {\n headers: {\n Version: NFT_API_VERSION,\n },\n },\n timeout: NFT_API_TIMEOUT,\n });\n\n if (!nftApiResponse) {\n return nfts;\n }\n\n const newNfts =\n nftApiResponse.tokens?.filter(\n (elm) =>\n elm.token.isSpam === false &&\n (elm.blockaidResult?.result_type\n ? elm.blockaidResult?.result_type === BlockaidResultType.Benign\n : true),\n ) ?? [];\n\n nfts = [...nfts, ...newNfts];\n } while ((next = nftApiResponse.continuation));\n\n return nfts;\n }\n\n /**\n * Triggers asset ERC721 token auto detection on mainnet. Any newly detected NFTs are\n * added.\n *\n * @param options - Options bag.\n * @param options.networkClientId - The network client ID to detect NFTs on.\n * @param options.userAddress - The address to detect NFTs for.\n */\n async detectNfts(options?: {\n networkClientId?: NetworkClientId;\n userAddress?: string;\n }) {\n const userAddress =\n options?.userAddress ??\n this.messagingSystem.call('AccountsController:getSelectedAccount')\n .address;\n /* istanbul ignore if */\n if (!this.isMainnet() || this.#disabled) {\n return;\n }\n /* istanbul ignore else */\n if (!userAddress) {\n return;\n }\n\n const apiNfts = await this.#getOwnerNfts(userAddress);\n const addNftPromises = apiNfts.map(async (nft) => {\n const {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n tokenId: token_id,\n contract,\n kind,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n image: image_url,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n imageSmall: image_thumbnail_url,\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n metadata: { imageOriginal: image_original_url } = {},\n name,\n description,\n attributes,\n topBid,\n lastSale,\n rarityRank,\n rarityScore,\n collection,\n } = nft.token;\n\n let ignored;\n /* istanbul ignore else */\n const { ignoredNfts } = this.#getNftState();\n if (ignoredNfts.length > 0) {\n ignored = ignoredNfts.find((c) => {\n /* istanbul ignore next */\n return (\n c.address === toChecksumHexAddress(contract) &&\n c.tokenId === token_id\n );\n });\n }\n\n /* istanbul ignore else */\n if (!ignored) {\n /* istanbul ignore next */\n const nftMetadata: NftMetadata = Object.assign(\n {},\n { name },\n description && { description },\n image_url && { image: image_url },\n image_thumbnail_url && { imageThumbnail: image_thumbnail_url },\n image_original_url && { imageOriginal: image_original_url },\n kind && { standard: kind.toUpperCase() },\n lastSale && { lastSale },\n attributes && { attributes },\n topBid && { topBid },\n rarityRank && { rarityRank },\n rarityScore && { rarityScore },\n collection && { collection },\n );\n\n await this.#addNft(contract, token_id, {\n nftMetadata,\n userAddress,\n source: Source.Detected,\n networkClientId: options?.networkClientId,\n });\n }\n });\n await Promise.all(addNftPromises);\n }\n}\n\nexport default NftDetectionController;\n"]}
|
package/dist/chunk-526TATMH.mjs
DELETED
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__privateAdd,
|
|
3
|
-
__privateMethod
|
|
4
|
-
} from "./chunk-XUI43LEZ.mjs";
|
|
5
|
-
|
|
6
|
-
// src/AccountTrackerController.ts
|
|
7
|
-
import {
|
|
8
|
-
query,
|
|
9
|
-
safelyExecuteWithTimeout,
|
|
10
|
-
toChecksumHexAddress
|
|
11
|
-
} from "@metamask/controller-utils";
|
|
12
|
-
import EthQuery from "@metamask/eth-query";
|
|
13
|
-
import { StaticIntervalPollingControllerV1 } from "@metamask/polling-controller";
|
|
14
|
-
import { assert } from "@metamask/utils";
|
|
15
|
-
import { Mutex } from "async-mutex";
|
|
16
|
-
import { cloneDeep } from "lodash";
|
|
17
|
-
var _getCorrectNetworkClient, getCorrectNetworkClient_fn;
|
|
18
|
-
var AccountTrackerController = class extends StaticIntervalPollingControllerV1 {
|
|
19
|
-
/**
|
|
20
|
-
* Creates an AccountTracker instance.
|
|
21
|
-
*
|
|
22
|
-
* @param options - The controller options.
|
|
23
|
-
* @param options.messenger - The messaging system used to communicate with other controllers.
|
|
24
|
-
* @param options.getMultiAccountBalancesEnabled - Gets the multi account balances enabled flag from the Preferences store.
|
|
25
|
-
* @param options.getCurrentChainId - Gets the chain ID for the current network from the Network store.
|
|
26
|
-
* @param options.getNetworkClientById - Gets the network client with the given id from the NetworkController.
|
|
27
|
-
* @param config - Initial options used to configure this controller.
|
|
28
|
-
* @param state - Initial state to set on this controller.
|
|
29
|
-
*/
|
|
30
|
-
constructor({
|
|
31
|
-
messenger,
|
|
32
|
-
getMultiAccountBalancesEnabled,
|
|
33
|
-
getCurrentChainId,
|
|
34
|
-
getNetworkClientById
|
|
35
|
-
}, config, state) {
|
|
36
|
-
super(config, state);
|
|
37
|
-
/**
|
|
38
|
-
* Resolves a networkClientId to a network client config
|
|
39
|
-
* or globally selected network config if not provided
|
|
40
|
-
*
|
|
41
|
-
* @param networkClientId - Optional networkClientId to fetch a network client with
|
|
42
|
-
* @returns network client config
|
|
43
|
-
*/
|
|
44
|
-
__privateAdd(this, _getCorrectNetworkClient);
|
|
45
|
-
this.refreshMutex = new Mutex();
|
|
46
|
-
/**
|
|
47
|
-
* Name of this controller used during composition
|
|
48
|
-
*/
|
|
49
|
-
this.name = "AccountTrackerController";
|
|
50
|
-
/**
|
|
51
|
-
* Refreshes the balances of the accounts depending on the multi-account setting.
|
|
52
|
-
* If multi-account is disabled, only updates the selected account balance.
|
|
53
|
-
* If multi-account is enabled, updates balances for all accounts.
|
|
54
|
-
*
|
|
55
|
-
* @param networkClientId - Optional networkClientId to fetch a network client with
|
|
56
|
-
*/
|
|
57
|
-
this.refresh = async (networkClientId) => {
|
|
58
|
-
const selectedAccount = this.messagingSystem.call(
|
|
59
|
-
"AccountsController:getSelectedAccount"
|
|
60
|
-
);
|
|
61
|
-
const releaseLock = await this.refreshMutex.acquire();
|
|
62
|
-
try {
|
|
63
|
-
const { chainId, ethQuery } = __privateMethod(this, _getCorrectNetworkClient, getCorrectNetworkClient_fn).call(this, networkClientId);
|
|
64
|
-
this.syncAccounts(chainId);
|
|
65
|
-
const { accounts, accountsByChainId } = this.state;
|
|
66
|
-
const isMultiAccountBalancesEnabled = this.getMultiAccountBalancesEnabled();
|
|
67
|
-
const accountsToUpdate = isMultiAccountBalancesEnabled ? Object.keys(accounts) : [toChecksumHexAddress(selectedAccount.address)];
|
|
68
|
-
const accountsForChain = { ...accountsByChainId[chainId] };
|
|
69
|
-
for (const address of accountsToUpdate) {
|
|
70
|
-
const balance = await this.getBalanceFromChain(address, ethQuery);
|
|
71
|
-
if (balance) {
|
|
72
|
-
accountsForChain[address] = {
|
|
73
|
-
balance
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
this.update({
|
|
78
|
-
...chainId === this.getCurrentChainId() && {
|
|
79
|
-
accounts: accountsForChain
|
|
80
|
-
},
|
|
81
|
-
accountsByChainId: {
|
|
82
|
-
...this.state.accountsByChainId,
|
|
83
|
-
[chainId]: accountsForChain
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
} finally {
|
|
87
|
-
releaseLock();
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
this.defaultConfig = {
|
|
91
|
-
interval: 1e4
|
|
92
|
-
};
|
|
93
|
-
this.defaultState = {
|
|
94
|
-
accounts: {},
|
|
95
|
-
accountsByChainId: {
|
|
96
|
-
[getCurrentChainId()]: {}
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
this.initialize();
|
|
100
|
-
this.messagingSystem = messenger;
|
|
101
|
-
this.setIntervalLength(this.config.interval);
|
|
102
|
-
this.getMultiAccountBalancesEnabled = getMultiAccountBalancesEnabled;
|
|
103
|
-
this.getCurrentChainId = getCurrentChainId;
|
|
104
|
-
this.getNetworkClientById = getNetworkClientById;
|
|
105
|
-
this.poll();
|
|
106
|
-
this.messagingSystem.subscribe(
|
|
107
|
-
"AccountsController:selectedEvmAccountChange",
|
|
108
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
109
|
-
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
110
|
-
() => this.refresh()
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
syncAccounts(newChainId) {
|
|
114
|
-
const accounts = { ...this.state.accounts };
|
|
115
|
-
const accountsByChainId = cloneDeep(this.state.accountsByChainId);
|
|
116
|
-
const existing = Object.keys(accounts);
|
|
117
|
-
if (!accountsByChainId[newChainId]) {
|
|
118
|
-
accountsByChainId[newChainId] = {};
|
|
119
|
-
existing.forEach((address) => {
|
|
120
|
-
accountsByChainId[newChainId][address] = { balance: "0x0" };
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
const addresses = Object.values(
|
|
124
|
-
this.messagingSystem.call("AccountsController:listAccounts").map(
|
|
125
|
-
(internalAccount) => toChecksumHexAddress(internalAccount.address)
|
|
126
|
-
)
|
|
127
|
-
);
|
|
128
|
-
const newAddresses = addresses.filter(
|
|
129
|
-
(address) => !existing.includes(address)
|
|
130
|
-
);
|
|
131
|
-
const oldAddresses = existing.filter(
|
|
132
|
-
(address) => !addresses.includes(address)
|
|
133
|
-
);
|
|
134
|
-
newAddresses.forEach((address) => {
|
|
135
|
-
accounts[address] = { balance: "0x0" };
|
|
136
|
-
});
|
|
137
|
-
Object.keys(accountsByChainId).forEach((chainId) => {
|
|
138
|
-
newAddresses.forEach((address) => {
|
|
139
|
-
accountsByChainId[chainId][address] = {
|
|
140
|
-
balance: "0x0"
|
|
141
|
-
};
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
oldAddresses.forEach((address) => {
|
|
145
|
-
delete accounts[address];
|
|
146
|
-
});
|
|
147
|
-
Object.keys(accountsByChainId).forEach((chainId) => {
|
|
148
|
-
oldAddresses.forEach((address) => {
|
|
149
|
-
delete accountsByChainId[chainId][address];
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
this.update({ accounts, accountsByChainId });
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Sets a new provider.
|
|
156
|
-
*
|
|
157
|
-
* TODO: Replace this wth a method.
|
|
158
|
-
*
|
|
159
|
-
* @param provider - Provider used to create a new underlying EthQuery instance.
|
|
160
|
-
*/
|
|
161
|
-
set provider(provider) {
|
|
162
|
-
this._provider = provider;
|
|
163
|
-
}
|
|
164
|
-
get provider() {
|
|
165
|
-
throw new Error("Property only used for setting");
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Starts a new polling interval.
|
|
169
|
-
*
|
|
170
|
-
* @param interval - Polling interval trigger a 'refresh'.
|
|
171
|
-
*/
|
|
172
|
-
async poll(interval) {
|
|
173
|
-
interval && this.configure({ interval }, false, false);
|
|
174
|
-
this.handle && clearTimeout(this.handle);
|
|
175
|
-
await this.refresh();
|
|
176
|
-
this.handle = setTimeout(() => {
|
|
177
|
-
this.poll(this.config.interval);
|
|
178
|
-
}, this.config.interval);
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Refreshes the balances of the accounts using the networkClientId
|
|
182
|
-
*
|
|
183
|
-
* @param networkClientId - The network client ID used to get balances.
|
|
184
|
-
*/
|
|
185
|
-
async _executePoll(networkClientId) {
|
|
186
|
-
this.refresh(networkClientId);
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Fetches the balance of a given address from the blockchain.
|
|
190
|
-
*
|
|
191
|
-
* @param address - The account address to fetch the balance for.
|
|
192
|
-
* @param ethQuery - The EthQuery instance to query getBalnce with.
|
|
193
|
-
* @returns A promise that resolves to the balance in a hex string format.
|
|
194
|
-
*/
|
|
195
|
-
async getBalanceFromChain(address, ethQuery) {
|
|
196
|
-
return await safelyExecuteWithTimeout(async () => {
|
|
197
|
-
assert(ethQuery, "Provider not set.");
|
|
198
|
-
return await query(ethQuery, "getBalance", [address]);
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Sync accounts balances with some additional addresses.
|
|
203
|
-
*
|
|
204
|
-
* @param addresses - the additional addresses, may be hardware wallet addresses.
|
|
205
|
-
* @param networkClientId - Optional networkClientId to fetch a network client with.
|
|
206
|
-
* @returns accounts - addresses with synced balance
|
|
207
|
-
*/
|
|
208
|
-
async syncBalanceWithAddresses(addresses, networkClientId) {
|
|
209
|
-
const { ethQuery } = __privateMethod(this, _getCorrectNetworkClient, getCorrectNetworkClient_fn).call(this, networkClientId);
|
|
210
|
-
return await Promise.all(
|
|
211
|
-
addresses.map((address) => {
|
|
212
|
-
return safelyExecuteWithTimeout(async () => {
|
|
213
|
-
assert(ethQuery, "Provider not set.");
|
|
214
|
-
const balance = await query(ethQuery, "getBalance", [address]);
|
|
215
|
-
return [address, balance];
|
|
216
|
-
});
|
|
217
|
-
})
|
|
218
|
-
).then((value) => {
|
|
219
|
-
return value.reduce((obj, item) => {
|
|
220
|
-
if (!item) {
|
|
221
|
-
return obj;
|
|
222
|
-
}
|
|
223
|
-
const [address, balance] = item;
|
|
224
|
-
return {
|
|
225
|
-
...obj,
|
|
226
|
-
[address]: {
|
|
227
|
-
balance
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
}, {});
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
_getCorrectNetworkClient = new WeakSet();
|
|
235
|
-
getCorrectNetworkClient_fn = function(networkClientId) {
|
|
236
|
-
if (networkClientId) {
|
|
237
|
-
const networkClient = this.getNetworkClientById(networkClientId);
|
|
238
|
-
return {
|
|
239
|
-
chainId: networkClient.configuration.chainId,
|
|
240
|
-
ethQuery: new EthQuery(networkClient.provider)
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
return {
|
|
244
|
-
chainId: this.getCurrentChainId(),
|
|
245
|
-
ethQuery: this._provider ? new EthQuery(this._provider) : void 0
|
|
246
|
-
};
|
|
247
|
-
};
|
|
248
|
-
var AccountTrackerController_default = AccountTrackerController;
|
|
249
|
-
|
|
250
|
-
export {
|
|
251
|
-
AccountTrackerController,
|
|
252
|
-
AccountTrackerController_default
|
|
253
|
-
};
|
|
254
|
-
//# sourceMappingURL=chunk-526TATMH.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/AccountTrackerController.ts"],"sourcesContent":["import type {\n AccountsControllerSelectedEvmAccountChangeEvent,\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerListAccountsAction,\n AccountsControllerSelectedAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n BaseConfig,\n BaseState,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n query,\n safelyExecuteWithTimeout,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport EthQuery from '@metamask/eth-query';\nimport type { Provider } from '@metamask/eth-query';\nimport type {\n NetworkClientId,\n NetworkController,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingControllerV1 } from '@metamask/polling-controller';\nimport type { PreferencesState } from '@metamask/preferences-controller';\nimport type { Hex } from '@metamask/utils';\nimport { assert } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport { cloneDeep } from 'lodash';\n\nconst controllerName = 'AccountTrackerController';\n\nexport type AllowedActions =\n | AccountsControllerListAccountsAction\n | AccountsControllerGetSelectedAccountAction;\n\nexport type AllowedEvents =\n | AccountsControllerSelectedEvmAccountChangeEvent\n | AccountsControllerSelectedAccountChangeEvent;\n\nexport type AccountTrackerControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n AllowedActions,\n AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * @type AccountInformation\n *\n * Account information object\n * @property balance - Hex string of an account balancec in wei\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\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 */\n// This interface was created before this ESLint rule was added.\n// Remove in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\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 */\n// This interface was created before this ESLint rule was added.\n// Remove in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface AccountTrackerState extends BaseState {\n accounts: { [address: string]: AccountInformation };\n accountsByChainId: Record<string, { [address: string]: AccountInformation }>;\n}\n\n/**\n * Controller that tracks the network balances for all user accounts.\n */\nexport class AccountTrackerController extends StaticIntervalPollingControllerV1<\n AccountTrackerConfig,\n AccountTrackerState\n> {\n private _provider?: Provider;\n\n private readonly refreshMutex = new Mutex();\n\n private handle?: ReturnType<typeof setTimeout>;\n\n private syncAccounts(newChainId: string) {\n const accounts = { ...this.state.accounts };\n const accountsByChainId = cloneDeep(this.state.accountsByChainId);\n\n const existing = Object.keys(accounts);\n if (!accountsByChainId[newChainId]) {\n accountsByChainId[newChainId] = {};\n existing.forEach((address) => {\n accountsByChainId[newChainId][address] = { balance: '0x0' };\n });\n }\n\n // Note: The address from the preferences controller are checksummed\n // The addresses from the accounts controller are lowercased\n const addresses = Object.values(\n this.messagingSystem\n .call('AccountsController:listAccounts')\n .map((internalAccount) =>\n toChecksumHexAddress(internalAccount.address),\n ),\n );\n const newAddresses = addresses.filter(\n (address) => !existing.includes(address),\n );\n const oldAddresses = existing.filter(\n (address) => !addresses.includes(address),\n );\n newAddresses.forEach((address) => {\n accounts[address] = { balance: '0x0' };\n });\n Object.keys(accountsByChainId).forEach((chainId) => {\n newAddresses.forEach((address) => {\n accountsByChainId[chainId][address] = {\n balance: '0x0',\n };\n });\n });\n\n oldAddresses.forEach((address) => {\n delete accounts[address];\n });\n Object.keys(accountsByChainId).forEach((chainId) => {\n oldAddresses.forEach((address) => {\n delete accountsByChainId[chainId][address];\n });\n });\n\n this.update({ accounts, accountsByChainId });\n }\n\n /**\n * Name of this controller used during composition\n */\n override name = 'AccountTrackerController' as const;\n\n private readonly getMultiAccountBalancesEnabled: () => PreferencesState['isMultiAccountBalancesEnabled'];\n\n private readonly getCurrentChainId: () => Hex;\n\n private readonly getNetworkClientById: NetworkController['getNetworkClientById'];\n\n private readonly messagingSystem: AccountTrackerControllerMessenger;\n\n /**\n * Creates an AccountTracker instance.\n *\n * @param options - The controller options.\n * @param options.messenger - The messaging system used to communicate with other controllers.\n * @param options.getMultiAccountBalancesEnabled - Gets the multi account balances enabled flag from the Preferences store.\n * @param options.getCurrentChainId - Gets the chain ID for the current network from the Network store.\n * @param options.getNetworkClientById - Gets the network client with the given id from the NetworkController.\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 messenger,\n getMultiAccountBalancesEnabled,\n getCurrentChainId,\n getNetworkClientById,\n }: {\n messenger: AccountTrackerControllerMessenger;\n getMultiAccountBalancesEnabled: () => PreferencesState['isMultiAccountBalancesEnabled'];\n getCurrentChainId: () => Hex;\n getNetworkClientById: NetworkController['getNetworkClientById'];\n },\n config?: Partial<AccountTrackerConfig>,\n state?: Partial<AccountTrackerState>,\n ) {\n super(config, state);\n this.defaultConfig = {\n interval: 10000,\n };\n this.defaultState = {\n accounts: {},\n accountsByChainId: {\n [getCurrentChainId()]: {},\n },\n };\n this.initialize();\n this.messagingSystem = messenger;\n this.setIntervalLength(this.config.interval);\n this.getMultiAccountBalancesEnabled = getMultiAccountBalancesEnabled;\n this.getCurrentChainId = getCurrentChainId;\n this.getNetworkClientById = getNetworkClientById;\n\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.poll();\n\n this.messagingSystem.subscribe(\n 'AccountsController:selectedEvmAccountChange',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n () => this.refresh(),\n );\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._provider = provider;\n }\n\n get provider() {\n throw new Error('Property only used for setting');\n }\n\n /**\n * Resolves a networkClientId to a network client config\n * or globally selected network config if not provided\n *\n * @param networkClientId - Optional networkClientId to fetch a network client with\n * @returns network client config\n */\n #getCorrectNetworkClient(networkClientId?: NetworkClientId): {\n chainId: string;\n ethQuery?: EthQuery;\n } {\n if (networkClientId) {\n const networkClient = this.getNetworkClientById(networkClientId);\n\n return {\n chainId: networkClient.configuration.chainId,\n ethQuery: new EthQuery(networkClient.provider),\n };\n }\n\n return {\n chainId: this.getCurrentChainId(),\n ethQuery: this._provider ? new EthQuery(this._provider) : undefined,\n };\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 interval && this.configure({ interval }, false, false);\n this.handle && clearTimeout(this.handle);\n await this.refresh();\n this.handle = setTimeout(() => {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.poll(this.config.interval);\n }, this.config.interval);\n }\n\n /**\n * Refreshes the balances of the accounts using the networkClientId\n *\n * @param networkClientId - The network client ID used to get balances.\n */\n async _executePoll(networkClientId: string): Promise<void> {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.refresh(networkClientId);\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 * @param networkClientId - Optional networkClientId to fetch a network client with\n */\n refresh = async (networkClientId?: NetworkClientId) => {\n const selectedAccount = this.messagingSystem.call(\n 'AccountsController:getSelectedAccount',\n );\n const releaseLock = await this.refreshMutex.acquire();\n try {\n const { chainId, ethQuery } =\n this.#getCorrectNetworkClient(networkClientId);\n this.syncAccounts(chainId);\n const { accounts, accountsByChainId } = this.state;\n const isMultiAccountBalancesEnabled =\n this.getMultiAccountBalancesEnabled();\n\n const accountsToUpdate = isMultiAccountBalancesEnabled\n ? Object.keys(accounts)\n : [toChecksumHexAddress(selectedAccount.address)];\n\n const accountsForChain = { ...accountsByChainId[chainId] };\n for (const address of accountsToUpdate) {\n const balance = await this.getBalanceFromChain(address, ethQuery);\n if (balance) {\n accountsForChain[address] = {\n balance,\n };\n }\n }\n\n this.update({\n ...(chainId === this.getCurrentChainId() && {\n accounts: accountsForChain,\n }),\n accountsByChainId: {\n ...this.state.accountsByChainId,\n [chainId]: accountsForChain,\n },\n });\n } finally {\n releaseLock();\n }\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 * @param ethQuery - The EthQuery instance to query getBalnce with.\n * @returns A promise that resolves to the balance in a hex string format.\n */\n private async getBalanceFromChain(\n address: string,\n ethQuery?: EthQuery,\n ): Promise<string | undefined> {\n return await safelyExecuteWithTimeout(async () => {\n assert(ethQuery, 'Provider not set.');\n return await query(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 * @param networkClientId - Optional networkClientId to fetch a network client with.\n * @returns accounts - addresses with synced balance\n */\n async syncBalanceWithAddresses(\n addresses: string[],\n networkClientId?: NetworkClientId,\n ): Promise<Record<string, { balance: string }>> {\n const { ethQuery } = this.#getCorrectNetworkClient(networkClientId);\n\n return await Promise.all(\n addresses.map((address): Promise<[string, string] | undefined> => {\n return safelyExecuteWithTimeout(async () => {\n assert(ethQuery, 'Provider not set.');\n const balance = await query(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"],"mappings":"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","names":[]}
|