@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,282 @@
1
+ import {
2
+ hashMessage,
3
+ verifyMessageHash
4
+ } from "./chunk-IHBVEU33.mjs";
5
+ import {
6
+ encodeWebAuthnSignature
7
+ } from "./chunk-N6KE5CII.mjs";
8
+
9
+ // src/server.ts
10
+ import { SignJWT, importJWK } from "jose";
11
+ import { isAddress } from "viem";
12
+ var SponsorshipDeniedError = class extends Error {
13
+ constructor() {
14
+ super("Sponsorship denied");
15
+ this.name = "SponsorshipDeniedError";
16
+ }
17
+ };
18
+ var OneAuthAccountVerificationError = class extends Error {
19
+ constructor(message) {
20
+ super(message);
21
+ this.name = "OneAuthAccountVerificationError";
22
+ }
23
+ };
24
+ var ENV_KEYS = {
25
+ privateKey: "RHINESTONE_JWT_PRIVATE_KEY",
26
+ integratorId: "RHINESTONE_INTEGRATOR_ID",
27
+ projectId: "RHINESTONE_PROJECT_ID",
28
+ appId: "RHINESTONE_APP_ID",
29
+ keyId: "RHINESTONE_KEY_ID"
30
+ };
31
+ function accountLookupUrl(providerUrl, address) {
32
+ return new URL(`/api/account/${address.toLowerCase()}`, providerUrl).toString();
33
+ }
34
+ async function parseAccountLookupResponse(response) {
35
+ try {
36
+ return await response.json();
37
+ } catch {
38
+ return null;
39
+ }
40
+ }
41
+ async function verifyOneAuthAccount(options) {
42
+ if (!isAddress(options.address)) {
43
+ throw new OneAuthAccountVerificationError(
44
+ "A valid 1auth account address is required"
45
+ );
46
+ }
47
+ const fetchImpl = options.fetch ?? globalThis.fetch;
48
+ if (typeof fetchImpl !== "function") {
49
+ throw new OneAuthAccountVerificationError(
50
+ "No fetch implementation is available to verify the 1auth account"
51
+ );
52
+ }
53
+ const url = accountLookupUrl(options.providerUrl, options.address);
54
+ const headers = { accept: "application/json" };
55
+ if (options.clientId) headers["x-client-id"] = options.clientId;
56
+ let response;
57
+ try {
58
+ response = await fetchImpl(url, {
59
+ headers,
60
+ cache: "no-store"
61
+ });
62
+ } catch (error) {
63
+ throw new OneAuthAccountVerificationError(
64
+ `Unable to reach the configured 1auth provider: ${error instanceof Error ? error.message : String(error)}`
65
+ );
66
+ }
67
+ const body = await parseAccountLookupResponse(response);
68
+ if (!response.ok) {
69
+ const message = body && typeof body === "object" && "error" in body ? String(body.error) : response.statusText || "account lookup failed";
70
+ throw new OneAuthAccountVerificationError(
71
+ `Configured 1auth provider did not recognize this account (${response.status}: ${message})`
72
+ );
73
+ }
74
+ const account = body;
75
+ if (!account?.address || !isAddress(account.address)) {
76
+ throw new OneAuthAccountVerificationError(
77
+ "Configured 1auth provider returned a malformed account record"
78
+ );
79
+ }
80
+ if (account.address.toLowerCase() !== options.address.toLowerCase()) {
81
+ throw new OneAuthAccountVerificationError(
82
+ "Configured 1auth provider returned a different account address"
83
+ );
84
+ }
85
+ return {
86
+ address: account.address,
87
+ deployed: typeof account.deployed === "boolean" ? account.deployed : void 0,
88
+ chainId: typeof account.chainId === "number" ? account.chainId : void 0
89
+ };
90
+ }
91
+ function jcsCanonicalise(value) {
92
+ return serialize(value);
93
+ }
94
+ function serialize(value) {
95
+ if (value === null || value === void 0) {
96
+ return "null";
97
+ }
98
+ switch (typeof value) {
99
+ case "boolean":
100
+ return value ? "true" : "false";
101
+ case "number":
102
+ if (!Number.isFinite(value)) {
103
+ throw new Error(`JCS: non-finite number: ${value}`);
104
+ }
105
+ return Object.is(value, -0) ? "0" : String(value);
106
+ case "string":
107
+ return JSON.stringify(value);
108
+ case "bigint":
109
+ if (value > BigInt(Number.MAX_SAFE_INTEGER) || value < BigInt(-Number.MAX_SAFE_INTEGER)) {
110
+ throw new Error(
111
+ `JCS: BigInt ${value} exceeds safe integer range \u2014 convert to string before calling`
112
+ );
113
+ }
114
+ return String(value);
115
+ default:
116
+ break;
117
+ }
118
+ if (Array.isArray(value)) {
119
+ return `[${value.map((item) => serialize(item)).join(",")}]`;
120
+ }
121
+ const obj = value;
122
+ const members = [];
123
+ for (const key of Object.keys(obj).sort()) {
124
+ const item = obj[key];
125
+ if (item === void 0) continue;
126
+ members.push(`${JSON.stringify(key)}:${serialize(item)}`);
127
+ }
128
+ return `{${members.join(",")}}`;
129
+ }
130
+ async function computeIntentInputDigest(intentInput) {
131
+ const canonical = jcsCanonicalise(intentInput);
132
+ const encoded = new TextEncoder().encode(canonical);
133
+ const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
134
+ return Array.from(new Uint8Array(hashBuffer)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
135
+ }
136
+ function parseIntentInput(intentInput) {
137
+ if (typeof intentInput !== "object" || intentInput === null) {
138
+ throw new Error("intentInput must be a non-null object");
139
+ }
140
+ const input = intentInput;
141
+ if (typeof input.destinationChainId !== "number") {
142
+ throw new Error("intentInput.destinationChainId must be a number");
143
+ }
144
+ if (typeof input.account !== "object" || input.account === null) {
145
+ throw new Error("intentInput.account must be a non-null object");
146
+ }
147
+ if (typeof input.account.address !== "string") {
148
+ throw new Error("intentInput.account.address must be a string");
149
+ }
150
+ if (!Array.isArray(input.destinationExecutions)) {
151
+ throw new Error("intentInput.destinationExecutions must be an array");
152
+ }
153
+ return {
154
+ chain: { id: input.destinationChainId },
155
+ account: input.account.address,
156
+ calls: input.destinationExecutions.map((execution) => ({
157
+ to: execution.to,
158
+ value: BigInt(execution.value),
159
+ data: execution.data
160
+ }))
161
+ };
162
+ }
163
+ async function shouldSponsor(intentInput, filters) {
164
+ const parsed = parseIntentInput(intentInput);
165
+ if (filters.chain && !await filters.chain(parsed.chain)) {
166
+ return false;
167
+ }
168
+ if (filters.account && !await filters.account(parsed.account)) {
169
+ return false;
170
+ }
171
+ if (filters.calls && !await filters.calls(parsed.calls)) {
172
+ return false;
173
+ }
174
+ return true;
175
+ }
176
+ function pickAlg(jwk) {
177
+ if (jwk.kty === "EC") {
178
+ if (jwk.crv === "P-256") return "ES256";
179
+ if (jwk.crv === "P-384") return "ES384";
180
+ if (jwk.crv === "P-521") return "ES512";
181
+ throw new Error(`Unsupported EC curve: ${jwk.crv}`);
182
+ }
183
+ if (jwk.kty === "RSA") return "RS256";
184
+ throw new Error(`Unsupported JWK kty: ${jwk.kty}`);
185
+ }
186
+ function createJwtSigner(config) {
187
+ const {
188
+ jwt: {
189
+ privateKey,
190
+ integratorId,
191
+ projectId,
192
+ appId,
193
+ keyId,
194
+ audience = "rhinestone-api"
195
+ },
196
+ shouldSponsor: filters
197
+ } = config;
198
+ const alg = pickAlg(privateKey);
199
+ let cachedKey = null;
200
+ async function getKey() {
201
+ if (!cachedKey) {
202
+ cachedKey = await importJWK(privateKey, alg);
203
+ }
204
+ return cachedKey;
205
+ }
206
+ return {
207
+ accessToken: async () => {
208
+ const key = await getKey();
209
+ return new SignJWT({ typ: "access", app_id: appId }).setProtectedHeader({ alg, kid: keyId }).setIssuer(integratorId).setSubject(projectId).setAudience(audience).setIssuedAt().setExpirationTime("1h").sign(key);
210
+ },
211
+ getIntentExtensionToken: async (intentInput) => {
212
+ if (filters && !await shouldSponsor(intentInput, filters)) {
213
+ throw new SponsorshipDeniedError();
214
+ }
215
+ const key = await getKey();
216
+ const digest = await computeIntentInputDigest(intentInput);
217
+ return new SignJWT({
218
+ typ: "intent_extension",
219
+ app_id: appId,
220
+ jti: crypto.randomUUID(),
221
+ policy: {
222
+ sponsorship: {
223
+ scope: "intent",
224
+ intent_input: { digest }
225
+ }
226
+ }
227
+ }).setProtectedHeader({ alg, kid: keyId }).setIssuer(integratorId).setSubject(projectId).setAudience(audience).setIssuedAt().setExpirationTime("5m").sign(key);
228
+ }
229
+ };
230
+ }
231
+ function readCredentialsFromEnv(env) {
232
+ const missing = [];
233
+ const read = (key) => {
234
+ const value = env[key];
235
+ if (!value) missing.push(key);
236
+ return value ?? "";
237
+ };
238
+ const privateKeyRaw = read(ENV_KEYS.privateKey);
239
+ const integratorId = read(ENV_KEYS.integratorId);
240
+ const projectId = read(ENV_KEYS.projectId);
241
+ const appId = read(ENV_KEYS.appId);
242
+ const keyId = read(ENV_KEYS.keyId);
243
+ if (missing.length > 0) {
244
+ throw new Error(
245
+ `createSponsorshipSigner: missing env var(s): ${missing.join(", ")}`
246
+ );
247
+ }
248
+ let privateKey;
249
+ try {
250
+ privateKey = JSON.parse(privateKeyRaw);
251
+ } catch {
252
+ throw new Error(
253
+ `createSponsorshipSigner: ${ENV_KEYS.privateKey} must be a JSON-encoded JWK`
254
+ );
255
+ }
256
+ return { privateKey, integratorId, projectId, appId, keyId };
257
+ }
258
+ function createSponsorshipSigner(options = {}) {
259
+ const credentials = options.credentials ?? readCredentialsFromEnv(options.env ?? process.env);
260
+ const inner = createJwtSigner({
261
+ jwt: credentials,
262
+ shouldSponsor: options.shouldSponsor
263
+ });
264
+ return {
265
+ accessToken: () => inner.accessToken(),
266
+ extensionToken: (intentOp) => {
267
+ const intentInput = typeof intentOp === "string" ? JSON.parse(intentOp) : intentOp;
268
+ return inner.getIntentExtensionToken(intentInput);
269
+ }
270
+ };
271
+ }
272
+ export {
273
+ OneAuthAccountVerificationError,
274
+ SponsorshipDeniedError,
275
+ createJwtSigner,
276
+ createSponsorshipSigner,
277
+ encodeWebAuthnSignature,
278
+ hashMessage,
279
+ verifyMessageHash,
280
+ verifyOneAuthAccount
281
+ };
282
+ //# sourceMappingURL=server.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts"],"sourcesContent":["/**\n * Server-side utilities for JWT sponsorship.\n *\n * The recommended entry point is `createSponsorshipSigner`, a\n * framework-agnostic factory that reads credentials from environment\n * variables and exposes the two operations each sponsorship endpoint\n * needs: `accessToken()` and `extensionToken(intentOp)`.\n *\n * For custom claims or non-standard flows, `createJwtSigner` is exposed as\n * an escape hatch. The implementation lives here instead of re-exporting\n * `@rhinestone/sdk/jwt-server` directly so downstream app builds do not need\n * to resolve the SDK's optional Express adapter surface.\n *\n * @example Next.js App Router\n * ```ts\n * // app/api/sponsorship/access-token/route.ts\n * import { createSponsorshipSigner } from \"@rhinestone/1auth/server\";\n *\n * const signer = createSponsorshipSigner();\n *\n * export async function GET() {\n * // Guard with your own session/auth before minting.\n * return Response.json({ token: await signer.accessToken() });\n * }\n * ```\n */\n\nimport { SignJWT, importJWK } from \"jose\";\nimport { isAddress, type Address, type Hex } from \"viem\";\n\nexport { hashMessage, verifyMessageHash } from \"./verify\";\nexport { encodeWebAuthnSignature } from \"./walletClient/utils\";\nexport type { WebAuthnSignature } from \"./types\";\n\nexport interface JwtCredentials {\n privateKey: JsonWebKey;\n integratorId: string;\n projectId: string;\n appId: string;\n keyId: string;\n audience?: string;\n}\n\nexport interface SponsorshipFilter {\n chain?: (chain: { id: number }) => boolean | Promise<boolean>;\n account?: (address: Address) => boolean | Promise<boolean>;\n calls?: (\n calls: {\n to: Address;\n value: bigint;\n data: Hex;\n }[],\n ) => boolean | Promise<boolean>;\n}\n\nexport interface JwtSignerConfig {\n jwt: JwtCredentials;\n shouldSponsor?: SponsorshipFilter;\n}\n\nexport class SponsorshipDeniedError extends Error {\n constructor() {\n super(\"Sponsorship denied\");\n this.name = \"SponsorshipDeniedError\";\n }\n}\n\n/**\n * Sponsorship signer used by the two endpoints the SDK client calls:\n *\n * - `accessToken()` — mints the app's identity token; return as\n * `{ token }` from `GET /sponsorship/access-token`.\n * - `extensionToken(intentOp)` — mints a per-intent sponsorship grant;\n * return as `{ token }` from `POST /sponsorship/extension-token`.\n * Accepts either the JSON-stringified `intentOp` the SDK sends or a\n * pre-parsed object.\n */\nexport interface SponsorshipSigner {\n accessToken(): Promise<string>;\n extensionToken(intentOp: string | object): Promise<string>;\n}\n\nexport interface CreateSponsorshipSignerOptions {\n /** Override all credentials explicitly (skips env lookup). */\n credentials?: JwtCredentials;\n /** Override the env source (defaults to `process.env`). */\n env?: NodeJS.ProcessEnv;\n /** Optional per-intent sponsorship filter (see `@rhinestone/sdk/jwt-server`). */\n shouldSponsor?: SponsorshipFilter;\n}\n\nexport interface VerifyOneAuthAccountOptions {\n /** 1auth provider origin, for example `https://passkey.1auth.box`. */\n providerUrl: string;\n /** Smart account address returned by a successful 1auth auth result. */\n address: Address;\n /** Optional app client id forwarded to provider APIs that scope by app. */\n clientId?: string;\n /** Injectable fetch implementation for tests and non-standard runtimes. */\n fetch?: typeof fetch;\n}\n\nexport interface VerifiedOneAuthAccount {\n address: Address;\n deployed?: boolean;\n chainId?: number;\n}\n\n/** Error raised when the provider cannot bind an address to a 1auth account. */\nexport class OneAuthAccountVerificationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"OneAuthAccountVerificationError\";\n }\n}\n\nconst ENV_KEYS = {\n privateKey: \"RHINESTONE_JWT_PRIVATE_KEY\",\n integratorId: \"RHINESTONE_INTEGRATOR_ID\",\n projectId: \"RHINESTONE_PROJECT_ID\",\n appId: \"RHINESTONE_APP_ID\",\n keyId: \"RHINESTONE_KEY_ID\",\n} as const;\n\n/** Build the documented account-lookup URL for a 1auth provider. */\nfunction accountLookupUrl(providerUrl: string, address: Address): string {\n return new URL(`/api/account/${address.toLowerCase()}`, providerUrl).toString();\n}\n\n/** Safely parse a provider account lookup response. */\nasync function parseAccountLookupResponse(response: Response): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n return null;\n }\n}\n\n/**\n * Verify that an address belongs to a 1auth account known by the configured\n * provider. This is intended for server-side app sessions that already have a\n * fresh challenge signature and need to reject arbitrary ERC-1271 contracts.\n */\nexport async function verifyOneAuthAccount(\n options: VerifyOneAuthAccountOptions,\n): Promise<VerifiedOneAuthAccount> {\n if (!isAddress(options.address)) {\n throw new OneAuthAccountVerificationError(\n \"A valid 1auth account address is required\",\n );\n }\n\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== \"function\") {\n throw new OneAuthAccountVerificationError(\n \"No fetch implementation is available to verify the 1auth account\",\n );\n }\n\n const url = accountLookupUrl(options.providerUrl, options.address);\n const headers: HeadersInit = { accept: \"application/json\" };\n if (options.clientId) headers[\"x-client-id\"] = options.clientId;\n\n let response: Response;\n try {\n response = await fetchImpl(url, {\n headers,\n cache: \"no-store\",\n });\n } catch (error) {\n throw new OneAuthAccountVerificationError(\n `Unable to reach the configured 1auth provider: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n\n const body = await parseAccountLookupResponse(response);\n if (!response.ok) {\n const message =\n body && typeof body === \"object\" && \"error\" in body\n ? String((body as { error: unknown }).error)\n : response.statusText || \"account lookup failed\";\n throw new OneAuthAccountVerificationError(\n `Configured 1auth provider did not recognize this account (${response.status}: ${message})`,\n );\n }\n\n const account = body as Partial<VerifiedOneAuthAccount> | null;\n if (!account?.address || !isAddress(account.address)) {\n throw new OneAuthAccountVerificationError(\n \"Configured 1auth provider returned a malformed account record\",\n );\n }\n if (account.address.toLowerCase() !== options.address.toLowerCase()) {\n throw new OneAuthAccountVerificationError(\n \"Configured 1auth provider returned a different account address\",\n );\n }\n\n return {\n address: account.address,\n deployed:\n typeof account.deployed === \"boolean\" ? account.deployed : undefined,\n chainId: typeof account.chainId === \"number\" ? account.chainId : undefined,\n };\n}\n\n/**\n * RFC 8785 JSON Canonicalization Scheme (JCS).\n *\n * The digest embedded in extension tokens must be byte-for-byte stable across\n * environments, so we canonicalize JSON before hashing instead of trusting\n * ordinary `JSON.stringify` object key order.\n */\nfunction jcsCanonicalise(value: unknown): string {\n return serialize(value);\n}\n\nfunction serialize(value: unknown): string {\n if (value === null || value === undefined) {\n return \"null\";\n }\n\n switch (typeof value) {\n case \"boolean\":\n return value ? \"true\" : \"false\";\n case \"number\":\n if (!Number.isFinite(value)) {\n throw new Error(`JCS: non-finite number: ${value}`);\n }\n return Object.is(value, -0) ? \"0\" : String(value);\n case \"string\":\n return JSON.stringify(value);\n case \"bigint\":\n if (\n value > BigInt(Number.MAX_SAFE_INTEGER) ||\n value < BigInt(-Number.MAX_SAFE_INTEGER)\n ) {\n throw new Error(\n `JCS: BigInt ${value} exceeds safe integer range — convert to string before calling`,\n );\n }\n return String(value);\n default:\n break;\n }\n\n if (Array.isArray(value)) {\n return `[${value.map((item) => serialize(item)).join(\",\")}]`;\n }\n\n const obj = value as Record<string, unknown>;\n const members: string[] = [];\n for (const key of Object.keys(obj).sort()) {\n const item = obj[key];\n if (item === undefined) continue;\n members.push(`${JSON.stringify(key)}:${serialize(item)}`);\n }\n return `{${members.join(\",\")}}`;\n}\n\n/**\n * Compute the canonical digest embedded in per-intent sponsorship grants.\n */\nasync function computeIntentInputDigest(intentInput: unknown): Promise<string> {\n const canonical = jcsCanonicalise(intentInput);\n const encoded = new TextEncoder().encode(canonical);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encoded);\n return Array.from(new Uint8Array(hashBuffer))\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction parseIntentInput(intentInput: unknown) {\n if (typeof intentInput !== \"object\" || intentInput === null) {\n throw new Error(\"intentInput must be a non-null object\");\n }\n\n const input = intentInput as {\n destinationChainId?: number;\n account?: { address?: string };\n destinationExecutions?: { to: Address; value: string; data: Hex }[];\n };\n\n if (typeof input.destinationChainId !== \"number\") {\n throw new Error(\"intentInput.destinationChainId must be a number\");\n }\n\n if (typeof input.account !== \"object\" || input.account === null) {\n throw new Error(\"intentInput.account must be a non-null object\");\n }\n\n if (typeof input.account.address !== \"string\") {\n throw new Error(\"intentInput.account.address must be a string\");\n }\n\n if (!Array.isArray(input.destinationExecutions)) {\n throw new Error(\"intentInput.destinationExecutions must be an array\");\n }\n\n return {\n chain: { id: input.destinationChainId },\n account: input.account.address as Address,\n calls: input.destinationExecutions.map((execution) => ({\n to: execution.to,\n value: BigInt(execution.value),\n data: execution.data,\n })),\n };\n}\n\nasync function shouldSponsor(\n intentInput: unknown,\n filters: SponsorshipFilter,\n): Promise<boolean> {\n const parsed = parseIntentInput(intentInput);\n if (filters.chain && !(await filters.chain(parsed.chain))) {\n return false;\n }\n if (filters.account && !(await filters.account(parsed.account))) {\n return false;\n }\n if (filters.calls && !(await filters.calls(parsed.calls))) {\n return false;\n }\n return true;\n}\n\nfunction pickAlg(jwk: JsonWebKey): \"ES256\" | \"ES384\" | \"ES512\" | \"RS256\" {\n if (jwk.kty === \"EC\") {\n if (jwk.crv === \"P-256\") return \"ES256\";\n if (jwk.crv === \"P-384\") return \"ES384\";\n if (jwk.crv === \"P-521\") return \"ES512\";\n throw new Error(`Unsupported EC curve: ${jwk.crv}`);\n }\n if (jwk.kty === \"RSA\") return \"RS256\";\n throw new Error(`Unsupported JWK kty: ${jwk.kty}`);\n}\n\n/**\n * Create a low-level JWT signer compatible with Rhinestone sponsorship flows.\n *\n * This mirrors the upstream SDK behavior while keeping our public server entry\n * point self-contained for app bundlers.\n */\nexport function createJwtSigner(config: JwtSignerConfig) {\n const {\n jwt: {\n privateKey,\n integratorId,\n projectId,\n appId,\n keyId,\n audience = \"rhinestone-api\",\n },\n shouldSponsor: filters,\n } = config;\n\n const alg = pickAlg(privateKey);\n let cachedKey: Awaited<ReturnType<typeof importJWK>> | null = null;\n\n async function getKey() {\n if (!cachedKey) {\n cachedKey = await importJWK(privateKey, alg);\n }\n return cachedKey;\n }\n\n return {\n accessToken: async () => {\n const key = await getKey();\n return new SignJWT({ typ: \"access\", app_id: appId })\n .setProtectedHeader({ alg, kid: keyId })\n .setIssuer(integratorId)\n .setSubject(projectId)\n .setAudience(audience)\n .setIssuedAt()\n .setExpirationTime(\"1h\")\n .sign(key);\n },\n getIntentExtensionToken: async (intentInput: unknown) => {\n if (filters && !(await shouldSponsor(intentInput, filters))) {\n throw new SponsorshipDeniedError();\n }\n\n const key = await getKey();\n const digest = await computeIntentInputDigest(intentInput);\n return new SignJWT({\n typ: \"intent_extension\",\n app_id: appId,\n jti: crypto.randomUUID(),\n policy: {\n sponsorship: {\n scope: \"intent\",\n intent_input: { digest },\n },\n },\n })\n .setProtectedHeader({ alg, kid: keyId })\n .setIssuer(integratorId)\n .setSubject(projectId)\n .setAudience(audience)\n .setIssuedAt()\n .setExpirationTime(\"5m\")\n .sign(key);\n },\n };\n}\n\nfunction readCredentialsFromEnv(env: NodeJS.ProcessEnv): JwtCredentials {\n const missing: string[] = [];\n const read = (key: string) => {\n const value = env[key];\n if (!value) missing.push(key);\n return value ?? \"\";\n };\n\n const privateKeyRaw = read(ENV_KEYS.privateKey);\n const integratorId = read(ENV_KEYS.integratorId);\n const projectId = read(ENV_KEYS.projectId);\n const appId = read(ENV_KEYS.appId);\n const keyId = read(ENV_KEYS.keyId);\n\n if (missing.length > 0) {\n throw new Error(\n `createSponsorshipSigner: missing env var(s): ${missing.join(\", \")}`,\n );\n }\n\n let privateKey: JsonWebKey;\n try {\n privateKey = JSON.parse(privateKeyRaw) as JsonWebKey;\n } catch {\n throw new Error(\n `createSponsorshipSigner: ${ENV_KEYS.privateKey} must be a JSON-encoded JWK`,\n );\n }\n\n return { privateKey, integratorId, projectId, appId, keyId };\n}\n\nexport function createSponsorshipSigner(\n options: CreateSponsorshipSignerOptions = {},\n): SponsorshipSigner {\n const credentials =\n options.credentials ?? readCredentialsFromEnv(options.env ?? process.env);\n\n const inner = createJwtSigner({\n jwt: credentials,\n shouldSponsor: options.shouldSponsor,\n });\n\n return {\n accessToken: () => inner.accessToken(),\n extensionToken: (intentOp) => {\n const intentInput =\n typeof intentOp === \"string\" ? JSON.parse(intentOp) : intentOp;\n return inner.getIntentExtensionToken(intentInput);\n },\n };\n}\n"],"mappings":"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","names":[]}