@rhinestone/1auth 0.6.8 → 0.6.9

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 (49) hide show
  1. package/README.md +171 -12
  2. package/dist/chunk-IHBVEU33.mjs +20 -0
  3. package/dist/chunk-IHBVEU33.mjs.map +1 -0
  4. package/dist/chunk-IIACVHR3.mjs +28 -0
  5. package/dist/chunk-IIACVHR3.mjs.map +1 -0
  6. package/dist/chunk-N6KE5CII.mjs +72 -0
  7. package/dist/chunk-N6KE5CII.mjs.map +1 -0
  8. package/dist/{chunk-SXISYG2P.mjs → chunk-VZYHCFEH.mjs} +195 -140
  9. package/dist/chunk-VZYHCFEH.mjs.map +1 -0
  10. package/dist/{client-BrMrhetG.d.mts → client-BNluVe4_.d.ts} +305 -849
  11. package/dist/{client-BrMrhetG.d.ts → client-CLCdahyj.d.mts} +305 -849
  12. package/dist/headless.d.mts +90 -0
  13. package/dist/headless.d.ts +90 -0
  14. package/dist/headless.js +327 -0
  15. package/dist/headless.js.map +1 -0
  16. package/dist/headless.mjs +280 -0
  17. package/dist/headless.mjs.map +1 -0
  18. package/dist/index.d.mts +96 -144
  19. package/dist/index.d.ts +96 -144
  20. package/dist/index.js +2984 -718
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +2740 -627
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/{provider-CDl9wYEc.d.mts → provider-BgD9PeDX.d.ts} +6 -5
  25. package/dist/{provider-Dgv533YQ.d.ts → provider-hxHGb6SX.d.mts} +6 -5
  26. package/dist/react.d.mts +42 -2
  27. package/dist/react.d.ts +42 -2
  28. package/dist/react.js +92 -2
  29. package/dist/react.js.map +1 -1
  30. package/dist/react.mjs +66 -1
  31. package/dist/react.mjs.map +1 -1
  32. package/dist/server.d.mts +118 -0
  33. package/dist/server.d.ts +118 -0
  34. package/dist/server.js +356 -0
  35. package/dist/server.js.map +1 -0
  36. package/dist/server.mjs +282 -0
  37. package/dist/server.mjs.map +1 -0
  38. package/dist/types-1BMD1PSH.d.mts +1425 -0
  39. package/dist/types-1BMD1PSH.d.ts +1425 -0
  40. package/dist/verify-CZe-m_Vf.d.ts +150 -0
  41. package/dist/verify-D3FaLeAi.d.mts +150 -0
  42. package/dist/wagmi.d.mts +5 -2
  43. package/dist/wagmi.d.ts +5 -2
  44. package/dist/wagmi.js +138 -43
  45. package/dist/wagmi.js.map +1 -1
  46. package/dist/wagmi.mjs +2 -1
  47. package/dist/wagmi.mjs.map +1 -1
  48. package/package.json +15 -2
  49. package/dist/chunk-SXISYG2P.mjs.map +0 -1
@@ -0,0 +1,90 @@
1
+ import { P as PasskeyProviderConfig, S as SponsorshipConfig, H as HeadlessIntentOptions, a as HeadlessPrepareResult, b as HeadlessSubmitOptions, c as HeadlessSubmitResult, d as HeadlessIntentStatusResult, I as InstallSmartSessionOptions, e as InstallSmartSessionResult } from './types-1BMD1PSH.mjs';
2
+ export { f as SessionKeyHandle, g as SmartSessionEnableRequest } from './types-1BMD1PSH.mjs';
3
+ import 'viem';
4
+ import '@rhinestone/sdk';
5
+
6
+ /**
7
+ * Headless 1auth client.
8
+ *
9
+ * Used by integrators that hold their own ECDSA signer in localStorage
10
+ * and produce signatures for an ERC-7579 validator other than the
11
+ * passkey one (typically `@rhinestone/sdk` experimental SmartSession).
12
+ *
13
+ * Responsibilities:
14
+ * - Fetch sponsorship JWTs from the app's own backend.
15
+ * - Call `/api/intent/prepare?signingMode=headless` to get an
16
+ * orchestrator-quoted `intentOp` + `digestResult`.
17
+ * - Forward pre-encoded validator-prefixed signatures to the new
18
+ * `/api/intent/headless-execute` route.
19
+ * - Drive the existing passkey dialog (via {@link OneAuthClient}) for
20
+ * the one-time SmartSession install ceremony.
21
+ *
22
+ * 1auth itself stays ignorant of session keys — the on-chain
23
+ * SmartSession validator is the only authority over what a session key
24
+ * may sign for. The host app persists `{ sessionKeyAddress, permissionId,
25
+ * accountAddress, permissions }` in its own storage.
26
+ */
27
+
28
+ declare class OneAuthHeadlessClient {
29
+ private providerUrl;
30
+ private clientId?;
31
+ private sponsorship;
32
+ constructor(config: PasskeyProviderConfig);
33
+ setSponsorship(sponsorship: SponsorshipConfig | undefined): void;
34
+ private fetchAccessToken;
35
+ private fetchExtensionToken;
36
+ /**
37
+ * Quote an intent without opening any dialog. Returns the orchestrator's
38
+ * `intentOp` plus the digest the caller must sign with their own
39
+ * validator (e.g. SmartSession). The caller is responsible for
40
+ * encoding signatures and submitting via {@link submitIntent}.
41
+ */
42
+ prepareIntent(options: HeadlessIntentOptions): Promise<HeadlessPrepareResult>;
43
+ /**
44
+ * Forward a pre-signed intent to the orchestrator. The caller has
45
+ * already encoded validator-prefixed origin + destination signatures
46
+ * (one origin signature per intent element); 1auth treats them as
47
+ * opaque bytes.
48
+ *
49
+ * If `sponsor` is omitted or `true`, an extension token is fetched
50
+ * just-in-time and bound to the intent. Pass `sponsor: false` for
51
+ * self-paying intents.
52
+ */
53
+ submitIntent(options: HeadlessSubmitOptions): Promise<HeadlessSubmitResult>;
54
+ /**
55
+ * Fetch the latest known status for a submitted headless intent.
56
+ * This is a non-blocking read and may return `pending` before a
57
+ * solver has produced a fill transaction hash.
58
+ */
59
+ getIntentStatus(intentId: string): Promise<HeadlessIntentStatusResult>;
60
+ /**
61
+ * Wait for a submitted headless intent to produce a status update and,
62
+ * when available, the final fill transaction hash. The wait endpoint
63
+ * needs the opaque `transactionResult` returned by submit because 1auth
64
+ * does not persist that SDK object in its database.
65
+ */
66
+ waitForIntent(intentId: string, transactionResult: unknown): Promise<HeadlessIntentStatusResult>;
67
+ /**
68
+ * Resolve the SmartSession install call(s) for `sessionKeyAddress`
69
+ * with the supplied `permissions`.
70
+ *
71
+ * Returns `{ install, sessionKeyHandle }`:
72
+ *
73
+ * - `install` is a `{ targetChain, calls }` pair the caller feeds
74
+ * straight into `OneAuthClient.sendIntent({ targetChain, calls })`
75
+ * so the user passkey-signs the install via the existing dialog.
76
+ * - `sessionKeyHandle` contains the deterministic `permissionId`
77
+ * plus metadata to persist in localStorage. Persist this BEFORE
78
+ * submitting the install so a refresh during signing doesn't
79
+ * lose the handle.
80
+ *
81
+ * If the validator is already installed on the user's account,
82
+ * `install.calls` is empty and `install.alreadyInstalled` is true.
83
+ * The caller should still persist `sessionKeyHandle` — the on-chain
84
+ * session enabling happens at first headless use via SmartSession's
85
+ * ENABLE-mode signature wrapping (see follow-up).
86
+ */
87
+ installSmartSession(options: InstallSmartSessionOptions): Promise<InstallSmartSessionResult>;
88
+ }
89
+
90
+ export { HeadlessIntentOptions, HeadlessIntentStatusResult, HeadlessPrepareResult, HeadlessSubmitOptions, HeadlessSubmitResult, InstallSmartSessionOptions, InstallSmartSessionResult, OneAuthHeadlessClient };
@@ -0,0 +1,90 @@
1
+ import { P as PasskeyProviderConfig, S as SponsorshipConfig, H as HeadlessIntentOptions, a as HeadlessPrepareResult, b as HeadlessSubmitOptions, c as HeadlessSubmitResult, d as HeadlessIntentStatusResult, I as InstallSmartSessionOptions, e as InstallSmartSessionResult } from './types-1BMD1PSH.js';
2
+ export { f as SessionKeyHandle, g as SmartSessionEnableRequest } from './types-1BMD1PSH.js';
3
+ import 'viem';
4
+ import '@rhinestone/sdk';
5
+
6
+ /**
7
+ * Headless 1auth client.
8
+ *
9
+ * Used by integrators that hold their own ECDSA signer in localStorage
10
+ * and produce signatures for an ERC-7579 validator other than the
11
+ * passkey one (typically `@rhinestone/sdk` experimental SmartSession).
12
+ *
13
+ * Responsibilities:
14
+ * - Fetch sponsorship JWTs from the app's own backend.
15
+ * - Call `/api/intent/prepare?signingMode=headless` to get an
16
+ * orchestrator-quoted `intentOp` + `digestResult`.
17
+ * - Forward pre-encoded validator-prefixed signatures to the new
18
+ * `/api/intent/headless-execute` route.
19
+ * - Drive the existing passkey dialog (via {@link OneAuthClient}) for
20
+ * the one-time SmartSession install ceremony.
21
+ *
22
+ * 1auth itself stays ignorant of session keys — the on-chain
23
+ * SmartSession validator is the only authority over what a session key
24
+ * may sign for. The host app persists `{ sessionKeyAddress, permissionId,
25
+ * accountAddress, permissions }` in its own storage.
26
+ */
27
+
28
+ declare class OneAuthHeadlessClient {
29
+ private providerUrl;
30
+ private clientId?;
31
+ private sponsorship;
32
+ constructor(config: PasskeyProviderConfig);
33
+ setSponsorship(sponsorship: SponsorshipConfig | undefined): void;
34
+ private fetchAccessToken;
35
+ private fetchExtensionToken;
36
+ /**
37
+ * Quote an intent without opening any dialog. Returns the orchestrator's
38
+ * `intentOp` plus the digest the caller must sign with their own
39
+ * validator (e.g. SmartSession). The caller is responsible for
40
+ * encoding signatures and submitting via {@link submitIntent}.
41
+ */
42
+ prepareIntent(options: HeadlessIntentOptions): Promise<HeadlessPrepareResult>;
43
+ /**
44
+ * Forward a pre-signed intent to the orchestrator. The caller has
45
+ * already encoded validator-prefixed origin + destination signatures
46
+ * (one origin signature per intent element); 1auth treats them as
47
+ * opaque bytes.
48
+ *
49
+ * If `sponsor` is omitted or `true`, an extension token is fetched
50
+ * just-in-time and bound to the intent. Pass `sponsor: false` for
51
+ * self-paying intents.
52
+ */
53
+ submitIntent(options: HeadlessSubmitOptions): Promise<HeadlessSubmitResult>;
54
+ /**
55
+ * Fetch the latest known status for a submitted headless intent.
56
+ * This is a non-blocking read and may return `pending` before a
57
+ * solver has produced a fill transaction hash.
58
+ */
59
+ getIntentStatus(intentId: string): Promise<HeadlessIntentStatusResult>;
60
+ /**
61
+ * Wait for a submitted headless intent to produce a status update and,
62
+ * when available, the final fill transaction hash. The wait endpoint
63
+ * needs the opaque `transactionResult` returned by submit because 1auth
64
+ * does not persist that SDK object in its database.
65
+ */
66
+ waitForIntent(intentId: string, transactionResult: unknown): Promise<HeadlessIntentStatusResult>;
67
+ /**
68
+ * Resolve the SmartSession install call(s) for `sessionKeyAddress`
69
+ * with the supplied `permissions`.
70
+ *
71
+ * Returns `{ install, sessionKeyHandle }`:
72
+ *
73
+ * - `install` is a `{ targetChain, calls }` pair the caller feeds
74
+ * straight into `OneAuthClient.sendIntent({ targetChain, calls })`
75
+ * so the user passkey-signs the install via the existing dialog.
76
+ * - `sessionKeyHandle` contains the deterministic `permissionId`
77
+ * plus metadata to persist in localStorage. Persist this BEFORE
78
+ * submitting the install so a refresh during signing doesn't
79
+ * lose the handle.
80
+ *
81
+ * If the validator is already installed on the user's account,
82
+ * `install.calls` is empty and `install.alreadyInstalled` is true.
83
+ * The caller should still persist `sessionKeyHandle` — the on-chain
84
+ * session enabling happens at first headless use via SmartSession's
85
+ * ENABLE-mode signature wrapping (see follow-up).
86
+ */
87
+ installSmartSession(options: InstallSmartSessionOptions): Promise<InstallSmartSessionResult>;
88
+ }
89
+
90
+ export { HeadlessIntentOptions, HeadlessIntentStatusResult, HeadlessPrepareResult, HeadlessSubmitOptions, HeadlessSubmitResult, InstallSmartSessionOptions, InstallSmartSessionResult, OneAuthHeadlessClient };
@@ -0,0 +1,327 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/headless.ts
21
+ var headless_exports = {};
22
+ __export(headless_exports, {
23
+ OneAuthHeadlessClient: () => OneAuthHeadlessClient
24
+ });
25
+ module.exports = __toCommonJS(headless_exports);
26
+
27
+ // src/sponsorship-fetch.ts
28
+ async function extractServerReason(response) {
29
+ try {
30
+ const text = await response.clone().text();
31
+ if (!text) return response.statusText;
32
+ try {
33
+ const data = JSON.parse(text);
34
+ const reason = data.error ?? data.message;
35
+ if (typeof reason === "string" && reason.trim()) return reason;
36
+ } catch {
37
+ }
38
+ return text.slice(0, 200);
39
+ } catch {
40
+ return response.statusText;
41
+ }
42
+ }
43
+ async function tokenFetchError(label, response) {
44
+ const reason = await extractServerReason(response);
45
+ const suffix = reason ? `: ${reason}` : "";
46
+ return new Error(
47
+ `Failed to fetch ${label} (${response.status} ${response.statusText})${suffix}`
48
+ );
49
+ }
50
+
51
+ // src/headless-client.ts
52
+ var DEFAULT_PROVIDER_URL = "https://passkey.1auth.box";
53
+ var MISSING_APP_CREDENTIALS_MESSAGE = "No sponsorship configured on OneAuthHeadlessClient. Every user intent must carry the app's JWT \u2014 pass `sponsorship: { accessToken, getExtensionToken }` (or URL form) to the constructor.";
54
+ function normalizeSponsorship(config) {
55
+ if (!config) return null;
56
+ if ("accessToken" in config && "getExtensionToken" in config) {
57
+ return config;
58
+ }
59
+ const { accessTokenUrl, extensionTokenUrl } = config;
60
+ return {
61
+ accessToken: async () => {
62
+ const response = await fetch(accessTokenUrl, { credentials: "include" });
63
+ if (!response.ok) {
64
+ throw await tokenFetchError("access token", response);
65
+ }
66
+ const data = await response.json();
67
+ if (!data.token) {
68
+ throw new Error("Access token response missing `token` field");
69
+ }
70
+ return data.token;
71
+ },
72
+ getExtensionToken: async (intentOp) => {
73
+ const response = await fetch(extensionTokenUrl, {
74
+ method: "POST",
75
+ credentials: "include",
76
+ headers: { "Content-Type": "application/json" },
77
+ body: JSON.stringify({ intentOp })
78
+ });
79
+ if (!response.ok) {
80
+ throw await tokenFetchError("extension token", response);
81
+ }
82
+ const data = await response.json();
83
+ if (!data.token) {
84
+ throw new Error("Extension token response missing `token` field");
85
+ }
86
+ return data.token;
87
+ }
88
+ };
89
+ }
90
+ var OneAuthHeadlessClient = class {
91
+ constructor(config) {
92
+ this.providerUrl = config.providerUrl || DEFAULT_PROVIDER_URL;
93
+ this.clientId = config.clientId;
94
+ this.sponsorship = normalizeSponsorship(config.sponsorship);
95
+ }
96
+ setSponsorship(sponsorship) {
97
+ this.sponsorship = normalizeSponsorship(sponsorship);
98
+ }
99
+ // ---------------------------------------------------------------------------
100
+ // Sponsorship JWT fetchers
101
+ // ---------------------------------------------------------------------------
102
+ async fetchAccessToken() {
103
+ if (!this.sponsorship) {
104
+ return {
105
+ ok: false,
106
+ code: "MISSING_APP_CREDENTIALS",
107
+ message: MISSING_APP_CREDENTIALS_MESSAGE
108
+ };
109
+ }
110
+ try {
111
+ const accessToken = await this.sponsorship.accessToken();
112
+ return { ok: true, accessToken };
113
+ } catch (err) {
114
+ return {
115
+ ok: false,
116
+ message: err instanceof Error ? err.message : String(err)
117
+ };
118
+ }
119
+ }
120
+ async fetchExtensionToken(intentOp, sponsor) {
121
+ if (!sponsor) return { ok: true, extensionToken: void 0 };
122
+ if (!this.sponsorship) {
123
+ return { ok: false, message: MISSING_APP_CREDENTIALS_MESSAGE };
124
+ }
125
+ try {
126
+ const token = await this.sponsorship.getExtensionToken(intentOp);
127
+ return { ok: true, extensionToken: token };
128
+ } catch (err) {
129
+ return {
130
+ ok: false,
131
+ message: err instanceof Error ? err.message : String(err)
132
+ };
133
+ }
134
+ }
135
+ // ---------------------------------------------------------------------------
136
+ // Intent prepare / submit
137
+ // ---------------------------------------------------------------------------
138
+ /**
139
+ * Quote an intent without opening any dialog. Returns the orchestrator's
140
+ * `intentOp` plus the digest the caller must sign with their own
141
+ * validator (e.g. SmartSession). The caller is responsible for
142
+ * encoding signatures and submitting via {@link submitIntent}.
143
+ */
144
+ async prepareIntent(options) {
145
+ if (!options.username && !options.accountAddress) {
146
+ throw new Error("prepareIntent requires either `username` or `accountAddress`");
147
+ }
148
+ const accessTokenResult = await this.fetchAccessToken();
149
+ if (!accessTokenResult.ok) {
150
+ throw new Error(`Sponsorship access token fetch failed: ${accessTokenResult.message}`);
151
+ }
152
+ const tokenRequests = options.tokenRequests?.map((tr) => ({
153
+ token: tr.token,
154
+ amount: tr.amount.toString()
155
+ }));
156
+ const body = {
157
+ username: options.username,
158
+ accountAddress: options.accountAddress,
159
+ targetChain: options.targetChain,
160
+ calls: options.calls,
161
+ tokenRequests,
162
+ sourceAssets: options.sourceAssets,
163
+ sourceChainId: options.sourceChainId,
164
+ sessionKeyHandle: options.sessionKeyHandle,
165
+ clientId: this.clientId,
166
+ signingMode: "headless",
167
+ auth: { accessToken: accessTokenResult.accessToken }
168
+ };
169
+ const response = await fetch(`${this.providerUrl}/api/intent/prepare`, {
170
+ method: "POST",
171
+ headers: { "Content-Type": "application/json" },
172
+ body: JSON.stringify(body)
173
+ });
174
+ if (!response.ok) {
175
+ const errorData = await response.json().catch(() => ({}));
176
+ throw new Error(errorData.error || `Prepare failed (${response.status})`);
177
+ }
178
+ return await response.json();
179
+ }
180
+ /**
181
+ * Forward a pre-signed intent to the orchestrator. The caller has
182
+ * already encoded validator-prefixed origin + destination signatures
183
+ * (one origin signature per intent element); 1auth treats them as
184
+ * opaque bytes.
185
+ *
186
+ * If `sponsor` is omitted or `true`, an extension token is fetched
187
+ * just-in-time and bound to the intent. Pass `sponsor: false` for
188
+ * self-paying intents.
189
+ */
190
+ async submitIntent(options) {
191
+ const sponsor = options.sponsor ?? true;
192
+ const accessTokenResult = await this.fetchAccessToken();
193
+ if (!accessTokenResult.ok) {
194
+ throw new Error(`Sponsorship access token fetch failed: ${accessTokenResult.message}`);
195
+ }
196
+ const extensionResult = await this.fetchExtensionToken(options.intentOp, sponsor);
197
+ if (!extensionResult.ok) {
198
+ throw new Error(`Sponsorship extension token fetch failed: ${extensionResult.message}`);
199
+ }
200
+ const body = {
201
+ intentOp: options.intentOp,
202
+ accountAddress: options.accountAddress,
203
+ targetChain: options.targetChain,
204
+ calls: options.calls,
205
+ expiresAt: options.expiresAt,
206
+ originSignatures: options.originSignatures,
207
+ destinationSignature: options.destinationSignature,
208
+ targetExecutionSignature: options.targetExecutionSignature,
209
+ auth: {
210
+ accessToken: accessTokenResult.accessToken,
211
+ ...extensionResult.extensionToken && { extensionToken: extensionResult.extensionToken }
212
+ }
213
+ };
214
+ const response = await fetch(`${this.providerUrl}/api/intent/headless-execute`, {
215
+ method: "POST",
216
+ headers: { "Content-Type": "application/json" },
217
+ body: JSON.stringify(body)
218
+ });
219
+ if (!response.ok) {
220
+ const errorData = await response.json().catch(() => ({}));
221
+ throw new Error(errorData.error || `Headless execute failed (${response.status})`);
222
+ }
223
+ return await response.json();
224
+ }
225
+ // ---------------------------------------------------------------------------
226
+ // Status / wait — proxies to the existing routes (no headless variant needed).
227
+ // ---------------------------------------------------------------------------
228
+ /**
229
+ * Fetch the latest known status for a submitted headless intent.
230
+ * This is a non-blocking read and may return `pending` before a
231
+ * solver has produced a fill transaction hash.
232
+ */
233
+ async getIntentStatus(intentId) {
234
+ const response = await fetch(`${this.providerUrl}/api/intent/status/${intentId}`);
235
+ if (!response.ok) {
236
+ throw new Error(`Status fetch failed (${response.status})`);
237
+ }
238
+ return await response.json();
239
+ }
240
+ /**
241
+ * Wait for a submitted headless intent to produce a status update and,
242
+ * when available, the final fill transaction hash. The wait endpoint
243
+ * needs the opaque `transactionResult` returned by submit because 1auth
244
+ * does not persist that SDK object in its database.
245
+ */
246
+ async waitForIntent(intentId, transactionResult) {
247
+ if (!transactionResult) {
248
+ throw new Error("waitForIntent requires submitResult.transactionResult");
249
+ }
250
+ const response = await fetch(`${this.providerUrl}/api/intent/wait/${intentId}`, {
251
+ method: "POST",
252
+ headers: { "Content-Type": "application/json" },
253
+ body: JSON.stringify({ transactionResult })
254
+ });
255
+ if (!response.ok) {
256
+ const errorData = await response.json().catch(() => ({}));
257
+ throw new Error(
258
+ errorData.details || errorData.error || `Wait fetch failed (${response.status})`
259
+ );
260
+ }
261
+ return await response.json();
262
+ }
263
+ // ---------------------------------------------------------------------------
264
+ // SmartSession install (one-time, passkey-signed)
265
+ // ---------------------------------------------------------------------------
266
+ /**
267
+ * Resolve the SmartSession install call(s) for `sessionKeyAddress`
268
+ * with the supplied `permissions`.
269
+ *
270
+ * Returns `{ install, sessionKeyHandle }`:
271
+ *
272
+ * - `install` is a `{ targetChain, calls }` pair the caller feeds
273
+ * straight into `OneAuthClient.sendIntent({ targetChain, calls })`
274
+ * so the user passkey-signs the install via the existing dialog.
275
+ * - `sessionKeyHandle` contains the deterministic `permissionId`
276
+ * plus metadata to persist in localStorage. Persist this BEFORE
277
+ * submitting the install so a refresh during signing doesn't
278
+ * lose the handle.
279
+ *
280
+ * If the validator is already installed on the user's account,
281
+ * `install.calls` is empty and `install.alreadyInstalled` is true.
282
+ * The caller should still persist `sessionKeyHandle` — the on-chain
283
+ * session enabling happens at first headless use via SmartSession's
284
+ * ENABLE-mode signature wrapping (see follow-up).
285
+ */
286
+ async installSmartSession(options) {
287
+ if (!options.username && !options.accountAddress) {
288
+ throw new Error(
289
+ "installSmartSession requires either `username` or `accountAddress`"
290
+ );
291
+ }
292
+ const accessTokenResult = await this.fetchAccessToken();
293
+ if (!accessTokenResult.ok) {
294
+ throw new Error(
295
+ `Sponsorship access token fetch failed: ${accessTokenResult.message}`
296
+ );
297
+ }
298
+ const body = {
299
+ username: options.username,
300
+ accountAddress: options.accountAddress,
301
+ targetChain: options.targetChain,
302
+ sessionKeyAddress: options.sessionKeyAddress,
303
+ permissions: options.permissions,
304
+ validUntil: options.validUntil,
305
+ validAfter: options.validAfter,
306
+ maxUses: options.maxUses,
307
+ enableSessionSignature: options.enableSessionSignature,
308
+ label: options.label,
309
+ auth: { accessToken: accessTokenResult.accessToken }
310
+ };
311
+ const response = await fetch(`${this.providerUrl}/api/sessions/install`, {
312
+ method: "POST",
313
+ headers: { "Content-Type": "application/json" },
314
+ body: JSON.stringify(body)
315
+ });
316
+ if (!response.ok) {
317
+ const errorData = await response.json().catch(() => ({}));
318
+ throw new Error(errorData.error || `Install failed (${response.status})`);
319
+ }
320
+ return await response.json();
321
+ }
322
+ };
323
+ // Annotate the CommonJS export names for ESM import in node:
324
+ 0 && (module.exports = {
325
+ OneAuthHeadlessClient
326
+ });
327
+ //# sourceMappingURL=headless.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/headless.ts","../src/sponsorship-fetch.ts","../src/headless-client.ts"],"sourcesContent":["/**\n * Public entry point for the headless 1auth SDK.\n *\n * Exposes {@link OneAuthHeadlessClient} plus the request/response types\n * an integrating app needs when using its own ERC-7579 validator (e.g.\n * the experimental SmartSession from `@rhinestone/sdk`) to sign intents\n * locally instead of going through the passkey dialog.\n */\n\nexport { OneAuthHeadlessClient } from \"./headless-client\";\n\nexport type {\n HeadlessIntentStatusResult,\n HeadlessIntentOptions,\n HeadlessPrepareResult,\n HeadlessSubmitOptions,\n HeadlessSubmitResult,\n InstallSmartSessionOptions,\n InstallSmartSessionResult,\n SessionKeyHandle,\n SmartSessionEnableRequest,\n} from \"./types\";\n","/**\n * Shared helpers for fetching sponsorship tokens (access + extension) from an\n * integrator's backend endpoints.\n *\n * The integrator's token routes return their failure reason in the JSON body\n * (`{ error: \"createSponsorshipSigner: missing env var(s): ...\" }`). Surfacing\n * only the HTTP status — \"Failed to fetch access token (500 ...)\" — hides that\n * reason and turns every misconfiguration into the same opaque dialog error.\n * These helpers read the body and fold the server's message into the thrown\n * Error so the actual cause (missing env var, bad JWK, expired session) is\n * visible at the call site and in the dialog.\n */\n\n/**\n * Pull a human-readable reason out of a failed token response. Tries the JSON\n * `error`/`message` fields first, then falls back to a short text snippet, then\n * to the HTTP status text. Never throws — diagnostics must not mask the original\n * failure with a parse error.\n */\nasync function extractServerReason(response: Response): Promise<string> {\n try {\n // Clone so a JSON parse failure can still fall back to reading text.\n const text = await response.clone().text();\n if (!text) return response.statusText;\n try {\n const data = JSON.parse(text) as { error?: unknown; message?: unknown };\n const reason = data.error ?? data.message;\n if (typeof reason === \"string\" && reason.trim()) return reason;\n } catch {\n // Body wasn't JSON — fall through to the raw text snippet.\n }\n // Cap the snippet so an HTML error page doesn't flood the message.\n return text.slice(0, 200);\n } catch {\n return response.statusText;\n }\n}\n\n/**\n * Build an Error for a failed token fetch that includes the server's reason.\n * `label` names the token kind, e.g. \"access token\" or \"extension token\".\n */\nexport async function tokenFetchError(\n label: string,\n response: Response,\n): Promise<Error> {\n const reason = await extractServerReason(response);\n const suffix = reason ? `: ${reason}` : \"\";\n return new Error(\n `Failed to fetch ${label} (${response.status} ${response.statusText})${suffix}`,\n );\n}\n","/**\n * Headless 1auth client.\n *\n * Used by integrators that hold their own ECDSA signer in localStorage\n * and produce signatures for an ERC-7579 validator other than the\n * passkey one (typically `@rhinestone/sdk` experimental SmartSession).\n *\n * Responsibilities:\n * - Fetch sponsorship JWTs from the app's own backend.\n * - Call `/api/intent/prepare?signingMode=headless` to get an\n * orchestrator-quoted `intentOp` + `digestResult`.\n * - Forward pre-encoded validator-prefixed signatures to the new\n * `/api/intent/headless-execute` route.\n * - Drive the existing passkey dialog (via {@link OneAuthClient}) for\n * the one-time SmartSession install ceremony.\n *\n * 1auth itself stays ignorant of session keys — the on-chain\n * SmartSession validator is the only authority over what a session key\n * may sign for. The host app persists `{ sessionKeyAddress, permissionId,\n * accountAddress, permissions }` in its own storage.\n */\n\nimport type {\n HeadlessIntentOptions,\n HeadlessIntentStatusResult,\n HeadlessPrepareResult,\n HeadlessSubmitOptions,\n HeadlessSubmitResult,\n InstallSmartSessionOptions,\n InstallSmartSessionResult,\n IntentTokenRequest,\n PasskeyProviderConfig,\n SponsorshipCallbackConfig,\n SponsorshipConfig,\n} from \"./types\";\nimport { tokenFetchError } from \"./sponsorship-fetch\";\n\nconst DEFAULT_PROVIDER_URL = \"https://passkey.1auth.box\";\n\nconst MISSING_APP_CREDENTIALS_MESSAGE =\n \"No sponsorship configured on OneAuthHeadlessClient. Every user intent must carry the app's JWT — pass `sponsorship: { accessToken, getExtensionToken }` (or URL form) to the constructor.\";\n\ntype AccessTokenFetchResult =\n | { ok: true; accessToken: string }\n | { ok: false; code?: \"MISSING_APP_CREDENTIALS\"; message: string };\n\ntype ExtensionTokenFetchResult =\n | { ok: true; extensionToken: string | undefined }\n | { ok: false; message: string };\n\n/**\n * Mirrors `normalizeSponsorship` in `client.ts`. Kept local so the\n * headless entry point doesn't pull in the whole OneAuthClient module\n * graph for callers that only need the headless surface.\n */\nfunction normalizeSponsorship(\n config: SponsorshipConfig | undefined,\n): SponsorshipCallbackConfig | null {\n if (!config) return null;\n if (\"accessToken\" in config && \"getExtensionToken\" in config) {\n return config;\n }\n const { accessTokenUrl, extensionTokenUrl } = config;\n return {\n accessToken: async () => {\n const response = await fetch(accessTokenUrl, { credentials: \"include\" });\n if (!response.ok) {\n throw await tokenFetchError(\"access token\", response);\n }\n const data = (await response.json()) as { token?: string };\n if (!data.token) {\n throw new Error(\"Access token response missing `token` field\");\n }\n return data.token;\n },\n getExtensionToken: async (intentOp: string) => {\n const response = await fetch(extensionTokenUrl, {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ intentOp }),\n });\n if (!response.ok) {\n throw await tokenFetchError(\"extension token\", response);\n }\n const data = (await response.json()) as { token?: string };\n if (!data.token) {\n throw new Error(\"Extension token response missing `token` field\");\n }\n return data.token;\n },\n };\n}\n\nexport class OneAuthHeadlessClient {\n private providerUrl: string;\n private clientId?: string;\n private sponsorship: SponsorshipCallbackConfig | null;\n\n constructor(config: PasskeyProviderConfig) {\n this.providerUrl = config.providerUrl || DEFAULT_PROVIDER_URL;\n this.clientId = config.clientId;\n this.sponsorship = normalizeSponsorship(config.sponsorship);\n }\n\n setSponsorship(sponsorship: SponsorshipConfig | undefined): void {\n this.sponsorship = normalizeSponsorship(sponsorship);\n }\n\n // ---------------------------------------------------------------------------\n // Sponsorship JWT fetchers\n // ---------------------------------------------------------------------------\n\n private async fetchAccessToken(): Promise<AccessTokenFetchResult> {\n if (!this.sponsorship) {\n return {\n ok: false,\n code: \"MISSING_APP_CREDENTIALS\",\n message: MISSING_APP_CREDENTIALS_MESSAGE,\n };\n }\n try {\n const accessToken = await this.sponsorship.accessToken();\n return { ok: true, accessToken };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n private async fetchExtensionToken(\n intentOp: string,\n sponsor: boolean,\n ): Promise<ExtensionTokenFetchResult> {\n if (!sponsor) return { ok: true, extensionToken: undefined };\n if (!this.sponsorship) {\n return { ok: false, message: MISSING_APP_CREDENTIALS_MESSAGE };\n }\n try {\n const token = await this.sponsorship.getExtensionToken(intentOp);\n return { ok: true, extensionToken: token };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n // ---------------------------------------------------------------------------\n // Intent prepare / submit\n // ---------------------------------------------------------------------------\n\n /**\n * Quote an intent without opening any dialog. Returns the orchestrator's\n * `intentOp` plus the digest the caller must sign with their own\n * validator (e.g. SmartSession). The caller is responsible for\n * encoding signatures and submitting via {@link submitIntent}.\n */\n async prepareIntent(options: HeadlessIntentOptions): Promise<HeadlessPrepareResult> {\n if (!options.username && !options.accountAddress) {\n throw new Error(\"prepareIntent requires either `username` or `accountAddress`\");\n }\n\n const accessTokenResult = await this.fetchAccessToken();\n if (!accessTokenResult.ok) {\n throw new Error(`Sponsorship access token fetch failed: ${accessTokenResult.message}`);\n }\n\n // bigint → string conversion for token requests; matches what the\n // dialog flow does before serializing requestBody.\n const tokenRequests = options.tokenRequests?.map((tr: IntentTokenRequest) => ({\n token: tr.token,\n amount: tr.amount.toString(),\n }));\n\n const body = {\n username: options.username,\n accountAddress: options.accountAddress,\n targetChain: options.targetChain,\n calls: options.calls,\n tokenRequests,\n sourceAssets: options.sourceAssets,\n sourceChainId: options.sourceChainId,\n sessionKeyHandle: options.sessionKeyHandle,\n clientId: this.clientId,\n signingMode: \"headless\" as const,\n auth: { accessToken: accessTokenResult.accessToken },\n };\n\n const response = await fetch(`${this.providerUrl}/api/intent/prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as { error?: string };\n throw new Error(errorData.error || `Prepare failed (${response.status})`);\n }\n\n return (await response.json()) as HeadlessPrepareResult;\n }\n\n /**\n * Forward a pre-signed intent to the orchestrator. The caller has\n * already encoded validator-prefixed origin + destination signatures\n * (one origin signature per intent element); 1auth treats them as\n * opaque bytes.\n *\n * If `sponsor` is omitted or `true`, an extension token is fetched\n * just-in-time and bound to the intent. Pass `sponsor: false` for\n * self-paying intents.\n */\n async submitIntent(options: HeadlessSubmitOptions): Promise<HeadlessSubmitResult> {\n const sponsor = options.sponsor ?? true;\n const accessTokenResult = await this.fetchAccessToken();\n if (!accessTokenResult.ok) {\n throw new Error(`Sponsorship access token fetch failed: ${accessTokenResult.message}`);\n }\n\n const extensionResult = await this.fetchExtensionToken(options.intentOp, sponsor);\n if (!extensionResult.ok) {\n throw new Error(`Sponsorship extension token fetch failed: ${extensionResult.message}`);\n }\n\n const body = {\n intentOp: options.intentOp,\n accountAddress: options.accountAddress,\n targetChain: options.targetChain,\n calls: options.calls,\n expiresAt: options.expiresAt,\n originSignatures: options.originSignatures,\n destinationSignature: options.destinationSignature,\n targetExecutionSignature: options.targetExecutionSignature,\n auth: {\n accessToken: accessTokenResult.accessToken,\n ...(extensionResult.extensionToken && { extensionToken: extensionResult.extensionToken }),\n },\n };\n\n const response = await fetch(`${this.providerUrl}/api/intent/headless-execute`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as { error?: string };\n throw new Error(errorData.error || `Headless execute failed (${response.status})`);\n }\n\n return (await response.json()) as HeadlessSubmitResult;\n }\n\n // ---------------------------------------------------------------------------\n // Status / wait — proxies to the existing routes (no headless variant needed).\n // ---------------------------------------------------------------------------\n\n /**\n * Fetch the latest known status for a submitted headless intent.\n * This is a non-blocking read and may return `pending` before a\n * solver has produced a fill transaction hash.\n */\n async getIntentStatus(intentId: string): Promise<HeadlessIntentStatusResult> {\n const response = await fetch(`${this.providerUrl}/api/intent/status/${intentId}`);\n if (!response.ok) {\n throw new Error(`Status fetch failed (${response.status})`);\n }\n return (await response.json()) as HeadlessIntentStatusResult;\n }\n\n /**\n * Wait for a submitted headless intent to produce a status update and,\n * when available, the final fill transaction hash. The wait endpoint\n * needs the opaque `transactionResult` returned by submit because 1auth\n * does not persist that SDK object in its database.\n */\n async waitForIntent(\n intentId: string,\n transactionResult: unknown,\n ): Promise<HeadlessIntentStatusResult> {\n if (!transactionResult) {\n throw new Error(\"waitForIntent requires submitResult.transactionResult\");\n }\n\n const response = await fetch(`${this.providerUrl}/api/intent/wait/${intentId}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ transactionResult }),\n });\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n details?: string;\n };\n throw new Error(\n errorData.details || errorData.error || `Wait fetch failed (${response.status})`,\n );\n }\n return (await response.json()) as HeadlessIntentStatusResult;\n }\n\n // ---------------------------------------------------------------------------\n // SmartSession install (one-time, passkey-signed)\n // ---------------------------------------------------------------------------\n\n /**\n * Resolve the SmartSession install call(s) for `sessionKeyAddress`\n * with the supplied `permissions`.\n *\n * Returns `{ install, sessionKeyHandle }`:\n *\n * - `install` is a `{ targetChain, calls }` pair the caller feeds\n * straight into `OneAuthClient.sendIntent({ targetChain, calls })`\n * so the user passkey-signs the install via the existing dialog.\n * - `sessionKeyHandle` contains the deterministic `permissionId`\n * plus metadata to persist in localStorage. Persist this BEFORE\n * submitting the install so a refresh during signing doesn't\n * lose the handle.\n *\n * If the validator is already installed on the user's account,\n * `install.calls` is empty and `install.alreadyInstalled` is true.\n * The caller should still persist `sessionKeyHandle` — the on-chain\n * session enabling happens at first headless use via SmartSession's\n * ENABLE-mode signature wrapping (see follow-up).\n */\n async installSmartSession(\n options: InstallSmartSessionOptions,\n ): Promise<InstallSmartSessionResult> {\n if (!options.username && !options.accountAddress) {\n throw new Error(\n \"installSmartSession requires either `username` or `accountAddress`\",\n );\n }\n\n const accessTokenResult = await this.fetchAccessToken();\n if (!accessTokenResult.ok) {\n throw new Error(\n `Sponsorship access token fetch failed: ${accessTokenResult.message}`,\n );\n }\n\n const body = {\n username: options.username,\n accountAddress: options.accountAddress,\n targetChain: options.targetChain,\n sessionKeyAddress: options.sessionKeyAddress,\n permissions: options.permissions,\n validUntil: options.validUntil,\n validAfter: options.validAfter,\n maxUses: options.maxUses,\n enableSessionSignature: options.enableSessionSignature,\n label: options.label,\n auth: { accessToken: accessTokenResult.accessToken },\n };\n\n const response = await fetch(`${this.providerUrl}/api/sessions/install`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(errorData.error || `Install failed (${response.status})`);\n }\n\n return (await response.json()) as InstallSmartSessionResult;\n }\n}\n"],"mappings":"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","names":[]}