@rhinestone/1auth 0.7.1 → 0.7.3

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.
@@ -1,5 +1,5 @@
1
- import { O as OneAuthClient } from './client-B_CzDa_I.js';
2
- import { a0 as CloseOnStatus } from './types-U_dwxbtS.js';
1
+ import { O as OneAuthClient } from './client-CuASptX3.js';
2
+ import { a0 as CloseOnStatus } from './types-C0jKNT_t.js';
3
3
 
4
4
  /**
5
5
  * EIP-1193 JSON-RPC provider factory for the 1auth passkey authentication system.
@@ -1,5 +1,5 @@
1
- import { O as OneAuthClient } from './client-F4DnFM8d.mjs';
2
- import { a0 as CloseOnStatus } from './types-U_dwxbtS.mjs';
1
+ import { O as OneAuthClient } from './client-D4HVy1KF.mjs';
2
+ import { a0 as CloseOnStatus } from './types-C0jKNT_t.mjs';
3
3
 
4
4
  /**
5
5
  * EIP-1193 JSON-RPC provider factory for the 1auth passkey authentication system.
package/dist/react.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import { O as OneAuthClient } from './client-F4DnFM8d.mjs';
4
- import { Y as SendIntentOptions, i as SendIntentResult, a0 as CloseOnStatus, aw as SponsorshipUrlConfig, av as SponsorshipCallbackConfig } from './types-U_dwxbtS.mjs';
3
+ import { O as OneAuthClient } from './client-D4HVy1KF.mjs';
4
+ import { Y as SendIntentOptions, i as SendIntentResult, a0 as CloseOnStatus, aw as SponsorshipUrlConfig, av as SponsorshipCallbackConfig } from './types-C0jKNT_t.mjs';
5
5
  import 'viem';
6
6
  import '@rhinestone/sdk';
7
7
 
package/dist/react.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import { O as OneAuthClient } from './client-B_CzDa_I.js';
4
- import { Y as SendIntentOptions, i as SendIntentResult, a0 as CloseOnStatus, aw as SponsorshipUrlConfig, av as SponsorshipCallbackConfig } from './types-U_dwxbtS.js';
3
+ import { O as OneAuthClient } from './client-CuASptX3.js';
4
+ import { Y as SendIntentOptions, i as SendIntentResult, a0 as CloseOnStatus, aw as SponsorshipUrlConfig, av as SponsorshipCallbackConfig } from './types-C0jKNT_t.js';
5
5
  import 'viem';
6
6
  import '@rhinestone/sdk';
7
7
 
package/dist/server.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Address, Hex } from 'viem';
2
- export { e as encodeWebAuthnSignature, a as hashMessage, v as verifyMessageHash } from './verify-C8-a5c3K.mjs';
3
- export { W as WebAuthnSignature } from './types-U_dwxbtS.mjs';
2
+ export { e as encodeWebAuthnSignature, q as hashMessage, k as isTestnet, v as verifyMessageHash } from './verify-aWdi5O2z.mjs';
3
+ export { W as WebAuthnSignature } from './types-C0jKNT_t.mjs';
4
4
  import '@rhinestone/sdk';
5
5
 
6
6
  /**
@@ -79,7 +79,7 @@ interface CreateSponsorshipSignerOptions {
79
79
  shouldSponsor?: SponsorshipFilter;
80
80
  }
81
81
  interface VerifyOneAuthAccountOptions {
82
- /** 1auth provider origin, for example `https://passkey.1auth.box`. */
82
+ /** 1auth provider origin, for example `https://passkey.1auth.app`. */
83
83
  providerUrl: string;
84
84
  /** Smart account address returned by a successful 1auth auth result. */
85
85
  address: Address;
package/dist/server.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Address, Hex } from 'viem';
2
- export { e as encodeWebAuthnSignature, a as hashMessage, v as verifyMessageHash } from './verify-BLgZzwmJ.js';
3
- export { W as WebAuthnSignature } from './types-U_dwxbtS.js';
2
+ export { e as encodeWebAuthnSignature, q as hashMessage, k as isTestnet, v as verifyMessageHash } from './verify-CnOwPq78.js';
3
+ export { W as WebAuthnSignature } from './types-C0jKNT_t.js';
4
4
  import '@rhinestone/sdk';
5
5
 
6
6
  /**
@@ -79,7 +79,7 @@ interface CreateSponsorshipSignerOptions {
79
79
  shouldSponsor?: SponsorshipFilter;
80
80
  }
81
81
  interface VerifyOneAuthAccountOptions {
82
- /** 1auth provider origin, for example `https://passkey.1auth.box`. */
82
+ /** 1auth provider origin, for example `https://passkey.1auth.app`. */
83
83
  providerUrl: string;
84
84
  /** Smart account address returned by a successful 1auth auth result. */
85
85
  address: Address;
package/dist/server.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/server.ts
@@ -26,12 +36,13 @@ __export(server_exports, {
26
36
  createSponsorshipSigner: () => createSponsorshipSigner,
27
37
  encodeWebAuthnSignature: () => encodeWebAuthnSignature,
28
38
  hashMessage: () => hashMessage,
39
+ isTestnet: () => isTestnet,
29
40
  verifyMessageHash: () => verifyMessageHash,
30
41
  verifyOneAuthAccount: () => verifyOneAuthAccount
31
42
  });
32
43
  module.exports = __toCommonJS(server_exports);
33
44
  var import_jose = require("jose");
34
- var import_viem3 = require("viem");
45
+ var import_viem4 = require("viem");
35
46
 
36
47
  // src/verify.ts
37
48
  var import_viem = require("viem");
@@ -81,6 +92,43 @@ function encodeWebAuthnSignature(sig) {
81
92
  ]);
82
93
  }
83
94
 
95
+ // src/registry.ts
96
+ var import_viem3 = require("viem");
97
+ var viemChains = __toESM(require("viem/chains"));
98
+ var import_shared_configs = require("@rhinestone/shared-configs");
99
+ var env = typeof process !== "undefined" ? process.env : {};
100
+ var VIEM_CHAIN_BY_ID = /* @__PURE__ */ new Map();
101
+ for (const value of Object.values(viemChains)) {
102
+ if (typeof value !== "object" || value === null || !("id" in value) || !("name" in value)) continue;
103
+ const chain = value;
104
+ const existing = VIEM_CHAIN_BY_ID.get(chain.id);
105
+ if (!existing || existing.testnet && !chain.testnet) {
106
+ VIEM_CHAIN_BY_ID.set(chain.id, chain);
107
+ }
108
+ }
109
+ function isEvmRegistryEntry(entry) {
110
+ return entry?.vmType === "evm";
111
+ }
112
+ var REGISTRY_CHAIN_IDS = Object.entries(import_shared_configs.chainRegistry).filter(([, entry]) => isEvmRegistryEntry(entry)).map(([id]) => Number(id));
113
+ var SUPPORTED_CHAIN_IDS = new Set(REGISTRY_CHAIN_IDS);
114
+ function getChainById(chainId) {
115
+ if (!SUPPORTED_CHAIN_IDS.has(chainId)) {
116
+ throw new Error(`Unsupported chain ID: ${chainId}`);
117
+ }
118
+ const chain = VIEM_CHAIN_BY_ID.get(chainId);
119
+ if (!chain) {
120
+ throw new Error(`Unsupported chain ID: ${chainId}`);
121
+ }
122
+ return chain;
123
+ }
124
+ function isTestnet(chainId) {
125
+ try {
126
+ return getChainById(chainId).testnet ?? false;
127
+ } catch {
128
+ return false;
129
+ }
130
+ }
131
+
84
132
  // src/server.ts
85
133
  var SponsorshipDeniedError = class extends Error {
86
134
  constructor() {
@@ -112,7 +160,7 @@ async function parseAccountLookupResponse(response) {
112
160
  }
113
161
  }
114
162
  async function verifyOneAuthAccount(options) {
115
- if (!(0, import_viem3.isAddress)(options.address)) {
163
+ if (!(0, import_viem4.isAddress)(options.address)) {
116
164
  throw new OneAuthAccountVerificationError(
117
165
  "A valid 1auth account address is required"
118
166
  );
@@ -145,7 +193,7 @@ async function verifyOneAuthAccount(options) {
145
193
  );
146
194
  }
147
195
  const account = body;
148
- if (!account?.address || !(0, import_viem3.isAddress)(account.address)) {
196
+ if (!account?.address || !(0, import_viem4.isAddress)(account.address)) {
149
197
  throw new OneAuthAccountVerificationError(
150
198
  "Configured 1auth provider returned a malformed account record"
151
199
  );
@@ -301,10 +349,10 @@ function createJwtSigner(config) {
301
349
  }
302
350
  };
303
351
  }
304
- function readCredentialsFromEnv(env) {
352
+ function readCredentialsFromEnv(env2) {
305
353
  const missing = [];
306
354
  const read = (key) => {
307
- const value = env[key];
355
+ const value = env2[key];
308
356
  if (!value) missing.push(key);
309
357
  return value ?? "";
310
358
  };
@@ -350,6 +398,7 @@ function createSponsorshipSigner(options = {}) {
350
398
  createSponsorshipSigner,
351
399
  encodeWebAuthnSignature,
352
400
  hashMessage,
401
+ isTestnet,
353
402
  verifyMessageHash,
354
403
  verifyOneAuthAccount
355
404
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server.ts","../src/verify.ts","../src/walletClient/utils.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","import { keccak256, toBytes } from \"viem\";\n\n/**\n * The EIP-191 prefix used for personal message signing.\n * This is the standard Ethereum message prefix for `personal_sign`.\n */\nexport const ETHEREUM_MESSAGE_PREFIX = \"\\x19Ethereum Signed Message:\\n\";\n\n/**\n * Hash a message with the EIP-191 Ethereum prefix.\n *\n * This is the same hashing function used by the passkey sign dialog.\n * Use this to verify that the `signedHash` returned from `signMessage()`\n * matches your original message.\n *\n * Format: keccak256(\"\\x19Ethereum Signed Message:\\n\" + len + message)\n *\n * @example\n * ```typescript\n * const message = \"Sign in to MyApp\\nTimestamp: 1234567890\";\n * const result = await client.signMessage({ username: 'alice', message });\n *\n * // Verify the hash matches\n * const expectedHash = hashMessage(message);\n * if (result.signedHash === expectedHash) {\n * console.log('Hash matches - signature is for this message');\n * }\n * ```\n */\nexport function hashMessage(message: string): `0x${string}` {\n const messageBytes = toBytes(message);\n const prefixed = ETHEREUM_MESSAGE_PREFIX + messageBytes.length.toString() + message;\n return keccak256(toBytes(prefixed));\n}\n\n/**\n * Verify that a signedHash matches the expected message.\n *\n * This is a convenience wrapper around `hashMessage()` that returns\n * a boolean. For full cryptographic verification of the P256 signature,\n * use on-chain verification via the WebAuthn.sol contract.\n *\n * @example\n * ```typescript\n * const result = await client.signMessage({ username: 'alice', message });\n *\n * if (result.success && verifyMessageHash(message, result.signedHash)) {\n * // The signature is for this exact message\n * // For full verification, verify the P256 signature on-chain or server-side\n * }\n * ```\n */\nexport function verifyMessageHash(\n message: string,\n signedHash: string | undefined\n): boolean {\n if (!signedHash) return false;\n const expectedHash = hashMessage(message);\n return expectedHash.toLowerCase() === signedHash.toLowerCase();\n}\n","import { encodeAbiParameters, keccak256 } from 'viem';\nimport type { Hex } from 'viem';\nimport type { WebAuthnSignature } from '../types';\nimport type { TransactionCall } from './types';\n\n/**\n * P-256 curve order (n)\n * Used for signature malleability normalization\n */\nconst P256_N = BigInt(\n '0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551'\n);\nconst P256_N_DIV_2 = P256_N / 2n;\n\n/**\n * WebAuthnAuth struct type for ABI encoding\n */\nconst WEBAUTHN_AUTH_TYPE = {\n type: 'tuple',\n components: [\n { type: 'bytes', name: 'authenticatorData' },\n { type: 'string', name: 'clientDataJSON' },\n { type: 'uint256', name: 'challengeIndex' },\n { type: 'uint256', name: 'typeIndex' },\n { type: 'uint256', name: 'r' },\n { type: 'uint256', name: 's' },\n ],\n} as const;\n\n/**\n * Encode a WebAuthn signature for ERC-1271 verification on-chain\n *\n * @param sig - The WebAuthn signature from the passkey\n * @returns ABI-encoded signature bytes\n */\nexport function encodeWebAuthnSignature(sig: WebAuthnSignature): Hex {\n // Normalize s to prevent signature malleability\n let s = BigInt(sig.s);\n if (s > P256_N_DIV_2) {\n s = P256_N - s;\n }\n\n return encodeAbiParameters([WEBAUTHN_AUTH_TYPE], [\n {\n authenticatorData: sig.authenticatorData as Hex,\n clientDataJSON: sig.clientDataJSON,\n challengeIndex: BigInt(sig.challengeIndex),\n typeIndex: BigInt(sig.typeIndex),\n r: BigInt(sig.r),\n s,\n },\n ]);\n}\n\n/**\n * Hash an array of transaction calls for signing\n *\n * @param calls - Array of transaction calls\n * @returns keccak256 hash of the encoded calls\n */\nexport function hashCalls(calls: TransactionCall[]): Hex {\n const encoded = encodeAbiParameters(\n [\n {\n type: 'tuple[]',\n components: [\n { type: 'address', name: 'to' },\n { type: 'bytes', name: 'data' },\n { type: 'uint256', name: 'value' },\n ],\n },\n ],\n [\n calls.map((c) => ({\n to: c.to,\n data: c.data || '0x',\n value: c.value || 0n,\n })),\n ]\n );\n return keccak256(encoded);\n}\n\n/**\n * Build transaction review display data from calls\n *\n * @param calls - Array of transaction calls\n * @returns TransactionDetails for the signing modal\n */\nexport function buildTransactionReview(calls: TransactionCall[]) {\n return {\n actions: calls.map((call, i) => ({\n type: 'custom' as const,\n label: call.label || `Contract Call ${i + 1}`,\n sublabel: call.sublabel || `To: ${call.to.slice(0, 10)}...${call.to.slice(-8)}`,\n amount: call.value ? `${call.value} wei` : undefined,\n })),\n };\n}\n"],"mappings":"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","names":["import_viem","import_viem"]}
1
+ {"version":3,"sources":["../src/server.ts","../src/verify.ts","../src/walletClient/utils.ts","../src/registry.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// Re-exported so sponsorship endpoints can build a `shouldSponsor` chain\n// policy without importing the browser-oriented main entry. `isTestnet` fails\n// closed (unknown/unrecognised chain id → false), which is the safe default\n// for a sponsorship gate: deny anything we can't positively classify.\nexport { isTestnet } from \"./registry\";\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.app`. */\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","import { keccak256, toBytes } from \"viem\";\n\n/**\n * The EIP-191 prefix used for personal message signing.\n * This is the standard Ethereum message prefix for `personal_sign`.\n */\nexport const ETHEREUM_MESSAGE_PREFIX = \"\\x19Ethereum Signed Message:\\n\";\n\n/**\n * Hash a message with the EIP-191 Ethereum prefix.\n *\n * This is the same hashing function used by the passkey sign dialog.\n * Use this to verify that the `signedHash` returned from `signMessage()`\n * matches your original message.\n *\n * Format: keccak256(\"\\x19Ethereum Signed Message:\\n\" + len + message)\n *\n * @example\n * ```typescript\n * const message = \"Sign in to MyApp\\nTimestamp: 1234567890\";\n * const result = await client.signMessage({ username: 'alice', message });\n *\n * // Verify the hash matches\n * const expectedHash = hashMessage(message);\n * if (result.signedHash === expectedHash) {\n * console.log('Hash matches - signature is for this message');\n * }\n * ```\n */\nexport function hashMessage(message: string): `0x${string}` {\n const messageBytes = toBytes(message);\n const prefixed = ETHEREUM_MESSAGE_PREFIX + messageBytes.length.toString() + message;\n return keccak256(toBytes(prefixed));\n}\n\n/**\n * Verify that a signedHash matches the expected message.\n *\n * This is a convenience wrapper around `hashMessage()` that returns\n * a boolean. For full cryptographic verification of the P256 signature,\n * use on-chain verification via the WebAuthn.sol contract.\n *\n * @example\n * ```typescript\n * const result = await client.signMessage({ username: 'alice', message });\n *\n * if (result.success && verifyMessageHash(message, result.signedHash)) {\n * // The signature is for this exact message\n * // For full verification, verify the P256 signature on-chain or server-side\n * }\n * ```\n */\nexport function verifyMessageHash(\n message: string,\n signedHash: string | undefined\n): boolean {\n if (!signedHash) return false;\n const expectedHash = hashMessage(message);\n return expectedHash.toLowerCase() === signedHash.toLowerCase();\n}\n","import { encodeAbiParameters, keccak256 } from 'viem';\nimport type { Hex } from 'viem';\nimport type { WebAuthnSignature } from '../types';\nimport type { TransactionCall } from './types';\n\n/**\n * P-256 curve order (n)\n * Used for signature malleability normalization\n */\nconst P256_N = BigInt(\n '0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551'\n);\nconst P256_N_DIV_2 = P256_N / 2n;\n\n/**\n * WebAuthnAuth struct type for ABI encoding\n */\nconst WEBAUTHN_AUTH_TYPE = {\n type: 'tuple',\n components: [\n { type: 'bytes', name: 'authenticatorData' },\n { type: 'string', name: 'clientDataJSON' },\n { type: 'uint256', name: 'challengeIndex' },\n { type: 'uint256', name: 'typeIndex' },\n { type: 'uint256', name: 'r' },\n { type: 'uint256', name: 's' },\n ],\n} as const;\n\n/**\n * Encode a WebAuthn signature for ERC-1271 verification on-chain\n *\n * @param sig - The WebAuthn signature from the passkey\n * @returns ABI-encoded signature bytes\n */\nexport function encodeWebAuthnSignature(sig: WebAuthnSignature): Hex {\n // Normalize s to prevent signature malleability\n let s = BigInt(sig.s);\n if (s > P256_N_DIV_2) {\n s = P256_N - s;\n }\n\n return encodeAbiParameters([WEBAUTHN_AUTH_TYPE], [\n {\n authenticatorData: sig.authenticatorData as Hex,\n clientDataJSON: sig.clientDataJSON,\n challengeIndex: BigInt(sig.challengeIndex),\n typeIndex: BigInt(sig.typeIndex),\n r: BigInt(sig.r),\n s,\n },\n ]);\n}\n\n/**\n * Hash an array of transaction calls for signing\n *\n * @param calls - Array of transaction calls\n * @returns keccak256 hash of the encoded calls\n */\nexport function hashCalls(calls: TransactionCall[]): Hex {\n const encoded = encodeAbiParameters(\n [\n {\n type: 'tuple[]',\n components: [\n { type: 'address', name: 'to' },\n { type: 'bytes', name: 'data' },\n { type: 'uint256', name: 'value' },\n ],\n },\n ],\n [\n calls.map((c) => ({\n to: c.to,\n data: c.data || '0x',\n value: c.value || 0n,\n })),\n ]\n );\n return keccak256(encoded);\n}\n\n/**\n * Build transaction review display data from calls\n *\n * @param calls - Array of transaction calls\n * @returns TransactionDetails for the signing modal\n */\nexport function buildTransactionReview(calls: TransactionCall[]) {\n return {\n actions: calls.map((call, i) => ({\n type: 'custom' as const,\n label: call.label || `Contract Call ${i + 1}`,\n sublabel: call.sublabel || `To: ${call.to.slice(0, 10)}...${call.to.slice(-8)}`,\n amount: call.value ? `${call.value} wei` : undefined,\n })),\n };\n}\n","/**\n * @file Chain and token registry for the 1auth SDK.\n *\n * Wraps `@rhinestone/shared-configs` chain/token data and combines it with\n * viem's chain definitions to expose a filtered, testnet-aware registry.\n * Consumers can look up supported chains and tokens, resolve token addresses\n * by symbol, and retrieve chain metadata such as explorer URLs and default RPC\n * endpoints.\n *\n * Testnet inclusion is controlled by the `includeTestnets` option on each\n * function or, as a project-wide default, by the environment variables\n * `NEXT_PUBLIC_ORCHESTRATOR_USE_TESTNETS` or `ORCHESTRATOR_USE_TESTNETS`.\n */\n\nimport type { Address, Chain } from \"viem\";\nimport { isAddress } from \"viem\";\nimport * as viemChains from \"viem/chains\";\nimport { chainRegistry } from \"@rhinestone/shared-configs\";\n\nexport type TokenConfig = {\n symbol: string;\n address: Address;\n decimals: number;\n};\n\nexport type ChainFilterOptions = {\n includeTestnets?: boolean;\n chainIds?: number[];\n};\n\ntype ChainRegistryEntry = (typeof chainRegistry)[keyof typeof chainRegistry];\n\nconst env: Record<string, string | undefined> =\n typeof process !== \"undefined\" ? process.env : {};\n\n// Build a chain-ID-to-Chain map from viem, resolving collisions by preferring\n// mainnet definitions over testnets. viem exports duplicate numeric IDs (e.g.\n// zoraTestnet and hyperEvm both use 999); a naive Map would silently keep\n// whichever entry happens to appear last in iteration order, which may be the\n// testnet. The loop below only overwrites an existing entry when the incoming\n// chain is NOT a testnet and the existing one IS, ensuring the production chain\n// always wins while still falling back to a testnet entry when no mainnet\n// definition exists for a given ID.\nconst VIEM_CHAIN_BY_ID = new Map<number, Chain>();\nfor (const value of Object.values(viemChains)) {\n if (typeof value !== \"object\" || value === null || !(\"id\" in value) || !(\"name\" in value)) continue;\n const chain = value as Chain;\n const existing = VIEM_CHAIN_BY_ID.get(chain.id);\n if (!existing || (existing.testnet && !chain.testnet)) {\n VIEM_CHAIN_BY_ID.set(chain.id, chain);\n }\n}\n\nfunction isEvmRegistryEntry(\n entry: ChainRegistryEntry | undefined,\n): entry is ChainRegistryEntry & { vmType: \"evm\" } {\n return entry?.vmType === \"evm\";\n}\n\nfunction getEvmRegistryEntry(\n chainId: number,\n): (ChainRegistryEntry & { vmType: \"evm\" }) | undefined {\n const entry = chainRegistry[String(chainId) as keyof typeof chainRegistry];\n return isEvmRegistryEntry(entry) ? entry : undefined;\n}\n\n// The shared-configs registry includes non-EVM chains (Solana, Tron). Filter\n// to EVM entries before exposing supported chains — downstream consumers\n// (viem clients, wallet_getCapabilities, RPC proxy) only handle eip155 chains.\nconst REGISTRY_CHAIN_IDS = Object.entries(chainRegistry)\n .filter(([, entry]) => isEvmRegistryEntry(entry))\n .map(([id]) => Number(id));\nconst SUPPORTED_CHAIN_IDS = new Set(REGISTRY_CHAIN_IDS);\n\nfunction tokensForChain(chainId: number): TokenConfig[] {\n const entry = getEvmRegistryEntry(chainId);\n if (!entry) return [];\n return entry.tokens.map((token) => ({\n symbol: token.symbol,\n address: token.address as Address,\n decimals: token.decimals,\n }));\n}\n\n/** Treat any 20-byte hex string as an address; checksum casing is optional for user inputs. */\nfunction isAddressInput(value: string): value is Address {\n return isAddress(value, { strict: false });\n}\n\n/**\n * Parse a string environment variable into a boolean, returning `undefined`\n * when the value is absent or not a recognised truthy/falsy literal.\n *\n * Accepted truthy values: `\"true\"`, `\"1\"`.\n * Accepted falsy values: `\"false\"`, `\"0\"`.\n */\nfunction parseBool(value?: string): boolean | undefined {\n if (value === \"true\" || value === \"1\") return true;\n if (value === \"false\" || value === \"0\") return false;\n return undefined;\n}\n\n/**\n * Determine whether testnet chains should be included in registry results.\n *\n * Precedence (highest to lowest):\n * 1. `explicit` argument — a caller-supplied boolean always wins.\n * 2. `NEXT_PUBLIC_ORCHESTRATOR_USE_TESTNETS` env var — checked first so\n * Next.js browser bundles (which only expose `NEXT_PUBLIC_*` variables)\n * can configure testnet mode without a server-side env var.\n * 3. `ORCHESTRATOR_USE_TESTNETS` env var — server-side / Node.js fallback.\n * 4. Defaults to `false` (testnets excluded) when none of the above is set.\n */\nfunction resolveIncludeTestnets(explicit?: boolean): boolean {\n if (explicit !== undefined) return explicit;\n const envValue =\n parseBool(env.NEXT_PUBLIC_ORCHESTRATOR_USE_TESTNETS) ??\n parseBool(env.ORCHESTRATOR_USE_TESTNETS);\n return envValue ?? false;\n}\n\nfunction applyChainFilters(chainIds: number[], options?: ChainFilterOptions): number[] {\n const includeTestnets = resolveIncludeTestnets(options?.includeTestnets);\n const allowlist = options?.chainIds;\n let filtered = chainIds;\n\n if (!includeTestnets) {\n filtered = filtered.filter((chainId) => !isTestnet(chainId));\n }\n\n if (allowlist) {\n const allowed = new Set(allowlist);\n filtered = filtered.filter((chainId) => allowed.has(chainId));\n }\n\n return filtered;\n}\n\nexport function getSupportedChainIds(options?: ChainFilterOptions): number[] {\n return applyChainFilters(REGISTRY_CHAIN_IDS, options);\n}\n\nexport function getSupportedChains(options?: ChainFilterOptions): Chain[] {\n return getSupportedChainIds(options)\n .map((chainId) => VIEM_CHAIN_BY_ID.get(chainId))\n .filter((chain): chain is Chain => Boolean(chain));\n}\n\nexport function getAllSupportedChainsAndTokens(options?: ChainFilterOptions): Array<{\n chainId: number;\n tokens: TokenConfig[];\n}> {\n return getSupportedChainIds(options).map((chainId) => ({\n chainId,\n tokens: tokensForChain(chainId),\n }));\n}\n\nexport function getChainById(chainId: number): Chain {\n if (!SUPPORTED_CHAIN_IDS.has(chainId)) {\n throw new Error(`Unsupported chain ID: ${chainId}`);\n }\n const chain = VIEM_CHAIN_BY_ID.get(chainId);\n if (!chain) {\n throw new Error(`Unsupported chain ID: ${chainId}`);\n }\n return chain;\n}\n\nexport function getChainName(chainId: number): string {\n try {\n return getChainById(chainId).name;\n } catch {\n return `Chain ${chainId}`;\n }\n}\n\nexport function getChainExplorerUrl(chainId: number): string | undefined {\n try {\n return getChainById(chainId).blockExplorers?.default?.url;\n } catch {\n return undefined;\n }\n}\n\nexport function getChainRpcUrl(chainId: number): string | undefined {\n try {\n const chain = getChainById(chainId);\n return chain.rpcUrls?.default?.http?.[0] || chain.rpcUrls?.public?.http?.[0];\n } catch {\n return undefined;\n }\n}\n\nexport function getSupportedTokens(chainId: number): TokenConfig[] {\n return tokensForChain(chainId);\n}\n\nexport function getSupportedTokenSymbols(chainId: number): string[] {\n return getSupportedTokens(chainId).map((token) => token.symbol);\n}\n\nexport function getTokenAddress(symbolOrAddress: string, chainId: number): Address {\n if (isAddressInput(symbolOrAddress)) {\n return symbolOrAddress;\n }\n const match = getSupportedTokens(chainId).find(\n (t) => t.symbol.toUpperCase() === symbolOrAddress.toUpperCase()\n );\n if (!match) {\n throw new Error(`Unsupported token \"${symbolOrAddress}\" on chain ${chainId}`);\n }\n return match.address;\n}\n\nexport function getTokenDecimals(symbolOrAddress: string, chainId: number): number {\n const match = getSupportedTokens(chainId).find(\n (t) =>\n isAddressInput(symbolOrAddress)\n ? t.address.toLowerCase() === symbolOrAddress.toLowerCase()\n : t.symbol.toUpperCase() === symbolOrAddress.toUpperCase()\n );\n if (!match && isAddressInput(symbolOrAddress) && SUPPORTED_CHAIN_IDS.has(chainId)) {\n return 18;\n }\n if (!match) {\n throw new Error(`Unsupported token \"${symbolOrAddress}\" on chain ${chainId}`);\n }\n return match.decimals;\n}\n\nexport function resolveTokenAddress(token: string, chainId: number): Address {\n if (isAddressInput(token)) {\n return token;\n }\n return getTokenAddress(token, chainId);\n}\n\nexport function isTestnet(chainId: number): boolean {\n try {\n return getChainById(chainId).testnet ?? false;\n } catch {\n return false;\n }\n}\n\nexport function getTokenSymbol(tokenAddress: Address, chainId: number): string {\n const token = getSupportedTokens(chainId).find(\n (entry) => entry.address.toLowerCase() === tokenAddress.toLowerCase()\n );\n if (token) {\n return token.symbol;\n }\n if (!SUPPORTED_CHAIN_IDS.has(chainId)) {\n throw new Error(`Unsupported chain ID: ${chainId}`);\n }\n return \"Token\";\n}\n\nexport function isTokenAddressSupported(tokenAddress: Address, chainId: number): boolean {\n return isAddressInput(tokenAddress) && SUPPORTED_CHAIN_IDS.has(chainId);\n}\n"],"mappings":"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","names":["import_viem","import_viem","import_viem","env"]}
package/dist/server.mjs CHANGED
@@ -5,6 +5,9 @@ import {
5
5
  import {
6
6
  encodeWebAuthnSignature
7
7
  } from "./chunk-N6KE5CII.mjs";
8
+ import {
9
+ isTestnet
10
+ } from "./chunk-GUAI55LL.mjs";
8
11
 
9
12
  // src/server.ts
10
13
  import { SignJWT, importJWK } from "jose";
@@ -276,6 +279,7 @@ export {
276
279
  createSponsorshipSigner,
277
280
  encodeWebAuthnSignature,
278
281
  hashMessage,
282
+ isTestnet,
279
283
  verifyMessageHash,
280
284
  verifyOneAuthAccount
281
285
  };
@@ -1 +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":[]}
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// Re-exported so sponsorship endpoints can build a `shouldSponsor` chain\n// policy without importing the browser-oriented main entry. `isTestnet` fails\n// closed (unknown/unrecognised chain id → false), which is the safe default\n// for a sponsorship gate: deny anything we can't positively classify.\nexport { isTestnet } from \"./registry\";\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.app`. */\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":[]}
@@ -190,7 +190,7 @@ interface OneAuthTelemetryConfig {
190
190
  attributes?: OneAuthTelemetryAttributes | (() => OneAuthTelemetryAttributes | undefined);
191
191
  }
192
192
  interface PasskeyProviderConfig {
193
- /** Base URL of the auth API. Defaults to https://passkey.1auth.box */
193
+ /** Base URL of the auth API. Defaults to https://passkey.1auth.app */
194
194
  providerUrl?: string;
195
195
  /** Client identifier for this application (optional for development) */
196
196
  clientId?: string;
@@ -190,7 +190,7 @@ interface OneAuthTelemetryConfig {
190
190
  attributes?: OneAuthTelemetryAttributes | (() => OneAuthTelemetryAttributes | undefined);
191
191
  }
192
192
  interface PasskeyProviderConfig {
193
- /** Base URL of the auth API. Defaults to https://passkey.1auth.box */
193
+ /** Base URL of the auth API. Defaults to https://passkey.1auth.app */
194
194
  providerUrl?: string;
195
195
  /** Client identifier for this application (optional for development) */
196
196
  clientId?: string;
@@ -1,5 +1,5 @@
1
1
  import { Address, Chain, Transport, Hex } from 'viem';
2
- import { aa as ThemeConfig, S as SponsorshipConfig, W as WebAuthnSignature } from './types-U_dwxbtS.js';
2
+ import { aa as ThemeConfig, S as SponsorshipConfig, W as WebAuthnSignature } from './types-C0jKNT_t.js';
3
3
 
4
4
  /**
5
5
  * Configuration for creating a passkey-enabled WalletClient
@@ -9,7 +9,7 @@ interface PasskeyWalletClientConfig {
9
9
  accountAddress: Address;
10
10
  /** Optional username hint for legacy passkey accounts. */
11
11
  username?: string;
12
- /** Base URL of the auth API (defaults to https://passkey.1auth.box) */
12
+ /** Base URL of the auth API (defaults to https://passkey.1auth.app) */
13
13
  providerUrl?: string;
14
14
  /** Client identifier for this application */
15
15
  clientId: string;
@@ -101,6 +101,47 @@ declare function encodeWebAuthnSignature(sig: WebAuthnSignature): Hex;
101
101
  */
102
102
  declare function hashCalls(calls: TransactionCall[]): Hex;
103
103
 
104
+ /**
105
+ * @file Chain and token registry for the 1auth SDK.
106
+ *
107
+ * Wraps `@rhinestone/shared-configs` chain/token data and combines it with
108
+ * viem's chain definitions to expose a filtered, testnet-aware registry.
109
+ * Consumers can look up supported chains and tokens, resolve token addresses
110
+ * by symbol, and retrieve chain metadata such as explorer URLs and default RPC
111
+ * endpoints.
112
+ *
113
+ * Testnet inclusion is controlled by the `includeTestnets` option on each
114
+ * function or, as a project-wide default, by the environment variables
115
+ * `NEXT_PUBLIC_ORCHESTRATOR_USE_TESTNETS` or `ORCHESTRATOR_USE_TESTNETS`.
116
+ */
117
+
118
+ type TokenConfig = {
119
+ symbol: string;
120
+ address: Address;
121
+ decimals: number;
122
+ };
123
+ type ChainFilterOptions = {
124
+ includeTestnets?: boolean;
125
+ chainIds?: number[];
126
+ };
127
+ declare function getSupportedChainIds(options?: ChainFilterOptions): number[];
128
+ declare function getSupportedChains(options?: ChainFilterOptions): Chain[];
129
+ declare function getAllSupportedChainsAndTokens(options?: ChainFilterOptions): Array<{
130
+ chainId: number;
131
+ tokens: TokenConfig[];
132
+ }>;
133
+ declare function getChainById(chainId: number): Chain;
134
+ declare function getChainExplorerUrl(chainId: number): string | undefined;
135
+ declare function getChainRpcUrl(chainId: number): string | undefined;
136
+ declare function getSupportedTokens(chainId: number): TokenConfig[];
137
+ declare function getSupportedTokenSymbols(chainId: number): string[];
138
+ declare function getTokenAddress(symbolOrAddress: string, chainId: number): Address;
139
+ declare function getTokenDecimals(symbolOrAddress: string, chainId: number): number;
140
+ declare function resolveTokenAddress(token: string, chainId: number): Address;
141
+ declare function isTestnet(chainId: number): boolean;
142
+ declare function getTokenSymbol(tokenAddress: Address, chainId: number): string;
143
+ declare function isTokenAddressSupported(tokenAddress: Address, chainId: number): boolean;
144
+
104
145
  /**
105
146
  * The EIP-191 prefix used for personal message signing.
106
147
  * This is the standard Ethereum message prefix for `personal_sign`.
@@ -147,4 +188,4 @@ declare function hashMessage(message: string): `0x${string}`;
147
188
  */
148
189
  declare function verifyMessageHash(message: string, signedHash: string | undefined): boolean;
149
190
 
150
- export { ETHEREUM_MESSAGE_PREFIX as E, type PasskeyWalletClientConfig as P, type SendCallsParams as S, type TransactionCall as T, hashMessage as a, encodeWebAuthnSignature as e, hashCalls as h, verifyMessageHash as v };
191
+ export { type ChainFilterOptions as C, ETHEREUM_MESSAGE_PREFIX as E, type PasskeyWalletClientConfig as P, type SendCallsParams as S, type TransactionCall as T, getSupportedChains as a, getAllSupportedChainsAndTokens as b, getSupportedTokens as c, getSupportedTokenSymbols as d, encodeWebAuthnSignature as e, getChainById as f, getSupportedChainIds as g, hashCalls as h, getChainExplorerUrl as i, getChainRpcUrl as j, isTestnet as k, getTokenAddress as l, getTokenSymbol as m, getTokenDecimals as n, isTokenAddressSupported as o, type TokenConfig as p, hashMessage as q, resolveTokenAddress as r, verifyMessageHash as v };