@metamask-previews/ai-controllers 0.2.0-preview-47d64d8 → 0.3.0-preview-91323fc2b
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 +10 -1
- package/dist/AiDigestController.cjs +14 -11
- package/dist/AiDigestController.cjs.map +1 -1
- package/dist/AiDigestController.d.cts +7 -3
- package/dist/AiDigestController.d.cts.map +1 -1
- package/dist/AiDigestController.d.mts +7 -3
- package/dist/AiDigestController.d.mts.map +1 -1
- package/dist/AiDigestController.mjs +14 -11
- package/dist/AiDigestController.mjs.map +1 -1
- package/dist/AiDigestService.cjs +12 -5
- package/dist/AiDigestService.cjs.map +1 -1
- package/dist/AiDigestService.d.cts +7 -5
- package/dist/AiDigestService.d.cts.map +1 -1
- package/dist/AiDigestService.d.mts +7 -5
- package/dist/AiDigestService.d.mts.map +1 -1
- package/dist/AiDigestService.mjs +12 -5
- package/dist/AiDigestService.mjs.map +1 -1
- package/dist/ai-digest-constants.cjs +1 -1
- package/dist/ai-digest-constants.cjs.map +1 -1
- package/dist/ai-digest-constants.d.cts +1 -1
- package/dist/ai-digest-constants.d.mts +1 -1
- package/dist/ai-digest-constants.mjs +1 -1
- package/dist/ai-digest-constants.mjs.map +1 -1
- package/dist/ai-digest-types.cjs +3 -0
- package/dist/ai-digest-types.cjs.map +1 -1
- package/dist/ai-digest-types.d.cts +13 -8
- package/dist/ai-digest-types.d.cts.map +1 -1
- package/dist/ai-digest-types.d.mts +13 -8
- package/dist/ai-digest-types.d.mts.map +1 -1
- package/dist/ai-digest-types.mjs +3 -0
- package/dist/ai-digest-types.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.0]
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- `AiDigestService.searchDigest` and `AiDigestController.fetchMarketInsights` now accept any string identifier rather than only CAIP-19 asset types. CAIP-19 identifiers continue to use the `caipAssetType` query parameter; all other strings (e.g. perps market symbols like `ETH`) use the new `hlPerpsMarket` query parameter ([#8182](https://github.com/MetaMask/core/pull/8182)).
|
|
15
|
+
- Rename `caip19Id` parameter to `assetIdentifier` in `DigestService.searchDigest`, `MarketInsightsEntry`, and `AiDigestController.fetchMarketInsights` ([#8182](https://github.com/MetaMask/core/pull/8182)).
|
|
16
|
+
- Replace `INVALID_CAIP_ASSET_TYPE` error message constant with `INVALID_ASSET_IDENTIFIER` in `AiDigestControllerErrorMessage` ([#8182](https://github.com/MetaMask/core/pull/8182)).
|
|
17
|
+
|
|
10
18
|
## [0.2.0]
|
|
11
19
|
|
|
12
20
|
### Added
|
|
@@ -42,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
42
50
|
- Removes `fetchDigest`, `clearDigest`, and `clearAllDigests` actions from the controller action surface.
|
|
43
51
|
- Removes `DigestData`/`DigestEntry` types and the `digests` state branch.
|
|
44
52
|
|
|
45
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/ai-controllers@0.
|
|
53
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/ai-controllers@0.3.0...HEAD
|
|
54
|
+
[0.3.0]: https://github.com/MetaMask/core/compare/@metamask/ai-controllers@0.2.0...@metamask/ai-controllers@0.3.0
|
|
46
55
|
[0.2.0]: https://github.com/MetaMask/core/compare/@metamask/ai-controllers@0.1.0...@metamask/ai-controllers@0.2.0
|
|
47
56
|
[0.1.0]: https://github.com/MetaMask/core/releases/tag/@metamask/ai-controllers@0.1.0
|
|
@@ -14,7 +14,6 @@ var _AiDigestController_instances, _AiDigestController_digestService, _AiDigestC
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.AiDigestController = exports.getDefaultAiDigestControllerState = void 0;
|
|
16
16
|
const base_controller_1 = require("@metamask/base-controller");
|
|
17
|
-
const utils_1 = require("@metamask/utils");
|
|
18
17
|
const ai_digest_constants_1 = require("./ai-digest-constants.cjs");
|
|
19
18
|
function getDefaultAiDigestControllerState() {
|
|
20
19
|
return {
|
|
@@ -54,38 +53,42 @@ class AiDigestController extends base_controller_1.BaseController {
|
|
|
54
53
|
__classPrivateFieldGet(this, _AiDigestController_instances, "m", _AiDigestController_registerMessageHandlers).call(this);
|
|
55
54
|
}
|
|
56
55
|
/**
|
|
57
|
-
* Fetches market insights for a given
|
|
56
|
+
* Fetches market insights for a given asset identifier.
|
|
58
57
|
* Returns cached data if still fresh, otherwise calls the service.
|
|
59
58
|
*
|
|
60
|
-
*
|
|
59
|
+
* Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps
|
|
60
|
+
* market symbol (e.g. `ETH`). The service handles choosing the correct API
|
|
61
|
+
* query parameter automatically.
|
|
62
|
+
*
|
|
63
|
+
* @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).
|
|
61
64
|
* @returns The market insights report, or `null` if none exists.
|
|
62
65
|
*/
|
|
63
|
-
async fetchMarketInsights(
|
|
64
|
-
if (!
|
|
65
|
-
throw new Error(ai_digest_constants_1.AiDigestControllerErrorMessage.
|
|
66
|
+
async fetchMarketInsights(assetIdentifier) {
|
|
67
|
+
if (!assetIdentifier) {
|
|
68
|
+
throw new Error(ai_digest_constants_1.AiDigestControllerErrorMessage.INVALID_ASSET_IDENTIFIER);
|
|
66
69
|
}
|
|
67
|
-
const existing = this.state.marketInsights[
|
|
70
|
+
const existing = this.state.marketInsights[assetIdentifier];
|
|
68
71
|
if (existing) {
|
|
69
72
|
const age = Date.now() - existing.fetchedAt;
|
|
70
73
|
if (age < ai_digest_constants_1.CACHE_DURATION_MS) {
|
|
71
74
|
return existing.data;
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
|
-
const data = await __classPrivateFieldGet(this, _AiDigestController_digestService, "f").searchDigest(
|
|
77
|
+
const data = await __classPrivateFieldGet(this, _AiDigestController_digestService, "f").searchDigest(assetIdentifier);
|
|
75
78
|
if (data === null) {
|
|
76
79
|
// No insights available for this asset — clear any stale cache entry
|
|
77
80
|
this.update((state) => {
|
|
78
|
-
delete state.marketInsights[
|
|
81
|
+
delete state.marketInsights[assetIdentifier];
|
|
79
82
|
});
|
|
80
83
|
return null;
|
|
81
84
|
}
|
|
82
85
|
const entry = {
|
|
83
|
-
|
|
86
|
+
assetIdentifier,
|
|
84
87
|
fetchedAt: Date.now(),
|
|
85
88
|
data,
|
|
86
89
|
};
|
|
87
90
|
this.update((state) => {
|
|
88
|
-
state.marketInsights[
|
|
91
|
+
state.marketInsights[assetIdentifier] = entry;
|
|
89
92
|
__classPrivateFieldGet(this, _AiDigestController_instances, "m", _AiDigestController_evictStaleCachedEntries).call(this, state.marketInsights);
|
|
90
93
|
});
|
|
91
94
|
return data;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiDigestController.cjs","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n StateMetadata,\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport { isCaipAssetType } from '@metamask/utils';\n\nimport {\n AiDigestControllerErrorMessage,\n controllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n} from './ai-digest-constants';\nimport type {\n AiDigestControllerState,\n DigestService,\n MarketInsightsReport,\n MarketInsightsEntry,\n MarketOverview,\n MarketOverviewEntry,\n} from './ai-digest-types';\n\nexport type AiDigestControllerFetchMarketInsightsAction = {\n type: `${typeof controllerName}:fetchMarketInsights`;\n handler: AiDigestController['fetchMarketInsights'];\n};\n\nexport type AiDigestControllerFetchMarketOverviewAction = {\n type: `${typeof controllerName}:fetchMarketOverview`;\n handler: AiDigestController['fetchMarketOverview'];\n};\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerFetchMarketInsightsAction\n | AiDigestControllerFetchMarketOverviewAction\n | AiDigestControllerGetStateAction;\n\nexport type AiDigestControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerEvents = AiDigestControllerStateChangeEvent;\n\nexport type AiDigestControllerMessenger = Messenger<\n typeof controllerName,\n AiDigestControllerActions,\n AiDigestControllerEvents\n>;\n\nexport type AiDigestControllerOptions = {\n messenger: AiDigestControllerMessenger;\n state?: Partial<AiDigestControllerState>;\n digestService: DigestService;\n};\n\nexport function getDefaultAiDigestControllerState(): AiDigestControllerState {\n return {\n marketInsights: {},\n marketOverview: null,\n };\n}\n\nconst aiDigestControllerMetadata: StateMetadata<AiDigestControllerState> = {\n marketInsights: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n marketOverview: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n};\n\nexport class AiDigestController extends BaseController<\n typeof controllerName,\n AiDigestControllerState,\n AiDigestControllerMessenger\n> {\n readonly #digestService: DigestService;\n\n constructor({ messenger, state, digestService }: AiDigestControllerOptions) {\n super({\n name: controllerName,\n metadata: aiDigestControllerMetadata,\n state: {\n ...getDefaultAiDigestControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#digestService = digestService;\n this.#registerMessageHandlers();\n }\n\n #registerMessageHandlers(): void {\n this.messenger.registerActionHandler(\n `${controllerName}:fetchMarketInsights`,\n this.fetchMarketInsights.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:fetchMarketOverview`,\n this.fetchMarketOverview.bind(this),\n );\n }\n\n /**\n * Fetches market insights for a given CAIP-19 asset identifier.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * @param caip19Id - The CAIP-19 identifier of the asset.\n * @returns The market insights report, or `null` if none exists.\n */\n async fetchMarketInsights(\n caip19Id: string,\n ): Promise<MarketInsightsReport | null> {\n if (!isCaipAssetType(caip19Id)) {\n throw new Error(AiDigestControllerErrorMessage.INVALID_CAIP_ASSET_TYPE);\n }\n\n const existing = this.state.marketInsights[caip19Id];\n if (existing) {\n const age = Date.now() - existing.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existing.data;\n }\n }\n\n const data = await this.#digestService.searchDigest(caip19Id);\n\n if (data === null) {\n // No insights available for this asset — clear any stale cache entry\n this.update((state) => {\n delete state.marketInsights[caip19Id];\n });\n return null;\n }\n\n const entry: MarketInsightsEntry = {\n caip19Id,\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketInsights[caip19Id] = entry;\n this.#evictStaleCachedEntries(state.marketInsights);\n });\n\n return data;\n }\n\n /**\n * Fetches the market overview report.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * @returns The market overview report, or `null` if none exists.\n */\n async fetchMarketOverview(): Promise<MarketOverview | null> {\n const existing = this.state.marketOverview;\n if (existing) {\n const age = Date.now() - existing.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existing.data;\n }\n }\n\n const data = await this.#digestService.fetchMarketOverview();\n\n if (data === null) {\n this.update((state) => {\n state.marketOverview = null;\n });\n return null;\n }\n\n const entry: MarketOverviewEntry = {\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketOverview = entry;\n });\n\n return data;\n }\n\n /**\n * Evicts stale (TTL expired) and oldest entries (FIFO) if cache exceeds max size.\n *\n * @param cache - The cache record to evict entries from.\n */\n #evictStaleCachedEntries<EntryType extends { fetchedAt: number }>(\n cache: Record<string, EntryType>,\n ): void {\n const now = Date.now();\n const entries = Object.entries(cache);\n const keysToDelete: string[] = [];\n const freshEntries: [string, EntryType][] = [];\n\n for (const [key, entry] of entries) {\n if (now - entry.fetchedAt >= CACHE_DURATION_MS) {\n keysToDelete.push(key);\n } else {\n freshEntries.push([key, entry]);\n }\n }\n\n if (freshEntries.length > MAX_CACHE_ENTRIES) {\n freshEntries.sort((a, b) => a[1].fetchedAt - b[1].fetchedAt);\n const entriesToRemove = freshEntries.length - MAX_CACHE_ENTRIES;\n for (let i = 0; i < entriesToRemove; i++) {\n keysToDelete.push(freshEntries[i][0]);\n }\n }\n\n for (const key of keysToDelete) {\n delete cache[key];\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AiDigestController.cjs","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n StateMetadata,\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport {\n AiDigestControllerErrorMessage,\n controllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n} from './ai-digest-constants';\nimport type {\n AiDigestControllerState,\n DigestService,\n MarketInsightsReport,\n MarketInsightsEntry,\n MarketOverview,\n MarketOverviewEntry,\n} from './ai-digest-types';\n\nexport type AiDigestControllerFetchMarketInsightsAction = {\n type: `${typeof controllerName}:fetchMarketInsights`;\n handler: AiDigestController['fetchMarketInsights'];\n};\n\nexport type AiDigestControllerFetchMarketOverviewAction = {\n type: `${typeof controllerName}:fetchMarketOverview`;\n handler: AiDigestController['fetchMarketOverview'];\n};\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerFetchMarketInsightsAction\n | AiDigestControllerFetchMarketOverviewAction\n | AiDigestControllerGetStateAction;\n\nexport type AiDigestControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerEvents = AiDigestControllerStateChangeEvent;\n\nexport type AiDigestControllerMessenger = Messenger<\n typeof controllerName,\n AiDigestControllerActions,\n AiDigestControllerEvents\n>;\n\nexport type AiDigestControllerOptions = {\n messenger: AiDigestControllerMessenger;\n state?: Partial<AiDigestControllerState>;\n digestService: DigestService;\n};\n\nexport function getDefaultAiDigestControllerState(): AiDigestControllerState {\n return {\n marketInsights: {},\n marketOverview: null,\n };\n}\n\nconst aiDigestControllerMetadata: StateMetadata<AiDigestControllerState> = {\n marketInsights: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n marketOverview: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n};\n\nexport class AiDigestController extends BaseController<\n typeof controllerName,\n AiDigestControllerState,\n AiDigestControllerMessenger\n> {\n readonly #digestService: DigestService;\n\n constructor({ messenger, state, digestService }: AiDigestControllerOptions) {\n super({\n name: controllerName,\n metadata: aiDigestControllerMetadata,\n state: {\n ...getDefaultAiDigestControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#digestService = digestService;\n this.#registerMessageHandlers();\n }\n\n #registerMessageHandlers(): void {\n this.messenger.registerActionHandler(\n `${controllerName}:fetchMarketInsights`,\n this.fetchMarketInsights.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:fetchMarketOverview`,\n this.fetchMarketOverview.bind(this),\n );\n }\n\n /**\n * Fetches market insights for a given asset identifier.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps\n * market symbol (e.g. `ETH`). The service handles choosing the correct API\n * query parameter automatically.\n *\n * @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).\n * @returns The market insights report, or `null` if none exists.\n */\n async fetchMarketInsights(\n assetIdentifier: string,\n ): Promise<MarketInsightsReport | null> {\n if (!assetIdentifier) {\n throw new Error(AiDigestControllerErrorMessage.INVALID_ASSET_IDENTIFIER);\n }\n\n const existing = this.state.marketInsights[assetIdentifier];\n if (existing) {\n const age = Date.now() - existing.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existing.data;\n }\n }\n\n const data = await this.#digestService.searchDigest(assetIdentifier);\n\n if (data === null) {\n // No insights available for this asset — clear any stale cache entry\n this.update((state) => {\n delete state.marketInsights[assetIdentifier];\n });\n return null;\n }\n\n const entry: MarketInsightsEntry = {\n assetIdentifier,\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketInsights[assetIdentifier] = entry;\n this.#evictStaleCachedEntries(state.marketInsights);\n });\n\n return data;\n }\n\n /**\n * Fetches the market overview report.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * @returns The market overview report, or `null` if none exists.\n */\n async fetchMarketOverview(): Promise<MarketOverview | null> {\n const existing = this.state.marketOverview;\n if (existing) {\n const age = Date.now() - existing.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existing.data;\n }\n }\n\n const data = await this.#digestService.fetchMarketOverview();\n\n if (data === null) {\n this.update((state) => {\n state.marketOverview = null;\n });\n return null;\n }\n\n const entry: MarketOverviewEntry = {\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketOverview = entry;\n });\n\n return data;\n }\n\n /**\n * Evicts stale (TTL expired) and oldest entries (FIFO) if cache exceeds max size.\n *\n * @param cache - The cache record to evict entries from.\n */\n #evictStaleCachedEntries<EntryType extends { fetchedAt: number }>(\n cache: Record<string, EntryType>,\n ): void {\n const now = Date.now();\n const entries = Object.entries(cache);\n const keysToDelete: string[] = [];\n const freshEntries: [string, EntryType][] = [];\n\n for (const [key, entry] of entries) {\n if (now - entry.fetchedAt >= CACHE_DURATION_MS) {\n keysToDelete.push(key);\n } else {\n freshEntries.push([key, entry]);\n }\n }\n\n if (freshEntries.length > MAX_CACHE_ENTRIES) {\n freshEntries.sort((a, b) => a[1].fetchedAt - b[1].fetchedAt);\n const entriesToRemove = freshEntries.length - MAX_CACHE_ENTRIES;\n for (let i = 0; i < entriesToRemove; i++) {\n keysToDelete.push(freshEntries[i][0]);\n }\n }\n\n for (const key of keysToDelete) {\n delete cache[key];\n }\n }\n}\n"]}
|
|
@@ -26,13 +26,17 @@ export declare class AiDigestController extends BaseController<typeof controller
|
|
|
26
26
|
#private;
|
|
27
27
|
constructor({ messenger, state, digestService }: AiDigestControllerOptions);
|
|
28
28
|
/**
|
|
29
|
-
* Fetches market insights for a given
|
|
29
|
+
* Fetches market insights for a given asset identifier.
|
|
30
30
|
* Returns cached data if still fresh, otherwise calls the service.
|
|
31
31
|
*
|
|
32
|
-
*
|
|
32
|
+
* Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps
|
|
33
|
+
* market symbol (e.g. `ETH`). The service handles choosing the correct API
|
|
34
|
+
* query parameter automatically.
|
|
35
|
+
*
|
|
36
|
+
* @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).
|
|
33
37
|
* @returns The market insights report, or `null` if none exists.
|
|
34
38
|
*/
|
|
35
|
-
fetchMarketInsights(
|
|
39
|
+
fetchMarketInsights(assetIdentifier: string): Promise<MarketInsightsReport | null>;
|
|
36
40
|
/**
|
|
37
41
|
* Fetches the market overview report.
|
|
38
42
|
* Returns cached data if still fresh, otherwise calls the service.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiDigestController.d.cts","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,0BAA0B,EAC1B,wBAAwB,EACzB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;
|
|
1
|
+
{"version":3,"file":"AiDigestController.d.cts","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,0BAA0B,EAC1B,wBAAwB,EACzB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,EAEL,cAAc,EAGf,kCAA8B;AAC/B,OAAO,KAAK,EACV,uBAAuB,EACvB,aAAa,EACb,oBAAoB,EAEpB,cAAc,EAEf,8BAA0B;AAE3B,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,sBAAsB,CAAC;IACrD,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,sBAAsB,CAAC;IACrD,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,2CAA2C,GAC3C,2CAA2C,GAC3C,gCAAgC,CAAC;AAErC,MAAM,MAAM,kCAAkC,GAAG,0BAA0B,CACzE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,kCAAkC,CAAC;AAE1E,MAAM,MAAM,2BAA2B,GAAG,SAAS,CACjD,OAAO,cAAc,EACrB,yBAAyB,EACzB,wBAAwB,CACzB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,2BAA2B,CAAC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACzC,aAAa,EAAE,aAAa,CAAC;CAC9B,CAAC;AAEF,wBAAgB,iCAAiC,IAAI,uBAAuB,CAK3E;AAiBD,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;gBAGa,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,yBAAyB;IA0B1E;;;;;;;;;;OAUG;IACG,mBAAmB,CACvB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAqCvC;;;;;OAKG;IACG,mBAAmB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CA+D5D"}
|
|
@@ -26,13 +26,17 @@ export declare class AiDigestController extends BaseController<typeof controller
|
|
|
26
26
|
#private;
|
|
27
27
|
constructor({ messenger, state, digestService }: AiDigestControllerOptions);
|
|
28
28
|
/**
|
|
29
|
-
* Fetches market insights for a given
|
|
29
|
+
* Fetches market insights for a given asset identifier.
|
|
30
30
|
* Returns cached data if still fresh, otherwise calls the service.
|
|
31
31
|
*
|
|
32
|
-
*
|
|
32
|
+
* Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps
|
|
33
|
+
* market symbol (e.g. `ETH`). The service handles choosing the correct API
|
|
34
|
+
* query parameter automatically.
|
|
35
|
+
*
|
|
36
|
+
* @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).
|
|
33
37
|
* @returns The market insights report, or `null` if none exists.
|
|
34
38
|
*/
|
|
35
|
-
fetchMarketInsights(
|
|
39
|
+
fetchMarketInsights(assetIdentifier: string): Promise<MarketInsightsReport | null>;
|
|
36
40
|
/**
|
|
37
41
|
* Fetches the market overview report.
|
|
38
42
|
* Returns cached data if still fresh, otherwise calls the service.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiDigestController.d.mts","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,0BAA0B,EAC1B,wBAAwB,EACzB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;
|
|
1
|
+
{"version":3,"file":"AiDigestController.d.mts","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,0BAA0B,EAC1B,wBAAwB,EACzB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,EAEL,cAAc,EAGf,kCAA8B;AAC/B,OAAO,KAAK,EACV,uBAAuB,EACvB,aAAa,EACb,oBAAoB,EAEpB,cAAc,EAEf,8BAA0B;AAE3B,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,sBAAsB,CAAC;IACrD,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,sBAAsB,CAAC;IACrD,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,2CAA2C,GAC3C,2CAA2C,GAC3C,gCAAgC,CAAC;AAErC,MAAM,MAAM,kCAAkC,GAAG,0BAA0B,CACzE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,kCAAkC,CAAC;AAE1E,MAAM,MAAM,2BAA2B,GAAG,SAAS,CACjD,OAAO,cAAc,EACrB,yBAAyB,EACzB,wBAAwB,CACzB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,2BAA2B,CAAC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACzC,aAAa,EAAE,aAAa,CAAC;CAC9B,CAAC;AAEF,wBAAgB,iCAAiC,IAAI,uBAAuB,CAK3E;AAiBD,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;gBAGa,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,yBAAyB;IA0B1E;;;;;;;;;;OAUG;IACG,mBAAmB,CACvB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAqCvC;;;;;OAKG;IACG,mBAAmB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CA+D5D"}
|
|
@@ -11,7 +11,6 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
11
11
|
};
|
|
12
12
|
var _AiDigestController_instances, _AiDigestController_digestService, _AiDigestController_registerMessageHandlers, _AiDigestController_evictStaleCachedEntries;
|
|
13
13
|
import { BaseController } from "@metamask/base-controller";
|
|
14
|
-
import { isCaipAssetType } from "@metamask/utils";
|
|
15
14
|
import { AiDigestControllerErrorMessage, controllerName, CACHE_DURATION_MS, MAX_CACHE_ENTRIES } from "./ai-digest-constants.mjs";
|
|
16
15
|
export function getDefaultAiDigestControllerState() {
|
|
17
16
|
return {
|
|
@@ -50,38 +49,42 @@ export class AiDigestController extends BaseController {
|
|
|
50
49
|
__classPrivateFieldGet(this, _AiDigestController_instances, "m", _AiDigestController_registerMessageHandlers).call(this);
|
|
51
50
|
}
|
|
52
51
|
/**
|
|
53
|
-
* Fetches market insights for a given
|
|
52
|
+
* Fetches market insights for a given asset identifier.
|
|
54
53
|
* Returns cached data if still fresh, otherwise calls the service.
|
|
55
54
|
*
|
|
56
|
-
*
|
|
55
|
+
* Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps
|
|
56
|
+
* market symbol (e.g. `ETH`). The service handles choosing the correct API
|
|
57
|
+
* query parameter automatically.
|
|
58
|
+
*
|
|
59
|
+
* @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).
|
|
57
60
|
* @returns The market insights report, or `null` if none exists.
|
|
58
61
|
*/
|
|
59
|
-
async fetchMarketInsights(
|
|
60
|
-
if (!
|
|
61
|
-
throw new Error(AiDigestControllerErrorMessage.
|
|
62
|
+
async fetchMarketInsights(assetIdentifier) {
|
|
63
|
+
if (!assetIdentifier) {
|
|
64
|
+
throw new Error(AiDigestControllerErrorMessage.INVALID_ASSET_IDENTIFIER);
|
|
62
65
|
}
|
|
63
|
-
const existing = this.state.marketInsights[
|
|
66
|
+
const existing = this.state.marketInsights[assetIdentifier];
|
|
64
67
|
if (existing) {
|
|
65
68
|
const age = Date.now() - existing.fetchedAt;
|
|
66
69
|
if (age < CACHE_DURATION_MS) {
|
|
67
70
|
return existing.data;
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
|
-
const data = await __classPrivateFieldGet(this, _AiDigestController_digestService, "f").searchDigest(
|
|
73
|
+
const data = await __classPrivateFieldGet(this, _AiDigestController_digestService, "f").searchDigest(assetIdentifier);
|
|
71
74
|
if (data === null) {
|
|
72
75
|
// No insights available for this asset — clear any stale cache entry
|
|
73
76
|
this.update((state) => {
|
|
74
|
-
delete state.marketInsights[
|
|
77
|
+
delete state.marketInsights[assetIdentifier];
|
|
75
78
|
});
|
|
76
79
|
return null;
|
|
77
80
|
}
|
|
78
81
|
const entry = {
|
|
79
|
-
|
|
82
|
+
assetIdentifier,
|
|
80
83
|
fetchedAt: Date.now(),
|
|
81
84
|
data,
|
|
82
85
|
};
|
|
83
86
|
this.update((state) => {
|
|
84
|
-
state.marketInsights[
|
|
87
|
+
state.marketInsights[assetIdentifier] = entry;
|
|
85
88
|
__classPrivateFieldGet(this, _AiDigestController_instances, "m", _AiDigestController_evictStaleCachedEntries).call(this, state.marketInsights);
|
|
86
89
|
});
|
|
87
90
|
return data;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiDigestController.mjs","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n StateMetadata,\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport { isCaipAssetType } from '@metamask/utils';\n\nimport {\n AiDigestControllerErrorMessage,\n controllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n} from './ai-digest-constants';\nimport type {\n AiDigestControllerState,\n DigestService,\n MarketInsightsReport,\n MarketInsightsEntry,\n MarketOverview,\n MarketOverviewEntry,\n} from './ai-digest-types';\n\nexport type AiDigestControllerFetchMarketInsightsAction = {\n type: `${typeof controllerName}:fetchMarketInsights`;\n handler: AiDigestController['fetchMarketInsights'];\n};\n\nexport type AiDigestControllerFetchMarketOverviewAction = {\n type: `${typeof controllerName}:fetchMarketOverview`;\n handler: AiDigestController['fetchMarketOverview'];\n};\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerFetchMarketInsightsAction\n | AiDigestControllerFetchMarketOverviewAction\n | AiDigestControllerGetStateAction;\n\nexport type AiDigestControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerEvents = AiDigestControllerStateChangeEvent;\n\nexport type AiDigestControllerMessenger = Messenger<\n typeof controllerName,\n AiDigestControllerActions,\n AiDigestControllerEvents\n>;\n\nexport type AiDigestControllerOptions = {\n messenger: AiDigestControllerMessenger;\n state?: Partial<AiDigestControllerState>;\n digestService: DigestService;\n};\n\nexport function getDefaultAiDigestControllerState(): AiDigestControllerState {\n return {\n marketInsights: {},\n marketOverview: null,\n };\n}\n\nconst aiDigestControllerMetadata: StateMetadata<AiDigestControllerState> = {\n marketInsights: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n marketOverview: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n};\n\nexport class AiDigestController extends BaseController<\n typeof controllerName,\n AiDigestControllerState,\n AiDigestControllerMessenger\n> {\n readonly #digestService: DigestService;\n\n constructor({ messenger, state, digestService }: AiDigestControllerOptions) {\n super({\n name: controllerName,\n metadata: aiDigestControllerMetadata,\n state: {\n ...getDefaultAiDigestControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#digestService = digestService;\n this.#registerMessageHandlers();\n }\n\n #registerMessageHandlers(): void {\n this.messenger.registerActionHandler(\n `${controllerName}:fetchMarketInsights`,\n this.fetchMarketInsights.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:fetchMarketOverview`,\n this.fetchMarketOverview.bind(this),\n );\n }\n\n /**\n * Fetches market insights for a given CAIP-19 asset identifier.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * @param caip19Id - The CAIP-19 identifier of the asset.\n * @returns The market insights report, or `null` if none exists.\n */\n async fetchMarketInsights(\n caip19Id: string,\n ): Promise<MarketInsightsReport | null> {\n if (!isCaipAssetType(caip19Id)) {\n throw new Error(AiDigestControllerErrorMessage.INVALID_CAIP_ASSET_TYPE);\n }\n\n const existing = this.state.marketInsights[caip19Id];\n if (existing) {\n const age = Date.now() - existing.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existing.data;\n }\n }\n\n const data = await this.#digestService.searchDigest(caip19Id);\n\n if (data === null) {\n // No insights available for this asset — clear any stale cache entry\n this.update((state) => {\n delete state.marketInsights[caip19Id];\n });\n return null;\n }\n\n const entry: MarketInsightsEntry = {\n caip19Id,\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketInsights[caip19Id] = entry;\n this.#evictStaleCachedEntries(state.marketInsights);\n });\n\n return data;\n }\n\n /**\n * Fetches the market overview report.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * @returns The market overview report, or `null` if none exists.\n */\n async fetchMarketOverview(): Promise<MarketOverview | null> {\n const existing = this.state.marketOverview;\n if (existing) {\n const age = Date.now() - existing.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existing.data;\n }\n }\n\n const data = await this.#digestService.fetchMarketOverview();\n\n if (data === null) {\n this.update((state) => {\n state.marketOverview = null;\n });\n return null;\n }\n\n const entry: MarketOverviewEntry = {\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketOverview = entry;\n });\n\n return data;\n }\n\n /**\n * Evicts stale (TTL expired) and oldest entries (FIFO) if cache exceeds max size.\n *\n * @param cache - The cache record to evict entries from.\n */\n #evictStaleCachedEntries<EntryType extends { fetchedAt: number }>(\n cache: Record<string, EntryType>,\n ): void {\n const now = Date.now();\n const entries = Object.entries(cache);\n const keysToDelete: string[] = [];\n const freshEntries: [string, EntryType][] = [];\n\n for (const [key, entry] of entries) {\n if (now - entry.fetchedAt >= CACHE_DURATION_MS) {\n keysToDelete.push(key);\n } else {\n freshEntries.push([key, entry]);\n }\n }\n\n if (freshEntries.length > MAX_CACHE_ENTRIES) {\n freshEntries.sort((a, b) => a[1].fetchedAt - b[1].fetchedAt);\n const entriesToRemove = freshEntries.length - MAX_CACHE_ENTRIES;\n for (let i = 0; i < entriesToRemove; i++) {\n keysToDelete.push(freshEntries[i][0]);\n }\n }\n\n for (const key of keysToDelete) {\n delete cache[key];\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AiDigestController.mjs","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n StateMetadata,\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport {\n AiDigestControllerErrorMessage,\n controllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n} from './ai-digest-constants';\nimport type {\n AiDigestControllerState,\n DigestService,\n MarketInsightsReport,\n MarketInsightsEntry,\n MarketOverview,\n MarketOverviewEntry,\n} from './ai-digest-types';\n\nexport type AiDigestControllerFetchMarketInsightsAction = {\n type: `${typeof controllerName}:fetchMarketInsights`;\n handler: AiDigestController['fetchMarketInsights'];\n};\n\nexport type AiDigestControllerFetchMarketOverviewAction = {\n type: `${typeof controllerName}:fetchMarketOverview`;\n handler: AiDigestController['fetchMarketOverview'];\n};\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerFetchMarketInsightsAction\n | AiDigestControllerFetchMarketOverviewAction\n | AiDigestControllerGetStateAction;\n\nexport type AiDigestControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerEvents = AiDigestControllerStateChangeEvent;\n\nexport type AiDigestControllerMessenger = Messenger<\n typeof controllerName,\n AiDigestControllerActions,\n AiDigestControllerEvents\n>;\n\nexport type AiDigestControllerOptions = {\n messenger: AiDigestControllerMessenger;\n state?: Partial<AiDigestControllerState>;\n digestService: DigestService;\n};\n\nexport function getDefaultAiDigestControllerState(): AiDigestControllerState {\n return {\n marketInsights: {},\n marketOverview: null,\n };\n}\n\nconst aiDigestControllerMetadata: StateMetadata<AiDigestControllerState> = {\n marketInsights: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n marketOverview: {\n persist: true,\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n usedInUi: true,\n },\n};\n\nexport class AiDigestController extends BaseController<\n typeof controllerName,\n AiDigestControllerState,\n AiDigestControllerMessenger\n> {\n readonly #digestService: DigestService;\n\n constructor({ messenger, state, digestService }: AiDigestControllerOptions) {\n super({\n name: controllerName,\n metadata: aiDigestControllerMetadata,\n state: {\n ...getDefaultAiDigestControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#digestService = digestService;\n this.#registerMessageHandlers();\n }\n\n #registerMessageHandlers(): void {\n this.messenger.registerActionHandler(\n `${controllerName}:fetchMarketInsights`,\n this.fetchMarketInsights.bind(this),\n );\n this.messenger.registerActionHandler(\n `${controllerName}:fetchMarketOverview`,\n this.fetchMarketOverview.bind(this),\n );\n }\n\n /**\n * Fetches market insights for a given asset identifier.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps\n * market symbol (e.g. `ETH`). The service handles choosing the correct API\n * query parameter automatically.\n *\n * @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).\n * @returns The market insights report, or `null` if none exists.\n */\n async fetchMarketInsights(\n assetIdentifier: string,\n ): Promise<MarketInsightsReport | null> {\n if (!assetIdentifier) {\n throw new Error(AiDigestControllerErrorMessage.INVALID_ASSET_IDENTIFIER);\n }\n\n const existing = this.state.marketInsights[assetIdentifier];\n if (existing) {\n const age = Date.now() - existing.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existing.data;\n }\n }\n\n const data = await this.#digestService.searchDigest(assetIdentifier);\n\n if (data === null) {\n // No insights available for this asset — clear any stale cache entry\n this.update((state) => {\n delete state.marketInsights[assetIdentifier];\n });\n return null;\n }\n\n const entry: MarketInsightsEntry = {\n assetIdentifier,\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketInsights[assetIdentifier] = entry;\n this.#evictStaleCachedEntries(state.marketInsights);\n });\n\n return data;\n }\n\n /**\n * Fetches the market overview report.\n * Returns cached data if still fresh, otherwise calls the service.\n *\n * @returns The market overview report, or `null` if none exists.\n */\n async fetchMarketOverview(): Promise<MarketOverview | null> {\n const existing = this.state.marketOverview;\n if (existing) {\n const age = Date.now() - existing.fetchedAt;\n if (age < CACHE_DURATION_MS) {\n return existing.data;\n }\n }\n\n const data = await this.#digestService.fetchMarketOverview();\n\n if (data === null) {\n this.update((state) => {\n state.marketOverview = null;\n });\n return null;\n }\n\n const entry: MarketOverviewEntry = {\n fetchedAt: Date.now(),\n data,\n };\n\n this.update((state) => {\n state.marketOverview = entry;\n });\n\n return data;\n }\n\n /**\n * Evicts stale (TTL expired) and oldest entries (FIFO) if cache exceeds max size.\n *\n * @param cache - The cache record to evict entries from.\n */\n #evictStaleCachedEntries<EntryType extends { fetchedAt: number }>(\n cache: Record<string, EntryType>,\n ): void {\n const now = Date.now();\n const entries = Object.entries(cache);\n const keysToDelete: string[] = [];\n const freshEntries: [string, EntryType][] = [];\n\n for (const [key, entry] of entries) {\n if (now - entry.fetchedAt >= CACHE_DURATION_MS) {\n keysToDelete.push(key);\n } else {\n freshEntries.push([key, entry]);\n }\n }\n\n if (freshEntries.length > MAX_CACHE_ENTRIES) {\n freshEntries.sort((a, b) => a[1].fetchedAt - b[1].fetchedAt);\n const entriesToRemove = freshEntries.length - MAX_CACHE_ENTRIES;\n for (let i = 0; i < entriesToRemove; i++) {\n keysToDelete.push(freshEntries[i][0]);\n }\n }\n\n for (const key of keysToDelete) {\n delete cache[key];\n }\n }\n}\n"]}
|
package/dist/AiDigestService.cjs
CHANGED
|
@@ -14,6 +14,7 @@ var _AiDigestService_baseUrl;
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.AiDigestService = void 0;
|
|
16
16
|
const superstruct_1 = require("@metamask/superstruct");
|
|
17
|
+
const utils_1 = require("@metamask/utils");
|
|
17
18
|
const ai_digest_constants_1 = require("./ai-digest-constants.cjs");
|
|
18
19
|
// Shared sub-type structs
|
|
19
20
|
const ArticleStruct = (0, superstruct_1.type)({
|
|
@@ -122,15 +123,21 @@ class AiDigestService {
|
|
|
122
123
|
return body;
|
|
123
124
|
}
|
|
124
125
|
/**
|
|
125
|
-
* Search for market insights by
|
|
126
|
+
* Search for market insights by asset identifier.
|
|
126
127
|
*
|
|
127
|
-
*
|
|
128
|
+
* Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps
|
|
129
|
+
* market symbol (e.g. `ETH`). The query parameter is chosen automatically:
|
|
130
|
+
* - CAIP-19 identifiers use `caipAssetType`
|
|
131
|
+
* - Perps market symbols use `hlPerpsMarket`
|
|
128
132
|
*
|
|
129
|
-
* @param
|
|
133
|
+
* @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).
|
|
130
134
|
* @returns The market insights report, or `null` if none exists (404).
|
|
131
135
|
*/
|
|
132
|
-
async searchDigest(
|
|
133
|
-
const
|
|
136
|
+
async searchDigest(assetIdentifier) {
|
|
137
|
+
const queryParam = (0, utils_1.isCaipAssetType)(assetIdentifier)
|
|
138
|
+
? `caipAssetType=${encodeURIComponent(assetIdentifier)}`
|
|
139
|
+
: `hlPerpsMarket=${encodeURIComponent(assetIdentifier)}`;
|
|
140
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _AiDigestService_baseUrl, "f")}/asset-summary?${queryParam}`);
|
|
134
141
|
if (response.status === 404) {
|
|
135
142
|
return null;
|
|
136
143
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiDigestService.cjs","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,uDAO+B;
|
|
1
|
+
{"version":3,"file":"AiDigestService.cjs","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n array,\n enums,\n is,\n optional,\n string,\n type as structType,\n} from '@metamask/superstruct';\nimport { isCaipAssetType } from '@metamask/utils';\n\nimport { AiDigestControllerErrorMessage } from './ai-digest-constants';\nimport type {\n DigestService,\n MarketInsightsReport,\n MarketOverview,\n} from './ai-digest-types';\n\nexport type AiDigestServiceConfig = {\n baseUrl: string;\n};\n\n// Shared sub-type structs\n\nconst ArticleStruct = structType({\n title: string(),\n url: string(),\n source: string(),\n date: string(),\n});\n\nconst TweetStruct = structType({\n contentSummary: string(),\n url: string(),\n author: string(),\n date: string(),\n});\n\nconst SourceStruct = structType({\n name: string(),\n url: string(),\n type: enums(['news', 'data', 'social'] as const),\n});\n\nconst AIResponseMetadataStruct = structType({\n provider: string(),\n});\n\nconst trendCategoryValues = [\n 'geopolitical',\n 'macro',\n 'regulatory',\n 'technical',\n 'social',\n 'other',\n] as const;\n\nconst trendImpactValues = ['positive', 'negative', 'neutral'] as const;\n\n// Market Insights structs\n\nconst MarketInsightsTrendStruct = structType({\n title: string(),\n description: string(),\n category: enums(trendCategoryValues),\n impact: enums(trendImpactValues),\n articles: array(ArticleStruct),\n tweets: array(TweetStruct),\n});\n\nconst MarketInsightsReportStruct = structType({\n version: optional(string()),\n asset: string(),\n generatedAt: string(),\n headline: string(),\n summary: string(),\n trends: array(MarketInsightsTrendStruct),\n social: optional(array(TweetStruct)),\n sources: array(SourceStruct),\n metadata: optional(array(AIResponseMetadataStruct)),\n});\n\nconst MarketInsightsDigestEnvelopeStruct = structType({\n digest: MarketInsightsReportStruct,\n});\n\n// Market Overview structs\n\nconst MarketOverviewTrendStruct = structType({\n title: string(),\n description: string(),\n category: enums(trendCategoryValues),\n impact: enums(trendImpactValues),\n articles: array(ArticleStruct),\n relatedAssets: array(string()),\n});\n\nconst MarketOverviewStruct = structType({\n version: optional(string()),\n generatedAt: string(),\n headline: string(),\n summary: string(),\n trends: array(MarketOverviewTrendStruct),\n sources: array(SourceStruct),\n metadata: optional(array(AIResponseMetadataStruct)),\n});\n\nconst getNormalizedMarketInsightsReport = (\n value: unknown,\n): MarketInsightsReport | null => {\n if (is(value, MarketInsightsReportStruct)) {\n return value;\n }\n\n if (is(value, MarketInsightsDigestEnvelopeStruct)) {\n return value.digest;\n }\n\n return null;\n};\n\nexport class AiDigestService implements DigestService {\n readonly #baseUrl: string;\n\n constructor(config: AiDigestServiceConfig) {\n this.#baseUrl = config.baseUrl;\n }\n\n /**\n * Fetch the market overview report.\n *\n * Calls `GET ${this.#baseUrl}/market-overview`.\n *\n * @returns The market overview report, or `null` if none exists (404).\n */\n async fetchMarketOverview(): Promise<MarketOverview | null> {\n const response = await fetch(`${this.#baseUrl}/market-overview`);\n\n if (response.status === 404) {\n return null;\n }\n\n if (!response.ok) {\n throw new Error(\n `${AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`,\n );\n }\n\n const body: unknown = await response.json();\n\n if (!is(body, MarketOverviewStruct)) {\n throw new Error(AiDigestControllerErrorMessage.API_INVALID_RESPONSE);\n }\n\n return body;\n }\n\n /**\n * Search for market insights by asset identifier.\n *\n * Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps\n * market symbol (e.g. `ETH`). The query parameter is chosen automatically:\n * - CAIP-19 identifiers use `caipAssetType`\n * - Perps market symbols use `hlPerpsMarket`\n *\n * @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).\n * @returns The market insights report, or `null` if none exists (404).\n */\n async searchDigest(\n assetIdentifier: string,\n ): Promise<MarketInsightsReport | null> {\n const queryParam = isCaipAssetType(assetIdentifier)\n ? `caipAssetType=${encodeURIComponent(assetIdentifier)}`\n : `hlPerpsMarket=${encodeURIComponent(assetIdentifier)}`;\n\n const response = await fetch(\n `${this.#baseUrl}/asset-summary?${queryParam}`,\n );\n\n if (response.status === 404) {\n return null;\n }\n\n if (!response.ok) {\n throw new Error(\n `${AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`,\n );\n }\n\n const report = getNormalizedMarketInsightsReport(await response.json());\n\n if (!report) {\n throw new Error(AiDigestControllerErrorMessage.API_INVALID_RESPONSE);\n }\n\n return report;\n }\n}\n"]}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { CaipAssetType } from "@metamask/utils";
|
|
2
1
|
import type { DigestService, MarketInsightsReport, MarketOverview } from "./ai-digest-types.cjs";
|
|
3
2
|
export type AiDigestServiceConfig = {
|
|
4
3
|
baseUrl: string;
|
|
@@ -15,13 +14,16 @@ export declare class AiDigestService implements DigestService {
|
|
|
15
14
|
*/
|
|
16
15
|
fetchMarketOverview(): Promise<MarketOverview | null>;
|
|
17
16
|
/**
|
|
18
|
-
* Search for market insights by
|
|
17
|
+
* Search for market insights by asset identifier.
|
|
19
18
|
*
|
|
20
|
-
*
|
|
19
|
+
* Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps
|
|
20
|
+
* market symbol (e.g. `ETH`). The query parameter is chosen automatically:
|
|
21
|
+
* - CAIP-19 identifiers use `caipAssetType`
|
|
22
|
+
* - Perps market symbols use `hlPerpsMarket`
|
|
21
23
|
*
|
|
22
|
-
* @param
|
|
24
|
+
* @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).
|
|
23
25
|
* @returns The market insights report, or `null` if none exists (404).
|
|
24
26
|
*/
|
|
25
|
-
searchDigest(
|
|
27
|
+
searchDigest(assetIdentifier: string): Promise<MarketInsightsReport | null>;
|
|
26
28
|
}
|
|
27
29
|
//# sourceMappingURL=AiDigestService.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiDigestService.d.cts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AiDigestService.d.cts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,cAAc,EACf,8BAA0B;AAE3B,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAqGF,qBAAa,eAAgB,YAAW,aAAa;;gBAGvC,MAAM,EAAE,qBAAqB;IAIzC;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAsB3D;;;;;;;;;;OAUG;IACG,YAAY,CAChB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;CA2BxC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { CaipAssetType } from "@metamask/utils";
|
|
2
1
|
import type { DigestService, MarketInsightsReport, MarketOverview } from "./ai-digest-types.mjs";
|
|
3
2
|
export type AiDigestServiceConfig = {
|
|
4
3
|
baseUrl: string;
|
|
@@ -15,13 +14,16 @@ export declare class AiDigestService implements DigestService {
|
|
|
15
14
|
*/
|
|
16
15
|
fetchMarketOverview(): Promise<MarketOverview | null>;
|
|
17
16
|
/**
|
|
18
|
-
* Search for market insights by
|
|
17
|
+
* Search for market insights by asset identifier.
|
|
19
18
|
*
|
|
20
|
-
*
|
|
19
|
+
* Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps
|
|
20
|
+
* market symbol (e.g. `ETH`). The query parameter is chosen automatically:
|
|
21
|
+
* - CAIP-19 identifiers use `caipAssetType`
|
|
22
|
+
* - Perps market symbols use `hlPerpsMarket`
|
|
21
23
|
*
|
|
22
|
-
* @param
|
|
24
|
+
* @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).
|
|
23
25
|
* @returns The market insights report, or `null` if none exists (404).
|
|
24
26
|
*/
|
|
25
|
-
searchDigest(
|
|
27
|
+
searchDigest(assetIdentifier: string): Promise<MarketInsightsReport | null>;
|
|
26
28
|
}
|
|
27
29
|
//# sourceMappingURL=AiDigestService.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiDigestService.d.mts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AiDigestService.d.mts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,cAAc,EACf,8BAA0B;AAE3B,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAqGF,qBAAa,eAAgB,YAAW,aAAa;;gBAGvC,MAAM,EAAE,qBAAqB;IAIzC;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAsB3D;;;;;;;;;;OAUG;IACG,YAAY,CAChB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;CA2BxC"}
|
package/dist/AiDigestService.mjs
CHANGED
|
@@ -11,6 +11,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
11
11
|
};
|
|
12
12
|
var _AiDigestService_baseUrl;
|
|
13
13
|
import { array, enums, is, optional, string, type as structType } from "@metamask/superstruct";
|
|
14
|
+
import { isCaipAssetType } from "@metamask/utils";
|
|
14
15
|
import { AiDigestControllerErrorMessage } from "./ai-digest-constants.mjs";
|
|
15
16
|
// Shared sub-type structs
|
|
16
17
|
const ArticleStruct = structType({
|
|
@@ -119,15 +120,21 @@ export class AiDigestService {
|
|
|
119
120
|
return body;
|
|
120
121
|
}
|
|
121
122
|
/**
|
|
122
|
-
* Search for market insights by
|
|
123
|
+
* Search for market insights by asset identifier.
|
|
123
124
|
*
|
|
124
|
-
*
|
|
125
|
+
* Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps
|
|
126
|
+
* market symbol (e.g. `ETH`). The query parameter is chosen automatically:
|
|
127
|
+
* - CAIP-19 identifiers use `caipAssetType`
|
|
128
|
+
* - Perps market symbols use `hlPerpsMarket`
|
|
125
129
|
*
|
|
126
|
-
* @param
|
|
130
|
+
* @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).
|
|
127
131
|
* @returns The market insights report, or `null` if none exists (404).
|
|
128
132
|
*/
|
|
129
|
-
async searchDigest(
|
|
130
|
-
const
|
|
133
|
+
async searchDigest(assetIdentifier) {
|
|
134
|
+
const queryParam = isCaipAssetType(assetIdentifier)
|
|
135
|
+
? `caipAssetType=${encodeURIComponent(assetIdentifier)}`
|
|
136
|
+
: `hlPerpsMarket=${encodeURIComponent(assetIdentifier)}`;
|
|
137
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _AiDigestService_baseUrl, "f")}/asset-summary?${queryParam}`);
|
|
131
138
|
if (response.status === 404) {
|
|
132
139
|
return null;
|
|
133
140
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiDigestService.mjs","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EACL,KAAK,EACL,KAAK,EACL,EAAE,EACF,QAAQ,EACR,MAAM,EACN,IAAI,IAAI,UAAU,EACnB,8BAA8B;
|
|
1
|
+
{"version":3,"file":"AiDigestService.mjs","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n array,\n enums,\n is,\n optional,\n string,\n type as structType,\n} from '@metamask/superstruct';\nimport { isCaipAssetType } from '@metamask/utils';\n\nimport { AiDigestControllerErrorMessage } from './ai-digest-constants';\nimport type {\n DigestService,\n MarketInsightsReport,\n MarketOverview,\n} from './ai-digest-types';\n\nexport type AiDigestServiceConfig = {\n baseUrl: string;\n};\n\n// Shared sub-type structs\n\nconst ArticleStruct = structType({\n title: string(),\n url: string(),\n source: string(),\n date: string(),\n});\n\nconst TweetStruct = structType({\n contentSummary: string(),\n url: string(),\n author: string(),\n date: string(),\n});\n\nconst SourceStruct = structType({\n name: string(),\n url: string(),\n type: enums(['news', 'data', 'social'] as const),\n});\n\nconst AIResponseMetadataStruct = structType({\n provider: string(),\n});\n\nconst trendCategoryValues = [\n 'geopolitical',\n 'macro',\n 'regulatory',\n 'technical',\n 'social',\n 'other',\n] as const;\n\nconst trendImpactValues = ['positive', 'negative', 'neutral'] as const;\n\n// Market Insights structs\n\nconst MarketInsightsTrendStruct = structType({\n title: string(),\n description: string(),\n category: enums(trendCategoryValues),\n impact: enums(trendImpactValues),\n articles: array(ArticleStruct),\n tweets: array(TweetStruct),\n});\n\nconst MarketInsightsReportStruct = structType({\n version: optional(string()),\n asset: string(),\n generatedAt: string(),\n headline: string(),\n summary: string(),\n trends: array(MarketInsightsTrendStruct),\n social: optional(array(TweetStruct)),\n sources: array(SourceStruct),\n metadata: optional(array(AIResponseMetadataStruct)),\n});\n\nconst MarketInsightsDigestEnvelopeStruct = structType({\n digest: MarketInsightsReportStruct,\n});\n\n// Market Overview structs\n\nconst MarketOverviewTrendStruct = structType({\n title: string(),\n description: string(),\n category: enums(trendCategoryValues),\n impact: enums(trendImpactValues),\n articles: array(ArticleStruct),\n relatedAssets: array(string()),\n});\n\nconst MarketOverviewStruct = structType({\n version: optional(string()),\n generatedAt: string(),\n headline: string(),\n summary: string(),\n trends: array(MarketOverviewTrendStruct),\n sources: array(SourceStruct),\n metadata: optional(array(AIResponseMetadataStruct)),\n});\n\nconst getNormalizedMarketInsightsReport = (\n value: unknown,\n): MarketInsightsReport | null => {\n if (is(value, MarketInsightsReportStruct)) {\n return value;\n }\n\n if (is(value, MarketInsightsDigestEnvelopeStruct)) {\n return value.digest;\n }\n\n return null;\n};\n\nexport class AiDigestService implements DigestService {\n readonly #baseUrl: string;\n\n constructor(config: AiDigestServiceConfig) {\n this.#baseUrl = config.baseUrl;\n }\n\n /**\n * Fetch the market overview report.\n *\n * Calls `GET ${this.#baseUrl}/market-overview`.\n *\n * @returns The market overview report, or `null` if none exists (404).\n */\n async fetchMarketOverview(): Promise<MarketOverview | null> {\n const response = await fetch(`${this.#baseUrl}/market-overview`);\n\n if (response.status === 404) {\n return null;\n }\n\n if (!response.ok) {\n throw new Error(\n `${AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`,\n );\n }\n\n const body: unknown = await response.json();\n\n if (!is(body, MarketOverviewStruct)) {\n throw new Error(AiDigestControllerErrorMessage.API_INVALID_RESPONSE);\n }\n\n return body;\n }\n\n /**\n * Search for market insights by asset identifier.\n *\n * Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps\n * market symbol (e.g. `ETH`). The query parameter is chosen automatically:\n * - CAIP-19 identifiers use `caipAssetType`\n * - Perps market symbols use `hlPerpsMarket`\n *\n * @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).\n * @returns The market insights report, or `null` if none exists (404).\n */\n async searchDigest(\n assetIdentifier: string,\n ): Promise<MarketInsightsReport | null> {\n const queryParam = isCaipAssetType(assetIdentifier)\n ? `caipAssetType=${encodeURIComponent(assetIdentifier)}`\n : `hlPerpsMarket=${encodeURIComponent(assetIdentifier)}`;\n\n const response = await fetch(\n `${this.#baseUrl}/asset-summary?${queryParam}`,\n );\n\n if (response.status === 404) {\n return null;\n }\n\n if (!response.ok) {\n throw new Error(\n `${AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`,\n );\n }\n\n const report = getNormalizedMarketInsightsReport(await response.json());\n\n if (!report) {\n throw new Error(AiDigestControllerErrorMessage.API_INVALID_RESPONSE);\n }\n\n return report;\n }\n}\n"]}
|
|
@@ -7,6 +7,6 @@ exports.MAX_CACHE_ENTRIES = 50;
|
|
|
7
7
|
exports.AiDigestControllerErrorMessage = {
|
|
8
8
|
API_REQUEST_FAILED: 'API request failed',
|
|
9
9
|
API_INVALID_RESPONSE: 'API returned invalid response',
|
|
10
|
-
|
|
10
|
+
INVALID_ASSET_IDENTIFIER: 'Invalid asset identifier',
|
|
11
11
|
};
|
|
12
12
|
//# sourceMappingURL=ai-digest-constants.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-digest-constants.cjs","sourceRoot":"","sources":["../src/ai-digest-constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG,oBAAoB,CAAC;AAEtC,QAAA,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAEjD,QAAA,iBAAiB,GAAG,EAAE,CAAC;AAEvB,QAAA,8BAA8B,GAAG;IAC5C,kBAAkB,EAAE,oBAAoB;IACxC,oBAAoB,EAAE,+BAA+B;IACrD,
|
|
1
|
+
{"version":3,"file":"ai-digest-constants.cjs","sourceRoot":"","sources":["../src/ai-digest-constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG,oBAAoB,CAAC;AAEtC,QAAA,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAEjD,QAAA,iBAAiB,GAAG,EAAE,CAAC;AAEvB,QAAA,8BAA8B,GAAG;IAC5C,kBAAkB,EAAE,oBAAoB;IACxC,oBAAoB,EAAE,+BAA+B;IACrD,wBAAwB,EAAE,0BAA0B;CAC5C,CAAC","sourcesContent":["export const controllerName = 'AiDigestController';\n\nexport const CACHE_DURATION_MS = 10 * 60 * 1000; // 10 minutes\n\nexport const MAX_CACHE_ENTRIES = 50;\n\nexport const AiDigestControllerErrorMessage = {\n API_REQUEST_FAILED: 'API request failed',\n API_INVALID_RESPONSE: 'API returned invalid response',\n INVALID_ASSET_IDENTIFIER: 'Invalid asset identifier',\n} as const;\n"]}
|
|
@@ -4,6 +4,6 @@ export declare const MAX_CACHE_ENTRIES = 50;
|
|
|
4
4
|
export declare const AiDigestControllerErrorMessage: {
|
|
5
5
|
readonly API_REQUEST_FAILED: "API request failed";
|
|
6
6
|
readonly API_INVALID_RESPONSE: "API returned invalid response";
|
|
7
|
-
readonly
|
|
7
|
+
readonly INVALID_ASSET_IDENTIFIER: "Invalid asset identifier";
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=ai-digest-constants.d.cts.map
|
|
@@ -4,6 +4,6 @@ export declare const MAX_CACHE_ENTRIES = 50;
|
|
|
4
4
|
export declare const AiDigestControllerErrorMessage: {
|
|
5
5
|
readonly API_REQUEST_FAILED: "API request failed";
|
|
6
6
|
readonly API_INVALID_RESPONSE: "API returned invalid response";
|
|
7
|
-
readonly
|
|
7
|
+
readonly INVALID_ASSET_IDENTIFIER: "Invalid asset identifier";
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=ai-digest-constants.d.mts.map
|
|
@@ -4,6 +4,6 @@ export const MAX_CACHE_ENTRIES = 50;
|
|
|
4
4
|
export const AiDigestControllerErrorMessage = {
|
|
5
5
|
API_REQUEST_FAILED: 'API request failed',
|
|
6
6
|
API_INVALID_RESPONSE: 'API returned invalid response',
|
|
7
|
-
|
|
7
|
+
INVALID_ASSET_IDENTIFIER: 'Invalid asset identifier',
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=ai-digest-constants.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-digest-constants.mjs","sourceRoot":"","sources":["../src/ai-digest-constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAEnD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAE9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,kBAAkB,EAAE,oBAAoB;IACxC,oBAAoB,EAAE,+BAA+B;IACrD,
|
|
1
|
+
{"version":3,"file":"ai-digest-constants.mjs","sourceRoot":"","sources":["../src/ai-digest-constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAEnD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAE9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,kBAAkB,EAAE,oBAAoB;IACxC,oBAAoB,EAAE,+BAA+B;IACrD,wBAAwB,EAAE,0BAA0B;CAC5C,CAAC","sourcesContent":["export const controllerName = 'AiDigestController';\n\nexport const CACHE_DURATION_MS = 10 * 60 * 1000; // 10 minutes\n\nexport const MAX_CACHE_ENTRIES = 50;\n\nexport const AiDigestControllerErrorMessage = {\n API_REQUEST_FAILED: 'API request failed',\n API_INVALID_RESPONSE: 'API returned invalid response',\n INVALID_ASSET_IDENTIFIER: 'Invalid asset identifier',\n} as const;\n"]}
|
package/dist/ai-digest-types.cjs
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Shared sub-types
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
//# sourceMappingURL=ai-digest-types.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-digest-types.cjs","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"","sourcesContent":["
|
|
1
|
+
{"version":3,"file":"ai-digest-types.cjs","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E","sourcesContent":["// ---------------------------------------------------------------------------\n// Shared sub-types\n// ---------------------------------------------------------------------------\n\n/**\n * A news article referenced by a trend.\n */\nexport type Article = {\n /** Article title */\n title: string;\n /** Full URL to the article */\n url: string;\n /** Source domain name (e.g. \"coindesk.com\") */\n source: string;\n /** ISO date string */\n date: string;\n};\n\n/**\n * A social media post referenced by a trend.\n */\nexport type Tweet = {\n /** Summary of the tweet content */\n contentSummary: string;\n /** Full URL to the tweet */\n url: string;\n /** Author handle (e.g. \"@saylordocs\") */\n author: string;\n /** ISO date string */\n date: string;\n};\n\n/**\n * A data source used to generate a report.\n */\nexport type Source = {\n /** Source name (e.g. \"CoinDesk\") */\n name: string;\n /** Source URL */\n url: string;\n /** Source type */\n type: 'news' | 'data' | 'social';\n};\n\nexport type MarketInsightsArticle = Article;\nexport type MarketInsightsTweet = Tweet;\nexport type MarketInsightsSource = Source;\n\n// ---------------------------------------------------------------------------\n// Market Insights types (asset-specific)\n// ---------------------------------------------------------------------------\n\n/**\n * A key market trend identified in the insights report.\n */\nexport type MarketInsightsTrend = {\n /** Trend title (e.g. \"Institutions Buying the Dip\") */\n title: string;\n /** Detailed description of the trend */\n description: string;\n /** Category of the trend */\n category:\n | 'geopolitical'\n | 'macro'\n | 'regulatory'\n | 'technical'\n | 'social'\n | 'other';\n /** Impact direction */\n impact: 'positive' | 'negative' | 'neutral';\n /** Related news articles */\n articles: Article[];\n /** Related social media posts */\n tweets: Tweet[];\n};\n\n/**\n * AI-generated market insights report for a crypto asset.\n * Returned by `GET /asset-summary?caipAssetType=<caip19Id>` or `GET /asset-summary?hlPerpsMarket=<symbol>`.\n */\nexport type MarketInsightsReport = {\n /** API version */\n version?: string;\n /** Asset symbol (lowercase, e.g. \"btc\") */\n asset: string;\n /** ISO date string when the report was generated */\n generatedAt: string;\n /** Main headline */\n headline: string;\n /** Summary paragraph */\n summary: string;\n /** Key market trends */\n trends: MarketInsightsTrend[];\n /** Optional top-level social posts included by the API */\n social?: Tweet[];\n /** Data sources used to generate the report */\n sources: Source[];\n /** Provider metadata */\n metadata?: AIResponseMetadata[];\n};\n\n/**\n * A cached market insights entry.\n */\nexport type MarketInsightsEntry = {\n /** Asset identifier — either a CAIP-19 ID (e.g. \"eip155:1/slip44:60\") or a perps market symbol (e.g. \"ETH\") */\n assetIdentifier: string;\n /** Timestamp when the entry was fetched */\n fetchedAt: number;\n /** The market insights report data */\n data: MarketInsightsReport;\n};\n\n/**\n * A cached market overview entry.\n */\nexport type MarketOverviewEntry = {\n /** Timestamp when the entry was fetched */\n fetchedAt: number;\n /** The market overview data */\n data: MarketOverview;\n};\n\n// ---------------------------------------------------------------------------\n// Market Overview types (non-asset-specific)\n// ---------------------------------------------------------------------------\n\nexport type MarketOverviewTrend = {\n title: string;\n description: string;\n category:\n | 'geopolitical'\n | 'macro'\n | 'regulatory'\n | 'technical'\n | 'social'\n | 'other';\n impact: 'positive' | 'negative' | 'neutral';\n articles: Article[];\n relatedAssets: string[];\n};\n\n/**\n * Provider metadata included in AI API responses.\n */\nexport type AIResponseMetadata = {\n provider: string;\n};\n\nexport type MarketOverview = {\n version?: string;\n generatedAt: string;\n headline: string;\n summary: string;\n trends: MarketOverviewTrend[];\n sources: Source[];\n metadata?: AIResponseMetadata[];\n};\n\n// ---------------------------------------------------------------------------\n// Controller state\n// ---------------------------------------------------------------------------\n\nexport type AiDigestControllerState = {\n marketInsights: Record<string, MarketInsightsEntry>;\n marketOverview: MarketOverviewEntry | null;\n};\n\n// ---------------------------------------------------------------------------\n// Service interface\n// ---------------------------------------------------------------------------\n\nexport type DigestService = {\n /**\n * Search for market insights by asset identifier.\n *\n * Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps\n * market symbol (e.g. `ETH`). The implementation is responsible for choosing\n * the correct query parameter (`caipAssetType` vs `hlPerpsMarket`).\n *\n * Calls `GET /asset-summary?caipAssetType=<assetIdentifier>` for CAIP-19 IDs,\n * or `GET /asset-summary?hlPerpsMarket=<assetIdentifier>` for perps symbols.\n *\n * @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).\n * @returns The market insights report, or `null` if no insights exist (404).\n */\n searchDigest(assetIdentifier: string): Promise<MarketInsightsReport | null>;\n\n /**\n * Fetch the market overview report.\n * Calls `GET /market-overview`.\n *\n * @returns The market overview report, or `null` if none exists (404).\n */\n fetchMarketOverview(): Promise<MarketOverview | null>;\n};\n"]}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { CaipAssetType } from "@metamask/utils";
|
|
2
1
|
/**
|
|
3
2
|
* A news article referenced by a trend.
|
|
4
3
|
*/
|
|
@@ -58,7 +57,7 @@ export type MarketInsightsTrend = {
|
|
|
58
57
|
};
|
|
59
58
|
/**
|
|
60
59
|
* AI-generated market insights report for a crypto asset.
|
|
61
|
-
* Returned by `GET /
|
|
60
|
+
* Returned by `GET /asset-summary?caipAssetType=<caip19Id>` or `GET /asset-summary?hlPerpsMarket=<symbol>`.
|
|
62
61
|
*/
|
|
63
62
|
export type MarketInsightsReport = {
|
|
64
63
|
/** API version */
|
|
@@ -84,8 +83,8 @@ export type MarketInsightsReport = {
|
|
|
84
83
|
* A cached market insights entry.
|
|
85
84
|
*/
|
|
86
85
|
export type MarketInsightsEntry = {
|
|
87
|
-
/** CAIP-19
|
|
88
|
-
|
|
86
|
+
/** Asset identifier — either a CAIP-19 ID (e.g. "eip155:1/slip44:60") or a perps market symbol (e.g. "ETH") */
|
|
87
|
+
assetIdentifier: string;
|
|
89
88
|
/** Timestamp when the entry was fetched */
|
|
90
89
|
fetchedAt: number;
|
|
91
90
|
/** The market insights report data */
|
|
@@ -129,13 +128,19 @@ export type AiDigestControllerState = {
|
|
|
129
128
|
};
|
|
130
129
|
export type DigestService = {
|
|
131
130
|
/**
|
|
132
|
-
* Search for market insights by
|
|
133
|
-
* Calls `GET /asset-summary?caipAssetType=<caip19Id>`.
|
|
131
|
+
* Search for market insights by asset identifier.
|
|
134
132
|
*
|
|
135
|
-
*
|
|
133
|
+
* Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps
|
|
134
|
+
* market symbol (e.g. `ETH`). The implementation is responsible for choosing
|
|
135
|
+
* the correct query parameter (`caipAssetType` vs `hlPerpsMarket`).
|
|
136
|
+
*
|
|
137
|
+
* Calls `GET /asset-summary?caipAssetType=<assetIdentifier>` for CAIP-19 IDs,
|
|
138
|
+
* or `GET /asset-summary?hlPerpsMarket=<assetIdentifier>` for perps symbols.
|
|
139
|
+
*
|
|
140
|
+
* @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).
|
|
136
141
|
* @returns The market insights report, or `null` if no insights exist (404).
|
|
137
142
|
*/
|
|
138
|
-
searchDigest(
|
|
143
|
+
searchDigest(assetIdentifier: string): Promise<MarketInsightsReport | null>;
|
|
139
144
|
/**
|
|
140
145
|
* Fetch the market overview report.
|
|
141
146
|
* Calls `GET /market-overview`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-digest-types.d.cts","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ai-digest-types.d.cts","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { CaipAssetType } from "@metamask/utils";
|
|
2
1
|
/**
|
|
3
2
|
* A news article referenced by a trend.
|
|
4
3
|
*/
|
|
@@ -58,7 +57,7 @@ export type MarketInsightsTrend = {
|
|
|
58
57
|
};
|
|
59
58
|
/**
|
|
60
59
|
* AI-generated market insights report for a crypto asset.
|
|
61
|
-
* Returned by `GET /
|
|
60
|
+
* Returned by `GET /asset-summary?caipAssetType=<caip19Id>` or `GET /asset-summary?hlPerpsMarket=<symbol>`.
|
|
62
61
|
*/
|
|
63
62
|
export type MarketInsightsReport = {
|
|
64
63
|
/** API version */
|
|
@@ -84,8 +83,8 @@ export type MarketInsightsReport = {
|
|
|
84
83
|
* A cached market insights entry.
|
|
85
84
|
*/
|
|
86
85
|
export type MarketInsightsEntry = {
|
|
87
|
-
/** CAIP-19
|
|
88
|
-
|
|
86
|
+
/** Asset identifier — either a CAIP-19 ID (e.g. "eip155:1/slip44:60") or a perps market symbol (e.g. "ETH") */
|
|
87
|
+
assetIdentifier: string;
|
|
89
88
|
/** Timestamp when the entry was fetched */
|
|
90
89
|
fetchedAt: number;
|
|
91
90
|
/** The market insights report data */
|
|
@@ -129,13 +128,19 @@ export type AiDigestControllerState = {
|
|
|
129
128
|
};
|
|
130
129
|
export type DigestService = {
|
|
131
130
|
/**
|
|
132
|
-
* Search for market insights by
|
|
133
|
-
* Calls `GET /asset-summary?caipAssetType=<caip19Id>`.
|
|
131
|
+
* Search for market insights by asset identifier.
|
|
134
132
|
*
|
|
135
|
-
*
|
|
133
|
+
* Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps
|
|
134
|
+
* market symbol (e.g. `ETH`). The implementation is responsible for choosing
|
|
135
|
+
* the correct query parameter (`caipAssetType` vs `hlPerpsMarket`).
|
|
136
|
+
*
|
|
137
|
+
* Calls `GET /asset-summary?caipAssetType=<assetIdentifier>` for CAIP-19 IDs,
|
|
138
|
+
* or `GET /asset-summary?hlPerpsMarket=<assetIdentifier>` for perps symbols.
|
|
139
|
+
*
|
|
140
|
+
* @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).
|
|
136
141
|
* @returns The market insights report, or `null` if no insights exist (404).
|
|
137
142
|
*/
|
|
138
|
-
searchDigest(
|
|
143
|
+
searchDigest(assetIdentifier: string): Promise<MarketInsightsReport | null>;
|
|
139
144
|
/**
|
|
140
145
|
* Fetch the market overview report.
|
|
141
146
|
* Calls `GET /market-overview`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-digest-types.d.mts","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ai-digest-types.d.mts","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"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"}
|
package/dist/ai-digest-types.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-digest-types.mjs","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"","sourcesContent":["
|
|
1
|
+
{"version":3,"file":"ai-digest-types.mjs","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E","sourcesContent":["// ---------------------------------------------------------------------------\n// Shared sub-types\n// ---------------------------------------------------------------------------\n\n/**\n * A news article referenced by a trend.\n */\nexport type Article = {\n /** Article title */\n title: string;\n /** Full URL to the article */\n url: string;\n /** Source domain name (e.g. \"coindesk.com\") */\n source: string;\n /** ISO date string */\n date: string;\n};\n\n/**\n * A social media post referenced by a trend.\n */\nexport type Tweet = {\n /** Summary of the tweet content */\n contentSummary: string;\n /** Full URL to the tweet */\n url: string;\n /** Author handle (e.g. \"@saylordocs\") */\n author: string;\n /** ISO date string */\n date: string;\n};\n\n/**\n * A data source used to generate a report.\n */\nexport type Source = {\n /** Source name (e.g. \"CoinDesk\") */\n name: string;\n /** Source URL */\n url: string;\n /** Source type */\n type: 'news' | 'data' | 'social';\n};\n\nexport type MarketInsightsArticle = Article;\nexport type MarketInsightsTweet = Tweet;\nexport type MarketInsightsSource = Source;\n\n// ---------------------------------------------------------------------------\n// Market Insights types (asset-specific)\n// ---------------------------------------------------------------------------\n\n/**\n * A key market trend identified in the insights report.\n */\nexport type MarketInsightsTrend = {\n /** Trend title (e.g. \"Institutions Buying the Dip\") */\n title: string;\n /** Detailed description of the trend */\n description: string;\n /** Category of the trend */\n category:\n | 'geopolitical'\n | 'macro'\n | 'regulatory'\n | 'technical'\n | 'social'\n | 'other';\n /** Impact direction */\n impact: 'positive' | 'negative' | 'neutral';\n /** Related news articles */\n articles: Article[];\n /** Related social media posts */\n tweets: Tweet[];\n};\n\n/**\n * AI-generated market insights report for a crypto asset.\n * Returned by `GET /asset-summary?caipAssetType=<caip19Id>` or `GET /asset-summary?hlPerpsMarket=<symbol>`.\n */\nexport type MarketInsightsReport = {\n /** API version */\n version?: string;\n /** Asset symbol (lowercase, e.g. \"btc\") */\n asset: string;\n /** ISO date string when the report was generated */\n generatedAt: string;\n /** Main headline */\n headline: string;\n /** Summary paragraph */\n summary: string;\n /** Key market trends */\n trends: MarketInsightsTrend[];\n /** Optional top-level social posts included by the API */\n social?: Tweet[];\n /** Data sources used to generate the report */\n sources: Source[];\n /** Provider metadata */\n metadata?: AIResponseMetadata[];\n};\n\n/**\n * A cached market insights entry.\n */\nexport type MarketInsightsEntry = {\n /** Asset identifier — either a CAIP-19 ID (e.g. \"eip155:1/slip44:60\") or a perps market symbol (e.g. \"ETH\") */\n assetIdentifier: string;\n /** Timestamp when the entry was fetched */\n fetchedAt: number;\n /** The market insights report data */\n data: MarketInsightsReport;\n};\n\n/**\n * A cached market overview entry.\n */\nexport type MarketOverviewEntry = {\n /** Timestamp when the entry was fetched */\n fetchedAt: number;\n /** The market overview data */\n data: MarketOverview;\n};\n\n// ---------------------------------------------------------------------------\n// Market Overview types (non-asset-specific)\n// ---------------------------------------------------------------------------\n\nexport type MarketOverviewTrend = {\n title: string;\n description: string;\n category:\n | 'geopolitical'\n | 'macro'\n | 'regulatory'\n | 'technical'\n | 'social'\n | 'other';\n impact: 'positive' | 'negative' | 'neutral';\n articles: Article[];\n relatedAssets: string[];\n};\n\n/**\n * Provider metadata included in AI API responses.\n */\nexport type AIResponseMetadata = {\n provider: string;\n};\n\nexport type MarketOverview = {\n version?: string;\n generatedAt: string;\n headline: string;\n summary: string;\n trends: MarketOverviewTrend[];\n sources: Source[];\n metadata?: AIResponseMetadata[];\n};\n\n// ---------------------------------------------------------------------------\n// Controller state\n// ---------------------------------------------------------------------------\n\nexport type AiDigestControllerState = {\n marketInsights: Record<string, MarketInsightsEntry>;\n marketOverview: MarketOverviewEntry | null;\n};\n\n// ---------------------------------------------------------------------------\n// Service interface\n// ---------------------------------------------------------------------------\n\nexport type DigestService = {\n /**\n * Search for market insights by asset identifier.\n *\n * Accepts either a CAIP-19 asset type (e.g. `eip155:1/slip44:60`) or a perps\n * market symbol (e.g. `ETH`). The implementation is responsible for choosing\n * the correct query parameter (`caipAssetType` vs `hlPerpsMarket`).\n *\n * Calls `GET /asset-summary?caipAssetType=<assetIdentifier>` for CAIP-19 IDs,\n * or `GET /asset-summary?hlPerpsMarket=<assetIdentifier>` for perps symbols.\n *\n * @param assetIdentifier - The asset identifier (CAIP-19 ID or perps market symbol).\n * @returns The market insights report, or `null` if no insights exist (404).\n */\n searchDigest(assetIdentifier: string): Promise<MarketInsightsReport | null>;\n\n /**\n * Fetch the market overview report.\n * Calls `GET /market-overview`.\n *\n * @returns The market overview report, or `null` if none exists (404).\n */\n fetchMarketOverview(): Promise<MarketOverview | null>;\n};\n"]}
|