From eecb77c31b47db1354266ade6bcb96c96df141c0 Mon Sep 17 00:00:00 2001 From: Antonio Regadas Date: Fri, 20 Mar 2026 14:53:06 +0000 Subject: [PATCH 1/5] chore: update service and type --- packages/ai-controllers/CHANGELOG.md | 8 ++++++ .../src/AiDigestService.test.ts | 14 +++++----- .../ai-controllers/src/AiDigestService.ts | 28 +++++++++---------- .../ai-controllers/src/ai-digest-types.ts | 24 ++++++++++------ 4 files changed, 44 insertions(+), 30 deletions(-) diff --git a/packages/ai-controllers/CHANGELOG.md b/packages/ai-controllers/CHANGELOG.md index 70bcfa28684..324df902f96 100644 --- a/packages/ai-controllers/CHANGELOG.md +++ b/packages/ai-controllers/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Optional `perpsAssetId` on `RelatedAsset` for HyperLiquid-style market ids (e.g. `BTC`, `xyz:TSLA`), enabling Perps-aligned icon resolution on clients. + +### 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. + ## [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..745b9ad91bc 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 @@ -91,6 +90,7 @@ const RelatedAssetStruct = structType({ caip19: array(string()), sourceAssetId: string(), hlPerpsMarket: optional(string()), + perpsAssetId: optional(string()), }); const MarketOverviewTrendStruct = structType({ @@ -132,8 +132,8 @@ const getNormalizedMarketInsightsReport = ( return value; } - if (is(value, MarketInsightsDigestEnvelopeStruct)) { - return value.digest; + if (is(value, MarketInsightsSummaryEnvelopeStruct)) { + return value.summary; } return null; @@ -178,23 +178,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..f124ebedec3 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,8 +138,17 @@ export type RelatedAsset = { caip19: string[]; /** Canonical source asset identifier (e.g. "bitcoin") */ sourceAssetId: string; - /** Optional Hyperliquid perps market symbol (e.g. "BTC") */ + /** + * Optional HyperLiquid perps market symbol (e.g. `BTC`). + * @deprecated Prefer `perpsAssetId` when available; this field is kept for + * backward compatibility with older API payloads. + */ hlPerpsMarket?: string; + /** + * Optional HyperLiquid-style perps asset id (e.g. `BTC`, `xyz:TSLA`). + * Use this to resolve Perps icon URLs via `getAssetIconUrls` on clients. + */ + perpsAssetId?: string; }; export type MarketOverviewTrend = { @@ -188,14 +197,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; From 4936f75fe583324016e632281e4eaa358a1ce6bf Mon Sep 17 00:00:00 2001 From: Antonio Regadas Date: Fri, 20 Mar 2026 14:58:52 +0000 Subject: [PATCH 2/5] chore: update changelog --- packages/ai-controllers/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ai-controllers/CHANGELOG.md b/packages/ai-controllers/CHANGELOG.md index 324df902f96..280db436b53 100644 --- a/packages/ai-controllers/CHANGELOG.md +++ b/packages/ai-controllers/CHANGELOG.md @@ -9,11 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Optional `perpsAssetId` on `RelatedAsset` for HyperLiquid-style market ids (e.g. `BTC`, `xyz:TSLA`), enabling Perps-aligned icon resolution on clients. +- Optional `perpsAssetId` on `RelatedAsset` for HyperLiquid-style market ids (`xyz:TSLA`), enabling Perps icon resolution on clients ([#8263](https://github.com/MetaMask/core/pull/8263)). ### 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. +- `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)). ## [0.4.0] From 3cfd5dce1096b7b37093d665e8dc1db2f2e1b1b3 Mon Sep 17 00:00:00 2001 From: Antonio Regadas Date: Fri, 20 Mar 2026 15:25:27 +0000 Subject: [PATCH 3/5] chore: update --- packages/ai-controllers/src/ai-digest-types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ai-controllers/src/ai-digest-types.ts b/packages/ai-controllers/src/ai-digest-types.ts index f124ebedec3..53ed0622fe9 100644 --- a/packages/ai-controllers/src/ai-digest-types.ts +++ b/packages/ai-controllers/src/ai-digest-types.ts @@ -140,6 +140,7 @@ export type RelatedAsset = { sourceAssetId: string; /** * Optional HyperLiquid perps market symbol (e.g. `BTC`). + * * @deprecated Prefer `perpsAssetId` when available; this field is kept for * backward compatibility with older API payloads. */ From 2d3ca1f934e815796584cb6347ee36818e0621b0 Mon Sep 17 00:00:00 2001 From: Antonio Regadas Date: Fri, 20 Mar 2026 16:57:54 +0000 Subject: [PATCH 4/5] chore: review point --- packages/ai-controllers/CHANGELOG.md | 2 +- packages/ai-controllers/src/ai-digest-types.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/ai-controllers/CHANGELOG.md b/packages/ai-controllers/CHANGELOG.md index 280db436b53..f1f1050604f 100644 --- a/packages/ai-controllers/CHANGELOG.md +++ b/packages/ai-controllers/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Optional `perpsAssetId` on `RelatedAsset` for HyperLiquid-style market ids (`xyz:TSLA`), enabling Perps icon resolution on clients ([#8263](https://github.com/MetaMask/core/pull/8263)). +- Optional `perpsAssetId` on `RelatedAsset` for purely Perps-only synthetic assets with no on-chain CAIP-19 id (`xyz:TSLA`). Distinct from the existing `hlPerpsMarket`, which identifies regular crypto tokens that also trade on HyperLiquid (`BTC`, `ETH`). ### Changed diff --git a/packages/ai-controllers/src/ai-digest-types.ts b/packages/ai-controllers/src/ai-digest-types.ts index 53ed0622fe9..dde9904d40d 100644 --- a/packages/ai-controllers/src/ai-digest-types.ts +++ b/packages/ai-controllers/src/ai-digest-types.ts @@ -139,14 +139,14 @@ export type RelatedAsset = { /** Canonical source asset identifier (e.g. "bitcoin") */ sourceAssetId: string; /** - * Optional HyperLiquid perps market symbol (e.g. `BTC`). - * - * @deprecated Prefer `perpsAssetId` when available; this field is kept for - * backward compatibility with older API payloads. + * Optional HyperLiquid perps market symbol for regular crypto tokens that + * also trade on HyperLiquid (e.g. `BTC`, `ETH`, `SOL`). + * Present alongside `caip19` for on-chain assets. */ hlPerpsMarket?: string; /** - * Optional HyperLiquid-style perps asset id (e.g. `BTC`, `xyz:TSLA`). + * Optional HyperLiquid-style perps asset id for purely Perps-only synthetic + * assets that have no on-chain CAIP-19 id (e.g. `xyz:TSLA`, `xyz:AAPL`). * Use this to resolve Perps icon URLs via `getAssetIconUrls` on clients. */ perpsAssetId?: string; From 37574b374751201b5d77e811750d0c867b521eff Mon Sep 17 00:00:00 2001 From: Antonio Regadas Date: Fri, 20 Mar 2026 17:18:09 +0000 Subject: [PATCH 5/5] chore: clean up --- packages/ai-controllers/CHANGELOG.md | 5 +---- packages/ai-controllers/src/AiDigestService.ts | 1 - packages/ai-controllers/src/ai-digest-types.ts | 13 ++++--------- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/packages/ai-controllers/CHANGELOG.md b/packages/ai-controllers/CHANGELOG.md index f1f1050604f..301467d41d6 100644 --- a/packages/ai-controllers/CHANGELOG.md +++ b/packages/ai-controllers/CHANGELOG.md @@ -7,13 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Added - -- Optional `perpsAssetId` on `RelatedAsset` for purely Perps-only synthetic assets with no on-chain CAIP-19 id (`xyz:TSLA`). Distinct from the existing `hlPerpsMarket`, which identifies regular crypto tokens that also trade on HyperLiquid (`BTC`, `ETH`). - ### 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] diff --git a/packages/ai-controllers/src/AiDigestService.ts b/packages/ai-controllers/src/AiDigestService.ts index 745b9ad91bc..c2a7a1da4f5 100644 --- a/packages/ai-controllers/src/AiDigestService.ts +++ b/packages/ai-controllers/src/AiDigestService.ts @@ -90,7 +90,6 @@ const RelatedAssetStruct = structType({ caip19: array(string()), sourceAssetId: string(), hlPerpsMarket: optional(string()), - perpsAssetId: optional(string()), }); const MarketOverviewTrendStruct = structType({ diff --git a/packages/ai-controllers/src/ai-digest-types.ts b/packages/ai-controllers/src/ai-digest-types.ts index dde9904d40d..efdadd6b927 100644 --- a/packages/ai-controllers/src/ai-digest-types.ts +++ b/packages/ai-controllers/src/ai-digest-types.ts @@ -139,17 +139,12 @@ export type RelatedAsset = { /** Canonical source asset identifier (e.g. "bitcoin") */ sourceAssetId: string; /** - * Optional HyperLiquid perps market symbol for regular crypto tokens that - * also trade on HyperLiquid (e.g. `BTC`, `ETH`, `SOL`). - * Present alongside `caip19` for on-chain assets. + * 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; - /** - * Optional HyperLiquid-style perps asset id for purely Perps-only synthetic - * assets that have no on-chain CAIP-19 id (e.g. `xyz:TSLA`, `xyz:AAPL`). - * Use this to resolve Perps icon URLs via `getAssetIconUrls` on clients. - */ - perpsAssetId?: string; }; export type MarketOverviewTrend = {