@buildaureon/sdk 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.
@@ -0,0 +1,604 @@
1
+ # Client API Reference
2
+
3
+ Complete reference for every public method on `AureonClient` as implemented in
4
+ `src/client/aureon-client.ts`, plus factories and the session helper.
5
+
6
+ Cross-links: [auth](./auth.md) | [architecture](./architecture.md) | [error-model](./error-model.md) |
7
+ [data-contracts](./data-contracts.md) | [transport](./transport.md)
8
+
9
+ ---
10
+
11
+ ## Table of contents
12
+
13
+ 1. [Construction](#1-construction)
14
+ 2. [Connectivity](#2-connectivity)
15
+ 3. [Authentication](#3-authentication)
16
+ 4. [Objectives](#4-objectives)
17
+ 5. [Health, timeline, portfolio, overview](#5-health-timeline-portfolio-overview)
18
+ 6. [Vault](#6-vault)
19
+ 7. [Market and execution](#7-market-and-execution)
20
+ 8. [Session helper](#8-session-helper)
21
+ 9. [Method → HTTP cheat sheet](#9-method--http-cheat-sheet)
22
+ 10. [Common error patterns](#10-common-error-patterns)
23
+
24
+ ---
25
+
26
+ ## 1. Construction
27
+
28
+ ```ts
29
+ import {
30
+ createAureonClient,
31
+ AureonClient,
32
+ } from "@buildaureon/sdk";
33
+
34
+ const aureon = createAureonClient({
35
+ // baseUrl defaults to https://api.aureonlabs.network
36
+ apiKey: process.env.AUREON_API_KEY,
37
+ getAccessToken: () => sessionToken,
38
+ timeoutMs: 30_000,
39
+ maxRetries: 2,
40
+ });
41
+ ```
42
+
43
+ ### Options reference
44
+
45
+ | Option | Required | Default | Description |
46
+ |--------|----------|---------|-------------|
47
+ | `baseUrl` | no | `https://api.aureonlabs.network` | Absolute `http://` or `https://` URL. |
48
+ | `apiKey` | SDK / CLI | N/A | Sent as `X-Aureon-Api-Key`. Utility uses wallet Bearer only. |
49
+ | `getAccessToken` | no | N/A | Sync/async getter before every request. Preferred for Bearer. |
50
+ | `authToken` | no | N/A | Static Bearer string when `getAccessToken` is omitted. |
51
+ | `timeoutMs` | no | `30000` | Per-attempt abort timeout. |
52
+ | `maxRetries` | no | `0` | Extra attempts after first failure for retryable errors. |
53
+ | `retryDelayMs` | no | `250` | Fixed delay between retries. |
54
+ | `logger` | no | N/A | `AureonLogger`. |
55
+ | `headers` | no | `{}` | Merged into every request. |
56
+ | `fetch` | no | `globalThis.fetch` | Custom fetch for unusual runtimes. |
57
+
58
+ ### Construction rules
59
+
60
+ | Rule | Behavior |
61
+ |------|----------|
62
+ | Omitted `baseUrl` | Uses production default |
63
+ | Invalid `baseUrl` scheme | Throws via `assertBaseUrl` |
64
+ | Both `authToken` and `getAccessToken` | Transport uses `getAccessToken` only |
65
+ | `aureon.baseUrl` getter | Returns resolved base (no trailing slash) |
66
+
67
+ ```mermaid
68
+ flowchart LR
69
+ Opts[AureonClientOptions] --> Ctor[constructor]
70
+ Ctor --> ResolveToken{getAccessToken_provided}
71
+ ResolveToken -->|yes| UseGetter[use_getter]
72
+ ResolveToken -->|no_but_authToken| Wrap[wrap_authToken]
73
+ ResolveToken -->|neither| NoAuth[no_Bearer]
74
+ Ctor --> Transport[TransportOptions]
75
+ ```
76
+
77
+ ---
78
+
79
+ ## 2. Connectivity
80
+
81
+ ### `ping()`
82
+
83
+ ```ts
84
+ async ping(): Promise<{ ok: true; service: string; version: string }>
85
+ ```
86
+
87
+ | | |
88
+ |--|--|
89
+ | Auth | No |
90
+ | HTTP | `GET /healthz` |
91
+ | Use | Boot checks, CLI smoke, CI health gate |
92
+ | Errors | `NETWORK_ERROR`, `TIMEOUT`, `SERVER_ERROR` |
93
+
94
+ ```ts
95
+ const { ok, service, version } = await aureon.ping();
96
+ // { ok: true, service: "aureon-backend", version: "0.2.0" }
97
+ ```
98
+
99
+ ---
100
+
101
+ ## 3. Authentication
102
+
103
+ Deep narrative: [auth.md](./auth.md). Method cards below.
104
+
105
+ ### `getAuthNonce(address)`
106
+
107
+ ```ts
108
+ async getAuthNonce(address: string): Promise<AuthNonceResponse>
109
+ // AuthNonceResponse: { walletAddress, nonce, message, expiresAt }
110
+ ```
111
+
112
+ | | |
113
+ |--|--|
114
+ | Auth | No |
115
+ | HTTP | `GET /auth/nonce?address=<encoded>` |
116
+ | Client validation | Empty/whitespace address → `VALIDATION_ERROR` |
117
+ | Notes | Sign the returned `message` **exactly**. Do not build your own challenge. |
118
+
119
+ ### `verifyWallet({ address, message, signature })`
120
+
121
+ ```ts
122
+ async verifyWallet(input: {
123
+ address: string;
124
+ message: string;
125
+ signature: string;
126
+ }): Promise<AuthSessionResponse>
127
+ // { token, walletAddress, expiresAt, sessionId, mode? }
128
+ ```
129
+
130
+ | | |
131
+ |--|--|
132
+ | Auth | No (establishes auth) |
133
+ | HTTP | `POST /auth/verify` |
134
+ | Client validation | All three fields required after trim |
135
+ | Host duty | Store `token`; feed via `getAccessToken` |
136
+
137
+ ### `devLogin()`
138
+
139
+ ```ts
140
+ async devLogin(): Promise<AuthSessionResponse>
141
+ ```
142
+
143
+ | | |
144
+ |--|--|
145
+ | Auth | No |
146
+ | HTTP | `POST /auth/dev-login` |
147
+ | Backend gate | `AUREON_ALLOW_DEV_LOGIN=1` |
148
+ | Typical failure | Forbidden / unauthorized when flag off |
149
+ | Notes | May include `mode: "dev-bypass"`. Never ship as sole product login. |
150
+
151
+ ### `logout()`
152
+
153
+ ```ts
154
+ async logout(): Promise<{ ok: true }>
155
+ ```
156
+
157
+ | | |
158
+ |--|--|
159
+ | Auth | Bearer recommended |
160
+ | HTTP | `POST /auth/logout` |
161
+ | Host duty | Also `session.clear()` / stop returning token |
162
+
163
+ ### `me()`
164
+
165
+ ```ts
166
+ async me(): Promise<AuthMeResponse>
167
+ // { walletAddress: string }
168
+ ```
169
+
170
+ | | |
171
+ |--|--|
172
+ | Auth | **Required** |
173
+ | HTTP | `GET /auth/me` |
174
+ | Use | Session probe after hydrate |
175
+ | Errors | `UNAUTHORIZED` when token missing/invalid |
176
+
177
+ ---
178
+
179
+ ## 4. Objectives
180
+
181
+ ### Objective kinds and priorities
182
+
183
+ | `ObjectiveKind` | Intent |
184
+ |-----------------|--------|
185
+ | `stable_allocation` | Hold a target stable weight (e.g. 20% USDG) |
186
+ | `balanced_portfolio` | Hold balanced sleeve near a target weight |
187
+ | `risk_ceiling` | Keep risk at or below configured ceiling |
188
+ | `reward_reinvestment` | Reinvest rewards toward a target sleeve |
189
+
190
+ | `ObjectivePriority` | Notes |
191
+ |---------------------|-------|
192
+ | `low` / `medium` / `high` / `critical` | Influences evaluation ordering when multiple objectives compete. Create defaults to `high`. |
193
+
194
+ ### `createObjective(input)`
195
+
196
+ ```ts
197
+ async createObjective(input: CreateObjectiveInput): Promise<Objective>
198
+ ```
199
+
200
+ | | |
201
+ |--|--|
202
+ | Auth | Required |
203
+ | HTTP | `POST /objectives` |
204
+ | Client validation | Name ≥ 3 chars; kind; `targetWeight` ∈ [0,1]; `tolerance` ∈ [0,0.5]; priority if set |
205
+ | Automation | Defaults **`automationMode: "auto"`** (Automatic restore). Omit `automationMode` in SDK/agent integrations. |
206
+ | `targetSymbol` | Required when `kind === "balanced_portfolio"` (uppercased on normalize). |
207
+
208
+ Manual Approve (`automationMode: "manual"`) is **operator-utility only**, and is not the recommended SDK create path.
209
+
210
+ ```ts
211
+ const objective = await aureon.createObjective({
212
+ name: "Maintain 20% Stable Assets",
213
+ kind: "stable_allocation",
214
+ targetWeight: 0.2,
215
+ tolerance: 0.02,
216
+ priority: "high",
217
+ // automationMode omitted → Automatic
218
+ });
219
+
220
+ const balanced = await aureon.createObjective({
221
+ name: "Hold 30% NVDA sleeve",
222
+ kind: "balanced_portfolio",
223
+ targetSymbol: "NVDA",
224
+ targetWeight: 0.3,
225
+ tolerance: 0.05,
226
+ });
227
+ ```
228
+
229
+ ### `listObjectives()`
230
+
231
+ ```ts
232
+ async listObjectives(): Promise<Objective[]>
233
+ ```
234
+
235
+ | | |
236
+ |--|--|
237
+ | Auth | Required |
238
+ | HTTP | `GET /objectives` |
239
+ | Unwrap | `{ objectives: Objective[] }` → array |
240
+
241
+ ### `getObjective(id)`
242
+
243
+ ```ts
244
+ async getObjective(id: string): Promise<Objective>
245
+ ```
246
+
247
+ | | |
248
+ |--|--|
249
+ | Auth | Required |
250
+ | HTTP | `GET /objectives/:id` |
251
+ | Client validation | Id must be a non-trivial string (`assertId`) |
252
+ | Errors | `NOT_FOUND`, `VALIDATION_ERROR` |
253
+
254
+ ### `updateObjective(id, input)`
255
+
256
+ ```ts
257
+ async updateObjective(id: string, input: UpdateObjectiveInput): Promise<Objective>
258
+ ```
259
+
260
+ | | |
261
+ |--|--|
262
+ | Auth | Required |
263
+ | HTTP | `PATCH /objectives/:id` |
264
+ | Body | Partial: name, priority, targetWeight, tolerance, maxRiskScore, reinvestRatio |
265
+
266
+ ### `pauseObjective(id)` / `resumeObjective(id)`
267
+
268
+ ```ts
269
+ async pauseObjective(id: string): Promise<Objective>
270
+ async resumeObjective(id: string): Promise<Objective>
271
+ ```
272
+
273
+ | | |
274
+ |--|--|
275
+ | Auth | Required |
276
+ | HTTP | `POST /objectives/:id/pause` · `POST /objectives/:id/resume` |
277
+ | Effect | Pause stops continuous evaluation; health typically reports `paused` |
278
+
279
+ ```mermaid
280
+ stateDiagram-v2
281
+ [*] --> active: createObjective
282
+ active --> paused: pauseObjective
283
+ paused --> active: resumeObjective
284
+ active --> active: updateObjective
285
+ ```
286
+
287
+ ---
288
+
289
+ ## 5. Health, timeline, portfolio, overview
290
+
291
+ ### `getHealth(objectiveId?)`
292
+
293
+ ```ts
294
+ async getHealth(objectiveId?: string): Promise<ObjectiveHealth[]>
295
+ ```
296
+
297
+ | | |
298
+ |--|--|
299
+ | Auth | Required |
300
+ | HTTP | `GET /health` optional `?objectiveId=` |
301
+ | Unwrap | `{ health }` |
302
+ | States | `healthy` · `warning` · `violation` · `paused` |
303
+
304
+ ### `getTimeline(objectiveId?)`
305
+
306
+ ```ts
307
+ async getTimeline(objectiveId?: string): Promise<TimelineEvent[]>
308
+ ```
309
+
310
+ | | |
311
+ |--|--|
312
+ | Auth | Required |
313
+ | HTTP | `GET /timeline` optional `?objectiveId=` |
314
+ | Unwrap | `{ events }` |
315
+ | Use | Operator narrative for launch video / audit |
316
+
317
+ ### `getPortfolio()`
318
+
319
+ ```ts
320
+ async getPortfolio(): Promise<PortfolioSnapshot>
321
+ ```
322
+
323
+ | | |
324
+ |--|--|
325
+ | Auth | Required |
326
+ | HTTP | `GET /portfolio` |
327
+ | Empty book | Valid: `positions.length === 0`, notional may be `0` |
328
+
329
+ ### `clearPortfolio()`
330
+
331
+ ```ts
332
+ async clearPortfolio(): Promise<PortfolioSnapshot>
333
+ ```
334
+
335
+ | | |
336
+ |--|--|
337
+ | Auth | Required |
338
+ | HTTP | `POST /portfolio/clear` |
339
+ | Unwrap | `{ portfolio }` → snapshot |
340
+ | Notes | Clears wallet positions. Does **not** seed holdings. |
341
+
342
+ ### `syncPortfolio()`
343
+
344
+ ```ts
345
+ async syncPortfolio(): Promise<SyncPortfolioResult>
346
+ ```
347
+
348
+ | | |
349
+ |--|--|
350
+ | Auth | API key + Bearer |
351
+ | HTTP | `POST /portfolio/sync` |
352
+ | Returns | `{ portfolio, chainId, skippedZero }` |
353
+ | Notes | On-chain balances for the session wallet. Vault balances merge into the book. Does **not** invent holdings. |
354
+
355
+ ### `getOverview()`
356
+
357
+ ```ts
358
+ async getOverview(): Promise<DashboardOverview>
359
+ ```
360
+
361
+ | | |
362
+ |--|--|
363
+ | Auth | Required |
364
+ | HTTP | `GET /overview` |
365
+ | Contains | Health counts, global score, 24h portfolio change (daily snapshots), evaluation schedule, recent executions + events |
366
+
367
+ ---
368
+
369
+ ## 6. Vault
370
+
371
+ Vault reads and prepare endpoints. The API returns calldata **steps**; the host wallet signs and broadcasts, meaning the API never holds user keys.
372
+
373
+ ### `getVault()`
374
+
375
+ ```ts
376
+ async getVault(): Promise<VaultOverview>
377
+ ```
378
+
379
+ | | |
380
+ |--|--|
381
+ | Auth | Required |
382
+ | HTTP | `GET /vault` |
383
+ | Returns | `address`, `chainId`, `tokens`, `balances`, `poolAddress`, `explorerBase`, `keeperAddress` |
384
+
385
+ ### `getVaultStatus()`
386
+
387
+ ```ts
388
+ async getVaultStatus(): Promise<VaultStatus>
389
+ // { empty, totalNotionalUsd, canRestore }
390
+ ```
391
+
392
+ | | |
393
+ |--|--|
394
+ | Auth | Required |
395
+ | HTTP | `GET /vault/status` |
396
+ | Use | Compact funding signal before restore |
397
+
398
+ ### `prepareVaultDeposit({ symbol, amount })`
399
+
400
+ ```ts
401
+ async prepareVaultDeposit(input: {
402
+ symbol: string; // "ETH" or any allowlisted ERC-20 (WETH, stables, …)
403
+ amount: string;
404
+ }): Promise<VaultPrepareResult>
405
+ ```
406
+
407
+ | | |
408
+ |--|--|
409
+ | Auth | Required |
410
+ | HTTP | `POST /vault/prepare-deposit` body `{ symbol, amount }` |
411
+ | ETH | Steps include `depositETH` (native value on step → vault WETH) |
412
+ | ERC-20 | Steps include `approve` then `deposit` for any allowlisted symbol |
413
+ | Host duty | Sign `steps` in order on `chainId`; broadcast each tx |
414
+
415
+ ### `prepareVaultWithdraw({ symbol?, amount })`
416
+
417
+ ```ts
418
+ async prepareVaultWithdraw(input: {
419
+ symbol?: string; // default "WETH"; any vault ERC-20 held by the user
420
+ amount: string;
421
+ }): Promise<VaultPrepareResult>
422
+ ```
423
+
424
+ | | |
425
+ |--|--|
426
+ | Auth | Required |
427
+ | HTTP | `POST /vault/prepare-withdraw` body `{ symbol, amount }` |
428
+ | Symbol | Any allowlisted vault ERC-20 (not native ETH, use WETH) |
429
+ | Host duty | Sign and broadcast returned `steps` |
430
+
431
+ ---
432
+
433
+ ## 7. Market and execution
434
+
435
+ ### Launch / rehearsal flow
436
+
437
+ ```mermaid
438
+ sequenceDiagram
439
+ participant App
440
+ participant SDK
441
+ participant API
442
+
443
+ App->>SDK: listMarketPresets
444
+ API-->>App: presets
445
+ App->>SDK: applyMarketEvent autoRestore true
446
+ API-->>App: event + portfolio + health + executions
447
+ Note over API: may run vault or staged restore
448
+ App->>SDK: getTimeline
449
+ API-->>App: violation_detected execution_completed
450
+ ```
451
+
452
+ ### `listMarketPresets()`
453
+
454
+ ```ts
455
+ async listMarketPresets(): Promise<MarketPreset[]>
456
+ ```
457
+
458
+ | | |
459
+ |--|--|
460
+ | Auth | Required |
461
+ | HTTP | `GET /market/presets` |
462
+ | Unwrap | `{ presets }` |
463
+ | Fields | `name`, `description`, `symbol`, `priceChangeRatio` |
464
+
465
+ ### `applyMarketEvent(input)`
466
+
467
+ ```ts
468
+ async applyMarketEvent(input: ApplyMarketEventInput): Promise<{
469
+ event: MarketEvent;
470
+ portfolio: PortfolioSnapshot;
471
+ health: ObjectiveHealth[];
472
+ executions: ExecutionReceipt[];
473
+ }>
474
+ ```
475
+
476
+ | | |
477
+ |--|--|
478
+ | Auth | Required |
479
+ | HTTP | `POST /market/events` |
480
+ | Normalization | Uppercases symbol; `autoRestore` defaults **true** |
481
+ | Validation | Symbol required; finite `priceChangeRatio`; rejects extreme ≤ -0.95 |
482
+
483
+ ### `getRestorePlan(objectiveId)`
484
+
485
+ ```ts
486
+ async getRestorePlan(objectiveId: string): Promise<RestorePlan>
487
+ // { kind, amountHuman, approxUsd, message, sellSymbol?, buySymbol? }
488
+ ```
489
+
490
+ | | |
491
+ |--|--|
492
+ | Auth | Required |
493
+ | HTTP | `GET /objectives/:id/restore-plan` |
494
+ | Kinds | `wrap_eth` · `unwrap_weth` · `vault_swap` |
495
+ | Use | Inspect plan before acting, noting that wrap/unwrap is client-side |
496
+
497
+ ### `runExecution(objectiveId)`
498
+
499
+ ```ts
500
+ async runExecution(objectiveId: string): Promise<ExecutionReceipt>
501
+ ```
502
+
503
+ | | |
504
+ |--|--|
505
+ | Auth | Required |
506
+ | HTTP | `POST /executions/run` body `{ objectiveId }` |
507
+ | Settlement | Receipt may include `settlement: "vault"` or `"staged"` |
508
+ | Use | Restore when plan kind is `vault_swap` (rejects wrap/unwrap with action details) |
509
+
510
+ ### `restoreObjective(objectiveId)`
511
+
512
+ ```ts
513
+ async restoreObjective(objectiveId: string): Promise<ExecutionReceipt>
514
+ ```
515
+
516
+ | | |
517
+ |--|--|
518
+ | Auth | Required |
519
+ | HTTP | `POST /objectives/:id/restore` |
520
+ | Settlement | Vault-backed restore when configured; same honesty labels as `runExecution` |
521
+ | Use | Preferred vault restore entry for Automatic objectives after breach |
522
+
523
+ ### `listExecutions(objectiveId?)`
524
+
525
+ ```ts
526
+ async listExecutions(objectiveId?: string): Promise<ExecutionReceipt[]>
527
+ ```
528
+
529
+ | | |
530
+ |--|--|
531
+ | Auth | Required |
532
+ | HTTP | `GET /executions` optional `?objectiveId=` |
533
+ | Unwrap | `{ executions }` |
534
+
535
+ ---
536
+
537
+ ## 8. Session helper
538
+
539
+ ```ts
540
+ import { createSessionTokenProvider } from "@buildaureon/sdk";
541
+
542
+ const session = createSessionTokenProvider(initialToken?: string | null);
543
+ session.getAccessToken(); // () => string | null
544
+ session.setToken(token);
545
+ session.clear();
546
+ ```
547
+
548
+ | Method | Purpose |
549
+ |--------|---------|
550
+ | `getAccessToken` | Pass directly into `createAureonClient({ getAccessToken })` |
551
+ | `setToken` | After `verifyWallet` / `devLogin` |
552
+ | `clear` | After `logout` or local sign-out |
553
+
554
+ ---
555
+
556
+ ## 9. Method → HTTP cheat sheet
557
+
558
+ | Method | Verb | Path | Auth |
559
+ |--------|------|------|------|
560
+ | `ping` | GET | `/healthz` | no |
561
+ | `getAuthNonce` | GET | `/auth/nonce` | no |
562
+ | `verifyWallet` | POST | `/auth/verify` | no |
563
+ | `devLogin` | POST | `/auth/dev-login` | no |
564
+ | `logout` | POST | `/auth/logout` | recommended |
565
+ | `me` | GET | `/auth/me` | **yes** |
566
+ | `createObjective` | POST | `/objectives` | **yes** |
567
+ | `listObjectives` | GET | `/objectives` | **yes** |
568
+ | `getObjective` | GET | `/objectives/:id` | **yes** |
569
+ | `updateObjective` | PATCH | `/objectives/:id` | **yes** |
570
+ | `pauseObjective` | POST | `/objectives/:id/pause` | **yes** |
571
+ | `resumeObjective` | POST | `/objectives/:id/resume` | **yes** |
572
+ | `getHealth` | GET | `/health` | **yes** |
573
+ | `getTimeline` | GET | `/timeline` | **yes** |
574
+ | `getPortfolio` | GET | `/portfolio` | **yes** |
575
+ | `setPortfolio` | PUT | `/portfolio` | **yes** |
576
+ | `clearPortfolio` | POST | `/portfolio/clear` | **yes** |
577
+ | `syncPortfolio` | POST | `/portfolio/sync` | **yes** |
578
+ | `refreshWatchdog` | POST | `/watchdog/refresh` | **yes** |
579
+ | `getOverview` | GET | `/overview` | **yes** |
580
+ | `listMarketPresets` | GET | `/market/presets` | **yes** |
581
+ | `applyMarketEvent` | POST | `/market/events` | **yes** |
582
+ | `getRestorePlan` | GET | `/objectives/:id/restore-plan` | **yes** |
583
+ | `restoreObjective` | POST | `/objectives/:id/restore` | **yes** |
584
+ | `runExecution` | POST | `/executions/run` | **yes** |
585
+ | `listExecutions` | GET | `/executions` | **yes** |
586
+ | `getVault` | GET | `/vault` | **yes** |
587
+ | `getVaultStatus` | GET | `/vault/status` | **yes** |
588
+ | `prepareVaultDeposit` | POST | `/vault/prepare-deposit` | **yes** |
589
+ | `prepareVaultWithdraw` | POST | `/vault/prepare-withdraw` | **yes** |
590
+
591
+ ---
592
+
593
+ ## 10. Common error patterns
594
+
595
+ | Situation | Typical `code` | Integrator action |
596
+ |-----------|----------------|-------------------|
597
+ | Forgot Bearer on protected route | `UNAUTHORIZED` | Re-login / fix `getAccessToken` |
598
+ | Name too short on create | `VALIDATION_ERROR` | Fix form |
599
+ | Unknown objective id | `NOT_FOUND` | Refresh list |
600
+ | Backend restart mid-session | `UNAUTHORIZED` | Clear token, connect again |
601
+ | Transient 503 | `SERVER_ERROR` | Retries if `maxRetries > 0` |
602
+ | Offline | `NETWORK_ERROR` | Show connectivity banner |
603
+
604
+ Full matrix: [error-model.md](./error-model.md).