@aetherwealth/sdk 0.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +207 -0
- package/dist/client.d.ts +130 -0
- package/dist/client.js +429 -0
- package/dist/errors.d.ts +131 -0
- package/dist/errors.js +178 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +24 -0
- package/dist/resources/accounts.d.ts +8 -0
- package/dist/resources/accounts.js +84 -0
- package/dist/resources/alerts.d.ts +8 -0
- package/dist/resources/alerts.js +178 -0
- package/dist/resources/diary.d.ts +8 -0
- package/dist/resources/diary.js +75 -0
- package/dist/resources/envelope.d.ts +7 -0
- package/dist/resources/envelope.js +15 -0
- package/dist/resources/idempotency.d.ts +15 -0
- package/dist/resources/idempotency.js +19 -0
- package/dist/resources/market.d.ts +8 -0
- package/dist/resources/market.js +90 -0
- package/dist/resources/paginate.d.ts +15 -0
- package/dist/resources/paginate.js +41 -0
- package/dist/resources/stats.d.ts +8 -0
- package/dist/resources/stats.js +28 -0
- package/dist/resources/trades.d.ts +8 -0
- package/dist/resources/trades.js +113 -0
- package/dist/resources/validate.d.ts +12 -0
- package/dist/resources/validate.js +22 -0
- package/dist/retry.d.ts +40 -0
- package/dist/retry.js +110 -0
- package/dist/schemas.d.ts +286 -0
- package/dist/schemas.js +239 -0
- package/dist/types.d.ts +528 -0
- package/dist/types.js +12 -0
- package/package.json +55 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire types mirroring the AetherWealth **aether-backend** REST API.
|
|
3
|
+
*
|
|
4
|
+
* The backend exposes a uniform POST-RPC surface: `POST /api/<domain>/<action>`
|
|
5
|
+
* returning `{success, <namedKey>}` (never a generic `{data}`). All response
|
|
6
|
+
* fields are **camelCase** (`userId`, `entryPrice`, `keyPrefix`). Resources
|
|
7
|
+
* pluck their named key from the envelope (see `resources/envelope.ts`).
|
|
8
|
+
*
|
|
9
|
+
* Only fields the backend Zod schemas actually emit are modeled; version-
|
|
10
|
+
* tolerant blobs stay `Record<string, unknown>`.
|
|
11
|
+
*/
|
|
12
|
+
export type ApiEnvelope<T> = {
|
|
13
|
+
success: boolean;
|
|
14
|
+
data?: T;
|
|
15
|
+
error?: string;
|
|
16
|
+
message?: string;
|
|
17
|
+
};
|
|
18
|
+
export type PaginationMeta = {
|
|
19
|
+
page: number;
|
|
20
|
+
limit: number;
|
|
21
|
+
total: number;
|
|
22
|
+
totalPages: number;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* A paginated list result: the items plus their pagination metadata. There is
|
|
26
|
+
* no `success` flag — `client.request` throws a typed error on any failure, so
|
|
27
|
+
* a resolved `PaginatedResponse` is always a success.
|
|
28
|
+
*/
|
|
29
|
+
export type PaginatedResponse<T> = {
|
|
30
|
+
data: T[];
|
|
31
|
+
pagination: PaginationMeta;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Per-call options for create methods.
|
|
35
|
+
*
|
|
36
|
+
* `idempotencyKey` is sent as the `Idempotency-Key` header so a retried create
|
|
37
|
+
* dedups to a single backend record. When omitted, the SDK generates a fresh
|
|
38
|
+
* key per call — which protects one call but is NOT retry-safe. To make a
|
|
39
|
+
* create retry-safe, pass a STABLE key so every attempt reuses it:
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* const key = crypto.randomUUID()
|
|
43
|
+
* await withRetry(() => client.trades.create(input, {idempotencyKey: key}))
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export type IdempotencyOptions = {
|
|
47
|
+
idempotencyKey?: string;
|
|
48
|
+
};
|
|
49
|
+
export type TradeDirection = 'LONG' | 'SHORT';
|
|
50
|
+
export type TradeStatus = 'OPEN' | 'CLOSED' | 'CANCELLED';
|
|
51
|
+
export type TradeStatusFilter = TradeStatus | 'ALL';
|
|
52
|
+
/** A trade as returned by aether-backend (`tradeSchema`, camelCase). */
|
|
53
|
+
export type Trade = {
|
|
54
|
+
id: string;
|
|
55
|
+
userId: string;
|
|
56
|
+
accountId: string;
|
|
57
|
+
pair: string;
|
|
58
|
+
direction: TradeDirection;
|
|
59
|
+
entryPrice: number;
|
|
60
|
+
exitPrice: number | null;
|
|
61
|
+
stopLoss: number | null;
|
|
62
|
+
takeProfit: number | null;
|
|
63
|
+
lotSize: number;
|
|
64
|
+
entryTime: string;
|
|
65
|
+
exitTime: string | null;
|
|
66
|
+
status: TradeStatus;
|
|
67
|
+
pnl: number | null;
|
|
68
|
+
pnlPercent: number | null;
|
|
69
|
+
pnlPips: number | null;
|
|
70
|
+
fees: number;
|
|
71
|
+
swap: number;
|
|
72
|
+
notes: string | null;
|
|
73
|
+
setupNotes: string | null;
|
|
74
|
+
emotionalTag: string | null;
|
|
75
|
+
timeframe: string | null;
|
|
76
|
+
screenshotUrl: string | null;
|
|
77
|
+
riskPercent: number | null;
|
|
78
|
+
initialRisk: number | null;
|
|
79
|
+
rMultiple: number | null;
|
|
80
|
+
notesFormat: string | null;
|
|
81
|
+
tags: string[];
|
|
82
|
+
createdAt: string;
|
|
83
|
+
updatedAt: string;
|
|
84
|
+
};
|
|
85
|
+
export type TradeListQuery = {
|
|
86
|
+
accountId?: string;
|
|
87
|
+
status?: TradeStatusFilter;
|
|
88
|
+
pair?: string;
|
|
89
|
+
from?: string;
|
|
90
|
+
to?: string;
|
|
91
|
+
page?: number;
|
|
92
|
+
limit?: number;
|
|
93
|
+
};
|
|
94
|
+
export type CreateTradeInput = {
|
|
95
|
+
accountId: string;
|
|
96
|
+
pair: string;
|
|
97
|
+
direction: TradeDirection;
|
|
98
|
+
entryPrice: number;
|
|
99
|
+
entryTime: string;
|
|
100
|
+
stopLoss?: number;
|
|
101
|
+
takeProfit?: number;
|
|
102
|
+
lotSize?: number;
|
|
103
|
+
notes?: string;
|
|
104
|
+
setupNotes?: string;
|
|
105
|
+
emotionalTag?: string;
|
|
106
|
+
timeframe?: string;
|
|
107
|
+
tags?: string[];
|
|
108
|
+
riskPercent?: number;
|
|
109
|
+
initialRisk?: number;
|
|
110
|
+
notesFormat?: string;
|
|
111
|
+
screenshotUrl?: string;
|
|
112
|
+
};
|
|
113
|
+
export type UpdateTradeInput = {
|
|
114
|
+
accountId?: string;
|
|
115
|
+
pair?: string;
|
|
116
|
+
direction?: TradeDirection;
|
|
117
|
+
entryPrice?: number;
|
|
118
|
+
entryTime?: string;
|
|
119
|
+
stopLoss?: number;
|
|
120
|
+
takeProfit?: number;
|
|
121
|
+
lotSize?: number;
|
|
122
|
+
notes?: string;
|
|
123
|
+
setupNotes?: string;
|
|
124
|
+
emotionalTag?: string;
|
|
125
|
+
timeframe?: string;
|
|
126
|
+
tags?: string[];
|
|
127
|
+
riskPercent?: number;
|
|
128
|
+
initialRisk?: number;
|
|
129
|
+
notesFormat?: string;
|
|
130
|
+
screenshotUrl?: string;
|
|
131
|
+
};
|
|
132
|
+
export type CloseTradeInput = {
|
|
133
|
+
exitPrice: number;
|
|
134
|
+
exitTime: string;
|
|
135
|
+
notes?: string;
|
|
136
|
+
fees?: number;
|
|
137
|
+
swap?: number;
|
|
138
|
+
};
|
|
139
|
+
export interface TradesResource {
|
|
140
|
+
list(query?: TradeListQuery): Promise<PaginatedResponse<Trade>>;
|
|
141
|
+
get(tradeId: string): Promise<Trade>;
|
|
142
|
+
/**
|
|
143
|
+
* Create a trade. Sends an `Idempotency-Key` header (auto-generated per call
|
|
144
|
+
* unless `opts.idempotencyKey` is given). Pass a STABLE key to make the call
|
|
145
|
+
* retry-safe under `withRetry`.
|
|
146
|
+
*/
|
|
147
|
+
create(input: CreateTradeInput, opts?: IdempotencyOptions): Promise<Trade>;
|
|
148
|
+
update(tradeId: string, input: UpdateTradeInput): Promise<Trade>;
|
|
149
|
+
close(tradeId: string, input: CloseTradeInput): Promise<Trade>;
|
|
150
|
+
/** Resolves on success; throws `AetherNotFoundError` if the trade is absent. */
|
|
151
|
+
delete(tradeId: string): Promise<void>;
|
|
152
|
+
/**
|
|
153
|
+
* Async-iterate every page of the trade list, auto-advancing `page` until
|
|
154
|
+
* the last page (or an empty page). Starts at `query.page` if given, else 1.
|
|
155
|
+
*/
|
|
156
|
+
pages(query?: TradeListQuery): AsyncIterableIterator<PaginatedResponse<Trade>>;
|
|
157
|
+
/** Async-iterate every trade across all pages (flattened {@link pages}). */
|
|
158
|
+
listAll(query?: TradeListQuery): AsyncIterableIterator<Trade>;
|
|
159
|
+
}
|
|
160
|
+
export type Account = {
|
|
161
|
+
id: string;
|
|
162
|
+
userId: string;
|
|
163
|
+
name: string;
|
|
164
|
+
broker: string | null;
|
|
165
|
+
accountType: string;
|
|
166
|
+
initialBalance: number;
|
|
167
|
+
currency: string;
|
|
168
|
+
notes: string | null;
|
|
169
|
+
isActive: boolean;
|
|
170
|
+
defaultRiskAmount: number | null;
|
|
171
|
+
createdAt: string;
|
|
172
|
+
updatedAt: string;
|
|
173
|
+
};
|
|
174
|
+
export type CreateAccountInput = {
|
|
175
|
+
name: string;
|
|
176
|
+
broker?: string;
|
|
177
|
+
accountType?: string;
|
|
178
|
+
initialBalance?: number;
|
|
179
|
+
currency?: string;
|
|
180
|
+
notes?: string;
|
|
181
|
+
defaultRiskAmount?: number;
|
|
182
|
+
};
|
|
183
|
+
export type UpdateAccountInput = {
|
|
184
|
+
name?: string;
|
|
185
|
+
broker?: string;
|
|
186
|
+
accountType?: string;
|
|
187
|
+
initialBalance?: number;
|
|
188
|
+
currency?: string;
|
|
189
|
+
notes?: string;
|
|
190
|
+
defaultRiskAmount?: number;
|
|
191
|
+
isActive?: boolean;
|
|
192
|
+
};
|
|
193
|
+
export interface AccountsResource {
|
|
194
|
+
list(): Promise<Account[]>;
|
|
195
|
+
/**
|
|
196
|
+
* Create an account. Sends an `Idempotency-Key` header (auto-generated per
|
|
197
|
+
* call unless `opts.idempotencyKey` is given). Pass a STABLE key to make the
|
|
198
|
+
* call retry-safe under `withRetry`.
|
|
199
|
+
*/
|
|
200
|
+
create(input: CreateAccountInput, opts?: IdempotencyOptions): Promise<Account>;
|
|
201
|
+
update(accountId: string, input: UpdateAccountInput): Promise<Account>;
|
|
202
|
+
/** Resolves on success; throws `AetherNotFoundError` if the account is absent. */
|
|
203
|
+
delete(accountId: string): Promise<void>;
|
|
204
|
+
/** Convenience: trades on an account (delegates to `trades.list({accountId})`). */
|
|
205
|
+
trades(accountId: string, query?: Omit<TradeListQuery, 'accountId'>): Promise<PaginatedResponse<Trade>>;
|
|
206
|
+
/** Async-iterate every trade on an account across all pages. */
|
|
207
|
+
tradesAll(accountId: string, query?: Omit<TradeListQuery, 'accountId'>): AsyncIterableIterator<Trade>;
|
|
208
|
+
}
|
|
209
|
+
export type TradingStats = {
|
|
210
|
+
totalTrades: number;
|
|
211
|
+
winRate: number;
|
|
212
|
+
profitFactor: number;
|
|
213
|
+
totalPnl: number;
|
|
214
|
+
totalPnlPips: number;
|
|
215
|
+
avgWin: number;
|
|
216
|
+
avgLoss: number;
|
|
217
|
+
maxDrawdown: number;
|
|
218
|
+
sharpeRatio: number | null;
|
|
219
|
+
riskRewardAvg: number | null;
|
|
220
|
+
bestPair: string | null;
|
|
221
|
+
worstPair: string | null;
|
|
222
|
+
avgHoldTimeMinutes: number;
|
|
223
|
+
avgR: number | null;
|
|
224
|
+
expectancyR: number | null;
|
|
225
|
+
sqn: number | null;
|
|
226
|
+
consecutiveWins: number;
|
|
227
|
+
consecutiveLosses: number;
|
|
228
|
+
};
|
|
229
|
+
export type StatsQuery = {
|
|
230
|
+
accountId?: string;
|
|
231
|
+
pair?: string;
|
|
232
|
+
from?: string;
|
|
233
|
+
to?: string;
|
|
234
|
+
};
|
|
235
|
+
export interface StatsResource {
|
|
236
|
+
summary(query?: StatsQuery): Promise<TradingStats>;
|
|
237
|
+
}
|
|
238
|
+
export type PriceCondition = 'above' | 'below' | 'crosses';
|
|
239
|
+
export type TriggerType = 'close' | 'wick';
|
|
240
|
+
export type DedupMode = 'edge' | 'continuous';
|
|
241
|
+
export type AlertType = 'price' | 'trendline';
|
|
242
|
+
export type Alert = {
|
|
243
|
+
id: string;
|
|
244
|
+
userId: string;
|
|
245
|
+
pair: string;
|
|
246
|
+
timeframe: string;
|
|
247
|
+
alertType: AlertType;
|
|
248
|
+
price: number | null;
|
|
249
|
+
price1: number | null;
|
|
250
|
+
time1: string | null;
|
|
251
|
+
price2: number | null;
|
|
252
|
+
time2: string | null;
|
|
253
|
+
slope: number | null;
|
|
254
|
+
intercept: number | null;
|
|
255
|
+
condition: PriceCondition | null;
|
|
256
|
+
triggerType: TriggerType;
|
|
257
|
+
isPersistent: boolean;
|
|
258
|
+
isActive: boolean;
|
|
259
|
+
isArchived: boolean;
|
|
260
|
+
notifyEmail: boolean;
|
|
261
|
+
notifyPush: boolean;
|
|
262
|
+
message: string | null;
|
|
263
|
+
triggeredAt: string | null;
|
|
264
|
+
triggeredPrice: number | null;
|
|
265
|
+
triggerCount: number;
|
|
266
|
+
expiresAt: string | null;
|
|
267
|
+
createdAt: string;
|
|
268
|
+
updatedAt: string;
|
|
269
|
+
};
|
|
270
|
+
export type ThresholdOp = 'gt' | 'gte' | 'lt' | 'lte' | 'eq' | 'crosses_above' | 'crosses_below';
|
|
271
|
+
export type SeriesOp = 'gt_series' | 'lt_series' | 'crosses_above_series' | 'crosses_below_series';
|
|
272
|
+
/** Indicator-alert condition DSL: threshold ops carry a number, series ops a peer series. */
|
|
273
|
+
export type IndicatorCondition = {
|
|
274
|
+
op: ThresholdOp;
|
|
275
|
+
threshold: number;
|
|
276
|
+
} | {
|
|
277
|
+
op: SeriesOp;
|
|
278
|
+
other: string;
|
|
279
|
+
};
|
|
280
|
+
export type IndicatorAlert = {
|
|
281
|
+
id: string;
|
|
282
|
+
userId: string;
|
|
283
|
+
pair: string;
|
|
284
|
+
timeframe: string;
|
|
285
|
+
indicatorType: string;
|
|
286
|
+
indicatorParams: Record<string, unknown>;
|
|
287
|
+
customIndicatorId: string | null;
|
|
288
|
+
customIndicatorVersion: number | null;
|
|
289
|
+
outputSeries: string | null;
|
|
290
|
+
condition: IndicatorCondition | null;
|
|
291
|
+
triggerType: TriggerType;
|
|
292
|
+
dedupMode: DedupMode;
|
|
293
|
+
isActive: boolean;
|
|
294
|
+
isArchived: boolean;
|
|
295
|
+
isTriggered: boolean;
|
|
296
|
+
isPersistent: boolean;
|
|
297
|
+
notifyEmail: boolean;
|
|
298
|
+
notifyPush: boolean;
|
|
299
|
+
message: string | null;
|
|
300
|
+
triggeredAt: string | null;
|
|
301
|
+
triggeredPrice: number | null;
|
|
302
|
+
triggerCount: number;
|
|
303
|
+
lastConditionState: string | null;
|
|
304
|
+
lastTriggeredValue: number | null;
|
|
305
|
+
lastEvaluatedAt: string | null;
|
|
306
|
+
lastError: string | null;
|
|
307
|
+
expiresAt: string | null;
|
|
308
|
+
createdAt: string;
|
|
309
|
+
updatedAt: string;
|
|
310
|
+
};
|
|
311
|
+
export type CreatePriceAlertInput = {
|
|
312
|
+
pair: string;
|
|
313
|
+
timeframe: string;
|
|
314
|
+
price: number;
|
|
315
|
+
condition: PriceCondition;
|
|
316
|
+
triggerType: TriggerType;
|
|
317
|
+
isPersistent: boolean;
|
|
318
|
+
notifyEmail: boolean;
|
|
319
|
+
notifyPush: boolean;
|
|
320
|
+
message?: string;
|
|
321
|
+
expiresAt?: string | null;
|
|
322
|
+
};
|
|
323
|
+
export type CreateTrendlineAlertInput = {
|
|
324
|
+
pair: string;
|
|
325
|
+
timeframe: string;
|
|
326
|
+
price1: number;
|
|
327
|
+
time1: string;
|
|
328
|
+
price2: number;
|
|
329
|
+
time2: string;
|
|
330
|
+
condition: PriceCondition;
|
|
331
|
+
triggerType: TriggerType;
|
|
332
|
+
isPersistent: boolean;
|
|
333
|
+
notifyEmail: boolean;
|
|
334
|
+
notifyPush: boolean;
|
|
335
|
+
message?: string;
|
|
336
|
+
expiresAt?: string | null;
|
|
337
|
+
};
|
|
338
|
+
export type UpdateAlertInput = {
|
|
339
|
+
price?: number;
|
|
340
|
+
price1?: number;
|
|
341
|
+
price2?: number;
|
|
342
|
+
time1?: string;
|
|
343
|
+
time2?: string;
|
|
344
|
+
condition?: PriceCondition;
|
|
345
|
+
triggerType?: TriggerType;
|
|
346
|
+
timeframe?: string;
|
|
347
|
+
isActive?: boolean;
|
|
348
|
+
isArchived?: boolean;
|
|
349
|
+
isPersistent?: boolean;
|
|
350
|
+
notifyEmail?: boolean;
|
|
351
|
+
notifyPush?: boolean;
|
|
352
|
+
message?: string;
|
|
353
|
+
expiresAt?: string | null;
|
|
354
|
+
};
|
|
355
|
+
export type ListAlertsQuery = {
|
|
356
|
+
includeArchived?: boolean;
|
|
357
|
+
pair?: string;
|
|
358
|
+
};
|
|
359
|
+
export type CreateIndicatorAlertInput = {
|
|
360
|
+
pair: string;
|
|
361
|
+
timeframe: string;
|
|
362
|
+
indicatorType: string;
|
|
363
|
+
indicatorParams: Record<string, unknown>;
|
|
364
|
+
outputSeries: string;
|
|
365
|
+
condition: IndicatorCondition;
|
|
366
|
+
triggerType: TriggerType;
|
|
367
|
+
dedupMode: DedupMode;
|
|
368
|
+
isPersistent: boolean;
|
|
369
|
+
notifyEmail: boolean;
|
|
370
|
+
notifyPush: boolean;
|
|
371
|
+
customIndicatorId?: string;
|
|
372
|
+
customIndicatorVersion?: number;
|
|
373
|
+
message?: string;
|
|
374
|
+
expiresAt?: string | null;
|
|
375
|
+
};
|
|
376
|
+
export type UpdateIndicatorAlertInput = {
|
|
377
|
+
condition?: IndicatorCondition;
|
|
378
|
+
dedupMode?: DedupMode;
|
|
379
|
+
triggerType?: TriggerType;
|
|
380
|
+
isActive?: boolean;
|
|
381
|
+
isArchived?: boolean;
|
|
382
|
+
isPersistent?: boolean;
|
|
383
|
+
notifyEmail?: boolean;
|
|
384
|
+
notifyPush?: boolean;
|
|
385
|
+
message?: string;
|
|
386
|
+
expiresAt?: string | null;
|
|
387
|
+
};
|
|
388
|
+
export interface AlertsResource {
|
|
389
|
+
list(query?: ListAlertsQuery): Promise<Alert[]>;
|
|
390
|
+
/** Create a price alert. Sends an `Idempotency-Key` header (see {@link IdempotencyOptions}). */
|
|
391
|
+
createPrice(input: CreatePriceAlertInput, opts?: IdempotencyOptions): Promise<Alert>;
|
|
392
|
+
/** Create a trendline alert. Sends an `Idempotency-Key` header (see {@link IdempotencyOptions}). */
|
|
393
|
+
createTrendline(input: CreateTrendlineAlertInput, opts?: IdempotencyOptions): Promise<Alert>;
|
|
394
|
+
update(alertId: string, input: UpdateAlertInput): Promise<Alert>;
|
|
395
|
+
/** Resolves on success; throws `AetherNotFoundError` if the alert is absent. */
|
|
396
|
+
delete(alertId: string): Promise<void>;
|
|
397
|
+
listIndicator(query?: ListAlertsQuery): Promise<IndicatorAlert[]>;
|
|
398
|
+
/** Create an indicator alert. Sends an `Idempotency-Key` header (see {@link IdempotencyOptions}). */
|
|
399
|
+
createIndicator(input: CreateIndicatorAlertInput, opts?: IdempotencyOptions): Promise<IndicatorAlert>;
|
|
400
|
+
updateIndicator(alertId: string, input: UpdateIndicatorAlertInput): Promise<IndicatorAlert>;
|
|
401
|
+
/** Resolves on success; throws `AetherNotFoundError` if the alert is absent. */
|
|
402
|
+
deleteIndicator(alertId: string): Promise<void>;
|
|
403
|
+
}
|
|
404
|
+
/** Nested instrument metadata keys are snake_case (emitted literally by the backend). */
|
|
405
|
+
export type MarketConfig = {
|
|
406
|
+
supportedTAPairs: Record<string, Record<string, unknown>>;
|
|
407
|
+
supportedFAPairs: Record<string, unknown>;
|
|
408
|
+
supportedTimeframes: string[];
|
|
409
|
+
supportedFACurrencies: string[];
|
|
410
|
+
};
|
|
411
|
+
export type EconomicEventMinimal = {
|
|
412
|
+
id: string;
|
|
413
|
+
currency: string;
|
|
414
|
+
release: string;
|
|
415
|
+
eventName: string;
|
|
416
|
+
announcementUnix: number;
|
|
417
|
+
impact: number;
|
|
418
|
+
actual: number | null;
|
|
419
|
+
forecast: number | null;
|
|
420
|
+
previous: number | null;
|
|
421
|
+
};
|
|
422
|
+
export type EconomicEventRich = EconomicEventMinimal & {
|
|
423
|
+
releaseDateLocal: string | null;
|
|
424
|
+
currencyTimezone: string | null;
|
|
425
|
+
changeMom: number | null;
|
|
426
|
+
changeQoq: number | null;
|
|
427
|
+
changeYoy: number | null;
|
|
428
|
+
surpriseDelta: number | null;
|
|
429
|
+
surpriseDirection: string | null;
|
|
430
|
+
trend: string | null;
|
|
431
|
+
revisionCount: number | null;
|
|
432
|
+
unit: string | null;
|
|
433
|
+
};
|
|
434
|
+
export type EconomicEvent = EconomicEventMinimal | EconomicEventRich;
|
|
435
|
+
export type CalendarQuery = {
|
|
436
|
+
currency?: string[];
|
|
437
|
+
from?: string;
|
|
438
|
+
to?: string;
|
|
439
|
+
indicator?: string;
|
|
440
|
+
impactMin?: number;
|
|
441
|
+
view?: 'minimal' | 'rich';
|
|
442
|
+
};
|
|
443
|
+
export type CalendarResult = {
|
|
444
|
+
events: EconomicEvent[];
|
|
445
|
+
view: string;
|
|
446
|
+
};
|
|
447
|
+
export type MacroSeriesQuery = {
|
|
448
|
+
currency: string;
|
|
449
|
+
indicator: string;
|
|
450
|
+
from?: string;
|
|
451
|
+
to?: string;
|
|
452
|
+
limit?: number;
|
|
453
|
+
};
|
|
454
|
+
/**
|
|
455
|
+
* Raw fxmacrodata series passed through by `/api/macro/:currency/:indicator`.
|
|
456
|
+
* `has_official_forecast`, `announcement_datetime`, and `cb_target` are
|
|
457
|
+
* snake_case because the upstream `fxmacrodata-client` emits them that way and
|
|
458
|
+
* the backend forwards them untransformed — same reasoning as `MarketConfig`.
|
|
459
|
+
*/
|
|
460
|
+
export type MacroSeriesResult = {
|
|
461
|
+
currency: string;
|
|
462
|
+
indicator: string;
|
|
463
|
+
unit?: string;
|
|
464
|
+
frequency?: string;
|
|
465
|
+
has_official_forecast?: boolean;
|
|
466
|
+
series: {
|
|
467
|
+
date: string;
|
|
468
|
+
val: number;
|
|
469
|
+
announcement_datetime: number;
|
|
470
|
+
}[];
|
|
471
|
+
cb_target?: Record<string, unknown>;
|
|
472
|
+
cachedAt?: number;
|
|
473
|
+
};
|
|
474
|
+
export type MacroRange = '3m' | '6m' | '12m' | '24m' | 'all';
|
|
475
|
+
/** Args for `market.macro` — an object (not positional) so the two same-typed
|
|
476
|
+
* `currency`/`indicator` strings can't be silently transposed. */
|
|
477
|
+
export type MacroQuery = {
|
|
478
|
+
/** 3-letter currency code, e.g. `USD`. */
|
|
479
|
+
currency: string;
|
|
480
|
+
/** Indicator slug (letters/digits/underscores), e.g. `cpi`. */
|
|
481
|
+
indicator: string;
|
|
482
|
+
range?: MacroRange;
|
|
483
|
+
};
|
|
484
|
+
export interface MarketResource {
|
|
485
|
+
config(): Promise<MarketConfig>;
|
|
486
|
+
calendar(query?: CalendarQuery): Promise<CalendarResult>;
|
|
487
|
+
/** Economic-calendar rich events for a currency+indicator (`/api/public/v1/market/macro-series`). */
|
|
488
|
+
macroSeries(query: MacroSeriesQuery): Promise<EconomicEventRich[]>;
|
|
489
|
+
/** fxmacrodata time series for a currency+indicator (`/api/public/v1/market/macro`). */
|
|
490
|
+
macro(query: MacroQuery): Promise<MacroSeriesResult | null>;
|
|
491
|
+
}
|
|
492
|
+
export type DiaryEntry = {
|
|
493
|
+
id: string;
|
|
494
|
+
date: string;
|
|
495
|
+
content: string;
|
|
496
|
+
mood: string | null;
|
|
497
|
+
rating: number | null;
|
|
498
|
+
tags: string[];
|
|
499
|
+
createdAt: string;
|
|
500
|
+
updatedAt: string;
|
|
501
|
+
};
|
|
502
|
+
export type DiaryListQuery = {
|
|
503
|
+
from?: string;
|
|
504
|
+
to?: string;
|
|
505
|
+
page?: number;
|
|
506
|
+
limit?: number;
|
|
507
|
+
};
|
|
508
|
+
export type UpsertDiaryInput = {
|
|
509
|
+
date: string;
|
|
510
|
+
content: string;
|
|
511
|
+
mood?: string | null;
|
|
512
|
+
rating?: number | null;
|
|
513
|
+
tags?: string[];
|
|
514
|
+
};
|
|
515
|
+
export interface DiaryResource {
|
|
516
|
+
list(query?: DiaryListQuery): Promise<PaginatedResponse<DiaryEntry>>;
|
|
517
|
+
get(date: string): Promise<DiaryEntry>;
|
|
518
|
+
upsert(input: UpsertDiaryInput): Promise<DiaryEntry>;
|
|
519
|
+
/** Resolves on success; throws `AetherNotFoundError` if the entry is absent. */
|
|
520
|
+
delete(date: string): Promise<void>;
|
|
521
|
+
/**
|
|
522
|
+
* Async-iterate every page of diary entries, auto-advancing `page` until the
|
|
523
|
+
* last page (or an empty page). Starts at `query.page` if given, else 1.
|
|
524
|
+
*/
|
|
525
|
+
pages(query?: DiaryListQuery): AsyncIterableIterator<PaginatedResponse<DiaryEntry>>;
|
|
526
|
+
/** Async-iterate every diary entry across all pages (flattened {@link pages}). */
|
|
527
|
+
listAll(query?: DiaryListQuery): AsyncIterableIterator<DiaryEntry>;
|
|
528
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire types mirroring the AetherWealth **aether-backend** REST API.
|
|
3
|
+
*
|
|
4
|
+
* The backend exposes a uniform POST-RPC surface: `POST /api/<domain>/<action>`
|
|
5
|
+
* returning `{success, <namedKey>}` (never a generic `{data}`). All response
|
|
6
|
+
* fields are **camelCase** (`userId`, `entryPrice`, `keyPrefix`). Resources
|
|
7
|
+
* pluck their named key from the envelope (see `resources/envelope.ts`).
|
|
8
|
+
*
|
|
9
|
+
* Only fields the backend Zod schemas actually emit are modeled; version-
|
|
10
|
+
* tolerant blobs stay `Record<string, unknown>`.
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aetherwealth/sdk",
|
|
3
|
+
"version": "0.1.32",
|
|
4
|
+
"description": "Official Aether Wealth SDK: a typed TypeScript client for the Aether Wealth public API — trades, accounts, analytics, alerts, market data, macro calendar, and diary.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./package.json": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"zod": "^4.4.3"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"aether wealth",
|
|
34
|
+
"aetherwealth",
|
|
35
|
+
"sdk",
|
|
36
|
+
"trading",
|
|
37
|
+
"trading journal",
|
|
38
|
+
"trading api",
|
|
39
|
+
"api client",
|
|
40
|
+
"forex",
|
|
41
|
+
"market data",
|
|
42
|
+
"technical indicators"
|
|
43
|
+
],
|
|
44
|
+
"author": "Aether Wealth <support@aetherwealth.ai>",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"homepage": "https://aetherwealth.ai/sdk",
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/Opus-Aether-AI/webapp.git",
|
|
50
|
+
"directory": "packages/sdk"
|
|
51
|
+
},
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/Opus-Aether-AI/webapp/issues"
|
|
54
|
+
}
|
|
55
|
+
}
|