Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/tron-wallet-snap/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **BREAKING** Bump `@metamask/keyring-snap-sdk` from `^9.2.1` to `^10.0.0` ([#214](https://github.com/MetaMask/internal-snaps/pull/214))
- **BREAKING** Bump `@metamask/snaps-sdk` from `^11.2.0` to `^12.0.1` ([#214](https://github.com/MetaMask/internal-snaps/pull/214))

### Removed

- **BREAKING** Remove the `onAssetsLookup`, `onAssetsConversion`, `onAssetHistoricalPrice`, and `onAssetsMarketData` asset handler entry points, along with the now-unused `AssetsHandler` and the `endowment:assets` permission ([#263](https://github.com/MetaMask/internal-snaps/pull/263))
- Remove now-unused asset lookup, conversion, market data, and historical price code paths (`AssetsService` and `SnapAssetsAdapter` methods, `PriceApiClient.getFiatExchangeRates` and `PriceApiClient.getHistoricalPrices`, and their associated types and mocks) ([#263](https://github.com/MetaMask/internal-snaps/pull/263))

## [3.2.0]

### Added
Expand Down
5 changes: 1 addition & 4 deletions packages/tron-wallet-snap/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/internal-snaps.git"
},
"source": {
"shasum": "ywXNBsBG0fniejuwfBWRFL2c2zEFyAJWiqiIhzNKG3Q=",
"shasum": "8BgBvWPHYMzKmBCQPHbLvvJjPs5L/rENxKfiXz8Ny6E=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down Expand Up @@ -61,9 +61,6 @@
}
]
},
"endowment:assets": {
"scopes": ["tron:728126428"]
},
"endowment:messenger": {
"actions": [
"RemoteFeatureFlagController:getState",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import { InMemoryCache } from '../../caching/InMemoryCache';
import { KnownCaip19Id } from '../../constants';
import type { ConfigProvider } from '../../services/config';
import { mockLogger } from '../../utils/mockLogger';
import { MOCK_EXCHANGE_RATES } from './mocks/exchange-rates';
import { MOCK_HISTORICAL_PRICES } from './mocks/historical-prices';
import { PriceApiClient } from './PriceApiClient';
import type { SpotPrices, VsCurrencyParam } from './types';

Expand All @@ -27,9 +25,7 @@ describe('PriceApiClient', () => {
baseUrl: 'https://some-mock-url.com',
chunkSize: 50,
cacheTtlsMilliseconds: {
fiatExchangeRates: 0,
spotPrices: 0,
historicalPrices: 0,
},
},
}),
Expand All @@ -45,50 +41,6 @@ describe('PriceApiClient', () => {
);
});

describe('getFiatExchangeRates', () => {
it('fetches fiat exchange rates successfully', async () => {
mockFetch.mockResolvedValueOnce({
ok: true,
json: jest.fn().mockResolvedValueOnce(MOCK_EXCHANGE_RATES),
});

const result = await client.getFiatExchangeRates();

expect(mockFetch).toHaveBeenCalledWith(
'https://some-mock-url.com/v1/exchange-rates/fiat',
);
expect(result).toStrictEqual(MOCK_EXCHANGE_RATES);
});

it('logs and throws when response is not ok', async () => {
mockFetch.mockResolvedValueOnce({
ok: false,
status: 500,
});

await expect(client.getFiatExchangeRates()).rejects.toThrow(
'HTTP error! status: 500',
);
expect(mockLogger.error).toHaveBeenCalledWith(
expect.any(Error),
'Error fetching fiat exchange rates',
);
});

it('logs and throws when fetch fails', async () => {
const mockError = new Error('Network error');
mockFetch.mockRejectedValueOnce(mockError);

await expect(client.getFiatExchangeRates()).rejects.toThrow(
'Network error',
);
expect(mockLogger.error).toHaveBeenCalledWith(
mockError,
'Error fetching fiat exchange rates',
);
});
});

describe('getMultipleSpotPrices', () => {
const mockResponse: SpotPrices = {
[KnownCaip19Id.TrxMainnet]: {
Expand Down Expand Up @@ -346,9 +298,7 @@ describe('PriceApiClient', () => {
baseUrl: 'invalid-url',
chunkSize: 50,
cacheTtlsMilliseconds: {
fiatExchangeRates: 0,
spotPrices: 0,
historicalPrices: 0,
},
},
}),
Expand Down Expand Up @@ -415,59 +365,4 @@ describe('PriceApiClient', () => {
).rejects.toThrow(/Expected/u);
});
});

describe('getHistoricalPrices', () => {
describe('when the data is not cached', () => {
it('fetches historical prices successfully', async () => {
mockFetch.mockResolvedValueOnce({
ok: true,
json: jest.fn().mockResolvedValueOnce(MOCK_HISTORICAL_PRICES),
});

const cacheSetSpy = jest.spyOn(mockCache, 'set');

const result = await client.getHistoricalPrices({
assetType: KnownCaip19Id.TrxMainnet,
timePeriod: '5d',
from: 123,
to: 456,
vsCurrency: 'usd',
});

expect(mockFetch).toHaveBeenCalledWith(
'https://some-mock-url.com/v3/historical-prices/tron:728126428/slip44:195?timePeriod=5d&from=123&to=456&vsCurrency=usd',
);
expect(cacheSetSpy).toHaveBeenCalledWith(
'PriceApiClient:getHistoricalPrices:{"assetType":"tron:728126428/slip44:195","timePeriod":"5d","from":123,"to":456,"vsCurrency":"usd"}',
MOCK_HISTORICAL_PRICES,
0,
);
expect(result).toStrictEqual(MOCK_HISTORICAL_PRICES);
});
});

describe('when the data is cached', () => {
it('returns the cached data', async () => {
jest
.spyOn(mockCache, 'get')
.mockResolvedValueOnce(MOCK_HISTORICAL_PRICES);

const cacheGetSpy = jest.spyOn(mockCache, 'get');
const cacheSetSpy = jest.spyOn(mockCache, 'set');

const result = await client.getHistoricalPrices({
assetType: KnownCaip19Id.TrxMainnet,
timePeriod: '5d',
from: 123,
to: 456,
vsCurrency: 'usd',
});

expect(cacheGetSpy).toHaveBeenCalled();
expect(mockFetch).not.toHaveBeenCalled();
expect(result).toStrictEqual(MOCK_HISTORICAL_PRICES);
expect(cacheSetSpy).not.toHaveBeenCalled();
});
});
});
});
106 changes: 2 additions & 104 deletions packages/tron-wallet-snap/src/clients/price-api/PriceApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,11 @@ import { CaipAssetTypeStruct } from '@metamask/utils';
import { mapKeys } from 'lodash';

import type { ICache } from '../../caching/ICache';
import { useCache } from '../../caching/useCache';
import { SNAP_OWNED_ASSETS } from '../../constants';
import type { ConfigProvider } from '../../services/config';
import logger from '../../utils/logger';
import type {
FiatExchangeRatesResponse,
GetHistoricalPricesParams,
GetHistoricalPricesResponse,
SpotPrices,
VsCurrencyParam,
} from './types';
import {
FiatExchangeRatesResponseStruct,
GetHistoricalPricesParamsStruct,
GetHistoricalPricesResponseStruct,
SpotPricesStruct,
VsCurrencyParamStruct,
} from './types';
import type { SpotPrices, VsCurrencyParam } from './types';
import { SpotPricesStruct, VsCurrencyParamStruct } from './types';

export class PriceApiClient {
readonly #fetch: typeof globalThis.fetch;
Expand All @@ -39,9 +26,7 @@ export class PriceApiClient {
readonly #cache: ICache<Serializable>;

readonly cacheTtlsMilliseconds: {
fiatExchangeRates: number;
spotPrices: number;
historicalPrices: number;
};

constructor(
Expand All @@ -64,29 +49,6 @@ export class PriceApiClient {
this.#cache = _cache;
}

async getFiatExchangeRates(): Promise<FiatExchangeRatesResponse> {
try {
const url = buildUrl({
baseUrl: this.#baseUrl,
path: '/v1/exchange-rates/fiat',
});

const response = await this.#fetch(url);

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const data = await response.json();
assert(data, FiatExchangeRatesResponseStruct);

return data;
} catch (error) {
this.#logger.error(error, 'Error fetching fiat exchange rates');
throw error;
}
}

/**
* Business logic for `getMultipleSpotPrices`.
*
Expand Down Expand Up @@ -260,68 +222,4 @@ export class PriceApiClient {

return this.#getMultipleSpotPrices_CACHE(filteredTokens, vsCurrency);
}

/**
* Business logic for `getHistoricalPrices`.
*
* @param params - The parameters for the request.
* @param params.assetType - The asset type of the token.
* @param params.timePeriod - The time period for the historical prices.
* @param params.from - The start date for the historical prices.
* @param params.to - The end date for the historical prices.
* @param params.vsCurrency - The currency to convert the prices to.
* @returns The historical prices for the token.
*/
async #getHistoricalPrices_INTERNAL(
params: GetHistoricalPricesParams,
): Promise<GetHistoricalPricesResponse> {
const url = buildUrl({
baseUrl: this.#baseUrl,
path: '/v3/historical-prices/{assetType}',
pathParams: {
assetType: params.assetType,
},
queryParams: {
...(params.timePeriod && { timePeriod: params.timePeriod }),
...(params.from && { from: params.from.toString() }),
...(params.to && { to: params.to.toString() }),
...(params.vsCurrency && { vsCurrency: params.vsCurrency }),
},
encodePathParams: false,
});

const response = await this.#fetch(url);
const historicalPrices = await response.json();
assert(historicalPrices, GetHistoricalPricesResponseStruct);

return historicalPrices;
}

/**
* Get historical prices for a token by calling the Price API.
* It caches the results for 1 hour.
*
* @see https://price.uat-api.cx.metamask.io/docs#/Historical%20Prices/PriceController_getHistoricalPricesByCaipAssetId
* @param params - The parameters for the request.
* @param params.assetType - The asset type of the token.
* @param params.timePeriod - The time period for the historical prices.
* @param params.from - The start date for the historical prices.
* @param params.to - The end date for the historical prices.
* @param params.vsCurrency - The currency to convert the prices to.
* @returns The historical prices for the token.
*/
async getHistoricalPrices(
params: GetHistoricalPricesParams,
): Promise<GetHistoricalPricesResponse> {
assert(params, GetHistoricalPricesParamsStruct);

return useCache(
this.#getHistoricalPrices_INTERNAL.bind(this),
this.#cache,
{
functionName: 'PriceApiClient:getHistoricalPrices',
ttlMilliseconds: this.cacheTtlsMilliseconds.historicalPrices,
},
)(params);
}
}
Loading