@metamask/money-account-api-data-service 0.1.0

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 (78) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +21 -0
  3. package/LICENSE.APACHE2 +201 -0
  4. package/LICENSE.MIT +21 -0
  5. package/README.md +26 -0
  6. package/dist/constants.cjs +31 -0
  7. package/dist/constants.cjs.map +1 -0
  8. package/dist/constants.d.cts +23 -0
  9. package/dist/constants.d.cts.map +1 -0
  10. package/dist/constants.d.mts +23 -0
  11. package/dist/constants.d.mts.map +1 -0
  12. package/dist/constants.mjs +28 -0
  13. package/dist/constants.mjs.map +1 -0
  14. package/dist/errors.cjs +16 -0
  15. package/dist/errors.cjs.map +1 -0
  16. package/dist/errors.d.cts +8 -0
  17. package/dist/errors.d.cts.map +1 -0
  18. package/dist/errors.d.mts +8 -0
  19. package/dist/errors.d.mts.map +1 -0
  20. package/dist/errors.mjs +12 -0
  21. package/dist/errors.mjs.map +1 -0
  22. package/dist/index.cjs +10 -0
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.cts +8 -0
  25. package/dist/index.d.cts.map +1 -0
  26. package/dist/index.d.mts +8 -0
  27. package/dist/index.d.mts.map +1 -0
  28. package/dist/index.mjs +4 -0
  29. package/dist/index.mjs.map +1 -0
  30. package/dist/logger.cjs +7 -0
  31. package/dist/logger.cjs.map +1 -0
  32. package/dist/logger.d.cts +5 -0
  33. package/dist/logger.d.cts.map +1 -0
  34. package/dist/logger.d.mts +5 -0
  35. package/dist/logger.d.mts.map +1 -0
  36. package/dist/logger.mjs +4 -0
  37. package/dist/logger.mjs.map +1 -0
  38. package/dist/money-account-api-data-service-method-action-types.cjs +7 -0
  39. package/dist/money-account-api-data-service-method-action-types.cjs.map +1 -0
  40. package/dist/money-account-api-data-service-method-action-types.d.cts +60 -0
  41. package/dist/money-account-api-data-service-method-action-types.d.cts.map +1 -0
  42. package/dist/money-account-api-data-service-method-action-types.d.mts +60 -0
  43. package/dist/money-account-api-data-service-method-action-types.d.mts.map +1 -0
  44. package/dist/money-account-api-data-service-method-action-types.mjs +6 -0
  45. package/dist/money-account-api-data-service-method-action-types.mjs.map +1 -0
  46. package/dist/money-account-api-data-service.cjs +228 -0
  47. package/dist/money-account-api-data-service.cjs.map +1 -0
  48. package/dist/money-account-api-data-service.d.cts +112 -0
  49. package/dist/money-account-api-data-service.d.cts.map +1 -0
  50. package/dist/money-account-api-data-service.d.mts +112 -0
  51. package/dist/money-account-api-data-service.d.mts.map +1 -0
  52. package/dist/money-account-api-data-service.mjs +224 -0
  53. package/dist/money-account-api-data-service.mjs.map +1 -0
  54. package/dist/response.types.cjs +3 -0
  55. package/dist/response.types.cjs.map +1 -0
  56. package/dist/response.types.d.cts +78 -0
  57. package/dist/response.types.d.cts.map +1 -0
  58. package/dist/response.types.d.mts +78 -0
  59. package/dist/response.types.d.mts.map +1 -0
  60. package/dist/response.types.mjs +2 -0
  61. package/dist/response.types.mjs.map +1 -0
  62. package/dist/structs.cjs +89 -0
  63. package/dist/structs.cjs.map +1 -0
  64. package/dist/structs.d.cts +230 -0
  65. package/dist/structs.d.cts.map +1 -0
  66. package/dist/structs.d.mts +230 -0
  67. package/dist/structs.d.mts.map +1 -0
  68. package/dist/structs.mjs +86 -0
  69. package/dist/structs.mjs.map +1 -0
  70. package/dist/types.cjs +3 -0
  71. package/dist/types.cjs.map +1 -0
  72. package/dist/types.d.cts +30 -0
  73. package/dist/types.d.cts.map +1 -0
  74. package/dist/types.d.mts +30 -0
  75. package/dist/types.d.mts.map +1 -0
  76. package/dist/types.mjs +2 -0
  77. package/dist/types.mjs.map +1 -0
  78. package/package.json +79 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"money-account-api-data-service.d.mts","sourceRoot":"","sources":["../src/money-account-api-data-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,oCAAoC,EACpC,kCAAkC,EACnC,oCAAoC;AACrC,OAAO,EAAE,eAAe,EAAE,oCAAoC;AAC9D,OAAO,KAAK,EAAE,0BAA0B,EAAE,mCAAmC;AAE7E,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAGrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,6BAA6B;AAE9D,OAAO,EAEL,GAAG,EAGJ,wBAAoB;AAGrB,OAAO,KAAK,EAAE,uCAAuC,EAAE,iEAA6D;AACpH,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACpB,6BAAyB;AAO1B,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,kBAAkB,EACnB,oBAAgB;AAIjB;;;GAGG;AACH,eAAO,MAAM,WAAW,+BAA+B,CAAC;AAaxD;;GAEG;AACH,MAAM,MAAM,iDAAiD,GAC3D,kCAAkC,CAAC,OAAO,WAAW,CAAC,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,iCAAiC,GACzC,uCAAuC,GACvC,iDAAiD,CAAC;AAEtD;;GAEG;AACH,KAAK,cAAc,GAAG,KAAK,CAAC;AAE5B;;GAEG;AACH,MAAM,MAAM,2CAA2C,GACrD,4BAA4B,CAAC,OAAO,WAAW,CAAC,CAAC;AAEnD;;;GAGG;AACH,MAAM,MAAM,mDAAmD,GAC7D,oCAAoC,CAAC,OAAO,WAAW,CAAC,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,gCAAgC,GACxC,2CAA2C,GAC3C,mDAAmD,CAAC;AAExD;;;GAGG;AACH,KAAK,aAAa,GAAG,KAAK,CAAC;AAE3B;;;GAGG;AACH,MAAM,MAAM,mCAAmC,GAAG,SAAS,CACzD,OAAO,WAAW,EAClB,iCAAiC,GAAG,cAAc,EAClD,gCAAgC,GAAG,aAAa,CACjD,CAAC;AAIF;;;GAGG;AACH,qBAAa,0BAA2B,SAAQ,eAAe,CAC7D,OAAO,WAAW,EAClB,mCAAmC,CACpC;;IAGC;;;;;;;;;OASG;gBACS,EACV,SAAS,EACT,GAAa,EACb,iBAAsB,EACtB,aAAkB,GACnB,EAAE;QACD,SAAS,EAAE,mCAAmC,CAAC;QAC/C,GAAG,CAAC,EAAE,GAAG,CAAC;QACV,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;QACtC,aAAa,CAAC,EAAE,0BAA0B,CAAC;KAC5C;IAuBD;;;;;OAKG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAiChE;;;;;;;OAOG;IACG,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,gBAAgB,CAAC;IA+C5B;;;;;;;;;;;;OAYG;IACG,YAAY,CAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,eAAe,CAAC;IA2D3B;;;;;;OAMG;IACG,gBAAgB,CACpB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,mBAAmB,CAAC;CA+ChC"}
@@ -0,0 +1,224 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _MoneyAccountApiDataService_baseUrl;
13
+ import { BaseDataService } from "@metamask/base-data-service";
14
+ import { handleWhen, HttpError } from "@metamask/controller-utils";
15
+ import { validate } from "@metamask/superstruct";
16
+ import { DEFAULT_STALE_TIME_MS, Env, MONEY_ACCOUNT_API_URL_MAP, RATE_HISTORY_STALE_TIME_MS } from "./constants.mjs";
17
+ import { MoneyAccountApiResponseValidationError } from "./errors.mjs";
18
+ import { projectLogger, createModuleLogger } from "./logger.mjs";
19
+ import { HistoryResponseStruct, InterestResponseStruct, PositionResponseStruct, RateHistoryResponseStruct } from "./structs.mjs";
20
+ // === GENERAL ===
21
+ /**
22
+ * The name of the {@link MoneyAccountApiDataService}, used to namespace the
23
+ * service's actions and events.
24
+ */
25
+ export const serviceName = 'MoneyAccountApiDataService';
26
+ const log = createModuleLogger(projectLogger, serviceName);
27
+ // === MESSENGER ===
28
+ const MESSENGER_EXPOSED_METHODS = [
29
+ 'fetchPositions',
30
+ 'fetchInterest',
31
+ 'fetchHistory',
32
+ 'fetchRateHistory',
33
+ ];
34
+ // === SERVICE DEFINITION ===
35
+ /**
36
+ * Data service responsible for fetching positions, interest, cash-flow
37
+ * history, and vault rate history from the Money Account APY Tracking API.
38
+ */
39
+ export class MoneyAccountApiDataService extends BaseDataService {
40
+ /**
41
+ * Constructs a new MoneyAccountApiDataService.
42
+ *
43
+ * @param args - The constructor arguments.
44
+ * @param args.messenger - The messenger suited for this service.
45
+ * @param args.env - The target environment. Defaults to production.
46
+ * @param args.queryClientConfig - Configuration for the underlying TanStack
47
+ * Query client.
48
+ * @param args.policyOptions - Options to pass to `createServicePolicy`.
49
+ */
50
+ constructor({ messenger, env = Env.PRD, queryClientConfig = {}, policyOptions = {}, }) {
51
+ super({
52
+ name: serviceName,
53
+ messenger,
54
+ queryClientConfig,
55
+ policyOptions: {
56
+ retryFilterPolicy: handleWhen((error) => !(error instanceof MoneyAccountApiResponseValidationError)),
57
+ ...policyOptions,
58
+ },
59
+ });
60
+ _MoneyAccountApiDataService_baseUrl.set(this, void 0);
61
+ __classPrivateFieldSet(this, _MoneyAccountApiDataService_baseUrl, MONEY_ACCOUNT_API_URL_MAP[env], "f");
62
+ this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
63
+ log('Initialized', { env, baseUrl: __classPrivateFieldGet(this, _MoneyAccountApiDataService_baseUrl, "f") });
64
+ }
65
+ /**
66
+ * Fetches the current vault positions for a given user address.
67
+ *
68
+ * @param address - The user's Ethereum address.
69
+ * @returns The position response containing vault positions.
70
+ */
71
+ async fetchPositions(address) {
72
+ const url = new URL(`/v1/positions/${address.toLowerCase()}`, __classPrivateFieldGet(this, _MoneyAccountApiDataService_baseUrl, "f"));
73
+ return this.fetchQuery({
74
+ queryKey: [`${this.name}:fetchPositions`, address.toLowerCase()],
75
+ staleTime: DEFAULT_STALE_TIME_MS,
76
+ queryFn: async () => {
77
+ const response = await fetch(url);
78
+ if (!response.ok) {
79
+ throw new HttpError(response.status, `Money Account API positions request failed with status '${response.status}'`);
80
+ }
81
+ const json = await response.json();
82
+ const [error, validated] = validate(json, PositionResponseStruct);
83
+ if (error) {
84
+ throw new MoneyAccountApiResponseValidationError(`Malformed response from positions endpoint: ${error.message}`);
85
+ }
86
+ return validated;
87
+ },
88
+ });
89
+ }
90
+ /**
91
+ * Fetches the interest earned for a given address and vault over a
92
+ * specified time window.
93
+ *
94
+ * @param address - The user's Ethereum address.
95
+ * @param options - Options specifying vault, window, and optional chain ID.
96
+ * @returns The interest response.
97
+ */
98
+ async fetchInterest(address, options) {
99
+ const url = new URL(`/v1/positions/${address.toLowerCase()}/interest`, __classPrivateFieldGet(this, _MoneyAccountApiDataService_baseUrl, "f"));
100
+ url.searchParams.append('vault_address', options.vaultAddress.toLowerCase());
101
+ url.searchParams.append('window', options.window);
102
+ if (options.chainId !== undefined) {
103
+ url.searchParams.append('chain_id', String(options.chainId));
104
+ }
105
+ return this.fetchQuery({
106
+ queryKey: [
107
+ `${this.name}:fetchInterest`,
108
+ address.toLowerCase(),
109
+ options.vaultAddress.toLowerCase(),
110
+ options.window,
111
+ ...(options.chainId === undefined ? [] : [options.chainId]),
112
+ ],
113
+ staleTime: DEFAULT_STALE_TIME_MS,
114
+ queryFn: async () => {
115
+ const response = await fetch(url);
116
+ if (!response.ok) {
117
+ throw new HttpError(response.status, `Money Account API interest request failed with status '${response.status}'`);
118
+ }
119
+ const json = await response.json();
120
+ const [error, validated] = validate(json, InterestResponseStruct);
121
+ if (error) {
122
+ throw new MoneyAccountApiResponseValidationError(`Malformed response from interest endpoint: ${error.message}`);
123
+ }
124
+ return validated;
125
+ },
126
+ });
127
+ }
128
+ /**
129
+ * Fetches cursor-paginated cash-flow history for a given address.
130
+ * Uses `fetchInfiniteQuery` for proper TanStack Query pagination semantics.
131
+ *
132
+ * When paginating, consumers must re-pass the same filter options
133
+ * (`vaultAddress`, `chainId`, `limit`) alongside `cursor` on every page
134
+ * request. This ensures the query key matches the original infinite query
135
+ * and that the HTTP request includes the correct filters.
136
+ *
137
+ * @param address - The user's Ethereum address.
138
+ * @param options - Optional filtering and pagination options.
139
+ * @returns The history response containing cash-flow entries for the requested page.
140
+ */
141
+ async fetchHistory(address, options) {
142
+ const normalizedAddress = address.toLowerCase();
143
+ const normalizedVault = options?.vaultAddress?.toLowerCase() ?? null;
144
+ return this.fetchInfiniteQuery({
145
+ queryKey: [
146
+ `${this.name}:fetchHistory`,
147
+ normalizedAddress,
148
+ normalizedVault,
149
+ options?.chainId ?? null,
150
+ options?.limit ?? null,
151
+ ],
152
+ staleTime: DEFAULT_STALE_TIME_MS,
153
+ queryFn: async (context) => {
154
+ const cursor = context.pageParam;
155
+ const url = new URL(`/v1/positions/${normalizedAddress}/history`, __classPrivateFieldGet(this, _MoneyAccountApiDataService_baseUrl, "f"));
156
+ if (normalizedVault) {
157
+ url.searchParams.append('vault_address', normalizedVault);
158
+ }
159
+ if (options?.chainId !== undefined) {
160
+ url.searchParams.append('chain_id', String(options.chainId));
161
+ }
162
+ if (cursor) {
163
+ url.searchParams.append('cursor', cursor);
164
+ }
165
+ if (options?.limit !== undefined) {
166
+ url.searchParams.append('limit', String(options.limit));
167
+ }
168
+ const response = await fetch(url);
169
+ if (!response.ok) {
170
+ throw new HttpError(response.status, `Money Account API history request failed with status '${response.status}'`);
171
+ }
172
+ const json = await response.json();
173
+ const [error, validated] = validate(json, HistoryResponseStruct);
174
+ if (error) {
175
+ throw new MoneyAccountApiResponseValidationError(`Malformed response from history endpoint: ${error.message}`);
176
+ }
177
+ return validated;
178
+ },
179
+ }, options?.cursor ?? undefined);
180
+ }
181
+ /**
182
+ * Fetches the exchange-rate time series for a given vault.
183
+ *
184
+ * @param vaultAddress - The vault's Ethereum address.
185
+ * @param options - Optional range and chain ID filters.
186
+ * @returns The rate history response.
187
+ */
188
+ async fetchRateHistory(vaultAddress, options) {
189
+ const url = new URL(`/v1/vaults/${vaultAddress.toLowerCase()}/rate-history`, __classPrivateFieldGet(this, _MoneyAccountApiDataService_baseUrl, "f"));
190
+ if (options?.chainId !== undefined) {
191
+ url.searchParams.append('chain_id', String(options.chainId));
192
+ }
193
+ if (options?.from) {
194
+ url.searchParams.append('from', options.from);
195
+ }
196
+ if (options?.to) {
197
+ url.searchParams.append('to', options.to);
198
+ }
199
+ return this.fetchQuery({
200
+ queryKey: [
201
+ `${this.name}:fetchRateHistory`,
202
+ vaultAddress.toLowerCase(),
203
+ ...(options?.chainId === undefined ? [null] : [options.chainId]),
204
+ ...(options?.from ? [options.from] : [null]),
205
+ ...(options?.to ? [options.to] : [null]),
206
+ ],
207
+ staleTime: RATE_HISTORY_STALE_TIME_MS,
208
+ queryFn: async () => {
209
+ const response = await fetch(url);
210
+ if (!response.ok) {
211
+ throw new HttpError(response.status, `Money Account API rate-history request failed with status '${response.status}'`);
212
+ }
213
+ const json = await response.json();
214
+ const [error, validated] = validate(json, RateHistoryResponseStruct);
215
+ if (error) {
216
+ throw new MoneyAccountApiResponseValidationError(`Malformed response from rate-history endpoint: ${error.message}`);
217
+ }
218
+ return validated;
219
+ },
220
+ });
221
+ }
222
+ }
223
+ _MoneyAccountApiDataService_baseUrl = new WeakMap();
224
+ //# sourceMappingURL=money-account-api-data-service.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"money-account-api-data-service.mjs","sourceRoot":"","sources":["../src/money-account-api-data-service.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n DataServiceCacheUpdatedEvent,\n DataServiceGranularCacheUpdatedEvent,\n DataServiceInvalidateQueriesAction,\n} from '@metamask/base-data-service';\nimport { BaseDataService } from '@metamask/base-data-service';\nimport type { CreateServicePolicyOptions } from '@metamask/controller-utils';\nimport { handleWhen, HttpError } from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport { validate } from '@metamask/superstruct';\nimport type { Json } from '@metamask/utils';\nimport type { QueryClientConfig } from '@tanstack/query-core';\n\nimport {\n DEFAULT_STALE_TIME_MS,\n Env,\n MONEY_ACCOUNT_API_URL_MAP,\n RATE_HISTORY_STALE_TIME_MS,\n} from './constants';\nimport { MoneyAccountApiResponseValidationError } from './errors';\nimport { projectLogger, createModuleLogger } from './logger';\nimport type { MoneyAccountApiDataServiceMethodActions } from './money-account-api-data-service-method-action-types';\nimport type {\n HistoryResponse,\n InterestResponse,\n PositionResponse,\n RateHistoryResponse,\n} from './response.types';\nimport {\n HistoryResponseStruct,\n InterestResponseStruct,\n PositionResponseStruct,\n RateHistoryResponseStruct,\n} from './structs';\nimport type {\n HistoryOptions,\n InterestOptions,\n RateHistoryOptions,\n} from './types';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link MoneyAccountApiDataService}, used to namespace the\n * service's actions and events.\n */\nexport const serviceName = 'MoneyAccountApiDataService';\n\nconst log = createModuleLogger(projectLogger, serviceName);\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'fetchPositions',\n 'fetchInterest',\n 'fetchHistory',\n 'fetchRateHistory',\n] as const;\n\n/**\n * Invalidates cached queries for {@link MoneyAccountApiDataService}.\n */\nexport type MoneyAccountApiDataServiceInvalidateQueriesAction =\n DataServiceInvalidateQueriesAction<typeof serviceName>;\n\n/**\n * Actions that {@link MoneyAccountApiDataService} exposes to other consumers.\n */\nexport type MoneyAccountApiDataServiceActions =\n | MoneyAccountApiDataServiceMethodActions\n | MoneyAccountApiDataServiceInvalidateQueriesAction;\n\n/**\n * Actions from other messengers that {@link MoneyAccountApiDataService} calls.\n */\ntype AllowedActions = never;\n\n/**\n * Published when {@link MoneyAccountApiDataService}'s cache is updated.\n */\nexport type MoneyAccountApiDataServiceCacheUpdatedEvent =\n DataServiceCacheUpdatedEvent<typeof serviceName>;\n\n/**\n * Published when a key within {@link MoneyAccountApiDataService}'s cache is\n * updated.\n */\nexport type MoneyAccountApiDataServiceGranularCacheUpdatedEvent =\n DataServiceGranularCacheUpdatedEvent<typeof serviceName>;\n\n/**\n * Events that {@link MoneyAccountApiDataService} exposes to other consumers.\n */\nexport type MoneyAccountApiDataServiceEvents =\n | MoneyAccountApiDataServiceCacheUpdatedEvent\n | MoneyAccountApiDataServiceGranularCacheUpdatedEvent;\n\n/**\n * Events from other messengers that {@link MoneyAccountApiDataService}\n * subscribes to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link MoneyAccountApiDataService}.\n */\nexport type MoneyAccountApiDataServiceMessenger = Messenger<\n typeof serviceName,\n MoneyAccountApiDataServiceActions | AllowedActions,\n MoneyAccountApiDataServiceEvents | AllowedEvents\n>;\n\n// === SERVICE DEFINITION ===\n\n/**\n * Data service responsible for fetching positions, interest, cash-flow\n * history, and vault rate history from the Money Account APY Tracking API.\n */\nexport class MoneyAccountApiDataService extends BaseDataService<\n typeof serviceName,\n MoneyAccountApiDataServiceMessenger\n> {\n readonly #baseUrl: string;\n\n /**\n * Constructs a new MoneyAccountApiDataService.\n *\n * @param args - The constructor arguments.\n * @param args.messenger - The messenger suited for this service.\n * @param args.env - The target environment. Defaults to production.\n * @param args.queryClientConfig - Configuration for the underlying TanStack\n * Query client.\n * @param args.policyOptions - Options to pass to `createServicePolicy`.\n */\n constructor({\n messenger,\n env = Env.PRD,\n queryClientConfig = {},\n policyOptions = {},\n }: {\n messenger: MoneyAccountApiDataServiceMessenger;\n env?: Env;\n queryClientConfig?: QueryClientConfig;\n policyOptions?: CreateServicePolicyOptions;\n }) {\n super({\n name: serviceName,\n messenger,\n queryClientConfig,\n policyOptions: {\n retryFilterPolicy: handleWhen(\n (error) => !(error instanceof MoneyAccountApiResponseValidationError),\n ),\n ...policyOptions,\n },\n });\n\n this.#baseUrl = MONEY_ACCOUNT_API_URL_MAP[env];\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n\n log('Initialized', { env, baseUrl: this.#baseUrl });\n }\n\n /**\n * Fetches the current vault positions for a given user address.\n *\n * @param address - The user's Ethereum address.\n * @returns The position response containing vault positions.\n */\n async fetchPositions(address: string): Promise<PositionResponse> {\n const url = new URL(\n `/v1/positions/${address.toLowerCase()}`,\n this.#baseUrl,\n );\n\n return this.fetchQuery({\n queryKey: [`${this.name}:fetchPositions`, address.toLowerCase()],\n staleTime: DEFAULT_STALE_TIME_MS,\n queryFn: async () => {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new HttpError(\n response.status,\n `Money Account API positions request failed with status '${response.status}'`,\n );\n }\n\n const json: Json = await response.json();\n\n const [error, validated] = validate(json, PositionResponseStruct);\n if (error) {\n throw new MoneyAccountApiResponseValidationError(\n `Malformed response from positions endpoint: ${error.message}`,\n );\n }\n\n return validated as unknown as PositionResponse;\n },\n });\n }\n\n /**\n * Fetches the interest earned for a given address and vault over a\n * specified time window.\n *\n * @param address - The user's Ethereum address.\n * @param options - Options specifying vault, window, and optional chain ID.\n * @returns The interest response.\n */\n async fetchInterest(\n address: string,\n options: InterestOptions,\n ): Promise<InterestResponse> {\n const url = new URL(\n `/v1/positions/${address.toLowerCase()}/interest`,\n this.#baseUrl,\n );\n url.searchParams.append(\n 'vault_address',\n options.vaultAddress.toLowerCase(),\n );\n url.searchParams.append('window', options.window);\n if (options.chainId !== undefined) {\n url.searchParams.append('chain_id', String(options.chainId));\n }\n\n return this.fetchQuery({\n queryKey: [\n `${this.name}:fetchInterest`,\n address.toLowerCase(),\n options.vaultAddress.toLowerCase(),\n options.window,\n ...(options.chainId === undefined ? [] : [options.chainId]),\n ],\n staleTime: DEFAULT_STALE_TIME_MS,\n queryFn: async () => {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new HttpError(\n response.status,\n `Money Account API interest request failed with status '${response.status}'`,\n );\n }\n\n const json: Json = await response.json();\n\n const [error, validated] = validate(json, InterestResponseStruct);\n if (error) {\n throw new MoneyAccountApiResponseValidationError(\n `Malformed response from interest endpoint: ${error.message}`,\n );\n }\n\n return validated as unknown as InterestResponse;\n },\n });\n }\n\n /**\n * Fetches cursor-paginated cash-flow history for a given address.\n * Uses `fetchInfiniteQuery` for proper TanStack Query pagination semantics.\n *\n * When paginating, consumers must re-pass the same filter options\n * (`vaultAddress`, `chainId`, `limit`) alongside `cursor` on every page\n * request. This ensures the query key matches the original infinite query\n * and that the HTTP request includes the correct filters.\n *\n * @param address - The user's Ethereum address.\n * @param options - Optional filtering and pagination options.\n * @returns The history response containing cash-flow entries for the requested page.\n */\n async fetchHistory(\n address: string,\n options?: HistoryOptions,\n ): Promise<HistoryResponse> {\n const normalizedAddress = address.toLowerCase();\n const normalizedVault = options?.vaultAddress?.toLowerCase() ?? null;\n\n return this.fetchInfiniteQuery(\n {\n queryKey: [\n `${this.name}:fetchHistory`,\n normalizedAddress,\n normalizedVault,\n options?.chainId ?? null,\n options?.limit ?? null,\n ],\n staleTime: DEFAULT_STALE_TIME_MS,\n queryFn: async (context) => {\n const cursor = context.pageParam as string | null | undefined;\n\n const url = new URL(\n `/v1/positions/${normalizedAddress}/history`,\n this.#baseUrl,\n );\n if (normalizedVault) {\n url.searchParams.append('vault_address', normalizedVault);\n }\n if (options?.chainId !== undefined) {\n url.searchParams.append('chain_id', String(options.chainId));\n }\n if (cursor) {\n url.searchParams.append('cursor', cursor);\n }\n if (options?.limit !== undefined) {\n url.searchParams.append('limit', String(options.limit));\n }\n\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new HttpError(\n response.status,\n `Money Account API history request failed with status '${response.status}'`,\n );\n }\n\n const json: Json = await response.json();\n\n const [error, validated] = validate(json, HistoryResponseStruct);\n if (error) {\n throw new MoneyAccountApiResponseValidationError(\n `Malformed response from history endpoint: ${error.message}`,\n );\n }\n\n return validated as unknown as HistoryResponse;\n },\n },\n options?.cursor ?? undefined,\n );\n }\n\n /**\n * Fetches the exchange-rate time series for a given vault.\n *\n * @param vaultAddress - The vault's Ethereum address.\n * @param options - Optional range and chain ID filters.\n * @returns The rate history response.\n */\n async fetchRateHistory(\n vaultAddress: string,\n options?: RateHistoryOptions,\n ): Promise<RateHistoryResponse> {\n const url = new URL(\n `/v1/vaults/${vaultAddress.toLowerCase()}/rate-history`,\n this.#baseUrl,\n );\n if (options?.chainId !== undefined) {\n url.searchParams.append('chain_id', String(options.chainId));\n }\n if (options?.from) {\n url.searchParams.append('from', options.from);\n }\n if (options?.to) {\n url.searchParams.append('to', options.to);\n }\n\n return this.fetchQuery({\n queryKey: [\n `${this.name}:fetchRateHistory`,\n vaultAddress.toLowerCase(),\n ...(options?.chainId === undefined ? [null] : [options.chainId]),\n ...(options?.from ? [options.from] : [null]),\n ...(options?.to ? [options.to] : [null]),\n ],\n staleTime: RATE_HISTORY_STALE_TIME_MS,\n queryFn: async () => {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new HttpError(\n response.status,\n `Money Account API rate-history request failed with status '${response.status}'`,\n );\n }\n\n const json: Json = await response.json();\n\n const [error, validated] = validate(json, RateHistoryResponseStruct);\n if (error) {\n throw new MoneyAccountApiResponseValidationError(\n `Malformed response from rate-history endpoint: ${error.message}`,\n );\n }\n\n return validated as unknown as RateHistoryResponse;\n },\n });\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=response.types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.types.cjs","sourceRoot":"","sources":["../src/response.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Infer } from '@metamask/superstruct';\n\nimport type {\n HistoryResponseStruct,\n InterestResponseStruct,\n PositionResponseStruct,\n RateHistoryResponseStruct,\n} from './structs';\n\n// All types in this file mirror the external Money Account API's snake_case\n// JSON contract verbatim to maintain 1:1 parity with API responses.\n/* eslint-disable @typescript-eslint/naming-convention */\n\n/**\n * Data freshness indicator returned by all business endpoints.\n */\nexport type DataFreshness = 'live' | 'degraded';\n\n/**\n * A single vault position within the positions response.\n */\nexport type VaultPosition = {\n vault_address: string;\n shares_held: string;\n current_rate: string;\n current_value_assets: string;\n current_value_usd: string;\n cost_basis_assets: string;\n cost_basis_usd: string;\n realized_interest_usd: string;\n unrealised_interest_usd: string;\n lifetime_interest_usd: string;\n current_apy: string;\n effective_apy: string;\n};\n\n/**\n * Response from `GET /v1/positions/:address`.\n * Derived from {@link PositionResponseStruct} to ensure type/struct parity.\n */\nexport type PositionResponse = Infer<typeof PositionResponseStruct>;\n\n/**\n * Response from `GET /v1/positions/:address/interest`.\n * Derived from {@link InterestResponseStruct} to ensure type/struct parity.\n */\nexport type InterestResponse = Infer<typeof InterestResponseStruct>;\n\n/**\n * Cash-flow type for the history endpoint.\n */\nexport type CashFlowType =\n | 'deposit'\n | 'withdraw'\n | 'transfer_in'\n | 'transfer_out';\n\n/**\n * Cash-flow source label.\n */\nexport type CashFlowSource =\n | 'teller'\n | 'withdraw_queue'\n | 'atomic_queue'\n | 'erc20_transfer'\n | 'cross_chain';\n\n/**\n * A single entry in the cash-flow history.\n */\nexport type CashFlowEntry = {\n type: CashFlowType;\n chain_id: number;\n vault_address: string;\n timestamp: string;\n block_number: number;\n log_index: number;\n tx_hash: string;\n assets_usd: string;\n assets_wei: string;\n shares_wei: string;\n rate: string;\n source: CashFlowSource;\n};\n\n/**\n * Response from `GET /v1/positions/:address/history`.\n * Derived from {@link HistoryResponseStruct} to ensure type/struct parity.\n */\nexport type HistoryResponse = Infer<typeof HistoryResponseStruct>;\n\n/**\n * A single entry in the rate-history time series.\n */\nexport type RateHistoryEntry = {\n timestamp: string;\n block_number: number;\n rate: string;\n tx_hash: string;\n};\n\n/**\n * Response from `GET /v1/vaults/:address/rate-history`.\n * Derived from {@link RateHistoryResponseStruct} to ensure type/struct parity.\n */\nexport type RateHistoryResponse = Infer<typeof RateHistoryResponseStruct>;\n"]}
@@ -0,0 +1,78 @@
1
+ import type { Infer } from "@metamask/superstruct";
2
+ import type { HistoryResponseStruct, InterestResponseStruct, PositionResponseStruct, RateHistoryResponseStruct } from "./structs.cjs";
3
+ /**
4
+ * Data freshness indicator returned by all business endpoints.
5
+ */
6
+ export type DataFreshness = 'live' | 'degraded';
7
+ /**
8
+ * A single vault position within the positions response.
9
+ */
10
+ export type VaultPosition = {
11
+ vault_address: string;
12
+ shares_held: string;
13
+ current_rate: string;
14
+ current_value_assets: string;
15
+ current_value_usd: string;
16
+ cost_basis_assets: string;
17
+ cost_basis_usd: string;
18
+ realized_interest_usd: string;
19
+ unrealised_interest_usd: string;
20
+ lifetime_interest_usd: string;
21
+ current_apy: string;
22
+ effective_apy: string;
23
+ };
24
+ /**
25
+ * Response from `GET /v1/positions/:address`.
26
+ * Derived from {@link PositionResponseStruct} to ensure type/struct parity.
27
+ */
28
+ export type PositionResponse = Infer<typeof PositionResponseStruct>;
29
+ /**
30
+ * Response from `GET /v1/positions/:address/interest`.
31
+ * Derived from {@link InterestResponseStruct} to ensure type/struct parity.
32
+ */
33
+ export type InterestResponse = Infer<typeof InterestResponseStruct>;
34
+ /**
35
+ * Cash-flow type for the history endpoint.
36
+ */
37
+ export type CashFlowType = 'deposit' | 'withdraw' | 'transfer_in' | 'transfer_out';
38
+ /**
39
+ * Cash-flow source label.
40
+ */
41
+ export type CashFlowSource = 'teller' | 'withdraw_queue' | 'atomic_queue' | 'erc20_transfer' | 'cross_chain';
42
+ /**
43
+ * A single entry in the cash-flow history.
44
+ */
45
+ export type CashFlowEntry = {
46
+ type: CashFlowType;
47
+ chain_id: number;
48
+ vault_address: string;
49
+ timestamp: string;
50
+ block_number: number;
51
+ log_index: number;
52
+ tx_hash: string;
53
+ assets_usd: string;
54
+ assets_wei: string;
55
+ shares_wei: string;
56
+ rate: string;
57
+ source: CashFlowSource;
58
+ };
59
+ /**
60
+ * Response from `GET /v1/positions/:address/history`.
61
+ * Derived from {@link HistoryResponseStruct} to ensure type/struct parity.
62
+ */
63
+ export type HistoryResponse = Infer<typeof HistoryResponseStruct>;
64
+ /**
65
+ * A single entry in the rate-history time series.
66
+ */
67
+ export type RateHistoryEntry = {
68
+ timestamp: string;
69
+ block_number: number;
70
+ rate: string;
71
+ tx_hash: string;
72
+ };
73
+ /**
74
+ * Response from `GET /v1/vaults/:address/rate-history`.
75
+ * Derived from {@link RateHistoryResponseStruct} to ensure type/struct parity.
76
+ */
77
+ export type RateHistoryResponse = Infer<typeof RateHistoryResponseStruct>;
78
+ //# sourceMappingURL=response.types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.types.d.cts","sourceRoot":"","sources":["../src/response.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,8BAA8B;AAEnD,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EAC1B,sBAAkB;AAMnB;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,uBAAuB,EAAE,MAAM,CAAC;IAChC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEpE;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,UAAU,GACV,aAAa,GACb,cAAc,CAAC;AAEnB;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,QAAQ,GACR,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,aAAa,CAAC;AAElB;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
@@ -0,0 +1,78 @@
1
+ import type { Infer } from "@metamask/superstruct";
2
+ import type { HistoryResponseStruct, InterestResponseStruct, PositionResponseStruct, RateHistoryResponseStruct } from "./structs.mjs";
3
+ /**
4
+ * Data freshness indicator returned by all business endpoints.
5
+ */
6
+ export type DataFreshness = 'live' | 'degraded';
7
+ /**
8
+ * A single vault position within the positions response.
9
+ */
10
+ export type VaultPosition = {
11
+ vault_address: string;
12
+ shares_held: string;
13
+ current_rate: string;
14
+ current_value_assets: string;
15
+ current_value_usd: string;
16
+ cost_basis_assets: string;
17
+ cost_basis_usd: string;
18
+ realized_interest_usd: string;
19
+ unrealised_interest_usd: string;
20
+ lifetime_interest_usd: string;
21
+ current_apy: string;
22
+ effective_apy: string;
23
+ };
24
+ /**
25
+ * Response from `GET /v1/positions/:address`.
26
+ * Derived from {@link PositionResponseStruct} to ensure type/struct parity.
27
+ */
28
+ export type PositionResponse = Infer<typeof PositionResponseStruct>;
29
+ /**
30
+ * Response from `GET /v1/positions/:address/interest`.
31
+ * Derived from {@link InterestResponseStruct} to ensure type/struct parity.
32
+ */
33
+ export type InterestResponse = Infer<typeof InterestResponseStruct>;
34
+ /**
35
+ * Cash-flow type for the history endpoint.
36
+ */
37
+ export type CashFlowType = 'deposit' | 'withdraw' | 'transfer_in' | 'transfer_out';
38
+ /**
39
+ * Cash-flow source label.
40
+ */
41
+ export type CashFlowSource = 'teller' | 'withdraw_queue' | 'atomic_queue' | 'erc20_transfer' | 'cross_chain';
42
+ /**
43
+ * A single entry in the cash-flow history.
44
+ */
45
+ export type CashFlowEntry = {
46
+ type: CashFlowType;
47
+ chain_id: number;
48
+ vault_address: string;
49
+ timestamp: string;
50
+ block_number: number;
51
+ log_index: number;
52
+ tx_hash: string;
53
+ assets_usd: string;
54
+ assets_wei: string;
55
+ shares_wei: string;
56
+ rate: string;
57
+ source: CashFlowSource;
58
+ };
59
+ /**
60
+ * Response from `GET /v1/positions/:address/history`.
61
+ * Derived from {@link HistoryResponseStruct} to ensure type/struct parity.
62
+ */
63
+ export type HistoryResponse = Infer<typeof HistoryResponseStruct>;
64
+ /**
65
+ * A single entry in the rate-history time series.
66
+ */
67
+ export type RateHistoryEntry = {
68
+ timestamp: string;
69
+ block_number: number;
70
+ rate: string;
71
+ tx_hash: string;
72
+ };
73
+ /**
74
+ * Response from `GET /v1/vaults/:address/rate-history`.
75
+ * Derived from {@link RateHistoryResponseStruct} to ensure type/struct parity.
76
+ */
77
+ export type RateHistoryResponse = Infer<typeof RateHistoryResponseStruct>;
78
+ //# sourceMappingURL=response.types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.types.d.mts","sourceRoot":"","sources":["../src/response.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,8BAA8B;AAEnD,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EAC1B,sBAAkB;AAMnB;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,uBAAuB,EAAE,MAAM,CAAC;IAChC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEpE;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,UAAU,GACV,aAAa,GACb,cAAc,CAAC;AAEnB;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,QAAQ,GACR,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,aAAa,CAAC;AAElB;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=response.types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.types.mjs","sourceRoot":"","sources":["../src/response.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Infer } from '@metamask/superstruct';\n\nimport type {\n HistoryResponseStruct,\n InterestResponseStruct,\n PositionResponseStruct,\n RateHistoryResponseStruct,\n} from './structs';\n\n// All types in this file mirror the external Money Account API's snake_case\n// JSON contract verbatim to maintain 1:1 parity with API responses.\n/* eslint-disable @typescript-eslint/naming-convention */\n\n/**\n * Data freshness indicator returned by all business endpoints.\n */\nexport type DataFreshness = 'live' | 'degraded';\n\n/**\n * A single vault position within the positions response.\n */\nexport type VaultPosition = {\n vault_address: string;\n shares_held: string;\n current_rate: string;\n current_value_assets: string;\n current_value_usd: string;\n cost_basis_assets: string;\n cost_basis_usd: string;\n realized_interest_usd: string;\n unrealised_interest_usd: string;\n lifetime_interest_usd: string;\n current_apy: string;\n effective_apy: string;\n};\n\n/**\n * Response from `GET /v1/positions/:address`.\n * Derived from {@link PositionResponseStruct} to ensure type/struct parity.\n */\nexport type PositionResponse = Infer<typeof PositionResponseStruct>;\n\n/**\n * Response from `GET /v1/positions/:address/interest`.\n * Derived from {@link InterestResponseStruct} to ensure type/struct parity.\n */\nexport type InterestResponse = Infer<typeof InterestResponseStruct>;\n\n/**\n * Cash-flow type for the history endpoint.\n */\nexport type CashFlowType =\n | 'deposit'\n | 'withdraw'\n | 'transfer_in'\n | 'transfer_out';\n\n/**\n * Cash-flow source label.\n */\nexport type CashFlowSource =\n | 'teller'\n | 'withdraw_queue'\n | 'atomic_queue'\n | 'erc20_transfer'\n | 'cross_chain';\n\n/**\n * A single entry in the cash-flow history.\n */\nexport type CashFlowEntry = {\n type: CashFlowType;\n chain_id: number;\n vault_address: string;\n timestamp: string;\n block_number: number;\n log_index: number;\n tx_hash: string;\n assets_usd: string;\n assets_wei: string;\n shares_wei: string;\n rate: string;\n source: CashFlowSource;\n};\n\n/**\n * Response from `GET /v1/positions/:address/history`.\n * Derived from {@link HistoryResponseStruct} to ensure type/struct parity.\n */\nexport type HistoryResponse = Infer<typeof HistoryResponseStruct>;\n\n/**\n * A single entry in the rate-history time series.\n */\nexport type RateHistoryEntry = {\n timestamp: string;\n block_number: number;\n rate: string;\n tx_hash: string;\n};\n\n/**\n * Response from `GET /v1/vaults/:address/rate-history`.\n * Derived from {@link RateHistoryResponseStruct} to ensure type/struct parity.\n */\nexport type RateHistoryResponse = Infer<typeof RateHistoryResponseStruct>;\n"]}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RateHistoryResponseStruct = exports.HistoryResponseStruct = exports.InterestResponseStruct = exports.PositionResponseStruct = void 0;
4
+ const superstruct_1 = require("@metamask/superstruct");
5
+ const DataFreshnessStruct = (0, superstruct_1.enums)(['live', 'degraded']);
6
+ const VaultPositionStruct = (0, superstruct_1.object)({
7
+ vault_address: (0, superstruct_1.string)(),
8
+ shares_held: (0, superstruct_1.string)(),
9
+ current_rate: (0, superstruct_1.string)(),
10
+ current_value_assets: (0, superstruct_1.string)(),
11
+ current_value_usd: (0, superstruct_1.string)(),
12
+ cost_basis_assets: (0, superstruct_1.string)(),
13
+ cost_basis_usd: (0, superstruct_1.string)(),
14
+ realized_interest_usd: (0, superstruct_1.string)(),
15
+ unrealised_interest_usd: (0, superstruct_1.string)(),
16
+ lifetime_interest_usd: (0, superstruct_1.string)(),
17
+ current_apy: (0, superstruct_1.string)(),
18
+ effective_apy: (0, superstruct_1.string)(),
19
+ });
20
+ exports.PositionResponseStruct = (0, superstruct_1.object)({
21
+ address: (0, superstruct_1.string)(),
22
+ as_of_block: (0, superstruct_1.number)(),
23
+ as_of_timestamp: (0, superstruct_1.string)(),
24
+ data_freshness: DataFreshnessStruct,
25
+ indexer_lag_seconds: (0, superstruct_1.number)(),
26
+ positions: (0, superstruct_1.array)(VaultPositionStruct),
27
+ });
28
+ exports.InterestResponseStruct = (0, superstruct_1.object)({
29
+ address: (0, superstruct_1.string)(),
30
+ vault_address: (0, superstruct_1.string)(),
31
+ window: (0, superstruct_1.string)(),
32
+ window_start: (0, superstruct_1.string)(),
33
+ window_end: (0, superstruct_1.string)(),
34
+ interest_earned_assets: (0, superstruct_1.string)(),
35
+ interest_earned_usd: (0, superstruct_1.string)(),
36
+ method: (0, superstruct_1.string)(),
37
+ as_of_block: (0, superstruct_1.number)(),
38
+ as_of_timestamp: (0, superstruct_1.string)(),
39
+ data_freshness: DataFreshnessStruct,
40
+ indexer_lag_seconds: (0, superstruct_1.number)(),
41
+ });
42
+ const CashFlowEntryStruct = (0, superstruct_1.object)({
43
+ type: (0, superstruct_1.enums)(['deposit', 'withdraw', 'transfer_in', 'transfer_out']),
44
+ chain_id: (0, superstruct_1.number)(),
45
+ vault_address: (0, superstruct_1.string)(),
46
+ timestamp: (0, superstruct_1.string)(),
47
+ block_number: (0, superstruct_1.number)(),
48
+ log_index: (0, superstruct_1.number)(),
49
+ tx_hash: (0, superstruct_1.string)(),
50
+ assets_usd: (0, superstruct_1.string)(),
51
+ assets_wei: (0, superstruct_1.string)(),
52
+ shares_wei: (0, superstruct_1.string)(),
53
+ rate: (0, superstruct_1.string)(),
54
+ source: (0, superstruct_1.enums)([
55
+ 'teller',
56
+ 'withdraw_queue',
57
+ 'atomic_queue',
58
+ 'erc20_transfer',
59
+ 'cross_chain',
60
+ ]),
61
+ });
62
+ exports.HistoryResponseStruct = (0, superstruct_1.object)({
63
+ address: (0, superstruct_1.string)(),
64
+ cash_flows: (0, superstruct_1.array)(CashFlowEntryStruct),
65
+ next_cursor: (0, superstruct_1.nullable)((0, superstruct_1.string)()),
66
+ has_more: (0, superstruct_1.boolean)(),
67
+ as_of_block: (0, superstruct_1.number)(),
68
+ as_of_timestamp: (0, superstruct_1.string)(),
69
+ data_freshness: DataFreshnessStruct,
70
+ indexer_lag_seconds: (0, superstruct_1.number)(),
71
+ });
72
+ const RateHistoryEntryStruct = (0, superstruct_1.object)({
73
+ timestamp: (0, superstruct_1.string)(),
74
+ block_number: (0, superstruct_1.number)(),
75
+ rate: (0, superstruct_1.string)(),
76
+ tx_hash: (0, superstruct_1.string)(),
77
+ });
78
+ exports.RateHistoryResponseStruct = (0, superstruct_1.object)({
79
+ vault_address: (0, superstruct_1.string)(),
80
+ chain_id: (0, superstruct_1.number)(),
81
+ range_start: (0, superstruct_1.string)(),
82
+ range_end: (0, superstruct_1.string)(),
83
+ rates: (0, superstruct_1.array)(RateHistoryEntryStruct),
84
+ as_of_block: (0, superstruct_1.number)(),
85
+ as_of_timestamp: (0, superstruct_1.string)(),
86
+ data_freshness: DataFreshnessStruct,
87
+ indexer_lag_seconds: (0, superstruct_1.number)(),
88
+ });
89
+ //# sourceMappingURL=structs.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structs.cjs","sourceRoot":"","sources":["../src/structs.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n array,\n boolean,\n enums,\n number,\n object,\n string,\n nullable,\n} from '@metamask/superstruct';\n\nconst DataFreshnessStruct = enums(['live', 'degraded']);\n\nconst VaultPositionStruct = object({\n vault_address: string(),\n shares_held: string(),\n current_rate: string(),\n current_value_assets: string(),\n current_value_usd: string(),\n cost_basis_assets: string(),\n cost_basis_usd: string(),\n realized_interest_usd: string(),\n unrealised_interest_usd: string(),\n lifetime_interest_usd: string(),\n current_apy: string(),\n effective_apy: string(),\n});\n\nexport const PositionResponseStruct = object({\n address: string(),\n as_of_block: number(),\n as_of_timestamp: string(),\n data_freshness: DataFreshnessStruct,\n indexer_lag_seconds: number(),\n positions: array(VaultPositionStruct),\n});\n\nexport const InterestResponseStruct = object({\n address: string(),\n vault_address: string(),\n window: string(),\n window_start: string(),\n window_end: string(),\n interest_earned_assets: string(),\n interest_earned_usd: string(),\n method: string(),\n as_of_block: number(),\n as_of_timestamp: string(),\n data_freshness: DataFreshnessStruct,\n indexer_lag_seconds: number(),\n});\n\nconst CashFlowEntryStruct = object({\n type: enums(['deposit', 'withdraw', 'transfer_in', 'transfer_out']),\n chain_id: number(),\n vault_address: string(),\n timestamp: string(),\n block_number: number(),\n log_index: number(),\n tx_hash: string(),\n assets_usd: string(),\n assets_wei: string(),\n shares_wei: string(),\n rate: string(),\n source: enums([\n 'teller',\n 'withdraw_queue',\n 'atomic_queue',\n 'erc20_transfer',\n 'cross_chain',\n ]),\n});\n\nexport const HistoryResponseStruct = object({\n address: string(),\n cash_flows: array(CashFlowEntryStruct),\n next_cursor: nullable(string()),\n has_more: boolean(),\n as_of_block: number(),\n as_of_timestamp: string(),\n data_freshness: DataFreshnessStruct,\n indexer_lag_seconds: number(),\n});\n\nconst RateHistoryEntryStruct = object({\n timestamp: string(),\n block_number: number(),\n rate: string(),\n tx_hash: string(),\n});\n\nexport const RateHistoryResponseStruct = object({\n vault_address: string(),\n chain_id: number(),\n range_start: string(),\n range_end: string(),\n rates: array(RateHistoryEntryStruct),\n as_of_block: number(),\n as_of_timestamp: string(),\n data_freshness: DataFreshnessStruct,\n indexer_lag_seconds: number(),\n});\n"]}