@metamask/assets-controllers 1.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/LICENSE +20 -0
  3. package/README.md +30 -0
  4. package/dist/AccountTrackerController.d.ts +88 -0
  5. package/dist/AccountTrackerController.js +138 -0
  6. package/dist/AccountTrackerController.js.map +1 -0
  7. package/dist/AssetsContractController.d.ts +176 -0
  8. package/dist/AssetsContractController.js +314 -0
  9. package/dist/AssetsContractController.js.map +1 -0
  10. package/dist/CurrencyRateController.d.ts +98 -0
  11. package/dist/CurrencyRateController.js +193 -0
  12. package/dist/CurrencyRateController.js.map +1 -0
  13. package/dist/NftController.d.ts +409 -0
  14. package/dist/NftController.js +835 -0
  15. package/dist/NftController.js.map +1 -0
  16. package/dist/NftDetectionController.d.ts +179 -0
  17. package/dist/NftDetectionController.js +204 -0
  18. package/dist/NftDetectionController.js.map +1 -0
  19. package/dist/Standards/ERC20Standard.d.ts +42 -0
  20. package/dist/Standards/ERC20Standard.js +121 -0
  21. package/dist/Standards/ERC20Standard.js.map +1 -0
  22. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.d.ts +78 -0
  23. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.js +148 -0
  24. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.js.map +1 -0
  25. package/dist/Standards/NftStandards/ERC721/ERC721Standard.d.ts +88 -0
  26. package/dist/Standards/NftStandards/ERC721/ERC721Standard.js +182 -0
  27. package/dist/Standards/NftStandards/ERC721/ERC721Standard.js.map +1 -0
  28. package/dist/Standards/standards-types.d.ts +14 -0
  29. package/dist/Standards/standards-types.js +3 -0
  30. package/dist/Standards/standards-types.js.map +1 -0
  31. package/dist/TokenBalancesController.d.ts +69 -0
  32. package/dist/TokenBalancesController.js +94 -0
  33. package/dist/TokenBalancesController.js.map +1 -0
  34. package/dist/TokenDetectionController.d.ts +84 -0
  35. package/dist/TokenDetectionController.js +185 -0
  36. package/dist/TokenDetectionController.js.map +1 -0
  37. package/dist/TokenListController.d.ts +114 -0
  38. package/dist/TokenListController.js +256 -0
  39. package/dist/TokenListController.js.map +1 -0
  40. package/dist/TokenRatesController.d.ts +167 -0
  41. package/dist/TokenRatesController.js +284 -0
  42. package/dist/TokenRatesController.js.map +1 -0
  43. package/dist/TokensController.d.ts +238 -0
  44. package/dist/TokensController.js +530 -0
  45. package/dist/TokensController.js.map +1 -0
  46. package/dist/assetsUtil.d.ts +106 -0
  47. package/dist/assetsUtil.js +228 -0
  48. package/dist/assetsUtil.js.map +1 -0
  49. package/dist/crypto-compare.d.ts +12 -0
  50. package/dist/crypto-compare.js +67 -0
  51. package/dist/crypto-compare.js.map +1 -0
  52. package/dist/index.d.ts +11 -0
  53. package/dist/index.js +31 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/token-service.d.ts +29 -0
  56. package/dist/token-service.js +134 -0
  57. package/dist/token-service.js.map +1 -0
  58. package/package.json +75 -0
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.fetchTokenMetadata = exports.fetchTokenList = exports.TOKEN_METADATA_NO_SUPPORT_ERROR = exports.TOKEN_END_POINT_API = void 0;
13
+ const controller_utils_1 = require("@metamask/controller-utils");
14
+ const assetsUtil_1 = require("./assetsUtil");
15
+ exports.TOKEN_END_POINT_API = 'https://token-api.metaswap.codefi.network';
16
+ exports.TOKEN_METADATA_NO_SUPPORT_ERROR = 'TokenService Error: Network does not support fetchTokenMetadata';
17
+ /**
18
+ * Get the tokens URL for a specific network.
19
+ *
20
+ * @param chainId - The chain ID of the network the tokens requested are on.
21
+ * @returns The tokens URL.
22
+ */
23
+ function getTokensURL(chainId) {
24
+ return `${exports.TOKEN_END_POINT_API}/tokens/${chainId}`;
25
+ }
26
+ /**
27
+ * Get the token metadata URL for the given network and token.
28
+ *
29
+ * @param chainId - The chain ID of the network the token is on.
30
+ * @param tokenAddress - The token address.
31
+ * @returns The token metadata URL.
32
+ */
33
+ function getTokenMetadataURL(chainId, tokenAddress) {
34
+ return `${exports.TOKEN_END_POINT_API}/token/${chainId}?address=${tokenAddress}`;
35
+ }
36
+ const tenSecondsInMilliseconds = 10000;
37
+ // Token list averages 1.6 MB in size
38
+ // timeoutFetch by default has a 500ms timeout, which will almost always timeout given the response size.
39
+ const defaultTimeout = tenSecondsInMilliseconds;
40
+ /**
41
+ * Fetch the list of token metadata for a given network. This request is cancellable using the
42
+ * abort signal passed in.
43
+ *
44
+ * @param chainId - The chain ID of the network the requested tokens are on.
45
+ * @param abortSignal - The abort signal used to cancel the request if necessary.
46
+ * @param options - Additional fetch options.
47
+ * @param options.timeout - The fetch timeout.
48
+ * @returns The token list, or `undefined` if the request was cancelled.
49
+ */
50
+ function fetchTokenList(chainId, abortSignal, { timeout = defaultTimeout } = {}) {
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ const tokenURL = getTokensURL(chainId);
53
+ const response = yield queryApi(tokenURL, abortSignal, timeout);
54
+ if (response) {
55
+ return parseJsonResponse(response);
56
+ }
57
+ return undefined;
58
+ });
59
+ }
60
+ exports.fetchTokenList = fetchTokenList;
61
+ /**
62
+ * Fetch metadata for the token address provided for a given network. This request is cancellable
63
+ * using the abort signal passed in.
64
+ *
65
+ * @param chainId - The chain ID of the network the token is on.
66
+ * @param tokenAddress - The address of the token to fetch metadata for.
67
+ * @param abortSignal - The abort signal used to cancel the request if necessary.
68
+ * @param options - Additional fetch options.
69
+ * @param options.timeout - The fetch timeout.
70
+ * @returns The token metadata, or `undefined` if the request was either aborted or failed.
71
+ */
72
+ function fetchTokenMetadata(chainId, tokenAddress, abortSignal, { timeout = defaultTimeout } = {}) {
73
+ return __awaiter(this, void 0, void 0, function* () {
74
+ if (!(0, assetsUtil_1.isTokenListSupportedForNetwork)(chainId)) {
75
+ throw new Error(exports.TOKEN_METADATA_NO_SUPPORT_ERROR);
76
+ }
77
+ const tokenMetadataURL = getTokenMetadataURL(chainId, tokenAddress);
78
+ const response = yield queryApi(tokenMetadataURL, abortSignal, timeout);
79
+ if (response) {
80
+ return parseJsonResponse(response);
81
+ }
82
+ return undefined;
83
+ });
84
+ }
85
+ exports.fetchTokenMetadata = fetchTokenMetadata;
86
+ /**
87
+ * Perform fetch request against the api.
88
+ *
89
+ * @param apiURL - The URL of the API to fetch.
90
+ * @param abortSignal - The abort signal used to cancel the request if necessary.
91
+ * @param timeout - The fetch timeout.
92
+ * @returns Promise resolving request response.
93
+ */
94
+ function queryApi(apiURL, abortSignal, timeout) {
95
+ return __awaiter(this, void 0, void 0, function* () {
96
+ const fetchOptions = {
97
+ referrer: apiURL,
98
+ referrerPolicy: 'no-referrer-when-downgrade',
99
+ method: 'GET',
100
+ mode: 'cors',
101
+ signal: abortSignal,
102
+ cache: 'default',
103
+ };
104
+ fetchOptions.headers = new window.Headers();
105
+ fetchOptions.headers.set('Content-Type', 'application/json');
106
+ try {
107
+ return yield (0, controller_utils_1.timeoutFetch)(apiURL, fetchOptions, timeout);
108
+ }
109
+ catch (error) {
110
+ if (error instanceof Error && error.name === 'AbortError') {
111
+ console.log('Request is aborted');
112
+ }
113
+ }
114
+ return undefined;
115
+ });
116
+ }
117
+ /**
118
+ * Parse an API response and return the response JSON data.
119
+ *
120
+ * @param apiResponse - The API response to parse.
121
+ * @returns The response JSON data.
122
+ * @throws Will throw if the response includes an error.
123
+ */
124
+ function parseJsonResponse(apiResponse) {
125
+ return __awaiter(this, void 0, void 0, function* () {
126
+ const responseObj = yield apiResponse.json();
127
+ // api may return errors as json without setting an error http status code
128
+ if (responseObj === null || responseObj === void 0 ? void 0 : responseObj.error) {
129
+ throw new Error(`TokenService Error: ${responseObj.error}`);
130
+ }
131
+ return responseObj;
132
+ });
133
+ }
134
+ //# sourceMappingURL=token-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-service.js","sourceRoot":"","sources":["../src/token-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { timeoutFetch } from '@metamask/controller-utils';\nimport { isTokenListSupportedForNetwork } from './assetsUtil';\n\nexport const TOKEN_END_POINT_API = 'https://token-api.metaswap.codefi.network';\nexport const TOKEN_METADATA_NO_SUPPORT_ERROR =\n 'TokenService Error: Network does not support fetchTokenMetadata';\n\n/**\n * Get the tokens URL for a specific network.\n *\n * @param chainId - The chain ID of the network the tokens requested are on.\n * @returns The tokens URL.\n */\nfunction getTokensURL(chainId: string) {\n return `${TOKEN_END_POINT_API}/tokens/${chainId}`;\n}\n\n/**\n * Get the token metadata URL for the given network and token.\n *\n * @param chainId - The chain ID of the network the token is on.\n * @param tokenAddress - The token address.\n * @returns The token metadata URL.\n */\nfunction getTokenMetadataURL(chainId: string, tokenAddress: string) {\n return `${TOKEN_END_POINT_API}/token/${chainId}?address=${tokenAddress}`;\n}\n\nconst tenSecondsInMilliseconds = 10_000;\n\n// Token list averages 1.6 MB in size\n// timeoutFetch by default has a 500ms timeout, which will almost always timeout given the response size.\nconst defaultTimeout = tenSecondsInMilliseconds;\n\n/**\n * Fetch the list of token metadata for a given network. This request is cancellable using the\n * abort signal passed in.\n *\n * @param chainId - The chain ID of the network the requested tokens are on.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param options - Additional fetch options.\n * @param options.timeout - The fetch timeout.\n * @returns The token list, or `undefined` if the request was cancelled.\n */\nexport async function fetchTokenList(\n chainId: string,\n abortSignal: AbortSignal,\n { timeout = defaultTimeout } = {},\n): Promise<unknown> {\n const tokenURL = getTokensURL(chainId);\n const response = await queryApi(tokenURL, abortSignal, timeout);\n if (response) {\n return parseJsonResponse(response);\n }\n return undefined;\n}\n\n/**\n * Fetch metadata for the token address provided for a given network. This request is cancellable\n * using the abort signal passed in.\n *\n * @param chainId - The chain ID of the network the token is on.\n * @param tokenAddress - The address of the token to fetch metadata for.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param options - Additional fetch options.\n * @param options.timeout - The fetch timeout.\n * @returns The token metadata, or `undefined` if the request was either aborted or failed.\n */\nexport async function fetchTokenMetadata<T>(\n chainId: string,\n tokenAddress: string,\n abortSignal: AbortSignal,\n { timeout = defaultTimeout } = {},\n): Promise<T | undefined> {\n if (!isTokenListSupportedForNetwork(chainId)) {\n throw new Error(TOKEN_METADATA_NO_SUPPORT_ERROR);\n }\n const tokenMetadataURL = getTokenMetadataURL(chainId, tokenAddress);\n const response = await queryApi(tokenMetadataURL, abortSignal, timeout);\n if (response) {\n return parseJsonResponse(response) as Promise<T>;\n }\n return undefined;\n}\n\n/**\n * Perform fetch request against the api.\n *\n * @param apiURL - The URL of the API to fetch.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param timeout - The fetch timeout.\n * @returns Promise resolving request response.\n */\nasync function queryApi(\n apiURL: string,\n abortSignal: AbortSignal,\n timeout: number,\n): Promise<Response | undefined> {\n const fetchOptions: RequestInit = {\n referrer: apiURL,\n referrerPolicy: 'no-referrer-when-downgrade',\n method: 'GET',\n mode: 'cors',\n signal: abortSignal,\n cache: 'default',\n };\n fetchOptions.headers = new window.Headers();\n fetchOptions.headers.set('Content-Type', 'application/json');\n try {\n return await timeoutFetch(apiURL, fetchOptions, timeout);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n console.log('Request is aborted');\n }\n }\n return undefined;\n}\n\n/**\n * Parse an API response and return the response JSON data.\n *\n * @param apiResponse - The API response to parse.\n * @returns The response JSON data.\n * @throws Will throw if the response includes an error.\n */\nasync function parseJsonResponse(apiResponse: Response): Promise<unknown> {\n const responseObj = await apiResponse.json();\n // api may return errors as json without setting an error http status code\n if (responseObj?.error) {\n throw new Error(`TokenService Error: ${responseObj.error}`);\n }\n return responseObj;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@metamask/assets-controllers",
3
+ "version": "1.0.0",
4
+ "description": "Controllers which manage interactions involving ERC-20, ERC-721, and ERC-1155 tokens (including NFTs)",
5
+ "keywords": [
6
+ "MetaMask",
7
+ "Ethereum"
8
+ ],
9
+ "homepage": "https://github.com/MetaMask/controllers/tree/main/packages/assets-controllers#readme",
10
+ "bugs": {
11
+ "url": "https://github.com/MetaMask/controllers/issues"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/MetaMask/controllers.git"
16
+ },
17
+ "license": "MIT",
18
+ "main": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "files": [
21
+ "dist/"
22
+ ],
23
+ "scripts": {
24
+ "build:docs": "typedoc",
25
+ "changelog:validate": "../../scripts/validate-changelog.sh @metamask/assets-controllers",
26
+ "prepare-manifest:preview": "../../scripts/prepare-preview-manifest.sh",
27
+ "publish:preview": "yarn npm publish --tag preview",
28
+ "test": "jest",
29
+ "test:watch": "jest --watch"
30
+ },
31
+ "dependencies": {
32
+ "@ethersproject/abi": "^5.7.0",
33
+ "@ethersproject/bignumber": "^5.7.0",
34
+ "@ethersproject/contracts": "^5.7.0",
35
+ "@ethersproject/providers": "^5.7.0",
36
+ "@metamask/base-controller": "~1.0.0",
37
+ "@metamask/contract-metadata": "^1.35.0",
38
+ "@metamask/controller-utils": "~1.0.0",
39
+ "@metamask/metamask-eth-abis": "3.0.0",
40
+ "@metamask/network-controller": "~1.0.0",
41
+ "@metamask/preferences-controller": "~1.0.0",
42
+ "@types/uuid": "^8.3.0",
43
+ "abort-controller": "^3.0.0",
44
+ "async-mutex": "^0.2.6",
45
+ "babel-runtime": "^6.26.0",
46
+ "eth-query": "^2.1.2",
47
+ "eth-rpc-errors": "^4.0.0",
48
+ "ethereumjs-util": "^7.0.10",
49
+ "immer": "^9.0.6",
50
+ "multiformats": "^9.5.2",
51
+ "single-call-balance-checker-abi": "^1.0.0",
52
+ "uuid": "^8.3.2"
53
+ },
54
+ "devDependencies": {
55
+ "@metamask/auto-changelog": "^3.1.0",
56
+ "@types/jest": "^26.0.22",
57
+ "@types/node": "^14.14.31",
58
+ "deepmerge": "^4.2.2",
59
+ "ethjs-provider-http": "^0.1.6",
60
+ "jest": "^26.4.2",
61
+ "nock": "^13.0.7",
62
+ "sinon": "^9.2.4",
63
+ "ts-jest": "^26.5.2",
64
+ "typedoc": "^0.22.15",
65
+ "typedoc-plugin-missing-exports": "^0.22.6",
66
+ "typescript": "~4.6.3"
67
+ },
68
+ "engines": {
69
+ "node": ">=14.0.0"
70
+ },
71
+ "publishConfig": {
72
+ "access": "public",
73
+ "registry": "https://registry.npmjs.org/"
74
+ }
75
+ }