@buildaureon/sdk 0.1.1 → 0.1.2

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.
@@ -1,605 +1,605 @@
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`. Issued developer keys also identify the bound wallet (no Bearer required). Env bootstrap keys are product-gate only. Utility uses wallet Bearer only. |
49
- | `getAccessToken` | no | N/A | Optional Bearer getter. Wins over API-key identity when present. |
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 | SDK supports **Automatic only**. Defaults **`automationMode: "auto"`**. Omit the field in agent integrations. |
206
- | `targetSymbol` | Required when `kind === "balanced_portfolio"` (uppercased on normalize). |
207
-
208
- **SDK policy:** Automatic mode only. Manual Approve belongs in the operator utility — do not build Manual agent loops with this package.
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
- | Locked at create | `targetSymbol`, `automationMode` — recreate the objective to change either |
266
-
267
- ### `pauseObjective(id)` / `resumeObjective(id)`
268
-
269
- ```ts
270
- async pauseObjective(id: string): Promise<Objective>
271
- async resumeObjective(id: string): Promise<Objective>
272
- ```
273
-
274
- | | |
275
- |--|--|
276
- | Auth | Required |
277
- | HTTP | `POST /objectives/:id/pause` · `POST /objectives/:id/resume` |
278
- | Effect | Pause stops continuous evaluation; health typically reports `paused` |
279
-
280
- ```mermaid
281
- stateDiagram-v2
282
- [*] --> active: createObjective
283
- active --> paused: pauseObjective
284
- paused --> active: resumeObjective
285
- active --> active: updateObjective
286
- ```
287
-
288
- ---
289
-
290
- ## 5. Health, timeline, portfolio, overview
291
-
292
- ### `getHealth(objectiveId?)`
293
-
294
- ```ts
295
- async getHealth(objectiveId?: string): Promise<ObjectiveHealth[]>
296
- ```
297
-
298
- | | |
299
- |--|--|
300
- | Auth | Required |
301
- | HTTP | `GET /health` optional `?objectiveId=` |
302
- | Unwrap | `{ health }` |
303
- | States | `healthy` · `warning` · `violation` · `paused` |
304
-
305
- ### `getTimeline(objectiveId?)`
306
-
307
- ```ts
308
- async getTimeline(objectiveId?: string): Promise<TimelineEvent[]>
309
- ```
310
-
311
- | | |
312
- |--|--|
313
- | Auth | Required |
314
- | HTTP | `GET /timeline` optional `?objectiveId=` |
315
- | Unwrap | `{ events }` |
316
- | Use | Operator narrative for launch video / audit |
317
-
318
- ### `getPortfolio()`
319
-
320
- ```ts
321
- async getPortfolio(): Promise<PortfolioSnapshot>
322
- ```
323
-
324
- | | |
325
- |--|--|
326
- | Auth | Required |
327
- | HTTP | `GET /portfolio` |
328
- | Empty book | Valid: `positions.length === 0`, notional may be `0` |
329
-
330
- ### `clearPortfolio()`
331
-
332
- ```ts
333
- async clearPortfolio(): Promise<PortfolioSnapshot>
334
- ```
335
-
336
- | | |
337
- |--|--|
338
- | Auth | Required |
339
- | HTTP | `POST /portfolio/clear` |
340
- | Unwrap | `{ portfolio }` → snapshot |
341
- | Notes | Clears wallet positions. Does **not** seed holdings. |
342
-
343
- ### `syncPortfolio()`
344
-
345
- ```ts
346
- async syncPortfolio(): Promise<SyncPortfolioResult>
347
- ```
348
-
349
- | | |
350
- |--|--|
351
- | Auth | API key + Bearer |
352
- | HTTP | `POST /portfolio/sync` |
353
- | Returns | `{ portfolio, chainId, skippedZero }` |
354
- | Notes | On-chain balances for the session wallet. Vault balances merge into the book. Does **not** invent holdings. |
355
-
356
- ### `getOverview()`
357
-
358
- ```ts
359
- async getOverview(): Promise<DashboardOverview>
360
- ```
361
-
362
- | | |
363
- |--|--|
364
- | Auth | Required |
365
- | HTTP | `GET /overview` |
366
- | Contains | Health counts, global score, 24h portfolio change (daily snapshots), evaluation schedule, recent executions + events |
367
-
368
- ---
369
-
370
- ## 6. Vault
371
-
372
- Vault reads and prepare endpoints. The API returns calldata **steps**; the host wallet signs and broadcasts, meaning the API never holds user keys.
373
-
374
- ### `getVault()`
375
-
376
- ```ts
377
- async getVault(): Promise<VaultOverview>
378
- ```
379
-
380
- | | |
381
- |--|--|
382
- | Auth | Required |
383
- | HTTP | `GET /vault` |
384
- | Returns | `address`, `chainId`, `tokens`, `balances`, `poolAddress`, `explorerBase`, `keeperAddress` |
385
-
386
- ### `getVaultStatus()`
387
-
388
- ```ts
389
- async getVaultStatus(): Promise<VaultStatus>
390
- // { empty, totalNotionalUsd, canRestore }
391
- ```
392
-
393
- | | |
394
- |--|--|
395
- | Auth | Required |
396
- | HTTP | `GET /vault/status` |
397
- | Use | Compact funding signal before restore |
398
-
399
- ### `prepareVaultDeposit({ symbol, amount })`
400
-
401
- ```ts
402
- async prepareVaultDeposit(input: {
403
- symbol: string; // "ETH" or any allowlisted ERC-20 (WETH, stables, …)
404
- amount: string;
405
- }): Promise<VaultPrepareResult>
406
- ```
407
-
408
- | | |
409
- |--|--|
410
- | Auth | Required |
411
- | HTTP | `POST /vault/prepare-deposit` body `{ symbol, amount }` |
412
- | ETH | Steps include `depositETH` (native value on step → vault WETH) |
413
- | ERC-20 | Steps include `approve` then `deposit` for any allowlisted symbol |
414
- | Host duty | Sign `steps` in order on `chainId`; broadcast each tx |
415
-
416
- ### `prepareVaultWithdraw({ symbol?, amount })`
417
-
418
- ```ts
419
- async prepareVaultWithdraw(input: {
420
- symbol?: string; // default "WETH"; any vault ERC-20 held by the user
421
- amount: string;
422
- }): Promise<VaultPrepareResult>
423
- ```
424
-
425
- | | |
426
- |--|--|
427
- | Auth | Required |
428
- | HTTP | `POST /vault/prepare-withdraw` body `{ symbol, amount }` |
429
- | Symbol | Any allowlisted vault ERC-20 (not native ETH, use WETH) |
430
- | Host duty | Sign and broadcast returned `steps` |
431
-
432
- ---
433
-
434
- ## 7. Market and execution
435
-
436
- ### Launch / rehearsal flow
437
-
438
- ```mermaid
439
- sequenceDiagram
440
- participant App
441
- participant SDK
442
- participant API
443
-
444
- App->>SDK: listMarketPresets
445
- API-->>App: presets
446
- App->>SDK: applyMarketEvent autoRestore true
447
- API-->>App: event + portfolio + health + executions
448
- Note over API: may run vault or staged restore
449
- App->>SDK: getTimeline
450
- API-->>App: violation_detected execution_completed
451
- ```
452
-
453
- ### `listMarketPresets()`
454
-
455
- ```ts
456
- async listMarketPresets(): Promise<MarketPreset[]>
457
- ```
458
-
459
- | | |
460
- |--|--|
461
- | Auth | Required |
462
- | HTTP | `GET /market/presets` |
463
- | Unwrap | `{ presets }` |
464
- | Fields | `name`, `description`, `symbol`, `priceChangeRatio` |
465
-
466
- ### `applyMarketEvent(input)`
467
-
468
- ```ts
469
- async applyMarketEvent(input: ApplyMarketEventInput): Promise<{
470
- event: MarketEvent;
471
- portfolio: PortfolioSnapshot;
472
- health: ObjectiveHealth[];
473
- executions: ExecutionReceipt[];
474
- }>
475
- ```
476
-
477
- | | |
478
- |--|--|
479
- | Auth | Required |
480
- | HTTP | `POST /market/events` |
481
- | Normalization | Uppercases symbol; `autoRestore` defaults **true** |
482
- | Validation | Symbol required; finite `priceChangeRatio`; rejects extreme ≤ -0.95 |
483
-
484
- ### `getRestorePlan(objectiveId)`
485
-
486
- ```ts
487
- async getRestorePlan(objectiveId: string): Promise<RestorePlan>
488
- // { kind, amountHuman, approxUsd, message, sellSymbol?, buySymbol? }
489
- ```
490
-
491
- | | |
492
- |--|--|
493
- | Auth | Required |
494
- | HTTP | `GET /objectives/:id/restore-plan` |
495
- | Kinds | `wrap_eth` · `unwrap_weth` · `vault_swap` |
496
- | Use | Inspect plan before acting, noting that wrap/unwrap is client-side |
497
-
498
- ### `runExecution(objectiveId)`
499
-
500
- ```ts
501
- async runExecution(objectiveId: string): Promise<ExecutionReceipt>
502
- ```
503
-
504
- | | |
505
- |--|--|
506
- | Auth | Required |
507
- | HTTP | `POST /executions/run` body `{ objectiveId }` |
508
- | Settlement | Receipt may include `settlement: "vault"` or `"staged"` |
509
- | Use | Restore when plan kind is `vault_swap` (rejects wrap/unwrap with action details) |
510
-
511
- ### `restoreObjective(objectiveId)`
512
-
513
- ```ts
514
- async restoreObjective(objectiveId: string): Promise<ExecutionReceipt>
515
- ```
516
-
517
- | | |
518
- |--|--|
519
- | Auth | Required |
520
- | HTTP | `POST /objectives/:id/restore` |
521
- | Settlement | Vault-backed restore when configured; same honesty labels as `runExecution` |
522
- | Use | Preferred vault restore entry for Automatic objectives after breach |
523
-
524
- ### `listExecutions(objectiveId?)`
525
-
526
- ```ts
527
- async listExecutions(objectiveId?: string): Promise<ExecutionReceipt[]>
528
- ```
529
-
530
- | | |
531
- |--|--|
532
- | Auth | Required |
533
- | HTTP | `GET /executions` optional `?objectiveId=` |
534
- | Unwrap | `{ executions }` |
535
-
536
- ---
537
-
538
- ## 8. Session helper
539
-
540
- ```ts
541
- import { createSessionTokenProvider } from "@buildaureon/sdk";
542
-
543
- const session = createSessionTokenProvider(initialToken?: string | null);
544
- session.getAccessToken(); // () => string | null
545
- session.setToken(token);
546
- session.clear();
547
- ```
548
-
549
- | Method | Purpose |
550
- |--------|---------|
551
- | `getAccessToken` | Pass directly into `createAureonClient({ getAccessToken })` |
552
- | `setToken` | After `verifyWallet` / `devLogin` |
553
- | `clear` | After `logout` or local sign-out |
554
-
555
- ---
556
-
557
- ## 9. Method → HTTP cheat sheet
558
-
559
- | Method | Verb | Path | Auth |
560
- |--------|------|------|------|
561
- | `ping` | GET | `/healthz` | no |
562
- | `getAuthNonce` | GET | `/auth/nonce` | no |
563
- | `verifyWallet` | POST | `/auth/verify` | no |
564
- | `devLogin` | POST | `/auth/dev-login` | no |
565
- | `logout` | POST | `/auth/logout` | recommended |
566
- | `me` | GET | `/auth/me` | **yes** |
567
- | `createObjective` | POST | `/objectives` | **yes** |
568
- | `listObjectives` | GET | `/objectives` | **yes** |
569
- | `getObjective` | GET | `/objectives/:id` | **yes** |
570
- | `updateObjective` | PATCH | `/objectives/:id` | **yes** |
571
- | `pauseObjective` | POST | `/objectives/:id/pause` | **yes** |
572
- | `resumeObjective` | POST | `/objectives/:id/resume` | **yes** |
573
- | `getHealth` | GET | `/health` | **yes** |
574
- | `getTimeline` | GET | `/timeline` | **yes** |
575
- | `getPortfolio` | GET | `/portfolio` | **yes** |
576
- | `setPortfolio` | PUT | `/portfolio` | **yes** |
577
- | `clearPortfolio` | POST | `/portfolio/clear` | **yes** |
578
- | `syncPortfolio` | POST | `/portfolio/sync` | **yes** |
579
- | `refreshWatchdog` | POST | `/watchdog/refresh` | **yes** |
580
- | `getOverview` | GET | `/overview` | **yes** |
581
- | `listMarketPresets` | GET | `/market/presets` | **yes** |
582
- | `applyMarketEvent` | POST | `/market/events` | **yes** |
583
- | `getRestorePlan` | GET | `/objectives/:id/restore-plan` | **yes** |
584
- | `restoreObjective` | POST | `/objectives/:id/restore` | **yes** |
585
- | `runExecution` | POST | `/executions/run` | **yes** |
586
- | `listExecutions` | GET | `/executions` | **yes** |
587
- | `getVault` | GET | `/vault` | **yes** |
588
- | `getVaultStatus` | GET | `/vault/status` | **yes** |
589
- | `prepareVaultDeposit` | POST | `/vault/prepare-deposit` | **yes** |
590
- | `prepareVaultWithdraw` | POST | `/vault/prepare-withdraw` | **yes** |
591
-
592
- ---
593
-
594
- ## 10. Common error patterns
595
-
596
- | Situation | Typical `code` | Integrator action |
597
- |-----------|----------------|-------------------|
598
- | Forgot Bearer on protected route | `UNAUTHORIZED` | Re-login / fix `getAccessToken` |
599
- | Name too short on create | `VALIDATION_ERROR` | Fix form |
600
- | Unknown objective id | `NOT_FOUND` | Refresh list |
601
- | Backend restart mid-session | `UNAUTHORIZED` | Clear token, connect again |
602
- | Transient 503 | `SERVER_ERROR` | Retries if `maxRetries > 0` |
603
- | Offline | `NETWORK_ERROR` | Show connectivity banner |
604
-
605
- Full matrix: [error-model.md](./error-model.md).
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`. Issued developer keys also identify the bound wallet (no Bearer required). Env bootstrap keys are product-gate only. Utility uses wallet Bearer only. |
49
+ | `getAccessToken` | no | N/A | Optional Bearer getter. Wins over API-key identity when present. |
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 | SDK supports **Automatic only**. Defaults **`automationMode: "auto"`**. Omit the field in agent integrations. |
206
+ | `targetSymbol` | Required when `kind === "balanced_portfolio"` (uppercased on normalize). |
207
+
208
+ **SDK policy:** Automatic mode only. Manual Approve belongs in the operator utility — do not build Manual agent loops with this package.
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
+ | Locked at create | `targetSymbol`, `automationMode` — recreate the objective to change either |
266
+
267
+ ### `pauseObjective(id)` / `resumeObjective(id)`
268
+
269
+ ```ts
270
+ async pauseObjective(id: string): Promise<Objective>
271
+ async resumeObjective(id: string): Promise<Objective>
272
+ ```
273
+
274
+ | | |
275
+ |--|--|
276
+ | Auth | Required |
277
+ | HTTP | `POST /objectives/:id/pause` · `POST /objectives/:id/resume` |
278
+ | Effect | Pause stops continuous evaluation; health typically reports `paused` |
279
+
280
+ ```mermaid
281
+ stateDiagram-v2
282
+ [*] --> active: createObjective
283
+ active --> paused: pauseObjective
284
+ paused --> active: resumeObjective
285
+ active --> active: updateObjective
286
+ ```
287
+
288
+ ---
289
+
290
+ ## 5. Health, timeline, portfolio, overview
291
+
292
+ ### `getHealth(objectiveId?)`
293
+
294
+ ```ts
295
+ async getHealth(objectiveId?: string): Promise<ObjectiveHealth[]>
296
+ ```
297
+
298
+ | | |
299
+ |--|--|
300
+ | Auth | Required |
301
+ | HTTP | `GET /health` optional `?objectiveId=` |
302
+ | Unwrap | `{ health }` |
303
+ | States | `healthy` · `warning` · `violation` · `paused` |
304
+
305
+ ### `getTimeline(objectiveId?)`
306
+
307
+ ```ts
308
+ async getTimeline(objectiveId?: string): Promise<TimelineEvent[]>
309
+ ```
310
+
311
+ | | |
312
+ |--|--|
313
+ | Auth | Required |
314
+ | HTTP | `GET /timeline` optional `?objectiveId=` |
315
+ | Unwrap | `{ events }` |
316
+ | Use | Operator narrative for launch video / audit |
317
+
318
+ ### `getPortfolio()`
319
+
320
+ ```ts
321
+ async getPortfolio(): Promise<PortfolioSnapshot>
322
+ ```
323
+
324
+ | | |
325
+ |--|--|
326
+ | Auth | Required |
327
+ | HTTP | `GET /portfolio` |
328
+ | Empty book | Valid: `positions.length === 0`, notional may be `0` |
329
+
330
+ ### `clearPortfolio()`
331
+
332
+ ```ts
333
+ async clearPortfolio(): Promise<PortfolioSnapshot>
334
+ ```
335
+
336
+ | | |
337
+ |--|--|
338
+ | Auth | Required |
339
+ | HTTP | `POST /portfolio/clear` |
340
+ | Unwrap | `{ portfolio }` → snapshot |
341
+ | Notes | Clears wallet positions. Does **not** seed holdings. |
342
+
343
+ ### `syncPortfolio()`
344
+
345
+ ```ts
346
+ async syncPortfolio(): Promise<SyncPortfolioResult>
347
+ ```
348
+
349
+ | | |
350
+ |--|--|
351
+ | Auth | API key + Bearer |
352
+ | HTTP | `POST /portfolio/sync` |
353
+ | Returns | `{ portfolio, chainId, skippedZero }` |
354
+ | Notes | On-chain balances for the session wallet. Vault balances merge into the book. Does **not** invent holdings. |
355
+
356
+ ### `getOverview()`
357
+
358
+ ```ts
359
+ async getOverview(): Promise<DashboardOverview>
360
+ ```
361
+
362
+ | | |
363
+ |--|--|
364
+ | Auth | Required |
365
+ | HTTP | `GET /overview` |
366
+ | Contains | Health counts, global score, 24h portfolio change (daily snapshots), evaluation schedule, recent executions + events |
367
+
368
+ ---
369
+
370
+ ## 6. Vault
371
+
372
+ Vault reads and prepare endpoints. The API returns calldata **steps**; the host wallet signs and broadcasts, meaning the API never holds user keys.
373
+
374
+ ### `getVault()`
375
+
376
+ ```ts
377
+ async getVault(): Promise<VaultOverview>
378
+ ```
379
+
380
+ | | |
381
+ |--|--|
382
+ | Auth | Required |
383
+ | HTTP | `GET /vault` |
384
+ | Returns | `address`, `chainId`, `tokens`, `balances`, `poolAddress`, `explorerBase`, `keeperAddress` |
385
+
386
+ ### `getVaultStatus()`
387
+
388
+ ```ts
389
+ async getVaultStatus(): Promise<VaultStatus>
390
+ // { empty, totalNotionalUsd, canRestore }
391
+ ```
392
+
393
+ | | |
394
+ |--|--|
395
+ | Auth | Required |
396
+ | HTTP | `GET /vault/status` |
397
+ | Use | Compact funding signal before restore |
398
+
399
+ ### `prepareVaultDeposit({ symbol, amount })`
400
+
401
+ ```ts
402
+ async prepareVaultDeposit(input: {
403
+ symbol: string; // "ETH" or any allowlisted ERC-20 (WETH, stables, …)
404
+ amount: string;
405
+ }): Promise<VaultPrepareResult>
406
+ ```
407
+
408
+ | | |
409
+ |--|--|
410
+ | Auth | Required |
411
+ | HTTP | `POST /vault/prepare-deposit` body `{ symbol, amount }` |
412
+ | ETH | Steps include `depositETH` (native value on step → vault WETH) |
413
+ | ERC-20 | Steps include `approve` then `deposit` for any allowlisted symbol |
414
+ | Host duty | Sign `steps` in order on `chainId`; broadcast each tx |
415
+
416
+ ### `prepareVaultWithdraw({ symbol?, amount })`
417
+
418
+ ```ts
419
+ async prepareVaultWithdraw(input: {
420
+ symbol?: string; // default "WETH"; any vault ERC-20 held by the user
421
+ amount: string;
422
+ }): Promise<VaultPrepareResult>
423
+ ```
424
+
425
+ | | |
426
+ |--|--|
427
+ | Auth | Required |
428
+ | HTTP | `POST /vault/prepare-withdraw` body `{ symbol, amount }` |
429
+ | Symbol | Any allowlisted vault ERC-20 (not native ETH, use WETH) |
430
+ | Host duty | Sign and broadcast returned `steps` |
431
+
432
+ ---
433
+
434
+ ## 7. Market and execution
435
+
436
+ ### Launch / rehearsal flow
437
+
438
+ ```mermaid
439
+ sequenceDiagram
440
+ participant App
441
+ participant SDK
442
+ participant API
443
+
444
+ App->>SDK: listMarketPresets
445
+ API-->>App: presets
446
+ App->>SDK: applyMarketEvent autoRestore true
447
+ API-->>App: event + portfolio + health + executions
448
+ Note over API: may run vault or staged restore
449
+ App->>SDK: getTimeline
450
+ API-->>App: violation_detected execution_completed
451
+ ```
452
+
453
+ ### `listMarketPresets()`
454
+
455
+ ```ts
456
+ async listMarketPresets(): Promise<MarketPreset[]>
457
+ ```
458
+
459
+ | | |
460
+ |--|--|
461
+ | Auth | Required |
462
+ | HTTP | `GET /market/presets` |
463
+ | Unwrap | `{ presets }` |
464
+ | Fields | `name`, `description`, `symbol`, `priceChangeRatio` |
465
+
466
+ ### `applyMarketEvent(input)`
467
+
468
+ ```ts
469
+ async applyMarketEvent(input: ApplyMarketEventInput): Promise<{
470
+ event: MarketEvent;
471
+ portfolio: PortfolioSnapshot;
472
+ health: ObjectiveHealth[];
473
+ executions: ExecutionReceipt[];
474
+ }>
475
+ ```
476
+
477
+ | | |
478
+ |--|--|
479
+ | Auth | Required |
480
+ | HTTP | `POST /market/events` |
481
+ | Normalization | Uppercases symbol; `autoRestore` defaults **true** |
482
+ | Validation | Symbol required; finite `priceChangeRatio`; rejects extreme ≤ -0.95 |
483
+
484
+ ### `getRestorePlan(objectiveId)`
485
+
486
+ ```ts
487
+ async getRestorePlan(objectiveId: string): Promise<RestorePlan>
488
+ // { kind, amountHuman, approxUsd, message, sellSymbol?, buySymbol? }
489
+ ```
490
+
491
+ | | |
492
+ |--|--|
493
+ | Auth | Required |
494
+ | HTTP | `GET /objectives/:id/restore-plan` |
495
+ | Kinds | `wrap_eth` · `unwrap_weth` · `vault_swap` |
496
+ | Use | Inspect plan before acting, noting that wrap/unwrap is client-side |
497
+
498
+ ### `runExecution(objectiveId)`
499
+
500
+ ```ts
501
+ async runExecution(objectiveId: string): Promise<ExecutionReceipt>
502
+ ```
503
+
504
+ | | |
505
+ |--|--|
506
+ | Auth | Required |
507
+ | HTTP | `POST /executions/run` body `{ objectiveId }` |
508
+ | Settlement | Receipt may include `settlement: "vault"` or `"staged"` |
509
+ | Use | Restore when plan kind is `vault_swap` (rejects wrap/unwrap with action details) |
510
+
511
+ ### `restoreObjective(objectiveId)`
512
+
513
+ ```ts
514
+ async restoreObjective(objectiveId: string): Promise<ExecutionReceipt>
515
+ ```
516
+
517
+ | | |
518
+ |--|--|
519
+ | Auth | Required |
520
+ | HTTP | `POST /objectives/:id/restore` |
521
+ | Settlement | Vault-backed restore when configured; same honesty labels as `runExecution` |
522
+ | Use | Preferred vault restore entry for Automatic objectives after breach |
523
+
524
+ ### `listExecutions(objectiveId?)`
525
+
526
+ ```ts
527
+ async listExecutions(objectiveId?: string): Promise<ExecutionReceipt[]>
528
+ ```
529
+
530
+ | | |
531
+ |--|--|
532
+ | Auth | Required |
533
+ | HTTP | `GET /executions` optional `?objectiveId=` |
534
+ | Unwrap | `{ executions }` |
535
+
536
+ ---
537
+
538
+ ## 8. Session helper
539
+
540
+ ```ts
541
+ import { createSessionTokenProvider } from "@buildaureon/sdk";
542
+
543
+ const session = createSessionTokenProvider(initialToken?: string | null);
544
+ session.getAccessToken(); // () => string | null
545
+ session.setToken(token);
546
+ session.clear();
547
+ ```
548
+
549
+ | Method | Purpose |
550
+ |--------|---------|
551
+ | `getAccessToken` | Pass directly into `createAureonClient({ getAccessToken })` |
552
+ | `setToken` | After `verifyWallet` / `devLogin` |
553
+ | `clear` | After `logout` or local sign-out |
554
+
555
+ ---
556
+
557
+ ## 9. Method → HTTP cheat sheet
558
+
559
+ | Method | Verb | Path | Auth |
560
+ |--------|------|------|------|
561
+ | `ping` | GET | `/healthz` | no |
562
+ | `getAuthNonce` | GET | `/auth/nonce` | no |
563
+ | `verifyWallet` | POST | `/auth/verify` | no |
564
+ | `devLogin` | POST | `/auth/dev-login` | no |
565
+ | `logout` | POST | `/auth/logout` | recommended |
566
+ | `me` | GET | `/auth/me` | **yes** |
567
+ | `createObjective` | POST | `/objectives` | **yes** |
568
+ | `listObjectives` | GET | `/objectives` | **yes** |
569
+ | `getObjective` | GET | `/objectives/:id` | **yes** |
570
+ | `updateObjective` | PATCH | `/objectives/:id` | **yes** |
571
+ | `pauseObjective` | POST | `/objectives/:id/pause` | **yes** |
572
+ | `resumeObjective` | POST | `/objectives/:id/resume` | **yes** |
573
+ | `getHealth` | GET | `/health` | **yes** |
574
+ | `getTimeline` | GET | `/timeline` | **yes** |
575
+ | `getPortfolio` | GET | `/portfolio` | **yes** |
576
+ | `setPortfolio` | PUT | `/portfolio` | **yes** |
577
+ | `clearPortfolio` | POST | `/portfolio/clear` | **yes** |
578
+ | `syncPortfolio` | POST | `/portfolio/sync` | **yes** |
579
+ | `refreshWatchdog` | POST | `/watchdog/refresh` | **yes** |
580
+ | `getOverview` | GET | `/overview` | **yes** |
581
+ | `listMarketPresets` | GET | `/market/presets` | **yes** |
582
+ | `applyMarketEvent` | POST | `/market/events` | **yes** |
583
+ | `getRestorePlan` | GET | `/objectives/:id/restore-plan` | **yes** |
584
+ | `restoreObjective` | POST | `/objectives/:id/restore` | **yes** |
585
+ | `runExecution` | POST | `/executions/run` | **yes** |
586
+ | `listExecutions` | GET | `/executions` | **yes** |
587
+ | `getVault` | GET | `/vault` | **yes** |
588
+ | `getVaultStatus` | GET | `/vault/status` | **yes** |
589
+ | `prepareVaultDeposit` | POST | `/vault/prepare-deposit` | **yes** |
590
+ | `prepareVaultWithdraw` | POST | `/vault/prepare-withdraw` | **yes** |
591
+
592
+ ---
593
+
594
+ ## 10. Common error patterns
595
+
596
+ | Situation | Typical `code` | Integrator action |
597
+ |-----------|----------------|-------------------|
598
+ | Forgot Bearer on protected route | `UNAUTHORIZED` | Re-login / fix `getAccessToken` |
599
+ | Name too short on create | `VALIDATION_ERROR` | Fix form |
600
+ | Unknown objective id | `NOT_FOUND` | Refresh list |
601
+ | Backend restart mid-session | `UNAUTHORIZED` | Clear token, connect again |
602
+ | Transient 503 | `SERVER_ERROR` | Retries if `maxRetries > 0` |
603
+ | Offline | `NETWORK_ERROR` | Show connectivity banner |
604
+
605
+ Full matrix: [error-model.md](./error-model.md).