@aithos/sdk 0.1.0-alpha.4 → 0.1.0-alpha.5

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.
Files changed (42) hide show
  1. package/dist/src/auth.d.ts +94 -136
  2. package/dist/src/auth.js +440 -159
  3. package/dist/src/compute.d.ts +8 -6
  4. package/dist/src/compute.js +19 -11
  5. package/dist/src/ethos.d.ts +117 -1
  6. package/dist/src/ethos.js +417 -16
  7. package/dist/src/index.d.ts +7 -4
  8. package/dist/src/index.js +17 -5
  9. package/dist/src/internal/delegate-bundle.d.ts +18 -0
  10. package/dist/src/internal/delegate-bundle.js +89 -0
  11. package/dist/src/internal/delegate-state.d.ts +45 -0
  12. package/dist/src/internal/delegate-state.js +120 -0
  13. package/dist/src/internal/owner-signers.d.ts +78 -0
  14. package/dist/src/internal/owner-signers.js +179 -0
  15. package/dist/src/internal/protocol-client-bridge.d.ts +8 -0
  16. package/dist/src/internal/protocol-client-bridge.js +20 -0
  17. package/dist/src/internal/recovery-file.d.ts +29 -0
  18. package/dist/src/internal/recovery-file.js +98 -0
  19. package/dist/src/internal/signer.d.ts +59 -0
  20. package/dist/src/internal/signer.js +86 -0
  21. package/dist/src/key-store.d.ts +128 -0
  22. package/dist/src/key-store.js +244 -0
  23. package/dist/src/mandates.d.ts +88 -1
  24. package/dist/src/mandates.js +185 -8
  25. package/dist/src/sdk.d.ts +36 -3
  26. package/dist/src/sdk.js +27 -23
  27. package/dist/src/wallet.d.ts +4 -6
  28. package/dist/src/wallet.js +18 -8
  29. package/dist/test/auth-j3.test.d.ts +2 -0
  30. package/dist/test/auth-j3.test.js +360 -0
  31. package/dist/test/compute.test.js +22 -11
  32. package/dist/test/ethos.test.d.ts +2 -0
  33. package/dist/test/ethos.test.js +219 -0
  34. package/dist/test/key-store.test.d.ts +2 -0
  35. package/dist/test/key-store.test.js +161 -0
  36. package/dist/test/mandates.test.d.ts +2 -0
  37. package/dist/test/mandates.test.js +93 -0
  38. package/dist/test/sdk.test.js +64 -30
  39. package/dist/test/signer.test.d.ts +2 -0
  40. package/dist/test/signer.test.js +117 -0
  41. package/dist/test/wallet.test.js +20 -9
  42. package/package.json +2 -1
@@ -1,2 +1,89 @@
1
- export { mintDelegateBundle, signAndPublishMandate, MintError, type MintArgs, type MintResult, type SignAndPublishMandateArgs, DEFAULT_READ_SCOPES, TTL_PRESETS, } from "@aithos/protocol-client";
1
+ import type { AithosAuth } from "./auth.js";
2
+ import type { AithosSdkEndpoints } from "./endpoints.js";
3
+ /** Capability scope the SDK accepts. Server-side ultimately decides. */
4
+ export type Scope = "ethos.read.public" | "ethos.read.circle" | "ethos.read.self" | "ethos.write.public" | "ethos.write.circle" | "ethos.write.self";
5
+ /**
6
+ * Which sphere of the owner signs the mandate. Bounds the upper-most
7
+ * scope set the mandate can carry.
8
+ */
9
+ export type ActorSphere = "public" | "circle" | "self";
10
+ export interface CreateMandateInput {
11
+ /** Grantee URN — usually `urn:aithos:agent:<extension-id>` or similar. */
12
+ readonly granteeId: string;
13
+ /** Optional human-readable label for the grantee. */
14
+ readonly granteeLabel?: string;
15
+ /**
16
+ * Sphere of the owner that issues the mandate. Defaults to the
17
+ * highest-numbered sphere covered by `scopes` (most permissive
18
+ * common ancestor): `"self"` if any scope ends in `.self`, else
19
+ * `"circle"` if any ends in `.circle`, else `"public"`.
20
+ */
21
+ readonly actorSphere?: ActorSphere;
22
+ /** Capability set granted by the mandate. */
23
+ readonly scopes: readonly Scope[];
24
+ /** Lifetime in seconds. */
25
+ readonly ttlSeconds: number;
26
+ }
27
+ export interface MintedMandate {
28
+ /** Unique mandate id (matches `mandate.id` inside the bundle). */
29
+ readonly mandateId: string;
30
+ /** Subject DID — the owner who issued it. */
31
+ readonly subjectDid: string;
32
+ /** Grantee URN. */
33
+ readonly granteeId: string;
34
+ readonly scopes: readonly Scope[];
35
+ /** ISO-8601 (UTC) — `null` if the mandate has no `not_after`. */
36
+ readonly expiresAt: string | null;
37
+ /** Shareable `.aithos-delegate.json` Blob. Hand this to the grantee. */
38
+ readonly bundle: Blob;
39
+ /** Suggested filename for the bundle. */
40
+ readonly filename: string;
41
+ }
42
+ export interface OwnedMandate {
43
+ readonly mandateId: string;
44
+ readonly issuerDid: string;
45
+ readonly actorDid: string;
46
+ readonly scopes: readonly Scope[];
47
+ readonly notBefore: number | null;
48
+ readonly notAfter: number | null;
49
+ readonly createdAt: number;
50
+ }
51
+ export interface MandatesNamespaceDeps {
52
+ readonly auth: AithosAuth;
53
+ readonly endpoints: AithosSdkEndpoints;
54
+ readonly fetch: typeof fetch;
55
+ }
56
+ export declare class MandatesNamespace {
57
+ #private;
58
+ constructor(deps: MandatesNamespaceDeps);
59
+ /**
60
+ * Mint, sign, publish, and package a fresh delegate bundle. The
61
+ * grantee's keypair is generated inside this call and never
62
+ * persisted on the owner's machine — the seed flows out via the
63
+ * returned Blob and only via that Blob.
64
+ */
65
+ create(input: CreateMandateInput): Promise<MintedMandate>;
66
+ /**
67
+ * List mandates issued by the signed-in owner. Pages through
68
+ * `aithos.list_mandates` until exhausted (or until 5 pages have
69
+ * been crawled — an owner with more than 1000 active mandates is
70
+ * out of scope today).
71
+ */
72
+ list(): Promise<readonly OwnedMandate[]>;
73
+ /**
74
+ * Publish a §4.2 revocation for `mandateId`. The mandate stops
75
+ * authorizing future actions (artifacts dated before `revoked_at`
76
+ * remain valid — revocation is not retroactive).
77
+ *
78
+ * Server-side: handled by `aithos.publish_revocation`. The envelope
79
+ * is signed by the owner's `#public` sphere — the spec also accepts
80
+ * `#root`, but `#public` is what the existing app does.
81
+ *
82
+ * Throws {@link AithosSDKError} on backend errors. Note that
83
+ * server-side support is in-flight; this method may surface a
84
+ * `mandates_-32601` (method not found) until the auth platform
85
+ * lands the corresponding write handler.
86
+ */
87
+ revoke(mandateId: string): Promise<void>;
88
+ }
2
89
  //# sourceMappingURL=mandates.d.ts.map
@@ -1,13 +1,190 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // Copyright 2026 Mathieu Colla
3
- // Mandates namespace — re-exports of mandate mint/sign primitives.
3
+ // `sdk.mandates` namespace — owner-side mandate lifecycle.
4
4
  //
5
- // A mandate is a signed delegation bundle that grants an app DID the right
6
- // to act on the user's behalf within a scoped set of operations (read
7
- // scopes, compute spend cap, TTL). Mandates are required by the compute
8
- // proxy on every Bedrock call.
5
+ // Three verbs:
6
+ // create(input) → mints + publishes + returns the
7
+ // shareable .aithos-delegate.json bundle
8
+ // list() → mandates the owner has issued
9
+ // revoke(mandateId) → publishes a §4.2 revocation
9
10
  //
10
- // See `@aithos/protocol-client/src/mandate-mint.ts` for the canonical
11
- // implementation; this namespace re-exports the public surface verbatim.
12
- export { mintDelegateBundle, signAndPublishMandate, MintError, DEFAULT_READ_SCOPES, TTL_PRESETS, } from "@aithos/protocol-client";
11
+ // Capability boundary: every method requires an owner signed in. We
12
+ // reach the OwnerSigners through `auth._getOwnerSigners()` and project
13
+ // to a `StoredIdentity` for protocol-client interop. When
14
+ // protocol-client gains a Signer-shaped API the projection step
15
+ // disappears.
16
+ import { buildSignedEnvelope, mintDelegateBundle, readRpc, } from "@aithos/protocol-client";
17
+ import { ownerKeyPair } from "./internal/protocol-client-bridge.js";
18
+ import { AithosSDKError } from "./types.js";
19
+ export class MandatesNamespace {
20
+ #deps;
21
+ constructor(deps) {
22
+ this.#deps = deps;
23
+ }
24
+ /**
25
+ * Mint, sign, publish, and package a fresh delegate bundle. The
26
+ * grantee's keypair is generated inside this call and never
27
+ * persisted on the owner's machine — the seed flows out via the
28
+ * returned Blob and only via that Blob.
29
+ */
30
+ async create(input) {
31
+ const owner = this.#requireOwner();
32
+ if (input.scopes.length === 0) {
33
+ throw new AithosSDKError("mandates_invalid_scopes", "scopes must be a non-empty list");
34
+ }
35
+ if (input.ttlSeconds <= 0) {
36
+ throw new AithosSDKError("mandates_invalid_ttl", "ttlSeconds must be > 0");
37
+ }
38
+ const actorSphere = input.actorSphere ?? defaultSphereFromScopes(input.scopes);
39
+ const ownerStored = owner._unsafeStoredIdentity();
40
+ const result = await mintDelegateBundle({
41
+ owner: ownerStored,
42
+ granteeId: input.granteeId,
43
+ ...(input.granteeLabel ? { granteeLabel: input.granteeLabel } : {}),
44
+ actorSphere,
45
+ scopes: [...input.scopes],
46
+ ttlSeconds: input.ttlSeconds,
47
+ });
48
+ const mandate = result.mandate;
49
+ return {
50
+ mandateId: mandate.id,
51
+ subjectDid: mandate.subject_did,
52
+ granteeId: input.granteeId,
53
+ scopes: input.scopes,
54
+ expiresAt: mandate.not_after ?? null,
55
+ bundle: result.bundleBlob,
56
+ filename: `aithos-delegate-${mandate.id}.json`,
57
+ };
58
+ }
59
+ /**
60
+ * List mandates issued by the signed-in owner. Pages through
61
+ * `aithos.list_mandates` until exhausted (or until 5 pages have
62
+ * been crawled — an owner with more than 1000 active mandates is
63
+ * out of scope today).
64
+ */
65
+ async list() {
66
+ const owner = this.#requireOwner();
67
+ const out = [];
68
+ let cursor;
69
+ for (let i = 0; i < 5; i++) {
70
+ const page = await readRpc("aithos.list_mandates", {
71
+ issuer_did: owner.did,
72
+ limit: 200,
73
+ ...(cursor ? { cursor } : {}),
74
+ });
75
+ for (const it of page.items) {
76
+ out.push(toOwnedMandate(it));
77
+ }
78
+ if (!page.next_cursor)
79
+ break;
80
+ cursor = page.next_cursor;
81
+ }
82
+ return out;
83
+ }
84
+ /**
85
+ * Publish a §4.2 revocation for `mandateId`. The mandate stops
86
+ * authorizing future actions (artifacts dated before `revoked_at`
87
+ * remain valid — revocation is not retroactive).
88
+ *
89
+ * Server-side: handled by `aithos.publish_revocation`. The envelope
90
+ * is signed by the owner's `#public` sphere — the spec also accepts
91
+ * `#root`, but `#public` is what the existing app does.
92
+ *
93
+ * Throws {@link AithosSDKError} on backend errors. Note that
94
+ * server-side support is in-flight; this method may surface a
95
+ * `mandates_-32601` (method not found) until the auth platform
96
+ * lands the corresponding write handler.
97
+ */
98
+ async revoke(mandateId) {
99
+ const owner = this.#requireOwner();
100
+ const ownerStored = owner._unsafeStoredIdentity();
101
+ // TODO(post-alpha): once @aithos/protocol-client exposes a public
102
+ // configuration API for the `api` endpoint, route this through the
103
+ // same channel as `readRpc` / `publishZoneEdit` so self-hosters
104
+ // can override. For now, target the production write surface.
105
+ const url = "https://api.aithos.be/mcp/primitives/write";
106
+ const params = {
107
+ mandate_id: mandateId,
108
+ revoked_at: new Date().toISOString(),
109
+ };
110
+ // Reach into the owner's #public signer for envelope signing via
111
+ // the centralized migration bridge (will go away when
112
+ // protocol-client accepts Signer-shaped objects).
113
+ const publicKp = ownerKeyPair(owner, "public");
114
+ const envelope = buildSignedEnvelope({
115
+ iss: ownerStored.did,
116
+ aud: url,
117
+ method: "aithos.publish_revocation",
118
+ verificationMethod: `${ownerStored.did}#public`,
119
+ params,
120
+ signer: publicKp,
121
+ });
122
+ let res;
123
+ try {
124
+ res = await this.#deps.fetch(url, {
125
+ method: "POST",
126
+ headers: { "content-type": "application/json" },
127
+ body: JSON.stringify({
128
+ jsonrpc: "2.0",
129
+ id: "aithos.publish_revocation",
130
+ method: "aithos.publish_revocation",
131
+ params: { ...params, _envelope: envelope },
132
+ }),
133
+ });
134
+ }
135
+ catch (e) {
136
+ throw new AithosSDKError("network", e.message);
137
+ }
138
+ const body = (await res.json().catch(() => null));
139
+ if (!body) {
140
+ throw new AithosSDKError("http", `HTTP ${res.status} ${res.statusText} — non-JSON response`, { status: res.status });
141
+ }
142
+ if (body.error) {
143
+ throw new AithosSDKError(`mandates_${body.error.code}`, body.error.message, body.error.data ? { data: body.error.data } : undefined);
144
+ }
145
+ }
146
+ /* ------------------------------------------------------------------------ */
147
+ /* Internals */
148
+ /* ------------------------------------------------------------------------ */
149
+ #requireOwner() {
150
+ const owner = this.#deps.auth._getOwnerSigners();
151
+ if (!owner || owner.destroyed) {
152
+ throw new AithosSDKError("mandates_no_owner", "no owner signed in; sign in first");
153
+ }
154
+ return owner;
155
+ }
156
+ }
157
+ /* -------------------------------------------------------------------------- */
158
+ /* Helpers */
159
+ /* -------------------------------------------------------------------------- */
160
+ function defaultSphereFromScopes(scopes) {
161
+ if (scopes.some((s) => s.endsWith(".self")))
162
+ return "self";
163
+ if (scopes.some((s) => s.endsWith(".circle")))
164
+ return "circle";
165
+ return "public";
166
+ }
167
+ function toOwnedMandate(it) {
168
+ return {
169
+ mandateId: requireString(it, "mandate_id"),
170
+ issuerDid: requireString(it, "issuer_did"),
171
+ actorDid: requireString(it, "actor_did"),
172
+ scopes: filterScopeArray(it["scopes"]),
173
+ notBefore: typeof it["not_before"] === "number" ? it["not_before"] : null,
174
+ notAfter: typeof it["not_after"] === "number" ? it["not_after"] : null,
175
+ createdAt: typeof it["created_at"] === "number" ? it["created_at"] : 0,
176
+ };
177
+ }
178
+ function requireString(o, key) {
179
+ const v = o[key];
180
+ if (typeof v !== "string") {
181
+ throw new AithosSDKError("mandates_response_malformed", `list_mandates row missing string field ${key}`);
182
+ }
183
+ return v;
184
+ }
185
+ function filterScopeArray(v) {
186
+ if (!Array.isArray(v))
187
+ return [];
188
+ return v.filter((s) => typeof s === "string");
189
+ }
13
190
  //# sourceMappingURL=mandates.js.map
package/dist/src/sdk.d.ts CHANGED
@@ -1,18 +1,51 @@
1
+ import type { AithosAuth } from "./auth.js";
1
2
  import { ComputeNamespace } from "./compute.js";
2
3
  import { type AithosSdkEndpoints } from "./endpoints.js";
4
+ import { EthosNamespace } from "./ethos.js";
5
+ import { MandatesNamespace } from "./mandates.js";
3
6
  import { WalletNamespace } from "./wallet.js";
4
- import type { AithosSDKConfig } from "./types.js";
7
+ export interface AithosSDKConfig {
8
+ /**
9
+ * The {@link AithosAuth} instance the SDK reads sign-in state from.
10
+ * Constructed and managed by the app — typically a singleton at the
11
+ * top of the application tree.
12
+ */
13
+ readonly auth: AithosAuth;
14
+ /**
15
+ * Application DID — identifies the calling app in mandates, audit
16
+ * logs, billing splits. Issued at developer onboarding (will be
17
+ * self-service before 0.1.0 stable).
18
+ */
19
+ readonly appDid: string;
20
+ /**
21
+ * Optional endpoint overrides. Production defaults point at the
22
+ * Aithos infrastructure; pass overrides for staging, self-hosting,
23
+ * tests.
24
+ */
25
+ readonly endpoints?: Partial<AithosSdkEndpoints>;
26
+ /**
27
+ * Optional `fetch` implementation. Defaults to the global `fetch`.
28
+ * Used by tests to inject a mock without monkeypatching globals.
29
+ */
30
+ readonly fetch?: typeof fetch;
31
+ }
5
32
  export declare class AithosSDK {
6
33
  /** Resolved endpoint configuration (defaults + caller overrides). */
7
34
  readonly endpoints: AithosSdkEndpoints;
8
35
  /** Application DID (as declared in mandates). */
9
36
  readonly appDid: string;
10
- /** User DID (derived from `config.identity`). */
11
- readonly userDid: string;
37
+ /** The same auth instance the app constructed and passed in. */
38
+ readonly auth: AithosAuth;
12
39
  /** Compute proxy namespace — Bedrock invocation. */
13
40
  readonly compute: ComputeNamespace;
14
41
  /** Wallet namespace — Stripe top-up. */
15
42
  readonly wallet: WalletNamespace;
43
+ /** Ethos editing namespace — load, mutate (staged), publish. */
44
+ readonly ethos: EthosNamespace;
45
+ /** Mandate lifecycle namespace — create / list / revoke. */
46
+ readonly mandates: MandatesNamespace;
16
47
  constructor(config: AithosSDKConfig);
48
+ /** DID of the currently signed-in owner, or null if no owner is loaded. */
49
+ get userDid(): string | null;
17
50
  }
18
51
  //# sourceMappingURL=sdk.d.ts.map
package/dist/src/sdk.js CHANGED
@@ -1,58 +1,62 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // Copyright 2026 Mathieu Colla
3
- // AithosSDK — top-level developer surface.
4
- //
5
- // One construction, namespaced methods. The SDK takes the user's identity
6
- // (a `BrowserIdentity` from `@aithos/protocol-client`) and the calling
7
- // app's DID, then exposes:
8
- //
9
- // sdk.compute — Bedrock invocation through the compute proxy.
10
- // sdk.wallet — Stripe Checkout for credit-pack top-ups.
11
- // sdk.ethos — re-exports from protocol-client (zone editor, signers).
12
- // sdk.onboarding / sdk.mandates — likewise.
13
- //
14
- // The class is intentionally thin: the heavy lifting lives in dedicated
15
- // namespace classes (`ComputeNamespace`, `WalletNamespace`) so each can be
16
- // tested in isolation with a mock fetch and so an advanced caller could
17
- // instantiate just one of them if needed.
18
3
  import { ComputeNamespace } from "./compute.js";
19
4
  import { resolveEndpoints } from "./endpoints.js";
5
+ import { EthosNamespace } from "./ethos.js";
6
+ import { MandatesNamespace } from "./mandates.js";
20
7
  import { WalletNamespace } from "./wallet.js";
21
8
  export class AithosSDK {
22
9
  /** Resolved endpoint configuration (defaults + caller overrides). */
23
10
  endpoints;
24
11
  /** Application DID (as declared in mandates). */
25
12
  appDid;
26
- /** User DID (derived from `config.identity`). */
27
- userDid;
13
+ /** The same auth instance the app constructed and passed in. */
14
+ auth;
28
15
  /** Compute proxy namespace — Bedrock invocation. */
29
16
  compute;
30
17
  /** Wallet namespace — Stripe top-up. */
31
18
  wallet;
19
+ /** Ethos editing namespace — load, mutate (staged), publish. */
20
+ ethos;
21
+ /** Mandate lifecycle namespace — create / list / revoke. */
22
+ mandates;
32
23
  constructor(config) {
33
- if (!config.identity) {
34
- throw new TypeError("AithosSDK: config.identity is required");
24
+ if (!config.auth) {
25
+ throw new TypeError("AithosSDK: config.auth is required");
35
26
  }
36
27
  if (!config.appDid || typeof config.appDid !== "string") {
37
28
  throw new TypeError("AithosSDK: config.appDid is required (string)");
38
29
  }
39
30
  this.endpoints = resolveEndpoints(config.endpoints);
40
31
  this.appDid = config.appDid;
41
- this.userDid = config.identity.did;
32
+ this.auth = config.auth;
42
33
  const fetchImpl = config.fetch ?? globalThis.fetch.bind(globalThis);
43
34
  this.compute = new ComputeNamespace({
44
- identity: config.identity,
35
+ auth: config.auth,
45
36
  appDid: config.appDid,
46
37
  endpoints: this.endpoints,
47
38
  fetch: fetchImpl,
48
39
  });
49
40
  this.wallet = new WalletNamespace({
50
- identity: config.identity,
41
+ auth: config.auth,
51
42
  appDid: config.appDid,
52
- userDid: config.identity.did,
53
43
  endpoints: this.endpoints,
54
44
  fetch: fetchImpl,
55
45
  });
46
+ this.ethos = new EthosNamespace({
47
+ auth: config.auth,
48
+ endpoints: this.endpoints,
49
+ fetch: fetchImpl,
50
+ });
51
+ this.mandates = new MandatesNamespace({
52
+ auth: config.auth,
53
+ endpoints: this.endpoints,
54
+ fetch: fetchImpl,
55
+ });
56
+ }
57
+ /** DID of the currently signed-in owner, or null if no owner is loaded. */
58
+ get userDid() {
59
+ return this.auth.getOwnerInfo()?.did ?? null;
56
60
  }
57
61
  }
58
62
  //# sourceMappingURL=sdk.js.map
@@ -1,4 +1,4 @@
1
- import { type BrowserIdentity } from "@aithos/protocol-client";
1
+ import type { AithosAuth } from "./auth.js";
2
2
  import { type AithosSdkEndpoints } from "./endpoints.js";
3
3
  /**
4
4
  * Canonical credit-pack identifiers. Pricing and microcredit amounts are
@@ -44,12 +44,10 @@ export interface GetBalanceResult {
44
44
  readonly exists: boolean;
45
45
  }
46
46
  export interface WalletNamespaceDeps {
47
- /** User identityneeded to sign the balance-lookup envelope. */
48
- readonly identity: BrowserIdentity;
47
+ /** Auth instancethe wallet reads the active owner DID + signing key from here. */
48
+ readonly auth: AithosAuth;
49
49
  /** App DID — sent as audit attribution alongside the balance request. */
50
50
  readonly appDid: string;
51
- /** Pre-resolved DID convenience accessor (mirrors identity.did). */
52
- readonly userDid: string;
53
51
  readonly endpoints: AithosSdkEndpoints;
54
52
  readonly fetch: typeof fetch;
55
53
  }
@@ -64,7 +62,7 @@ export declare class WalletNamespace {
64
62
  * hosted URL — the caller is responsible for redirecting the user (e.g.
65
63
  * `window.location.href = result.checkoutUrl`).
66
64
  *
67
- * On success, the Stripe webhook will credit `userDid`'s wallet once the
65
+ * On success, the Stripe webhook will credit the user's wallet once the
68
66
  * payment clears. Wallet balances are shared across all Aithos apps that
69
67
  * use the same DID.
70
68
  */
@@ -13,8 +13,9 @@
13
13
  // compute proxy at `${compute}/v1/invoke`. Read-only DDB GetItem on
14
14
  // the wallet table, gated by the same signed envelope verification
15
15
  // as compute_invoke. Returns the current balance + daily spent.
16
- import { buildSignedEnvelope, } from "@aithos/protocol-client";
16
+ import { buildSignedEnvelope } from "@aithos/protocol-client";
17
17
  import { computeInvokeUrl, walletTopupCheckoutUrl, } from "./endpoints.js";
18
+ import { ownerKeyPair } from "./internal/protocol-client-bridge.js";
18
19
  import { AithosSDKError } from "./types.js";
19
20
  /**
20
21
  * `sdk.wallet` namespace.
@@ -29,12 +30,16 @@ export class WalletNamespace {
29
30
  * hosted URL — the caller is responsible for redirecting the user (e.g.
30
31
  * `window.location.href = result.checkoutUrl`).
31
32
  *
32
- * On success, the Stripe webhook will credit `userDid`'s wallet once the
33
+ * On success, the Stripe webhook will credit the user's wallet once the
33
34
  * payment clears. Wallet balances are shared across all Aithos apps that
34
35
  * use the same DID.
35
36
  */
36
37
  async createTopupSession(args) {
37
- const { userDid, endpoints, fetch: fetchImpl } = this.#deps;
38
+ const { auth, endpoints, fetch: fetchImpl } = this.#deps;
39
+ const owner = auth._getOwnerSigners();
40
+ if (!owner || owner.destroyed) {
41
+ throw new AithosSDKError("sdk_no_owner", "no owner signed in; sign in first");
42
+ }
38
43
  const url = walletTopupCheckoutUrl(endpoints);
39
44
  let res;
40
45
  try {
@@ -42,7 +47,7 @@ export class WalletNamespace {
42
47
  method: "POST",
43
48
  headers: { "content-type": "application/json" },
44
49
  body: JSON.stringify({
45
- user_did: userDid,
50
+ user_did: owner.did,
46
51
  pack_id: args.packId,
47
52
  success_url: args.successUrl,
48
53
  cancel_url: args.cancelUrl,
@@ -88,16 +93,21 @@ export class WalletNamespace {
88
93
  * envelope-verify failures from the proxy).
89
94
  */
90
95
  async getBalance(args = {}) {
91
- const { identity, appDid, endpoints, fetch: fetchImpl } = this.#deps;
96
+ const { auth, appDid, endpoints, fetch: fetchImpl } = this.#deps;
97
+ const owner = auth._getOwnerSigners();
98
+ if (!owner || owner.destroyed) {
99
+ throw new AithosSDKError("sdk_no_owner", "no owner signed in; sign in first");
100
+ }
101
+ const publicKp = ownerKeyPair(owner, "public");
92
102
  const url = computeInvokeUrl(endpoints);
93
103
  const params = { app_did: appDid };
94
104
  const envelope = buildSignedEnvelope({
95
- iss: identity.did,
105
+ iss: owner.did,
96
106
  aud: url,
97
107
  method: "aithos.wallet_get_balance",
98
- verificationMethod: `${identity.did}#public`,
108
+ verificationMethod: `${owner.did}#public`,
99
109
  params,
100
- signer: identity.public,
110
+ signer: publicKp,
101
111
  });
102
112
  let res;
103
113
  try {
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=auth-j3.test.d.ts.map