@buildaureon/sdk 0.1.0 → 0.1.1

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/docs/auth.md CHANGED
@@ -1,60 +1,108 @@
1
- # Cryptographic Authentication Guide
1
+ # Authentication Guide
2
2
 
3
- AUREON combines classic API authentication with Web3 signature verification. This guide provides an in-depth technical explanation of the handshake flow, JWT payloads, and client integrations using standard EVM libraries.
3
+ How `@buildaureon/sdk` authenticates to the hosted AUREON API for agents, scripts, and server integrations.
4
4
 
5
- ---
5
+ **Automation note:** The SDK path is designed for **Automatic** objectives only (`automationMode: "auto"`). Manual operator Approve flows belong in the utility UI, not in SDK agent loops.
6
6
 
7
- ## 1. Authentication Topology
7
+ ---
8
8
 
9
- Requests are validated using a dual-token header model.
9
+ ## 1. Authentication topology
10
10
 
11
11
  ```mermaid
12
12
  graph TD
13
- Request[Client Request] --> KeyCheck{Has API Key?}
14
- KeyCheck -->|No| Reject1[401 Unauthorized: Missing API Key]
15
- KeyCheck -->|Yes| RouteCheck{Is Route Public?}
16
- RouteCheck -->|Yes| Allow[Process Request]
17
- RouteCheck -->|No| BearerCheck{Has Valid Bearer JWT?}
18
- BearerCheck -->|No| Reject2[401 Unauthorized: Missing Session Token]
19
- BearerCheck -->|Yes| ScopeCheck{Is Token Bound to Target Wallet?}
20
- ScopeCheck -->|No| Reject3[403 Forbidden: Wallet Mismatch]
21
- ScopeCheck -->|Yes| Process[Process request]
13
+ Request[Client_request] --> BearerCheck{Valid_Bearer?}
14
+ BearerCheck -->|Yes| Process[Act_as_session_wallet]
15
+ BearerCheck -->|No| KeyCheck{API_key_present?}
16
+ KeyCheck -->|No| Reject1[401_missing_credentials]
17
+ KeyCheck -->|Yes| IssuedCheck{Issued_developer_key?}
18
+ IssuedCheck -->|Yes| ProcessKey[Act_as_key_bound_wallet]
19
+ IssuedCheck -->|No_env_bootstrap| Reject2[401_need_issued_key_or_Bearer]
20
+ ```
21
+
22
+ | Credential | Header | Role |
23
+ | --- | --- | --- |
24
+ | **Issued API key** (Developers console) | `X-Aureon-Api-Key` | Product access **and** wallet identity for control-plane calls |
25
+ | **Env bootstrap key** (`AUREON_API_KEYS` on server) | `X-Aureon-Api-Key` | Product gate only — does **not** identify a wallet |
26
+ | **Wallet Bearer** | `Authorization: Bearer …` | Optional session identity. **Wins** when both Bearer and key are present |
27
+ | **Private key** | (chain only) | Sign/broadcast deposit & withdraw txs — never sent to the API |
28
+
29
+ Control-plane calls (sync, objectives, health, restore, vault reads, prepare-*) need an **issued** developer key **or** a Bearer session. Moving capital on-chain always needs a local signer.
30
+
31
+ ---
32
+
33
+ ## 2. Recommended path: issued API key
34
+
35
+ 1. Open the operator utility → **Developers**.
36
+ 2. Create a key. Copy the plaintext once.
37
+ 3. Set env and construct the client:
38
+
39
+ ```ts
40
+ import { createAureonClient } from "@buildaureon/sdk";
41
+
42
+ const aureon = createAureonClient({
43
+ baseUrl: "https://api.aureonlabs.network",
44
+ apiKey: process.env.AUREON_API_KEY!, // issued key from Developers
45
+ });
46
+
47
+ const me = await aureon.me();
48
+ console.log("wallet", me.walletAddress);
49
+
50
+ const vault = await aureon.getVaultStatus();
51
+ const objectives = await aureon.listObjectives();
22
52
  ```
23
53
 
24
- * **API Key (`X-Aureon-Api-Key`)**: Sent in the headers to identify your product subscription or server deployment. It is generated in the developer dashboard.
25
- * **Bearer JWT (`Authorization: Bearer <token>`)**: Establishes session ownership. It is generated dynamically by signing a server-issued challenge message with your private key.
54
+ No Bearer token is required for this path. The gateway resolves the wallet bound to the issued key.
55
+
56
+ ### Deposit / withdraw still need a private key
57
+
58
+ ```ts
59
+ const prep = await aureon.prepareVaultDeposit({ symbol: "ETH", amount: "0.1" });
60
+ // prep.steps are UNSIGNED — sign and broadcast with viem / ethers / your wallet host
61
+ ```
62
+
63
+ The API key can request prepare steps. It cannot sign chain transactions.
26
64
 
27
65
  ---
28
66
 
29
- ## 2. EIP-191 Cryptographic Handshake
67
+ ## 3. Optional Bearer handshake
30
68
 
31
- The signature validation relies on the EIP-191 standard for signing personal messages. The process prevents replay attacks and ensures session integrity.
69
+ Use when you intentionally want a wallet session, or when you only have an env bootstrap key (no issued key).
32
70
 
33
71
  ```mermaid
34
72
  sequenceDiagram
35
73
  autonumber
36
- participant Client as SDK Client
37
- participant Gateway as Aureon Gateway
38
- participant Signer as Wallet Signer (EIP-191)
39
-
40
- Client->>Gateway: GET /auth/nonce?address=0x742...
41
- Gateway->>Gateway: Generate unique nonce & expiresAt
42
- Gateway-->>Client: Challenge (nonce, message, expiresAt)
43
- Client->>Signer: Request signature over message
44
- Signer->>Signer: Sign message using private key (personal_sign)
45
- Signer-->>Client: Cryptographic Signature (65-byte hex string)
46
- Client->>Gateway: POST /auth/verify { address, message, signature }
47
- Gateway->>Gateway: Recover signer address from signature
48
- alt Recovered Address == Input Address and Not Expired
49
- Gateway->>Gateway: Generate JWT (Expires in 24 hours)
50
- Gateway-->>Client: AuthSessionResponse (token, expiresAt)
51
- else Validation Failed
52
- Gateway-->>Client: Throw 401 ValidationError
53
- end
74
+ participant Client as SDK_client
75
+ participant API as Aureon_API
76
+ participant Signer as Wallet_signer
77
+
78
+ Client->>API: GET /auth/nonce?address=0x...
79
+ API-->>Client: challenge message
80
+ Client->>Signer: personal_sign(message)
81
+ Signer-->>Client: signature
82
+ Client->>API: POST /auth/verify
83
+ API-->>Client: session token
54
84
  ```
55
85
 
56
- ### 2.1 The Challenge Message Schema
57
- The message returned by `/auth/nonce` follows a strict structure:
86
+ ```ts
87
+ import { createAureonClient, createSessionTokenProvider } from "@buildaureon/sdk";
88
+
89
+ const session = createSessionTokenProvider(null);
90
+ const aureon = createAureonClient({
91
+ baseUrl: "https://api.aureonlabs.network",
92
+ apiKey: process.env.AUREON_API_KEY,
93
+ getAccessToken: session.getAccessToken,
94
+ });
95
+
96
+ const { message } = await aureon.getAuthNonce(address);
97
+ const signature = await wallet.signMessage({ message });
98
+ const login = await aureon.verifyWallet({ address, message, signature });
99
+ session.setToken(login.token);
100
+
101
+ await aureon.me();
102
+ ```
103
+
104
+ ### Challenge message shape
105
+
58
106
  ```text
59
107
  AUREON Login Challenge
60
108
  Wallet: 0x742d35Cc6634C0532925a3b844Bc454e4438f44e
@@ -64,152 +112,63 @@ Expires: 2026-07-15T22:50:00.000Z
64
112
 
65
113
  Sign this message to prove ownership of the wallet.
66
114
  ```
67
- * **Nonce**: A cryptographically secure random string preventing replay attacks.
68
- * **Expires**: The timestamp (5-minute TTL) after which the challenge becomes invalid.
69
115
 
70
- ---
116
+ ### Session provider lifecycle
71
117
 
72
- ## 3. JWT Payload Structure
73
-
74
- Upon successful signature recovery, the gateway issues a JSON Web Token containing the session metadata:
75
-
76
- ```json
77
- {
78
- "sub": "0x742d35cc6634c0532925a3b844bc454e4438f44e",
79
- "iss": "aureon-auth-service",
80
- "iat": 1784155500,
81
- "exp": 1784241900,
82
- "sid": "sess_01h8v12x8p8p3z2v1q45r3m2e1",
83
- "scope": "operator"
84
- }
118
+ ```ts
119
+ session.setToken(login.token); // after verify
120
+ await aureon.logout();
121
+ session.clear();
85
122
  ```
86
123
 
87
- * **`sub` (Subject)**: The lowercase Ethereum address of the authenticated wallet.
88
- * **`exp` (Expiration)**: Unix timestamp set exactly 24 hours after token issuance.
89
- * **`scope`**: Defines operational permissions (e.g. `operator`, `read-only`).
124
+ `createSessionTokenProvider` keeps the client free of global mutable auth state. Prefer `getAccessToken` over a static `authToken` when sessions can rotate.
90
125
 
91
126
  ---
92
127
 
93
- ## 4. Multi-Framework Integration Examples
128
+ ## 4. Precedence and edge cases
94
129
 
95
- ### 4.1 Integration via Viem (TypeScript / Node.js)
96
- Ideal for background cron daemons, keepers, and automated scripts.
130
+ | Situation | Result |
131
+ | --- | --- |
132
+ | Issued key only | Act as key-bound wallet |
133
+ | Bearer only | Act as session wallet |
134
+ | Bearer + any key | Bearer wins (key validated if sent) |
135
+ | Env bootstrap key only | 401 — cannot identify a wallet |
136
+ | Invalid / paused / revoked issued key | 401 |
137
+ | `devLogin()` | Local preview APIs only — not production |
97
138
 
98
- ```ts
99
- import { createAureonClient, createSessionTokenProvider } from "@buildaureon/sdk";
100
- import { createWalletClient, http } from "viem";
101
- import { privateKeyToAccount } from "viem/accounts";
102
- import { mainnet } from "viem/chains";
103
-
104
- async function authenticateAgent() {
105
- const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
106
- const wallet = createWalletClient({
107
- account,
108
- chain: mainnet,
109
- transport: http()
110
- });
111
-
112
- const session = createSessionTokenProvider(null);
113
- const aureon = createAureonClient({
114
- apiKey: process.env.AUREON_API_KEY,
115
- getAccessToken: session.getAccessToken
116
- });
117
-
118
- // 1. Get nonce
119
- const { message } = await aureon.getAuthNonce(account.address);
120
-
121
- // 2. Sign EIP-191 message
122
- const signature = await wallet.signMessage({ message });
123
-
124
- // 3. Verify on server
125
- const login = await aureon.verifyWallet({
126
- address: account.address,
127
- message,
128
- signature
129
- });
130
-
131
- session.setToken(login.token);
132
- return aureon;
133
- }
134
- ```
139
+ ---
135
140
 
136
- ### 4.2 Integration via Ethers.js v6
137
- Useful for traditional Node.js servers or scripts using Ethers.
141
+ ## 5. Environment variables
138
142
 
139
- ```ts
140
- import { createAureonClient, createSessionTokenProvider } from "@buildaureon/sdk";
141
- import { Wallet } from "ethers";
142
-
143
- async function authenticateEthers() {
144
- const wallet = new Wallet(process.env.PRIVATE_KEY!);
145
- const session = createSessionTokenProvider(null);
146
- const aureon = createAureonClient({
147
- apiKey: process.env.AUREON_API_KEY,
148
- getAccessToken: session.getAccessToken
149
- });
150
-
151
- const { message } = await aureon.getAuthNonce(wallet.address);
152
- const signature = await wallet.signMessage(message);
153
-
154
- const login = await aureon.verifyWallet({
155
- address: wallet.address,
156
- message,
157
- signature
158
- });
159
-
160
- session.setToken(login.token);
161
- return aureon;
162
- }
143
+ | Variable | Required | Description |
144
+ | --- | --- | --- |
145
+ | `AUREON_API_KEY` | Recommended | Issued developer key |
146
+ | `AUREON_API_URL` | No | Defaults to `https://api.aureonlabs.network` |
147
+ | `AUREON_TOKEN` | No | Optional Bearer for CLI / scripts |
148
+
149
+ CLI example:
150
+
151
+ ```bash
152
+ export AUREON_API_KEY=aureon_....
153
+ pnpm --filter @buildaureon/sdk cli me
154
+ pnpm --filter @buildaureon/sdk cli sync
155
+ pnpm --filter @buildaureon/sdk cli objectives
163
156
  ```
164
157
 
165
- ### 4.3 Integration in Browser Frontends (window.ethereum)
166
- Suitable for operator portals and user-facing dashboards.
158
+ ---
167
159
 
168
- ```ts
169
- import { createAureonClient, createSessionTokenProvider } from "@buildaureon/sdk";
160
+ ## 6. Security rules
170
161
 
171
- async function loginBrowser() {
172
- if (!window.ethereum) throw new Error("No provider found");
173
-
174
- const [address] = await window.ethereum.request({ method: "eth_requestAccounts" });
175
- const session = createSessionTokenProvider(localStorage.getItem("aureon_token"));
176
-
177
- const aureon = createAureonClient({
178
- apiKey: process.env.AUREON_API_KEY,
179
- getAccessToken: session.getAccessToken
180
- });
181
-
182
- try {
183
- // Validate current token
184
- await aureon.me();
185
- } catch (err) {
186
- // Fetch new challenge
187
- const { message } = await aureon.getAuthNonce(address);
188
-
189
- // Sign using browser extension wallet
190
- const signature = await window.ethereum.request({
191
- method: "personal_sign",
192
- params: [message, address]
193
- });
194
-
195
- const login = await aureon.verifyWallet({ address, message, signature });
196
- session.setToken(login.token);
197
- localStorage.setItem("aureon_token", login.token);
198
- }
199
-
200
- return aureon;
201
- }
202
- ```
162
+ - Treat issued keys like passwords: pause, revoke, rotate in Developers.
163
+ - Never commit keys or Bearer tokens.
164
+ - Never put private keys in SDK env for “convenience.”
165
+ - Do not log `Authorization` or `X-Aureon-Api-Key` headers.
203
166
 
204
167
  ---
205
168
 
206
- ## 5. Token Lifecycle and Recovery
169
+ ## 7. Related docs
207
170
 
208
- * **Handling Token Expirations**: When a session token expires, the gateway returns a `401 UNAUTHORIZED` error. Integrators should register a callback in their request loops to renew the token automatically.
209
- * **Multi-Wallet Routing**: If your application manages multiple vaults, instantiate separate `AureonClient` instances for each session token provider. Portfolios are partitioned by wallet address.
210
- * **Logout Mechanics**: Invoking `aureon.logout()` invalidates the JWT on the gateway. The local cache should be cleared immediately:
211
- ```ts
212
- await aureon.logout();
213
- session.clear();
214
- localStorage.removeItem("aureon_token");
215
- ```
171
+ - [Integration guide](./integration-guide.md)
172
+ - [Security](./security.md)
173
+ - [Client API](./client-api.md)
174
+ - [Error model](./error-model.md)
@@ -45,8 +45,8 @@ const aureon = createAureonClient({
45
45
  | Option | Required | Default | Description |
46
46
  |--------|----------|---------|-------------|
47
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. |
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
50
  | `authToken` | no | N/A | Static Bearer string when `getAccessToken` is omitted. |
51
51
  | `timeoutMs` | no | `30000` | Per-attempt abort timeout. |
52
52
  | `maxRetries` | no | `0` | Extra attempts after first failure for retryable errors. |
@@ -202,10 +202,10 @@ async createObjective(input: CreateObjectiveInput): Promise<Objective>
202
202
  | Auth | Required |
203
203
  | HTTP | `POST /objectives` |
204
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. |
205
+ | Automation | SDK supports **Automatic only**. Defaults **`automationMode: "auto"`**. Omit the field in agent integrations. |
206
206
  | `targetSymbol` | Required when `kind === "balanced_portfolio"` (uppercased on normalize). |
207
207
 
208
- Manual Approve (`automationMode: "manual"`) is **operator-utility only**, and is not the recommended SDK create path.
208
+ **SDK policy:** Automatic mode only. Manual Approve belongs in the operator utility do not build Manual agent loops with this package.
209
209
 
210
210
  ```ts
211
211
  const objective = await aureon.createObjective({
@@ -262,6 +262,7 @@ async updateObjective(id: string, input: UpdateObjectiveInput): Promise<Objectiv
262
262
  | Auth | Required |
263
263
  | HTTP | `PATCH /objectives/:id` |
264
264
  | Body | Partial: name, priority, targetWeight, tolerance, maxRiskScore, reinvestRatio |
265
+ | Locked at create | `targetSymbol`, `automationMode` — recreate the objective to change either |
265
266
 
266
267
  ### `pauseObjective(id)` / `resumeObjective(id)`
267
268
 
@@ -65,13 +65,16 @@ export type ObjectivePriority = "low" | "medium" | "high" | "critical";
65
65
  ### ObjectiveAutomationMode
66
66
 
67
67
  Determines how policy violations are corrected:
68
- * `auto`: Fully automated restore loops. The system generates execution receipts immediately upon detecting a violation (SDK default).
69
- * `manual`: The operator utility flags the violation, requiring an explicit approval step in the UI.
68
+
69
+ * `auto` Automatic restore coordination (SDK **only** supported mode; default).
70
+ * `manual` — Operator utility Approve flow. Not used for SDK agent integrations.
70
71
 
71
72
  ```ts
72
73
  export type ObjectiveAutomationMode = "manual" | "auto";
73
74
  ```
74
75
 
76
+ For `@buildaureon/sdk`, always omit `automationMode` or pass `"auto"`.
77
+
75
78
  ### ObjectivePolicy
76
79
 
77
80
  Specifies the mathematical parameters governing target bounds:
@@ -149,7 +152,7 @@ Passed to `createObjective` to register a new rule:
149
152
  * `automationMode` (Optional): Defaults to `auto` in the SDK.
150
153
 
151
154
  #### `UpdateObjectiveInput`
152
- Passed to `updateObjective` for partial updates. Note that `automationMode` is fixed at creation and cannot be updated.
155
+ Passed to `updateObjective` for partial updates. `targetSymbol` and `automationMode` are fixed at creation and cannot be updated.
153
156
 
154
157
  ```ts
155
158
  export interface UpdateObjectiveInput {
@@ -159,7 +162,7 @@ export interface UpdateObjectiveInput {
159
162
  tolerance?: number;
160
163
  maxRiskScore?: number;
161
164
  reinvestRatio?: number;
162
- targetSymbol?: string | null;
165
+ targetSymbol?: never; // Disallowed on updates
163
166
  automationMode?: never; // Disallowed on updates
164
167
  }
165
168
  ```