diff --git a/packages/ai-controllers/CHANGELOG.md b/packages/ai-controllers/CHANGELOG.md index 70bcfa28684..301467d41d6 100644 --- a/packages/ai-controllers/CHANGELOG.md +++ b/packages/ai-controllers/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- `AiDigestService.searchDigest` now uses the universal `asset` query parameter instead of the previous `caipAssetType` / `hlPerpsMarket` branching logic. The public TypeScript API is unchanged; any identifier (CAIP-19, ticker, name, perps market id) can be passed as before ([#8263](https://github.com/MetaMask/core/pull/8263)). +- `RelatedAsset.hlPerpsMarket` now covers all HyperLiquid market identifiers — both regular crypto tokens (`BTC`, `ETH`) and purely synthetic perps assets (`xyz:TSLA`). No separate field is needed; clients use `caip19` presence to decide the icon resolution strategy ([#8263](https://github.com/MetaMask/core/pull/8263)). + ## [0.4.0] ### Added diff --git a/packages/ai-controllers/src/AiDigestService.test.ts b/packages/ai-controllers/src/AiDigestService.test.ts index 55cc948bba4..9b92791c591 100644 --- a/packages/ai-controllers/src/AiDigestService.test.ts +++ b/packages/ai-controllers/src/AiDigestService.test.ts @@ -53,7 +53,7 @@ describe('AiDigestService', () => { ], }; - it('fetches market insights from API using caipAssetType for CAIP-19 identifiers', async () => { + it('fetches market insights using universal asset= param for CAIP-19 identifiers', async () => { mockFetch.mockResolvedValue({ ok: true, status: 200, @@ -69,11 +69,11 @@ describe('AiDigestService', () => { expect(result).toStrictEqual(mockMarketInsightsReport); expect(mockFetch).toHaveBeenCalledWith( - 'http://test.com/api/v1/asset-summary?caipAssetType=eip155%3A1%2Ferc20%3A0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', + 'http://test.com/api/v1/asset-summary?asset=eip155%3A1%2Ferc20%3A0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', ); }); - it('fetches market insights from API using hlPerpsMarket for perps symbols', async () => { + it('fetches market insights using universal asset= param for ticker symbols', async () => { mockFetch.mockResolvedValue({ ok: true, status: 200, @@ -87,7 +87,7 @@ describe('AiDigestService', () => { expect(result).toStrictEqual(mockMarketInsightsReport); expect(mockFetch).toHaveBeenCalledWith( - 'http://test.com/api/v1/asset-summary?hlPerpsMarket=ETH', + 'http://test.com/api/v1/asset-summary?asset=ETH', ); }); @@ -104,17 +104,17 @@ describe('AiDigestService', () => { await service.searchDigest('xyz:TSLA'); expect(mockFetch).toHaveBeenCalledWith( - 'http://test.com/api/v1/asset-summary?hlPerpsMarket=xyz%3ATSLA', + 'http://test.com/api/v1/asset-summary?asset=xyz%3ATSLA', ); }); - it('accepts digest envelope responses', async () => { + it('accepts summary envelope responses', async () => { mockFetch.mockResolvedValue({ ok: true, status: 200, json: () => Promise.resolve({ - digest: mockMarketInsightsReport, + summary: mockMarketInsightsReport, }), }); diff --git a/packages/ai-controllers/src/AiDigestService.ts b/packages/ai-controllers/src/AiDigestService.ts index 798bb1ba93a..c2a7a1da4f5 100644 --- a/packages/ai-controllers/src/AiDigestService.ts +++ b/packages/ai-controllers/src/AiDigestService.ts @@ -6,7 +6,6 @@ import { string, type as structType, } from '@metamask/superstruct'; -import { isCaipAssetType } from '@metamask/utils'; import { AiDigestControllerErrorMessage } from './ai-digest-constants'; import type { @@ -79,8 +78,8 @@ const MarketInsightsReportStruct = structType({ metadata: optional(array(AIResponseMetadataStruct)), }); -const MarketInsightsDigestEnvelopeStruct = structType({ - digest: MarketInsightsReportStruct, +const MarketInsightsSummaryEnvelopeStruct = structType({ + summary: MarketInsightsReportStruct, }); // Market Overview structs @@ -132,8 +131,8 @@ const getNormalizedMarketInsightsReport = ( return value; } - if (is(value, MarketInsightsDigestEnvelopeStruct)) { - return value.digest; + if (is(value, MarketInsightsSummaryEnvelopeStruct)) { + return value.summary; } return null; @@ -178,23 +177,21 @@ export class AiDigestService implements DigestService { /** * Search for market insights by asset identifier. * - * Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps - * market symbol (e.g. `ETH`). The query parameter is chosen automatically: - * - CAIP-19 identifiers use `caipAssetType` - * - Perps market symbols use `hlPerpsMarket` + * Accepts any identifier the API understands (CAIP-19 asset type, ticker + * symbol, asset name, HyperLiquid perps market id, etc.) and forwards it + * unchanged via the universal `asset` query parameter. * - * @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol). + * Calls `GET ${baseUrl}/asset-summary?asset=`. + * + * @param assetIdentifier - The asset identifier (e.g. `eip155:1/slip44:60`, + * `ETH`, `Bitcoin`, `xyz:TSLA`). * @returns The market insights report, or `null` if none exists (404). */ async searchDigest( assetIdentifier: string, ): Promise { - const queryParam = isCaipAssetType(assetIdentifier) - ? `caipAssetType=${encodeURIComponent(assetIdentifier)}` - : `hlPerpsMarket=${encodeURIComponent(assetIdentifier)}`; - const response = await fetch( - `${this.#baseUrl}/asset-summary?${queryParam}`, + `${this.#baseUrl}/asset-summary?asset=${encodeURIComponent(assetIdentifier)}`, ); if (response.status === 404) { diff --git a/packages/ai-controllers/src/ai-digest-types.ts b/packages/ai-controllers/src/ai-digest-types.ts index 56d4ff45936..efdadd6b927 100644 --- a/packages/ai-controllers/src/ai-digest-types.ts +++ b/packages/ai-controllers/src/ai-digest-types.ts @@ -76,7 +76,7 @@ export type MarketInsightsTrend = { /** * AI-generated market insights report for a crypto asset. - * Returned by `GET /asset-summary?caipAssetType=` or `GET /asset-summary?hlPerpsMarket=`. + * Returned by `GET /asset-summary?asset=`. */ export type MarketInsightsReport = { /** API version */ @@ -138,7 +138,12 @@ export type RelatedAsset = { caip19: string[]; /** Canonical source asset identifier (e.g. "bitcoin") */ sourceAssetId: string; - /** Optional Hyperliquid perps market symbol (e.g. "BTC") */ + /** + * Optional HyperLiquid market identifier for this asset (e.g. `BTC`, `ETH`, + * `xyz:TSLA`). Covers both regular crypto tokens that trade on HyperLiquid + * and purely synthetic perps assets. Use this to resolve Perps icon URLs via + * `getAssetIconUrls` on clients when `caip19` is empty. + */ hlPerpsMarket?: string; }; @@ -188,14 +193,13 @@ export type DigestService = { /** * Search for market insights by asset identifier. * - * Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps - * market symbol (e.g. `ETH`). The implementation is responsible for choosing - * the correct query parameter (`caipAssetType` vs `hlPerpsMarket`). + * Accepts any identifier the API understands — CAIP-19 asset type + * (e.g. `eip155:1/slip44:60`), ticker symbol (e.g. `ETH`), asset name + * (e.g. `Bitcoin`), or HyperLiquid perps market id (e.g. `xyz:TSLA`). * - * Calls `GET /asset-summary?caipAssetType=` for CAIP-19 IDs, - * or `GET /asset-summary?hlPerpsMarket=` for perps symbols. + * Calls `GET /asset-summary?asset=`. * - * @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol). + * @param assetIdentifier - The asset identifier. * @returns The market insights report, or `null` if no insights exist (404). */ searchDigest(assetIdentifier: string): Promise;