@rhinestone/1auth 0.1.0 → 0.1.1

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,4 +1,4 @@
1
- import { P as PasskeyProviderClient } from './client-C1inywuT.js';
1
+ import { O as OneAuthClient, I as IntentSigner } from './client-B-HGKKaJ.mjs';
2
2
 
3
3
  type ProviderRequest = {
4
4
  method: string;
@@ -12,12 +12,13 @@ type PasskeyProvider = {
12
12
  disconnect: () => Promise<void>;
13
13
  };
14
14
  type PasskeyProviderOptions = {
15
- client: PasskeyProviderClient;
15
+ client: OneAuthClient;
16
16
  chainId: number;
17
17
  storageKey?: string;
18
18
  waitForHash?: boolean;
19
19
  hashTimeoutMs?: number;
20
20
  hashIntervalMs?: number;
21
+ signIntent?: IntentSigner;
21
22
  };
22
23
  declare function createPasskeyProvider(options: PasskeyProviderOptions): PasskeyProvider;
23
24
 
@@ -1,4 +1,4 @@
1
- import { P as PasskeyProviderClient } from './client-C1inywuT.mjs';
1
+ import { O as OneAuthClient, I as IntentSigner } from './client-B-HGKKaJ.js';
2
2
 
3
3
  type ProviderRequest = {
4
4
  method: string;
@@ -12,12 +12,13 @@ type PasskeyProvider = {
12
12
  disconnect: () => Promise<void>;
13
13
  };
14
14
  type PasskeyProviderOptions = {
15
- client: PasskeyProviderClient;
15
+ client: OneAuthClient;
16
16
  chainId: number;
17
17
  storageKey?: string;
18
18
  waitForHash?: boolean;
19
19
  hashTimeoutMs?: number;
20
20
  hashIntervalMs?: number;
21
+ signIntent?: IntentSigner;
21
22
  };
22
23
  declare function createPasskeyProvider(options: PasskeyProviderOptions): PasskeyProvider;
23
24
 
package/dist/react.d.mts CHANGED
@@ -1,10 +1,10 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import { P as PasskeyProviderClient, v as SendIntentOptions, S as SendIntentResult, y as CloseOnStatus, M as MerchantSignedIntent } from './client-C1inywuT.mjs';
3
+ import { O as OneAuthClient, v as SendIntentOptions, S as SendIntentResult, z as CloseOnStatus, M as MerchantSignedIntent } from './client-B-HGKKaJ.mjs';
4
4
 
5
5
  interface PayButtonProps {
6
- /** The PasskeyProviderClient instance */
7
- client: PasskeyProviderClient;
6
+ /** The OneAuthClient instance */
7
+ client: OneAuthClient;
8
8
  /** Intent parameters (calls, targetChain, etc.) - username will be filled automatically */
9
9
  intent: Omit<SendIntentOptions, "username" | "closeOn" | "signedIntent">;
10
10
  /** Called when payment succeeds */
package/dist/react.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import { P as PasskeyProviderClient, v as SendIntentOptions, S as SendIntentResult, y as CloseOnStatus, M as MerchantSignedIntent } from './client-C1inywuT.js';
3
+ import { O as OneAuthClient, v as SendIntentOptions, S as SendIntentResult, z as CloseOnStatus, M as MerchantSignedIntent } from './client-B-HGKKaJ.js';
4
4
 
5
5
  interface PayButtonProps {
6
- /** The PasskeyProviderClient instance */
7
- client: PasskeyProviderClient;
6
+ /** The OneAuthClient instance */
7
+ client: OneAuthClient;
8
8
  /** Intent parameters (calls, targetChain, etc.) - username will be filled automatically */
9
9
  intent: Omit<SendIntentOptions, "username" | "closeOn" | "signedIntent">;
10
10
  /** Called when payment succeeds */
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { PasskeyProviderClient } from \"./client\";\nimport type { SendIntentOptions, SendIntentResult, CloseOnStatus, MerchantSignedIntent } from \"./types\";\n\n// Fingerprint icon SVG\nconst FingerprintIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4\" />\n <path d=\"M14 13.12c0 2.38 0 6.38-1 8.88\" />\n <path d=\"M17.29 21.02c.12-.6.43-2.3.5-3.02\" />\n <path d=\"M2 12a10 10 0 0 1 18-6\" />\n <path d=\"M2 16h.01\" />\n <path d=\"M21.8 16c.2-2 .131-5.354 0-6\" />\n <path d=\"M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2\" />\n <path d=\"M8.65 22c.21-.66.45-1.32.57-2\" />\n <path d=\"M9 6.8a6 6 0 0 1 9 5.2v2\" />\n </svg>\n);\n\n// Default styles\nconst defaultStyles: React.CSSProperties = {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"8px\",\n padding: \"16px 32px\",\n fontSize: \"16px\",\n fontWeight: 500,\n color: \"#ffffff\",\n backgroundColor: \"#18181b\",\n border: \"none\",\n borderRadius: \"9999px\",\n cursor: \"pointer\",\n transition: \"background-color 0.2s\",\n width: \"100%\",\n};\n\nconst defaultDisabledStyles: React.CSSProperties = {\n opacity: 0.5,\n cursor: \"not-allowed\",\n};\n\nconst defaultHoverStyles: React.CSSProperties = {\n backgroundColor: \"#27272a\",\n};\n\nconst defaultSuccessStyles: React.CSSProperties = {\n backgroundColor: \"#16a34a\",\n cursor: \"default\",\n};\n\n// Checkmark icon SVG\nconst CheckIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M20 6L9 17l-5-5\" />\n </svg>\n);\n\nexport interface PayButtonProps {\n /** The PasskeyProviderClient instance */\n client: PasskeyProviderClient;\n /** Intent parameters (calls, targetChain, etc.) - username will be filled automatically */\n intent: Omit<SendIntentOptions, \"username\" | \"closeOn\" | \"signedIntent\">;\n /** Called when payment succeeds */\n onSuccess?: (result: SendIntentResult) => void;\n /** Called when payment fails */\n onError?: (error: Error) => void;\n /** When to close the dialog and return success. Defaults to \"preconfirmed\" */\n closeOn?: CloseOnStatus;\n /**\n * Optional callback to get a signed intent from your backend.\n * Provides XSS protection by ensuring calls are constructed server-side.\n * If provided, this will be called with the intent and username before sending.\n * The returned signed intent will be used instead of the raw intent.\n */\n getSignedIntent?: (params: {\n username: string;\n targetChain: number;\n calls: SendIntentOptions[\"calls\"];\n tokenRequests?: SendIntentOptions[\"tokenRequests\"];\n }) => Promise<MerchantSignedIntent>;\n /** Button text - defaults to \"Pay with 1auth\" */\n children?: React.ReactNode;\n /** Custom class name */\n className?: string;\n /** Custom inline styles (merged with defaults) */\n style?: React.CSSProperties;\n /** Disabled state */\n disabled?: boolean;\n /** Hide the fingerprint icon */\n hideIcon?: boolean;\n}\n\nexport function PayButton({\n client,\n intent,\n onSuccess,\n onError,\n closeOn = \"preconfirmed\",\n getSignedIntent,\n children = \"Pay with 1auth\",\n className,\n style,\n disabled,\n hideIcon,\n}: PayButtonProps) {\n const [isProcessing, setIsProcessing] = React.useState(false);\n const [isSuccess, setIsSuccess] = React.useState(false);\n const [isHovered, setIsHovered] = React.useState(false);\n\n const handleClick = async () => {\n if (disabled || isProcessing || isSuccess) return;\n\n setIsProcessing(true);\n\n try {\n await executePayment();\n } catch (err) {\n if (err instanceof Error && !err.message.includes(\"rejected\")) {\n onError?.(err);\n }\n } finally {\n setIsProcessing(false);\n }\n };\n\n const executePayment = async (forceReauth = false) => {\n // Try to get existing user from localStorage\n let username: string | null = null;\n if (!forceReauth) {\n const savedUser = localStorage.getItem(\"1auth-user\");\n if (savedUser) {\n try {\n const parsed = JSON.parse(savedUser);\n username = parsed.username;\n } catch {\n localStorage.removeItem(\"1auth-user\");\n }\n }\n }\n\n // If no user (or forced reauth), authenticate first\n if (!username) {\n const authResult = await client.authWithModal();\n if (authResult.success && authResult.username) {\n username = authResult.username;\n localStorage.setItem(\n \"1auth-user\",\n JSON.stringify({ username })\n );\n } else {\n // Auth cancelled or failed\n return;\n }\n }\n\n // Send the intent\n // If getSignedIntent is provided, use signed intent flow (XSS protected)\n // Otherwise, use the raw intent (only works for first-party apps)\n let result: SendIntentResult;\n try {\n if (getSignedIntent) {\n const signedIntent = await getSignedIntent({\n username,\n targetChain: intent.targetChain!,\n calls: intent.calls,\n tokenRequests: intent.tokenRequests,\n });\n result = await client.sendIntent({\n signedIntent,\n closeOn,\n });\n } else {\n result = await client.sendIntent({\n ...intent,\n username,\n closeOn,\n });\n }\n } catch (err) {\n // If user not found, clear localStorage and force re-authentication\n if (err instanceof Error && err.message.includes(\"User not found\")) {\n localStorage.removeItem(\"1auth-user\");\n return executePayment(true);\n }\n throw err;\n }\n\n if (result.success) {\n setIsSuccess(true);\n onSuccess?.(result);\n } else {\n // If user not found error in result, clear localStorage and retry\n if (result.error?.message?.includes(\"User not found\")) {\n localStorage.removeItem(\"1auth-user\");\n return executePayment(true);\n }\n onError?.(new Error(result.error?.message || \"Payment failed\"));\n }\n };\n\n const combinedStyles: React.CSSProperties = {\n ...defaultStyles,\n ...(isSuccess ? defaultSuccessStyles : {}),\n ...(isHovered && !disabled && !isProcessing && !isSuccess ? defaultHoverStyles : {}),\n ...(disabled || isProcessing ? defaultDisabledStyles : {}),\n ...style,\n };\n\n return (\n <button\n type=\"button\"\n className={className}\n style={combinedStyles}\n onClick={handleClick}\n disabled={disabled || isProcessing || isSuccess}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {isSuccess ? (\n <>\n <CheckIcon className=\"pay-button-icon\" />\n Paid\n </>\n ) : isProcessing ? (\n \"Processing...\"\n ) : (\n <>\n {!hideIcon && <FingerprintIcon className=\"pay-button-icon\" />}\n {children}\n </>\n )}\n </button>\n );\n}\n\n// Re-export types for convenience\nexport type { SendIntentOptions, SendIntentResult, CloseOnStatus } from \"./types\";\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/react.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { OneAuthClient } from \"./client\";\nimport type { SendIntentOptions, SendIntentResult, CloseOnStatus, MerchantSignedIntent } from \"./types\";\n\n// Fingerprint icon SVG\nconst FingerprintIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4\" />\n <path d=\"M14 13.12c0 2.38 0 6.38-1 8.88\" />\n <path d=\"M17.29 21.02c.12-.6.43-2.3.5-3.02\" />\n <path d=\"M2 12a10 10 0 0 1 18-6\" />\n <path d=\"M2 16h.01\" />\n <path d=\"M21.8 16c.2-2 .131-5.354 0-6\" />\n <path d=\"M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2\" />\n <path d=\"M8.65 22c.21-.66.45-1.32.57-2\" />\n <path d=\"M9 6.8a6 6 0 0 1 9 5.2v2\" />\n </svg>\n);\n\n// Default styles\nconst defaultStyles: React.CSSProperties = {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"8px\",\n padding: \"16px 32px\",\n fontSize: \"16px\",\n fontWeight: 500,\n color: \"#ffffff\",\n backgroundColor: \"#18181b\",\n border: \"none\",\n borderRadius: \"9999px\",\n cursor: \"pointer\",\n transition: \"background-color 0.2s\",\n width: \"100%\",\n};\n\nconst defaultDisabledStyles: React.CSSProperties = {\n opacity: 0.5,\n cursor: \"not-allowed\",\n};\n\nconst defaultHoverStyles: React.CSSProperties = {\n backgroundColor: \"#27272a\",\n};\n\nconst defaultSuccessStyles: React.CSSProperties = {\n backgroundColor: \"#16a34a\",\n cursor: \"default\",\n};\n\n// Checkmark icon SVG\nconst CheckIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M20 6L9 17l-5-5\" />\n </svg>\n);\n\nexport interface PayButtonProps {\n /** The OneAuthClient instance */\n client: OneAuthClient;\n /** Intent parameters (calls, targetChain, etc.) - username will be filled automatically */\n intent: Omit<SendIntentOptions, \"username\" | \"closeOn\" | \"signedIntent\">;\n /** Called when payment succeeds */\n onSuccess?: (result: SendIntentResult) => void;\n /** Called when payment fails */\n onError?: (error: Error) => void;\n /** When to close the dialog and return success. Defaults to \"preconfirmed\" */\n closeOn?: CloseOnStatus;\n /**\n * Optional callback to get a signed intent from your backend.\n * Provides XSS protection by ensuring calls are constructed server-side.\n * If provided, this will be called with the intent and username before sending.\n * The returned signed intent will be used instead of the raw intent.\n */\n getSignedIntent?: (params: {\n username: string;\n targetChain: number;\n calls: SendIntentOptions[\"calls\"];\n tokenRequests?: SendIntentOptions[\"tokenRequests\"];\n }) => Promise<MerchantSignedIntent>;\n /** Button text - defaults to \"Pay with 1auth\" */\n children?: React.ReactNode;\n /** Custom class name */\n className?: string;\n /** Custom inline styles (merged with defaults) */\n style?: React.CSSProperties;\n /** Disabled state */\n disabled?: boolean;\n /** Hide the fingerprint icon */\n hideIcon?: boolean;\n}\n\nexport function PayButton({\n client,\n intent,\n onSuccess,\n onError,\n closeOn = \"preconfirmed\",\n getSignedIntent,\n children = \"Pay with 1auth\",\n className,\n style,\n disabled,\n hideIcon,\n}: PayButtonProps) {\n const [isProcessing, setIsProcessing] = React.useState(false);\n const [isSuccess, setIsSuccess] = React.useState(false);\n const [isHovered, setIsHovered] = React.useState(false);\n\n const handleClick = async () => {\n if (disabled || isProcessing || isSuccess) return;\n\n setIsProcessing(true);\n\n try {\n await executePayment();\n } catch (err) {\n if (err instanceof Error && !err.message.includes(\"rejected\")) {\n onError?.(err);\n }\n } finally {\n setIsProcessing(false);\n }\n };\n\n const executePayment = async (forceReauth = false) => {\n // Try to get existing user from localStorage\n let username: string | null = null;\n if (!forceReauth) {\n const savedUser = localStorage.getItem(\"1auth-user\");\n if (savedUser) {\n try {\n const parsed = JSON.parse(savedUser);\n username = parsed.username;\n } catch {\n localStorage.removeItem(\"1auth-user\");\n }\n }\n }\n\n // If no user (or forced reauth), authenticate first\n if (!username) {\n const authResult = await client.authWithModal();\n if (authResult.success && authResult.username) {\n username = authResult.username;\n localStorage.setItem(\n \"1auth-user\",\n JSON.stringify({ username })\n );\n } else {\n // Auth cancelled or failed\n return;\n }\n }\n\n // Send the intent\n // If getSignedIntent is provided, use signed intent flow (XSS protected)\n // Otherwise, use the raw intent (only works for first-party apps)\n let result: SendIntentResult;\n try {\n if (getSignedIntent) {\n const signedIntent = await getSignedIntent({\n username,\n targetChain: intent.targetChain!,\n calls: intent.calls,\n tokenRequests: intent.tokenRequests,\n });\n result = await client.sendIntent({\n signedIntent,\n closeOn,\n });\n } else {\n result = await client.sendIntent({\n ...intent,\n username,\n closeOn,\n });\n }\n } catch (err) {\n // If user not found, clear localStorage and force re-authentication\n if (err instanceof Error && err.message.includes(\"User not found\")) {\n localStorage.removeItem(\"1auth-user\");\n return executePayment(true);\n }\n throw err;\n }\n\n if (result.success) {\n setIsSuccess(true);\n onSuccess?.(result);\n } else {\n // If user not found error in result, clear localStorage and retry\n if (result.error?.message?.includes(\"User not found\")) {\n localStorage.removeItem(\"1auth-user\");\n return executePayment(true);\n }\n onError?.(new Error(result.error?.message || \"Payment failed\"));\n }\n };\n\n const combinedStyles: React.CSSProperties = {\n ...defaultStyles,\n ...(isSuccess ? defaultSuccessStyles : {}),\n ...(isHovered && !disabled && !isProcessing && !isSuccess ? defaultHoverStyles : {}),\n ...(disabled || isProcessing ? defaultDisabledStyles : {}),\n ...style,\n };\n\n return (\n <button\n type=\"button\"\n className={className}\n style={combinedStyles}\n onClick={handleClick}\n disabled={disabled || isProcessing || isSuccess}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {isSuccess ? (\n <>\n <CheckIcon className=\"pay-button-icon\" />\n Paid\n </>\n ) : isProcessing ? (\n \"Processing...\"\n ) : (\n <>\n {!hideIcon && <FingerprintIcon className=\"pay-button-icon\" />}\n {children}\n </>\n )}\n </button>\n );\n}\n\n// Re-export types for convenience\nexport type { SendIntentOptions, SendIntentResult, CloseOnStatus } from \"./types\";\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { PasskeyProviderClient } from \"./client\";\nimport type { SendIntentOptions, SendIntentResult, CloseOnStatus, MerchantSignedIntent } from \"./types\";\n\n// Fingerprint icon SVG\nconst FingerprintIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4\" />\n <path d=\"M14 13.12c0 2.38 0 6.38-1 8.88\" />\n <path d=\"M17.29 21.02c.12-.6.43-2.3.5-3.02\" />\n <path d=\"M2 12a10 10 0 0 1 18-6\" />\n <path d=\"M2 16h.01\" />\n <path d=\"M21.8 16c.2-2 .131-5.354 0-6\" />\n <path d=\"M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2\" />\n <path d=\"M8.65 22c.21-.66.45-1.32.57-2\" />\n <path d=\"M9 6.8a6 6 0 0 1 9 5.2v2\" />\n </svg>\n);\n\n// Default styles\nconst defaultStyles: React.CSSProperties = {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"8px\",\n padding: \"16px 32px\",\n fontSize: \"16px\",\n fontWeight: 500,\n color: \"#ffffff\",\n backgroundColor: \"#18181b\",\n border: \"none\",\n borderRadius: \"9999px\",\n cursor: \"pointer\",\n transition: \"background-color 0.2s\",\n width: \"100%\",\n};\n\nconst defaultDisabledStyles: React.CSSProperties = {\n opacity: 0.5,\n cursor: \"not-allowed\",\n};\n\nconst defaultHoverStyles: React.CSSProperties = {\n backgroundColor: \"#27272a\",\n};\n\nconst defaultSuccessStyles: React.CSSProperties = {\n backgroundColor: \"#16a34a\",\n cursor: \"default\",\n};\n\n// Checkmark icon SVG\nconst CheckIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M20 6L9 17l-5-5\" />\n </svg>\n);\n\nexport interface PayButtonProps {\n /** The PasskeyProviderClient instance */\n client: PasskeyProviderClient;\n /** Intent parameters (calls, targetChain, etc.) - username will be filled automatically */\n intent: Omit<SendIntentOptions, \"username\" | \"closeOn\" | \"signedIntent\">;\n /** Called when payment succeeds */\n onSuccess?: (result: SendIntentResult) => void;\n /** Called when payment fails */\n onError?: (error: Error) => void;\n /** When to close the dialog and return success. Defaults to \"preconfirmed\" */\n closeOn?: CloseOnStatus;\n /**\n * Optional callback to get a signed intent from your backend.\n * Provides XSS protection by ensuring calls are constructed server-side.\n * If provided, this will be called with the intent and username before sending.\n * The returned signed intent will be used instead of the raw intent.\n */\n getSignedIntent?: (params: {\n username: string;\n targetChain: number;\n calls: SendIntentOptions[\"calls\"];\n tokenRequests?: SendIntentOptions[\"tokenRequests\"];\n }) => Promise<MerchantSignedIntent>;\n /** Button text - defaults to \"Pay with 1auth\" */\n children?: React.ReactNode;\n /** Custom class name */\n className?: string;\n /** Custom inline styles (merged with defaults) */\n style?: React.CSSProperties;\n /** Disabled state */\n disabled?: boolean;\n /** Hide the fingerprint icon */\n hideIcon?: boolean;\n}\n\nexport function PayButton({\n client,\n intent,\n onSuccess,\n onError,\n closeOn = \"preconfirmed\",\n getSignedIntent,\n children = \"Pay with 1auth\",\n className,\n style,\n disabled,\n hideIcon,\n}: PayButtonProps) {\n const [isProcessing, setIsProcessing] = React.useState(false);\n const [isSuccess, setIsSuccess] = React.useState(false);\n const [isHovered, setIsHovered] = React.useState(false);\n\n const handleClick = async () => {\n if (disabled || isProcessing || isSuccess) return;\n\n setIsProcessing(true);\n\n try {\n await executePayment();\n } catch (err) {\n if (err instanceof Error && !err.message.includes(\"rejected\")) {\n onError?.(err);\n }\n } finally {\n setIsProcessing(false);\n }\n };\n\n const executePayment = async (forceReauth = false) => {\n // Try to get existing user from localStorage\n let username: string | null = null;\n if (!forceReauth) {\n const savedUser = localStorage.getItem(\"1auth-user\");\n if (savedUser) {\n try {\n const parsed = JSON.parse(savedUser);\n username = parsed.username;\n } catch {\n localStorage.removeItem(\"1auth-user\");\n }\n }\n }\n\n // If no user (or forced reauth), authenticate first\n if (!username) {\n const authResult = await client.authWithModal();\n if (authResult.success && authResult.username) {\n username = authResult.username;\n localStorage.setItem(\n \"1auth-user\",\n JSON.stringify({ username })\n );\n } else {\n // Auth cancelled or failed\n return;\n }\n }\n\n // Send the intent\n // If getSignedIntent is provided, use signed intent flow (XSS protected)\n // Otherwise, use the raw intent (only works for first-party apps)\n let result: SendIntentResult;\n try {\n if (getSignedIntent) {\n const signedIntent = await getSignedIntent({\n username,\n targetChain: intent.targetChain!,\n calls: intent.calls,\n tokenRequests: intent.tokenRequests,\n });\n result = await client.sendIntent({\n signedIntent,\n closeOn,\n });\n } else {\n result = await client.sendIntent({\n ...intent,\n username,\n closeOn,\n });\n }\n } catch (err) {\n // If user not found, clear localStorage and force re-authentication\n if (err instanceof Error && err.message.includes(\"User not found\")) {\n localStorage.removeItem(\"1auth-user\");\n return executePayment(true);\n }\n throw err;\n }\n\n if (result.success) {\n setIsSuccess(true);\n onSuccess?.(result);\n } else {\n // If user not found error in result, clear localStorage and retry\n if (result.error?.message?.includes(\"User not found\")) {\n localStorage.removeItem(\"1auth-user\");\n return executePayment(true);\n }\n onError?.(new Error(result.error?.message || \"Payment failed\"));\n }\n };\n\n const combinedStyles: React.CSSProperties = {\n ...defaultStyles,\n ...(isSuccess ? defaultSuccessStyles : {}),\n ...(isHovered && !disabled && !isProcessing && !isSuccess ? defaultHoverStyles : {}),\n ...(disabled || isProcessing ? defaultDisabledStyles : {}),\n ...style,\n };\n\n return (\n <button\n type=\"button\"\n className={className}\n style={combinedStyles}\n onClick={handleClick}\n disabled={disabled || isProcessing || isSuccess}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {isSuccess ? (\n <>\n <CheckIcon className=\"pay-button-icon\" />\n Paid\n </>\n ) : isProcessing ? (\n \"Processing...\"\n ) : (\n <>\n {!hideIcon && <FingerprintIcon className=\"pay-button-icon\" />}\n {children}\n </>\n )}\n </button>\n );\n}\n\n// Re-export types for convenience\nexport type { SendIntentOptions, SendIntentResult, CloseOnStatus } from \"./types\";\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/react.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { OneAuthClient } from \"./client\";\nimport type { SendIntentOptions, SendIntentResult, CloseOnStatus, MerchantSignedIntent } from \"./types\";\n\n// Fingerprint icon SVG\nconst FingerprintIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4\" />\n <path d=\"M14 13.12c0 2.38 0 6.38-1 8.88\" />\n <path d=\"M17.29 21.02c.12-.6.43-2.3.5-3.02\" />\n <path d=\"M2 12a10 10 0 0 1 18-6\" />\n <path d=\"M2 16h.01\" />\n <path d=\"M21.8 16c.2-2 .131-5.354 0-6\" />\n <path d=\"M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2\" />\n <path d=\"M8.65 22c.21-.66.45-1.32.57-2\" />\n <path d=\"M9 6.8a6 6 0 0 1 9 5.2v2\" />\n </svg>\n);\n\n// Default styles\nconst defaultStyles: React.CSSProperties = {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"8px\",\n padding: \"16px 32px\",\n fontSize: \"16px\",\n fontWeight: 500,\n color: \"#ffffff\",\n backgroundColor: \"#18181b\",\n border: \"none\",\n borderRadius: \"9999px\",\n cursor: \"pointer\",\n transition: \"background-color 0.2s\",\n width: \"100%\",\n};\n\nconst defaultDisabledStyles: React.CSSProperties = {\n opacity: 0.5,\n cursor: \"not-allowed\",\n};\n\nconst defaultHoverStyles: React.CSSProperties = {\n backgroundColor: \"#27272a\",\n};\n\nconst defaultSuccessStyles: React.CSSProperties = {\n backgroundColor: \"#16a34a\",\n cursor: \"default\",\n};\n\n// Checkmark icon SVG\nconst CheckIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M20 6L9 17l-5-5\" />\n </svg>\n);\n\nexport interface PayButtonProps {\n /** The OneAuthClient instance */\n client: OneAuthClient;\n /** Intent parameters (calls, targetChain, etc.) - username will be filled automatically */\n intent: Omit<SendIntentOptions, \"username\" | \"closeOn\" | \"signedIntent\">;\n /** Called when payment succeeds */\n onSuccess?: (result: SendIntentResult) => void;\n /** Called when payment fails */\n onError?: (error: Error) => void;\n /** When to close the dialog and return success. Defaults to \"preconfirmed\" */\n closeOn?: CloseOnStatus;\n /**\n * Optional callback to get a signed intent from your backend.\n * Provides XSS protection by ensuring calls are constructed server-side.\n * If provided, this will be called with the intent and username before sending.\n * The returned signed intent will be used instead of the raw intent.\n */\n getSignedIntent?: (params: {\n username: string;\n targetChain: number;\n calls: SendIntentOptions[\"calls\"];\n tokenRequests?: SendIntentOptions[\"tokenRequests\"];\n }) => Promise<MerchantSignedIntent>;\n /** Button text - defaults to \"Pay with 1auth\" */\n children?: React.ReactNode;\n /** Custom class name */\n className?: string;\n /** Custom inline styles (merged with defaults) */\n style?: React.CSSProperties;\n /** Disabled state */\n disabled?: boolean;\n /** Hide the fingerprint icon */\n hideIcon?: boolean;\n}\n\nexport function PayButton({\n client,\n intent,\n onSuccess,\n onError,\n closeOn = \"preconfirmed\",\n getSignedIntent,\n children = \"Pay with 1auth\",\n className,\n style,\n disabled,\n hideIcon,\n}: PayButtonProps) {\n const [isProcessing, setIsProcessing] = React.useState(false);\n const [isSuccess, setIsSuccess] = React.useState(false);\n const [isHovered, setIsHovered] = React.useState(false);\n\n const handleClick = async () => {\n if (disabled || isProcessing || isSuccess) return;\n\n setIsProcessing(true);\n\n try {\n await executePayment();\n } catch (err) {\n if (err instanceof Error && !err.message.includes(\"rejected\")) {\n onError?.(err);\n }\n } finally {\n setIsProcessing(false);\n }\n };\n\n const executePayment = async (forceReauth = false) => {\n // Try to get existing user from localStorage\n let username: string | null = null;\n if (!forceReauth) {\n const savedUser = localStorage.getItem(\"1auth-user\");\n if (savedUser) {\n try {\n const parsed = JSON.parse(savedUser);\n username = parsed.username;\n } catch {\n localStorage.removeItem(\"1auth-user\");\n }\n }\n }\n\n // If no user (or forced reauth), authenticate first\n if (!username) {\n const authResult = await client.authWithModal();\n if (authResult.success && authResult.username) {\n username = authResult.username;\n localStorage.setItem(\n \"1auth-user\",\n JSON.stringify({ username })\n );\n } else {\n // Auth cancelled or failed\n return;\n }\n }\n\n // Send the intent\n // If getSignedIntent is provided, use signed intent flow (XSS protected)\n // Otherwise, use the raw intent (only works for first-party apps)\n let result: SendIntentResult;\n try {\n if (getSignedIntent) {\n const signedIntent = await getSignedIntent({\n username,\n targetChain: intent.targetChain!,\n calls: intent.calls,\n tokenRequests: intent.tokenRequests,\n });\n result = await client.sendIntent({\n signedIntent,\n closeOn,\n });\n } else {\n result = await client.sendIntent({\n ...intent,\n username,\n closeOn,\n });\n }\n } catch (err) {\n // If user not found, clear localStorage and force re-authentication\n if (err instanceof Error && err.message.includes(\"User not found\")) {\n localStorage.removeItem(\"1auth-user\");\n return executePayment(true);\n }\n throw err;\n }\n\n if (result.success) {\n setIsSuccess(true);\n onSuccess?.(result);\n } else {\n // If user not found error in result, clear localStorage and retry\n if (result.error?.message?.includes(\"User not found\")) {\n localStorage.removeItem(\"1auth-user\");\n return executePayment(true);\n }\n onError?.(new Error(result.error?.message || \"Payment failed\"));\n }\n };\n\n const combinedStyles: React.CSSProperties = {\n ...defaultStyles,\n ...(isSuccess ? defaultSuccessStyles : {}),\n ...(isHovered && !disabled && !isProcessing && !isSuccess ? defaultHoverStyles : {}),\n ...(disabled || isProcessing ? defaultDisabledStyles : {}),\n ...style,\n };\n\n return (\n <button\n type=\"button\"\n className={className}\n style={combinedStyles}\n onClick={handleClick}\n disabled={disabled || isProcessing || isSuccess}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {isSuccess ? (\n <>\n <CheckIcon className=\"pay-button-icon\" />\n Paid\n </>\n ) : isProcessing ? (\n \"Processing...\"\n ) : (\n <>\n {!hideIcon && <FingerprintIcon className=\"pay-button-icon\" />}\n {children}\n </>\n )}\n </button>\n );\n}\n\n// Re-export types for convenience\nexport type { SendIntentOptions, SendIntentResult, CloseOnStatus } from \"./types\";\n"],"mappings":"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","names":[]}
package/dist/server.d.mts CHANGED
@@ -1,15 +1,14 @@
1
- /**
2
- * Server-side utilities for 1auth SDK
3
- * Use these in Next.js API routes or server actions
4
- */
5
- interface MerchantConfig {
6
- /** Merchant ID from registration */
7
- merchantId: string;
1
+ interface DeveloperConfig {
2
+ /** Developer/app ID (clientId from the dashboard) */
3
+ developerId?: string;
4
+ /** Deprecated alias for developerId */
5
+ merchantId?: string;
8
6
  /** Ed25519 private key (base64 encoded) */
9
7
  privateKey: string;
10
8
  /** Intent expiry time in ms (default: 5 minutes) */
11
9
  expiryMs?: number;
12
10
  }
11
+ type MerchantConfig = DeveloperConfig;
13
12
  interface IntentCall {
14
13
  to: string;
15
14
  data?: string;
@@ -29,6 +28,7 @@ interface SignIntentParams {
29
28
  }
30
29
  interface SignedIntent {
31
30
  merchantId: string;
31
+ developerId?: string;
32
32
  targetChain: number;
33
33
  calls: IntentCall[];
34
34
  username?: string;
@@ -41,41 +41,7 @@ interface SignedIntent {
41
41
  amount: string;
42
42
  }>;
43
43
  }
44
- /**
45
- * Sign an intent for submission to the passkey service
46
- *
47
- * @example
48
- * ```typescript
49
- * import { signIntent } from "@rhinestone/1auth/server";
50
- *
51
- * const signedIntent = signIntent(
52
- * {
53
- * username: "alice",
54
- * targetChain: 8453,
55
- * calls: [{ to: "0x...", data: "0x...", label: "Buy NFT" }],
56
- * },
57
- * {
58
- * merchantId: process.env.MERCHANT_ID!,
59
- * privateKey: process.env.MERCHANT_PRIVATE_KEY!,
60
- * }
61
- * );
62
- * ```
63
- */
64
- declare function signIntent(params: SignIntentParams, config: MerchantConfig): SignedIntent;
65
- /**
66
- * Create a Next.js API route handler for signing intents
67
- *
68
- * @example
69
- * ```typescript
70
- * // app/api/sign-intent/route.ts
71
- * import { createSignIntentHandler } from "@rhinestone/1auth/server";
72
- *
73
- * export const POST = createSignIntentHandler({
74
- * merchantId: process.env.MERCHANT_ID!,
75
- * privateKey: process.env.MERCHANT_PRIVATE_KEY!,
76
- * });
77
- * ```
78
- */
79
- declare function createSignIntentHandler(config: MerchantConfig): (request: Request) => Promise<Response>;
44
+ declare function signIntent(params: SignIntentParams, config: DeveloperConfig): SignedIntent;
45
+ declare function createSignIntentHandler(config: DeveloperConfig): (request: Request) => Promise<Response>;
80
46
 
81
- export { type IntentCall, type MerchantConfig, type SignIntentParams, type SignedIntent, createSignIntentHandler, signIntent };
47
+ export { type DeveloperConfig, type IntentCall, type MerchantConfig, type SignIntentParams, type SignedIntent, createSignIntentHandler, signIntent };
package/dist/server.d.ts CHANGED
@@ -1,15 +1,14 @@
1
- /**
2
- * Server-side utilities for 1auth SDK
3
- * Use these in Next.js API routes or server actions
4
- */
5
- interface MerchantConfig {
6
- /** Merchant ID from registration */
7
- merchantId: string;
1
+ interface DeveloperConfig {
2
+ /** Developer/app ID (clientId from the dashboard) */
3
+ developerId?: string;
4
+ /** Deprecated alias for developerId */
5
+ merchantId?: string;
8
6
  /** Ed25519 private key (base64 encoded) */
9
7
  privateKey: string;
10
8
  /** Intent expiry time in ms (default: 5 minutes) */
11
9
  expiryMs?: number;
12
10
  }
11
+ type MerchantConfig = DeveloperConfig;
13
12
  interface IntentCall {
14
13
  to: string;
15
14
  data?: string;
@@ -29,6 +28,7 @@ interface SignIntentParams {
29
28
  }
30
29
  interface SignedIntent {
31
30
  merchantId: string;
31
+ developerId?: string;
32
32
  targetChain: number;
33
33
  calls: IntentCall[];
34
34
  username?: string;
@@ -41,41 +41,7 @@ interface SignedIntent {
41
41
  amount: string;
42
42
  }>;
43
43
  }
44
- /**
45
- * Sign an intent for submission to the passkey service
46
- *
47
- * @example
48
- * ```typescript
49
- * import { signIntent } from "@rhinestone/1auth/server";
50
- *
51
- * const signedIntent = signIntent(
52
- * {
53
- * username: "alice",
54
- * targetChain: 8453,
55
- * calls: [{ to: "0x...", data: "0x...", label: "Buy NFT" }],
56
- * },
57
- * {
58
- * merchantId: process.env.MERCHANT_ID!,
59
- * privateKey: process.env.MERCHANT_PRIVATE_KEY!,
60
- * }
61
- * );
62
- * ```
63
- */
64
- declare function signIntent(params: SignIntentParams, config: MerchantConfig): SignedIntent;
65
- /**
66
- * Create a Next.js API route handler for signing intents
67
- *
68
- * @example
69
- * ```typescript
70
- * // app/api/sign-intent/route.ts
71
- * import { createSignIntentHandler } from "@rhinestone/1auth/server";
72
- *
73
- * export const POST = createSignIntentHandler({
74
- * merchantId: process.env.MERCHANT_ID!,
75
- * privateKey: process.env.MERCHANT_PRIVATE_KEY!,
76
- * });
77
- * ```
78
- */
79
- declare function createSignIntentHandler(config: MerchantConfig): (request: Request) => Promise<Response>;
44
+ declare function signIntent(params: SignIntentParams, config: DeveloperConfig): SignedIntent;
45
+ declare function createSignIntentHandler(config: DeveloperConfig): (request: Request) => Promise<Response>;
80
46
 
81
- export { type IntentCall, type MerchantConfig, type SignIntentParams, type SignedIntent, createSignIntentHandler, signIntent };
47
+ export { type DeveloperConfig, type IntentCall, type MerchantConfig, type SignIntentParams, type SignedIntent, createSignIntentHandler, signIntent };
package/dist/server.js CHANGED
@@ -53,9 +53,10 @@ function signMessage(message, privateKeyBase64) {
53
53
  }
54
54
  function signIntent(params, config) {
55
55
  const { username, accountAddress, targetChain, calls, tokenRequests } = params;
56
- const { merchantId, privateKey, expiryMs = 5 * 60 * 1e3 } = config;
57
- if (!merchantId || !privateKey) {
58
- throw new Error("Missing merchantId or privateKey in config");
56
+ const { privateKey, expiryMs = 5 * 60 * 1e3 } = config;
57
+ const developerId = config.developerId || config.merchantId;
58
+ if (!developerId || !privateKey) {
59
+ throw new Error("Missing developerId (clientId) or privateKey in config");
59
60
  }
60
61
  if (!username && !accountAddress) {
61
62
  throw new Error("Either username or accountAddress is required");
@@ -66,7 +67,7 @@ function signIntent(params, config) {
66
67
  const nonce = crypto.randomUUID();
67
68
  const expiresAt = Date.now() + expiryMs;
68
69
  const intentData = {
69
- merchantId,
70
+ merchantId: developerId,
70
71
  targetChain,
71
72
  calls,
72
73
  username,
@@ -79,15 +80,17 @@ function signIntent(params, config) {
79
80
  return {
80
81
  ...intentData,
81
82
  signature,
83
+ developerId,
82
84
  tokenRequests
83
85
  };
84
86
  }
85
87
  function createSignIntentHandler(config) {
86
88
  return async function handler(request) {
87
- if (!config.merchantId || !config.privateKey) {
88
- console.error("Missing MERCHANT_ID or MERCHANT_PRIVATE_KEY");
89
+ const developerId = config.developerId || config.merchantId;
90
+ if (!developerId || !config.privateKey) {
91
+ console.error("Missing DEVELOPER_ID (clientId) or DEVELOPER_PRIVATE_KEY");
89
92
  return Response.json(
90
- { error: "Server misconfiguration: missing merchant credentials" },
93
+ { error: "Server misconfiguration: missing developer credentials" },
91
94
  { status: 500 }
92
95
  );
93
96
  }
@@ -122,7 +125,7 @@ function createSignIntentHandler(config) {
122
125
  }
123
126
  const signedIntent = signIntent(
124
127
  { username, accountAddress, targetChain, calls, tokenRequests },
125
- config
128
+ { ...config, developerId }
126
129
  );
127
130
  return Response.json(signedIntent);
128
131
  } catch (error) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server.ts"],"sourcesContent":["/**\n * Server-side utilities for 1auth SDK\n * Use these in Next.js API routes or server actions\n */\n\nimport { sign } from \"crypto\";\n\nexport interface MerchantConfig {\n /** Merchant ID from registration */\n merchantId: string;\n /** Ed25519 private key (base64 encoded) */\n privateKey: string;\n /** Intent expiry time in ms (default: 5 minutes) */\n expiryMs?: number;\n}\n\nexport interface IntentCall {\n to: string;\n data?: string;\n value?: string;\n label?: string;\n sublabel?: string;\n}\n\nexport interface SignIntentParams {\n username?: string;\n accountAddress?: string;\n targetChain: number;\n calls: IntentCall[];\n tokenRequests?: Array<{ token: string; amount: string }>;\n}\n\nexport interface SignedIntent {\n merchantId: string;\n targetChain: number;\n calls: IntentCall[];\n username?: string;\n accountAddress?: string;\n nonce: string;\n expiresAt: number;\n signature: string;\n tokenRequests?: Array<{ token: string; amount: string }>;\n}\n\n/**\n * Create canonical message for signing\n * Must match the format expected by passkey service\n */\nfunction createCanonicalMessage(data: {\n merchantId: string;\n targetChain: number;\n calls: IntentCall[];\n username?: string;\n accountAddress?: string;\n nonce: string;\n expiresAt: number;\n}): string {\n return JSON.stringify({\n merchantId: data.merchantId,\n targetChain: data.targetChain,\n calls: data.calls.map((c) => ({\n to: c.to.toLowerCase(),\n data: (c.data || \"0x\").toLowerCase(),\n value: c.value || \"0\",\n label: c.label || \"\",\n sublabel: c.sublabel || \"\",\n })),\n username: data.username,\n accountAddress: data.accountAddress?.toLowerCase(),\n nonce: data.nonce,\n expiresAt: data.expiresAt,\n });\n}\n\n/**\n * Sign an intent with Ed25519 private key\n */\nfunction signMessage(message: string, privateKeyBase64: string): string {\n const privateKeyBuffer = Buffer.from(privateKeyBase64, \"base64\");\n const signature = sign(null, Buffer.from(message), {\n key: privateKeyBuffer,\n format: \"der\",\n type: \"pkcs8\",\n });\n return signature.toString(\"base64\");\n}\n\n/**\n * Sign an intent for submission to the passkey service\n *\n * @example\n * ```typescript\n * import { signIntent } from \"@rhinestone/1auth/server\";\n *\n * const signedIntent = signIntent(\n * {\n * username: \"alice\",\n * targetChain: 8453,\n * calls: [{ to: \"0x...\", data: \"0x...\", label: \"Buy NFT\" }],\n * },\n * {\n * merchantId: process.env.MERCHANT_ID!,\n * privateKey: process.env.MERCHANT_PRIVATE_KEY!,\n * }\n * );\n * ```\n */\nexport function signIntent(\n params: SignIntentParams,\n config: MerchantConfig\n): SignedIntent {\n const { username, accountAddress, targetChain, calls, tokenRequests } = params;\n const { merchantId, privateKey, expiryMs = 5 * 60 * 1000 } = config;\n\n if (!merchantId || !privateKey) {\n throw new Error(\"Missing merchantId or privateKey in config\");\n }\n\n if (!username && !accountAddress) {\n throw new Error(\"Either username or accountAddress is required\");\n }\n\n if (!targetChain || !calls?.length) {\n throw new Error(\"targetChain and calls are required\");\n }\n\n // Generate nonce and expiry\n const nonce = crypto.randomUUID();\n const expiresAt = Date.now() + expiryMs;\n\n // Create intent data\n const intentData = {\n merchantId,\n targetChain,\n calls,\n username,\n accountAddress,\n nonce,\n expiresAt,\n };\n\n // Create canonical message and sign\n const message = createCanonicalMessage(intentData);\n const signature = signMessage(message, privateKey);\n\n return {\n ...intentData,\n signature,\n tokenRequests,\n };\n}\n\n/**\n * Create a Next.js API route handler for signing intents\n *\n * @example\n * ```typescript\n * // app/api/sign-intent/route.ts\n * import { createSignIntentHandler } from \"@rhinestone/1auth/server\";\n *\n * export const POST = createSignIntentHandler({\n * merchantId: process.env.MERCHANT_ID!,\n * privateKey: process.env.MERCHANT_PRIVATE_KEY!,\n * });\n * ```\n */\nexport function createSignIntentHandler(config: MerchantConfig) {\n return async function handler(request: Request): Promise<Response> {\n // Validate config\n if (!config.merchantId || !config.privateKey) {\n console.error(\"Missing MERCHANT_ID or MERCHANT_PRIVATE_KEY\");\n return Response.json(\n { error: \"Server misconfiguration: missing merchant credentials\" },\n { status: 500 }\n );\n }\n\n try {\n const body = await request.json();\n\n // Validate required fields\n const { targetChain, calls, username, accountAddress, tokenRequests } = body;\n\n if (!targetChain || typeof targetChain !== \"number\") {\n return Response.json(\n { error: \"targetChain is required and must be a number\" },\n { status: 400 }\n );\n }\n\n if (!calls || !Array.isArray(calls) || calls.length === 0) {\n return Response.json(\n { error: \"calls is required and must be a non-empty array\" },\n { status: 400 }\n );\n }\n\n if (!username && !accountAddress) {\n return Response.json(\n { error: \"Either username or accountAddress is required\" },\n { status: 400 }\n );\n }\n\n // Validate each call has a valid address\n for (const call of calls) {\n if (!call.to || !/^0x[a-fA-F0-9]{40}$/.test(call.to)) {\n return Response.json(\n { error: \"Each call must have a valid 'to' address\" },\n { status: 400 }\n );\n }\n }\n\n // Sign the intent\n const signedIntent = signIntent(\n { username, accountAddress, targetChain, calls, tokenRequests },\n config\n );\n\n return Response.json(signedIntent);\n } catch (error) {\n console.error(\"Error signing intent:\", error);\n return Response.json(\n { error: \"Failed to sign intent\" },\n { status: 500 }\n );\n }\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/server.ts"],"sourcesContent":["import { sign } from \"crypto\";\n\nexport interface DeveloperConfig {\n /** Developer/app ID (clientId from the dashboard) */\n developerId?: string;\n /** Deprecated alias for developerId */\n merchantId?: string;\n /** Ed25519 private key (base64 encoded) */\n privateKey: string;\n /** Intent expiry time in ms (default: 5 minutes) */\n expiryMs?: number;\n}\n\nexport type MerchantConfig = DeveloperConfig;\n\nexport interface IntentCall {\n to: string;\n data?: string;\n value?: string;\n label?: string;\n sublabel?: string;\n}\n\nexport interface SignIntentParams {\n username?: string;\n accountAddress?: string;\n targetChain: number;\n calls: IntentCall[];\n tokenRequests?: Array<{ token: string; amount: string }>;\n}\n\nexport interface SignedIntent {\n merchantId: string;\n developerId?: string;\n targetChain: number;\n calls: IntentCall[];\n username?: string;\n accountAddress?: string;\n nonce: string;\n expiresAt: number;\n signature: string;\n tokenRequests?: Array<{ token: string; amount: string }>;\n}\n\n/**\n * Create canonical message for signing.\n */\nfunction createCanonicalMessage(data: {\n merchantId: string;\n targetChain: number;\n calls: IntentCall[];\n username?: string;\n accountAddress?: string;\n nonce: string;\n expiresAt: number;\n}): string {\n return JSON.stringify({\n merchantId: data.merchantId,\n targetChain: data.targetChain,\n calls: data.calls.map((c) => ({\n to: c.to.toLowerCase(),\n data: (c.data || \"0x\").toLowerCase(),\n value: c.value || \"0\",\n label: c.label || \"\",\n sublabel: c.sublabel || \"\",\n })),\n username: data.username,\n accountAddress: data.accountAddress?.toLowerCase(),\n nonce: data.nonce,\n expiresAt: data.expiresAt,\n });\n}\n\nfunction signMessage(message: string, privateKeyBase64: string): string {\n const privateKeyBuffer = Buffer.from(privateKeyBase64, \"base64\");\n const signature = sign(null, Buffer.from(message), {\n key: privateKeyBuffer,\n format: \"der\",\n type: \"pkcs8\",\n });\n return signature.toString(\"base64\");\n}\n\nexport function signIntent(\n params: SignIntentParams,\n config: DeveloperConfig\n): SignedIntent {\n const { username, accountAddress, targetChain, calls, tokenRequests } = params;\n const { privateKey, expiryMs = 5 * 60 * 1000 } = config;\n const developerId = config.developerId || config.merchantId;\n\n if (!developerId || !privateKey) {\n throw new Error(\"Missing developerId (clientId) or privateKey in config\");\n }\n\n if (!username && !accountAddress) {\n throw new Error(\"Either username or accountAddress is required\");\n }\n\n if (!targetChain || !calls?.length) {\n throw new Error(\"targetChain and calls are required\");\n }\n\n // Generate nonce and expiry\n const nonce = crypto.randomUUID();\n const expiresAt = Date.now() + expiryMs;\n\n // Create intent data\n const intentData = {\n merchantId: developerId,\n targetChain,\n calls,\n username,\n accountAddress,\n nonce,\n expiresAt,\n };\n\n // Create canonical message and sign\n const message = createCanonicalMessage(intentData);\n const signature = signMessage(message, privateKey);\n\n return {\n ...intentData,\n signature,\n developerId,\n tokenRequests,\n };\n}\n\nexport function createSignIntentHandler(config: DeveloperConfig) {\n return async function handler(request: Request): Promise<Response> {\n const developerId = config.developerId || config.merchantId;\n if (!developerId || !config.privateKey) {\n console.error(\"Missing DEVELOPER_ID (clientId) or DEVELOPER_PRIVATE_KEY\");\n return Response.json(\n { error: \"Server misconfiguration: missing developer credentials\" },\n { status: 500 }\n );\n }\n\n try {\n const body = await request.json();\n\n // Validate required fields\n const { targetChain, calls, username, accountAddress, tokenRequests } = body;\n\n if (!targetChain || typeof targetChain !== \"number\") {\n return Response.json(\n { error: \"targetChain is required and must be a number\" },\n { status: 400 }\n );\n }\n\n if (!calls || !Array.isArray(calls) || calls.length === 0) {\n return Response.json(\n { error: \"calls is required and must be a non-empty array\" },\n { status: 400 }\n );\n }\n\n if (!username && !accountAddress) {\n return Response.json(\n { error: \"Either username or accountAddress is required\" },\n { status: 400 }\n );\n }\n\n // Validate each call has a valid address\n for (const call of calls) {\n if (!call.to || !/^0x[a-fA-F0-9]{40}$/.test(call.to)) {\n return Response.json(\n { error: \"Each call must have a valid 'to' address\" },\n { status: 400 }\n );\n }\n }\n\n // Sign the intent\n const signedIntent = signIntent(\n { username, accountAddress, targetChain, calls, tokenRequests },\n { ...config, developerId }\n );\n\n return Response.json(signedIntent);\n } catch (error) {\n console.error(\"Error signing intent:\", error);\n return Response.json(\n { error: \"Failed to sign intent\" },\n { status: 500 }\n );\n }\n };\n}\n"],"mappings":"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","names":[]}
package/dist/server.mjs CHANGED
@@ -28,9 +28,10 @@ function signMessage(message, privateKeyBase64) {
28
28
  }
29
29
  function signIntent(params, config) {
30
30
  const { username, accountAddress, targetChain, calls, tokenRequests } = params;
31
- const { merchantId, privateKey, expiryMs = 5 * 60 * 1e3 } = config;
32
- if (!merchantId || !privateKey) {
33
- throw new Error("Missing merchantId or privateKey in config");
31
+ const { privateKey, expiryMs = 5 * 60 * 1e3 } = config;
32
+ const developerId = config.developerId || config.merchantId;
33
+ if (!developerId || !privateKey) {
34
+ throw new Error("Missing developerId (clientId) or privateKey in config");
34
35
  }
35
36
  if (!username && !accountAddress) {
36
37
  throw new Error("Either username or accountAddress is required");
@@ -41,7 +42,7 @@ function signIntent(params, config) {
41
42
  const nonce = crypto.randomUUID();
42
43
  const expiresAt = Date.now() + expiryMs;
43
44
  const intentData = {
44
- merchantId,
45
+ merchantId: developerId,
45
46
  targetChain,
46
47
  calls,
47
48
  username,
@@ -54,15 +55,17 @@ function signIntent(params, config) {
54
55
  return {
55
56
  ...intentData,
56
57
  signature,
58
+ developerId,
57
59
  tokenRequests
58
60
  };
59
61
  }
60
62
  function createSignIntentHandler(config) {
61
63
  return async function handler(request) {
62
- if (!config.merchantId || !config.privateKey) {
63
- console.error("Missing MERCHANT_ID or MERCHANT_PRIVATE_KEY");
64
+ const developerId = config.developerId || config.merchantId;
65
+ if (!developerId || !config.privateKey) {
66
+ console.error("Missing DEVELOPER_ID (clientId) or DEVELOPER_PRIVATE_KEY");
64
67
  return Response.json(
65
- { error: "Server misconfiguration: missing merchant credentials" },
68
+ { error: "Server misconfiguration: missing developer credentials" },
66
69
  { status: 500 }
67
70
  );
68
71
  }
@@ -97,7 +100,7 @@ function createSignIntentHandler(config) {
97
100
  }
98
101
  const signedIntent = signIntent(
99
102
  { username, accountAddress, targetChain, calls, tokenRequests },
100
- config
103
+ { ...config, developerId }
101
104
  );
102
105
  return Response.json(signedIntent);
103
106
  } catch (error) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server.ts"],"sourcesContent":["/**\n * Server-side utilities for 1auth SDK\n * Use these in Next.js API routes or server actions\n */\n\nimport { sign } from \"crypto\";\n\nexport interface MerchantConfig {\n /** Merchant ID from registration */\n merchantId: string;\n /** Ed25519 private key (base64 encoded) */\n privateKey: string;\n /** Intent expiry time in ms (default: 5 minutes) */\n expiryMs?: number;\n}\n\nexport interface IntentCall {\n to: string;\n data?: string;\n value?: string;\n label?: string;\n sublabel?: string;\n}\n\nexport interface SignIntentParams {\n username?: string;\n accountAddress?: string;\n targetChain: number;\n calls: IntentCall[];\n tokenRequests?: Array<{ token: string; amount: string }>;\n}\n\nexport interface SignedIntent {\n merchantId: string;\n targetChain: number;\n calls: IntentCall[];\n username?: string;\n accountAddress?: string;\n nonce: string;\n expiresAt: number;\n signature: string;\n tokenRequests?: Array<{ token: string; amount: string }>;\n}\n\n/**\n * Create canonical message for signing\n * Must match the format expected by passkey service\n */\nfunction createCanonicalMessage(data: {\n merchantId: string;\n targetChain: number;\n calls: IntentCall[];\n username?: string;\n accountAddress?: string;\n nonce: string;\n expiresAt: number;\n}): string {\n return JSON.stringify({\n merchantId: data.merchantId,\n targetChain: data.targetChain,\n calls: data.calls.map((c) => ({\n to: c.to.toLowerCase(),\n data: (c.data || \"0x\").toLowerCase(),\n value: c.value || \"0\",\n label: c.label || \"\",\n sublabel: c.sublabel || \"\",\n })),\n username: data.username,\n accountAddress: data.accountAddress?.toLowerCase(),\n nonce: data.nonce,\n expiresAt: data.expiresAt,\n });\n}\n\n/**\n * Sign an intent with Ed25519 private key\n */\nfunction signMessage(message: string, privateKeyBase64: string): string {\n const privateKeyBuffer = Buffer.from(privateKeyBase64, \"base64\");\n const signature = sign(null, Buffer.from(message), {\n key: privateKeyBuffer,\n format: \"der\",\n type: \"pkcs8\",\n });\n return signature.toString(\"base64\");\n}\n\n/**\n * Sign an intent for submission to the passkey service\n *\n * @example\n * ```typescript\n * import { signIntent } from \"@rhinestone/1auth/server\";\n *\n * const signedIntent = signIntent(\n * {\n * username: \"alice\",\n * targetChain: 8453,\n * calls: [{ to: \"0x...\", data: \"0x...\", label: \"Buy NFT\" }],\n * },\n * {\n * merchantId: process.env.MERCHANT_ID!,\n * privateKey: process.env.MERCHANT_PRIVATE_KEY!,\n * }\n * );\n * ```\n */\nexport function signIntent(\n params: SignIntentParams,\n config: MerchantConfig\n): SignedIntent {\n const { username, accountAddress, targetChain, calls, tokenRequests } = params;\n const { merchantId, privateKey, expiryMs = 5 * 60 * 1000 } = config;\n\n if (!merchantId || !privateKey) {\n throw new Error(\"Missing merchantId or privateKey in config\");\n }\n\n if (!username && !accountAddress) {\n throw new Error(\"Either username or accountAddress is required\");\n }\n\n if (!targetChain || !calls?.length) {\n throw new Error(\"targetChain and calls are required\");\n }\n\n // Generate nonce and expiry\n const nonce = crypto.randomUUID();\n const expiresAt = Date.now() + expiryMs;\n\n // Create intent data\n const intentData = {\n merchantId,\n targetChain,\n calls,\n username,\n accountAddress,\n nonce,\n expiresAt,\n };\n\n // Create canonical message and sign\n const message = createCanonicalMessage(intentData);\n const signature = signMessage(message, privateKey);\n\n return {\n ...intentData,\n signature,\n tokenRequests,\n };\n}\n\n/**\n * Create a Next.js API route handler for signing intents\n *\n * @example\n * ```typescript\n * // app/api/sign-intent/route.ts\n * import { createSignIntentHandler } from \"@rhinestone/1auth/server\";\n *\n * export const POST = createSignIntentHandler({\n * merchantId: process.env.MERCHANT_ID!,\n * privateKey: process.env.MERCHANT_PRIVATE_KEY!,\n * });\n * ```\n */\nexport function createSignIntentHandler(config: MerchantConfig) {\n return async function handler(request: Request): Promise<Response> {\n // Validate config\n if (!config.merchantId || !config.privateKey) {\n console.error(\"Missing MERCHANT_ID or MERCHANT_PRIVATE_KEY\");\n return Response.json(\n { error: \"Server misconfiguration: missing merchant credentials\" },\n { status: 500 }\n );\n }\n\n try {\n const body = await request.json();\n\n // Validate required fields\n const { targetChain, calls, username, accountAddress, tokenRequests } = body;\n\n if (!targetChain || typeof targetChain !== \"number\") {\n return Response.json(\n { error: \"targetChain is required and must be a number\" },\n { status: 400 }\n );\n }\n\n if (!calls || !Array.isArray(calls) || calls.length === 0) {\n return Response.json(\n { error: \"calls is required and must be a non-empty array\" },\n { status: 400 }\n );\n }\n\n if (!username && !accountAddress) {\n return Response.json(\n { error: \"Either username or accountAddress is required\" },\n { status: 400 }\n );\n }\n\n // Validate each call has a valid address\n for (const call of calls) {\n if (!call.to || !/^0x[a-fA-F0-9]{40}$/.test(call.to)) {\n return Response.json(\n { error: \"Each call must have a valid 'to' address\" },\n { status: 400 }\n );\n }\n }\n\n // Sign the intent\n const signedIntent = signIntent(\n { username, accountAddress, targetChain, calls, tokenRequests },\n config\n );\n\n return Response.json(signedIntent);\n } catch (error) {\n console.error(\"Error signing intent:\", error);\n return Response.json(\n { error: \"Failed to sign intent\" },\n { status: 500 }\n );\n }\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/server.ts"],"sourcesContent":["import { sign } from \"crypto\";\n\nexport interface DeveloperConfig {\n /** Developer/app ID (clientId from the dashboard) */\n developerId?: string;\n /** Deprecated alias for developerId */\n merchantId?: string;\n /** Ed25519 private key (base64 encoded) */\n privateKey: string;\n /** Intent expiry time in ms (default: 5 minutes) */\n expiryMs?: number;\n}\n\nexport type MerchantConfig = DeveloperConfig;\n\nexport interface IntentCall {\n to: string;\n data?: string;\n value?: string;\n label?: string;\n sublabel?: string;\n}\n\nexport interface SignIntentParams {\n username?: string;\n accountAddress?: string;\n targetChain: number;\n calls: IntentCall[];\n tokenRequests?: Array<{ token: string; amount: string }>;\n}\n\nexport interface SignedIntent {\n merchantId: string;\n developerId?: string;\n targetChain: number;\n calls: IntentCall[];\n username?: string;\n accountAddress?: string;\n nonce: string;\n expiresAt: number;\n signature: string;\n tokenRequests?: Array<{ token: string; amount: string }>;\n}\n\n/**\n * Create canonical message for signing.\n */\nfunction createCanonicalMessage(data: {\n merchantId: string;\n targetChain: number;\n calls: IntentCall[];\n username?: string;\n accountAddress?: string;\n nonce: string;\n expiresAt: number;\n}): string {\n return JSON.stringify({\n merchantId: data.merchantId,\n targetChain: data.targetChain,\n calls: data.calls.map((c) => ({\n to: c.to.toLowerCase(),\n data: (c.data || \"0x\").toLowerCase(),\n value: c.value || \"0\",\n label: c.label || \"\",\n sublabel: c.sublabel || \"\",\n })),\n username: data.username,\n accountAddress: data.accountAddress?.toLowerCase(),\n nonce: data.nonce,\n expiresAt: data.expiresAt,\n });\n}\n\nfunction signMessage(message: string, privateKeyBase64: string): string {\n const privateKeyBuffer = Buffer.from(privateKeyBase64, \"base64\");\n const signature = sign(null, Buffer.from(message), {\n key: privateKeyBuffer,\n format: \"der\",\n type: \"pkcs8\",\n });\n return signature.toString(\"base64\");\n}\n\nexport function signIntent(\n params: SignIntentParams,\n config: DeveloperConfig\n): SignedIntent {\n const { username, accountAddress, targetChain, calls, tokenRequests } = params;\n const { privateKey, expiryMs = 5 * 60 * 1000 } = config;\n const developerId = config.developerId || config.merchantId;\n\n if (!developerId || !privateKey) {\n throw new Error(\"Missing developerId (clientId) or privateKey in config\");\n }\n\n if (!username && !accountAddress) {\n throw new Error(\"Either username or accountAddress is required\");\n }\n\n if (!targetChain || !calls?.length) {\n throw new Error(\"targetChain and calls are required\");\n }\n\n // Generate nonce and expiry\n const nonce = crypto.randomUUID();\n const expiresAt = Date.now() + expiryMs;\n\n // Create intent data\n const intentData = {\n merchantId: developerId,\n targetChain,\n calls,\n username,\n accountAddress,\n nonce,\n expiresAt,\n };\n\n // Create canonical message and sign\n const message = createCanonicalMessage(intentData);\n const signature = signMessage(message, privateKey);\n\n return {\n ...intentData,\n signature,\n developerId,\n tokenRequests,\n };\n}\n\nexport function createSignIntentHandler(config: DeveloperConfig) {\n return async function handler(request: Request): Promise<Response> {\n const developerId = config.developerId || config.merchantId;\n if (!developerId || !config.privateKey) {\n console.error(\"Missing DEVELOPER_ID (clientId) or DEVELOPER_PRIVATE_KEY\");\n return Response.json(\n { error: \"Server misconfiguration: missing developer credentials\" },\n { status: 500 }\n );\n }\n\n try {\n const body = await request.json();\n\n // Validate required fields\n const { targetChain, calls, username, accountAddress, tokenRequests } = body;\n\n if (!targetChain || typeof targetChain !== \"number\") {\n return Response.json(\n { error: \"targetChain is required and must be a number\" },\n { status: 400 }\n );\n }\n\n if (!calls || !Array.isArray(calls) || calls.length === 0) {\n return Response.json(\n { error: \"calls is required and must be a non-empty array\" },\n { status: 400 }\n );\n }\n\n if (!username && !accountAddress) {\n return Response.json(\n { error: \"Either username or accountAddress is required\" },\n { status: 400 }\n );\n }\n\n // Validate each call has a valid address\n for (const call of calls) {\n if (!call.to || !/^0x[a-fA-F0-9]{40}$/.test(call.to)) {\n return Response.json(\n { error: \"Each call must have a valid 'to' address\" },\n { status: 400 }\n );\n }\n }\n\n // Sign the intent\n const signedIntent = signIntent(\n { username, accountAddress, targetChain, calls, tokenRequests },\n { ...config, developerId }\n );\n\n return Response.json(signedIntent);\n } catch (error) {\n console.error(\"Error signing intent:\", error);\n return Response.json(\n { error: \"Failed to sign intent\" },\n { status: 500 }\n );\n }\n };\n}\n"],"mappings":"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","names":[]}
package/dist/wagmi.d.mts CHANGED
@@ -1,14 +1,15 @@
1
1
  import * as _wagmi_core from '@wagmi/core';
2
- import { P as PasskeyProvider } from './provider-Dgh51NRc.mjs';
3
- import { P as PasskeyProviderClient } from './client-C1inywuT.mjs';
2
+ import { P as PasskeyProvider } from './provider-CDIRlA4y.mjs';
3
+ import { O as OneAuthClient, I as IntentSigner } from './client-B-HGKKaJ.mjs';
4
4
 
5
5
  type OneAuthConnectorOptions = {
6
- client: PasskeyProviderClient;
6
+ client: OneAuthClient;
7
7
  chainId?: number;
8
8
  storageKey?: string;
9
9
  waitForHash?: boolean;
10
10
  hashTimeoutMs?: number;
11
11
  hashIntervalMs?: number;
12
+ signIntent?: IntentSigner;
12
13
  };
13
14
  declare function oneAuth(options: OneAuthConnectorOptions): _wagmi_core.CreateConnectorFn<PasskeyProvider, Record<string, unknown>, Record<string, unknown>>;
14
15
 
package/dist/wagmi.d.ts CHANGED
@@ -1,14 +1,15 @@
1
1
  import * as _wagmi_core from '@wagmi/core';
2
- import { P as PasskeyProvider } from './provider-q7M728Mn.js';
3
- import { P as PasskeyProviderClient } from './client-C1inywuT.js';
2
+ import { P as PasskeyProvider } from './provider-Cy1StrOe.js';
3
+ import { O as OneAuthClient, I as IntentSigner } from './client-B-HGKKaJ.js';
4
4
 
5
5
  type OneAuthConnectorOptions = {
6
- client: PasskeyProviderClient;
6
+ client: OneAuthClient;
7
7
  chainId?: number;
8
8
  storageKey?: string;
9
9
  waitForHash?: boolean;
10
10
  hashTimeoutMs?: number;
11
11
  hashIntervalMs?: number;
12
+ signIntent?: IntentSigner;
12
13
  };
13
14
  declare function oneAuth(options: OneAuthConnectorOptions): _wagmi_core.CreateConnectorFn<PasskeyProvider, Record<string, unknown>, Record<string, unknown>>;
14
15
 
package/dist/wagmi.js CHANGED
@@ -283,10 +283,27 @@ function createPasskeyProvider(options) {
283
283
  }
284
284
  return encodeWebAuthnSignature(result.signature);
285
285
  };
286
+ const resolveIntentPayload = async (payload) => {
287
+ if (!options.signIntent) {
288
+ return {
289
+ username: payload.username,
290
+ targetChain: payload.targetChain,
291
+ calls: payload.calls
292
+ };
293
+ }
294
+ const signedIntent = await options.signIntent({
295
+ username: payload.username,
296
+ accountAddress: payload.accountAddress,
297
+ targetChain: payload.targetChain,
298
+ calls: payload.calls
299
+ });
300
+ return { signedIntent };
301
+ };
286
302
  const sendIntent = async (payload) => {
287
303
  const closeOn = options.waitForHash ?? true ? "completed" : "preconfirmed";
304
+ const intentPayload = await resolveIntentPayload(payload);
288
305
  const result = await client.sendIntent({
289
- ...payload,
306
+ ...intentPayload,
290
307
  closeOn,
291
308
  waitForHash: options.waitForHash ?? true,
292
309
  hashTimeoutMs: options.hashTimeoutMs,
@@ -350,6 +367,7 @@ function createPasskeyProvider(options) {
350
367
  const calls = normalizeCalls([tx]);
351
368
  return sendIntent({
352
369
  username: user.username,
370
+ accountAddress: user.address,
353
371
  targetChain,
354
372
  calls
355
373
  });
@@ -363,6 +381,7 @@ function createPasskeyProvider(options) {
363
381
  if (!calls.length) throw new Error("No calls provided");
364
382
  return sendIntent({
365
383
  username: user.username,
384
+ accountAddress: user.address,
366
385
  targetChain,
367
386
  calls
368
387
  });
@@ -499,7 +518,8 @@ function oneAuth(options) {
499
518
  storageKey: options.storageKey,
500
519
  waitForHash: options.waitForHash,
501
520
  hashTimeoutMs: options.hashTimeoutMs,
502
- hashIntervalMs: options.hashIntervalMs
521
+ hashIntervalMs: options.hashIntervalMs,
522
+ signIntent: options.signIntent
503
523
  });
504
524
  }
505
525
  if (chainId) {