@usepraxis/sdk 0.1.1 → 0.2.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.
package/README.md CHANGED
@@ -84,13 +84,25 @@ toBaseUnits("500000000"); // 500000000n
84
84
  | Auth | `connect()`, `session()`, `logout()` |
85
85
  | Conversation | `ask()`, `send()`, `newThread()`, `signProposal()`, `cancelProposal()` |
86
86
  | Reads | `getPolicy()`, `getThreads()`, `getThread()`, `getProposal()`, `getActivity()`, `getAddressBook()`, `isThinking()`, `getVersion()` |
87
- | Policy (server-key) | `bootstrapPolicy()`, `updatePolicy()`, `configureToken()`, `prepareTokenAccounts()`, `revokeAgent()`, `rotateAgent()`, `addToAllowList()`, `removeFromAllowList()` |
87
+ | Policy (server-key) | `bootstrapPolicy()`, `fundVault()`, `withdrawVault()`, `updatePolicy()`, `configureToken()`, `prepareTokenAccounts()`, `revokeAgent()`, `rotateAgent()`, `addToAllowList()`, `removeFromAllowList()`, `deleteAgent()` |
88
88
  | Owner (wallet-signed) | `buildOwnerTransaction()`, `submitOwnerTransaction()` |
89
89
 
90
+ `session()` returns the current `SessionInfo` or `null` when signed out.
91
+
92
+ > **Owner wallet-signed path.** `buildOwnerTransaction()` returns an *unsigned*
93
+ > transaction; you sign it with a transaction-capable wallet (a browser wallet
94
+ > adapter or `@solana/web3.js`) and submit the result with
95
+ > `submitOwnerTransaction()`. The SDK's `keypairSigner` signs the sign-in
96
+ > *message* only, not transactions — so a pure-Node owner-action flow must bring
97
+ > its own transaction signer.
98
+
90
99
  ## Errors
91
100
 
92
101
  Non-2xx responses throw `PraxisApiError` with `.status`, `.type`, and helpers
93
- `.isAuth` / `.isRateLimited` / `.isInput`.
102
+ `.isAuth` / `.isRateLimited` / `.isInput` / `.isNotFound` / `.isConfig` /
103
+ `.isServer`. A client-side timeout or connection failure throws
104
+ `PraxisApiError` with `.isTimeout` / `.isNetwork` (and `.status === 0`, with the
105
+ original error on `.cause`). SDK-side misconfiguration throws `PraxisConfigError`.
94
106
 
95
107
  ```ts
96
108
  import { PraxisApiError } from "@usepraxis/sdk";
package/dist/index.cjs CHANGED
@@ -15,8 +15,8 @@ var PraxisApiError = class _PraxisApiError extends Error {
15
15
  status;
16
16
  /** The backend error class name, e.g. "PraxisAuthError", "PraxisRateLimitError". */
17
17
  type;
18
- constructor(status, type, message) {
19
- super(message);
18
+ constructor(status, type, message, options) {
19
+ super(message, options);
20
20
  this.name = "PraxisApiError";
21
21
  this.status = status;
22
22
  this.type = type;
@@ -31,10 +31,30 @@ var PraxisApiError = class _PraxisApiError extends Error {
31
31
  get isInput() {
32
32
  return this.status === 400;
33
33
  }
34
+ /** Resource not found (404). */
35
+ get isNotFound() {
36
+ return this.status === 404;
37
+ }
38
+ /** Server reported a configuration problem (503) — usually transient. */
39
+ get isConfig() {
40
+ return this.status === 503;
41
+ }
42
+ /** The request timed out client-side before any HTTP response. */
43
+ get isTimeout() {
44
+ return this.status === 0 && this.type === "TimeoutError";
45
+ }
46
+ /** A connection-level failure (DNS, refused, TLS) before any HTTP response. */
47
+ get isNetwork() {
48
+ return this.status === 0 && this.type === "NetworkError";
49
+ }
50
+ /** Any server-side failure (HTTP >= 500). */
51
+ get isServer() {
52
+ return this.status >= 500;
53
+ }
34
54
  };
35
55
  var PraxisConfigError = class _PraxisConfigError extends Error {
36
- constructor(message) {
37
- super(message);
56
+ constructor(message, options) {
57
+ super(message, options);
38
58
  this.name = "PraxisConfigError";
39
59
  Object.setPrototypeOf(this, _PraxisConfigError.prototype);
40
60
  }
@@ -47,6 +67,7 @@ var PraxisClient = class {
47
67
  signer;
48
68
  fetchImpl;
49
69
  timeoutMs;
70
+ agentTimeoutMs;
50
71
  /** Manual cookie jar — Node's fetch does not persist Set-Cookie across calls. */
51
72
  sessionCookie;
52
73
  constructor(options) {
@@ -59,6 +80,7 @@ var PraxisClient = class {
59
80
  }
60
81
  this.fetchImpl = resolvedFetch;
61
82
  this.timeoutMs = options.timeoutMs ?? 2e4;
83
+ this.agentTimeoutMs = Math.max(options.agentTimeoutMs ?? 6e4, this.timeoutMs);
62
84
  }
63
85
  // --- auth ----------------------------------------------------------------
64
86
  /** The signer's wallet address, if a signer was provided. */
@@ -67,7 +89,8 @@ var PraxisClient = class {
67
89
  }
68
90
  /**
69
91
  * Run the wallet-ownership handshake: request a challenge, sign its message,
70
- * verify it, and store the resulting session cookie. Idempotent.
92
+ * verify it, and store the resulting session cookie. Safe to call again to
93
+ * refresh the session (each call issues a new challenge + cookie).
71
94
  */
72
95
  async connect() {
73
96
  if (!this.signer) {
@@ -83,24 +106,37 @@ var PraxisClient = class {
83
106
  signature: bs582__default.default.encode(signature)
84
107
  });
85
108
  }
86
- /** Current session, or `null` if not signed in. */
109
+ /**
110
+ * Current session, or `null` if not signed in. The endpoint answers `200`
111
+ * with `{ authenticated: false }` when signed out, so this normalizes both
112
+ * that shape and a `401` to `null`.
113
+ */
87
114
  async session() {
88
115
  try {
89
- return await this.get("/auth/session");
116
+ const info = await this.get("/auth/session");
117
+ return info && info.authenticated ? info : null;
90
118
  } catch (error) {
91
119
  if (error instanceof PraxisApiError && error.isAuth) return null;
92
120
  throw error;
93
121
  }
94
122
  }
95
- /** Clear the session (server-side cookie + local jar). */
123
+ /**
124
+ * Clear the session (server-side cookie + local jar). Idempotent: if there is
125
+ * no active session, the local jar is still cleared and no error is thrown.
126
+ */
96
127
  async logout() {
97
- await this.request("DELETE", "/auth/session");
98
- this.sessionCookie = void 0;
128
+ try {
129
+ await this.request("DELETE", "/auth/session");
130
+ } catch (error) {
131
+ if (!(error instanceof PraxisApiError && error.isAuth)) throw error;
132
+ } finally {
133
+ this.sessionCookie = void 0;
134
+ }
99
135
  }
100
136
  // --- conversation --------------------------------------------------------
101
137
  /** Send a line to the agent. Creates a thread when `threadId` is omitted. */
102
138
  send(text, threadId = null) {
103
- return this.post("/send", { text, threadId });
139
+ return this.post("/send", { text, threadId }, this.agentTimeoutMs);
104
140
  }
105
141
  /**
106
142
  * Send a line and return the agent's reply in one call. The API resolves
@@ -155,6 +191,18 @@ var PraxisClient = class {
155
191
  bootstrapPolicy(fundLamports) {
156
192
  return this.post("/bootstrap-policy", fundLamports ? { fundLamports } : {});
157
193
  }
194
+ /** Deposit SOL (lamports, base-unit string) from the owner into the vault. */
195
+ fundVault(amount) {
196
+ return this.post("/fund-vault", { amount });
197
+ }
198
+ /** Withdraw SOL (lamports, base-unit string) from the vault to the owner. */
199
+ withdrawVault(amount) {
200
+ return this.post("/withdraw-vault", { amount });
201
+ }
202
+ /** Tear the agent down — drain the vault and close the policy. Irreversible. */
203
+ deleteAgent() {
204
+ return this.post("/delete-agent", {});
205
+ }
158
206
  updatePolicy(patch) {
159
207
  return this.post("/update-policy", { patch });
160
208
  }
@@ -177,11 +225,16 @@ var PraxisClient = class {
177
225
  return this.post("/remove-from-allow-list", { kind, address });
178
226
  }
179
227
  // --- owner wallet-signed transaction path --------------------------------
180
- /** Build an unsigned owner transaction for the wallet to sign. */
228
+ /**
229
+ * Build an unsigned owner transaction for the wallet to sign. The caller signs
230
+ * the returned base64 `transaction` with a transaction-capable wallet, then
231
+ * passes the result to {@link submitOwnerTransaction}. (The SDK's
232
+ * `keypairSigner` signs sign-in messages only, not transactions.)
233
+ */
181
234
  buildOwnerTransaction(action) {
182
235
  return this.post("/owner/build", { action });
183
236
  }
184
- /** Submit a wallet-signed owner transaction. */
237
+ /** Submit a wallet-signed owner transaction; resolves with its signature. */
185
238
  submitOwnerTransaction(signed) {
186
239
  return this.post("/owner/submit", signed);
187
240
  }
@@ -189,8 +242,8 @@ var PraxisClient = class {
189
242
  get(path, query) {
190
243
  return this.request("GET", path, { query });
191
244
  }
192
- post(path, body) {
193
- return this.request("POST", path, { body });
245
+ post(path, body, timeoutMs) {
246
+ return this.request("POST", path, { body, timeoutMs });
194
247
  }
195
248
  async request(method, path, opts = {}) {
196
249
  const url = new URL(this.baseUrl + API_PREFIX + path);
@@ -198,8 +251,9 @@ var PraxisClient = class {
198
251
  const headers = { accept: "application/json" };
199
252
  if (opts.body !== void 0) headers["content-type"] = "application/json";
200
253
  if (this.sessionCookie) headers["cookie"] = this.sessionCookie;
254
+ const timeoutMs = opts.timeoutMs ?? this.timeoutMs;
201
255
  const controller = new AbortController();
202
- const timer = setTimeout(() => controller.abort(), this.timeoutMs);
256
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
203
257
  let res;
204
258
  try {
205
259
  res = await this.fetchImpl(url.toString(), {
@@ -212,9 +266,13 @@ var PraxisClient = class {
212
266
  });
213
267
  } catch (error) {
214
268
  if (error instanceof Error && error.name === "AbortError") {
215
- throw new PraxisApiError(0, "TimeoutError", `Praxis request timed out after ${this.timeoutMs}ms`);
269
+ throw new PraxisApiError(0, "TimeoutError", `Praxis request timed out after ${timeoutMs}ms`, {
270
+ cause: error
271
+ });
216
272
  }
217
- throw error;
273
+ if (error instanceof PraxisApiError) throw error;
274
+ const detail = error instanceof Error ? error.message : String(error);
275
+ throw new PraxisApiError(0, "NetworkError", `Praxis request failed: ${detail}`, { cause: error });
218
276
  } finally {
219
277
  clearTimeout(timer);
220
278
  }
@@ -276,6 +334,9 @@ function normalizeSecret(secret) {
276
334
  throw new PraxisConfigError("secret key string must be base58-encoded");
277
335
  }
278
336
  } else if (Array.isArray(secret)) {
337
+ if (!secret.every((b) => Number.isInteger(b) && b >= 0 && b <= 255)) {
338
+ throw new PraxisConfigError("secret key array must contain only byte values (integers 0\u2013255)");
339
+ }
279
340
  bytes = Uint8Array.from(secret);
280
341
  } else {
281
342
  bytes = secret;
@@ -289,10 +350,19 @@ function normalizeSecret(secret) {
289
350
  }
290
351
 
291
352
  // src/units.ts
353
+ var INTEGER_RE = /^-?\d+$/;
292
354
  function toBaseUnits(value) {
293
- return typeof value === "bigint" ? value : BigInt(value.trim());
355
+ if (typeof value === "bigint") return value;
356
+ const trimmed = value.trim();
357
+ if (!INTEGER_RE.test(trimmed)) {
358
+ throw new Error(`toBaseUnits: expected an integer base-unit string, got "${value}"`);
359
+ }
360
+ return BigInt(trimmed);
294
361
  }
295
362
  function fromBaseUnits(value) {
363
+ if (typeof value === "number" && !Number.isSafeInteger(value)) {
364
+ throw new Error(`fromBaseUnits: number must be a safe integer, got ${value}`);
365
+ }
296
366
  return BigInt(value).toString();
297
367
  }
298
368
  function humanToBaseUnits(amount, decimals) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/signer.ts","../src/units.ts","../src/types.ts"],"names":["bs58","nacl","ActionKind","RejectReason"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Thrown when the Praxis API returns a non-2xx response. The backend's error\n * envelope is `{ error: string, type: string }` with a meaningful HTTP status\n * (400 input, 401 auth, 404 not-found, 429 rate-limit, 503 config, 500 other).\n */\nexport class PraxisApiError extends Error {\n readonly status: number;\n /** The backend error class name, e.g. \"PraxisAuthError\", \"PraxisRateLimitError\". */\n readonly type: string;\n\n constructor(status: number, type: string, message: string) {\n super(message);\n this.name = \"PraxisApiError\";\n this.status = status;\n this.type = type;\n // Restore prototype chain for instanceof across transpile targets.\n Object.setPrototypeOf(this, PraxisApiError.prototype);\n }\n\n get isAuth(): boolean {\n return this.status === 401;\n }\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n get isInput(): boolean {\n return this.status === 400;\n }\n}\n\n/** Thrown for SDK-side misconfiguration (no fetch, no signer, bad key, …). */\nexport class PraxisConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PraxisConfigError\";\n Object.setPrototypeOf(this, PraxisConfigError.prototype);\n }\n}\n","import bs58 from \"bs58\";\n\nimport { PraxisApiError, PraxisConfigError } from \"./errors\";\nimport type { PraxisSigner } from \"./signer\";\nimport type {\n ActionProposal,\n ActivityEntry,\n AddressBookEntry,\n AgentMessage,\n AllowListKind,\n BaseUnitString,\n OwnerAction,\n PolicyUpdate,\n PolicyView,\n SessionInfo,\n Thread,\n TokenEnvelopeConfig,\n UnsignedOwnerTransaction,\n WalletChallenge,\n} from \"./types\";\n\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;\n\nexport interface PraxisClientOptions {\n /** Base origin of the Praxis deployment, e.g. \"http://localhost:3000\". */\n baseUrl: string;\n /** Wallet signer for `connect()`. Optional if you only call public reads after an external login. */\n signer?: PraxisSigner;\n /** Custom fetch (defaults to global fetch). Required in runtimes without one. */\n fetch?: FetchLike;\n /** Per-request timeout in ms (default 20_000). */\n timeoutMs?: number;\n}\n\n/** Result of {@link PraxisClient.ask} — the agent's reply, distilled. */\nexport interface AskResult {\n threadId: string;\n /** The agent's reply message (prose / clarify / proposal / research blocks). */\n message: AgentMessage;\n /** Any action proposals the agent produced, hydrated for convenience. */\n proposals: ActionProposal[];\n}\n\nconst API_PREFIX = \"/api/praxis\";\n\n/**\n * Typed client for a hosted Praxis agent. The agent's LLM, scoped agent key, and\n * Aegis policy enforcement all live server-side; this SDK is an authenticated\n * client of the `/api/praxis/*` surface.\n *\n * ```ts\n * const praxis = new PraxisClient({ baseUrl, signer: keypairSigner(secret) });\n * await praxis.connect();\n * const { proposals } = await praxis.ask(\"send 0.5 SOL to maya\");\n * if (proposals[0]?.check.allowed) await praxis.signProposal(proposals[0].id);\n * ```\n */\nexport class PraxisClient {\n private readonly baseUrl: string;\n private readonly signer?: PraxisSigner;\n private readonly fetchImpl: FetchLike;\n private readonly timeoutMs: number;\n /** Manual cookie jar — Node's fetch does not persist Set-Cookie across calls. */\n private sessionCookie?: string;\n\n constructor(options: PraxisClientOptions) {\n if (!options.baseUrl) throw new PraxisConfigError(\"baseUrl is required\");\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.signer = options.signer;\n const resolvedFetch = options.fetch ?? (globalThis.fetch as FetchLike | undefined);\n if (!resolvedFetch) {\n throw new PraxisConfigError(\"No fetch available; pass options.fetch (Node <18 or non-browser runtime).\");\n }\n this.fetchImpl = resolvedFetch;\n this.timeoutMs = options.timeoutMs ?? 20_000;\n }\n\n // --- auth ----------------------------------------------------------------\n\n /** The signer's wallet address, if a signer was provided. */\n get address(): string | undefined {\n return this.signer?.address;\n }\n\n /**\n * Run the wallet-ownership handshake: request a challenge, sign its message,\n * verify it, and store the resulting session cookie. Idempotent.\n */\n async connect(): Promise<SessionInfo> {\n if (!this.signer) {\n throw new PraxisConfigError(\"connect() requires a signer. Pass one to the constructor.\");\n }\n const challenge = await this.post<WalletChallenge>(\"/auth/challenge\", {\n address: this.signer.address,\n });\n const signature = await this.signer.signMessage(new TextEncoder().encode(challenge.message));\n return this.post<SessionInfo>(\"/auth/verify\", {\n address: this.signer.address,\n nonce: challenge.nonce,\n signature: bs58.encode(signature),\n });\n }\n\n /** Current session, or `null` if not signed in. */\n async session(): Promise<SessionInfo | null> {\n try {\n return await this.get<SessionInfo>(\"/auth/session\");\n } catch (error) {\n if (error instanceof PraxisApiError && error.isAuth) return null;\n throw error;\n }\n }\n\n /** Clear the session (server-side cookie + local jar). */\n async logout(): Promise<void> {\n await this.request<unknown>(\"DELETE\", \"/auth/session\");\n this.sessionCookie = undefined;\n }\n\n // --- conversation --------------------------------------------------------\n\n /** Send a line to the agent. Creates a thread when `threadId` is omitted. */\n send(text: string, threadId: string | null = null): Promise<{ threadId: string }> {\n return this.post<{ threadId: string }>(\"/send\", { text, threadId });\n }\n\n /**\n * Send a line and return the agent's reply in one call. The API resolves\n * `send` only after the agent has finished, so this needs no polling.\n */\n async ask(text: string, threadId: string | null = null): Promise<AskResult> {\n const { threadId: tid } = await this.send(text, threadId);\n const thread = await this.getThread(tid);\n const message = lastAgentMessage(thread);\n if (!message) {\n throw new PraxisApiError(500, \"Error\", \"Agent produced no reply message.\");\n }\n const proposalIds = message.blocks\n .filter((b): b is Extract<typeof b, { type: \"proposal\" }> => b.type === \"proposal\")\n .map((b) => b.proposalId);\n const proposals = await Promise.all(proposalIds.map((id) => this.getProposal(id)));\n return { threadId: tid, message, proposals };\n }\n\n newThread(threadId?: string): Promise<{ threadId: string }> {\n return this.post<{ threadId: string }>(\"/new-thread\", threadId ? { threadId } : {});\n }\n\n signProposal(proposalId: string): Promise<void> {\n return this.post<void>(\"/sign-proposal\", { proposalId });\n }\n\n cancelProposal(proposalId: string): Promise<void> {\n return this.post<void>(\"/cancel-proposal\", { proposalId });\n }\n\n // --- reads ---------------------------------------------------------------\n\n getThreads(): Promise<Thread[]> {\n return this.get<Thread[]>(\"/get-threads\");\n }\n getThread(id: string): Promise<Thread> {\n return this.get<Thread>(\"/get-thread\", { id });\n }\n getProposal(id: string): Promise<ActionProposal> {\n return this.get<ActionProposal>(\"/get-proposal\", { id });\n }\n getPolicy(): Promise<PolicyView> {\n return this.get<PolicyView>(\"/get-policy\");\n }\n getActivity(): Promise<ActivityEntry[]> {\n return this.get<ActivityEntry[]>(\"/get-activity\");\n }\n getAddressBook(): Promise<AddressBookEntry[]> {\n return this.get<AddressBookEntry[]>(\"/get-address-book\");\n }\n isThinking(threadId: string): Promise<boolean> {\n return this.get<boolean>(\"/is-thinking\", { threadId });\n }\n getVersion(): Promise<number> {\n return this.get<number>(\"/get-version\");\n }\n\n // --- policy / owner mutations (server-key mode) --------------------------\n\n bootstrapPolicy(fundLamports?: BaseUnitString): Promise<void> {\n return this.post<void>(\"/bootstrap-policy\", fundLamports ? { fundLamports } : {});\n }\n updatePolicy(patch: PolicyUpdate): Promise<void> {\n return this.post<void>(\"/update-policy\", { patch });\n }\n configureToken(config: TokenEnvelopeConfig): Promise<void> {\n return this.post<void>(\"/configure-token\", { config });\n }\n prepareTokenAccounts(recipientAddresses?: string[]): Promise<void> {\n return this.post<void>(\"/prepare-token-accounts\", recipientAddresses ? { recipientAddresses } : {});\n }\n revokeAgent(): Promise<void> {\n return this.post<void>(\"/revoke-agent\", {});\n }\n rotateAgent(): Promise<void> {\n return this.post<void>(\"/rotate-agent\", {});\n }\n addToAllowList(kind: AllowListKind, address: string): Promise<void> {\n return this.post<void>(\"/add-to-allow-list\", { kind, address });\n }\n removeFromAllowList(kind: AllowListKind, address: string): Promise<void> {\n return this.post<void>(\"/remove-from-allow-list\", { kind, address });\n }\n\n // --- owner wallet-signed transaction path --------------------------------\n\n /** Build an unsigned owner transaction for the wallet to sign. */\n buildOwnerTransaction(action: OwnerAction): Promise<UnsignedOwnerTransaction> {\n return this.post<UnsignedOwnerTransaction>(\"/owner/build\", { action });\n }\n /** Submit a wallet-signed owner transaction. */\n submitOwnerTransaction(signed: UnsignedOwnerTransaction): Promise<{ sig: string }> {\n return this.post<{ sig: string }>(\"/owner/submit\", signed);\n }\n\n // --- transport -----------------------------------------------------------\n\n private get<T>(path: string, query?: Record<string, string>): Promise<T> {\n return this.request<T>(\"GET\", path, { query });\n }\n\n private post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, { body });\n }\n\n private async request<T>(\n method: string,\n path: string,\n opts: { body?: unknown; query?: Record<string, string> } = {},\n ): Promise<T> {\n const url = new URL(this.baseUrl + API_PREFIX + path);\n for (const [k, v] of Object.entries(opts.query ?? {})) url.searchParams.set(k, v);\n\n const headers: Record<string, string> = { accept: \"application/json\" };\n if (opts.body !== undefined) headers[\"content-type\"] = \"application/json\";\n if (this.sessionCookie) headers[\"cookie\"] = this.sessionCookie;\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n let res: Response;\n try {\n res = await this.fetchImpl(url.toString(), {\n method,\n headers,\n body: opts.body === undefined ? undefined : JSON.stringify(opts.body),\n // Browser same-origin: let the HttpOnly cookie ride along.\n credentials: \"include\",\n signal: controller.signal,\n } as RequestInit);\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new PraxisApiError(0, \"TimeoutError\", `Praxis request timed out after ${this.timeoutMs}ms`);\n }\n throw error;\n } finally {\n clearTimeout(timer);\n }\n\n this.captureCookie(res);\n\n const text = await res.text();\n const parsed = text ? safeJsonParse(text) : undefined;\n\n if (!res.ok) {\n const message =\n (parsed && typeof parsed === \"object\" && \"error\" in parsed && typeof parsed.error === \"string\"\n ? parsed.error\n : undefined) ?? `Praxis API error ${res.status}`;\n const type =\n parsed && typeof parsed === \"object\" && \"type\" in parsed && typeof parsed.type === \"string\"\n ? parsed.type\n : \"Error\";\n throw new PraxisApiError(res.status, type, message);\n }\n\n return parsed as T;\n }\n\n private captureCookie(res: Response): void {\n // Node 18.14+ exposes getSetCookie(); fall back to the combined header.\n const anyHeaders = res.headers as Headers & { getSetCookie?: () => string[] };\n const cookies = anyHeaders.getSetCookie?.() ?? splitSetCookie(res.headers.get(\"set-cookie\"));\n for (const cookie of cookies) {\n const [pair] = cookie.split(\";\");\n if (pair && pair.trim().startsWith(\"praxis_session=\")) {\n this.sessionCookie = pair.trim();\n }\n }\n }\n}\n\nfunction lastAgentMessage(thread: Thread): AgentMessage | undefined {\n for (let i = thread.messages.length - 1; i >= 0; i--) {\n const m = thread.messages[i];\n if (m.role === \"agent\") return m;\n }\n return undefined;\n}\n\nfunction safeJsonParse(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction splitSetCookie(header: string | null): string[] {\n if (!header) return [];\n // Split on commas that precede a new cookie name=value pair, not commas inside\n // Expires dates (\"Wed, 01 Jan ...\").\n return header.split(/,(?=\\s*[^;,\\s]+=)/);\n}\n","import bs58 from \"bs58\";\nimport nacl from \"tweetnacl\";\n\nimport { PraxisConfigError } from \"./errors\";\n\n/**\n * Signs the wallet-ownership challenge. Implement this to bridge any wallet:\n * - Node / backend agents: use {@link keypairSigner} with a secret key.\n * - Browser: wrap a wallet-adapter, e.g.\n * `{ address: wallet.publicKey.toBase58(), signMessage: (m) => wallet.signMessage(m) }`.\n *\n * `signMessage` must return the raw 64-byte Ed25519 signature; the SDK base58-\n * encodes it for the API.\n */\nexport interface PraxisSigner {\n /** base58-encoded Solana public key. */\n readonly address: string;\n signMessage(message: Uint8Array): Promise<Uint8Array> | Uint8Array;\n}\n\nexport type SecretKeyInput = Uint8Array | number[] | string;\n\n/**\n * Build a {@link PraxisSigner} from a Solana secret key — a 64-byte keypair or a\n * 32-byte seed, as raw bytes, a number array, or a base58 string (Phantom /\n * `solana-keygen` export). Node and browser friendly; no `@solana/web3.js`\n * dependency.\n */\nexport function keypairSigner(secret: SecretKeyInput): PraxisSigner {\n const bytes = normalizeSecret(secret);\n const pair =\n bytes.length === 64\n ? nacl.sign.keyPair.fromSecretKey(bytes)\n : nacl.sign.keyPair.fromSeed(bytes);\n const address = bs58.encode(pair.publicKey);\n const secretKey = pair.secretKey;\n\n return {\n address,\n signMessage: (message: Uint8Array) => nacl.sign.detached(message, secretKey),\n };\n}\n\nfunction normalizeSecret(secret: SecretKeyInput): Uint8Array {\n let bytes: Uint8Array;\n if (typeof secret === \"string\") {\n try {\n bytes = bs58.decode(secret.trim());\n } catch {\n throw new PraxisConfigError(\"secret key string must be base58-encoded\");\n }\n } else if (Array.isArray(secret)) {\n bytes = Uint8Array.from(secret);\n } else {\n bytes = secret;\n }\n\n if (bytes.length !== 64 && bytes.length !== 32) {\n throw new PraxisConfigError(\n `secret key must be 64 bytes (keypair) or 32 bytes (seed), got ${bytes.length}`,\n );\n }\n return bytes;\n}\n","/**\n * Money helpers. Praxis money crosses the wire as decimal strings of integer\n * base units (lamports / token base units). These convert to/from `bigint` and\n * human decimal amounts without floats.\n */\n\n/** Parse a base-unit string (or bigint) into a bigint. */\nexport function toBaseUnits(value: string | bigint): bigint {\n return typeof value === \"bigint\" ? value : BigInt(value.trim());\n}\n\n/** Serialize a bigint (or number of whole base units) into a base-unit string. */\nexport function fromBaseUnits(value: bigint | number): string {\n return BigInt(value).toString();\n}\n\n/** Convert a human decimal amount (\"0.5\") into base units for `decimals` places. */\nexport function humanToBaseUnits(amount: string, decimals: number): string {\n const trimmed = amount.trim();\n if (!/^\\d+(\\.\\d+)?$/.test(trimmed)) {\n throw new Error(`invalid decimal amount: \"${amount}\"`);\n }\n const [whole, fraction = \"\"] = trimmed.split(\".\");\n if (fraction.length > decimals) {\n throw new Error(`\"${amount}\" has more than ${decimals} decimal places`);\n }\n const padded = fraction.padEnd(decimals, \"0\");\n return (BigInt(whole) * 10n ** BigInt(decimals) + BigInt(padded || \"0\")).toString();\n}\n\n/** Convert base units into a human decimal string for `decimals` places. */\nexport function baseUnitsToHuman(value: string | bigint, decimals: number): string {\n const units = toBaseUnits(value);\n const negative = units < 0n;\n const abs = negative ? -units : units;\n const divisor = 10n ** BigInt(decimals);\n const whole = abs / divisor;\n const fraction = (abs % divisor).toString().padStart(decimals, \"0\").replace(/0+$/, \"\");\n const sign = negative ? \"-\" : \"\";\n return fraction ? `${sign}${whole}.${fraction}` : `${sign}${whole}`;\n}\n","/**\n * Praxis SDK wire types — the JSON contract exposed by `/api/praxis/*`.\n *\n * MONEY RULE: every monetary value crosses the wire as a **decimal string of\n * integer base units** (lamports for SOL, token base units for SPL) — never a\n * float. On the server these are `bigint`; the API serializes them to strings.\n * The SDK keeps them as strings and leaves bigint conversion to the caller\n * (see `toBaseUnits` / `fromBaseUnits` in `units.ts`). This file intentionally\n * mirrors `@praxis/shared` but with `string` money, so the SDK ships a\n * self-contained type contract with no internal workspace dependency.\n */\n\n/** A base58-encoded Solana public key. */\nexport type Address = string;\n\n/** Integer base units as a decimal string (e.g. \"500000000\" = 0.5 SOL). */\nexport type BaseUnitString = string;\n\n/** Mirrors the on-chain `ActionKind` discriminants. */\nexport enum ActionKind {\n Transfer = 0,\n TransferSpl = 1,\n}\n\n/** Why Aegis rejected an agent action. Mirrors the on-chain enum order. */\nexport enum RejectReason {\n Unauthorized = 0,\n Paused = 1,\n Expired = 2,\n OverPerTx = 3,\n OverDaily = 4,\n RecipientNotAllowed = 5,\n Overflow = 6,\n MintNotAllowed = 7,\n}\n\n// --- Auth ------------------------------------------------------------------\n\n/** Returned by `POST /auth/challenge`; sign `message` to prove wallet ownership. */\nexport interface WalletChallenge {\n address: Address;\n /** Opaque signed token echoed back to `/auth/verify`. */\n nonce: string;\n /** The exact UTF-8 string the wallet must sign. */\n message: string;\n /** ISO-8601 expiry of the challenge. */\n expiresAt: string;\n}\n\nexport interface SessionInfo {\n authenticated: boolean;\n walletAddress: Address;\n}\n\n// --- Tokens / address book -------------------------------------------------\n\nexport interface TokenInfo {\n symbol: string;\n mint: Address;\n decimals: number;\n verified: boolean;\n}\n\nexport interface AddressBookEntry {\n label: string;\n name: string;\n address: Address;\n note?: string;\n}\n\n// --- Policy ----------------------------------------------------------------\n\nexport interface PolicyView {\n address: Address;\n owner: Address;\n /** `11111…1111` (default) once the agent key is revoked. */\n agentAuthority: Address;\n maxPerTx: BaseUnitString;\n dailyLimit: BaseUnitString;\n spentToday: BaseUnitString;\n dayStartTs: number;\n allowedPrograms: Address[];\n /** Empty array means \"any recipient allowed\". */\n allowedRecipients: Address[];\n allowedMints: Address[];\n expiryTs: number;\n paused: boolean;\n vaultBalance: BaseUnitString;\n tokenMint: Address;\n tokenMaxPerTx: BaseUnitString;\n tokenDailyLimit: BaseUnitString;\n tokenSpentToday: BaseUnitString;\n tokenDayStartTs: number;\n}\n\nexport interface PolicyCheckResult {\n allowed: boolean;\n reason?: string;\n reasonCode?: RejectReason;\n spentToday: BaseUnitString;\n dailyLimit: BaseUnitString;\n remaining: BaseUnitString;\n}\n\nexport interface PolicyUpdate {\n maxPerTx?: BaseUnitString;\n dailyLimit?: BaseUnitString;\n expiryTs?: number;\n paused?: boolean;\n}\n\nexport interface TokenEnvelopeConfig {\n tokenMint: Address;\n tokenMaxPerTx: BaseUnitString;\n tokenDailyLimit: BaseUnitString;\n}\n\nexport type AllowListKind = \"programs\" | \"recipients\" | \"mints\";\n\n// --- Proposals -------------------------------------------------------------\n\nexport interface TransferDetail {\n kind: \"transfer\";\n amount: BaseUnitString;\n asset: TokenInfo;\n recipientName: string;\n recipientAddress: Address;\n recipientNote?: string;\n}\n\nexport interface SwapDetail {\n kind: \"swap\";\n amountIn: BaseUnitString;\n assetIn: TokenInfo;\n estAmountOut: BaseUnitString;\n assetOut: TokenInfo;\n route: string;\n priceImpactBps: number;\n}\n\nexport type ProposalDetail = TransferDetail | SwapDetail;\n\nexport type ProposalState = \"pending\" | \"signing\" | \"signed\" | \"blocked\" | \"cancelled\";\n\nexport interface ActionProposal {\n id: string;\n detail: ProposalDetail;\n networkFee: BaseUnitString;\n simulation: string;\n check: PolicyCheckResult;\n state: ProposalState;\n sig?: string;\n}\n\n// --- Conversation ----------------------------------------------------------\n\nexport interface ClarifyOption {\n label: string;\n value: string;\n hint?: string;\n}\n\nexport interface ResearchMetric {\n label: string;\n value: string;\n trend?: \"up\" | \"down\" | \"flat\";\n}\n\nexport interface ResearchData {\n token: string;\n mint: Address;\n metrics: ResearchMetric[];\n summary: string;\n}\n\nexport type AgentBlock =\n | { type: \"prose\"; text: string }\n | { type: \"clarify\"; text: string; options: ClarifyOption[] }\n | { type: \"proposal\"; text: string; proposalId: string }\n | { type: \"research\"; text: string; data: ResearchData };\n\nexport type UserMessage = { id: string; role: \"user\"; ts: number; text: string };\nexport type AgentMessage = { id: string; role: \"agent\"; ts: number; blocks: AgentBlock[] };\nexport type Message = UserMessage | AgentMessage;\n\nexport interface Thread {\n id: string;\n title: string;\n messages: Message[];\n updatedAt: number;\n}\n\n// --- Activity --------------------------------------------------------------\n\nexport interface ActivityEntry {\n id: string;\n kind: \"transfer\" | \"swap\";\n label: string;\n asset: string;\n amount: BaseUnitString;\n decimals: number;\n result: \"allowed\" | \"rejected\";\n reason?: string;\n reasonCode?: RejectReason;\n ts: number;\n sig?: string;\n}\n\n// --- Owner transactions (wallet-signed path) -------------------------------\n\nexport interface UnsignedOwnerTransaction {\n /** base64-encoded unsigned transaction for the owner wallet to sign. */\n transaction: string;\n blockhash: string;\n lastValidBlockHeight: number;\n}\n\n/** Typed owner action accepted by `POST /owner/build`. */\nexport type OwnerAction =\n | { kind: \"bootstrapPolicy\"; fundLamports?: BaseUnitString }\n | { kind: \"fundVault\"; amount: BaseUnitString }\n | { kind: \"withdrawVault\"; amount: BaseUnitString }\n | { kind: \"closePolicy\" }\n | { kind: \"revoke\" }\n | { kind: \"rotate\" }\n | { kind: \"updatePolicy\"; patch: PolicyUpdate }\n | { kind: \"allowList\"; listKind: AllowListKind; address: Address; mode: \"add\" | \"remove\" };\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/signer.ts","../src/units.ts","../src/types.ts"],"names":["bs58","nacl","ActionKind","RejectReason"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Thrown when the Praxis API returns a non-2xx response. The backend's error\n * envelope is `{ error: string, type: string }` with a meaningful HTTP status\n * (400 input, 401 auth, 404 not-found, 429 rate-limit, 503 config, 500 other).\n */\nexport class PraxisApiError extends Error {\n readonly status: number;\n /** The backend error class name, e.g. \"PraxisAuthError\", \"PraxisRateLimitError\". */\n readonly type: string;\n\n constructor(status: number, type: string, message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = \"PraxisApiError\";\n this.status = status;\n this.type = type;\n // Restore prototype chain for instanceof across transpile targets.\n Object.setPrototypeOf(this, PraxisApiError.prototype);\n }\n\n get isAuth(): boolean {\n return this.status === 401;\n }\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n get isInput(): boolean {\n return this.status === 400;\n }\n /** Resource not found (404). */\n get isNotFound(): boolean {\n return this.status === 404;\n }\n /** Server reported a configuration problem (503) — usually transient. */\n get isConfig(): boolean {\n return this.status === 503;\n }\n /** The request timed out client-side before any HTTP response. */\n get isTimeout(): boolean {\n return this.status === 0 && this.type === \"TimeoutError\";\n }\n /** A connection-level failure (DNS, refused, TLS) before any HTTP response. */\n get isNetwork(): boolean {\n return this.status === 0 && this.type === \"NetworkError\";\n }\n /** Any server-side failure (HTTP >= 500). */\n get isServer(): boolean {\n return this.status >= 500;\n }\n}\n\n/** Thrown for SDK-side misconfiguration (no fetch, no signer, bad key, …). */\nexport class PraxisConfigError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = \"PraxisConfigError\";\n Object.setPrototypeOf(this, PraxisConfigError.prototype);\n }\n}\n","import bs58 from \"bs58\";\n\nimport { PraxisApiError, PraxisConfigError } from \"./errors\";\nimport type { PraxisSigner } from \"./signer\";\nimport type {\n ActionProposal,\n ActivityEntry,\n AddressBookEntry,\n AgentMessage,\n AllowListKind,\n BaseUnitString,\n OwnerAction,\n PolicyUpdate,\n PolicyView,\n SessionInfo,\n SignedOwnerTransaction,\n Thread,\n TokenEnvelopeConfig,\n UnsignedOwnerTransaction,\n WalletChallenge,\n} from \"./types\";\n\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;\n\nexport interface PraxisClientOptions {\n /** Base origin of the Praxis deployment, e.g. \"http://localhost:3000\". */\n baseUrl: string;\n /** Wallet signer for `connect()`. Optional if you only call public reads after an external login. */\n signer?: PraxisSigner;\n /** Custom fetch (defaults to global fetch). Required in runtimes without one. */\n fetch?: FetchLike;\n /** Per-request timeout in ms for reads/mutations (default 20_000). */\n timeoutMs?: number;\n /**\n * Per-request timeout in ms for agent conversation turns (`send`/`ask`), which\n * block on the full LLM round-trip (default 60_000). Effective value is never\n * below `timeoutMs`.\n */\n agentTimeoutMs?: number;\n}\n\n/** Result of {@link PraxisClient.ask} — the agent's reply, distilled. */\nexport interface AskResult {\n threadId: string;\n /** The agent's reply message (prose / clarify / proposal / research blocks). */\n message: AgentMessage;\n /** Any action proposals the agent produced, hydrated for convenience. */\n proposals: ActionProposal[];\n}\n\nconst API_PREFIX = \"/api/praxis\";\n\n/**\n * Typed client for a hosted Praxis agent. The agent's LLM, scoped agent key, and\n * Aegis policy enforcement all live server-side; this SDK is an authenticated\n * client of the `/api/praxis/*` surface.\n *\n * ```ts\n * const praxis = new PraxisClient({ baseUrl, signer: keypairSigner(secret) });\n * await praxis.connect();\n * const { proposals } = await praxis.ask(\"send 0.5 SOL to maya\");\n * if (proposals[0]?.check.allowed) await praxis.signProposal(proposals[0].id);\n * ```\n */\nexport class PraxisClient {\n private readonly baseUrl: string;\n private readonly signer?: PraxisSigner;\n private readonly fetchImpl: FetchLike;\n private readonly timeoutMs: number;\n private readonly agentTimeoutMs: number;\n /** Manual cookie jar — Node's fetch does not persist Set-Cookie across calls. */\n private sessionCookie?: string;\n\n constructor(options: PraxisClientOptions) {\n if (!options.baseUrl) throw new PraxisConfigError(\"baseUrl is required\");\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.signer = options.signer;\n const resolvedFetch = options.fetch ?? (globalThis.fetch as FetchLike | undefined);\n if (!resolvedFetch) {\n throw new PraxisConfigError(\"No fetch available; pass options.fetch (Node <18 or non-browser runtime).\");\n }\n this.fetchImpl = resolvedFetch;\n this.timeoutMs = options.timeoutMs ?? 20_000;\n this.agentTimeoutMs = Math.max(options.agentTimeoutMs ?? 60_000, this.timeoutMs);\n }\n\n // --- auth ----------------------------------------------------------------\n\n /** The signer's wallet address, if a signer was provided. */\n get address(): string | undefined {\n return this.signer?.address;\n }\n\n /**\n * Run the wallet-ownership handshake: request a challenge, sign its message,\n * verify it, and store the resulting session cookie. Safe to call again to\n * refresh the session (each call issues a new challenge + cookie).\n */\n async connect(): Promise<SessionInfo> {\n if (!this.signer) {\n throw new PraxisConfigError(\"connect() requires a signer. Pass one to the constructor.\");\n }\n const challenge = await this.post<WalletChallenge>(\"/auth/challenge\", {\n address: this.signer.address,\n });\n const signature = await this.signer.signMessage(new TextEncoder().encode(challenge.message));\n return this.post<SessionInfo>(\"/auth/verify\", {\n address: this.signer.address,\n nonce: challenge.nonce,\n signature: bs58.encode(signature),\n });\n }\n\n /**\n * Current session, or `null` if not signed in. The endpoint answers `200`\n * with `{ authenticated: false }` when signed out, so this normalizes both\n * that shape and a `401` to `null`.\n */\n async session(): Promise<SessionInfo | null> {\n try {\n const info = await this.get<SessionInfo>(\"/auth/session\");\n return info && info.authenticated ? info : null;\n } catch (error) {\n if (error instanceof PraxisApiError && error.isAuth) return null;\n throw error;\n }\n }\n\n /**\n * Clear the session (server-side cookie + local jar). Idempotent: if there is\n * no active session, the local jar is still cleared and no error is thrown.\n */\n async logout(): Promise<void> {\n try {\n await this.request<unknown>(\"DELETE\", \"/auth/session\");\n } catch (error) {\n // Already signed out (missing / expired session) is a successful logout.\n if (!(error instanceof PraxisApiError && error.isAuth)) throw error;\n } finally {\n this.sessionCookie = undefined;\n }\n }\n\n // --- conversation --------------------------------------------------------\n\n /** Send a line to the agent. Creates a thread when `threadId` is omitted. */\n send(text: string, threadId: string | null = null): Promise<{ threadId: string }> {\n // Conversation turns block on the agent's LLM round-trip — give them the\n // longer agent budget rather than the shorter read/mutation timeout.\n return this.post<{ threadId: string }>(\"/send\", { text, threadId }, this.agentTimeoutMs);\n }\n\n /**\n * Send a line and return the agent's reply in one call. The API resolves\n * `send` only after the agent has finished, so this needs no polling.\n */\n async ask(text: string, threadId: string | null = null): Promise<AskResult> {\n const { threadId: tid } = await this.send(text, threadId);\n const thread = await this.getThread(tid);\n const message = lastAgentMessage(thread);\n if (!message) {\n throw new PraxisApiError(500, \"Error\", \"Agent produced no reply message.\");\n }\n const proposalIds = message.blocks\n .filter((b): b is Extract<typeof b, { type: \"proposal\" }> => b.type === \"proposal\")\n .map((b) => b.proposalId);\n const proposals = await Promise.all(proposalIds.map((id) => this.getProposal(id)));\n return { threadId: tid, message, proposals };\n }\n\n newThread(threadId?: string): Promise<{ threadId: string }> {\n return this.post<{ threadId: string }>(\"/new-thread\", threadId ? { threadId } : {});\n }\n\n signProposal(proposalId: string): Promise<void> {\n return this.post<void>(\"/sign-proposal\", { proposalId });\n }\n\n cancelProposal(proposalId: string): Promise<void> {\n return this.post<void>(\"/cancel-proposal\", { proposalId });\n }\n\n // --- reads ---------------------------------------------------------------\n\n getThreads(): Promise<Thread[]> {\n return this.get<Thread[]>(\"/get-threads\");\n }\n getThread(id: string): Promise<Thread> {\n return this.get<Thread>(\"/get-thread\", { id });\n }\n getProposal(id: string): Promise<ActionProposal> {\n return this.get<ActionProposal>(\"/get-proposal\", { id });\n }\n getPolicy(): Promise<PolicyView> {\n return this.get<PolicyView>(\"/get-policy\");\n }\n getActivity(): Promise<ActivityEntry[]> {\n return this.get<ActivityEntry[]>(\"/get-activity\");\n }\n getAddressBook(): Promise<AddressBookEntry[]> {\n return this.get<AddressBookEntry[]>(\"/get-address-book\");\n }\n isThinking(threadId: string): Promise<boolean> {\n return this.get<boolean>(\"/is-thinking\", { threadId });\n }\n getVersion(): Promise<number> {\n return this.get<number>(\"/get-version\");\n }\n\n // --- policy / owner mutations (server-key mode) --------------------------\n\n bootstrapPolicy(fundLamports?: BaseUnitString): Promise<void> {\n return this.post<void>(\"/bootstrap-policy\", fundLamports ? { fundLamports } : {});\n }\n /** Deposit SOL (lamports, base-unit string) from the owner into the vault. */\n fundVault(amount: BaseUnitString): Promise<void> {\n return this.post<void>(\"/fund-vault\", { amount });\n }\n /** Withdraw SOL (lamports, base-unit string) from the vault to the owner. */\n withdrawVault(amount: BaseUnitString): Promise<void> {\n return this.post<void>(\"/withdraw-vault\", { amount });\n }\n /** Tear the agent down — drain the vault and close the policy. Irreversible. */\n deleteAgent(): Promise<void> {\n return this.post<void>(\"/delete-agent\", {});\n }\n updatePolicy(patch: PolicyUpdate): Promise<void> {\n return this.post<void>(\"/update-policy\", { patch });\n }\n configureToken(config: TokenEnvelopeConfig): Promise<void> {\n return this.post<void>(\"/configure-token\", { config });\n }\n prepareTokenAccounts(recipientAddresses?: string[]): Promise<void> {\n return this.post<void>(\"/prepare-token-accounts\", recipientAddresses ? { recipientAddresses } : {});\n }\n revokeAgent(): Promise<void> {\n return this.post<void>(\"/revoke-agent\", {});\n }\n rotateAgent(): Promise<void> {\n return this.post<void>(\"/rotate-agent\", {});\n }\n addToAllowList(kind: AllowListKind, address: string): Promise<void> {\n return this.post<void>(\"/add-to-allow-list\", { kind, address });\n }\n removeFromAllowList(kind: AllowListKind, address: string): Promise<void> {\n return this.post<void>(\"/remove-from-allow-list\", { kind, address });\n }\n\n // --- owner wallet-signed transaction path --------------------------------\n\n /**\n * Build an unsigned owner transaction for the wallet to sign. The caller signs\n * the returned base64 `transaction` with a transaction-capable wallet, then\n * passes the result to {@link submitOwnerTransaction}. (The SDK's\n * `keypairSigner` signs sign-in messages only, not transactions.)\n */\n buildOwnerTransaction(action: OwnerAction): Promise<UnsignedOwnerTransaction> {\n return this.post<UnsignedOwnerTransaction>(\"/owner/build\", { action });\n }\n /** Submit a wallet-signed owner transaction; resolves with its signature. */\n submitOwnerTransaction(signed: SignedOwnerTransaction): Promise<{ sig: string }> {\n return this.post<{ sig: string }>(\"/owner/submit\", signed);\n }\n\n // --- transport -----------------------------------------------------------\n\n private get<T>(path: string, query?: Record<string, string>): Promise<T> {\n return this.request<T>(\"GET\", path, { query });\n }\n\n private post<T>(path: string, body: unknown, timeoutMs?: number): Promise<T> {\n return this.request<T>(\"POST\", path, { body, timeoutMs });\n }\n\n private async request<T>(\n method: string,\n path: string,\n opts: { body?: unknown; query?: Record<string, string>; timeoutMs?: number } = {},\n ): Promise<T> {\n const url = new URL(this.baseUrl + API_PREFIX + path);\n for (const [k, v] of Object.entries(opts.query ?? {})) url.searchParams.set(k, v);\n\n const headers: Record<string, string> = { accept: \"application/json\" };\n if (opts.body !== undefined) headers[\"content-type\"] = \"application/json\";\n if (this.sessionCookie) headers[\"cookie\"] = this.sessionCookie;\n\n const timeoutMs = opts.timeoutMs ?? this.timeoutMs;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n let res: Response;\n try {\n res = await this.fetchImpl(url.toString(), {\n method,\n headers,\n body: opts.body === undefined ? undefined : JSON.stringify(opts.body),\n // Browser same-origin: let the HttpOnly cookie ride along.\n credentials: \"include\",\n signal: controller.signal,\n } as RequestInit);\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new PraxisApiError(0, \"TimeoutError\", `Praxis request timed out after ${timeoutMs}ms`, {\n cause: error,\n });\n }\n if (error instanceof PraxisApiError) throw error;\n // Connection-level failures (DNS, ECONNREFUSED, TLS) surface uniformly as\n // a PraxisApiError so callers have a single error type to catch.\n const detail = error instanceof Error ? error.message : String(error);\n throw new PraxisApiError(0, \"NetworkError\", `Praxis request failed: ${detail}`, { cause: error });\n } finally {\n clearTimeout(timer);\n }\n\n this.captureCookie(res);\n\n const text = await res.text();\n const parsed = text ? safeJsonParse(text) : undefined;\n\n if (!res.ok) {\n const message =\n (parsed && typeof parsed === \"object\" && \"error\" in parsed && typeof parsed.error === \"string\"\n ? parsed.error\n : undefined) ?? `Praxis API error ${res.status}`;\n const type =\n parsed && typeof parsed === \"object\" && \"type\" in parsed && typeof parsed.type === \"string\"\n ? parsed.type\n : \"Error\";\n throw new PraxisApiError(res.status, type, message);\n }\n\n return parsed as T;\n }\n\n private captureCookie(res: Response): void {\n // Node 18.14+ exposes getSetCookie(); fall back to the combined header.\n const anyHeaders = res.headers as Headers & { getSetCookie?: () => string[] };\n const cookies = anyHeaders.getSetCookie?.() ?? splitSetCookie(res.headers.get(\"set-cookie\"));\n for (const cookie of cookies) {\n const [pair] = cookie.split(\";\");\n if (pair && pair.trim().startsWith(\"praxis_session=\")) {\n this.sessionCookie = pair.trim();\n }\n }\n }\n}\n\nfunction lastAgentMessage(thread: Thread): AgentMessage | undefined {\n for (let i = thread.messages.length - 1; i >= 0; i--) {\n const m = thread.messages[i];\n if (m.role === \"agent\") return m;\n }\n return undefined;\n}\n\nfunction safeJsonParse(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction splitSetCookie(header: string | null): string[] {\n if (!header) return [];\n // Split on commas that precede a new cookie name=value pair, not commas inside\n // Expires dates (\"Wed, 01 Jan ...\").\n return header.split(/,(?=\\s*[^;,\\s]+=)/);\n}\n","import bs58 from \"bs58\";\nimport nacl from \"tweetnacl\";\n\nimport { PraxisConfigError } from \"./errors\";\n\n/**\n * Signs the wallet-ownership challenge. Implement this to bridge any wallet:\n * - Node / backend agents: use {@link keypairSigner} with a secret key.\n * - Browser: wrap a wallet-adapter, e.g.\n * `{ address: wallet.publicKey.toBase58(), signMessage: (m) => wallet.signMessage(m) }`.\n *\n * `signMessage` must return the raw 64-byte Ed25519 signature; the SDK base58-\n * encodes it for the API.\n */\nexport interface PraxisSigner {\n /** base58-encoded Solana public key. */\n readonly address: string;\n signMessage(message: Uint8Array): Promise<Uint8Array> | Uint8Array;\n}\n\nexport type SecretKeyInput = Uint8Array | number[] | string;\n\n/**\n * Build a {@link PraxisSigner} from a Solana secret key — a 64-byte keypair or a\n * 32-byte seed, as raw bytes, a number array, or a base58 string (Phantom /\n * `solana-keygen` export). Node and browser friendly; no `@solana/web3.js`\n * dependency.\n */\nexport function keypairSigner(secret: SecretKeyInput): PraxisSigner {\n const bytes = normalizeSecret(secret);\n const pair =\n bytes.length === 64\n ? nacl.sign.keyPair.fromSecretKey(bytes)\n : nacl.sign.keyPair.fromSeed(bytes);\n const address = bs58.encode(pair.publicKey);\n const secretKey = pair.secretKey;\n\n return {\n address,\n signMessage: (message: Uint8Array) => nacl.sign.detached(message, secretKey),\n };\n}\n\nfunction normalizeSecret(secret: SecretKeyInput): Uint8Array {\n let bytes: Uint8Array;\n if (typeof secret === \"string\") {\n try {\n bytes = bs58.decode(secret.trim());\n } catch {\n throw new PraxisConfigError(\"secret key string must be base58-encoded\");\n }\n } else if (Array.isArray(secret)) {\n if (!secret.every((b) => Number.isInteger(b) && b >= 0 && b <= 255)) {\n throw new PraxisConfigError(\"secret key array must contain only byte values (integers 0–255)\");\n }\n bytes = Uint8Array.from(secret);\n } else {\n bytes = secret;\n }\n\n if (bytes.length !== 64 && bytes.length !== 32) {\n throw new PraxisConfigError(\n `secret key must be 64 bytes (keypair) or 32 bytes (seed), got ${bytes.length}`,\n );\n }\n return bytes;\n}\n","/**\n * Money helpers. Praxis money crosses the wire as decimal strings of integer\n * base units (lamports / token base units). These convert to/from `bigint` and\n * human decimal amounts without floats.\n */\n\n/** An optionally-signed decimal integer — the only valid base-unit string. */\nconst INTEGER_RE = /^-?\\d+$/;\n\n/**\n * Parse a base-unit string (or bigint) into a bigint. Rejects floats, hex, and\n * other non-decimal-integer input so the SDK and server agree on what a valid\n * base-unit string is (mirrors the server's `parseUnits`).\n */\nexport function toBaseUnits(value: string | bigint): bigint {\n if (typeof value === \"bigint\") return value;\n const trimmed = value.trim();\n if (!INTEGER_RE.test(trimmed)) {\n throw new Error(`toBaseUnits: expected an integer base-unit string, got \"${value}\"`);\n }\n return BigInt(trimmed);\n}\n\n/**\n * Serialize a bigint (or a whole, safe-integer number of base units) into a\n * base-unit string. A non-integer or unsafe `number` throws rather than\n * silently losing precision.\n */\nexport function fromBaseUnits(value: bigint | number): string {\n if (typeof value === \"number\" && !Number.isSafeInteger(value)) {\n throw new Error(`fromBaseUnits: number must be a safe integer, got ${value}`);\n }\n return BigInt(value).toString();\n}\n\n/** Convert a human decimal amount (\"0.5\") into base units for `decimals` places. */\nexport function humanToBaseUnits(amount: string, decimals: number): string {\n const trimmed = amount.trim();\n if (!/^\\d+(\\.\\d+)?$/.test(trimmed)) {\n throw new Error(`invalid decimal amount: \"${amount}\"`);\n }\n const [whole, fraction = \"\"] = trimmed.split(\".\");\n if (fraction.length > decimals) {\n throw new Error(`\"${amount}\" has more than ${decimals} decimal places`);\n }\n const padded = fraction.padEnd(decimals, \"0\");\n return (BigInt(whole) * 10n ** BigInt(decimals) + BigInt(padded || \"0\")).toString();\n}\n\n/** Convert base units into a human decimal string for `decimals` places. */\nexport function baseUnitsToHuman(value: string | bigint, decimals: number): string {\n const units = toBaseUnits(value);\n const negative = units < 0n;\n const abs = negative ? -units : units;\n const divisor = 10n ** BigInt(decimals);\n const whole = abs / divisor;\n const fraction = (abs % divisor).toString().padStart(decimals, \"0\").replace(/0+$/, \"\");\n const sign = negative ? \"-\" : \"\";\n return fraction ? `${sign}${whole}.${fraction}` : `${sign}${whole}`;\n}\n","/**\n * Praxis SDK wire types — the JSON contract exposed by `/api/praxis/*`.\n *\n * MONEY RULE: every monetary value crosses the wire as a **decimal string of\n * integer base units** (lamports for SOL, token base units for SPL) — never a\n * float. On the server these are `bigint`; the API serializes them to strings.\n * The SDK keeps them as strings and leaves bigint conversion to the caller\n * (see `toBaseUnits` / `fromBaseUnits` in `units.ts`). This file intentionally\n * mirrors `@praxis/shared` but with `string` money, so the SDK ships a\n * self-contained type contract with no internal workspace dependency.\n */\n\n/** A base58-encoded Solana public key. */\nexport type Address = string;\n\n/** Integer base units as a decimal string (e.g. \"500000000\" = 0.5 SOL). */\nexport type BaseUnitString = string;\n\n/** Mirrors the on-chain `ActionKind` discriminants. */\nexport enum ActionKind {\n Transfer = 0,\n TransferSpl = 1,\n}\n\n/** Why Aegis rejected an agent action. Mirrors the on-chain enum order. */\nexport enum RejectReason {\n Unauthorized = 0,\n Paused = 1,\n Expired = 2,\n OverPerTx = 3,\n OverDaily = 4,\n RecipientNotAllowed = 5,\n Overflow = 6,\n MintNotAllowed = 7,\n}\n\n// --- Auth ------------------------------------------------------------------\n\n/** Returned by `POST /auth/challenge`; sign `message` to prove wallet ownership. */\nexport interface WalletChallenge {\n address: Address;\n /** Opaque signed token echoed back to `/auth/verify`. */\n nonce: string;\n /** The exact UTF-8 string the wallet must sign. */\n message: string;\n /** ISO-8601 expiry of the challenge. */\n expiresAt: string;\n}\n\nexport interface SessionInfo {\n authenticated: boolean;\n /** The signed-in wallet (owner). Present whenever `authenticated` is true. */\n walletAddress: Address;\n /** Unix seconds at which the session expires (from `GET /auth/session`). */\n expiresAt?: number;\n}\n\n// --- Tokens / address book -------------------------------------------------\n\nexport interface TokenInfo {\n symbol: string;\n mint: Address;\n decimals: number;\n verified: boolean;\n}\n\nexport interface AddressBookEntry {\n label: string;\n name: string;\n address: Address;\n note?: string;\n}\n\n// --- Policy ----------------------------------------------------------------\n\nexport interface PolicyView {\n address: Address;\n owner: Address;\n /** `11111…1111` (default) once the agent key is revoked. */\n agentAuthority: Address;\n maxPerTx: BaseUnitString;\n dailyLimit: BaseUnitString;\n spentToday: BaseUnitString;\n dayStartTs: number;\n allowedPrograms: Address[];\n /** Empty array means \"any recipient allowed\". */\n allowedRecipients: Address[];\n allowedMints: Address[];\n expiryTs: number;\n paused: boolean;\n vaultBalance: BaseUnitString;\n tokenMint: Address;\n tokenMaxPerTx: BaseUnitString;\n tokenDailyLimit: BaseUnitString;\n tokenSpentToday: BaseUnitString;\n tokenDayStartTs: number;\n}\n\nexport interface PolicyCheckResult {\n allowed: boolean;\n reason?: string;\n reasonCode?: RejectReason;\n spentToday: BaseUnitString;\n dailyLimit: BaseUnitString;\n remaining: BaseUnitString;\n}\n\nexport interface PolicyUpdate {\n maxPerTx?: BaseUnitString;\n dailyLimit?: BaseUnitString;\n expiryTs?: number;\n paused?: boolean;\n}\n\nexport interface TokenEnvelopeConfig {\n tokenMint: Address;\n tokenMaxPerTx: BaseUnitString;\n tokenDailyLimit: BaseUnitString;\n}\n\nexport type AllowListKind = \"programs\" | \"recipients\" | \"mints\";\n\n// --- Proposals -------------------------------------------------------------\n\nexport interface TransferDetail {\n kind: \"transfer\";\n amount: BaseUnitString;\n asset: TokenInfo;\n recipientName: string;\n recipientAddress: Address;\n recipientNote?: string;\n}\n\nexport interface SwapDetail {\n kind: \"swap\";\n amountIn: BaseUnitString;\n assetIn: TokenInfo;\n estAmountOut: BaseUnitString;\n assetOut: TokenInfo;\n route: string;\n priceImpactBps: number;\n}\n\nexport type ProposalDetail = TransferDetail | SwapDetail;\n\nexport type ProposalState = \"pending\" | \"signing\" | \"signed\" | \"blocked\" | \"cancelled\";\n\nexport interface ActionProposal {\n id: string;\n detail: ProposalDetail;\n networkFee: BaseUnitString;\n simulation: string;\n check: PolicyCheckResult;\n state: ProposalState;\n sig?: string;\n}\n\n// --- Conversation ----------------------------------------------------------\n\nexport interface ClarifyOption {\n label: string;\n value: string;\n hint?: string;\n}\n\nexport interface ResearchMetric {\n label: string;\n value: string;\n trend?: \"up\" | \"down\" | \"flat\";\n}\n\nexport interface ResearchData {\n token: string;\n mint: Address;\n metrics: ResearchMetric[];\n summary: string;\n}\n\nexport interface PolicyChangeRow {\n label: string;\n from: string;\n to: string;\n}\n\nexport type AgentBlock =\n | { type: \"prose\"; text: string }\n | { type: \"clarify\"; text: string; options: ClarifyOption[] }\n | { type: \"proposal\"; text: string; proposalId: string }\n | { type: \"research\"; text: string; data: ResearchData }\n | { type: \"notice\"; tone: \"success\" | \"info\"; text: string }\n | {\n type: \"policy_change\";\n text: string;\n patch: PolicyUpdate;\n changes: PolicyChangeRow[];\n applied: boolean;\n };\n\nexport type UserMessage = { id: string; role: \"user\"; ts: number; text: string };\nexport type AgentMessage = { id: string; role: \"agent\"; ts: number; blocks: AgentBlock[] };\nexport type Message = UserMessage | AgentMessage;\n\nexport interface Thread {\n id: string;\n title: string;\n messages: Message[];\n updatedAt: number;\n}\n\n// --- Activity --------------------------------------------------------------\n\nexport interface ActivityEntry {\n id: string;\n kind: \"transfer\" | \"swap\";\n label: string;\n asset: string;\n amount: BaseUnitString;\n decimals: number;\n result: \"allowed\" | \"rejected\";\n reason?: string;\n reasonCode?: RejectReason;\n ts: number;\n sig?: string;\n}\n\n// --- Owner transactions (wallet-signed path) -------------------------------\n\nexport interface UnsignedOwnerTransaction {\n /** base64-encoded unsigned transaction for the owner wallet to sign. */\n transaction: string;\n blockhash: string;\n lastValidBlockHeight: number;\n}\n\n/**\n * An {@link UnsignedOwnerTransaction} after the owner wallet has signed it — the\n * base64 `transaction` now carries the owner's signature. This is what you pass\n * to {@link PraxisClient.submitOwnerTransaction}. Signing a Solana transaction\n * requires a transaction-capable wallet (browser wallet adapter / `@solana/web3.js`);\n * the SDK's `keypairSigner` only signs the sign-in *message*, not transactions.\n */\nexport type SignedOwnerTransaction = UnsignedOwnerTransaction;\n\n/** Typed owner action accepted by `POST /owner/build`. */\nexport type OwnerAction =\n | { kind: \"bootstrapPolicy\"; fundLamports?: BaseUnitString }\n | { kind: \"fundVault\"; amount: BaseUnitString }\n | { kind: \"withdrawVault\"; amount: BaseUnitString }\n | { kind: \"closePolicy\" }\n | { kind: \"revoke\" }\n | { kind: \"rotate\" }\n | { kind: \"updatePolicy\"; patch: PolicyUpdate }\n | { kind: \"allowList\"; listKind: AllowListKind; address: Address; mode: \"add\" | \"remove\" };\n"]}
package/dist/index.d.cts CHANGED
@@ -64,7 +64,10 @@ interface WalletChallenge {
64
64
  }
65
65
  interface SessionInfo {
66
66
  authenticated: boolean;
67
+ /** The signed-in wallet (owner). Present whenever `authenticated` is true. */
67
68
  walletAddress: Address;
69
+ /** Unix seconds at which the session expires (from `GET /auth/session`). */
70
+ expiresAt?: number;
68
71
  }
69
72
  interface TokenInfo {
70
73
  symbol: string;
@@ -164,6 +167,11 @@ interface ResearchData {
164
167
  metrics: ResearchMetric[];
165
168
  summary: string;
166
169
  }
170
+ interface PolicyChangeRow {
171
+ label: string;
172
+ from: string;
173
+ to: string;
174
+ }
167
175
  type AgentBlock = {
168
176
  type: "prose";
169
177
  text: string;
@@ -179,6 +187,16 @@ type AgentBlock = {
179
187
  type: "research";
180
188
  text: string;
181
189
  data: ResearchData;
190
+ } | {
191
+ type: "notice";
192
+ tone: "success" | "info";
193
+ text: string;
194
+ } | {
195
+ type: "policy_change";
196
+ text: string;
197
+ patch: PolicyUpdate;
198
+ changes: PolicyChangeRow[];
199
+ applied: boolean;
182
200
  };
183
201
  type UserMessage = {
184
202
  id: string;
@@ -218,6 +236,14 @@ interface UnsignedOwnerTransaction {
218
236
  blockhash: string;
219
237
  lastValidBlockHeight: number;
220
238
  }
239
+ /**
240
+ * An {@link UnsignedOwnerTransaction} after the owner wallet has signed it — the
241
+ * base64 `transaction` now carries the owner's signature. This is what you pass
242
+ * to {@link PraxisClient.submitOwnerTransaction}. Signing a Solana transaction
243
+ * requires a transaction-capable wallet (browser wallet adapter / `@solana/web3.js`);
244
+ * the SDK's `keypairSigner` only signs the sign-in *message*, not transactions.
245
+ */
246
+ type SignedOwnerTransaction = UnsignedOwnerTransaction;
221
247
  /** Typed owner action accepted by `POST /owner/build`. */
222
248
  type OwnerAction = {
223
249
  kind: "bootstrapPolicy";
@@ -252,8 +278,14 @@ interface PraxisClientOptions {
252
278
  signer?: PraxisSigner;
253
279
  /** Custom fetch (defaults to global fetch). Required in runtimes without one. */
254
280
  fetch?: FetchLike;
255
- /** Per-request timeout in ms (default 20_000). */
281
+ /** Per-request timeout in ms for reads/mutations (default 20_000). */
256
282
  timeoutMs?: number;
283
+ /**
284
+ * Per-request timeout in ms for agent conversation turns (`send`/`ask`), which
285
+ * block on the full LLM round-trip (default 60_000). Effective value is never
286
+ * below `timeoutMs`.
287
+ */
288
+ agentTimeoutMs?: number;
257
289
  }
258
290
  /** Result of {@link PraxisClient.ask} — the agent's reply, distilled. */
259
291
  interface AskResult {
@@ -280,6 +312,7 @@ declare class PraxisClient {
280
312
  private readonly signer?;
281
313
  private readonly fetchImpl;
282
314
  private readonly timeoutMs;
315
+ private readonly agentTimeoutMs;
283
316
  /** Manual cookie jar — Node's fetch does not persist Set-Cookie across calls. */
284
317
  private sessionCookie?;
285
318
  constructor(options: PraxisClientOptions);
@@ -287,12 +320,20 @@ declare class PraxisClient {
287
320
  get address(): string | undefined;
288
321
  /**
289
322
  * Run the wallet-ownership handshake: request a challenge, sign its message,
290
- * verify it, and store the resulting session cookie. Idempotent.
323
+ * verify it, and store the resulting session cookie. Safe to call again to
324
+ * refresh the session (each call issues a new challenge + cookie).
291
325
  */
292
326
  connect(): Promise<SessionInfo>;
293
- /** Current session, or `null` if not signed in. */
327
+ /**
328
+ * Current session, or `null` if not signed in. The endpoint answers `200`
329
+ * with `{ authenticated: false }` when signed out, so this normalizes both
330
+ * that shape and a `401` to `null`.
331
+ */
294
332
  session(): Promise<SessionInfo | null>;
295
- /** Clear the session (server-side cookie + local jar). */
333
+ /**
334
+ * Clear the session (server-side cookie + local jar). Idempotent: if there is
335
+ * no active session, the local jar is still cleared and no error is thrown.
336
+ */
296
337
  logout(): Promise<void>;
297
338
  /** Send a line to the agent. Creates a thread when `threadId` is omitted. */
298
339
  send(text: string, threadId?: string | null): Promise<{
@@ -317,6 +358,12 @@ declare class PraxisClient {
317
358
  isThinking(threadId: string): Promise<boolean>;
318
359
  getVersion(): Promise<number>;
319
360
  bootstrapPolicy(fundLamports?: BaseUnitString): Promise<void>;
361
+ /** Deposit SOL (lamports, base-unit string) from the owner into the vault. */
362
+ fundVault(amount: BaseUnitString): Promise<void>;
363
+ /** Withdraw SOL (lamports, base-unit string) from the vault to the owner. */
364
+ withdrawVault(amount: BaseUnitString): Promise<void>;
365
+ /** Tear the agent down — drain the vault and close the policy. Irreversible. */
366
+ deleteAgent(): Promise<void>;
320
367
  updatePolicy(patch: PolicyUpdate): Promise<void>;
321
368
  configureToken(config: TokenEnvelopeConfig): Promise<void>;
322
369
  prepareTokenAccounts(recipientAddresses?: string[]): Promise<void>;
@@ -324,10 +371,15 @@ declare class PraxisClient {
324
371
  rotateAgent(): Promise<void>;
325
372
  addToAllowList(kind: AllowListKind, address: string): Promise<void>;
326
373
  removeFromAllowList(kind: AllowListKind, address: string): Promise<void>;
327
- /** Build an unsigned owner transaction for the wallet to sign. */
374
+ /**
375
+ * Build an unsigned owner transaction for the wallet to sign. The caller signs
376
+ * the returned base64 `transaction` with a transaction-capable wallet, then
377
+ * passes the result to {@link submitOwnerTransaction}. (The SDK's
378
+ * `keypairSigner` signs sign-in messages only, not transactions.)
379
+ */
328
380
  buildOwnerTransaction(action: OwnerAction): Promise<UnsignedOwnerTransaction>;
329
- /** Submit a wallet-signed owner transaction. */
330
- submitOwnerTransaction(signed: UnsignedOwnerTransaction): Promise<{
381
+ /** Submit a wallet-signed owner transaction; resolves with its signature. */
382
+ submitOwnerTransaction(signed: SignedOwnerTransaction): Promise<{
331
383
  sig: string;
332
384
  }>;
333
385
  private get;
@@ -345,14 +397,28 @@ declare class PraxisApiError extends Error {
345
397
  readonly status: number;
346
398
  /** The backend error class name, e.g. "PraxisAuthError", "PraxisRateLimitError". */
347
399
  readonly type: string;
348
- constructor(status: number, type: string, message: string);
400
+ constructor(status: number, type: string, message: string, options?: {
401
+ cause?: unknown;
402
+ });
349
403
  get isAuth(): boolean;
350
404
  get isRateLimited(): boolean;
351
405
  get isInput(): boolean;
406
+ /** Resource not found (404). */
407
+ get isNotFound(): boolean;
408
+ /** Server reported a configuration problem (503) — usually transient. */
409
+ get isConfig(): boolean;
410
+ /** The request timed out client-side before any HTTP response. */
411
+ get isTimeout(): boolean;
412
+ /** A connection-level failure (DNS, refused, TLS) before any HTTP response. */
413
+ get isNetwork(): boolean;
414
+ /** Any server-side failure (HTTP >= 500). */
415
+ get isServer(): boolean;
352
416
  }
353
417
  /** Thrown for SDK-side misconfiguration (no fetch, no signer, bad key, …). */
354
418
  declare class PraxisConfigError extends Error {
355
- constructor(message: string);
419
+ constructor(message: string, options?: {
420
+ cause?: unknown;
421
+ });
356
422
  }
357
423
 
358
424
  /**
@@ -360,13 +426,21 @@ declare class PraxisConfigError extends Error {
360
426
  * base units (lamports / token base units). These convert to/from `bigint` and
361
427
  * human decimal amounts without floats.
362
428
  */
363
- /** Parse a base-unit string (or bigint) into a bigint. */
429
+ /**
430
+ * Parse a base-unit string (or bigint) into a bigint. Rejects floats, hex, and
431
+ * other non-decimal-integer input so the SDK and server agree on what a valid
432
+ * base-unit string is (mirrors the server's `parseUnits`).
433
+ */
364
434
  declare function toBaseUnits(value: string | bigint): bigint;
365
- /** Serialize a bigint (or number of whole base units) into a base-unit string. */
435
+ /**
436
+ * Serialize a bigint (or a whole, safe-integer number of base units) into a
437
+ * base-unit string. A non-integer or unsafe `number` throws rather than
438
+ * silently losing precision.
439
+ */
366
440
  declare function fromBaseUnits(value: bigint | number): string;
367
441
  /** Convert a human decimal amount ("0.5") into base units for `decimals` places. */
368
442
  declare function humanToBaseUnits(amount: string, decimals: number): string;
369
443
  /** Convert base units into a human decimal string for `decimals` places. */
370
444
  declare function baseUnitsToHuman(value: string | bigint, decimals: number): string;
371
445
 
372
- export { ActionKind, type ActionProposal, type ActivityEntry, type Address, type AddressBookEntry, type AgentBlock, type AgentMessage, type AllowListKind, type AskResult, type BaseUnitString, type ClarifyOption, type FetchLike, type Message, type OwnerAction, type PolicyCheckResult, type PolicyUpdate, type PolicyView, PraxisApiError, PraxisClient, type PraxisClientOptions, PraxisConfigError, type PraxisSigner, type ProposalDetail, type ProposalState, RejectReason, type ResearchData, type ResearchMetric, type SecretKeyInput, type SessionInfo, type SwapDetail, type Thread, type TokenEnvelopeConfig, type TokenInfo, type TransferDetail, type UnsignedOwnerTransaction, type UserMessage, type WalletChallenge, baseUnitsToHuman, fromBaseUnits, humanToBaseUnits, keypairSigner, toBaseUnits };
446
+ export { ActionKind, type ActionProposal, type ActivityEntry, type Address, type AddressBookEntry, type AgentBlock, type AgentMessage, type AllowListKind, type AskResult, type BaseUnitString, type ClarifyOption, type FetchLike, type Message, type OwnerAction, type PolicyChangeRow, type PolicyCheckResult, type PolicyUpdate, type PolicyView, PraxisApiError, PraxisClient, type PraxisClientOptions, PraxisConfigError, type PraxisSigner, type ProposalDetail, type ProposalState, RejectReason, type ResearchData, type ResearchMetric, type SecretKeyInput, type SessionInfo, type SignedOwnerTransaction, type SwapDetail, type Thread, type TokenEnvelopeConfig, type TokenInfo, type TransferDetail, type UnsignedOwnerTransaction, type UserMessage, type WalletChallenge, baseUnitsToHuman, fromBaseUnits, humanToBaseUnits, keypairSigner, toBaseUnits };
package/dist/index.d.ts CHANGED
@@ -64,7 +64,10 @@ interface WalletChallenge {
64
64
  }
65
65
  interface SessionInfo {
66
66
  authenticated: boolean;
67
+ /** The signed-in wallet (owner). Present whenever `authenticated` is true. */
67
68
  walletAddress: Address;
69
+ /** Unix seconds at which the session expires (from `GET /auth/session`). */
70
+ expiresAt?: number;
68
71
  }
69
72
  interface TokenInfo {
70
73
  symbol: string;
@@ -164,6 +167,11 @@ interface ResearchData {
164
167
  metrics: ResearchMetric[];
165
168
  summary: string;
166
169
  }
170
+ interface PolicyChangeRow {
171
+ label: string;
172
+ from: string;
173
+ to: string;
174
+ }
167
175
  type AgentBlock = {
168
176
  type: "prose";
169
177
  text: string;
@@ -179,6 +187,16 @@ type AgentBlock = {
179
187
  type: "research";
180
188
  text: string;
181
189
  data: ResearchData;
190
+ } | {
191
+ type: "notice";
192
+ tone: "success" | "info";
193
+ text: string;
194
+ } | {
195
+ type: "policy_change";
196
+ text: string;
197
+ patch: PolicyUpdate;
198
+ changes: PolicyChangeRow[];
199
+ applied: boolean;
182
200
  };
183
201
  type UserMessage = {
184
202
  id: string;
@@ -218,6 +236,14 @@ interface UnsignedOwnerTransaction {
218
236
  blockhash: string;
219
237
  lastValidBlockHeight: number;
220
238
  }
239
+ /**
240
+ * An {@link UnsignedOwnerTransaction} after the owner wallet has signed it — the
241
+ * base64 `transaction` now carries the owner's signature. This is what you pass
242
+ * to {@link PraxisClient.submitOwnerTransaction}. Signing a Solana transaction
243
+ * requires a transaction-capable wallet (browser wallet adapter / `@solana/web3.js`);
244
+ * the SDK's `keypairSigner` only signs the sign-in *message*, not transactions.
245
+ */
246
+ type SignedOwnerTransaction = UnsignedOwnerTransaction;
221
247
  /** Typed owner action accepted by `POST /owner/build`. */
222
248
  type OwnerAction = {
223
249
  kind: "bootstrapPolicy";
@@ -252,8 +278,14 @@ interface PraxisClientOptions {
252
278
  signer?: PraxisSigner;
253
279
  /** Custom fetch (defaults to global fetch). Required in runtimes without one. */
254
280
  fetch?: FetchLike;
255
- /** Per-request timeout in ms (default 20_000). */
281
+ /** Per-request timeout in ms for reads/mutations (default 20_000). */
256
282
  timeoutMs?: number;
283
+ /**
284
+ * Per-request timeout in ms for agent conversation turns (`send`/`ask`), which
285
+ * block on the full LLM round-trip (default 60_000). Effective value is never
286
+ * below `timeoutMs`.
287
+ */
288
+ agentTimeoutMs?: number;
257
289
  }
258
290
  /** Result of {@link PraxisClient.ask} — the agent's reply, distilled. */
259
291
  interface AskResult {
@@ -280,6 +312,7 @@ declare class PraxisClient {
280
312
  private readonly signer?;
281
313
  private readonly fetchImpl;
282
314
  private readonly timeoutMs;
315
+ private readonly agentTimeoutMs;
283
316
  /** Manual cookie jar — Node's fetch does not persist Set-Cookie across calls. */
284
317
  private sessionCookie?;
285
318
  constructor(options: PraxisClientOptions);
@@ -287,12 +320,20 @@ declare class PraxisClient {
287
320
  get address(): string | undefined;
288
321
  /**
289
322
  * Run the wallet-ownership handshake: request a challenge, sign its message,
290
- * verify it, and store the resulting session cookie. Idempotent.
323
+ * verify it, and store the resulting session cookie. Safe to call again to
324
+ * refresh the session (each call issues a new challenge + cookie).
291
325
  */
292
326
  connect(): Promise<SessionInfo>;
293
- /** Current session, or `null` if not signed in. */
327
+ /**
328
+ * Current session, or `null` if not signed in. The endpoint answers `200`
329
+ * with `{ authenticated: false }` when signed out, so this normalizes both
330
+ * that shape and a `401` to `null`.
331
+ */
294
332
  session(): Promise<SessionInfo | null>;
295
- /** Clear the session (server-side cookie + local jar). */
333
+ /**
334
+ * Clear the session (server-side cookie + local jar). Idempotent: if there is
335
+ * no active session, the local jar is still cleared and no error is thrown.
336
+ */
296
337
  logout(): Promise<void>;
297
338
  /** Send a line to the agent. Creates a thread when `threadId` is omitted. */
298
339
  send(text: string, threadId?: string | null): Promise<{
@@ -317,6 +358,12 @@ declare class PraxisClient {
317
358
  isThinking(threadId: string): Promise<boolean>;
318
359
  getVersion(): Promise<number>;
319
360
  bootstrapPolicy(fundLamports?: BaseUnitString): Promise<void>;
361
+ /** Deposit SOL (lamports, base-unit string) from the owner into the vault. */
362
+ fundVault(amount: BaseUnitString): Promise<void>;
363
+ /** Withdraw SOL (lamports, base-unit string) from the vault to the owner. */
364
+ withdrawVault(amount: BaseUnitString): Promise<void>;
365
+ /** Tear the agent down — drain the vault and close the policy. Irreversible. */
366
+ deleteAgent(): Promise<void>;
320
367
  updatePolicy(patch: PolicyUpdate): Promise<void>;
321
368
  configureToken(config: TokenEnvelopeConfig): Promise<void>;
322
369
  prepareTokenAccounts(recipientAddresses?: string[]): Promise<void>;
@@ -324,10 +371,15 @@ declare class PraxisClient {
324
371
  rotateAgent(): Promise<void>;
325
372
  addToAllowList(kind: AllowListKind, address: string): Promise<void>;
326
373
  removeFromAllowList(kind: AllowListKind, address: string): Promise<void>;
327
- /** Build an unsigned owner transaction for the wallet to sign. */
374
+ /**
375
+ * Build an unsigned owner transaction for the wallet to sign. The caller signs
376
+ * the returned base64 `transaction` with a transaction-capable wallet, then
377
+ * passes the result to {@link submitOwnerTransaction}. (The SDK's
378
+ * `keypairSigner` signs sign-in messages only, not transactions.)
379
+ */
328
380
  buildOwnerTransaction(action: OwnerAction): Promise<UnsignedOwnerTransaction>;
329
- /** Submit a wallet-signed owner transaction. */
330
- submitOwnerTransaction(signed: UnsignedOwnerTransaction): Promise<{
381
+ /** Submit a wallet-signed owner transaction; resolves with its signature. */
382
+ submitOwnerTransaction(signed: SignedOwnerTransaction): Promise<{
331
383
  sig: string;
332
384
  }>;
333
385
  private get;
@@ -345,14 +397,28 @@ declare class PraxisApiError extends Error {
345
397
  readonly status: number;
346
398
  /** The backend error class name, e.g. "PraxisAuthError", "PraxisRateLimitError". */
347
399
  readonly type: string;
348
- constructor(status: number, type: string, message: string);
400
+ constructor(status: number, type: string, message: string, options?: {
401
+ cause?: unknown;
402
+ });
349
403
  get isAuth(): boolean;
350
404
  get isRateLimited(): boolean;
351
405
  get isInput(): boolean;
406
+ /** Resource not found (404). */
407
+ get isNotFound(): boolean;
408
+ /** Server reported a configuration problem (503) — usually transient. */
409
+ get isConfig(): boolean;
410
+ /** The request timed out client-side before any HTTP response. */
411
+ get isTimeout(): boolean;
412
+ /** A connection-level failure (DNS, refused, TLS) before any HTTP response. */
413
+ get isNetwork(): boolean;
414
+ /** Any server-side failure (HTTP >= 500). */
415
+ get isServer(): boolean;
352
416
  }
353
417
  /** Thrown for SDK-side misconfiguration (no fetch, no signer, bad key, …). */
354
418
  declare class PraxisConfigError extends Error {
355
- constructor(message: string);
419
+ constructor(message: string, options?: {
420
+ cause?: unknown;
421
+ });
356
422
  }
357
423
 
358
424
  /**
@@ -360,13 +426,21 @@ declare class PraxisConfigError extends Error {
360
426
  * base units (lamports / token base units). These convert to/from `bigint` and
361
427
  * human decimal amounts without floats.
362
428
  */
363
- /** Parse a base-unit string (or bigint) into a bigint. */
429
+ /**
430
+ * Parse a base-unit string (or bigint) into a bigint. Rejects floats, hex, and
431
+ * other non-decimal-integer input so the SDK and server agree on what a valid
432
+ * base-unit string is (mirrors the server's `parseUnits`).
433
+ */
364
434
  declare function toBaseUnits(value: string | bigint): bigint;
365
- /** Serialize a bigint (or number of whole base units) into a base-unit string. */
435
+ /**
436
+ * Serialize a bigint (or a whole, safe-integer number of base units) into a
437
+ * base-unit string. A non-integer or unsafe `number` throws rather than
438
+ * silently losing precision.
439
+ */
366
440
  declare function fromBaseUnits(value: bigint | number): string;
367
441
  /** Convert a human decimal amount ("0.5") into base units for `decimals` places. */
368
442
  declare function humanToBaseUnits(amount: string, decimals: number): string;
369
443
  /** Convert base units into a human decimal string for `decimals` places. */
370
444
  declare function baseUnitsToHuman(value: string | bigint, decimals: number): string;
371
445
 
372
- export { ActionKind, type ActionProposal, type ActivityEntry, type Address, type AddressBookEntry, type AgentBlock, type AgentMessage, type AllowListKind, type AskResult, type BaseUnitString, type ClarifyOption, type FetchLike, type Message, type OwnerAction, type PolicyCheckResult, type PolicyUpdate, type PolicyView, PraxisApiError, PraxisClient, type PraxisClientOptions, PraxisConfigError, type PraxisSigner, type ProposalDetail, type ProposalState, RejectReason, type ResearchData, type ResearchMetric, type SecretKeyInput, type SessionInfo, type SwapDetail, type Thread, type TokenEnvelopeConfig, type TokenInfo, type TransferDetail, type UnsignedOwnerTransaction, type UserMessage, type WalletChallenge, baseUnitsToHuman, fromBaseUnits, humanToBaseUnits, keypairSigner, toBaseUnits };
446
+ export { ActionKind, type ActionProposal, type ActivityEntry, type Address, type AddressBookEntry, type AgentBlock, type AgentMessage, type AllowListKind, type AskResult, type BaseUnitString, type ClarifyOption, type FetchLike, type Message, type OwnerAction, type PolicyChangeRow, type PolicyCheckResult, type PolicyUpdate, type PolicyView, PraxisApiError, PraxisClient, type PraxisClientOptions, PraxisConfigError, type PraxisSigner, type ProposalDetail, type ProposalState, RejectReason, type ResearchData, type ResearchMetric, type SecretKeyInput, type SessionInfo, type SignedOwnerTransaction, type SwapDetail, type Thread, type TokenEnvelopeConfig, type TokenInfo, type TransferDetail, type UnsignedOwnerTransaction, type UserMessage, type WalletChallenge, baseUnitsToHuman, fromBaseUnits, humanToBaseUnits, keypairSigner, toBaseUnits };
package/dist/index.js CHANGED
@@ -8,8 +8,8 @@ var PraxisApiError = class _PraxisApiError extends Error {
8
8
  status;
9
9
  /** The backend error class name, e.g. "PraxisAuthError", "PraxisRateLimitError". */
10
10
  type;
11
- constructor(status, type, message) {
12
- super(message);
11
+ constructor(status, type, message, options) {
12
+ super(message, options);
13
13
  this.name = "PraxisApiError";
14
14
  this.status = status;
15
15
  this.type = type;
@@ -24,10 +24,30 @@ var PraxisApiError = class _PraxisApiError extends Error {
24
24
  get isInput() {
25
25
  return this.status === 400;
26
26
  }
27
+ /** Resource not found (404). */
28
+ get isNotFound() {
29
+ return this.status === 404;
30
+ }
31
+ /** Server reported a configuration problem (503) — usually transient. */
32
+ get isConfig() {
33
+ return this.status === 503;
34
+ }
35
+ /** The request timed out client-side before any HTTP response. */
36
+ get isTimeout() {
37
+ return this.status === 0 && this.type === "TimeoutError";
38
+ }
39
+ /** A connection-level failure (DNS, refused, TLS) before any HTTP response. */
40
+ get isNetwork() {
41
+ return this.status === 0 && this.type === "NetworkError";
42
+ }
43
+ /** Any server-side failure (HTTP >= 500). */
44
+ get isServer() {
45
+ return this.status >= 500;
46
+ }
27
47
  };
28
48
  var PraxisConfigError = class _PraxisConfigError extends Error {
29
- constructor(message) {
30
- super(message);
49
+ constructor(message, options) {
50
+ super(message, options);
31
51
  this.name = "PraxisConfigError";
32
52
  Object.setPrototypeOf(this, _PraxisConfigError.prototype);
33
53
  }
@@ -40,6 +60,7 @@ var PraxisClient = class {
40
60
  signer;
41
61
  fetchImpl;
42
62
  timeoutMs;
63
+ agentTimeoutMs;
43
64
  /** Manual cookie jar — Node's fetch does not persist Set-Cookie across calls. */
44
65
  sessionCookie;
45
66
  constructor(options) {
@@ -52,6 +73,7 @@ var PraxisClient = class {
52
73
  }
53
74
  this.fetchImpl = resolvedFetch;
54
75
  this.timeoutMs = options.timeoutMs ?? 2e4;
76
+ this.agentTimeoutMs = Math.max(options.agentTimeoutMs ?? 6e4, this.timeoutMs);
55
77
  }
56
78
  // --- auth ----------------------------------------------------------------
57
79
  /** The signer's wallet address, if a signer was provided. */
@@ -60,7 +82,8 @@ var PraxisClient = class {
60
82
  }
61
83
  /**
62
84
  * Run the wallet-ownership handshake: request a challenge, sign its message,
63
- * verify it, and store the resulting session cookie. Idempotent.
85
+ * verify it, and store the resulting session cookie. Safe to call again to
86
+ * refresh the session (each call issues a new challenge + cookie).
64
87
  */
65
88
  async connect() {
66
89
  if (!this.signer) {
@@ -76,24 +99,37 @@ var PraxisClient = class {
76
99
  signature: bs582.encode(signature)
77
100
  });
78
101
  }
79
- /** Current session, or `null` if not signed in. */
102
+ /**
103
+ * Current session, or `null` if not signed in. The endpoint answers `200`
104
+ * with `{ authenticated: false }` when signed out, so this normalizes both
105
+ * that shape and a `401` to `null`.
106
+ */
80
107
  async session() {
81
108
  try {
82
- return await this.get("/auth/session");
109
+ const info = await this.get("/auth/session");
110
+ return info && info.authenticated ? info : null;
83
111
  } catch (error) {
84
112
  if (error instanceof PraxisApiError && error.isAuth) return null;
85
113
  throw error;
86
114
  }
87
115
  }
88
- /** Clear the session (server-side cookie + local jar). */
116
+ /**
117
+ * Clear the session (server-side cookie + local jar). Idempotent: if there is
118
+ * no active session, the local jar is still cleared and no error is thrown.
119
+ */
89
120
  async logout() {
90
- await this.request("DELETE", "/auth/session");
91
- this.sessionCookie = void 0;
121
+ try {
122
+ await this.request("DELETE", "/auth/session");
123
+ } catch (error) {
124
+ if (!(error instanceof PraxisApiError && error.isAuth)) throw error;
125
+ } finally {
126
+ this.sessionCookie = void 0;
127
+ }
92
128
  }
93
129
  // --- conversation --------------------------------------------------------
94
130
  /** Send a line to the agent. Creates a thread when `threadId` is omitted. */
95
131
  send(text, threadId = null) {
96
- return this.post("/send", { text, threadId });
132
+ return this.post("/send", { text, threadId }, this.agentTimeoutMs);
97
133
  }
98
134
  /**
99
135
  * Send a line and return the agent's reply in one call. The API resolves
@@ -148,6 +184,18 @@ var PraxisClient = class {
148
184
  bootstrapPolicy(fundLamports) {
149
185
  return this.post("/bootstrap-policy", fundLamports ? { fundLamports } : {});
150
186
  }
187
+ /** Deposit SOL (lamports, base-unit string) from the owner into the vault. */
188
+ fundVault(amount) {
189
+ return this.post("/fund-vault", { amount });
190
+ }
191
+ /** Withdraw SOL (lamports, base-unit string) from the vault to the owner. */
192
+ withdrawVault(amount) {
193
+ return this.post("/withdraw-vault", { amount });
194
+ }
195
+ /** Tear the agent down — drain the vault and close the policy. Irreversible. */
196
+ deleteAgent() {
197
+ return this.post("/delete-agent", {});
198
+ }
151
199
  updatePolicy(patch) {
152
200
  return this.post("/update-policy", { patch });
153
201
  }
@@ -170,11 +218,16 @@ var PraxisClient = class {
170
218
  return this.post("/remove-from-allow-list", { kind, address });
171
219
  }
172
220
  // --- owner wallet-signed transaction path --------------------------------
173
- /** Build an unsigned owner transaction for the wallet to sign. */
221
+ /**
222
+ * Build an unsigned owner transaction for the wallet to sign. The caller signs
223
+ * the returned base64 `transaction` with a transaction-capable wallet, then
224
+ * passes the result to {@link submitOwnerTransaction}. (The SDK's
225
+ * `keypairSigner` signs sign-in messages only, not transactions.)
226
+ */
174
227
  buildOwnerTransaction(action) {
175
228
  return this.post("/owner/build", { action });
176
229
  }
177
- /** Submit a wallet-signed owner transaction. */
230
+ /** Submit a wallet-signed owner transaction; resolves with its signature. */
178
231
  submitOwnerTransaction(signed) {
179
232
  return this.post("/owner/submit", signed);
180
233
  }
@@ -182,8 +235,8 @@ var PraxisClient = class {
182
235
  get(path, query) {
183
236
  return this.request("GET", path, { query });
184
237
  }
185
- post(path, body) {
186
- return this.request("POST", path, { body });
238
+ post(path, body, timeoutMs) {
239
+ return this.request("POST", path, { body, timeoutMs });
187
240
  }
188
241
  async request(method, path, opts = {}) {
189
242
  const url = new URL(this.baseUrl + API_PREFIX + path);
@@ -191,8 +244,9 @@ var PraxisClient = class {
191
244
  const headers = { accept: "application/json" };
192
245
  if (opts.body !== void 0) headers["content-type"] = "application/json";
193
246
  if (this.sessionCookie) headers["cookie"] = this.sessionCookie;
247
+ const timeoutMs = opts.timeoutMs ?? this.timeoutMs;
194
248
  const controller = new AbortController();
195
- const timer = setTimeout(() => controller.abort(), this.timeoutMs);
249
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
196
250
  let res;
197
251
  try {
198
252
  res = await this.fetchImpl(url.toString(), {
@@ -205,9 +259,13 @@ var PraxisClient = class {
205
259
  });
206
260
  } catch (error) {
207
261
  if (error instanceof Error && error.name === "AbortError") {
208
- throw new PraxisApiError(0, "TimeoutError", `Praxis request timed out after ${this.timeoutMs}ms`);
262
+ throw new PraxisApiError(0, "TimeoutError", `Praxis request timed out after ${timeoutMs}ms`, {
263
+ cause: error
264
+ });
209
265
  }
210
- throw error;
266
+ if (error instanceof PraxisApiError) throw error;
267
+ const detail = error instanceof Error ? error.message : String(error);
268
+ throw new PraxisApiError(0, "NetworkError", `Praxis request failed: ${detail}`, { cause: error });
211
269
  } finally {
212
270
  clearTimeout(timer);
213
271
  }
@@ -269,6 +327,9 @@ function normalizeSecret(secret) {
269
327
  throw new PraxisConfigError("secret key string must be base58-encoded");
270
328
  }
271
329
  } else if (Array.isArray(secret)) {
330
+ if (!secret.every((b) => Number.isInteger(b) && b >= 0 && b <= 255)) {
331
+ throw new PraxisConfigError("secret key array must contain only byte values (integers 0\u2013255)");
332
+ }
272
333
  bytes = Uint8Array.from(secret);
273
334
  } else {
274
335
  bytes = secret;
@@ -282,10 +343,19 @@ function normalizeSecret(secret) {
282
343
  }
283
344
 
284
345
  // src/units.ts
346
+ var INTEGER_RE = /^-?\d+$/;
285
347
  function toBaseUnits(value) {
286
- return typeof value === "bigint" ? value : BigInt(value.trim());
348
+ if (typeof value === "bigint") return value;
349
+ const trimmed = value.trim();
350
+ if (!INTEGER_RE.test(trimmed)) {
351
+ throw new Error(`toBaseUnits: expected an integer base-unit string, got "${value}"`);
352
+ }
353
+ return BigInt(trimmed);
287
354
  }
288
355
  function fromBaseUnits(value) {
356
+ if (typeof value === "number" && !Number.isSafeInteger(value)) {
357
+ throw new Error(`fromBaseUnits: number must be a safe integer, got ${value}`);
358
+ }
289
359
  return BigInt(value).toString();
290
360
  }
291
361
  function humanToBaseUnits(amount, decimals) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/signer.ts","../src/units.ts","../src/types.ts"],"names":["bs58","ActionKind","RejectReason"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Thrown when the Praxis API returns a non-2xx response. The backend's error\n * envelope is `{ error: string, type: string }` with a meaningful HTTP status\n * (400 input, 401 auth, 404 not-found, 429 rate-limit, 503 config, 500 other).\n */\nexport class PraxisApiError extends Error {\n readonly status: number;\n /** The backend error class name, e.g. \"PraxisAuthError\", \"PraxisRateLimitError\". */\n readonly type: string;\n\n constructor(status: number, type: string, message: string) {\n super(message);\n this.name = \"PraxisApiError\";\n this.status = status;\n this.type = type;\n // Restore prototype chain for instanceof across transpile targets.\n Object.setPrototypeOf(this, PraxisApiError.prototype);\n }\n\n get isAuth(): boolean {\n return this.status === 401;\n }\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n get isInput(): boolean {\n return this.status === 400;\n }\n}\n\n/** Thrown for SDK-side misconfiguration (no fetch, no signer, bad key, …). */\nexport class PraxisConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PraxisConfigError\";\n Object.setPrototypeOf(this, PraxisConfigError.prototype);\n }\n}\n","import bs58 from \"bs58\";\n\nimport { PraxisApiError, PraxisConfigError } from \"./errors\";\nimport type { PraxisSigner } from \"./signer\";\nimport type {\n ActionProposal,\n ActivityEntry,\n AddressBookEntry,\n AgentMessage,\n AllowListKind,\n BaseUnitString,\n OwnerAction,\n PolicyUpdate,\n PolicyView,\n SessionInfo,\n Thread,\n TokenEnvelopeConfig,\n UnsignedOwnerTransaction,\n WalletChallenge,\n} from \"./types\";\n\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;\n\nexport interface PraxisClientOptions {\n /** Base origin of the Praxis deployment, e.g. \"http://localhost:3000\". */\n baseUrl: string;\n /** Wallet signer for `connect()`. Optional if you only call public reads after an external login. */\n signer?: PraxisSigner;\n /** Custom fetch (defaults to global fetch). Required in runtimes without one. */\n fetch?: FetchLike;\n /** Per-request timeout in ms (default 20_000). */\n timeoutMs?: number;\n}\n\n/** Result of {@link PraxisClient.ask} — the agent's reply, distilled. */\nexport interface AskResult {\n threadId: string;\n /** The agent's reply message (prose / clarify / proposal / research blocks). */\n message: AgentMessage;\n /** Any action proposals the agent produced, hydrated for convenience. */\n proposals: ActionProposal[];\n}\n\nconst API_PREFIX = \"/api/praxis\";\n\n/**\n * Typed client for a hosted Praxis agent. The agent's LLM, scoped agent key, and\n * Aegis policy enforcement all live server-side; this SDK is an authenticated\n * client of the `/api/praxis/*` surface.\n *\n * ```ts\n * const praxis = new PraxisClient({ baseUrl, signer: keypairSigner(secret) });\n * await praxis.connect();\n * const { proposals } = await praxis.ask(\"send 0.5 SOL to maya\");\n * if (proposals[0]?.check.allowed) await praxis.signProposal(proposals[0].id);\n * ```\n */\nexport class PraxisClient {\n private readonly baseUrl: string;\n private readonly signer?: PraxisSigner;\n private readonly fetchImpl: FetchLike;\n private readonly timeoutMs: number;\n /** Manual cookie jar — Node's fetch does not persist Set-Cookie across calls. */\n private sessionCookie?: string;\n\n constructor(options: PraxisClientOptions) {\n if (!options.baseUrl) throw new PraxisConfigError(\"baseUrl is required\");\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.signer = options.signer;\n const resolvedFetch = options.fetch ?? (globalThis.fetch as FetchLike | undefined);\n if (!resolvedFetch) {\n throw new PraxisConfigError(\"No fetch available; pass options.fetch (Node <18 or non-browser runtime).\");\n }\n this.fetchImpl = resolvedFetch;\n this.timeoutMs = options.timeoutMs ?? 20_000;\n }\n\n // --- auth ----------------------------------------------------------------\n\n /** The signer's wallet address, if a signer was provided. */\n get address(): string | undefined {\n return this.signer?.address;\n }\n\n /**\n * Run the wallet-ownership handshake: request a challenge, sign its message,\n * verify it, and store the resulting session cookie. Idempotent.\n */\n async connect(): Promise<SessionInfo> {\n if (!this.signer) {\n throw new PraxisConfigError(\"connect() requires a signer. Pass one to the constructor.\");\n }\n const challenge = await this.post<WalletChallenge>(\"/auth/challenge\", {\n address: this.signer.address,\n });\n const signature = await this.signer.signMessage(new TextEncoder().encode(challenge.message));\n return this.post<SessionInfo>(\"/auth/verify\", {\n address: this.signer.address,\n nonce: challenge.nonce,\n signature: bs58.encode(signature),\n });\n }\n\n /** Current session, or `null` if not signed in. */\n async session(): Promise<SessionInfo | null> {\n try {\n return await this.get<SessionInfo>(\"/auth/session\");\n } catch (error) {\n if (error instanceof PraxisApiError && error.isAuth) return null;\n throw error;\n }\n }\n\n /** Clear the session (server-side cookie + local jar). */\n async logout(): Promise<void> {\n await this.request<unknown>(\"DELETE\", \"/auth/session\");\n this.sessionCookie = undefined;\n }\n\n // --- conversation --------------------------------------------------------\n\n /** Send a line to the agent. Creates a thread when `threadId` is omitted. */\n send(text: string, threadId: string | null = null): Promise<{ threadId: string }> {\n return this.post<{ threadId: string }>(\"/send\", { text, threadId });\n }\n\n /**\n * Send a line and return the agent's reply in one call. The API resolves\n * `send` only after the agent has finished, so this needs no polling.\n */\n async ask(text: string, threadId: string | null = null): Promise<AskResult> {\n const { threadId: tid } = await this.send(text, threadId);\n const thread = await this.getThread(tid);\n const message = lastAgentMessage(thread);\n if (!message) {\n throw new PraxisApiError(500, \"Error\", \"Agent produced no reply message.\");\n }\n const proposalIds = message.blocks\n .filter((b): b is Extract<typeof b, { type: \"proposal\" }> => b.type === \"proposal\")\n .map((b) => b.proposalId);\n const proposals = await Promise.all(proposalIds.map((id) => this.getProposal(id)));\n return { threadId: tid, message, proposals };\n }\n\n newThread(threadId?: string): Promise<{ threadId: string }> {\n return this.post<{ threadId: string }>(\"/new-thread\", threadId ? { threadId } : {});\n }\n\n signProposal(proposalId: string): Promise<void> {\n return this.post<void>(\"/sign-proposal\", { proposalId });\n }\n\n cancelProposal(proposalId: string): Promise<void> {\n return this.post<void>(\"/cancel-proposal\", { proposalId });\n }\n\n // --- reads ---------------------------------------------------------------\n\n getThreads(): Promise<Thread[]> {\n return this.get<Thread[]>(\"/get-threads\");\n }\n getThread(id: string): Promise<Thread> {\n return this.get<Thread>(\"/get-thread\", { id });\n }\n getProposal(id: string): Promise<ActionProposal> {\n return this.get<ActionProposal>(\"/get-proposal\", { id });\n }\n getPolicy(): Promise<PolicyView> {\n return this.get<PolicyView>(\"/get-policy\");\n }\n getActivity(): Promise<ActivityEntry[]> {\n return this.get<ActivityEntry[]>(\"/get-activity\");\n }\n getAddressBook(): Promise<AddressBookEntry[]> {\n return this.get<AddressBookEntry[]>(\"/get-address-book\");\n }\n isThinking(threadId: string): Promise<boolean> {\n return this.get<boolean>(\"/is-thinking\", { threadId });\n }\n getVersion(): Promise<number> {\n return this.get<number>(\"/get-version\");\n }\n\n // --- policy / owner mutations (server-key mode) --------------------------\n\n bootstrapPolicy(fundLamports?: BaseUnitString): Promise<void> {\n return this.post<void>(\"/bootstrap-policy\", fundLamports ? { fundLamports } : {});\n }\n updatePolicy(patch: PolicyUpdate): Promise<void> {\n return this.post<void>(\"/update-policy\", { patch });\n }\n configureToken(config: TokenEnvelopeConfig): Promise<void> {\n return this.post<void>(\"/configure-token\", { config });\n }\n prepareTokenAccounts(recipientAddresses?: string[]): Promise<void> {\n return this.post<void>(\"/prepare-token-accounts\", recipientAddresses ? { recipientAddresses } : {});\n }\n revokeAgent(): Promise<void> {\n return this.post<void>(\"/revoke-agent\", {});\n }\n rotateAgent(): Promise<void> {\n return this.post<void>(\"/rotate-agent\", {});\n }\n addToAllowList(kind: AllowListKind, address: string): Promise<void> {\n return this.post<void>(\"/add-to-allow-list\", { kind, address });\n }\n removeFromAllowList(kind: AllowListKind, address: string): Promise<void> {\n return this.post<void>(\"/remove-from-allow-list\", { kind, address });\n }\n\n // --- owner wallet-signed transaction path --------------------------------\n\n /** Build an unsigned owner transaction for the wallet to sign. */\n buildOwnerTransaction(action: OwnerAction): Promise<UnsignedOwnerTransaction> {\n return this.post<UnsignedOwnerTransaction>(\"/owner/build\", { action });\n }\n /** Submit a wallet-signed owner transaction. */\n submitOwnerTransaction(signed: UnsignedOwnerTransaction): Promise<{ sig: string }> {\n return this.post<{ sig: string }>(\"/owner/submit\", signed);\n }\n\n // --- transport -----------------------------------------------------------\n\n private get<T>(path: string, query?: Record<string, string>): Promise<T> {\n return this.request<T>(\"GET\", path, { query });\n }\n\n private post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, { body });\n }\n\n private async request<T>(\n method: string,\n path: string,\n opts: { body?: unknown; query?: Record<string, string> } = {},\n ): Promise<T> {\n const url = new URL(this.baseUrl + API_PREFIX + path);\n for (const [k, v] of Object.entries(opts.query ?? {})) url.searchParams.set(k, v);\n\n const headers: Record<string, string> = { accept: \"application/json\" };\n if (opts.body !== undefined) headers[\"content-type\"] = \"application/json\";\n if (this.sessionCookie) headers[\"cookie\"] = this.sessionCookie;\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n let res: Response;\n try {\n res = await this.fetchImpl(url.toString(), {\n method,\n headers,\n body: opts.body === undefined ? undefined : JSON.stringify(opts.body),\n // Browser same-origin: let the HttpOnly cookie ride along.\n credentials: \"include\",\n signal: controller.signal,\n } as RequestInit);\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new PraxisApiError(0, \"TimeoutError\", `Praxis request timed out after ${this.timeoutMs}ms`);\n }\n throw error;\n } finally {\n clearTimeout(timer);\n }\n\n this.captureCookie(res);\n\n const text = await res.text();\n const parsed = text ? safeJsonParse(text) : undefined;\n\n if (!res.ok) {\n const message =\n (parsed && typeof parsed === \"object\" && \"error\" in parsed && typeof parsed.error === \"string\"\n ? parsed.error\n : undefined) ?? `Praxis API error ${res.status}`;\n const type =\n parsed && typeof parsed === \"object\" && \"type\" in parsed && typeof parsed.type === \"string\"\n ? parsed.type\n : \"Error\";\n throw new PraxisApiError(res.status, type, message);\n }\n\n return parsed as T;\n }\n\n private captureCookie(res: Response): void {\n // Node 18.14+ exposes getSetCookie(); fall back to the combined header.\n const anyHeaders = res.headers as Headers & { getSetCookie?: () => string[] };\n const cookies = anyHeaders.getSetCookie?.() ?? splitSetCookie(res.headers.get(\"set-cookie\"));\n for (const cookie of cookies) {\n const [pair] = cookie.split(\";\");\n if (pair && pair.trim().startsWith(\"praxis_session=\")) {\n this.sessionCookie = pair.trim();\n }\n }\n }\n}\n\nfunction lastAgentMessage(thread: Thread): AgentMessage | undefined {\n for (let i = thread.messages.length - 1; i >= 0; i--) {\n const m = thread.messages[i];\n if (m.role === \"agent\") return m;\n }\n return undefined;\n}\n\nfunction safeJsonParse(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction splitSetCookie(header: string | null): string[] {\n if (!header) return [];\n // Split on commas that precede a new cookie name=value pair, not commas inside\n // Expires dates (\"Wed, 01 Jan ...\").\n return header.split(/,(?=\\s*[^;,\\s]+=)/);\n}\n","import bs58 from \"bs58\";\nimport nacl from \"tweetnacl\";\n\nimport { PraxisConfigError } from \"./errors\";\n\n/**\n * Signs the wallet-ownership challenge. Implement this to bridge any wallet:\n * - Node / backend agents: use {@link keypairSigner} with a secret key.\n * - Browser: wrap a wallet-adapter, e.g.\n * `{ address: wallet.publicKey.toBase58(), signMessage: (m) => wallet.signMessage(m) }`.\n *\n * `signMessage` must return the raw 64-byte Ed25519 signature; the SDK base58-\n * encodes it for the API.\n */\nexport interface PraxisSigner {\n /** base58-encoded Solana public key. */\n readonly address: string;\n signMessage(message: Uint8Array): Promise<Uint8Array> | Uint8Array;\n}\n\nexport type SecretKeyInput = Uint8Array | number[] | string;\n\n/**\n * Build a {@link PraxisSigner} from a Solana secret key — a 64-byte keypair or a\n * 32-byte seed, as raw bytes, a number array, or a base58 string (Phantom /\n * `solana-keygen` export). Node and browser friendly; no `@solana/web3.js`\n * dependency.\n */\nexport function keypairSigner(secret: SecretKeyInput): PraxisSigner {\n const bytes = normalizeSecret(secret);\n const pair =\n bytes.length === 64\n ? nacl.sign.keyPair.fromSecretKey(bytes)\n : nacl.sign.keyPair.fromSeed(bytes);\n const address = bs58.encode(pair.publicKey);\n const secretKey = pair.secretKey;\n\n return {\n address,\n signMessage: (message: Uint8Array) => nacl.sign.detached(message, secretKey),\n };\n}\n\nfunction normalizeSecret(secret: SecretKeyInput): Uint8Array {\n let bytes: Uint8Array;\n if (typeof secret === \"string\") {\n try {\n bytes = bs58.decode(secret.trim());\n } catch {\n throw new PraxisConfigError(\"secret key string must be base58-encoded\");\n }\n } else if (Array.isArray(secret)) {\n bytes = Uint8Array.from(secret);\n } else {\n bytes = secret;\n }\n\n if (bytes.length !== 64 && bytes.length !== 32) {\n throw new PraxisConfigError(\n `secret key must be 64 bytes (keypair) or 32 bytes (seed), got ${bytes.length}`,\n );\n }\n return bytes;\n}\n","/**\n * Money helpers. Praxis money crosses the wire as decimal strings of integer\n * base units (lamports / token base units). These convert to/from `bigint` and\n * human decimal amounts without floats.\n */\n\n/** Parse a base-unit string (or bigint) into a bigint. */\nexport function toBaseUnits(value: string | bigint): bigint {\n return typeof value === \"bigint\" ? value : BigInt(value.trim());\n}\n\n/** Serialize a bigint (or number of whole base units) into a base-unit string. */\nexport function fromBaseUnits(value: bigint | number): string {\n return BigInt(value).toString();\n}\n\n/** Convert a human decimal amount (\"0.5\") into base units for `decimals` places. */\nexport function humanToBaseUnits(amount: string, decimals: number): string {\n const trimmed = amount.trim();\n if (!/^\\d+(\\.\\d+)?$/.test(trimmed)) {\n throw new Error(`invalid decimal amount: \"${amount}\"`);\n }\n const [whole, fraction = \"\"] = trimmed.split(\".\");\n if (fraction.length > decimals) {\n throw new Error(`\"${amount}\" has more than ${decimals} decimal places`);\n }\n const padded = fraction.padEnd(decimals, \"0\");\n return (BigInt(whole) * 10n ** BigInt(decimals) + BigInt(padded || \"0\")).toString();\n}\n\n/** Convert base units into a human decimal string for `decimals` places. */\nexport function baseUnitsToHuman(value: string | bigint, decimals: number): string {\n const units = toBaseUnits(value);\n const negative = units < 0n;\n const abs = negative ? -units : units;\n const divisor = 10n ** BigInt(decimals);\n const whole = abs / divisor;\n const fraction = (abs % divisor).toString().padStart(decimals, \"0\").replace(/0+$/, \"\");\n const sign = negative ? \"-\" : \"\";\n return fraction ? `${sign}${whole}.${fraction}` : `${sign}${whole}`;\n}\n","/**\n * Praxis SDK wire types — the JSON contract exposed by `/api/praxis/*`.\n *\n * MONEY RULE: every monetary value crosses the wire as a **decimal string of\n * integer base units** (lamports for SOL, token base units for SPL) — never a\n * float. On the server these are `bigint`; the API serializes them to strings.\n * The SDK keeps them as strings and leaves bigint conversion to the caller\n * (see `toBaseUnits` / `fromBaseUnits` in `units.ts`). This file intentionally\n * mirrors `@praxis/shared` but with `string` money, so the SDK ships a\n * self-contained type contract with no internal workspace dependency.\n */\n\n/** A base58-encoded Solana public key. */\nexport type Address = string;\n\n/** Integer base units as a decimal string (e.g. \"500000000\" = 0.5 SOL). */\nexport type BaseUnitString = string;\n\n/** Mirrors the on-chain `ActionKind` discriminants. */\nexport enum ActionKind {\n Transfer = 0,\n TransferSpl = 1,\n}\n\n/** Why Aegis rejected an agent action. Mirrors the on-chain enum order. */\nexport enum RejectReason {\n Unauthorized = 0,\n Paused = 1,\n Expired = 2,\n OverPerTx = 3,\n OverDaily = 4,\n RecipientNotAllowed = 5,\n Overflow = 6,\n MintNotAllowed = 7,\n}\n\n// --- Auth ------------------------------------------------------------------\n\n/** Returned by `POST /auth/challenge`; sign `message` to prove wallet ownership. */\nexport interface WalletChallenge {\n address: Address;\n /** Opaque signed token echoed back to `/auth/verify`. */\n nonce: string;\n /** The exact UTF-8 string the wallet must sign. */\n message: string;\n /** ISO-8601 expiry of the challenge. */\n expiresAt: string;\n}\n\nexport interface SessionInfo {\n authenticated: boolean;\n walletAddress: Address;\n}\n\n// --- Tokens / address book -------------------------------------------------\n\nexport interface TokenInfo {\n symbol: string;\n mint: Address;\n decimals: number;\n verified: boolean;\n}\n\nexport interface AddressBookEntry {\n label: string;\n name: string;\n address: Address;\n note?: string;\n}\n\n// --- Policy ----------------------------------------------------------------\n\nexport interface PolicyView {\n address: Address;\n owner: Address;\n /** `11111…1111` (default) once the agent key is revoked. */\n agentAuthority: Address;\n maxPerTx: BaseUnitString;\n dailyLimit: BaseUnitString;\n spentToday: BaseUnitString;\n dayStartTs: number;\n allowedPrograms: Address[];\n /** Empty array means \"any recipient allowed\". */\n allowedRecipients: Address[];\n allowedMints: Address[];\n expiryTs: number;\n paused: boolean;\n vaultBalance: BaseUnitString;\n tokenMint: Address;\n tokenMaxPerTx: BaseUnitString;\n tokenDailyLimit: BaseUnitString;\n tokenSpentToday: BaseUnitString;\n tokenDayStartTs: number;\n}\n\nexport interface PolicyCheckResult {\n allowed: boolean;\n reason?: string;\n reasonCode?: RejectReason;\n spentToday: BaseUnitString;\n dailyLimit: BaseUnitString;\n remaining: BaseUnitString;\n}\n\nexport interface PolicyUpdate {\n maxPerTx?: BaseUnitString;\n dailyLimit?: BaseUnitString;\n expiryTs?: number;\n paused?: boolean;\n}\n\nexport interface TokenEnvelopeConfig {\n tokenMint: Address;\n tokenMaxPerTx: BaseUnitString;\n tokenDailyLimit: BaseUnitString;\n}\n\nexport type AllowListKind = \"programs\" | \"recipients\" | \"mints\";\n\n// --- Proposals -------------------------------------------------------------\n\nexport interface TransferDetail {\n kind: \"transfer\";\n amount: BaseUnitString;\n asset: TokenInfo;\n recipientName: string;\n recipientAddress: Address;\n recipientNote?: string;\n}\n\nexport interface SwapDetail {\n kind: \"swap\";\n amountIn: BaseUnitString;\n assetIn: TokenInfo;\n estAmountOut: BaseUnitString;\n assetOut: TokenInfo;\n route: string;\n priceImpactBps: number;\n}\n\nexport type ProposalDetail = TransferDetail | SwapDetail;\n\nexport type ProposalState = \"pending\" | \"signing\" | \"signed\" | \"blocked\" | \"cancelled\";\n\nexport interface ActionProposal {\n id: string;\n detail: ProposalDetail;\n networkFee: BaseUnitString;\n simulation: string;\n check: PolicyCheckResult;\n state: ProposalState;\n sig?: string;\n}\n\n// --- Conversation ----------------------------------------------------------\n\nexport interface ClarifyOption {\n label: string;\n value: string;\n hint?: string;\n}\n\nexport interface ResearchMetric {\n label: string;\n value: string;\n trend?: \"up\" | \"down\" | \"flat\";\n}\n\nexport interface ResearchData {\n token: string;\n mint: Address;\n metrics: ResearchMetric[];\n summary: string;\n}\n\nexport type AgentBlock =\n | { type: \"prose\"; text: string }\n | { type: \"clarify\"; text: string; options: ClarifyOption[] }\n | { type: \"proposal\"; text: string; proposalId: string }\n | { type: \"research\"; text: string; data: ResearchData };\n\nexport type UserMessage = { id: string; role: \"user\"; ts: number; text: string };\nexport type AgentMessage = { id: string; role: \"agent\"; ts: number; blocks: AgentBlock[] };\nexport type Message = UserMessage | AgentMessage;\n\nexport interface Thread {\n id: string;\n title: string;\n messages: Message[];\n updatedAt: number;\n}\n\n// --- Activity --------------------------------------------------------------\n\nexport interface ActivityEntry {\n id: string;\n kind: \"transfer\" | \"swap\";\n label: string;\n asset: string;\n amount: BaseUnitString;\n decimals: number;\n result: \"allowed\" | \"rejected\";\n reason?: string;\n reasonCode?: RejectReason;\n ts: number;\n sig?: string;\n}\n\n// --- Owner transactions (wallet-signed path) -------------------------------\n\nexport interface UnsignedOwnerTransaction {\n /** base64-encoded unsigned transaction for the owner wallet to sign. */\n transaction: string;\n blockhash: string;\n lastValidBlockHeight: number;\n}\n\n/** Typed owner action accepted by `POST /owner/build`. */\nexport type OwnerAction =\n | { kind: \"bootstrapPolicy\"; fundLamports?: BaseUnitString }\n | { kind: \"fundVault\"; amount: BaseUnitString }\n | { kind: \"withdrawVault\"; amount: BaseUnitString }\n | { kind: \"closePolicy\" }\n | { kind: \"revoke\" }\n | { kind: \"rotate\" }\n | { kind: \"updatePolicy\"; patch: PolicyUpdate }\n | { kind: \"allowList\"; listKind: AllowListKind; address: Address; mode: \"add\" | \"remove\" };\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/signer.ts","../src/units.ts","../src/types.ts"],"names":["bs58","ActionKind","RejectReason"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Thrown when the Praxis API returns a non-2xx response. The backend's error\n * envelope is `{ error: string, type: string }` with a meaningful HTTP status\n * (400 input, 401 auth, 404 not-found, 429 rate-limit, 503 config, 500 other).\n */\nexport class PraxisApiError extends Error {\n readonly status: number;\n /** The backend error class name, e.g. \"PraxisAuthError\", \"PraxisRateLimitError\". */\n readonly type: string;\n\n constructor(status: number, type: string, message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = \"PraxisApiError\";\n this.status = status;\n this.type = type;\n // Restore prototype chain for instanceof across transpile targets.\n Object.setPrototypeOf(this, PraxisApiError.prototype);\n }\n\n get isAuth(): boolean {\n return this.status === 401;\n }\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n get isInput(): boolean {\n return this.status === 400;\n }\n /** Resource not found (404). */\n get isNotFound(): boolean {\n return this.status === 404;\n }\n /** Server reported a configuration problem (503) — usually transient. */\n get isConfig(): boolean {\n return this.status === 503;\n }\n /** The request timed out client-side before any HTTP response. */\n get isTimeout(): boolean {\n return this.status === 0 && this.type === \"TimeoutError\";\n }\n /** A connection-level failure (DNS, refused, TLS) before any HTTP response. */\n get isNetwork(): boolean {\n return this.status === 0 && this.type === \"NetworkError\";\n }\n /** Any server-side failure (HTTP >= 500). */\n get isServer(): boolean {\n return this.status >= 500;\n }\n}\n\n/** Thrown for SDK-side misconfiguration (no fetch, no signer, bad key, …). */\nexport class PraxisConfigError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = \"PraxisConfigError\";\n Object.setPrototypeOf(this, PraxisConfigError.prototype);\n }\n}\n","import bs58 from \"bs58\";\n\nimport { PraxisApiError, PraxisConfigError } from \"./errors\";\nimport type { PraxisSigner } from \"./signer\";\nimport type {\n ActionProposal,\n ActivityEntry,\n AddressBookEntry,\n AgentMessage,\n AllowListKind,\n BaseUnitString,\n OwnerAction,\n PolicyUpdate,\n PolicyView,\n SessionInfo,\n SignedOwnerTransaction,\n Thread,\n TokenEnvelopeConfig,\n UnsignedOwnerTransaction,\n WalletChallenge,\n} from \"./types\";\n\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;\n\nexport interface PraxisClientOptions {\n /** Base origin of the Praxis deployment, e.g. \"http://localhost:3000\". */\n baseUrl: string;\n /** Wallet signer for `connect()`. Optional if you only call public reads after an external login. */\n signer?: PraxisSigner;\n /** Custom fetch (defaults to global fetch). Required in runtimes without one. */\n fetch?: FetchLike;\n /** Per-request timeout in ms for reads/mutations (default 20_000). */\n timeoutMs?: number;\n /**\n * Per-request timeout in ms for agent conversation turns (`send`/`ask`), which\n * block on the full LLM round-trip (default 60_000). Effective value is never\n * below `timeoutMs`.\n */\n agentTimeoutMs?: number;\n}\n\n/** Result of {@link PraxisClient.ask} — the agent's reply, distilled. */\nexport interface AskResult {\n threadId: string;\n /** The agent's reply message (prose / clarify / proposal / research blocks). */\n message: AgentMessage;\n /** Any action proposals the agent produced, hydrated for convenience. */\n proposals: ActionProposal[];\n}\n\nconst API_PREFIX = \"/api/praxis\";\n\n/**\n * Typed client for a hosted Praxis agent. The agent's LLM, scoped agent key, and\n * Aegis policy enforcement all live server-side; this SDK is an authenticated\n * client of the `/api/praxis/*` surface.\n *\n * ```ts\n * const praxis = new PraxisClient({ baseUrl, signer: keypairSigner(secret) });\n * await praxis.connect();\n * const { proposals } = await praxis.ask(\"send 0.5 SOL to maya\");\n * if (proposals[0]?.check.allowed) await praxis.signProposal(proposals[0].id);\n * ```\n */\nexport class PraxisClient {\n private readonly baseUrl: string;\n private readonly signer?: PraxisSigner;\n private readonly fetchImpl: FetchLike;\n private readonly timeoutMs: number;\n private readonly agentTimeoutMs: number;\n /** Manual cookie jar — Node's fetch does not persist Set-Cookie across calls. */\n private sessionCookie?: string;\n\n constructor(options: PraxisClientOptions) {\n if (!options.baseUrl) throw new PraxisConfigError(\"baseUrl is required\");\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.signer = options.signer;\n const resolvedFetch = options.fetch ?? (globalThis.fetch as FetchLike | undefined);\n if (!resolvedFetch) {\n throw new PraxisConfigError(\"No fetch available; pass options.fetch (Node <18 or non-browser runtime).\");\n }\n this.fetchImpl = resolvedFetch;\n this.timeoutMs = options.timeoutMs ?? 20_000;\n this.agentTimeoutMs = Math.max(options.agentTimeoutMs ?? 60_000, this.timeoutMs);\n }\n\n // --- auth ----------------------------------------------------------------\n\n /** The signer's wallet address, if a signer was provided. */\n get address(): string | undefined {\n return this.signer?.address;\n }\n\n /**\n * Run the wallet-ownership handshake: request a challenge, sign its message,\n * verify it, and store the resulting session cookie. Safe to call again to\n * refresh the session (each call issues a new challenge + cookie).\n */\n async connect(): Promise<SessionInfo> {\n if (!this.signer) {\n throw new PraxisConfigError(\"connect() requires a signer. Pass one to the constructor.\");\n }\n const challenge = await this.post<WalletChallenge>(\"/auth/challenge\", {\n address: this.signer.address,\n });\n const signature = await this.signer.signMessage(new TextEncoder().encode(challenge.message));\n return this.post<SessionInfo>(\"/auth/verify\", {\n address: this.signer.address,\n nonce: challenge.nonce,\n signature: bs58.encode(signature),\n });\n }\n\n /**\n * Current session, or `null` if not signed in. The endpoint answers `200`\n * with `{ authenticated: false }` when signed out, so this normalizes both\n * that shape and a `401` to `null`.\n */\n async session(): Promise<SessionInfo | null> {\n try {\n const info = await this.get<SessionInfo>(\"/auth/session\");\n return info && info.authenticated ? info : null;\n } catch (error) {\n if (error instanceof PraxisApiError && error.isAuth) return null;\n throw error;\n }\n }\n\n /**\n * Clear the session (server-side cookie + local jar). Idempotent: if there is\n * no active session, the local jar is still cleared and no error is thrown.\n */\n async logout(): Promise<void> {\n try {\n await this.request<unknown>(\"DELETE\", \"/auth/session\");\n } catch (error) {\n // Already signed out (missing / expired session) is a successful logout.\n if (!(error instanceof PraxisApiError && error.isAuth)) throw error;\n } finally {\n this.sessionCookie = undefined;\n }\n }\n\n // --- conversation --------------------------------------------------------\n\n /** Send a line to the agent. Creates a thread when `threadId` is omitted. */\n send(text: string, threadId: string | null = null): Promise<{ threadId: string }> {\n // Conversation turns block on the agent's LLM round-trip — give them the\n // longer agent budget rather than the shorter read/mutation timeout.\n return this.post<{ threadId: string }>(\"/send\", { text, threadId }, this.agentTimeoutMs);\n }\n\n /**\n * Send a line and return the agent's reply in one call. The API resolves\n * `send` only after the agent has finished, so this needs no polling.\n */\n async ask(text: string, threadId: string | null = null): Promise<AskResult> {\n const { threadId: tid } = await this.send(text, threadId);\n const thread = await this.getThread(tid);\n const message = lastAgentMessage(thread);\n if (!message) {\n throw new PraxisApiError(500, \"Error\", \"Agent produced no reply message.\");\n }\n const proposalIds = message.blocks\n .filter((b): b is Extract<typeof b, { type: \"proposal\" }> => b.type === \"proposal\")\n .map((b) => b.proposalId);\n const proposals = await Promise.all(proposalIds.map((id) => this.getProposal(id)));\n return { threadId: tid, message, proposals };\n }\n\n newThread(threadId?: string): Promise<{ threadId: string }> {\n return this.post<{ threadId: string }>(\"/new-thread\", threadId ? { threadId } : {});\n }\n\n signProposal(proposalId: string): Promise<void> {\n return this.post<void>(\"/sign-proposal\", { proposalId });\n }\n\n cancelProposal(proposalId: string): Promise<void> {\n return this.post<void>(\"/cancel-proposal\", { proposalId });\n }\n\n // --- reads ---------------------------------------------------------------\n\n getThreads(): Promise<Thread[]> {\n return this.get<Thread[]>(\"/get-threads\");\n }\n getThread(id: string): Promise<Thread> {\n return this.get<Thread>(\"/get-thread\", { id });\n }\n getProposal(id: string): Promise<ActionProposal> {\n return this.get<ActionProposal>(\"/get-proposal\", { id });\n }\n getPolicy(): Promise<PolicyView> {\n return this.get<PolicyView>(\"/get-policy\");\n }\n getActivity(): Promise<ActivityEntry[]> {\n return this.get<ActivityEntry[]>(\"/get-activity\");\n }\n getAddressBook(): Promise<AddressBookEntry[]> {\n return this.get<AddressBookEntry[]>(\"/get-address-book\");\n }\n isThinking(threadId: string): Promise<boolean> {\n return this.get<boolean>(\"/is-thinking\", { threadId });\n }\n getVersion(): Promise<number> {\n return this.get<number>(\"/get-version\");\n }\n\n // --- policy / owner mutations (server-key mode) --------------------------\n\n bootstrapPolicy(fundLamports?: BaseUnitString): Promise<void> {\n return this.post<void>(\"/bootstrap-policy\", fundLamports ? { fundLamports } : {});\n }\n /** Deposit SOL (lamports, base-unit string) from the owner into the vault. */\n fundVault(amount: BaseUnitString): Promise<void> {\n return this.post<void>(\"/fund-vault\", { amount });\n }\n /** Withdraw SOL (lamports, base-unit string) from the vault to the owner. */\n withdrawVault(amount: BaseUnitString): Promise<void> {\n return this.post<void>(\"/withdraw-vault\", { amount });\n }\n /** Tear the agent down — drain the vault and close the policy. Irreversible. */\n deleteAgent(): Promise<void> {\n return this.post<void>(\"/delete-agent\", {});\n }\n updatePolicy(patch: PolicyUpdate): Promise<void> {\n return this.post<void>(\"/update-policy\", { patch });\n }\n configureToken(config: TokenEnvelopeConfig): Promise<void> {\n return this.post<void>(\"/configure-token\", { config });\n }\n prepareTokenAccounts(recipientAddresses?: string[]): Promise<void> {\n return this.post<void>(\"/prepare-token-accounts\", recipientAddresses ? { recipientAddresses } : {});\n }\n revokeAgent(): Promise<void> {\n return this.post<void>(\"/revoke-agent\", {});\n }\n rotateAgent(): Promise<void> {\n return this.post<void>(\"/rotate-agent\", {});\n }\n addToAllowList(kind: AllowListKind, address: string): Promise<void> {\n return this.post<void>(\"/add-to-allow-list\", { kind, address });\n }\n removeFromAllowList(kind: AllowListKind, address: string): Promise<void> {\n return this.post<void>(\"/remove-from-allow-list\", { kind, address });\n }\n\n // --- owner wallet-signed transaction path --------------------------------\n\n /**\n * Build an unsigned owner transaction for the wallet to sign. The caller signs\n * the returned base64 `transaction` with a transaction-capable wallet, then\n * passes the result to {@link submitOwnerTransaction}. (The SDK's\n * `keypairSigner` signs sign-in messages only, not transactions.)\n */\n buildOwnerTransaction(action: OwnerAction): Promise<UnsignedOwnerTransaction> {\n return this.post<UnsignedOwnerTransaction>(\"/owner/build\", { action });\n }\n /** Submit a wallet-signed owner transaction; resolves with its signature. */\n submitOwnerTransaction(signed: SignedOwnerTransaction): Promise<{ sig: string }> {\n return this.post<{ sig: string }>(\"/owner/submit\", signed);\n }\n\n // --- transport -----------------------------------------------------------\n\n private get<T>(path: string, query?: Record<string, string>): Promise<T> {\n return this.request<T>(\"GET\", path, { query });\n }\n\n private post<T>(path: string, body: unknown, timeoutMs?: number): Promise<T> {\n return this.request<T>(\"POST\", path, { body, timeoutMs });\n }\n\n private async request<T>(\n method: string,\n path: string,\n opts: { body?: unknown; query?: Record<string, string>; timeoutMs?: number } = {},\n ): Promise<T> {\n const url = new URL(this.baseUrl + API_PREFIX + path);\n for (const [k, v] of Object.entries(opts.query ?? {})) url.searchParams.set(k, v);\n\n const headers: Record<string, string> = { accept: \"application/json\" };\n if (opts.body !== undefined) headers[\"content-type\"] = \"application/json\";\n if (this.sessionCookie) headers[\"cookie\"] = this.sessionCookie;\n\n const timeoutMs = opts.timeoutMs ?? this.timeoutMs;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n let res: Response;\n try {\n res = await this.fetchImpl(url.toString(), {\n method,\n headers,\n body: opts.body === undefined ? undefined : JSON.stringify(opts.body),\n // Browser same-origin: let the HttpOnly cookie ride along.\n credentials: \"include\",\n signal: controller.signal,\n } as RequestInit);\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new PraxisApiError(0, \"TimeoutError\", `Praxis request timed out after ${timeoutMs}ms`, {\n cause: error,\n });\n }\n if (error instanceof PraxisApiError) throw error;\n // Connection-level failures (DNS, ECONNREFUSED, TLS) surface uniformly as\n // a PraxisApiError so callers have a single error type to catch.\n const detail = error instanceof Error ? error.message : String(error);\n throw new PraxisApiError(0, \"NetworkError\", `Praxis request failed: ${detail}`, { cause: error });\n } finally {\n clearTimeout(timer);\n }\n\n this.captureCookie(res);\n\n const text = await res.text();\n const parsed = text ? safeJsonParse(text) : undefined;\n\n if (!res.ok) {\n const message =\n (parsed && typeof parsed === \"object\" && \"error\" in parsed && typeof parsed.error === \"string\"\n ? parsed.error\n : undefined) ?? `Praxis API error ${res.status}`;\n const type =\n parsed && typeof parsed === \"object\" && \"type\" in parsed && typeof parsed.type === \"string\"\n ? parsed.type\n : \"Error\";\n throw new PraxisApiError(res.status, type, message);\n }\n\n return parsed as T;\n }\n\n private captureCookie(res: Response): void {\n // Node 18.14+ exposes getSetCookie(); fall back to the combined header.\n const anyHeaders = res.headers as Headers & { getSetCookie?: () => string[] };\n const cookies = anyHeaders.getSetCookie?.() ?? splitSetCookie(res.headers.get(\"set-cookie\"));\n for (const cookie of cookies) {\n const [pair] = cookie.split(\";\");\n if (pair && pair.trim().startsWith(\"praxis_session=\")) {\n this.sessionCookie = pair.trim();\n }\n }\n }\n}\n\nfunction lastAgentMessage(thread: Thread): AgentMessage | undefined {\n for (let i = thread.messages.length - 1; i >= 0; i--) {\n const m = thread.messages[i];\n if (m.role === \"agent\") return m;\n }\n return undefined;\n}\n\nfunction safeJsonParse(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction splitSetCookie(header: string | null): string[] {\n if (!header) return [];\n // Split on commas that precede a new cookie name=value pair, not commas inside\n // Expires dates (\"Wed, 01 Jan ...\").\n return header.split(/,(?=\\s*[^;,\\s]+=)/);\n}\n","import bs58 from \"bs58\";\nimport nacl from \"tweetnacl\";\n\nimport { PraxisConfigError } from \"./errors\";\n\n/**\n * Signs the wallet-ownership challenge. Implement this to bridge any wallet:\n * - Node / backend agents: use {@link keypairSigner} with a secret key.\n * - Browser: wrap a wallet-adapter, e.g.\n * `{ address: wallet.publicKey.toBase58(), signMessage: (m) => wallet.signMessage(m) }`.\n *\n * `signMessage` must return the raw 64-byte Ed25519 signature; the SDK base58-\n * encodes it for the API.\n */\nexport interface PraxisSigner {\n /** base58-encoded Solana public key. */\n readonly address: string;\n signMessage(message: Uint8Array): Promise<Uint8Array> | Uint8Array;\n}\n\nexport type SecretKeyInput = Uint8Array | number[] | string;\n\n/**\n * Build a {@link PraxisSigner} from a Solana secret key — a 64-byte keypair or a\n * 32-byte seed, as raw bytes, a number array, or a base58 string (Phantom /\n * `solana-keygen` export). Node and browser friendly; no `@solana/web3.js`\n * dependency.\n */\nexport function keypairSigner(secret: SecretKeyInput): PraxisSigner {\n const bytes = normalizeSecret(secret);\n const pair =\n bytes.length === 64\n ? nacl.sign.keyPair.fromSecretKey(bytes)\n : nacl.sign.keyPair.fromSeed(bytes);\n const address = bs58.encode(pair.publicKey);\n const secretKey = pair.secretKey;\n\n return {\n address,\n signMessage: (message: Uint8Array) => nacl.sign.detached(message, secretKey),\n };\n}\n\nfunction normalizeSecret(secret: SecretKeyInput): Uint8Array {\n let bytes: Uint8Array;\n if (typeof secret === \"string\") {\n try {\n bytes = bs58.decode(secret.trim());\n } catch {\n throw new PraxisConfigError(\"secret key string must be base58-encoded\");\n }\n } else if (Array.isArray(secret)) {\n if (!secret.every((b) => Number.isInteger(b) && b >= 0 && b <= 255)) {\n throw new PraxisConfigError(\"secret key array must contain only byte values (integers 0–255)\");\n }\n bytes = Uint8Array.from(secret);\n } else {\n bytes = secret;\n }\n\n if (bytes.length !== 64 && bytes.length !== 32) {\n throw new PraxisConfigError(\n `secret key must be 64 bytes (keypair) or 32 bytes (seed), got ${bytes.length}`,\n );\n }\n return bytes;\n}\n","/**\n * Money helpers. Praxis money crosses the wire as decimal strings of integer\n * base units (lamports / token base units). These convert to/from `bigint` and\n * human decimal amounts without floats.\n */\n\n/** An optionally-signed decimal integer — the only valid base-unit string. */\nconst INTEGER_RE = /^-?\\d+$/;\n\n/**\n * Parse a base-unit string (or bigint) into a bigint. Rejects floats, hex, and\n * other non-decimal-integer input so the SDK and server agree on what a valid\n * base-unit string is (mirrors the server's `parseUnits`).\n */\nexport function toBaseUnits(value: string | bigint): bigint {\n if (typeof value === \"bigint\") return value;\n const trimmed = value.trim();\n if (!INTEGER_RE.test(trimmed)) {\n throw new Error(`toBaseUnits: expected an integer base-unit string, got \"${value}\"`);\n }\n return BigInt(trimmed);\n}\n\n/**\n * Serialize a bigint (or a whole, safe-integer number of base units) into a\n * base-unit string. A non-integer or unsafe `number` throws rather than\n * silently losing precision.\n */\nexport function fromBaseUnits(value: bigint | number): string {\n if (typeof value === \"number\" && !Number.isSafeInteger(value)) {\n throw new Error(`fromBaseUnits: number must be a safe integer, got ${value}`);\n }\n return BigInt(value).toString();\n}\n\n/** Convert a human decimal amount (\"0.5\") into base units for `decimals` places. */\nexport function humanToBaseUnits(amount: string, decimals: number): string {\n const trimmed = amount.trim();\n if (!/^\\d+(\\.\\d+)?$/.test(trimmed)) {\n throw new Error(`invalid decimal amount: \"${amount}\"`);\n }\n const [whole, fraction = \"\"] = trimmed.split(\".\");\n if (fraction.length > decimals) {\n throw new Error(`\"${amount}\" has more than ${decimals} decimal places`);\n }\n const padded = fraction.padEnd(decimals, \"0\");\n return (BigInt(whole) * 10n ** BigInt(decimals) + BigInt(padded || \"0\")).toString();\n}\n\n/** Convert base units into a human decimal string for `decimals` places. */\nexport function baseUnitsToHuman(value: string | bigint, decimals: number): string {\n const units = toBaseUnits(value);\n const negative = units < 0n;\n const abs = negative ? -units : units;\n const divisor = 10n ** BigInt(decimals);\n const whole = abs / divisor;\n const fraction = (abs % divisor).toString().padStart(decimals, \"0\").replace(/0+$/, \"\");\n const sign = negative ? \"-\" : \"\";\n return fraction ? `${sign}${whole}.${fraction}` : `${sign}${whole}`;\n}\n","/**\n * Praxis SDK wire types — the JSON contract exposed by `/api/praxis/*`.\n *\n * MONEY RULE: every monetary value crosses the wire as a **decimal string of\n * integer base units** (lamports for SOL, token base units for SPL) — never a\n * float. On the server these are `bigint`; the API serializes them to strings.\n * The SDK keeps them as strings and leaves bigint conversion to the caller\n * (see `toBaseUnits` / `fromBaseUnits` in `units.ts`). This file intentionally\n * mirrors `@praxis/shared` but with `string` money, so the SDK ships a\n * self-contained type contract with no internal workspace dependency.\n */\n\n/** A base58-encoded Solana public key. */\nexport type Address = string;\n\n/** Integer base units as a decimal string (e.g. \"500000000\" = 0.5 SOL). */\nexport type BaseUnitString = string;\n\n/** Mirrors the on-chain `ActionKind` discriminants. */\nexport enum ActionKind {\n Transfer = 0,\n TransferSpl = 1,\n}\n\n/** Why Aegis rejected an agent action. Mirrors the on-chain enum order. */\nexport enum RejectReason {\n Unauthorized = 0,\n Paused = 1,\n Expired = 2,\n OverPerTx = 3,\n OverDaily = 4,\n RecipientNotAllowed = 5,\n Overflow = 6,\n MintNotAllowed = 7,\n}\n\n// --- Auth ------------------------------------------------------------------\n\n/** Returned by `POST /auth/challenge`; sign `message` to prove wallet ownership. */\nexport interface WalletChallenge {\n address: Address;\n /** Opaque signed token echoed back to `/auth/verify`. */\n nonce: string;\n /** The exact UTF-8 string the wallet must sign. */\n message: string;\n /** ISO-8601 expiry of the challenge. */\n expiresAt: string;\n}\n\nexport interface SessionInfo {\n authenticated: boolean;\n /** The signed-in wallet (owner). Present whenever `authenticated` is true. */\n walletAddress: Address;\n /** Unix seconds at which the session expires (from `GET /auth/session`). */\n expiresAt?: number;\n}\n\n// --- Tokens / address book -------------------------------------------------\n\nexport interface TokenInfo {\n symbol: string;\n mint: Address;\n decimals: number;\n verified: boolean;\n}\n\nexport interface AddressBookEntry {\n label: string;\n name: string;\n address: Address;\n note?: string;\n}\n\n// --- Policy ----------------------------------------------------------------\n\nexport interface PolicyView {\n address: Address;\n owner: Address;\n /** `11111…1111` (default) once the agent key is revoked. */\n agentAuthority: Address;\n maxPerTx: BaseUnitString;\n dailyLimit: BaseUnitString;\n spentToday: BaseUnitString;\n dayStartTs: number;\n allowedPrograms: Address[];\n /** Empty array means \"any recipient allowed\". */\n allowedRecipients: Address[];\n allowedMints: Address[];\n expiryTs: number;\n paused: boolean;\n vaultBalance: BaseUnitString;\n tokenMint: Address;\n tokenMaxPerTx: BaseUnitString;\n tokenDailyLimit: BaseUnitString;\n tokenSpentToday: BaseUnitString;\n tokenDayStartTs: number;\n}\n\nexport interface PolicyCheckResult {\n allowed: boolean;\n reason?: string;\n reasonCode?: RejectReason;\n spentToday: BaseUnitString;\n dailyLimit: BaseUnitString;\n remaining: BaseUnitString;\n}\n\nexport interface PolicyUpdate {\n maxPerTx?: BaseUnitString;\n dailyLimit?: BaseUnitString;\n expiryTs?: number;\n paused?: boolean;\n}\n\nexport interface TokenEnvelopeConfig {\n tokenMint: Address;\n tokenMaxPerTx: BaseUnitString;\n tokenDailyLimit: BaseUnitString;\n}\n\nexport type AllowListKind = \"programs\" | \"recipients\" | \"mints\";\n\n// --- Proposals -------------------------------------------------------------\n\nexport interface TransferDetail {\n kind: \"transfer\";\n amount: BaseUnitString;\n asset: TokenInfo;\n recipientName: string;\n recipientAddress: Address;\n recipientNote?: string;\n}\n\nexport interface SwapDetail {\n kind: \"swap\";\n amountIn: BaseUnitString;\n assetIn: TokenInfo;\n estAmountOut: BaseUnitString;\n assetOut: TokenInfo;\n route: string;\n priceImpactBps: number;\n}\n\nexport type ProposalDetail = TransferDetail | SwapDetail;\n\nexport type ProposalState = \"pending\" | \"signing\" | \"signed\" | \"blocked\" | \"cancelled\";\n\nexport interface ActionProposal {\n id: string;\n detail: ProposalDetail;\n networkFee: BaseUnitString;\n simulation: string;\n check: PolicyCheckResult;\n state: ProposalState;\n sig?: string;\n}\n\n// --- Conversation ----------------------------------------------------------\n\nexport interface ClarifyOption {\n label: string;\n value: string;\n hint?: string;\n}\n\nexport interface ResearchMetric {\n label: string;\n value: string;\n trend?: \"up\" | \"down\" | \"flat\";\n}\n\nexport interface ResearchData {\n token: string;\n mint: Address;\n metrics: ResearchMetric[];\n summary: string;\n}\n\nexport interface PolicyChangeRow {\n label: string;\n from: string;\n to: string;\n}\n\nexport type AgentBlock =\n | { type: \"prose\"; text: string }\n | { type: \"clarify\"; text: string; options: ClarifyOption[] }\n | { type: \"proposal\"; text: string; proposalId: string }\n | { type: \"research\"; text: string; data: ResearchData }\n | { type: \"notice\"; tone: \"success\" | \"info\"; text: string }\n | {\n type: \"policy_change\";\n text: string;\n patch: PolicyUpdate;\n changes: PolicyChangeRow[];\n applied: boolean;\n };\n\nexport type UserMessage = { id: string; role: \"user\"; ts: number; text: string };\nexport type AgentMessage = { id: string; role: \"agent\"; ts: number; blocks: AgentBlock[] };\nexport type Message = UserMessage | AgentMessage;\n\nexport interface Thread {\n id: string;\n title: string;\n messages: Message[];\n updatedAt: number;\n}\n\n// --- Activity --------------------------------------------------------------\n\nexport interface ActivityEntry {\n id: string;\n kind: \"transfer\" | \"swap\";\n label: string;\n asset: string;\n amount: BaseUnitString;\n decimals: number;\n result: \"allowed\" | \"rejected\";\n reason?: string;\n reasonCode?: RejectReason;\n ts: number;\n sig?: string;\n}\n\n// --- Owner transactions (wallet-signed path) -------------------------------\n\nexport interface UnsignedOwnerTransaction {\n /** base64-encoded unsigned transaction for the owner wallet to sign. */\n transaction: string;\n blockhash: string;\n lastValidBlockHeight: number;\n}\n\n/**\n * An {@link UnsignedOwnerTransaction} after the owner wallet has signed it — the\n * base64 `transaction` now carries the owner's signature. This is what you pass\n * to {@link PraxisClient.submitOwnerTransaction}. Signing a Solana transaction\n * requires a transaction-capable wallet (browser wallet adapter / `@solana/web3.js`);\n * the SDK's `keypairSigner` only signs the sign-in *message*, not transactions.\n */\nexport type SignedOwnerTransaction = UnsignedOwnerTransaction;\n\n/** Typed owner action accepted by `POST /owner/build`. */\nexport type OwnerAction =\n | { kind: \"bootstrapPolicy\"; fundLamports?: BaseUnitString }\n | { kind: \"fundVault\"; amount: BaseUnitString }\n | { kind: \"withdrawVault\"; amount: BaseUnitString }\n | { kind: \"closePolicy\" }\n | { kind: \"revoke\" }\n | { kind: \"rotate\" }\n | { kind: \"updatePolicy\"; patch: PolicyUpdate }\n | { kind: \"allowList\"; listKind: AllowListKind; address: Address; mode: \"add\" | \"remove\" };\n"]}
package/package.json CHANGED
@@ -1,8 +1,18 @@
1
1
  {
2
2
  "name": "@usepraxis/sdk",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Typed client SDK for a hosted Praxis agent — natural-language Solana actions enforced on-chain by Aegis.",
5
5
  "license": "MIT",
6
+ "author": "Praxis",
7
+ "homepage": "https://github.com/user-64bit/Praxis/tree/main/sdk#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/user-64bit/Praxis.git",
11
+ "directory": "sdk"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/user-64bit/Praxis/issues"
15
+ },
6
16
  "type": "module",
7
17
  "main": "./dist/index.cjs",
8
18
  "module": "./dist/index.js",
@@ -11,8 +21,10 @@
11
21
  ".": {
12
22
  "types": "./dist/index.d.ts",
13
23
  "import": "./dist/index.js",
14
- "require": "./dist/index.cjs"
15
- }
24
+ "require": "./dist/index.cjs",
25
+ "default": "./dist/index.js"
26
+ },
27
+ "./package.json": "./package.json"
16
28
  },
17
29
  "files": [
18
30
  "dist",