@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/README.md +353 -245
- package/dist/index.d.ts +15 -6
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/docs/architecture.md +139 -138
- package/docs/auth.md +127 -168
- package/docs/client-api.md +5 -4
- package/docs/data-contracts.md +7 -4
- package/docs/error-model.md +151 -116
- package/docs/integration-guide.md +173 -112
- package/docs/security.md +87 -41
- package/docs/transport.md +91 -77
- package/examples/e2e-policy-rebalance/main.ts +24 -36
- package/examples/e2e-policy-rebalance/underrun.ts +28 -24
- package/examples/e2e-policy-rebalance/verify-sizing.ts +29 -26
- package/examples/e2e-vault-flow/main.ts +36 -90
- package/examples/market-event/main.ts +9 -9
- package/examples/quickstart/main.ts +17 -16
- package/examples/sdk-demo-terminal/main.ts +171 -0
- package/package.json +5 -8
package/docs/auth.md
CHANGED
|
@@ -1,60 +1,108 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Authentication Guide
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
7
|
+
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## 1. Authentication topology
|
|
10
10
|
|
|
11
11
|
```mermaid
|
|
12
12
|
graph TD
|
|
13
|
-
Request[
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
25
|
-
|
|
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
|
-
##
|
|
67
|
+
## 3. Optional Bearer handshake
|
|
30
68
|
|
|
31
|
-
|
|
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
|
|
37
|
-
participant
|
|
38
|
-
participant Signer as
|
|
39
|
-
|
|
40
|
-
Client->>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
Client
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
57
|
-
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
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.
|
|
128
|
+
## 4. Precedence and edge cases
|
|
94
129
|
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
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
|
-
|
|
137
|
-
Useful for traditional Node.js servers or scripts using Ethers.
|
|
141
|
+
## 5. Environment variables
|
|
138
142
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
-
|
|
166
|
-
Suitable for operator portals and user-facing dashboards.
|
|
158
|
+
---
|
|
167
159
|
|
|
168
|
-
|
|
169
|
-
import { createAureonClient, createSessionTokenProvider } from "@buildaureon/sdk";
|
|
160
|
+
## 6. Security rules
|
|
170
161
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
##
|
|
169
|
+
## 7. Related docs
|
|
207
170
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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)
|
package/docs/client-api.md
CHANGED
|
@@ -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 |
|
|
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"
|
|
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
|
|
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
|
|
package/docs/data-contracts.md
CHANGED
|
@@ -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
|
-
|
|
69
|
-
*
|
|
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.
|
|
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?:
|
|
165
|
+
targetSymbol?: never; // Disallowed on updates
|
|
163
166
|
automationMode?: never; // Disallowed on updates
|
|
164
167
|
}
|
|
165
168
|
```
|