@metamask-previews/assets-controllers 50.0.0-preview-a1eb992b → 51.0.0-preview-dbdf1da
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 +17 -1
- package/dist/RatesController/RatesController.cjs +1 -0
- package/dist/RatesController/RatesController.cjs.map +1 -1
- package/dist/RatesController/RatesController.d.cts.map +1 -1
- package/dist/RatesController/RatesController.d.mts.map +1 -1
- package/dist/RatesController/RatesController.mjs +1 -0
- package/dist/RatesController/RatesController.mjs.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Bump `@metamask/keyring-api"` from `^17.0.0` to `^17.2.0` ([#5366](https://github.com/MetaMask/core/pull/5366))
|
|
13
|
+
|
|
14
|
+
## [51.0.0]
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **BREAKING:** Rename `MultiChainAssetsRatesController` to `MultichainAssetsRatesController` ([#5354](https://github.com/MetaMask/core/pull/5354))
|
|
19
|
+
- Bump `@metamask/utils` from `^11.1.0` to `^11.2.0` ([#5301](https://github.com/MetaMask/core/pull/5301))
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Resolved an issue where rate polling would only begin after the default 3-minute interval by manually triggering a rate update upon initialization, ensuring an immediate refresh for a better user experience ([#5364](https://github.com/MetaMask/core/pull/5364))
|
|
24
|
+
|
|
10
25
|
## [50.0.0]
|
|
11
26
|
|
|
12
27
|
### Changed
|
|
@@ -1405,7 +1420,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
1405
1420
|
|
|
1406
1421
|
- Use Ethers for AssetsContractController ([#845](https://github.com/MetaMask/core/pull/845))
|
|
1407
1422
|
|
|
1408
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@
|
|
1423
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@51.0.0...HEAD
|
|
1424
|
+
[51.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@50.0.0...@metamask/assets-controllers@51.0.0
|
|
1409
1425
|
[50.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@49.0.0...@metamask/assets-controllers@50.0.0
|
|
1410
1426
|
[49.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@48.0.0...@metamask/assets-controllers@49.0.0
|
|
1411
1427
|
[48.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@47.0.0...@metamask/assets-controllers@48.0.0
|
|
@@ -84,6 +84,7 @@ class RatesController extends base_controller_1.BaseController {
|
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
86
|
this.messagingSystem.publish(`${exports.name}:pollingStarted`);
|
|
87
|
+
await __classPrivateFieldGet(this, _RatesController_instances, "m", _RatesController_updateRates).call(this);
|
|
87
88
|
__classPrivateFieldSet(this, _RatesController_intervalId, setInterval(() => {
|
|
88
89
|
__classPrivateFieldGet(this, _RatesController_instances, "m", _RatesController_executePoll).call(this).catch(console.error);
|
|
89
90
|
}, __classPrivateFieldGet(this, _RatesController_intervalLength, "f")), "f");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RatesController.cjs","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport { Mutex } from 'async-mutex';\nimport type { Draft } from 'immer';\n\nimport { fetchMultiExchangeRate as defaultFetchExchangeRate } from '../crypto-compare-service';\nimport type {\n ConversionRates,\n RatesControllerState,\n RatesControllerOptions,\n RatesControllerMessenger,\n} from './types';\n\nexport const name = 'RatesController';\n\n/**\n * Supported cryptocurrencies that can be used as a base currency. The value needs to be compatible\n * with CryptoCompare's API which is the default source for the rates.\n *\n * See: https://min-api.cryptocompare.com/documentation?key=Price&cat=multipleSymbolsPriceEndpoint\n */\nexport enum Cryptocurrency {\n Btc = 'btc',\n Solana = 'sol',\n}\n\nconst DEFAULT_INTERVAL = 180000;\n\nconst metadata = {\n fiatCurrency: { persist: true, anonymous: true },\n rates: { persist: true, anonymous: true },\n cryptocurrencies: { persist: true, anonymous: true },\n};\n\nconst defaultState = {\n fiatCurrency: 'usd',\n rates: {\n [Cryptocurrency.Btc]: {\n conversionDate: 0,\n conversionRate: 0,\n },\n [Cryptocurrency.Solana]: {\n conversionDate: 0,\n conversionRate: 0,\n },\n },\n cryptocurrencies: [Cryptocurrency.Btc, Cryptocurrency.Solana],\n};\n\nexport class RatesController extends BaseController<\n typeof name,\n RatesControllerState,\n RatesControllerMessenger\n> {\n readonly #mutex = new Mutex();\n\n readonly #fetchMultiExchangeRate;\n\n readonly #includeUsdRate;\n\n #intervalLength: number;\n\n #intervalId: NodeJS.Timeout | undefined;\n\n /**\n * Creates a RatesController instance.\n *\n * @param options - Constructor options.\n * @param options.includeUsdRate - Keep track of the USD rate in addition to the current currency rate.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.messenger - A reference to the messaging system.\n * @param options.state - Initial state to set on this controller.\n * @param options.fetchMultiExchangeRate - Fetches the exchange rate from an external API. This option is primarily meant for use in unit tests.\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n messenger,\n state,\n includeUsdRate,\n fetchMultiExchangeRate = defaultFetchExchangeRate,\n }: RatesControllerOptions) {\n super({\n name,\n metadata,\n messenger,\n state: { ...defaultState, ...state },\n });\n this.#includeUsdRate = includeUsdRate;\n this.#fetchMultiExchangeRate = fetchMultiExchangeRate;\n this.#intervalLength = interval;\n }\n\n /**\n * Executes a function `callback` within a mutex lock to ensure that only one instance of `callback` runs at a time across all invocations of `#withLock`.\n * This method is useful for synchronizing access to a resource or section of code that should not be executed concurrently.\n *\n * @template R - The return type of the function `callback`.\n * @param callback - A callback to execute once the lock is acquired. This callback can be synchronous or asynchronous.\n * @returns A promise that resolves to the result of the function `callback`. The promise is fulfilled once `callback` has completed execution.\n * @example\n * async function criticalLogic() {\n * // Critical logic code goes here.\n * }\n *\n * // Execute criticalLogic within a lock.\n * const result = await this.#withLock(criticalLogic);\n */\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 async #withLock<R>(callback: () => R) {\n const releaseLock = await this.#mutex.acquire();\n try {\n return callback();\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Executes the polling operation to update rates.\n */\n async #executePoll(): Promise<void> {\n await this.#updateRates();\n }\n\n /**\n * Updates the rates by fetching new data.\n */\n async #updateRates(): Promise<void> {\n await this.#withLock(async () => {\n const { fiatCurrency, cryptocurrencies } = this.state;\n const response: Record<\n Cryptocurrency,\n Record<string, number>\n > = await this.#fetchMultiExchangeRate(\n fiatCurrency,\n cryptocurrencies,\n this.#includeUsdRate,\n );\n\n const updatedRates: ConversionRates = {};\n for (const [cryptocurrency, values] of Object.entries(response)) {\n updatedRates[cryptocurrency] = {\n conversionDate: Date.now(),\n conversionRate: values[fiatCurrency],\n ...(this.#includeUsdRate && { usdConversionRate: values.usd }),\n };\n }\n\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n rates: updatedRates,\n };\n },\n );\n });\n }\n\n /**\n * Starts the polling process.\n */\n async start(): Promise<void> {\n if (this.#intervalId) {\n return;\n }\n\n this.messagingSystem.publish(`${name}:pollingStarted`);\n\n this.#intervalId = setInterval(() => {\n this.#executePoll().catch(console.error);\n }, this.#intervalLength);\n }\n\n /**\n * Stops the polling process.\n */\n async stop(): Promise<void> {\n if (!this.#intervalId) {\n return;\n }\n\n clearInterval(this.#intervalId);\n this.#intervalId = undefined;\n this.messagingSystem.publish(`${name}:pollingStopped`);\n }\n\n /**\n * Returns the current list of cryptocurrency.\n * @returns The cryptocurrency list.\n */\n getCryptocurrencyList(): Cryptocurrency[] {\n const { cryptocurrencies } = this.state;\n return cryptocurrencies;\n }\n\n /**\n * Sets the list of supported cryptocurrencies.\n * @param cryptocurrencies - The list of supported cryptocurrencies.\n */\n async setCryptocurrencyList(\n cryptocurrencies: Cryptocurrency[],\n ): Promise<void> {\n await this.#withLock(() => {\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n cryptocurrencies,\n };\n },\n );\n });\n }\n\n /**\n * Sets the internal fiat currency and update rates accordingly.\n * @param fiatCurrency - The fiat currency.\n */\n async setFiatCurrency(fiatCurrency: string): Promise<void> {\n if (fiatCurrency === '') {\n throw new Error('The currency can not be an empty string');\n }\n\n await this.#withLock(() => {\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n fiatCurrency,\n };\n },\n );\n });\n await this.#updateRates();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"RatesController.cjs","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport { Mutex } from 'async-mutex';\nimport type { Draft } from 'immer';\n\nimport { fetchMultiExchangeRate as defaultFetchExchangeRate } from '../crypto-compare-service';\nimport type {\n ConversionRates,\n RatesControllerState,\n RatesControllerOptions,\n RatesControllerMessenger,\n} from './types';\n\nexport const name = 'RatesController';\n\n/**\n * Supported cryptocurrencies that can be used as a base currency. The value needs to be compatible\n * with CryptoCompare's API which is the default source for the rates.\n *\n * See: https://min-api.cryptocompare.com/documentation?key=Price&cat=multipleSymbolsPriceEndpoint\n */\nexport enum Cryptocurrency {\n Btc = 'btc',\n Solana = 'sol',\n}\n\nconst DEFAULT_INTERVAL = 180000;\n\nconst metadata = {\n fiatCurrency: { persist: true, anonymous: true },\n rates: { persist: true, anonymous: true },\n cryptocurrencies: { persist: true, anonymous: true },\n};\n\nconst defaultState = {\n fiatCurrency: 'usd',\n rates: {\n [Cryptocurrency.Btc]: {\n conversionDate: 0,\n conversionRate: 0,\n },\n [Cryptocurrency.Solana]: {\n conversionDate: 0,\n conversionRate: 0,\n },\n },\n cryptocurrencies: [Cryptocurrency.Btc, Cryptocurrency.Solana],\n};\n\nexport class RatesController extends BaseController<\n typeof name,\n RatesControllerState,\n RatesControllerMessenger\n> {\n readonly #mutex = new Mutex();\n\n readonly #fetchMultiExchangeRate;\n\n readonly #includeUsdRate;\n\n #intervalLength: number;\n\n #intervalId: NodeJS.Timeout | undefined;\n\n /**\n * Creates a RatesController instance.\n *\n * @param options - Constructor options.\n * @param options.includeUsdRate - Keep track of the USD rate in addition to the current currency rate.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.messenger - A reference to the messaging system.\n * @param options.state - Initial state to set on this controller.\n * @param options.fetchMultiExchangeRate - Fetches the exchange rate from an external API. This option is primarily meant for use in unit tests.\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n messenger,\n state,\n includeUsdRate,\n fetchMultiExchangeRate = defaultFetchExchangeRate,\n }: RatesControllerOptions) {\n super({\n name,\n metadata,\n messenger,\n state: { ...defaultState, ...state },\n });\n this.#includeUsdRate = includeUsdRate;\n this.#fetchMultiExchangeRate = fetchMultiExchangeRate;\n this.#intervalLength = interval;\n }\n\n /**\n * Executes a function `callback` within a mutex lock to ensure that only one instance of `callback` runs at a time across all invocations of `#withLock`.\n * This method is useful for synchronizing access to a resource or section of code that should not be executed concurrently.\n *\n * @template R - The return type of the function `callback`.\n * @param callback - A callback to execute once the lock is acquired. This callback can be synchronous or asynchronous.\n * @returns A promise that resolves to the result of the function `callback`. The promise is fulfilled once `callback` has completed execution.\n * @example\n * async function criticalLogic() {\n * // Critical logic code goes here.\n * }\n *\n * // Execute criticalLogic within a lock.\n * const result = await this.#withLock(criticalLogic);\n */\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 async #withLock<R>(callback: () => R) {\n const releaseLock = await this.#mutex.acquire();\n try {\n return callback();\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Executes the polling operation to update rates.\n */\n async #executePoll(): Promise<void> {\n await this.#updateRates();\n }\n\n /**\n * Updates the rates by fetching new data.\n */\n async #updateRates(): Promise<void> {\n await this.#withLock(async () => {\n const { fiatCurrency, cryptocurrencies } = this.state;\n const response: Record<\n Cryptocurrency,\n Record<string, number>\n > = await this.#fetchMultiExchangeRate(\n fiatCurrency,\n cryptocurrencies,\n this.#includeUsdRate,\n );\n\n const updatedRates: ConversionRates = {};\n for (const [cryptocurrency, values] of Object.entries(response)) {\n updatedRates[cryptocurrency] = {\n conversionDate: Date.now(),\n conversionRate: values[fiatCurrency],\n ...(this.#includeUsdRate && { usdConversionRate: values.usd }),\n };\n }\n\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n rates: updatedRates,\n };\n },\n );\n });\n }\n\n /**\n * Starts the polling process.\n */\n async start(): Promise<void> {\n if (this.#intervalId) {\n return;\n }\n\n this.messagingSystem.publish(`${name}:pollingStarted`);\n\n await this.#updateRates();\n\n this.#intervalId = setInterval(() => {\n this.#executePoll().catch(console.error);\n }, this.#intervalLength);\n }\n\n /**\n * Stops the polling process.\n */\n async stop(): Promise<void> {\n if (!this.#intervalId) {\n return;\n }\n\n clearInterval(this.#intervalId);\n this.#intervalId = undefined;\n this.messagingSystem.publish(`${name}:pollingStopped`);\n }\n\n /**\n * Returns the current list of cryptocurrency.\n * @returns The cryptocurrency list.\n */\n getCryptocurrencyList(): Cryptocurrency[] {\n const { cryptocurrencies } = this.state;\n return cryptocurrencies;\n }\n\n /**\n * Sets the list of supported cryptocurrencies.\n * @param cryptocurrencies - The list of supported cryptocurrencies.\n */\n async setCryptocurrencyList(\n cryptocurrencies: Cryptocurrency[],\n ): Promise<void> {\n await this.#withLock(() => {\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n cryptocurrencies,\n };\n },\n );\n });\n }\n\n /**\n * Sets the internal fiat currency and update rates accordingly.\n * @param fiatCurrency - The fiat currency.\n */\n async setFiatCurrency(fiatCurrency: string): Promise<void> {\n if (fiatCurrency === '') {\n throw new Error('The currency can not be an empty string');\n }\n\n await this.#withLock(() => {\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n fiatCurrency,\n };\n },\n );\n });\n await this.#updateRates();\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RatesController.d.cts","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAK3D,OAAO,KAAK,EAEV,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACzB,oBAAgB;AAEjB,eAAO,MAAM,IAAI,oBAAoB,CAAC;AAEtC;;;;;GAKG;AACH,oBAAY,cAAc;IACxB,GAAG,QAAQ;IACX,MAAM,QAAQ;CACf;AAyBD,qBAAa,eAAgB,SAAQ,cAAc,CACjD,OAAO,IAAI,EACX,oBAAoB,EACpB,wBAAwB,CACzB;;IAWC;;;;;;;;;OASG;gBACS,EACV,QAA2B,EAC3B,SAAS,EACT,KAAK,EACL,cAAc,EACd,sBAAiD,GAClD,EAAE,sBAAsB;IAgFzB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"RatesController.d.cts","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAK3D,OAAO,KAAK,EAEV,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACzB,oBAAgB;AAEjB,eAAO,MAAM,IAAI,oBAAoB,CAAC;AAEtC;;;;;GAKG;AACH,oBAAY,cAAc;IACxB,GAAG,QAAQ;IACX,MAAM,QAAQ;CACf;AAyBD,qBAAa,eAAgB,SAAQ,cAAc,CACjD,OAAO,IAAI,EACX,oBAAoB,EACpB,wBAAwB,CACzB;;IAWC;;;;;;;;;OASG;gBACS,EACV,QAA2B,EAC3B,SAAS,EACT,KAAK,EACL,cAAc,EACd,sBAAiD,GAClD,EAAE,sBAAsB;IAgFzB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B;;;OAGG;IACH,qBAAqB,IAAI,cAAc,EAAE;IAKzC;;;OAGG;IACG,qBAAqB,CACzB,gBAAgB,EAAE,cAAc,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC;IAahB;;;OAGG;IACG,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiB3D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RatesController.d.mts","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAK3D,OAAO,KAAK,EAEV,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACzB,oBAAgB;AAEjB,eAAO,MAAM,IAAI,oBAAoB,CAAC;AAEtC;;;;;GAKG;AACH,oBAAY,cAAc;IACxB,GAAG,QAAQ;IACX,MAAM,QAAQ;CACf;AAyBD,qBAAa,eAAgB,SAAQ,cAAc,CACjD,OAAO,IAAI,EACX,oBAAoB,EACpB,wBAAwB,CACzB;;IAWC;;;;;;;;;OASG;gBACS,EACV,QAA2B,EAC3B,SAAS,EACT,KAAK,EACL,cAAc,EACd,sBAAiD,GAClD,EAAE,sBAAsB;IAgFzB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"RatesController.d.mts","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAK3D,OAAO,KAAK,EAEV,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACzB,oBAAgB;AAEjB,eAAO,MAAM,IAAI,oBAAoB,CAAC;AAEtC;;;;;GAKG;AACH,oBAAY,cAAc;IACxB,GAAG,QAAQ;IACX,MAAM,QAAQ;CACf;AAyBD,qBAAa,eAAgB,SAAQ,cAAc,CACjD,OAAO,IAAI,EACX,oBAAoB,EACpB,wBAAwB,CACzB;;IAWC;;;;;;;;;OASG;gBACS,EACV,QAA2B,EAC3B,SAAS,EACT,KAAK,EACL,cAAc,EACd,sBAAiD,GAClD,EAAE,sBAAsB;IAgFzB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B;;;OAGG;IACH,qBAAqB,IAAI,cAAc,EAAE;IAKzC;;;OAGG;IACG,qBAAqB,CACzB,gBAAgB,EAAE,cAAc,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC;IAahB;;;OAGG;IACG,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiB3D"}
|
|
@@ -81,6 +81,7 @@ export class RatesController extends BaseController {
|
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
83
|
this.messagingSystem.publish(`${name}:pollingStarted`);
|
|
84
|
+
await __classPrivateFieldGet(this, _RatesController_instances, "m", _RatesController_updateRates).call(this);
|
|
84
85
|
__classPrivateFieldSet(this, _RatesController_intervalId, setInterval(() => {
|
|
85
86
|
__classPrivateFieldGet(this, _RatesController_instances, "m", _RatesController_executePoll).call(this).catch(console.error);
|
|
86
87
|
}, __classPrivateFieldGet(this, _RatesController_intervalLength, "f")), "f");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RatesController.mjs","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport { Mutex } from 'async-mutex';\nimport type { Draft } from 'immer';\n\nimport { fetchMultiExchangeRate as defaultFetchExchangeRate } from '../crypto-compare-service';\nimport type {\n ConversionRates,\n RatesControllerState,\n RatesControllerOptions,\n RatesControllerMessenger,\n} from './types';\n\nexport const name = 'RatesController';\n\n/**\n * Supported cryptocurrencies that can be used as a base currency. The value needs to be compatible\n * with CryptoCompare's API which is the default source for the rates.\n *\n * See: https://min-api.cryptocompare.com/documentation?key=Price&cat=multipleSymbolsPriceEndpoint\n */\nexport enum Cryptocurrency {\n Btc = 'btc',\n Solana = 'sol',\n}\n\nconst DEFAULT_INTERVAL = 180000;\n\nconst metadata = {\n fiatCurrency: { persist: true, anonymous: true },\n rates: { persist: true, anonymous: true },\n cryptocurrencies: { persist: true, anonymous: true },\n};\n\nconst defaultState = {\n fiatCurrency: 'usd',\n rates: {\n [Cryptocurrency.Btc]: {\n conversionDate: 0,\n conversionRate: 0,\n },\n [Cryptocurrency.Solana]: {\n conversionDate: 0,\n conversionRate: 0,\n },\n },\n cryptocurrencies: [Cryptocurrency.Btc, Cryptocurrency.Solana],\n};\n\nexport class RatesController extends BaseController<\n typeof name,\n RatesControllerState,\n RatesControllerMessenger\n> {\n readonly #mutex = new Mutex();\n\n readonly #fetchMultiExchangeRate;\n\n readonly #includeUsdRate;\n\n #intervalLength: number;\n\n #intervalId: NodeJS.Timeout | undefined;\n\n /**\n * Creates a RatesController instance.\n *\n * @param options - Constructor options.\n * @param options.includeUsdRate - Keep track of the USD rate in addition to the current currency rate.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.messenger - A reference to the messaging system.\n * @param options.state - Initial state to set on this controller.\n * @param options.fetchMultiExchangeRate - Fetches the exchange rate from an external API. This option is primarily meant for use in unit tests.\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n messenger,\n state,\n includeUsdRate,\n fetchMultiExchangeRate = defaultFetchExchangeRate,\n }: RatesControllerOptions) {\n super({\n name,\n metadata,\n messenger,\n state: { ...defaultState, ...state },\n });\n this.#includeUsdRate = includeUsdRate;\n this.#fetchMultiExchangeRate = fetchMultiExchangeRate;\n this.#intervalLength = interval;\n }\n\n /**\n * Executes a function `callback` within a mutex lock to ensure that only one instance of `callback` runs at a time across all invocations of `#withLock`.\n * This method is useful for synchronizing access to a resource or section of code that should not be executed concurrently.\n *\n * @template R - The return type of the function `callback`.\n * @param callback - A callback to execute once the lock is acquired. This callback can be synchronous or asynchronous.\n * @returns A promise that resolves to the result of the function `callback`. The promise is fulfilled once `callback` has completed execution.\n * @example\n * async function criticalLogic() {\n * // Critical logic code goes here.\n * }\n *\n * // Execute criticalLogic within a lock.\n * const result = await this.#withLock(criticalLogic);\n */\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 async #withLock<R>(callback: () => R) {\n const releaseLock = await this.#mutex.acquire();\n try {\n return callback();\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Executes the polling operation to update rates.\n */\n async #executePoll(): Promise<void> {\n await this.#updateRates();\n }\n\n /**\n * Updates the rates by fetching new data.\n */\n async #updateRates(): Promise<void> {\n await this.#withLock(async () => {\n const { fiatCurrency, cryptocurrencies } = this.state;\n const response: Record<\n Cryptocurrency,\n Record<string, number>\n > = await this.#fetchMultiExchangeRate(\n fiatCurrency,\n cryptocurrencies,\n this.#includeUsdRate,\n );\n\n const updatedRates: ConversionRates = {};\n for (const [cryptocurrency, values] of Object.entries(response)) {\n updatedRates[cryptocurrency] = {\n conversionDate: Date.now(),\n conversionRate: values[fiatCurrency],\n ...(this.#includeUsdRate && { usdConversionRate: values.usd }),\n };\n }\n\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n rates: updatedRates,\n };\n },\n );\n });\n }\n\n /**\n * Starts the polling process.\n */\n async start(): Promise<void> {\n if (this.#intervalId) {\n return;\n }\n\n this.messagingSystem.publish(`${name}:pollingStarted`);\n\n this.#intervalId = setInterval(() => {\n this.#executePoll().catch(console.error);\n }, this.#intervalLength);\n }\n\n /**\n * Stops the polling process.\n */\n async stop(): Promise<void> {\n if (!this.#intervalId) {\n return;\n }\n\n clearInterval(this.#intervalId);\n this.#intervalId = undefined;\n this.messagingSystem.publish(`${name}:pollingStopped`);\n }\n\n /**\n * Returns the current list of cryptocurrency.\n * @returns The cryptocurrency list.\n */\n getCryptocurrencyList(): Cryptocurrency[] {\n const { cryptocurrencies } = this.state;\n return cryptocurrencies;\n }\n\n /**\n * Sets the list of supported cryptocurrencies.\n * @param cryptocurrencies - The list of supported cryptocurrencies.\n */\n async setCryptocurrencyList(\n cryptocurrencies: Cryptocurrency[],\n ): Promise<void> {\n await this.#withLock(() => {\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n cryptocurrencies,\n };\n },\n );\n });\n }\n\n /**\n * Sets the internal fiat currency and update rates accordingly.\n * @param fiatCurrency - The fiat currency.\n */\n async setFiatCurrency(fiatCurrency: string): Promise<void> {\n if (fiatCurrency === '') {\n throw new Error('The currency can not be an empty string');\n }\n\n await this.#withLock(() => {\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n fiatCurrency,\n };\n },\n );\n });\n await this.#updateRates();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"RatesController.mjs","sourceRoot":"","sources":["../../src/RatesController/RatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport { Mutex } from 'async-mutex';\nimport type { Draft } from 'immer';\n\nimport { fetchMultiExchangeRate as defaultFetchExchangeRate } from '../crypto-compare-service';\nimport type {\n ConversionRates,\n RatesControllerState,\n RatesControllerOptions,\n RatesControllerMessenger,\n} from './types';\n\nexport const name = 'RatesController';\n\n/**\n * Supported cryptocurrencies that can be used as a base currency. The value needs to be compatible\n * with CryptoCompare's API which is the default source for the rates.\n *\n * See: https://min-api.cryptocompare.com/documentation?key=Price&cat=multipleSymbolsPriceEndpoint\n */\nexport enum Cryptocurrency {\n Btc = 'btc',\n Solana = 'sol',\n}\n\nconst DEFAULT_INTERVAL = 180000;\n\nconst metadata = {\n fiatCurrency: { persist: true, anonymous: true },\n rates: { persist: true, anonymous: true },\n cryptocurrencies: { persist: true, anonymous: true },\n};\n\nconst defaultState = {\n fiatCurrency: 'usd',\n rates: {\n [Cryptocurrency.Btc]: {\n conversionDate: 0,\n conversionRate: 0,\n },\n [Cryptocurrency.Solana]: {\n conversionDate: 0,\n conversionRate: 0,\n },\n },\n cryptocurrencies: [Cryptocurrency.Btc, Cryptocurrency.Solana],\n};\n\nexport class RatesController extends BaseController<\n typeof name,\n RatesControllerState,\n RatesControllerMessenger\n> {\n readonly #mutex = new Mutex();\n\n readonly #fetchMultiExchangeRate;\n\n readonly #includeUsdRate;\n\n #intervalLength: number;\n\n #intervalId: NodeJS.Timeout | undefined;\n\n /**\n * Creates a RatesController instance.\n *\n * @param options - Constructor options.\n * @param options.includeUsdRate - Keep track of the USD rate in addition to the current currency rate.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.messenger - A reference to the messaging system.\n * @param options.state - Initial state to set on this controller.\n * @param options.fetchMultiExchangeRate - Fetches the exchange rate from an external API. This option is primarily meant for use in unit tests.\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n messenger,\n state,\n includeUsdRate,\n fetchMultiExchangeRate = defaultFetchExchangeRate,\n }: RatesControllerOptions) {\n super({\n name,\n metadata,\n messenger,\n state: { ...defaultState, ...state },\n });\n this.#includeUsdRate = includeUsdRate;\n this.#fetchMultiExchangeRate = fetchMultiExchangeRate;\n this.#intervalLength = interval;\n }\n\n /**\n * Executes a function `callback` within a mutex lock to ensure that only one instance of `callback` runs at a time across all invocations of `#withLock`.\n * This method is useful for synchronizing access to a resource or section of code that should not be executed concurrently.\n *\n * @template R - The return type of the function `callback`.\n * @param callback - A callback to execute once the lock is acquired. This callback can be synchronous or asynchronous.\n * @returns A promise that resolves to the result of the function `callback`. The promise is fulfilled once `callback` has completed execution.\n * @example\n * async function criticalLogic() {\n * // Critical logic code goes here.\n * }\n *\n * // Execute criticalLogic within a lock.\n * const result = await this.#withLock(criticalLogic);\n */\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 async #withLock<R>(callback: () => R) {\n const releaseLock = await this.#mutex.acquire();\n try {\n return callback();\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Executes the polling operation to update rates.\n */\n async #executePoll(): Promise<void> {\n await this.#updateRates();\n }\n\n /**\n * Updates the rates by fetching new data.\n */\n async #updateRates(): Promise<void> {\n await this.#withLock(async () => {\n const { fiatCurrency, cryptocurrencies } = this.state;\n const response: Record<\n Cryptocurrency,\n Record<string, number>\n > = await this.#fetchMultiExchangeRate(\n fiatCurrency,\n cryptocurrencies,\n this.#includeUsdRate,\n );\n\n const updatedRates: ConversionRates = {};\n for (const [cryptocurrency, values] of Object.entries(response)) {\n updatedRates[cryptocurrency] = {\n conversionDate: Date.now(),\n conversionRate: values[fiatCurrency],\n ...(this.#includeUsdRate && { usdConversionRate: values.usd }),\n };\n }\n\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n rates: updatedRates,\n };\n },\n );\n });\n }\n\n /**\n * Starts the polling process.\n */\n async start(): Promise<void> {\n if (this.#intervalId) {\n return;\n }\n\n this.messagingSystem.publish(`${name}:pollingStarted`);\n\n await this.#updateRates();\n\n this.#intervalId = setInterval(() => {\n this.#executePoll().catch(console.error);\n }, this.#intervalLength);\n }\n\n /**\n * Stops the polling process.\n */\n async stop(): Promise<void> {\n if (!this.#intervalId) {\n return;\n }\n\n clearInterval(this.#intervalId);\n this.#intervalId = undefined;\n this.messagingSystem.publish(`${name}:pollingStopped`);\n }\n\n /**\n * Returns the current list of cryptocurrency.\n * @returns The cryptocurrency list.\n */\n getCryptocurrencyList(): Cryptocurrency[] {\n const { cryptocurrencies } = this.state;\n return cryptocurrencies;\n }\n\n /**\n * Sets the list of supported cryptocurrencies.\n * @param cryptocurrencies - The list of supported cryptocurrencies.\n */\n async setCryptocurrencyList(\n cryptocurrencies: Cryptocurrency[],\n ): Promise<void> {\n await this.#withLock(() => {\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n cryptocurrencies,\n };\n },\n );\n });\n }\n\n /**\n * Sets the internal fiat currency and update rates accordingly.\n * @param fiatCurrency - The fiat currency.\n */\n async setFiatCurrency(fiatCurrency: string): Promise<void> {\n if (fiatCurrency === '') {\n throw new Error('The currency can not be an empty string');\n }\n\n await this.#withLock(() => {\n this.update(\n (state: Draft<RatesControllerState>): RatesControllerState => {\n return {\n ...state,\n fiatCurrency,\n };\n },\n );\n });\n await this.#updateRates();\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/assets-controllers",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "51.0.0-preview-dbdf1da",
|
|
4
4
|
"description": "Controllers which manage interactions involving ERC-20, ERC-721, and ERC-1155 tokens (including NFTs)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"@metamask/contract-metadata": "^2.4.0",
|
|
59
59
|
"@metamask/controller-utils": "^11.5.0",
|
|
60
60
|
"@metamask/eth-query": "^4.0.0",
|
|
61
|
-
"@metamask/keyring-api": "^17.
|
|
61
|
+
"@metamask/keyring-api": "^17.2.0",
|
|
62
62
|
"@metamask/metamask-eth-abis": "^3.1.1",
|
|
63
63
|
"@metamask/polling-controller": "^12.0.3",
|
|
64
64
|
"@metamask/rpc-errors": "^7.0.2",
|
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
"@metamask/auto-changelog": "^3.4.4",
|
|
83
83
|
"@metamask/ethjs-provider-http": "^0.3.0",
|
|
84
84
|
"@metamask/keyring-controller": "^19.2.0",
|
|
85
|
-
"@metamask/keyring-internal-api": "^4.0.
|
|
86
|
-
"@metamask/keyring-snap-client": "^4.0.
|
|
85
|
+
"@metamask/keyring-internal-api": "^4.0.3",
|
|
86
|
+
"@metamask/keyring-snap-client": "^4.0.1",
|
|
87
87
|
"@metamask/network-controller": "^22.2.1",
|
|
88
88
|
"@metamask/permission-controller": "^11.0.6",
|
|
89
89
|
"@metamask/preferences-controller": "^15.0.2",
|