@metamask-previews/ai-controllers 0.7.0-preview-b3fa32653 → 0.8.0-preview-34f2bcbf7

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/dist/AiDigestController-method-action-types.cjs.map +1 -1
  3. package/dist/AiDigestController-method-action-types.d.cts +15 -1
  4. package/dist/AiDigestController-method-action-types.d.cts.map +1 -1
  5. package/dist/AiDigestController-method-action-types.d.mts +15 -1
  6. package/dist/AiDigestController-method-action-types.d.mts.map +1 -1
  7. package/dist/AiDigestController-method-action-types.mjs.map +1 -1
  8. package/dist/AiDigestController.cjs +17 -0
  9. package/dist/AiDigestController.cjs.map +1 -1
  10. package/dist/AiDigestController.d.cts +12 -1
  11. package/dist/AiDigestController.d.cts.map +1 -1
  12. package/dist/AiDigestController.d.mts +12 -1
  13. package/dist/AiDigestController.d.mts.map +1 -1
  14. package/dist/AiDigestController.mjs +17 -0
  15. package/dist/AiDigestController.mjs.map +1 -1
  16. package/dist/AiDigestService.cjs +46 -7
  17. package/dist/AiDigestService.cjs.map +1 -1
  18. package/dist/AiDigestService.d.cts +10 -1
  19. package/dist/AiDigestService.d.cts.map +1 -1
  20. package/dist/AiDigestService.d.mts +10 -1
  21. package/dist/AiDigestService.d.mts.map +1 -1
  22. package/dist/AiDigestService.mjs +46 -7
  23. package/dist/AiDigestService.mjs.map +1 -1
  24. package/dist/ai-digest-constants.cjs +1 -0
  25. package/dist/ai-digest-constants.cjs.map +1 -1
  26. package/dist/ai-digest-constants.d.cts +1 -0
  27. package/dist/ai-digest-constants.d.cts.map +1 -1
  28. package/dist/ai-digest-constants.d.mts +1 -0
  29. package/dist/ai-digest-constants.d.mts.map +1 -1
  30. package/dist/ai-digest-constants.mjs +1 -0
  31. package/dist/ai-digest-constants.mjs.map +1 -1
  32. package/dist/ai-digest-types.cjs.map +1 -1
  33. package/dist/ai-digest-types.d.cts +33 -0
  34. package/dist/ai-digest-types.d.cts.map +1 -1
  35. package/dist/ai-digest-types.d.mts +33 -0
  36. package/dist/ai-digest-types.d.mts.map +1 -1
  37. package/dist/ai-digest-types.mjs.map +1 -1
  38. package/dist/index.cjs.map +1 -1
  39. package/dist/index.d.cts +2 -2
  40. package/dist/index.d.cts.map +1 -1
  41. package/dist/index.d.mts +2 -2
  42. package/dist/index.d.mts.map +1 -1
  43. package/dist/index.mjs.map +1 -1
  44. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.8.0]
11
+
12
+ ### Added
13
+
14
+ - Add `AiDigestController.fetchFrontPageItem(id)` (and the underlying `AiDigestService.fetchFrontPageItem`) which fetches a single market overview "front page" by id from `GET /market-overview/front-page/:id`, exposed via the `AiDigestController:fetchFrontPageItem` messenger action ([#9394](https://github.com/MetaMask/core/pull/9394))
15
+ - Add `MarketOverviewFrontPage` and `MarketOverviewItem` types ([#9394](https://github.com/MetaMask/core/pull/9394))
16
+
10
17
  ### Changed
11
18
 
12
19
  - Bump `@metamask/utils` from `^11.9.0` to `^11.11.0` ([#9074](https://github.com/MetaMask/core/pull/9074))
@@ -112,7 +119,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
112
119
  - Removes `fetchDigest`, `clearDigest`, and `clearAllDigests` actions from the controller action surface.
113
120
  - Removes `DigestData`/`DigestEntry` types and the `digests` state branch.
114
121
 
115
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/ai-controllers@0.7.0...HEAD
122
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/ai-controllers@0.8.0...HEAD
123
+ [0.8.0]: https://github.com/MetaMask/core/compare/@metamask/ai-controllers@0.7.0...@metamask/ai-controllers@0.8.0
116
124
  [0.7.0]: https://github.com/MetaMask/core/compare/@metamask/ai-controllers@0.6.3...@metamask/ai-controllers@0.7.0
117
125
  [0.6.3]: https://github.com/MetaMask/core/compare/@metamask/ai-controllers@0.6.2...@metamask/ai-controllers@0.6.3
118
126
  [0.6.2]: https://github.com/MetaMask/core/compare/@metamask/ai-controllers@0.6.1...@metamask/ai-controllers@0.6.2
@@ -1 +1 @@
1
- {"version":3,"file":"AiDigestController-method-action-types.cjs","sourceRoot":"","sources":["../src/AiDigestController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { AiDigestController } from './AiDigestController';\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 */\nexport type AiDigestControllerFetchMarketInsightsAction = {\n type: `AiDigestController:fetchMarketInsights`;\n handler: AiDigestController['fetchMarketInsights'];\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 */\nexport type AiDigestControllerFetchMarketOverviewAction = {\n type: `AiDigestController:fetchMarketOverview`;\n handler: AiDigestController['fetchMarketOverview'];\n};\n\n/**\n * Union of all AiDigestController action types.\n */\nexport type AiDigestControllerMethodActions =\n | AiDigestControllerFetchMarketInsightsAction\n | AiDigestControllerFetchMarketOverviewAction;\n"]}
1
+ {"version":3,"file":"AiDigestController-method-action-types.cjs","sourceRoot":"","sources":["../src/AiDigestController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { AiDigestController } from './AiDigestController';\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 */\nexport type AiDigestControllerFetchMarketInsightsAction = {\n type: `AiDigestController:fetchMarketInsights`;\n handler: AiDigestController['fetchMarketInsights'];\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 */\nexport type AiDigestControllerFetchMarketOverviewAction = {\n type: `AiDigestController:fetchMarketOverview`;\n handler: AiDigestController['fetchMarketOverview'];\n};\n\n/**\n * Fetches a single market overview front page by id.\n *\n * Unlike the market overview report (which only returns the latest items),\n * this resolves an older item that has since dropped out of the report, so\n * clients can render it directly (e.g. from a deep link).\n *\n * @param id - The front-page identifier (UUID).\n * @returns The market overview front page, or `null` if none exists.\n */\nexport type AiDigestControllerFetchFrontPageItemAction = {\n type: `AiDigestController:fetchFrontPageItem`;\n handler: AiDigestController['fetchFrontPageItem'];\n};\n\n/**\n * Union of all AiDigestController action types.\n */\nexport type AiDigestControllerMethodActions =\n | AiDigestControllerFetchMarketInsightsAction\n | AiDigestControllerFetchMarketOverviewAction\n | AiDigestControllerFetchFrontPageItemAction;\n"]}
@@ -28,8 +28,22 @@ export type AiDigestControllerFetchMarketOverviewAction = {
28
28
  type: `AiDigestController:fetchMarketOverview`;
29
29
  handler: AiDigestController['fetchMarketOverview'];
30
30
  };
31
+ /**
32
+ * Fetches a single market overview front page by id.
33
+ *
34
+ * Unlike the market overview report (which only returns the latest items),
35
+ * this resolves an older item that has since dropped out of the report, so
36
+ * clients can render it directly (e.g. from a deep link).
37
+ *
38
+ * @param id - The front-page identifier (UUID).
39
+ * @returns The market overview front page, or `null` if none exists.
40
+ */
41
+ export type AiDigestControllerFetchFrontPageItemAction = {
42
+ type: `AiDigestController:fetchFrontPageItem`;
43
+ handler: AiDigestController['fetchFrontPageItem'];
44
+ };
31
45
  /**
32
46
  * Union of all AiDigestController action types.
33
47
  */
34
- export type AiDigestControllerMethodActions = AiDigestControllerFetchMarketInsightsAction | AiDigestControllerFetchMarketOverviewAction;
48
+ export type AiDigestControllerMethodActions = AiDigestControllerFetchMarketInsightsAction | AiDigestControllerFetchMarketOverviewAction | AiDigestControllerFetchFrontPageItemAction;
35
49
  //# sourceMappingURL=AiDigestController-method-action-types.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AiDigestController-method-action-types.d.cts","sourceRoot":"","sources":["../src/AiDigestController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,iCAA6B;AAE/D;;;;;;;;;;GAUG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,+BAA+B,GACvC,2CAA2C,GAC3C,2CAA2C,CAAC"}
1
+ {"version":3,"file":"AiDigestController-method-action-types.d.cts","sourceRoot":"","sources":["../src/AiDigestController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,iCAA6B;AAE/D;;;;;;;;;;GAUG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,0CAA0C,GAAG;IACvD,IAAI,EAAE,uCAAuC,CAAC;IAC9C,OAAO,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;CACnD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,+BAA+B,GACvC,2CAA2C,GAC3C,2CAA2C,GAC3C,0CAA0C,CAAC"}
@@ -28,8 +28,22 @@ export type AiDigestControllerFetchMarketOverviewAction = {
28
28
  type: `AiDigestController:fetchMarketOverview`;
29
29
  handler: AiDigestController['fetchMarketOverview'];
30
30
  };
31
+ /**
32
+ * Fetches a single market overview front page by id.
33
+ *
34
+ * Unlike the market overview report (which only returns the latest items),
35
+ * this resolves an older item that has since dropped out of the report, so
36
+ * clients can render it directly (e.g. from a deep link).
37
+ *
38
+ * @param id - The front-page identifier (UUID).
39
+ * @returns The market overview front page, or `null` if none exists.
40
+ */
41
+ export type AiDigestControllerFetchFrontPageItemAction = {
42
+ type: `AiDigestController:fetchFrontPageItem`;
43
+ handler: AiDigestController['fetchFrontPageItem'];
44
+ };
31
45
  /**
32
46
  * Union of all AiDigestController action types.
33
47
  */
34
- export type AiDigestControllerMethodActions = AiDigestControllerFetchMarketInsightsAction | AiDigestControllerFetchMarketOverviewAction;
48
+ export type AiDigestControllerMethodActions = AiDigestControllerFetchMarketInsightsAction | AiDigestControllerFetchMarketOverviewAction | AiDigestControllerFetchFrontPageItemAction;
35
49
  //# sourceMappingURL=AiDigestController-method-action-types.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AiDigestController-method-action-types.d.mts","sourceRoot":"","sources":["../src/AiDigestController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,iCAA6B;AAE/D;;;;;;;;;;GAUG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,+BAA+B,GACvC,2CAA2C,GAC3C,2CAA2C,CAAC"}
1
+ {"version":3,"file":"AiDigestController-method-action-types.d.mts","sourceRoot":"","sources":["../src/AiDigestController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,iCAA6B;AAE/D;;;;;;;;;;GAUG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,0CAA0C,GAAG;IACvD,IAAI,EAAE,uCAAuC,CAAC;IAC9C,OAAO,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;CACnD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,+BAA+B,GACvC,2CAA2C,GAC3C,2CAA2C,GAC3C,0CAA0C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AiDigestController-method-action-types.mjs","sourceRoot":"","sources":["../src/AiDigestController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { AiDigestController } from './AiDigestController';\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 */\nexport type AiDigestControllerFetchMarketInsightsAction = {\n type: `AiDigestController:fetchMarketInsights`;\n handler: AiDigestController['fetchMarketInsights'];\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 */\nexport type AiDigestControllerFetchMarketOverviewAction = {\n type: `AiDigestController:fetchMarketOverview`;\n handler: AiDigestController['fetchMarketOverview'];\n};\n\n/**\n * Union of all AiDigestController action types.\n */\nexport type AiDigestControllerMethodActions =\n | AiDigestControllerFetchMarketInsightsAction\n | AiDigestControllerFetchMarketOverviewAction;\n"]}
1
+ {"version":3,"file":"AiDigestController-method-action-types.mjs","sourceRoot":"","sources":["../src/AiDigestController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { AiDigestController } from './AiDigestController';\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 */\nexport type AiDigestControllerFetchMarketInsightsAction = {\n type: `AiDigestController:fetchMarketInsights`;\n handler: AiDigestController['fetchMarketInsights'];\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 */\nexport type AiDigestControllerFetchMarketOverviewAction = {\n type: `AiDigestController:fetchMarketOverview`;\n handler: AiDigestController['fetchMarketOverview'];\n};\n\n/**\n * Fetches a single market overview front page by id.\n *\n * Unlike the market overview report (which only returns the latest items),\n * this resolves an older item that has since dropped out of the report, so\n * clients can render it directly (e.g. from a deep link).\n *\n * @param id - The front-page identifier (UUID).\n * @returns The market overview front page, or `null` if none exists.\n */\nexport type AiDigestControllerFetchFrontPageItemAction = {\n type: `AiDigestController:fetchFrontPageItem`;\n handler: AiDigestController['fetchFrontPageItem'];\n};\n\n/**\n * Union of all AiDigestController action types.\n */\nexport type AiDigestControllerMethodActions =\n | AiDigestControllerFetchMarketInsightsAction\n | AiDigestControllerFetchMarketOverviewAction\n | AiDigestControllerFetchFrontPageItemAction;\n"]}
@@ -39,6 +39,7 @@ const aiDigestControllerMetadata = {
39
39
  const MESSENGER_EXPOSED_METHODS = [
40
40
  'fetchMarketInsights',
41
41
  'fetchMarketOverview',
42
+ 'fetchFrontPageItem',
42
43
  ];
43
44
  class AiDigestController extends base_controller_1.BaseController {
44
45
  constructor({ messenger, state, digestService }) {
@@ -127,6 +128,22 @@ class AiDigestController extends base_controller_1.BaseController {
127
128
  });
128
129
  return data;
129
130
  }
131
+ /**
132
+ * Fetches a single market overview front page by id.
133
+ *
134
+ * Unlike the market overview report (which only returns the latest items),
135
+ * this resolves an older item that has since dropped out of the report, so
136
+ * clients can render it directly (e.g. from a deep link).
137
+ *
138
+ * @param id - The front-page identifier (UUID).
139
+ * @returns The market overview front page, or `null` if none exists.
140
+ */
141
+ async fetchFrontPageItem(id) {
142
+ if (!id) {
143
+ throw new Error(ai_digest_constants_1.AiDigestControllerErrorMessage.INVALID_FRONT_PAGE_ID);
144
+ }
145
+ return __classPrivateFieldGet(this, _AiDigestController_digestService, "f").fetchFrontPageItem(id);
146
+ }
130
147
  }
131
148
  exports.AiDigestController = AiDigestController;
132
149
  _AiDigestController_digestService = new WeakMap(), _AiDigestController_instances = new WeakSet(), _AiDigestController_evictStaleCachedEntries = function _AiDigestController_evictStaleCachedEntries(cache) {
@@ -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';\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';\nimport type { AiDigestControllerMethodActions } from './AiDigestController-method-action-types';\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerGetStateAction\n | AiDigestControllerMethodActions;\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\nconst MESSENGER_EXPOSED_METHODS = [\n 'fetchMarketInsights',\n 'fetchMarketOverview',\n] as const;\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.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\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"]}
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 MarketOverviewFrontPage,\n} from './ai-digest-types';\nimport type { AiDigestControllerMethodActions } from './AiDigestController-method-action-types';\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerGetStateAction\n | AiDigestControllerMethodActions;\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\nconst MESSENGER_EXPOSED_METHODS = [\n 'fetchMarketInsights',\n 'fetchMarketOverview',\n 'fetchFrontPageItem',\n] as const;\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.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\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 * Fetches a single market overview front page by id.\n *\n * Unlike the market overview report (which only returns the latest items),\n * this resolves an older item that has since dropped out of the report, so\n * clients can render it directly (e.g. from a deep link).\n *\n * @param id - The front-page identifier (UUID).\n * @returns The market overview front page, or `null` if none exists.\n */\n async fetchFrontPageItem(\n id: string,\n ): Promise<MarketOverviewFrontPage | null> {\n if (!id) {\n throw new Error(AiDigestControllerErrorMessage.INVALID_FRONT_PAGE_ID);\n }\n\n return this.#digestService.fetchFrontPageItem(id);\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"]}
@@ -2,7 +2,7 @@ import type { ControllerStateChangeEvent, ControllerGetStateAction } from "@meta
2
2
  import { BaseController } from "@metamask/base-controller";
3
3
  import type { Messenger } from "@metamask/messenger";
4
4
  import { controllerName } from "./ai-digest-constants.cjs";
5
- import type { AiDigestControllerState, DigestService, MarketInsightsReport, MarketOverview } from "./ai-digest-types.cjs";
5
+ import type { AiDigestControllerState, DigestService, MarketInsightsReport, MarketOverview, MarketOverviewFrontPage } from "./ai-digest-types.cjs";
6
6
  import type { AiDigestControllerMethodActions } from "./AiDigestController-method-action-types.cjs";
7
7
  export type AiDigestControllerGetStateAction = ControllerGetStateAction<typeof controllerName, AiDigestControllerState>;
8
8
  export type AiDigestControllerActions = AiDigestControllerGetStateAction | AiDigestControllerMethodActions;
@@ -37,5 +37,16 @@ export declare class AiDigestController extends BaseController<typeof controller
37
37
  * @returns The market overview report, or `null` if none exists.
38
38
  */
39
39
  fetchMarketOverview(): Promise<MarketOverview | null>;
40
+ /**
41
+ * Fetches a single market overview front page by id.
42
+ *
43
+ * Unlike the market overview report (which only returns the latest items),
44
+ * this resolves an older item that has since dropped out of the report, so
45
+ * clients can render it directly (e.g. from a deep link).
46
+ *
47
+ * @param id - The front-page identifier (UUID).
48
+ * @returns The market overview front page, or `null` if none exists.
49
+ */
50
+ fetchFrontPageItem(id: string): Promise<MarketOverviewFrontPage | null>;
40
51
  }
41
52
  //# sourceMappingURL=AiDigestController.d.cts.map
@@ -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;AAErD,OAAO,EAEL,cAAc,EAGf,kCAA8B;AAC/B,OAAO,KAAK,EACV,uBAAuB,EACvB,aAAa,EACb,oBAAoB,EAEpB,cAAc,EAEf,8BAA0B;AAC3B,OAAO,KAAK,EAAE,+BAA+B,EAAE,qDAAiD;AAEhG,MAAM,MAAM,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,gCAAgC,GAChC,+BAA+B,CAAC;AAEpC,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;AAsBD,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;gBAGa,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,yBAAyB;IAkB1E;;;;;;;;;;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"}
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,EAEd,uBAAuB,EACxB,8BAA0B;AAC3B,OAAO,KAAK,EAAE,+BAA+B,EAAE,qDAAiD;AAEhG,MAAM,MAAM,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,gCAAgC,GAChC,+BAA+B,CAAC;AAEpC,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;AAuBD,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;gBAGa,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,yBAAyB;IAkB1E;;;;;;;;;;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;IA8B3D;;;;;;;;;OASG;IACG,kBAAkB,CACtB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;CAyC3C"}
@@ -2,7 +2,7 @@ import type { ControllerStateChangeEvent, ControllerGetStateAction } from "@meta
2
2
  import { BaseController } from "@metamask/base-controller";
3
3
  import type { Messenger } from "@metamask/messenger";
4
4
  import { controllerName } from "./ai-digest-constants.mjs";
5
- import type { AiDigestControllerState, DigestService, MarketInsightsReport, MarketOverview } from "./ai-digest-types.mjs";
5
+ import type { AiDigestControllerState, DigestService, MarketInsightsReport, MarketOverview, MarketOverviewFrontPage } from "./ai-digest-types.mjs";
6
6
  import type { AiDigestControllerMethodActions } from "./AiDigestController-method-action-types.mjs";
7
7
  export type AiDigestControllerGetStateAction = ControllerGetStateAction<typeof controllerName, AiDigestControllerState>;
8
8
  export type AiDigestControllerActions = AiDigestControllerGetStateAction | AiDigestControllerMethodActions;
@@ -37,5 +37,16 @@ export declare class AiDigestController extends BaseController<typeof controller
37
37
  * @returns The market overview report, or `null` if none exists.
38
38
  */
39
39
  fetchMarketOverview(): Promise<MarketOverview | null>;
40
+ /**
41
+ * Fetches a single market overview front page by id.
42
+ *
43
+ * Unlike the market overview report (which only returns the latest items),
44
+ * this resolves an older item that has since dropped out of the report, so
45
+ * clients can render it directly (e.g. from a deep link).
46
+ *
47
+ * @param id - The front-page identifier (UUID).
48
+ * @returns The market overview front page, or `null` if none exists.
49
+ */
50
+ fetchFrontPageItem(id: string): Promise<MarketOverviewFrontPage | null>;
40
51
  }
41
52
  //# sourceMappingURL=AiDigestController.d.mts.map
@@ -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;AAErD,OAAO,EAEL,cAAc,EAGf,kCAA8B;AAC/B,OAAO,KAAK,EACV,uBAAuB,EACvB,aAAa,EACb,oBAAoB,EAEpB,cAAc,EAEf,8BAA0B;AAC3B,OAAO,KAAK,EAAE,+BAA+B,EAAE,qDAAiD;AAEhG,MAAM,MAAM,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,gCAAgC,GAChC,+BAA+B,CAAC;AAEpC,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;AAsBD,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;gBAGa,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,yBAAyB;IAkB1E;;;;;;;;;;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"}
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,EAEd,uBAAuB,EACxB,8BAA0B;AAC3B,OAAO,KAAK,EAAE,+BAA+B,EAAE,qDAAiD;AAEhG,MAAM,MAAM,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,gCAAgC,GAChC,+BAA+B,CAAC;AAEpC,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;AAuBD,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;gBAGa,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,yBAAyB;IAkB1E;;;;;;;;;;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;IA8B3D;;;;;;;;;OASG;IACG,kBAAkB,CACtB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;CAyC3C"}
@@ -35,6 +35,7 @@ const aiDigestControllerMetadata = {
35
35
  const MESSENGER_EXPOSED_METHODS = [
36
36
  'fetchMarketInsights',
37
37
  'fetchMarketOverview',
38
+ 'fetchFrontPageItem',
38
39
  ];
39
40
  export class AiDigestController extends BaseController {
40
41
  constructor({ messenger, state, digestService }) {
@@ -123,6 +124,22 @@ export class AiDigestController extends BaseController {
123
124
  });
124
125
  return data;
125
126
  }
127
+ /**
128
+ * Fetches a single market overview front page by id.
129
+ *
130
+ * Unlike the market overview report (which only returns the latest items),
131
+ * this resolves an older item that has since dropped out of the report, so
132
+ * clients can render it directly (e.g. from a deep link).
133
+ *
134
+ * @param id - The front-page identifier (UUID).
135
+ * @returns The market overview front page, or `null` if none exists.
136
+ */
137
+ async fetchFrontPageItem(id) {
138
+ if (!id) {
139
+ throw new Error(AiDigestControllerErrorMessage.INVALID_FRONT_PAGE_ID);
140
+ }
141
+ return __classPrivateFieldGet(this, _AiDigestController_digestService, "f").fetchFrontPageItem(id);
142
+ }
126
143
  }
127
144
  _AiDigestController_digestService = new WeakMap(), _AiDigestController_instances = new WeakSet(), _AiDigestController_evictStaleCachedEntries = function _AiDigestController_evictStaleCachedEntries(cache) {
128
145
  const now = Date.now();
@@ -1 +1 @@
1
- {"version":3,"file":"AiDigestController.mjs","sourceRoot":"","sources":["../src/AiDigestController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAKA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAG3D,OAAO,EACL,8BAA8B,EAC9B,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EAClB,kCAA8B;AAuC/B,MAAM,UAAU,iCAAiC;IAC/C,OAAO;QACL,cAAc,EAAE,EAAE;QAClB,cAAc,EAAE,IAAI;KACrB,CAAC;AACJ,CAAC;AAED,MAAM,0BAA0B,GAA2C;IACzE,cAAc,EAAE;QACd,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,QAAQ,EAAE,IAAI;KACf;IACD,cAAc,EAAE;QACd,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,QAAQ,EAAE,IAAI;KACf;CACF,CAAC;AAEF,MAAM,yBAAyB,GAAG;IAChC,qBAAqB;IACrB,qBAAqB;CACb,CAAC;AAEX,MAAM,OAAO,kBAAmB,SAAQ,cAIvC;IAGC,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAA6B;QACxE,KAAK,CAAC;YACJ,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,0BAA0B;YACpC,KAAK,EAAE;gBACL,GAAG,iCAAiC,EAAE;gBACtC,GAAG,KAAK;aACT;YACD,SAAS;SACV,CAAC,CAAC;;QAXI,oDAA8B;QAarC,uBAAA,IAAI,qCAAkB,aAAa,MAAA,CAAC;QACpC,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,mBAAmB,CACvB,eAAuB;QAEvB,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,wBAAwB,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;QAC5D,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,SAAS,CAAC;YAC5C,IAAI,GAAG,GAAG,iBAAiB,EAAE,CAAC;gBAC5B,OAAO,QAAQ,CAAC,IAAI,CAAC;YACvB,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,uBAAA,IAAI,yCAAe,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QAErE,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,qEAAqE;YACrE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,OAAO,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;YAC/C,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAwB;YACjC,eAAe;YACf,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,IAAI;SACL,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,GAAG,KAAK,CAAC;YAC9C,uBAAA,IAAI,kFAAyB,MAA7B,IAAI,EAA0B,KAAK,CAAC,cAAc,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,mBAAmB;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC;QAC3C,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,SAAS,CAAC;YAC5C,IAAI,GAAG,GAAG,iBAAiB,EAAE,CAAC;gBAC5B,OAAO,QAAQ,CAAC,IAAI,CAAC;YACvB,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,uBAAA,IAAI,yCAAe,CAAC,mBAAmB,EAAE,CAAC;QAE7D,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC;YAC9B,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAwB;YACjC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,IAAI;SACL,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;CAmCF;qMA3BG,KAAgC;IAEhC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,MAAM,YAAY,GAA0B,EAAE,CAAC;IAE/C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;QACnC,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,IAAI,iBAAiB,EAAE,CAAC;YAC/C,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,GAAG,iBAAiB,EAAE,CAAC;QAC5C,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7D,MAAM,eAAe,GAAG,YAAY,CAAC,MAAM,GAAG,iBAAiB,CAAC;QAChE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;AACH,CAAC","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';\nimport type { AiDigestControllerMethodActions } from './AiDigestController-method-action-types';\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerGetStateAction\n | AiDigestControllerMethodActions;\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\nconst MESSENGER_EXPOSED_METHODS = [\n 'fetchMarketInsights',\n 'fetchMarketOverview',\n] as const;\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.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\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"]}
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 MarketOverviewFrontPage,\n} from './ai-digest-types';\nimport type { AiDigestControllerMethodActions } from './AiDigestController-method-action-types';\n\nexport type AiDigestControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AiDigestControllerState\n>;\n\nexport type AiDigestControllerActions =\n | AiDigestControllerGetStateAction\n | AiDigestControllerMethodActions;\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\nconst MESSENGER_EXPOSED_METHODS = [\n 'fetchMarketInsights',\n 'fetchMarketOverview',\n 'fetchFrontPageItem',\n] as const;\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.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\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 * Fetches a single market overview front page by id.\n *\n * Unlike the market overview report (which only returns the latest items),\n * this resolves an older item that has since dropped out of the report, so\n * clients can render it directly (e.g. from a deep link).\n *\n * @param id - The front-page identifier (UUID).\n * @returns The market overview front page, or `null` if none exists.\n */\n async fetchFrontPageItem(\n id: string,\n ): Promise<MarketOverviewFrontPage | null> {\n if (!id) {\n throw new Error(AiDigestControllerErrorMessage.INVALID_FRONT_PAGE_ID);\n }\n\n return this.#digestService.fetchFrontPageItem(id);\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"]}
@@ -94,15 +94,26 @@ const MarketOverviewStruct = (0, superstruct_1.type)({
94
94
  const MarketOverviewReportEnvelopeStruct = (0, superstruct_1.type)({
95
95
  report: MarketOverviewStruct,
96
96
  });
97
+ // A single front-page row. `item` shares the exact same schema as an
98
+ // individual market overview trend; `ctaTitle`/`ctaDescription` are the
99
+ // AI-authored call-to-action copy layered on top.
100
+ const MarketOverviewFrontPageStruct = (0, superstruct_1.type)({
101
+ id: (0, superstruct_1.string)(),
102
+ item: MarketOverviewTrendStruct,
103
+ ctaTitle: (0, superstruct_1.string)(),
104
+ ctaDescription: (0, superstruct_1.string)(),
105
+ createdAt: (0, superstruct_1.string)(),
106
+ });
107
+ const normalizeItemRelatedAssets = (item) => ({
108
+ ...item,
109
+ relatedAssets: item.relatedAssets.map((asset) => ({
110
+ ...asset,
111
+ caip19: asset.caip19 ?? [],
112
+ })),
113
+ });
97
114
  const normalizeRelatedAssets = (raw) => ({
98
115
  ...raw,
99
- trends: raw.trends.map((trend) => ({
100
- ...trend,
101
- relatedAssets: trend.relatedAssets.map((asset) => ({
102
- ...asset,
103
- caip19: asset.caip19 ?? [],
104
- })),
105
- })),
116
+ trends: raw.trends.map(normalizeItemRelatedAssets),
106
117
  });
107
118
  const getNormalizedMarketOverview = (value) => {
108
119
  if ((0, superstruct_1.is)(value, MarketOverviewStruct)) {
@@ -113,6 +124,12 @@ const getNormalizedMarketOverview = (value) => {
113
124
  }
114
125
  return null;
115
126
  };
127
+ const getNormalizedFrontPage = (value) => {
128
+ if (!(0, superstruct_1.is)(value, MarketOverviewFrontPageStruct)) {
129
+ return null;
130
+ }
131
+ return { ...value, item: normalizeItemRelatedAssets(value.item) };
132
+ };
116
133
  const getNormalizedMarketInsightsReport = (value) => {
117
134
  if ((0, superstruct_1.is)(value, MarketInsightsDigestEnvelopeStruct)) {
118
135
  return { ...value.digest, digestId: value.id };
@@ -145,6 +162,28 @@ class AiDigestService {
145
162
  }
146
163
  return overview;
147
164
  }
165
+ /**
166
+ * Fetch a single market overview front page by id.
167
+ *
168
+ * Calls `GET ${this.#baseUrl}/market-overview/front-page/:id`.
169
+ *
170
+ * @param id - The front-page identifier (UUID).
171
+ * @returns The market overview front page, or `null` if none exists (404).
172
+ */
173
+ async fetchFrontPageItem(id) {
174
+ const response = await fetch(`${__classPrivateFieldGet(this, _AiDigestService_baseUrl, "f")}/market-overview/front-page/${encodeURIComponent(id)}`);
175
+ if (response.status === 404) {
176
+ return null;
177
+ }
178
+ if (!response.ok) {
179
+ throw new Error(`${ai_digest_constants_1.AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`);
180
+ }
181
+ const frontPage = getNormalizedFrontPage(await response.json());
182
+ if (!frontPage) {
183
+ throw new Error(ai_digest_constants_1.AiDigestControllerErrorMessage.API_INVALID_RESPONSE);
184
+ }
185
+ return frontPage;
186
+ }
148
187
  /**
149
188
  * Search for market insights by asset identifier.
150
189
  *
@@ -1 +1 @@
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';\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 id: string(),\n digest: MarketInsightsReportStruct,\n});\n\n// Market Overview structs\n\nconst RelatedAssetStruct = structType({\n name: optional(string()),\n symbol: string(),\n caip19: optional(array(string())),\n sourceAssetId: optional(string()),\n hlPerpsMarket: optional(array(string())),\n});\n\nconst MarketOverviewTrendStruct = structType({\n title: string(),\n description: string(),\n category: optional(enums(trendCategoryValues)),\n impact: optional(enums(trendImpactValues)),\n articles: array(ArticleStruct),\n relatedAssets: array(RelatedAssetStruct),\n});\n\nconst MarketOverviewStruct = structType({\n version: optional(string()),\n generatedAt: string(),\n trends: array(MarketOverviewTrendStruct),\n metadata: optional(array(AIResponseMetadataStruct)),\n});\n\nconst MarketOverviewReportEnvelopeStruct = structType({\n report: MarketOverviewStruct,\n});\n\nconst normalizeRelatedAssets = (raw: MarketOverview): MarketOverview => ({\n ...raw,\n trends: raw.trends.map((trend) => ({\n ...trend,\n relatedAssets: trend.relatedAssets.map((asset) => ({\n ...asset,\n caip19: asset.caip19 ?? [],\n })),\n })),\n});\n\nconst getNormalizedMarketOverview = (value: unknown): MarketOverview | null => {\n if (is(value, MarketOverviewStruct)) {\n return normalizeRelatedAssets(value);\n }\n\n if (is(value, MarketOverviewReportEnvelopeStruct)) {\n return normalizeRelatedAssets(value.report);\n }\n\n return null;\n};\n\nconst getNormalizedMarketInsightsReport = (\n value: unknown,\n): MarketInsightsReport | null => {\n if (is(value, MarketInsightsDigestEnvelopeStruct)) {\n return { ...value.digest, digestId: value.id };\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 overview = getNormalizedMarketOverview(await response.json());\n\n if (!overview) {\n throw new Error(AiDigestControllerErrorMessage.API_INVALID_RESPONSE);\n }\n\n return overview;\n }\n\n /**\n * Search for market insights by asset identifier.\n *\n * Accepts any identifier the API understands (CAIP-19 asset type, ticker\n * symbol, asset name, HyperLiquid perps market id, etc.) and forwards it\n * unchanged via the universal `asset` query parameter.\n *\n * Calls `GET ${baseUrl}/asset-summary?asset=<assetIdentifier>`.\n *\n * @param assetIdentifier - The asset identifier (e.g. `eip155:1/slip44:60`,\n * `ETH`, `Bitcoin`, `xyz:TSLA`).\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 response = await fetch(\n `${this.#baseUrl}/asset-summary?asset=${encodeURIComponent(assetIdentifier)}`,\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
+ {"version":3,"file":"AiDigestService.cjs","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,uDAO+B;AAE/B,mEAAuE;AAavE,0BAA0B;AAE1B,MAAM,aAAa,GAAG,IAAA,kBAAU,EAAC;IAC/B,KAAK,EAAE,IAAA,oBAAM,GAAE;IACf,GAAG,EAAE,IAAA,oBAAM,GAAE;IACb,MAAM,EAAE,IAAA,oBAAM,GAAE;IAChB,IAAI,EAAE,IAAA,oBAAM,GAAE;CACf,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG,IAAA,kBAAU,EAAC;IAC7B,cAAc,EAAE,IAAA,oBAAM,GAAE;IACxB,GAAG,EAAE,IAAA,oBAAM,GAAE;IACb,MAAM,EAAE,IAAA,oBAAM,GAAE;IAChB,IAAI,EAAE,IAAA,oBAAM,GAAE;CACf,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,IAAA,kBAAU,EAAC;IAC9B,IAAI,EAAE,IAAA,oBAAM,GAAE;IACd,GAAG,EAAE,IAAA,oBAAM,GAAE;IACb,IAAI,EAAE,IAAA,mBAAK,EAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;CACjD,CAAC,CAAC;AAEH,MAAM,wBAAwB,GAAG,IAAA,kBAAU,EAAC;IAC1C,QAAQ,EAAE,IAAA,oBAAM,GAAE;CACnB,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG;IAC1B,cAAc;IACd,OAAO;IACP,YAAY;IACZ,WAAW;IACX,QAAQ;IACR,OAAO;CACC,CAAC;AAEX,MAAM,iBAAiB,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,CAAU,CAAC;AAEvE,0BAA0B;AAE1B,MAAM,yBAAyB,GAAG,IAAA,kBAAU,EAAC;IAC3C,KAAK,EAAE,IAAA,oBAAM,GAAE;IACf,WAAW,EAAE,IAAA,oBAAM,GAAE;IACrB,QAAQ,EAAE,IAAA,mBAAK,EAAC,mBAAmB,CAAC;IACpC,MAAM,EAAE,IAAA,mBAAK,EAAC,iBAAiB,CAAC;IAChC,QAAQ,EAAE,IAAA,mBAAK,EAAC,aAAa,CAAC;IAC9B,MAAM,EAAE,IAAA,mBAAK,EAAC,WAAW,CAAC;CAC3B,CAAC,CAAC;AAEH,MAAM,0BAA0B,GAAG,IAAA,kBAAU,EAAC;IAC5C,OAAO,EAAE,IAAA,sBAAQ,EAAC,IAAA,oBAAM,GAAE,CAAC;IAC3B,KAAK,EAAE,IAAA,oBAAM,GAAE;IACf,WAAW,EAAE,IAAA,oBAAM,GAAE;IACrB,QAAQ,EAAE,IAAA,oBAAM,GAAE;IAClB,OAAO,EAAE,IAAA,oBAAM,GAAE;IACjB,MAAM,EAAE,IAAA,mBAAK,EAAC,yBAAyB,CAAC;IACxC,MAAM,EAAE,IAAA,sBAAQ,EAAC,IAAA,mBAAK,EAAC,WAAW,CAAC,CAAC;IACpC,OAAO,EAAE,IAAA,mBAAK,EAAC,YAAY,CAAC;IAC5B,QAAQ,EAAE,IAAA,sBAAQ,EAAC,IAAA,mBAAK,EAAC,wBAAwB,CAAC,CAAC;CACpD,CAAC,CAAC;AAEH,MAAM,kCAAkC,GAAG,IAAA,kBAAU,EAAC;IACpD,EAAE,EAAE,IAAA,oBAAM,GAAE;IACZ,MAAM,EAAE,0BAA0B;CACnC,CAAC,CAAC;AAEH,0BAA0B;AAE1B,MAAM,kBAAkB,GAAG,IAAA,kBAAU,EAAC;IACpC,IAAI,EAAE,IAAA,sBAAQ,EAAC,IAAA,oBAAM,GAAE,CAAC;IACxB,MAAM,EAAE,IAAA,oBAAM,GAAE;IAChB,MAAM,EAAE,IAAA,sBAAQ,EAAC,IAAA,mBAAK,EAAC,IAAA,oBAAM,GAAE,CAAC,CAAC;IACjC,aAAa,EAAE,IAAA,sBAAQ,EAAC,IAAA,oBAAM,GAAE,CAAC;IACjC,aAAa,EAAE,IAAA,sBAAQ,EAAC,IAAA,mBAAK,EAAC,IAAA,oBAAM,GAAE,CAAC,CAAC;CACzC,CAAC,CAAC;AAEH,MAAM,yBAAyB,GAAG,IAAA,kBAAU,EAAC;IAC3C,KAAK,EAAE,IAAA,oBAAM,GAAE;IACf,WAAW,EAAE,IAAA,oBAAM,GAAE;IACrB,QAAQ,EAAE,IAAA,sBAAQ,EAAC,IAAA,mBAAK,EAAC,mBAAmB,CAAC,CAAC;IAC9C,MAAM,EAAE,IAAA,sBAAQ,EAAC,IAAA,mBAAK,EAAC,iBAAiB,CAAC,CAAC;IAC1C,QAAQ,EAAE,IAAA,mBAAK,EAAC,aAAa,CAAC;IAC9B,aAAa,EAAE,IAAA,mBAAK,EAAC,kBAAkB,CAAC;CACzC,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,IAAA,kBAAU,EAAC;IACtC,OAAO,EAAE,IAAA,sBAAQ,EAAC,IAAA,oBAAM,GAAE,CAAC;IAC3B,WAAW,EAAE,IAAA,oBAAM,GAAE;IACrB,MAAM,EAAE,IAAA,mBAAK,EAAC,yBAAyB,CAAC;IACxC,QAAQ,EAAE,IAAA,sBAAQ,EAAC,IAAA,mBAAK,EAAC,wBAAwB,CAAC,CAAC;CACpD,CAAC,CAAC;AAEH,MAAM,kCAAkC,GAAG,IAAA,kBAAU,EAAC;IACpD,MAAM,EAAE,oBAAoB;CAC7B,CAAC,CAAC;AAEH,qEAAqE;AACrE,wEAAwE;AACxE,kDAAkD;AAClD,MAAM,6BAA6B,GAAG,IAAA,kBAAU,EAAC;IAC/C,EAAE,EAAE,IAAA,oBAAM,GAAE;IACZ,IAAI,EAAE,yBAAyB;IAC/B,QAAQ,EAAE,IAAA,oBAAM,GAAE;IAClB,cAAc,EAAE,IAAA,oBAAM,GAAE;IACxB,SAAS,EAAE,IAAA,oBAAM,GAAE;CACpB,CAAC,CAAC;AAEH,MAAM,0BAA0B,GAAG,CACjC,IAAyB,EACJ,EAAE,CAAC,CAAC;IACzB,GAAG,IAAI;IACP,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAChD,GAAG,KAAK;QACR,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE;KAC3B,CAAC,CAAC;CACJ,CAAC,CAAC;AAEH,MAAM,sBAAsB,GAAG,CAAC,GAAmB,EAAkB,EAAE,CAAC,CAAC;IACvE,GAAG,GAAG;IACN,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,0BAA0B,CAAC;CACnD,CAAC,CAAC;AAEH,MAAM,2BAA2B,GAAG,CAAC,KAAc,EAAyB,EAAE;IAC5E,IAAI,IAAA,gBAAE,EAAC,KAAK,EAAE,oBAAoB,CAAC,EAAE,CAAC;QACpC,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,IAAA,gBAAE,EAAC,KAAK,EAAE,kCAAkC,CAAC,EAAE,CAAC;QAClD,OAAO,sBAAsB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,CAC7B,KAAc,EACkB,EAAE;IAClC,IAAI,CAAC,IAAA,gBAAE,EAAC,KAAK,EAAE,6BAA6B,CAAC,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,0BAA0B,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;AACpE,CAAC,CAAC;AAEF,MAAM,iCAAiC,GAAG,CACxC,KAAc,EACe,EAAE;IAC/B,IAAI,IAAA,gBAAE,EAAC,KAAK,EAAE,kCAAkC,CAAC,EAAE,CAAC;QAClD,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;IACjD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAa,eAAe;IAG1B,YAAY,MAA6B;QAFhC,2CAAiB;QAGxB,uBAAA,IAAI,4BAAY,MAAM,CAAC,OAAO,MAAA,CAAC;IACjC,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,mBAAmB;QACvB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,uBAAA,IAAI,gCAAS,kBAAkB,CAAC,CAAC;QAEjE,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,GAAG,oDAA8B,CAAC,kBAAkB,KAAK,QAAQ,CAAC,MAAM,EAAE,CAC3E,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,2BAA2B,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAEpE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,oDAA8B,CAAC,oBAAoB,CAAC,CAAC;QACvE,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,kBAAkB,CACtB,EAAU;QAEV,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,uBAAA,IAAI,gCAAS,+BAA+B,kBAAkB,CAAC,EAAE,CAAC,EAAE,CACxE,CAAC;QAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,GAAG,oDAA8B,CAAC,kBAAkB,KAAK,QAAQ,CAAC,MAAM,EAAE,CAC3E,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,sBAAsB,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAEhE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,oDAA8B,CAAC,oBAAoB,CAAC,CAAC;QACvE,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,YAAY,CAChB,eAAuB;QAEvB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,uBAAA,IAAI,gCAAS,wBAAwB,kBAAkB,CAAC,eAAe,CAAC,EAAE,CAC9E,CAAC;QAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,GAAG,oDAA8B,CAAC,kBAAkB,KAAK,QAAQ,CAAC,MAAM,EAAE,CAC3E,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,iCAAiC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAExE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,oDAA8B,CAAC,oBAAoB,CAAC,CAAC;QACvE,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AA5GD,0CA4GC","sourcesContent":["import {\n array,\n enums,\n is,\n optional,\n string,\n type as structType,\n} from '@metamask/superstruct';\n\nimport { AiDigestControllerErrorMessage } from './ai-digest-constants';\nimport type {\n DigestService,\n MarketInsightsReport,\n MarketOverview,\n MarketOverviewFrontPage,\n MarketOverviewTrend,\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 id: string(),\n digest: MarketInsightsReportStruct,\n});\n\n// Market Overview structs\n\nconst RelatedAssetStruct = structType({\n name: optional(string()),\n symbol: string(),\n caip19: optional(array(string())),\n sourceAssetId: optional(string()),\n hlPerpsMarket: optional(array(string())),\n});\n\nconst MarketOverviewTrendStruct = structType({\n title: string(),\n description: string(),\n category: optional(enums(trendCategoryValues)),\n impact: optional(enums(trendImpactValues)),\n articles: array(ArticleStruct),\n relatedAssets: array(RelatedAssetStruct),\n});\n\nconst MarketOverviewStruct = structType({\n version: optional(string()),\n generatedAt: string(),\n trends: array(MarketOverviewTrendStruct),\n metadata: optional(array(AIResponseMetadataStruct)),\n});\n\nconst MarketOverviewReportEnvelopeStruct = structType({\n report: MarketOverviewStruct,\n});\n\n// A single front-page row. `item` shares the exact same schema as an\n// individual market overview trend; `ctaTitle`/`ctaDescription` are the\n// AI-authored call-to-action copy layered on top.\nconst MarketOverviewFrontPageStruct = structType({\n id: string(),\n item: MarketOverviewTrendStruct,\n ctaTitle: string(),\n ctaDescription: string(),\n createdAt: string(),\n});\n\nconst normalizeItemRelatedAssets = (\n item: MarketOverviewTrend,\n): MarketOverviewTrend => ({\n ...item,\n relatedAssets: item.relatedAssets.map((asset) => ({\n ...asset,\n caip19: asset.caip19 ?? [],\n })),\n});\n\nconst normalizeRelatedAssets = (raw: MarketOverview): MarketOverview => ({\n ...raw,\n trends: raw.trends.map(normalizeItemRelatedAssets),\n});\n\nconst getNormalizedMarketOverview = (value: unknown): MarketOverview | null => {\n if (is(value, MarketOverviewStruct)) {\n return normalizeRelatedAssets(value);\n }\n\n if (is(value, MarketOverviewReportEnvelopeStruct)) {\n return normalizeRelatedAssets(value.report);\n }\n\n return null;\n};\n\nconst getNormalizedFrontPage = (\n value: unknown,\n): MarketOverviewFrontPage | null => {\n if (!is(value, MarketOverviewFrontPageStruct)) {\n return null;\n }\n\n return { ...value, item: normalizeItemRelatedAssets(value.item) };\n};\n\nconst getNormalizedMarketInsightsReport = (\n value: unknown,\n): MarketInsightsReport | null => {\n if (is(value, MarketInsightsDigestEnvelopeStruct)) {\n return { ...value.digest, digestId: value.id };\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 overview = getNormalizedMarketOverview(await response.json());\n\n if (!overview) {\n throw new Error(AiDigestControllerErrorMessage.API_INVALID_RESPONSE);\n }\n\n return overview;\n }\n\n /**\n * Fetch a single market overview front page by id.\n *\n * Calls `GET ${this.#baseUrl}/market-overview/front-page/:id`.\n *\n * @param id - The front-page identifier (UUID).\n * @returns The market overview front page, or `null` if none exists (404).\n */\n async fetchFrontPageItem(\n id: string,\n ): Promise<MarketOverviewFrontPage | null> {\n const response = await fetch(\n `${this.#baseUrl}/market-overview/front-page/${encodeURIComponent(id)}`,\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 frontPage = getNormalizedFrontPage(await response.json());\n\n if (!frontPage) {\n throw new Error(AiDigestControllerErrorMessage.API_INVALID_RESPONSE);\n }\n\n return frontPage;\n }\n\n /**\n * Search for market insights by asset identifier.\n *\n * Accepts any identifier the API understands (CAIP-19 asset type, ticker\n * symbol, asset name, HyperLiquid perps market id, etc.) and forwards it\n * unchanged via the universal `asset` query parameter.\n *\n * Calls `GET ${baseUrl}/asset-summary?asset=<assetIdentifier>`.\n *\n * @param assetIdentifier - The asset identifier (e.g. `eip155:1/slip44:60`,\n * `ETH`, `Bitcoin`, `xyz:TSLA`).\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 response = await fetch(\n `${this.#baseUrl}/asset-summary?asset=${encodeURIComponent(assetIdentifier)}`,\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,4 @@
1
- import type { DigestService, MarketInsightsReport, MarketOverview } from "./ai-digest-types.cjs";
1
+ import type { DigestService, MarketInsightsReport, MarketOverview, MarketOverviewFrontPage } from "./ai-digest-types.cjs";
2
2
  export type AiDigestServiceConfig = {
3
3
  baseUrl: string;
4
4
  };
@@ -13,6 +13,15 @@ export declare class AiDigestService implements DigestService {
13
13
  * @returns The market overview report, or `null` if none exists (404).
14
14
  */
15
15
  fetchMarketOverview(): Promise<MarketOverview | null>;
16
+ /**
17
+ * Fetch a single market overview front page by id.
18
+ *
19
+ * Calls `GET ${this.#baseUrl}/market-overview/front-page/:id`.
20
+ *
21
+ * @param id - The front-page identifier (UUID).
22
+ * @returns The market overview front page, or `null` if none exists (404).
23
+ */
24
+ fetchFrontPageItem(id: string): Promise<MarketOverviewFrontPage | null>;
16
25
  /**
17
26
  * Search for market insights by asset identifier.
18
27
  *
@@ -1 +1 @@
1
- {"version":3,"file":"AiDigestService.d.cts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,cAAc,EACf,8BAA0B;AAE3B,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAkIF,qBAAa,eAAgB,YAAW,aAAa;;gBAGvC,MAAM,EAAE,qBAAqB;IAIzC;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAsB3D;;;;;;;;;;;;OAYG;IACG,YAAY,CAChB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;CAuBxC"}
1
+ {"version":3,"file":"AiDigestService.d.cts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,uBAAuB,EAExB,8BAA0B;AAE3B,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AA2JF,qBAAa,eAAgB,YAAW,aAAa;;gBAGvC,MAAM,EAAE,qBAAqB;IAIzC;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAsB3D;;;;;;;OAOG;IACG,kBAAkB,CACtB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;IAwB1C;;;;;;;;;;;;OAYG;IACG,YAAY,CAChB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;CAuBxC"}
@@ -1,4 +1,4 @@
1
- import type { DigestService, MarketInsightsReport, MarketOverview } from "./ai-digest-types.mjs";
1
+ import type { DigestService, MarketInsightsReport, MarketOverview, MarketOverviewFrontPage } from "./ai-digest-types.mjs";
2
2
  export type AiDigestServiceConfig = {
3
3
  baseUrl: string;
4
4
  };
@@ -13,6 +13,15 @@ export declare class AiDigestService implements DigestService {
13
13
  * @returns The market overview report, or `null` if none exists (404).
14
14
  */
15
15
  fetchMarketOverview(): Promise<MarketOverview | null>;
16
+ /**
17
+ * Fetch a single market overview front page by id.
18
+ *
19
+ * Calls `GET ${this.#baseUrl}/market-overview/front-page/:id`.
20
+ *
21
+ * @param id - The front-page identifier (UUID).
22
+ * @returns The market overview front page, or `null` if none exists (404).
23
+ */
24
+ fetchFrontPageItem(id: string): Promise<MarketOverviewFrontPage | null>;
16
25
  /**
17
26
  * Search for market insights by asset identifier.
18
27
  *
@@ -1 +1 @@
1
- {"version":3,"file":"AiDigestService.d.mts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,cAAc,EACf,8BAA0B;AAE3B,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAkIF,qBAAa,eAAgB,YAAW,aAAa;;gBAGvC,MAAM,EAAE,qBAAqB;IAIzC;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAsB3D;;;;;;;;;;;;OAYG;IACG,YAAY,CAChB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;CAuBxC"}
1
+ {"version":3,"file":"AiDigestService.d.mts","sourceRoot":"","sources":["../src/AiDigestService.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,uBAAuB,EAExB,8BAA0B;AAE3B,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AA2JF,qBAAa,eAAgB,YAAW,aAAa;;gBAGvC,MAAM,EAAE,qBAAqB;IAIzC;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAsB3D;;;;;;;OAOG;IACG,kBAAkB,CACtB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;IAwB1C;;;;;;;;;;;;OAYG;IACG,YAAY,CAChB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;CAuBxC"}
@@ -91,15 +91,26 @@ const MarketOverviewStruct = structType({
91
91
  const MarketOverviewReportEnvelopeStruct = structType({
92
92
  report: MarketOverviewStruct,
93
93
  });
94
+ // A single front-page row. `item` shares the exact same schema as an
95
+ // individual market overview trend; `ctaTitle`/`ctaDescription` are the
96
+ // AI-authored call-to-action copy layered on top.
97
+ const MarketOverviewFrontPageStruct = structType({
98
+ id: string(),
99
+ item: MarketOverviewTrendStruct,
100
+ ctaTitle: string(),
101
+ ctaDescription: string(),
102
+ createdAt: string(),
103
+ });
104
+ const normalizeItemRelatedAssets = (item) => ({
105
+ ...item,
106
+ relatedAssets: item.relatedAssets.map((asset) => ({
107
+ ...asset,
108
+ caip19: asset.caip19 ?? [],
109
+ })),
110
+ });
94
111
  const normalizeRelatedAssets = (raw) => ({
95
112
  ...raw,
96
- trends: raw.trends.map((trend) => ({
97
- ...trend,
98
- relatedAssets: trend.relatedAssets.map((asset) => ({
99
- ...asset,
100
- caip19: asset.caip19 ?? [],
101
- })),
102
- })),
113
+ trends: raw.trends.map(normalizeItemRelatedAssets),
103
114
  });
104
115
  const getNormalizedMarketOverview = (value) => {
105
116
  if (is(value, MarketOverviewStruct)) {
@@ -110,6 +121,12 @@ const getNormalizedMarketOverview = (value) => {
110
121
  }
111
122
  return null;
112
123
  };
124
+ const getNormalizedFrontPage = (value) => {
125
+ if (!is(value, MarketOverviewFrontPageStruct)) {
126
+ return null;
127
+ }
128
+ return { ...value, item: normalizeItemRelatedAssets(value.item) };
129
+ };
113
130
  const getNormalizedMarketInsightsReport = (value) => {
114
131
  if (is(value, MarketInsightsDigestEnvelopeStruct)) {
115
132
  return { ...value.digest, digestId: value.id };
@@ -142,6 +159,28 @@ export class AiDigestService {
142
159
  }
143
160
  return overview;
144
161
  }
162
+ /**
163
+ * Fetch a single market overview front page by id.
164
+ *
165
+ * Calls `GET ${this.#baseUrl}/market-overview/front-page/:id`.
166
+ *
167
+ * @param id - The front-page identifier (UUID).
168
+ * @returns The market overview front page, or `null` if none exists (404).
169
+ */
170
+ async fetchFrontPageItem(id) {
171
+ const response = await fetch(`${__classPrivateFieldGet(this, _AiDigestService_baseUrl, "f")}/market-overview/front-page/${encodeURIComponent(id)}`);
172
+ if (response.status === 404) {
173
+ return null;
174
+ }
175
+ if (!response.ok) {
176
+ throw new Error(`${AiDigestControllerErrorMessage.API_REQUEST_FAILED}: ${response.status}`);
177
+ }
178
+ const frontPage = getNormalizedFrontPage(await response.json());
179
+ if (!frontPage) {
180
+ throw new Error(AiDigestControllerErrorMessage.API_INVALID_RESPONSE);
181
+ }
182
+ return frontPage;
183
+ }
145
184
  /**
146
185
  * Search for market insights by asset identifier.
147
186
  *
@@ -1 +1 @@
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';\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 id: string(),\n digest: MarketInsightsReportStruct,\n});\n\n// Market Overview structs\n\nconst RelatedAssetStruct = structType({\n name: optional(string()),\n symbol: string(),\n caip19: optional(array(string())),\n sourceAssetId: optional(string()),\n hlPerpsMarket: optional(array(string())),\n});\n\nconst MarketOverviewTrendStruct = structType({\n title: string(),\n description: string(),\n category: optional(enums(trendCategoryValues)),\n impact: optional(enums(trendImpactValues)),\n articles: array(ArticleStruct),\n relatedAssets: array(RelatedAssetStruct),\n});\n\nconst MarketOverviewStruct = structType({\n version: optional(string()),\n generatedAt: string(),\n trends: array(MarketOverviewTrendStruct),\n metadata: optional(array(AIResponseMetadataStruct)),\n});\n\nconst MarketOverviewReportEnvelopeStruct = structType({\n report: MarketOverviewStruct,\n});\n\nconst normalizeRelatedAssets = (raw: MarketOverview): MarketOverview => ({\n ...raw,\n trends: raw.trends.map((trend) => ({\n ...trend,\n relatedAssets: trend.relatedAssets.map((asset) => ({\n ...asset,\n caip19: asset.caip19 ?? [],\n })),\n })),\n});\n\nconst getNormalizedMarketOverview = (value: unknown): MarketOverview | null => {\n if (is(value, MarketOverviewStruct)) {\n return normalizeRelatedAssets(value);\n }\n\n if (is(value, MarketOverviewReportEnvelopeStruct)) {\n return normalizeRelatedAssets(value.report);\n }\n\n return null;\n};\n\nconst getNormalizedMarketInsightsReport = (\n value: unknown,\n): MarketInsightsReport | null => {\n if (is(value, MarketInsightsDigestEnvelopeStruct)) {\n return { ...value.digest, digestId: value.id };\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 overview = getNormalizedMarketOverview(await response.json());\n\n if (!overview) {\n throw new Error(AiDigestControllerErrorMessage.API_INVALID_RESPONSE);\n }\n\n return overview;\n }\n\n /**\n * Search for market insights by asset identifier.\n *\n * Accepts any identifier the API understands (CAIP-19 asset type, ticker\n * symbol, asset name, HyperLiquid perps market id, etc.) and forwards it\n * unchanged via the universal `asset` query parameter.\n *\n * Calls `GET ${baseUrl}/asset-summary?asset=<assetIdentifier>`.\n *\n * @param assetIdentifier - The asset identifier (e.g. `eip155:1/slip44:60`,\n * `ETH`, `Bitcoin`, `xyz:TSLA`).\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 response = await fetch(\n `${this.#baseUrl}/asset-summary?asset=${encodeURIComponent(assetIdentifier)}`,\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
+ {"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';\n\nimport { AiDigestControllerErrorMessage } from './ai-digest-constants';\nimport type {\n DigestService,\n MarketInsightsReport,\n MarketOverview,\n MarketOverviewFrontPage,\n MarketOverviewTrend,\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 id: string(),\n digest: MarketInsightsReportStruct,\n});\n\n// Market Overview structs\n\nconst RelatedAssetStruct = structType({\n name: optional(string()),\n symbol: string(),\n caip19: optional(array(string())),\n sourceAssetId: optional(string()),\n hlPerpsMarket: optional(array(string())),\n});\n\nconst MarketOverviewTrendStruct = structType({\n title: string(),\n description: string(),\n category: optional(enums(trendCategoryValues)),\n impact: optional(enums(trendImpactValues)),\n articles: array(ArticleStruct),\n relatedAssets: array(RelatedAssetStruct),\n});\n\nconst MarketOverviewStruct = structType({\n version: optional(string()),\n generatedAt: string(),\n trends: array(MarketOverviewTrendStruct),\n metadata: optional(array(AIResponseMetadataStruct)),\n});\n\nconst MarketOverviewReportEnvelopeStruct = structType({\n report: MarketOverviewStruct,\n});\n\n// A single front-page row. `item` shares the exact same schema as an\n// individual market overview trend; `ctaTitle`/`ctaDescription` are the\n// AI-authored call-to-action copy layered on top.\nconst MarketOverviewFrontPageStruct = structType({\n id: string(),\n item: MarketOverviewTrendStruct,\n ctaTitle: string(),\n ctaDescription: string(),\n createdAt: string(),\n});\n\nconst normalizeItemRelatedAssets = (\n item: MarketOverviewTrend,\n): MarketOverviewTrend => ({\n ...item,\n relatedAssets: item.relatedAssets.map((asset) => ({\n ...asset,\n caip19: asset.caip19 ?? [],\n })),\n});\n\nconst normalizeRelatedAssets = (raw: MarketOverview): MarketOverview => ({\n ...raw,\n trends: raw.trends.map(normalizeItemRelatedAssets),\n});\n\nconst getNormalizedMarketOverview = (value: unknown): MarketOverview | null => {\n if (is(value, MarketOverviewStruct)) {\n return normalizeRelatedAssets(value);\n }\n\n if (is(value, MarketOverviewReportEnvelopeStruct)) {\n return normalizeRelatedAssets(value.report);\n }\n\n return null;\n};\n\nconst getNormalizedFrontPage = (\n value: unknown,\n): MarketOverviewFrontPage | null => {\n if (!is(value, MarketOverviewFrontPageStruct)) {\n return null;\n }\n\n return { ...value, item: normalizeItemRelatedAssets(value.item) };\n};\n\nconst getNormalizedMarketInsightsReport = (\n value: unknown,\n): MarketInsightsReport | null => {\n if (is(value, MarketInsightsDigestEnvelopeStruct)) {\n return { ...value.digest, digestId: value.id };\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 overview = getNormalizedMarketOverview(await response.json());\n\n if (!overview) {\n throw new Error(AiDigestControllerErrorMessage.API_INVALID_RESPONSE);\n }\n\n return overview;\n }\n\n /**\n * Fetch a single market overview front page by id.\n *\n * Calls `GET ${this.#baseUrl}/market-overview/front-page/:id`.\n *\n * @param id - The front-page identifier (UUID).\n * @returns The market overview front page, or `null` if none exists (404).\n */\n async fetchFrontPageItem(\n id: string,\n ): Promise<MarketOverviewFrontPage | null> {\n const response = await fetch(\n `${this.#baseUrl}/market-overview/front-page/${encodeURIComponent(id)}`,\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 frontPage = getNormalizedFrontPage(await response.json());\n\n if (!frontPage) {\n throw new Error(AiDigestControllerErrorMessage.API_INVALID_RESPONSE);\n }\n\n return frontPage;\n }\n\n /**\n * Search for market insights by asset identifier.\n *\n * Accepts any identifier the API understands (CAIP-19 asset type, ticker\n * symbol, asset name, HyperLiquid perps market id, etc.) and forwards it\n * unchanged via the universal `asset` query parameter.\n *\n * Calls `GET ${baseUrl}/asset-summary?asset=<assetIdentifier>`.\n *\n * @param assetIdentifier - The asset identifier (e.g. `eip155:1/slip44:60`,\n * `ETH`, `Bitcoin`, `xyz:TSLA`).\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 response = await fetch(\n `${this.#baseUrl}/asset-summary?asset=${encodeURIComponent(assetIdentifier)}`,\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"]}
@@ -8,5 +8,6 @@ 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
+ INVALID_FRONT_PAGE_ID: 'Invalid front page id',
11
12
  };
12
13
  //# 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,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"]}
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;IACpD,qBAAqB,EAAE,uBAAuB;CACtC,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 INVALID_FRONT_PAGE_ID: 'Invalid front page id',\n} as const;\n"]}
@@ -5,5 +5,6 @@ export declare const AiDigestControllerErrorMessage: {
5
5
  readonly API_REQUEST_FAILED: "API request failed";
6
6
  readonly API_INVALID_RESPONSE: "API returned invalid response";
7
7
  readonly INVALID_ASSET_IDENTIFIER: "Invalid asset identifier";
8
+ readonly INVALID_FRONT_PAGE_ID: "Invalid front page id";
8
9
  };
9
10
  //# sourceMappingURL=ai-digest-constants.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-digest-constants.d.cts","sourceRoot":"","sources":["../src/ai-digest-constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAEnD,eAAO,MAAM,iBAAiB,QAAiB,CAAC;AAEhD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,eAAO,MAAM,8BAA8B;;;;CAIjC,CAAC"}
1
+ {"version":3,"file":"ai-digest-constants.d.cts","sourceRoot":"","sources":["../src/ai-digest-constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAEnD,eAAO,MAAM,iBAAiB,QAAiB,CAAC;AAEhD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,eAAO,MAAM,8BAA8B;;;;;CAKjC,CAAC"}
@@ -5,5 +5,6 @@ export declare const AiDigestControllerErrorMessage: {
5
5
  readonly API_REQUEST_FAILED: "API request failed";
6
6
  readonly API_INVALID_RESPONSE: "API returned invalid response";
7
7
  readonly INVALID_ASSET_IDENTIFIER: "Invalid asset identifier";
8
+ readonly INVALID_FRONT_PAGE_ID: "Invalid front page id";
8
9
  };
9
10
  //# sourceMappingURL=ai-digest-constants.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-digest-constants.d.mts","sourceRoot":"","sources":["../src/ai-digest-constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAEnD,eAAO,MAAM,iBAAiB,QAAiB,CAAC;AAEhD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,eAAO,MAAM,8BAA8B;;;;CAIjC,CAAC"}
1
+ {"version":3,"file":"ai-digest-constants.d.mts","sourceRoot":"","sources":["../src/ai-digest-constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAEnD,eAAO,MAAM,iBAAiB,QAAiB,CAAC;AAEhD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,eAAO,MAAM,8BAA8B;;;;;CAKjC,CAAC"}
@@ -5,5 +5,6 @@ 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
+ INVALID_FRONT_PAGE_ID: 'Invalid front page id',
8
9
  };
9
10
  //# 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,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"]}
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;IACpD,qBAAqB,EAAE,uBAAuB;CACtC,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 INVALID_FRONT_PAGE_ID: 'Invalid front page id',\n} as const;\n"]}
@@ -1 +1 @@
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?asset=<identifier>`.\n */\nexport type MarketInsightsReport = {\n /** Unique identifier for this digest, sourced from the API response envelope. */\n digestId: string;\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\n/**\n * A crypto asset related to a market overview trend.\n * Returned by the `/market-overview` API as a rich object.\n */\nexport type RelatedAsset = {\n /**\n * Human-readable asset name (e.g. \"Bitcoin\"). Optional — clients must fall\n * back to `symbol` when absent.\n */\n name?: string;\n /** Ticker symbol (e.g. \"BTC\"). The only field guaranteed to be present. */\n symbol: string;\n /**\n * CAIP-19 identifiers for this asset across chains. May be absent for\n * purely synthetic / perps-only assets (e.g. ETHFI). The service\n * normalises missing values to `[]`.\n */\n caip19?: string[];\n /**\n * Canonical source asset identifier (e.g. \"bitcoin\"). Optional — may be\n * absent when the API pipeline cannot enrich the asset record.\n */\n sourceAssetId?: string;\n /**\n * Optional HyperLiquid market identifiers for this asset (e.g. `BTC`, `ETH`,\n * `xyz:TSLA`). Covers both regular crypto tokens that trade on HyperLiquid\n * and purely synthetic perps assets. Use this to resolve Perps icon URLs via\n * `getAssetIconUrls` on clients when `caip19` is empty.\n */\n hlPerpsMarket?: string[];\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: RelatedAsset[];\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 trends: MarketOverviewTrend[];\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 any identifier the API understands — CAIP-19 asset type\n * (e.g. `eip155:1/slip44:60`), ticker symbol (e.g. `ETH`), asset name\n * (e.g. `Bitcoin`), or HyperLiquid perps market id (e.g. `xyz:TSLA`).\n *\n * Calls `GET /asset-summary?asset=<assetIdentifier>`.\n *\n * @param assetIdentifier - The asset identifier.\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
+ {"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?asset=<identifier>`.\n */\nexport type MarketInsightsReport = {\n /** Unique identifier for this digest, sourced from the API response envelope. */\n digestId: string;\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\n/**\n * A crypto asset related to a market overview trend.\n * Returned by the `/market-overview` API as a rich object.\n */\nexport type RelatedAsset = {\n /**\n * Human-readable asset name (e.g. \"Bitcoin\"). Optional — clients must fall\n * back to `symbol` when absent.\n */\n name?: string;\n /** Ticker symbol (e.g. \"BTC\"). The only field guaranteed to be present. */\n symbol: string;\n /**\n * CAIP-19 identifiers for this asset across chains. May be absent for\n * purely synthetic / perps-only assets (e.g. ETHFI). The service\n * normalises missing values to `[]`.\n */\n caip19?: string[];\n /**\n * Canonical source asset identifier (e.g. \"bitcoin\"). Optional — may be\n * absent when the API pipeline cannot enrich the asset record.\n */\n sourceAssetId?: string;\n /**\n * Optional HyperLiquid market identifiers for this asset (e.g. `BTC`, `ETH`,\n * `xyz:TSLA`). Covers both regular crypto tokens that trade on HyperLiquid\n * and purely synthetic perps assets. Use this to resolve Perps icon URLs via\n * `getAssetIconUrls` on clients when `caip19` is empty.\n */\n hlPerpsMarket?: string[];\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: RelatedAsset[];\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 trends: MarketOverviewTrend[];\n metadata?: AIResponseMetadata[];\n};\n\n/**\n * A single market overview item. Shares the exact same schema as a\n * {@link MarketOverviewTrend} — i.e. one entry of `MarketOverview.trends`.\n */\nexport type MarketOverviewItem = MarketOverviewTrend;\n\n/**\n * A market overview \"front page\": a single AI-selected item (mirroring the\n * front page of a newspaper) plus its call-to-action copy, addressable by id.\n *\n * Returned by `GET /market-overview/front-page/:id` (and `.../latest`). Unlike\n * `/market-overview`, which only ever returns the latest report, this lets\n * clients fetch an older item that has since dropped out of the report.\n */\nexport type MarketOverviewFrontPage = {\n /** Unique identifier of the front-page row (UUID). */\n id: string;\n /** The selected item — same schema as an individual market overview item. */\n item: MarketOverviewItem;\n /** Call-to-action title for the front-page item. */\n ctaTitle: string;\n /** Call-to-action description for the front-page item. */\n ctaDescription: string;\n /** ISO date string when the front-page row was created. */\n createdAt: string;\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 any identifier the API understands — CAIP-19 asset type\n * (e.g. `eip155:1/slip44:60`), ticker symbol (e.g. `ETH`), asset name\n * (e.g. `Bitcoin`), or HyperLiquid perps market id (e.g. `xyz:TSLA`).\n *\n * Calls `GET /asset-summary?asset=<assetIdentifier>`.\n *\n * @param assetIdentifier - The asset identifier.\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 /**\n * Fetch a single market overview front page by id.\n * Calls `GET /market-overview/front-page/:id`.\n *\n * @param id - The front-page identifier (UUID).\n * @returns The market overview front page, or `null` if none exists (404).\n */\n fetchFrontPageItem(id: string): Promise<MarketOverviewFrontPage | null>;\n};\n"]}
@@ -152,6 +152,31 @@ export type MarketOverview = {
152
152
  trends: MarketOverviewTrend[];
153
153
  metadata?: AIResponseMetadata[];
154
154
  };
155
+ /**
156
+ * A single market overview item. Shares the exact same schema as a
157
+ * {@link MarketOverviewTrend} — i.e. one entry of `MarketOverview.trends`.
158
+ */
159
+ export type MarketOverviewItem = MarketOverviewTrend;
160
+ /**
161
+ * A market overview "front page": a single AI-selected item (mirroring the
162
+ * front page of a newspaper) plus its call-to-action copy, addressable by id.
163
+ *
164
+ * Returned by `GET /market-overview/front-page/:id` (and `.../latest`). Unlike
165
+ * `/market-overview`, which only ever returns the latest report, this lets
166
+ * clients fetch an older item that has since dropped out of the report.
167
+ */
168
+ export type MarketOverviewFrontPage = {
169
+ /** Unique identifier of the front-page row (UUID). */
170
+ id: string;
171
+ /** The selected item — same schema as an individual market overview item. */
172
+ item: MarketOverviewItem;
173
+ /** Call-to-action title for the front-page item. */
174
+ ctaTitle: string;
175
+ /** Call-to-action description for the front-page item. */
176
+ ctaDescription: string;
177
+ /** ISO date string when the front-page row was created. */
178
+ createdAt: string;
179
+ };
155
180
  export type AiDigestControllerState = {
156
181
  marketInsights: Record<string, MarketInsightsEntry>;
157
182
  marketOverview: MarketOverviewEntry | null;
@@ -177,5 +202,13 @@ export type DigestService = {
177
202
  * @returns The market overview report, or `null` if none exists (404).
178
203
  */
179
204
  fetchMarketOverview(): Promise<MarketOverview | null>;
205
+ /**
206
+ * Fetch a single market overview front page by id.
207
+ * Calls `GET /market-overview/front-page/:id`.
208
+ *
209
+ * @param id - The front-page identifier (UUID).
210
+ * @returns The market overview front page, or `null` if none exists (404).
211
+ */
212
+ fetchFrontPageItem(id: string): Promise<MarketOverviewFrontPage | null>;
180
213
  };
181
214
  //# sourceMappingURL=ai-digest-types.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-digest-types.d.cts","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ai-digest-types.d.cts","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB,mCAAmC;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,kBAAkB;IAClB,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,OAAO,CAAC;AAC5C,MAAM,MAAM,mBAAmB,GAAG,KAAK,CAAC;AACxC,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAM1C;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,QAAQ,EACJ,cAAc,GACd,OAAO,GACP,YAAY,GACZ,WAAW,GACX,QAAQ,GACR,OAAO,CAAC;IACZ,uBAAuB;IACvB,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;IAC5C,4BAA4B;IAC5B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,iCAAiC;IACjC,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,iFAAiF;IACjF,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,+CAA+C;IAC/C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACjC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,+GAA+G;IAC/G,eAAe,EAAE,MAAM,CAAC;IACxB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,IAAI,EAAE,oBAAoB,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAMF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EACL,cAAc,GACd,OAAO,GACP,YAAY,GACZ,WAAW,GACX,QAAQ,GACR,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;IAC7C,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACjC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AAErD;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,6EAA6E;IAC7E,IAAI,EAAE,kBAAkB,CAAC;IACzB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,cAAc,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAMF,MAAM,MAAM,uBAAuB,GAAG;IACpC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IACpD,cAAc,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAC5C,CAAC;AAMF,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;IAE5E;;;;;OAKG;IACH,mBAAmB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAEtD;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;CACzE,CAAC"}
@@ -152,6 +152,31 @@ export type MarketOverview = {
152
152
  trends: MarketOverviewTrend[];
153
153
  metadata?: AIResponseMetadata[];
154
154
  };
155
+ /**
156
+ * A single market overview item. Shares the exact same schema as a
157
+ * {@link MarketOverviewTrend} — i.e. one entry of `MarketOverview.trends`.
158
+ */
159
+ export type MarketOverviewItem = MarketOverviewTrend;
160
+ /**
161
+ * A market overview "front page": a single AI-selected item (mirroring the
162
+ * front page of a newspaper) plus its call-to-action copy, addressable by id.
163
+ *
164
+ * Returned by `GET /market-overview/front-page/:id` (and `.../latest`). Unlike
165
+ * `/market-overview`, which only ever returns the latest report, this lets
166
+ * clients fetch an older item that has since dropped out of the report.
167
+ */
168
+ export type MarketOverviewFrontPage = {
169
+ /** Unique identifier of the front-page row (UUID). */
170
+ id: string;
171
+ /** The selected item — same schema as an individual market overview item. */
172
+ item: MarketOverviewItem;
173
+ /** Call-to-action title for the front-page item. */
174
+ ctaTitle: string;
175
+ /** Call-to-action description for the front-page item. */
176
+ ctaDescription: string;
177
+ /** ISO date string when the front-page row was created. */
178
+ createdAt: string;
179
+ };
155
180
  export type AiDigestControllerState = {
156
181
  marketInsights: Record<string, MarketInsightsEntry>;
157
182
  marketOverview: MarketOverviewEntry | null;
@@ -177,5 +202,13 @@ export type DigestService = {
177
202
  * @returns The market overview report, or `null` if none exists (404).
178
203
  */
179
204
  fetchMarketOverview(): Promise<MarketOverview | null>;
205
+ /**
206
+ * Fetch a single market overview front page by id.
207
+ * Calls `GET /market-overview/front-page/:id`.
208
+ *
209
+ * @param id - The front-page identifier (UUID).
210
+ * @returns The market overview front page, or `null` if none exists (404).
211
+ */
212
+ fetchFrontPageItem(id: string): Promise<MarketOverviewFrontPage | null>;
180
213
  };
181
214
  //# sourceMappingURL=ai-digest-types.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-digest-types.d.mts","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ai-digest-types.d.mts","sourceRoot":"","sources":["../src/ai-digest-types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
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?asset=<identifier>`.\n */\nexport type MarketInsightsReport = {\n /** Unique identifier for this digest, sourced from the API response envelope. */\n digestId: string;\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\n/**\n * A crypto asset related to a market overview trend.\n * Returned by the `/market-overview` API as a rich object.\n */\nexport type RelatedAsset = {\n /**\n * Human-readable asset name (e.g. \"Bitcoin\"). Optional — clients must fall\n * back to `symbol` when absent.\n */\n name?: string;\n /** Ticker symbol (e.g. \"BTC\"). The only field guaranteed to be present. */\n symbol: string;\n /**\n * CAIP-19 identifiers for this asset across chains. May be absent for\n * purely synthetic / perps-only assets (e.g. ETHFI). The service\n * normalises missing values to `[]`.\n */\n caip19?: string[];\n /**\n * Canonical source asset identifier (e.g. \"bitcoin\"). Optional — may be\n * absent when the API pipeline cannot enrich the asset record.\n */\n sourceAssetId?: string;\n /**\n * Optional HyperLiquid market identifiers for this asset (e.g. `BTC`, `ETH`,\n * `xyz:TSLA`). Covers both regular crypto tokens that trade on HyperLiquid\n * and purely synthetic perps assets. Use this to resolve Perps icon URLs via\n * `getAssetIconUrls` on clients when `caip19` is empty.\n */\n hlPerpsMarket?: string[];\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: RelatedAsset[];\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 trends: MarketOverviewTrend[];\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 any identifier the API understands — CAIP-19 asset type\n * (e.g. `eip155:1/slip44:60`), ticker symbol (e.g. `ETH`), asset name\n * (e.g. `Bitcoin`), or HyperLiquid perps market id (e.g. `xyz:TSLA`).\n *\n * Calls `GET /asset-summary?asset=<assetIdentifier>`.\n *\n * @param assetIdentifier - The asset identifier.\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
+ {"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?asset=<identifier>`.\n */\nexport type MarketInsightsReport = {\n /** Unique identifier for this digest, sourced from the API response envelope. */\n digestId: string;\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\n/**\n * A crypto asset related to a market overview trend.\n * Returned by the `/market-overview` API as a rich object.\n */\nexport type RelatedAsset = {\n /**\n * Human-readable asset name (e.g. \"Bitcoin\"). Optional — clients must fall\n * back to `symbol` when absent.\n */\n name?: string;\n /** Ticker symbol (e.g. \"BTC\"). The only field guaranteed to be present. */\n symbol: string;\n /**\n * CAIP-19 identifiers for this asset across chains. May be absent for\n * purely synthetic / perps-only assets (e.g. ETHFI). The service\n * normalises missing values to `[]`.\n */\n caip19?: string[];\n /**\n * Canonical source asset identifier (e.g. \"bitcoin\"). Optional — may be\n * absent when the API pipeline cannot enrich the asset record.\n */\n sourceAssetId?: string;\n /**\n * Optional HyperLiquid market identifiers for this asset (e.g. `BTC`, `ETH`,\n * `xyz:TSLA`). Covers both regular crypto tokens that trade on HyperLiquid\n * and purely synthetic perps assets. Use this to resolve Perps icon URLs via\n * `getAssetIconUrls` on clients when `caip19` is empty.\n */\n hlPerpsMarket?: string[];\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: RelatedAsset[];\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 trends: MarketOverviewTrend[];\n metadata?: AIResponseMetadata[];\n};\n\n/**\n * A single market overview item. Shares the exact same schema as a\n * {@link MarketOverviewTrend} — i.e. one entry of `MarketOverview.trends`.\n */\nexport type MarketOverviewItem = MarketOverviewTrend;\n\n/**\n * A market overview \"front page\": a single AI-selected item (mirroring the\n * front page of a newspaper) plus its call-to-action copy, addressable by id.\n *\n * Returned by `GET /market-overview/front-page/:id` (and `.../latest`). Unlike\n * `/market-overview`, which only ever returns the latest report, this lets\n * clients fetch an older item that has since dropped out of the report.\n */\nexport type MarketOverviewFrontPage = {\n /** Unique identifier of the front-page row (UUID). */\n id: string;\n /** The selected item — same schema as an individual market overview item. */\n item: MarketOverviewItem;\n /** Call-to-action title for the front-page item. */\n ctaTitle: string;\n /** Call-to-action description for the front-page item. */\n ctaDescription: string;\n /** ISO date string when the front-page row was created. */\n createdAt: string;\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 any identifier the API understands — CAIP-19 asset type\n * (e.g. `eip155:1/slip44:60`), ticker symbol (e.g. `ETH`), asset name\n * (e.g. `Bitcoin`), or HyperLiquid perps market id (e.g. `xyz:TSLA`).\n *\n * Calls `GET /asset-summary?asset=<assetIdentifier>`.\n *\n * @param assetIdentifier - The asset identifier.\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 /**\n * Fetch a single market overview front page by id.\n * Calls `GET /market-overview/front-page/:id`.\n *\n * @param id - The front-page identifier (UUID).\n * @returns The market overview front page, or `null` if none exists (404).\n */\n fetchFrontPageItem(id: string): Promise<MarketOverviewFrontPage | null>;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAQA,+DAG8B;AAF5B,wHAAA,kBAAkB,OAAA;AAClB,uIAAA,iCAAiC,OAAA;AAQnC,yDAAoD;AAA3C,kHAAA,eAAe,OAAA;AAqBxB,iEAK+B;AAJ7B,6HAAA,cAAc,OAA0B;AACxC,wHAAA,iBAAiB,OAAA;AACjB,wHAAA,iBAAiB,OAAA;AACjB,qIAAA,8BAA8B,OAAA","sourcesContent":["export type {\n AiDigestControllerActions,\n AiDigestControllerEvents,\n AiDigestControllerGetStateAction,\n AiDigestControllerMessenger,\n AiDigestControllerOptions,\n AiDigestControllerStateChangeEvent,\n} from './AiDigestController';\nexport {\n AiDigestController,\n getDefaultAiDigestControllerState,\n} from './AiDigestController';\nexport type {\n AiDigestControllerFetchMarketInsightsAction,\n AiDigestControllerFetchMarketOverviewAction,\n} from './AiDigestController-method-action-types';\n\nexport type { AiDigestServiceConfig } from './AiDigestService';\nexport { AiDigestService } from './AiDigestService';\n\nexport type {\n AiDigestControllerState,\n AIResponseMetadata,\n Article,\n DigestService,\n MarketInsightsArticle,\n MarketInsightsEntry,\n MarketInsightsReport,\n MarketInsightsSource,\n MarketInsightsTrend,\n MarketInsightsTweet,\n MarketOverview,\n MarketOverviewEntry,\n MarketOverviewTrend,\n RelatedAsset,\n Source,\n Tweet,\n} from './ai-digest-types';\n\nexport {\n controllerName as aiDigestControllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n AiDigestControllerErrorMessage,\n} from './ai-digest-constants';\n"]}
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAQA,+DAG8B;AAF5B,wHAAA,kBAAkB,OAAA;AAClB,uIAAA,iCAAiC,OAAA;AASnC,yDAAoD;AAA3C,kHAAA,eAAe,OAAA;AAuBxB,iEAK+B;AAJ7B,6HAAA,cAAc,OAA0B;AACxC,wHAAA,iBAAiB,OAAA;AACjB,wHAAA,iBAAiB,OAAA;AACjB,qIAAA,8BAA8B,OAAA","sourcesContent":["export type {\n AiDigestControllerActions,\n AiDigestControllerEvents,\n AiDigestControllerGetStateAction,\n AiDigestControllerMessenger,\n AiDigestControllerOptions,\n AiDigestControllerStateChangeEvent,\n} from './AiDigestController';\nexport {\n AiDigestController,\n getDefaultAiDigestControllerState,\n} from './AiDigestController';\nexport type {\n AiDigestControllerFetchMarketInsightsAction,\n AiDigestControllerFetchMarketOverviewAction,\n AiDigestControllerFetchFrontPageItemAction,\n} from './AiDigestController-method-action-types';\n\nexport type { AiDigestServiceConfig } from './AiDigestService';\nexport { AiDigestService } from './AiDigestService';\n\nexport type {\n AiDigestControllerState,\n AIResponseMetadata,\n Article,\n DigestService,\n MarketInsightsArticle,\n MarketInsightsEntry,\n MarketInsightsReport,\n MarketInsightsSource,\n MarketInsightsTrend,\n MarketInsightsTweet,\n MarketOverview,\n MarketOverviewEntry,\n MarketOverviewFrontPage,\n MarketOverviewItem,\n MarketOverviewTrend,\n RelatedAsset,\n Source,\n Tweet,\n} from './ai-digest-types';\n\nexport {\n controllerName as aiDigestControllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n AiDigestControllerErrorMessage,\n} from './ai-digest-constants';\n"]}
package/dist/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
1
  export type { AiDigestControllerActions, AiDigestControllerEvents, AiDigestControllerGetStateAction, AiDigestControllerMessenger, AiDigestControllerOptions, AiDigestControllerStateChangeEvent, } from "./AiDigestController.cjs";
2
2
  export { AiDigestController, getDefaultAiDigestControllerState, } from "./AiDigestController.cjs";
3
- export type { AiDigestControllerFetchMarketInsightsAction, AiDigestControllerFetchMarketOverviewAction, } from "./AiDigestController-method-action-types.cjs";
3
+ export type { AiDigestControllerFetchMarketInsightsAction, AiDigestControllerFetchMarketOverviewAction, AiDigestControllerFetchFrontPageItemAction, } from "./AiDigestController-method-action-types.cjs";
4
4
  export type { AiDigestServiceConfig } from "./AiDigestService.cjs";
5
5
  export { AiDigestService } from "./AiDigestService.cjs";
6
- export type { AiDigestControllerState, AIResponseMetadata, Article, DigestService, MarketInsightsArticle, MarketInsightsEntry, MarketInsightsReport, MarketInsightsSource, MarketInsightsTrend, MarketInsightsTweet, MarketOverview, MarketOverviewEntry, MarketOverviewTrend, RelatedAsset, Source, Tweet, } from "./ai-digest-types.cjs";
6
+ export type { AiDigestControllerState, AIResponseMetadata, Article, DigestService, MarketInsightsArticle, MarketInsightsEntry, MarketInsightsReport, MarketInsightsSource, MarketInsightsTrend, MarketInsightsTweet, MarketOverview, MarketOverviewEntry, MarketOverviewFrontPage, MarketOverviewItem, MarketOverviewTrend, RelatedAsset, Source, Tweet, } from "./ai-digest-types.cjs";
7
7
  export { controllerName as aiDigestControllerName, CACHE_DURATION_MS, MAX_CACHE_ENTRIES, AiDigestControllerErrorMessage, } from "./ai-digest-constants.cjs";
8
8
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,yBAAyB,EACzB,wBAAwB,EACxB,gCAAgC,EAChC,2BAA2B,EAC3B,yBAAyB,EACzB,kCAAkC,GACnC,iCAA6B;AAC9B,OAAO,EACL,kBAAkB,EAClB,iCAAiC,GAClC,iCAA6B;AAC9B,YAAY,EACV,2CAA2C,EAC3C,2CAA2C,GAC5C,qDAAiD;AAElD,YAAY,EAAE,qBAAqB,EAAE,8BAA0B;AAC/D,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAEpD,YAAY,EACV,uBAAuB,EACvB,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACZ,MAAM,EACN,KAAK,GACN,8BAA0B;AAE3B,OAAO,EACL,cAAc,IAAI,sBAAsB,EACxC,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,GAC/B,kCAA8B"}
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,yBAAyB,EACzB,wBAAwB,EACxB,gCAAgC,EAChC,2BAA2B,EAC3B,yBAAyB,EACzB,kCAAkC,GACnC,iCAA6B;AAC9B,OAAO,EACL,kBAAkB,EAClB,iCAAiC,GAClC,iCAA6B;AAC9B,YAAY,EACV,2CAA2C,EAC3C,2CAA2C,EAC3C,0CAA0C,GAC3C,qDAAiD;AAElD,YAAY,EAAE,qBAAqB,EAAE,8BAA0B;AAC/D,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAEpD,YAAY,EACV,uBAAuB,EACvB,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,MAAM,EACN,KAAK,GACN,8BAA0B;AAE3B,OAAO,EACL,cAAc,IAAI,sBAAsB,EACxC,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,GAC/B,kCAA8B"}
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
1
  export type { AiDigestControllerActions, AiDigestControllerEvents, AiDigestControllerGetStateAction, AiDigestControllerMessenger, AiDigestControllerOptions, AiDigestControllerStateChangeEvent, } from "./AiDigestController.mjs";
2
2
  export { AiDigestController, getDefaultAiDigestControllerState, } from "./AiDigestController.mjs";
3
- export type { AiDigestControllerFetchMarketInsightsAction, AiDigestControllerFetchMarketOverviewAction, } from "./AiDigestController-method-action-types.mjs";
3
+ export type { AiDigestControllerFetchMarketInsightsAction, AiDigestControllerFetchMarketOverviewAction, AiDigestControllerFetchFrontPageItemAction, } from "./AiDigestController-method-action-types.mjs";
4
4
  export type { AiDigestServiceConfig } from "./AiDigestService.mjs";
5
5
  export { AiDigestService } from "./AiDigestService.mjs";
6
- export type { AiDigestControllerState, AIResponseMetadata, Article, DigestService, MarketInsightsArticle, MarketInsightsEntry, MarketInsightsReport, MarketInsightsSource, MarketInsightsTrend, MarketInsightsTweet, MarketOverview, MarketOverviewEntry, MarketOverviewTrend, RelatedAsset, Source, Tweet, } from "./ai-digest-types.mjs";
6
+ export type { AiDigestControllerState, AIResponseMetadata, Article, DigestService, MarketInsightsArticle, MarketInsightsEntry, MarketInsightsReport, MarketInsightsSource, MarketInsightsTrend, MarketInsightsTweet, MarketOverview, MarketOverviewEntry, MarketOverviewFrontPage, MarketOverviewItem, MarketOverviewTrend, RelatedAsset, Source, Tweet, } from "./ai-digest-types.mjs";
7
7
  export { controllerName as aiDigestControllerName, CACHE_DURATION_MS, MAX_CACHE_ENTRIES, AiDigestControllerErrorMessage, } from "./ai-digest-constants.mjs";
8
8
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,yBAAyB,EACzB,wBAAwB,EACxB,gCAAgC,EAChC,2BAA2B,EAC3B,yBAAyB,EACzB,kCAAkC,GACnC,iCAA6B;AAC9B,OAAO,EACL,kBAAkB,EAClB,iCAAiC,GAClC,iCAA6B;AAC9B,YAAY,EACV,2CAA2C,EAC3C,2CAA2C,GAC5C,qDAAiD;AAElD,YAAY,EAAE,qBAAqB,EAAE,8BAA0B;AAC/D,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAEpD,YAAY,EACV,uBAAuB,EACvB,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACZ,MAAM,EACN,KAAK,GACN,8BAA0B;AAE3B,OAAO,EACL,cAAc,IAAI,sBAAsB,EACxC,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,GAC/B,kCAA8B"}
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,yBAAyB,EACzB,wBAAwB,EACxB,gCAAgC,EAChC,2BAA2B,EAC3B,yBAAyB,EACzB,kCAAkC,GACnC,iCAA6B;AAC9B,OAAO,EACL,kBAAkB,EAClB,iCAAiC,GAClC,iCAA6B;AAC9B,YAAY,EACV,2CAA2C,EAC3C,2CAA2C,EAC3C,0CAA0C,GAC3C,qDAAiD;AAElD,YAAY,EAAE,qBAAqB,EAAE,8BAA0B;AAC/D,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAEpD,YAAY,EACV,uBAAuB,EACvB,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,MAAM,EACN,KAAK,GACN,8BAA0B;AAE3B,OAAO,EACL,cAAc,IAAI,sBAAsB,EACxC,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,GAC/B,kCAA8B"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,kBAAkB,EAClB,iCAAiC,EAClC,iCAA6B;AAO9B,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAqBpD,OAAO,EACL,cAAc,IAAI,sBAAsB,EACxC,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,EAC/B,kCAA8B","sourcesContent":["export type {\n AiDigestControllerActions,\n AiDigestControllerEvents,\n AiDigestControllerGetStateAction,\n AiDigestControllerMessenger,\n AiDigestControllerOptions,\n AiDigestControllerStateChangeEvent,\n} from './AiDigestController';\nexport {\n AiDigestController,\n getDefaultAiDigestControllerState,\n} from './AiDigestController';\nexport type {\n AiDigestControllerFetchMarketInsightsAction,\n AiDigestControllerFetchMarketOverviewAction,\n} from './AiDigestController-method-action-types';\n\nexport type { AiDigestServiceConfig } from './AiDigestService';\nexport { AiDigestService } from './AiDigestService';\n\nexport type {\n AiDigestControllerState,\n AIResponseMetadata,\n Article,\n DigestService,\n MarketInsightsArticle,\n MarketInsightsEntry,\n MarketInsightsReport,\n MarketInsightsSource,\n MarketInsightsTrend,\n MarketInsightsTweet,\n MarketOverview,\n MarketOverviewEntry,\n MarketOverviewTrend,\n RelatedAsset,\n Source,\n Tweet,\n} from './ai-digest-types';\n\nexport {\n controllerName as aiDigestControllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n AiDigestControllerErrorMessage,\n} from './ai-digest-constants';\n"]}
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,kBAAkB,EAClB,iCAAiC,EAClC,iCAA6B;AAQ9B,OAAO,EAAE,eAAe,EAAE,8BAA0B;AAuBpD,OAAO,EACL,cAAc,IAAI,sBAAsB,EACxC,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,EAC/B,kCAA8B","sourcesContent":["export type {\n AiDigestControllerActions,\n AiDigestControllerEvents,\n AiDigestControllerGetStateAction,\n AiDigestControllerMessenger,\n AiDigestControllerOptions,\n AiDigestControllerStateChangeEvent,\n} from './AiDigestController';\nexport {\n AiDigestController,\n getDefaultAiDigestControllerState,\n} from './AiDigestController';\nexport type {\n AiDigestControllerFetchMarketInsightsAction,\n AiDigestControllerFetchMarketOverviewAction,\n AiDigestControllerFetchFrontPageItemAction,\n} from './AiDigestController-method-action-types';\n\nexport type { AiDigestServiceConfig } from './AiDigestService';\nexport { AiDigestService } from './AiDigestService';\n\nexport type {\n AiDigestControllerState,\n AIResponseMetadata,\n Article,\n DigestService,\n MarketInsightsArticle,\n MarketInsightsEntry,\n MarketInsightsReport,\n MarketInsightsSource,\n MarketInsightsTrend,\n MarketInsightsTweet,\n MarketOverview,\n MarketOverviewEntry,\n MarketOverviewFrontPage,\n MarketOverviewItem,\n MarketOverviewTrend,\n RelatedAsset,\n Source,\n Tweet,\n} from './ai-digest-types';\n\nexport {\n controllerName as aiDigestControllerName,\n CACHE_DURATION_MS,\n MAX_CACHE_ENTRIES,\n AiDigestControllerErrorMessage,\n} from './ai-digest-constants';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/ai-controllers",
3
- "version": "0.7.0-preview-b3fa32653",
3
+ "version": "0.8.0-preview-34f2bcbf7",
4
4
  "description": "A collection of AI-related controllers",
5
5
  "keywords": [
6
6
  "Ethereum",