-
-
Notifications
You must be signed in to change notification settings - Fork 277
fetch both selectedcurrency and usd prices #8123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f529ec0
95ab8f4
647c5e1
883a837
635bdf9
4f2265b
077dbd7
c701159
01d82d7
0c1e527
84240e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,19 @@ import type { | |
| } from './AssetsController'; | ||
| import type { PriceDataSourceConfig } from './data-sources/PriceDataSource'; | ||
| import type { Caip19AssetId, AccountId } from './types'; | ||
| import { formatExchangeRatesForBridge } from './utils'; | ||
|
|
||
| jest.mock('./utils', () => { | ||
| const actual = jest.requireActual<typeof import('./utils')>('./utils'); | ||
| return { | ||
| ...actual, | ||
| formatExchangeRatesForBridge: jest.fn(actual.formatExchangeRatesForBridge), | ||
| }; | ||
| }); | ||
|
|
||
| const formatExchangeRatesForBridgeMock = jest.mocked( | ||
| formatExchangeRatesForBridge, | ||
| ); | ||
|
|
||
| function createMockQueryApiClient(): ApiPlatformClient { | ||
| return { fetch: jest.fn() } as unknown as ApiPlatformClient; | ||
|
|
@@ -621,99 +634,33 @@ describe('AssetsController', () => { | |
| }); | ||
|
|
||
| describe('getExchangeRatesForBridge', () => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do not need to re-test |
||
| it('returns bridge format via action with empty state', async () => { | ||
| await withController(({ messenger }) => { | ||
| const result = (messenger.call as CallableFunction)( | ||
| 'AssetsController:getExchangeRatesForBridge', | ||
| ); | ||
|
|
||
| expect(result).toStrictEqual({ | ||
| conversionRates: {}, | ||
| currencyRates: {}, | ||
| marketData: {}, | ||
| currentCurrency: 'usd', | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| it('returns bridge format derived from assetsPrice and selectedCurrency', async () => { | ||
| const bitcoinAssetId = | ||
| 'bip122:000000000019d6689c085ae165831e93/slip44:0' as Caip19AssetId; | ||
| it('calls formatExchangeRatesForBridge with state and network data', async () => { | ||
| const initialState: Partial<AssetsControllerState> = { | ||
| assetsPrice: { | ||
| [bitcoinAssetId]: { | ||
| price: 50000, | ||
| lastUpdated: 1_600_000_000, | ||
| [MOCK_NATIVE_ASSET_ID]: { | ||
| assetPriceType: 'fungible', | ||
| price: 2000, | ||
| usdPrice: 2000, | ||
| lastUpdated: 1_700_000_000_000, | ||
| }, | ||
| }, | ||
| selectedCurrency: 'eur', | ||
| }; | ||
|
|
||
| await withController({ state: initialState }, ({ messenger }) => { | ||
| const result = (messenger.call as CallableFunction)( | ||
| 'AssetsController:getExchangeRatesForBridge', | ||
| ); | ||
|
|
||
| expect(result.currentCurrency).toBe('eur'); | ||
| expect(result.conversionRates[bitcoinAssetId]).toBeDefined(); | ||
| expect(result.conversionRates[bitcoinAssetId].rate).toBe('50000'); | ||
| expect(result.conversionRates[bitcoinAssetId].currency).toBe( | ||
| 'swift:0/iso4217:EUR', | ||
| ); | ||
| }); | ||
| }); | ||
|
|
||
| it('returns same result as controller.getExchangeRatesForBridge()', async () => { | ||
| await withController(({ controller, messenger }) => { | ||
| const viaAction = (messenger.call as CallableFunction)( | ||
| 'AssetsController:getExchangeRatesForBridge', | ||
| ); | ||
| const viaMethod = controller.getExchangeRatesForBridge(); | ||
|
|
||
| expect(viaAction).toStrictEqual(viaMethod); | ||
| }); | ||
| }); | ||
|
|
||
| it('passes usdToSelectedCurrencyRate so currencyRates have distinct conversionRate and usdConversionRate', async () => { | ||
| const ethNativeId = 'eip155:1/slip44:60' as Caip19AssetId; | ||
| const initialState: Partial<AssetsControllerState> = { | ||
| assetsPrice: { | ||
| [ethNativeId]: { price: 2000, lastUpdated: 1_700_000_000_000 }, | ||
| }, | ||
| selectedCurrency: 'eur', | ||
| }; | ||
|
|
||
| await withController({ state: initialState }, ({ controller }) => { | ||
| const result = controller.getExchangeRatesForBridge({ | ||
| usdToSelectedCurrencyRate: 0.92, | ||
| }); | ||
|
|
||
| expect(result.currencyRates.ETH).toBeDefined(); | ||
| expect(result.currencyRates.ETH?.conversionRate).toBe(2000 * 0.92); | ||
| expect(result.currencyRates.ETH?.usdConversionRate).toBe(2000); | ||
| }); | ||
| }); | ||
| }); | ||
| formatExchangeRatesForBridgeMock.mockClear(); | ||
|
|
||
| describe('getStateForTransactionPay', () => { | ||
| it('passes usdToSelectedCurrencyRate so currencyRates have distinct conversionRate and usdConversionRate', async () => { | ||
| const ethNativeId = 'eip155:1/slip44:60' as Caip19AssetId; | ||
| const initialState: Partial<AssetsControllerState> = { | ||
| assetsPrice: { | ||
| [ethNativeId]: { price: 2000, lastUpdated: 1_700_000_000_000 }, | ||
| }, | ||
| selectedCurrency: 'eur', | ||
| }; | ||
| controller.getExchangeRatesForBridge(); | ||
|
|
||
| await withController({ state: initialState }, ({ controller }) => { | ||
| const result = controller.getStateForTransactionPay({ | ||
| usdToSelectedCurrencyRate: 0.92, | ||
| expect(formatExchangeRatesForBridgeMock).toHaveBeenCalledTimes(1); | ||
| expect(formatExchangeRatesForBridgeMock).toHaveBeenCalledWith({ | ||
| assetsPrice: initialState.assetsPrice, | ||
| selectedCurrency: 'eur', | ||
| nativeAssetIdentifiers: { | ||
| 'eip155:1': 'eip155:1/slip44:60', | ||
| }, | ||
| networkConfigurationsByChainId: {}, | ||
| }); | ||
|
|
||
| expect(result.currentCurrency).toBe('eur'); | ||
| expect(result.currencyRates.ETH).toBeDefined(); | ||
| expect(result.currencyRates.ETH?.conversionRate).toBe(2000 * 0.92); | ||
| expect(result.currencyRates.ETH?.usdConversionRate).toBe(2000); | ||
| }); | ||
| }); | ||
| }); | ||
|
|
@@ -976,7 +923,9 @@ describe('AssetsController', () => { | |
| { | ||
| assetsPrice: { | ||
| [MOCK_ASSET_ID]: { | ||
| assetPriceType: 'fungible', | ||
| price: 1.0, | ||
| usdPrice: 1.0, | ||
| pricePercentChange1d: 0.5, | ||
| lastUpdated: Date.now(), | ||
| }, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1138,13 +1138,9 @@ export class AssetsController extends BaseController< | |
| * action instead of MultichainAssetsRatesController, TokenRatesController, | ||
| * and CurrencyRateController. | ||
| * | ||
| * @param options - Optional options for bridge rate conversion. | ||
| * @param options.usdToSelectedCurrencyRate - When selectedCurrency is not 'usd', pass 1 USD = this many units of selected currency so that currencyRates and conversionRates use correct user-currency vs USD values; otherwise the bridge USD conversion will be wrong for non-USD currencies. | ||
| * @returns Bridge-compatible exchange rate state derived from assetsPrice and selectedCurrency. | ||
| */ | ||
| getExchangeRatesForBridge(options?: { | ||
| usdToSelectedCurrencyRate?: number; | ||
| }): BridgeExchangeRatesFormat { | ||
| getExchangeRatesForBridge(): BridgeExchangeRatesFormat { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is good and exactly what we need here 👍 |
||
| const { nativeAssetIdentifiers } = this.messenger.call( | ||
| 'NetworkEnablementController:getState', | ||
| ); | ||
|
|
@@ -1156,7 +1152,6 @@ export class AssetsController extends BaseController< | |
| selectedCurrency: this.state.selectedCurrency, | ||
| nativeAssetIdentifiers, | ||
| networkConfigurationsByChainId, | ||
| usdToSelectedCurrencyRate: options?.usdToSelectedCurrencyRate, | ||
| }); | ||
| } | ||
|
|
||
|
|
@@ -1167,13 +1162,9 @@ export class AssetsController extends BaseController< | |
| * useAssetsController is true the transaction-pay-controller can use a | ||
| * single action instead of five separate getState calls. | ||
| * | ||
| * @param options - Optional options for legacy rate conversion. | ||
| * @param options.usdToSelectedCurrencyRate - When selectedCurrency is not 'usd', pass 1 USD = this many units of selected currency so that currencyRates and marketData use correct user-currency vs USD values; otherwise conversion rates will be wrong for non-USD currencies. | ||
| * @returns Legacy-compatible state for transaction-pay-controller. | ||
| */ | ||
| getStateForTransactionPay(options?: { | ||
| usdToSelectedCurrencyRate?: number; | ||
| }): TransactionPayLegacyFormat { | ||
| getStateForTransactionPay(): TransactionPayLegacyFormat { | ||
| const accounts = this.#selectedAccounts; | ||
| const { nativeAssetIdentifiers } = this.messenger.call( | ||
| 'NetworkEnablementController:getState', | ||
|
|
@@ -1189,7 +1180,6 @@ export class AssetsController extends BaseController< | |
| accounts: accounts.map((a) => ({ id: a.id, address: a.address })), | ||
| nativeAssetIdentifiers, | ||
| networkConfigurationsByChainId, | ||
| usdToSelectedCurrencyRate: options?.usdToSelectedCurrencyRate, | ||
| }); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we haven't released this yet, it is not breaking. I'm just amending the changelog.