@use-glyph/sdk-react 2.1.12 → 2.2.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 +1 @@
1
- {"version":3,"file":"EIP1193Strategy.js","sources":["../src/context/strategies/EIP1193Strategy.tsx"],"sourcesContent":["import { SignTypedDataParams, UnsignedTransactionRequest } from \"@privy-io/react-auth\";\nimport react, { useCallback, useEffect, useState } from \"react\";\nimport {\n useAccount,\n useAccountEffect,\n useDisconnect,\n useSendTransaction,\n useSignMessage,\n useSignTypedData,\n} from \"wagmi\";\nimport { WIDGET_API_BASE_URL } from \"../../lib/constants\";\nimport { createLogger } from \"../../lib/utils\";\nimport { BaseGlyphProviderOptionsWithSignature } from \"../../types\";\nimport { GlyphApiFetch, GlyphContext, createApiFetch } from \"../GlyphContext\";\n\ntype GlyphSigningMsgResponse = { message: string; nonce: string };\ntype GlyphSignatureVerifyResponse = { token: string };\n\nconst TOKEN_KEY = \"__glyph-widget-token__\";\nconst NONCE_KEY = \"__glyph-widget-nonce__\";\nconst logger = createLogger(\"EIP1193Strategy\");\n\nconst EIP1193Strategy: react.FC<BaseGlyphProviderOptionsWithSignature> = ({\n children,\n glyphUrl,\n onLogin,\n onLogout,\n askForSignature = true\n}) => {\n const [loading, setLoading] = useState(false);\n const [apiFetch, setApiFetch] = useState<GlyphApiFetch | null>(null);\n const { address, isConnected, chainId } = useAccount(); // detect wallet connection\n const { disconnectAsync } = useDisconnect(); // disconnect the wallet\n const { signMessageAsync } = useSignMessage(); // signing messages with the wallet\n const { signTypedDataAsync } = useSignTypedData(); // signing typed data with the wallet\n const { sendTransactionAsync } = useSendTransaction(); // sending transactions with the wallet\n\n // Fetch authentication token from session storage\n const [token, setToken] = useState<string | null>(() => {\n if (typeof window === \"undefined\") {\n return null;\n }\n try {\n return localStorage.getItem(TOKEN_KEY);\n } catch (error) {\n logger.warn(\"Error reading session token\");\n return null;\n }\n });\n\n const [message, setMessage] = useState<string | null>(null);\n\n // fetch nonce from session storage\n const [sessNonce, setSessNonce] = useState<string | null>(() => {\n if (typeof window === \"undefined\") {\n return null;\n }\n try {\n return localStorage.getItem(NONCE_KEY);\n } catch (error) {\n logger.warn(\"Error reading session nonce\");\n return null;\n }\n });\n\n // Keep token and nonce updated in session storage\n useEffect(() => {\n try {\n if (!token || !sessNonce) {\n localStorage.removeItem(TOKEN_KEY);\n localStorage.removeItem(NONCE_KEY);\n } else {\n localStorage.setItem(TOKEN_KEY, token!);\n localStorage.setItem(NONCE_KEY, sessNonce!);\n }\n } catch (error) {\n logger.error(\"Error saving session token\");\n }\n }, [sessNonce, token]);\n\n const fetchMessageToSign = useCallback(\n async (address: string): Promise<GlyphSigningMsgResponse> => {\n try {\n const payload = (await fetch(\n `${glyphUrl || WIDGET_API_BASE_URL}/api/widget/auth/message/${address}`\n ).then((resp) => resp.json())) as GlyphSigningMsgResponse;\n\n return payload;\n } catch (error) {\n logger.error(\"Can't fetch message to sign\");\n throw new Error(\"Failed to fetch the message to sign.\");\n }\n },\n [glyphUrl]\n );\n\n const verifySignature = useCallback(\n async (address: string, signature: string, nonce: string): Promise<GlyphSignatureVerifyResponse> => {\n try {\n const payload = await fetch(`${glyphUrl || WIDGET_API_BASE_URL}/api/widget/auth/verify/${address}`, {\n method: \"POST\",\n body: JSON.stringify({ signature, nonce })\n }).then((resp) => resp.json());\n return payload as unknown as GlyphSignatureVerifyResponse;\n } catch (error) {\n logger.error(\"Can't verify signature\");\n throw new Error(\"Signature verification failed.\");\n }\n },\n [glyphUrl]\n );\n\n useEffect(() => {\n if (!address || !isConnected) return;\n if (sessNonce) return;\n\n setLoading(true);\n fetchMessageToSign(address)\n .then(({ message, nonce }) => {\n setMessage(message);\n setSessNonce(nonce);\n setLoading(false);\n })\n .finally(() => {\n setLoading(false);\n });\n }, [address, isConnected, fetchMessageToSign, sessNonce]);\n\n useEffect(() => {\n if (!token || !sessNonce) return;\n\n const glyphApiFetch = createApiFetch(glyphUrl || WIDGET_API_BASE_URL, async () => token, {\n \"x-evm-address\": address!,\n \"x-glyph-nonce\": sessNonce!\n });\n setApiFetch(() => glyphApiFetch);\n }, [token, address, glyphUrl, sessNonce]);\n\n const disconnect = useCallback(async () => {\n await disconnectAsync();\n }, [disconnectAsync]);\n\n const authenticate = useCallback(async () => {\n logger.log(\"authenticate\");\n if (!address) {\n logger.error(\"no wallet connected.\");\n return;\n }\n\n try {\n if (!address || !isConnected || !message || !sessNonce) {\n setApiFetch(null);\n setLoading(false);\n return;\n }\n\n // Sign a message with the wallet to authenticate\n setLoading(true);\n\n const userSignature = await signMessageAsync({ account: address, message: message });\n\n const token = (await verifySignature(address, userSignature, sessNonce))?.token;\n\n setToken(token);\n } catch (error) {\n logger.error(\"Authentication failed\");\n if (!(error as Error)?.message?.toLowerCase?.().includes?.(\"user rejected\")) {\n await alert(\n \"Authentication failed - your browser could be blocking the popups. Allow popups or try to manually click sign in.\"\n );\n }\n setApiFetch(null);\n setToken(null);\n setSessNonce(null);\n } finally {\n setLoading(false);\n onLogin?.();\n }\n }, [address, isConnected, message, sessNonce, signMessageAsync, verifySignature]);\n\n const logoutSideEffect = useCallback(async () => {\n setSessNonce(null);\n setToken(null);\n setLoading(false);\n setApiFetch(null);\n onLogout?.();\n }, []);\n\n const signMessage = useCallback(\n async ({ message }: { message: string }) => {\n if (!address || !isConnected) {\n throw new Error(\"Wallet not connected\");\n }\n return signMessageAsync({ account: address, message });\n },\n [address, isConnected, signMessageAsync]\n );\n\n const signTypedData = useCallback(\n async ({ data }: { data: SignTypedDataParams }) => {\n if (!address || !isConnected) {\n throw new Error(\"Wallet not connected\");\n }\n const types = data.types;\n const primaryType = data.primaryType as string;\n const message = data.message;\n return signTypedDataAsync({ types, primaryType, message });\n },\n [address, isConnected, signTypedDataAsync]\n );\n\n const sendTransaction = useCallback(\n async ({ transaction }: { transaction: UnsignedTransactionRequest }) => {\n if (!address || !isConnected) throw new Error(\"Wallet not connected\");\n\n return sendTransactionAsync({ ...transaction, chainId: transaction.chainId || chainId } as any);\n },\n [address, isConnected, sendTransactionAsync, chainId]\n );\n\n const [tryAuthenticate, setTryAuthenticate] = useState<boolean>(false);\n // Perform graceful logout when the wallet is disconnected from anywhere within the app\n useAccountEffect({\n onConnect: () => {\n if (askForSignature) {\n // Perform initial authentication when the wallet is connected\n setTryAuthenticate(true);\n }\n },\n onDisconnect: () => {\n logoutSideEffect();\n }\n });\n useEffect(() => {\n if (askForSignature && isConnected && address && tryAuthenticate && sessNonce && message) {\n // Initial authentication\n authenticate();\n setTryAuthenticate(false);\n }\n }, [isConnected, address, authenticate, tryAuthenticate, sessNonce, message, askForSignature]);\n\n return (\n <GlyphContext.Provider\n value={{\n ready: !loading && !!sessNonce,\n authenticated: isConnected && !!address && token !== null,\n glyphUrl: glyphUrl as string, // Pass as string to avoid type error (we are passing fallback value in useGlyph hook at a common place)\n hideWidget: !isConnected || !address,\n login: authenticate,\n logout: disconnect, // on disconnect, logoutSideEffect is called and clears states\n signMessage,\n signTypedData,\n sendTransaction,\n apiFetch: apiFetch!\n }}\n children={children}\n />\n );\n};\n\nexport default EIP1193Strategy;\n"],"names":["TOKEN_KEY","NONCE_KEY","logger","createLogger","EIP1193Strategy","children","glyphUrl","onLogin","onLogout","askForSignature","loading","setLoading","useState","apiFetch","setApiFetch","address","isConnected","chainId","useAccount","disconnectAsync","useDisconnect","signMessageAsync","useSignMessage","signTypedDataAsync","useSignTypedData","sendTransactionAsync","useSendTransaction","token","setToken","message","setMessage","sessNonce","setSessNonce","useEffect","fetchMessageToSign","useCallback","WIDGET_API_BASE_URL","resp","verifySignature","signature","nonce","glyphApiFetch","createApiFetch","disconnect","authenticate","userSignature","error","logoutSideEffect","signMessage","signTypedData","data","types","primaryType","sendTransaction","transaction","tryAuthenticate","setTryAuthenticate","useAccountEffect","jsx","GlyphContext"],"mappings":"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"}
1
+ {"version":3,"file":"EIP1193Strategy.js","sources":["../src/lib/walletAuth.ts","../src/lib/walletAuthSession.ts","../src/context/strategies/EIP1193Strategy.tsx"],"sourcesContent":["import type { GlyphAuthError, GlyphAuthErrorReason } from \"../types\";\n\nexport class WalletAuthFailure extends Error {\n constructor(\n readonly reason: GlyphAuthErrorReason,\n message: string,\n readonly retryAfterMs?: number\n ) {\n super(message);\n }\n}\n\nexport function walletAuthOrigin(value: string): string | null {\n try {\n const url = new URL(value);\n return [\"http:\", \"https:\"].includes(url.protocol) && !url.username && !url.password ? url.origin : null;\n } catch {\n return null;\n }\n}\n\nexport function hasWalletActivation(): boolean {\n if (typeof navigator === \"undefined\") return false;\n return navigator.userActivation?.isActive ?? true;\n}\n\nexport function signingFailure(error: unknown): WalletAuthFailure {\n try {\n let current = error;\n for (let depth = 0; current && depth < 5; depth++) {\n const item = current as { code?: unknown; message?: unknown; details?: unknown; cause?: unknown };\n const text = [item.message, item.details]\n .filter((v): v is string => typeof v === \"string\")\n .map((v) => v.slice(0, 4096))\n .join(\" \");\n if (item.code === 4001 || /user (rejected|denied|cancel)/i.test(text))\n return new WalletAuthFailure(\"rejected\", \"The signature request was rejected.\");\n if (/failed to initialize request|popup.*block|pop-up.*block/i.test(text))\n return new WalletAuthFailure(\"popup_blocked\", \"Open sign-in from a click to allow the wallet popup.\");\n current = item.cause;\n }\n } catch {\n /* Untrusted SDK errors are never returned or logged. */\n }\n return new WalletAuthFailure(\"network\", \"The signature request failed.\");\n}\n\nasync function authJson(\n response: Response,\n rejected: GlyphAuthErrorReason,\n signal: AbortSignal\n): Promise<Record<string, unknown>> {\n if (response.status === 429) {\n const header = response.headers.get(\"Retry-After\");\n void response.body?.cancel().catch(() => {});\n const seconds = header?.trim() ? Number(header) : NaN;\n const date = header ? Date.parse(header) : NaN;\n const delay =\n Number.isFinite(seconds) && seconds >= 0\n ? seconds * 1000\n : Number.isFinite(date)\n ? Math.max(0, date - Date.now())\n : 0;\n throw new WalletAuthFailure(\n \"network\",\n \"Sign-in is rate limited. Try again later.\",\n Number.isSafeInteger(delay) && delay > 0 ? delay : 0\n );\n }\n if (!response.ok) {\n void response.body?.cancel().catch(() => {});\n throw new WalletAuthFailure(rejected, \"The authentication request was rejected.\");\n }\n const reader = response.body?.getReader();\n if (!reader) throw new WalletAuthFailure(rejected, \"The authentication response was invalid.\");\n // Bind the deadline directly to the response reader as well as fetch.\n // Transport cleanup must not delay authentication failure settlement.\n const cancelRead = () => {\n void reader.cancel().catch(() => {});\n };\n signal.addEventListener(\"abort\", cancelRead, { once: true });\n if (signal.aborted) cancelRead();\n const chunks: Uint8Array[] = [];\n let bytes = 0;\n try {\n for (;;) {\n if (signal.aborted) throw new WalletAuthFailure(\"network\", \"The authentication request timed out.\");\n const item = await reader.read();\n if (signal.aborted) throw new WalletAuthFailure(\"network\", \"The authentication request timed out.\");\n if (item.done) break;\n bytes += item.value.byteLength;\n if (bytes > 65536) throw new WalletAuthFailure(rejected, \"The authentication response was invalid.\");\n chunks.push(item.value);\n }\n } finally {\n signal.removeEventListener(\"abort\", cancelRead);\n cancelRead();\n reader.releaseLock();\n }\n const raw = new Uint8Array(bytes);\n let offset = 0;\n for (const chunk of chunks) {\n raw.set(chunk, offset);\n offset += chunk.byteLength;\n }\n let body: unknown;\n try {\n body = JSON.parse(new TextDecoder(\"utf-8\", { fatal: true }).decode(raw));\n } catch {\n throw new WalletAuthFailure(rejected, \"The authentication response was invalid.\");\n }\n if (!body || typeof body !== \"object\" || Array.isArray(body))\n throw new WalletAuthFailure(\"network\", \"The authentication response was invalid.\");\n return body as Record<string, unknown>;\n}\n\nconst text = (value: unknown, max: number): value is string =>\n typeof value === \"string\" && value.trim().length > 0 && value.length <= max;\n\n/** Bound only HTTP/body work. Wallet interaction has no timeout or automatic retry. */\nasync function authRequest(url: URL, init: RequestInit, lifecycle: AbortSignal, rejected: GlyphAuthErrorReason) {\n const controller = new AbortController();\n // Retain a direct signal and lifecycle listener through response-body settlement.\n const signal = controller.signal;\n const cancel = () => controller.abort();\n if (lifecycle.aborted) cancel();\n else lifecycle.addEventListener(\"abort\", cancel, { once: true });\n const started = performance.now();\n const timer = setTimeout(() => controller.abort(), 10000);\n try {\n const response = await fetch(url, { ...init, signal, redirect: \"error\", credentials: \"omit\" });\n const body = await authJson(response, rejected, signal);\n if (signal.aborted || performance.now() - started >= 10000)\n throw new WalletAuthFailure(\"network\", \"The authentication request timed out.\");\n return body;\n } finally {\n lifecycle.removeEventListener(\"abort\", cancel);\n clearTimeout(timer);\n controller.abort();\n }\n}\n\nexport async function fetchWalletMessage(origin: string, address: string, signal: AbortSignal) {\n const body = await authRequest(new URL(`/api/widget/auth/message/${address}`, origin), {}, signal, \"network\");\n if (!text(body.message, 16384) || !text(body.nonce, 1024))\n throw new WalletAuthFailure(\"network\", \"The sign-in message was invalid.\");\n return { message: body.message, nonce: body.nonce };\n}\n\nexport async function verifyWalletSignature(\n origin: string,\n address: string,\n signature: string,\n nonce: string,\n signal: AbortSignal\n) {\n const body = await authRequest(\n new URL(`/api/widget/auth/verify/${address}`, origin),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ signature, nonce })\n },\n signal,\n \"verify_failed\"\n );\n if (!text(body.token, 16384))\n throw new WalletAuthFailure(\"verify_failed\", \"Signature verification returned no token.\");\n return body.token;\n}\n\nexport function publicAuthError(error: unknown): GlyphAuthError {\n return error instanceof WalletAuthFailure\n ? { reason: error.reason, message: error.message }\n : { reason: \"network\", message: \"Authentication failed.\" };\n}\n","import type { GlyphApiFetch } from \"../context/GlyphContext\";\nimport type { GlyphAuthError } from \"../types\";\nimport { createApiFetch } from \"../context/GlyphContext\";\nimport {\n fetchWalletMessage,\n hasWalletActivation,\n publicAuthError,\n signingFailure,\n verifyWalletSignature,\n WalletAuthFailure\n} from \"./walletAuth\";\n\ntype Session = { token: string; nonce: string };\ntype Message = { message: string; nonce: string };\ntype Snapshot = {\n generation: number;\n ready: boolean;\n authenticated: boolean;\n needsSignature: boolean;\n authError: GlyphAuthError | null;\n apiFetch: GlyphApiFetch | null;\n};\ntype Options = {\n address: string;\n origin: string;\n /** Stable connector family; runtime instance identity is fenced by isCurrent. */\n connector: string;\n popup: boolean;\n isCurrent: () => boolean;\n sign: (message: string) => Promise<string>;\n onLogin: () => void;\n onAuthError: (error: GlyphAuthError) => void;\n storage?: Pick<Storage, \"getItem\" | \"setItem\" | \"removeItem\">;\n activation?: () => boolean;\n};\n\n/** One mounted wallet/origin/connector capability. No async result can change another generation. */\nexport function createWalletAuthSession(options: Options) {\n let active = false,\n epoch = 0,\n autoAttempted = false,\n signing = false,\n fetching = false;\n let session: Session | undefined, message: Message | undefined;\n let retryAt = 0,\n rateLimits = 0;\n let controller = new AbortController();\n let prefetch: Promise<void> | undefined;\n let retryTimer: ReturnType<typeof setTimeout> | undefined;\n const listeners = new Set<() => void>();\n const storageKey = `__glyph-wallet-session-v2__:${JSON.stringify([options.origin, options.address.toLowerCase(), options.connector])}`;\n let snapshot: Readonly<Snapshot> = Object.freeze({\n generation: epoch,\n ready: false,\n authenticated: false,\n needsSignature: false,\n authError: null as GlyphAuthError | null,\n apiFetch: null as GlyphApiFetch | null\n });\n const current = (generation = epoch) => active && epoch === generation && options.isCurrent();\n const publish = (patch: Partial<Snapshot>) => {\n snapshot = Object.freeze({ ...snapshot, ...patch, generation: epoch });\n for (const listener of listeners) listener();\n };\n const storage = (work: (store: NonNullable<Options[\"storage\"]>) => void) => {\n try {\n if (options.storage) work(options.storage);\n } catch {\n /* Storage is optional, never authority. */\n }\n };\n const callback = (work: () => void) => {\n try {\n work();\n } catch {\n /* Host callbacks cannot change authentication. */\n }\n };\n const capability =\n (credential: Session, generation: number): GlyphApiFetch =>\n async (path, init) => {\n const assert = () => {\n if (!current(generation) || session !== credential) throw new Error(\"Glyph wallet session changed\");\n };\n assert();\n let target: URL;\n try {\n target = new URL(path, options.origin);\n if (target.origin !== options.origin || target.username || target.password) throw new Error();\n } catch {\n throw new Error(\"Unsupported Glyph request URL\");\n }\n const signal = init?.signal ? AbortSignal.any([init.signal, controller.signal]) : controller.signal;\n const response = await createApiFetch(options.origin, undefined, {\n Authorization: `Bearer ${credential.token}`,\n \"x-evm-address\": options.address,\n \"x-glyph-nonce\": credential.nonce\n })(target.href, { ...init, signal, redirect: \"error\" });\n assert();\n if (response.status === 401) {\n // A late old response fails the assertion above and cannot revoke a new credential.\n revoke(true);\n report(new WalletAuthFailure(\"verify_failed\", \"The wallet session expired. Sign in again.\"), epoch);\n void prepare();\n }\n return response;\n };\n const report = (error: unknown, generation: number) => {\n if (!current(generation)) return;\n let failure = publicAuthError(error);\n if (error instanceof WalletAuthFailure && error.retryAfterMs !== undefined) {\n rateLimits++;\n const delay = error.retryAfterMs || Math.min(30000 * 2 ** Math.min(rateLimits - 1, 5), 600000);\n retryAt = Math.min(Number.MAX_SAFE_INTEGER, Date.now() + delay);\n failure = { ...failure, retryAt };\n }\n publish({ authError: failure, needsSignature: true });\n if (current(generation)) callback(() => options.onAuthError(failure));\n };\n const schedule = (generation: number) => {\n clearTimeout(retryTimer);\n if (!current(generation) || !retryAt) return;\n // Long Retry-After dates must not overflow a browser's signed 32-bit timer.\n retryTimer = setTimeout(\n () => {\n if (!current(generation)) return;\n if (Date.now() < retryAt) schedule(generation);\n else {\n retryAt = 0;\n void prepare();\n }\n },\n Math.max(1, Math.min(2147483647, retryAt - Date.now()))\n );\n };\n const prepare = (): Promise<void> => {\n if (!current() || session || message || prefetch) return prefetch ?? Promise.resolve();\n const generation = epoch;\n if (Date.now() < retryAt) {\n schedule(generation);\n return Promise.resolve();\n }\n fetching = true;\n publish({ ready: false });\n if (!current(generation)) return Promise.resolve();\n const pending = fetchWalletMessage(options.origin, options.address, controller.signal)\n .then((value) => {\n if (current(generation)) message = value;\n })\n .catch((error: unknown) => {\n report(error, generation);\n })\n .finally(() => {\n if (!current(generation) || prefetch !== pending) return;\n prefetch = undefined;\n fetching = false;\n publish({ ready: !signing, needsSignature: !session });\n if (retryAt) schedule(generation);\n });\n prefetch = pending;\n return pending;\n };\n const revoke = (forget: boolean) => {\n epoch++;\n controller.abort();\n controller = new AbortController();\n clearTimeout(retryTimer);\n session = undefined;\n message = undefined;\n prefetch = undefined;\n signing = false;\n fetching = false;\n autoAttempted = true;\n if (forget) storage((store) => store.removeItem(storageKey));\n publish({ ready: active, authenticated: false, apiFetch: null, authError: null, needsSignature: false });\n };\n const signIn = (generation: number): Promise<boolean> => {\n if (!current(generation) || signing) return Promise.resolve(false);\n autoAttempted = true;\n if (session) return Promise.resolve(true);\n if (Date.now() < retryAt) {\n publish({\n authError: { reason: \"network\", message: \"Sign-in is rate limited. Try again later.\", retryAt },\n needsSignature: true\n });\n return Promise.resolve(false);\n }\n if (!message) {\n // Never await network work before opening a popup. Prepare, then require a fresh click.\n void prepare();\n publish({ needsSignature: true });\n return Promise.resolve(false);\n }\n if (options.popup && !(options.activation ?? hasWalletActivation)()) {\n publish({ needsSignature: true });\n return Promise.resolve(false);\n }\n const challenge = message;\n signing = true;\n publish({ ready: false, needsSignature: false, authError: null });\n if (!current(generation)) return Promise.resolve(false);\n let signed: Promise<string>;\n try {\n signed = options.sign(challenge.message);\n } catch (error) {\n signed = Promise.reject(error);\n }\n return (async () => {\n try {\n let signature: string;\n try {\n signature = await signed;\n } catch (error) {\n throw signingFailure(error);\n }\n if (!current(generation)) return false;\n const token = await verifyWalletSignature(\n options.origin,\n options.address,\n signature,\n challenge.nonce,\n controller.signal\n );\n if (!current(generation)) return false;\n session = { token, nonce: challenge.nonce };\n rateLimits = 0;\n retryAt = 0;\n storage((store) => store.setItem(storageKey, JSON.stringify(session)));\n publish({ authenticated: true, apiFetch: capability(session, generation), authError: null });\n if (current(generation)) callback(options.onLogin);\n return current(generation) && !!session;\n } catch (error) {\n if (!current(generation)) return false;\n message = undefined;\n session = undefined;\n storage((store) => store.removeItem(storageKey));\n publish({ authenticated: false, apiFetch: null });\n report(error, generation);\n return false;\n } finally {\n if (current(generation)) {\n signing = false;\n publish({ ready: !fetching, needsSignature: !session });\n if (!session) void prepare();\n }\n }\n })();\n };\n return {\n subscribe(listener: () => void) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n getSnapshot: () => snapshot,\n current,\n signIn,\n automatic() {\n if (!current() || autoAttempted || !message || session || signing) return;\n if (options.popup && !(options.activation ?? hasWalletActivation)()) {\n autoAttempted = true;\n publish({ needsSignature: true });\n return;\n }\n void signIn(epoch);\n },\n start() {\n active = true;\n storage((store) => {\n store.removeItem(\"__glyph-widget-token__\");\n store.removeItem(\"__glyph-widget-nonce__\");\n try {\n const saved = JSON.parse(store.getItem(storageKey) ?? \"null\");\n if (\n saved &&\n typeof saved.token === \"string\" &&\n saved.token.trim() &&\n saved.token.length <= 16384 &&\n typeof saved.nonce === \"string\" &&\n saved.nonce.trim() &&\n saved.nonce.length <= 1024\n )\n session = saved;\n } catch {\n /* Malformed legacy state is not authenticated. */\n }\n });\n publish({ ready: true, authenticated: !!session, apiFetch: session ? capability(session, epoch) : null });\n if (!session) void prepare();\n },\n stop(forget = false) {\n const attempted = autoAttempted;\n active = false;\n revoke(forget);\n autoAttempted = attempted;\n },\n logout() {\n if (current()) revoke(true);\n },\n // A replaced instance shares its family's persistence key, but no longer\n // owns it. Committed scope cleanup already forgets the departing record.\n forget() {\n if (current()) revoke(true);\n }\n };\n}\n","import type { SignTypedDataParams, UnsignedTransactionRequest } from \"@privy-io/react-auth\";\nimport react, { useCallback, useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport {\n useAccount,\n useAccountEffect,\n useDisconnect,\n useSendTransaction,\n useSignMessage,\n useSignTypedData\n} from \"wagmi\";\nimport { WIDGET_API_BASE_URL, glyphConnectorDetails } from \"../../lib/constants\";\nimport { walletAuthOrigin } from \"../../lib/walletAuth\";\nimport { createWalletAuthSession } from \"../../lib/walletAuthSession\";\nimport { createLogger } from \"../../lib/utils\";\nimport type { BaseGlyphProviderOptionsWithSignature } from \"../../types\";\nimport { GlyphContext } from \"../GlyphContext\";\n\nconst logger = createLogger(\"EIP1193Strategy\");\nconst EIP1193Strategy: react.FC<BaseGlyphProviderOptionsWithSignature> = ({\n children,\n glyphUrl,\n onLogin,\n onLogout,\n onAuthError,\n askForSignature = true\n}) => {\n const { address, isConnected, chainId, connector } = useAccount();\n const { disconnectAsync } = useDisconnect();\n const { signMessageAsync } = useSignMessage();\n const { signTypedDataAsync } = useSignTypedData();\n const { sendTransactionAsync } = useSendTransaction();\n const origin = walletAuthOrigin(glyphUrl || WIDGET_API_BASE_URL);\n const current = useRef<ReturnType<typeof createWalletAuthSession> | null>(null);\n const latest = useRef({ onLogin, onLogout, onAuthError, signMessageAsync });\n latest.current = { onLogin, onLogout, onAuthError, signMessageAsync };\n const logoutNotified = useRef(false);\n const lastConnected = useRef<ReturnType<typeof createWalletAuthSession> | null>(null);\n // UID stays in the live identity; only its stable family is persisted.\n const connectorIdentity = useMemo(\n () => ({ family: JSON.stringify([connector?.id, connector?.type]), uid: connector?.uid }),\n [connector?.id, connector?.type, connector?.uid]\n );\n const session = useMemo(() => {\n const instance = createWalletAuthSession({\n address: address ?? \"\",\n origin: origin ?? \"\",\n connector: connectorIdentity.family,\n popup: connector?.type === \"privy\" || connector?.id === glyphConnectorDetails.id,\n isCurrent: () => current.current === instance && !!address && isConnected && !!origin,\n sign: (message) => latest.current.signMessageAsync({ account: address!, message }),\n onLogin: () => {\n logoutNotified.current = false;\n latest.current.onLogin?.();\n },\n onAuthError: (error) => latest.current.onAuthError?.(error),\n storage:\n typeof window === \"undefined\"\n ? undefined\n : {\n getItem: (key) => window.localStorage.getItem(key),\n setItem: (key, value) => window.localStorage.setItem(key, value),\n removeItem: (key) => window.localStorage.removeItem(key)\n }\n });\n return instance;\n }, [address, isConnected, origin, connectorIdentity, connector?.type, connector?.id]);\n // Render-time fencing revokes old callbacks before passive effect cleanup.\n current.current = session;\n const disconnectOwner = isConnected ? session : lastConnected.current;\n if (isConnected) lastConnected.current = session;\n const state = useSyncExternalStore(session.subscribe, session.getSnapshot, session.getSnapshot);\n useEffect(() => {\n session.start();\n // A committed live scope replacement forgets its old record. Ordinary\n // unmount/StrictMode replay keeps it for restoration by the same family.\n return () => session.stop(current.current !== session);\n }, [session]);\n useEffect(() => {\n if (askForSignature) session.automatic();\n }, [session, state, askForSignature]);\n const signIn = useCallback(() => session.signIn(state.generation), [session, state.generation]);\n const notifyLogout = useCallback(() => {\n if (logoutNotified.current) return;\n logoutNotified.current = true;\n try {\n latest.current.onLogout?.();\n } catch {\n logger.error(\"Logout callback failed\");\n }\n }, []);\n const logout = useCallback(async () => {\n if (!session.current(state.generation)) return;\n session.logout();\n notifyLogout();\n try {\n await disconnectAsync();\n } catch {\n logger.error(\"Wallet disconnect failed\");\n }\n }, [session, state.generation, notifyLogout, disconnectAsync]);\n useAccountEffect({\n onDisconnect: () => {\n disconnectOwner?.forget();\n if (current.current === disconnectOwner || !isConnected) notifyLogout();\n }\n });\n const assertCurrent = useCallback(() => {\n if (!session.current(state.generation)) throw new Error(\"Glyph wallet session changed\");\n }, [session, state.generation]);\n const signMessage = useCallback(\n async ({ message }: { message: string }) => {\n assertCurrent();\n const result = await signMessageAsync({ account: address!, message });\n assertCurrent();\n return result;\n },\n [assertCurrent, address, signMessageAsync]\n );\n const signTypedData = useCallback(\n async ({ data }: { data: SignTypedDataParams }) => {\n assertCurrent();\n const result = await signTypedDataAsync({\n types: data.types,\n primaryType: data.primaryType as string,\n message: data.message\n });\n assertCurrent();\n return result;\n },\n [assertCurrent, signTypedDataAsync]\n );\n const sendTransaction = useCallback(\n async ({ transaction }: { transaction: UnsignedTransactionRequest }) => {\n assertCurrent();\n const result = await sendTransactionAsync({\n ...transaction,\n chainId: transaction.chainId || chainId\n } as any);\n assertCurrent();\n return result;\n },\n [assertCurrent, sendTransactionAsync, chainId]\n );\n const live = session.current(state.generation);\n return (\n <GlyphContext.Provider\n value={{\n ready: state.ready,\n authenticated: live && state.authenticated,\n glyphUrl: glyphUrl as string,\n hideWidget: !isConnected || !address,\n login: signIn,\n signIn,\n needsSignature: live && state.needsSignature,\n authError: live ? state.authError : null,\n logout,\n signMessage,\n signTypedData,\n sendTransaction,\n apiFetch: live ? state.apiFetch : null\n }}\n >\n {children}\n </GlyphContext.Provider>\n );\n};\nexport default EIP1193Strategy;\n"],"names":["WalletAuthFailure","reason","message","retryAfterMs","walletAuthOrigin","value","url","hasWalletActivation","signingFailure","error","current","depth","item","text","v","authJson","response","rejected","signal","header","seconds","date","delay","reader","cancelRead","chunks","bytes","raw","offset","chunk","body","max","authRequest","init","lifecycle","controller","cancel","started","timer","fetchWalletMessage","origin","address","verifyWalletSignature","signature","nonce","publicAuthError","createWalletAuthSession","options","active","epoch","autoAttempted","signing","fetching","session","retryAt","rateLimits","prefetch","retryTimer","listeners","storageKey","snapshot","generation","publish","patch","listener","storage","work","callback","capability","credential","path","assert","target","createApiFetch","revoke","report","prepare","failure","schedule","pending","forget","store","signIn","challenge","signed","token","saved","attempted","logger","createLogger","EIP1193Strategy","children","glyphUrl","onLogin","onLogout","onAuthError","askForSignature","isConnected","chainId","connector","useAccount","disconnectAsync","useDisconnect","signMessageAsync","useSignMessage","signTypedDataAsync","useSignTypedData","sendTransactionAsync","useSendTransaction","WIDGET_API_BASE_URL","useRef","latest","logoutNotified","lastConnected","connectorIdentity","useMemo","instance","glyphConnectorDetails","key","disconnectOwner","state","useSyncExternalStore","useEffect","useCallback","notifyLogout","logout","useAccountEffect","assertCurrent","signMessage","result","signTypedData","data","sendTransaction","transaction","live","jsx","GlyphContext"],"mappings":"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"}
@@ -1,118 +1,127 @@
1
- import { jsx as j } from "react/jsx-runtime";
2
- import { usePrivy as B, useCrossAppAccounts as q } from "@privy-io/react-auth";
3
- import { memo as z, useState as d, useEffect as J, useCallback as o } from "react";
1
+ import { jsx as V } from "react/jsx-runtime";
2
+ import { usePrivy as j, useCrossAppAccounts as z } from "@privy-io/react-auth";
3
+ import { memo as N, useMemo as k, useRef as $, useState as q, useEffect as J, useCallback as c } from "react";
4
4
  import { useChainId as K } from "wagmi";
5
- import { i as O, c as Q, S as W, G as b, a as X, b as Z, W as $ } from "./index.js";
6
- const a = Q("PrivyStrategy"), ss = ({
7
- children: M,
8
- glyphUrl: p,
9
- onLogin: m,
10
- onLogout: v,
11
- useStagingTenant: l
5
+ import { i as W, c as O, G as Q, S as X, a as Z, W as U } from "./index.js";
6
+ function ee(A, o) {
7
+ const u = A?.linkedAccounts ?? [], l = u.flatMap((s) => {
8
+ if (s.type !== "cross_app" || !s.providerApp?.id) return [];
9
+ const p = s.embeddedWallets?.find((y) => W(y.address));
10
+ return p ? [{ address: p.address, usesCrossapp: !0, providerAppId: s.providerApp.id }] : [];
11
+ }), d = l.find((s) => s.providerAppId === o) ?? l[0];
12
+ if (d) return d;
13
+ const v = u.find(
14
+ (s) => s.type === "wallet" && s.chainType === "ethereum" && s.walletClientType === "privy" && W(s.address)
15
+ );
16
+ return v?.type === "wallet" ? { address: v.address, usesCrossapp: !1, providerAppId: null } : null;
17
+ }
18
+ const se = ({
19
+ children: A,
20
+ glyphUrl: o,
21
+ onLogin: u,
22
+ onLogout: l,
23
+ useStagingTenant: d
12
24
  }) => {
13
- const [k, u] = d(!0), [x, y] = d(null), [t, L] = d(null), [r, F] = d(!1), w = K(), {
14
- ready: c,
15
- authenticated: g,
16
- user: i,
17
- getAccessToken: P,
18
- login: _,
19
- logout: h,
25
+ const v = K(), {
26
+ ready: s,
27
+ authenticated: p,
28
+ user: y,
29
+ getAccessToken: I,
30
+ login: m,
31
+ logout: P,
20
32
  signMessage: T,
21
- signTypedData: I,
22
- sendTransaction: S
23
- } = B(), {
24
- signMessage: D,
25
- signTypedData: E,
26
- sendTransaction: G
27
- } = q();
28
- J(() => {
29
- if (!c) {
30
- y(null), u(!0);
31
- return;
32
- }
33
- if (!g || !i) {
34
- y(null), u(!1);
35
- return;
36
- }
37
- let s;
38
- const n = i.linkedAccounts?.find(
39
- (e) => e.type === "wallet" && e.chainType === "ethereum" && e.walletClientType === "privy"
40
- ), H = n && O(n.address);
41
- a.debug("finding cross-app accounts...");
42
- const C = i.linkedAccounts?.filter?.((e) => e.type === "cross_app") || [], f = C.filter(
43
- (e) => e.providerApp?.id !== (l ? W : b)
44
- ).map((e) => e.embeddedWallets[0].address);
45
- f.length > 0 && (s = f[0], a.log("using cross_app (non-Glyph) account"), f.length > 1 && a.warn("too many cross_app accounts"));
46
- const A = C.filter(
47
- (e) => e.providerApp?.id === (l ? W : b)
48
- ).map((e) => e.embeddedWallets[0].address);
49
- A.length > 0 && (s = A[0], a.log("using cross_app (Glyph) account"), A.length > 1 && a.warn("too many cross_app accounts")), s ? (F(!0), a.log("using cross_app account")) : H && (s = n.address, a.log("using Privy (main) EVM embedded wallet")), L(s ?? null), (async () => {
50
- if (!s) {
51
- a.error("user has no wallet");
52
- return;
53
- }
54
- const e = Z(
55
- p || $,
56
- async () => await P(),
57
- { "x-evm-address": s }
58
- );
59
- y(() => e), u(!1);
60
- })();
61
- }, [
62
- p,
63
- g,
64
- c,
65
- i,
66
- l,
67
- r,
68
- t,
69
- P,
70
- h
71
- ]);
72
- const N = o(async () => {
73
- await _(), m?.();
74
- }, [m, _]), R = o(async () => {
75
- h(), v?.();
76
- }, [v, h]), Y = o(
77
- async ({ message: s }) => {
78
- if (!t) throw new Error("No wallet address found");
79
- return r ? D(s, { address: t }) : (await T({ message: s })).signature;
33
+ signTypedData: S,
34
+ sendTransaction: _
35
+ } = j(), {
36
+ signMessage: C,
37
+ signTypedData: G,
38
+ sendTransaction: D
39
+ } = z(), h = s && p && y?.id ? ee(y, d ? X : Z) : null, e = h?.address ?? null, n = h?.usesCrossapp ?? !1, E = h?.providerAppId ?? null, M = y?.id, r = k(
40
+ () => ({
41
+ active: !0,
42
+ privyReady: s,
43
+ privyAuthenticated: p,
44
+ userId: M,
45
+ walletAddress: e,
46
+ usesCrossapp: n,
47
+ providerAppId: E,
48
+ glyphUrl: o,
49
+ useStagingTenant: d
50
+ }),
51
+ [s, p, M, e, n, E, o, d]
52
+ ), w = $(r);
53
+ w.current = r;
54
+ const [, x] = q(0);
55
+ J(() => (r.active = !0, () => {
56
+ r.active = !1;
57
+ }), [r]);
58
+ const t = c(() => {
59
+ if (!e || !r.active || w.current !== r)
60
+ throw new Error("Glyph wallet session is unavailable or changed");
61
+ }, [r, e]), R = k(() => !e || !r.active ? null : async (a, i) => {
62
+ t();
63
+ const f = await I();
64
+ if (t(), !f) throw new Error("Privy access token is unavailable");
65
+ const H = await O(o || U, void 0, {
66
+ Authorization: `Bearer ${f}`,
67
+ "x-evm-address": e
68
+ })(a, i);
69
+ return t(), H;
70
+ }, [e, r, t, I, o]), g = c(async () => {
71
+ await m(), u?.();
72
+ }, [u, m]), b = c(async () => {
73
+ if (w.current !== r) throw new Error("Glyph wallet session changed");
74
+ r.active = !1, x((a) => a + 1), await P(), l?.();
75
+ }, [r, l, P]), Y = c(
76
+ async ({ message: a }) => {
77
+ t();
78
+ const i = n ? await C(a, { address: e }) : (await T({ message: a }, { address: e })).signature;
79
+ return t(), i;
80
80
  },
81
- [t, r, D, T]
82
- ), U = o(
83
- async ({ data: s }) => {
84
- if (!t) throw new Error("No wallet address found");
85
- return r ? E(s, { address: t }) : (await I(s)).signature;
81
+ [e, n, t, C, T]
82
+ ), F = c(
83
+ async ({ data: a }) => {
84
+ t();
85
+ const i = n ? await G(a, { address: e }) : (await S(a, { address: e })).signature;
86
+ return t(), i;
86
87
  },
87
- [t, r, E, I]
88
- ), V = o(
89
- async ({ transaction: s }) => {
90
- if (!t) throw new Error("No wallet address found");
91
- const n = { ...s, chainId: s.chainId || w };
92
- return r ? G(n, { address: t }) : (await S(n, { address: t })).hash;
88
+ [e, n, t, G, S]
89
+ ), L = c(
90
+ async ({ transaction: a }) => {
91
+ t();
92
+ const i = { ...a, chainId: a.chainId || v }, f = n ? await D(i, { address: e }) : (await _(i, { address: e })).hash;
93
+ return t(), f;
93
94
  },
94
- [w, r, t, G, S]
95
- );
96
- return /* @__PURE__ */ j(
97
- X.Provider,
95
+ [v, n, e, t, D, _]
96
+ ), B = c(async () => {
97
+ try {
98
+ return await g(), !0;
99
+ } catch {
100
+ return !1;
101
+ }
102
+ }, [g]);
103
+ return /* @__PURE__ */ V(
104
+ Q.Provider,
98
105
  {
99
106
  value: {
100
- ready: c && !k,
101
- authenticated: c && g,
102
- glyphUrl: p,
103
- // Pass as string to avoid type error (we are passing fallback value in useGlyph hook at a common place)
104
- login: N,
105
- logout: R,
107
+ ready: s,
108
+ authenticated: !!e && r.active,
109
+ glyphUrl: o,
110
+ login: g,
111
+ signIn: B,
112
+ needsSignature: !1,
113
+ authError: null,
114
+ logout: b,
106
115
  signMessage: Y,
107
- signTypedData: U,
108
- sendTransaction: V,
109
- apiFetch: x
116
+ signTypedData: F,
117
+ sendTransaction: L,
118
+ apiFetch: r.active ? R : null
110
119
  },
111
- children: M
120
+ children: A
112
121
  }
113
122
  );
114
- }, ds = z(ss);
123
+ }, oe = N(se);
115
124
  export {
116
- ds as default
125
+ oe as default
117
126
  };
118
127
  //# sourceMappingURL=PrivyStrategy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PrivyStrategy.js","sources":["../src/context/strategies/PrivyStrategy.tsx"],"sourcesContent":["import {\n SignTypedDataParams,\n UnsignedTransactionRequest,\n useCrossAppAccounts,\n usePrivy,\n WalletWithMetadata\n} from \"@privy-io/react-auth\";\nimport react, { memo, useCallback, useEffect, useState } from \"react\";\nimport { useChainId } from \"wagmi\";\nimport { GLYPH_PRIVY_APP_ID, STAGING_GLYPH_PRIVY_APP_ID, WIDGET_API_BASE_URL } from \"../../lib/constants\";\nimport { createLogger, isEthereumAddress } from \"../../lib/utils\";\nimport { BaseGlyphProviderOptions } from \"../../types\";\nimport { createApiFetch, GlyphApiFetch, GlyphContext } from \"../GlyphContext\";\n\nconst logger = createLogger(\"PrivyStrategy\");\n\nconst PrivyStrategy: react.FC<BaseGlyphProviderOptions> = ({\n children,\n glyphUrl,\n onLogin,\n onLogout,\n useStagingTenant\n}) => {\n const [loading, setLoading] = useState<boolean>(true);\n const [apiFetch, setApiFetch] = useState<GlyphApiFetch | null>(null);\n const [walletAddress, setWalletAddress] = useState<string | null>(null);\n const [usesCrossapp, setUsesCrossapp] = useState<boolean>(false);\n const chainId = useChainId();\n\n const {\n ready: privyReady,\n authenticated: privyAuthenticated,\n user: privyUser,\n getAccessToken: getPrivyAccessToken,\n login: privyLogin,\n logout: privyLogout,\n signMessage: privySignMessage,\n signTypedData: privySignTypedData,\n sendTransaction: privySendTransaction\n } = usePrivy();\n\n const {\n signMessage: crossAppSignMessage,\n signTypedData: crossAppSignTypedData,\n sendTransaction: crossAppSendTransaction\n } = useCrossAppAccounts();\n\n\n useEffect(() => {\n // If Privy is not ready, reset widget state (loading: true)\n if (!privyReady) {\n setApiFetch(null);\n setLoading(true);\n return;\n }\n\n // If user is not authenticated, reset widget state (loading: false)\n if (!privyAuthenticated || !privyUser) {\n setApiFetch(null);\n setLoading(false);\n return;\n }\n\n let address: string | undefined;\n\n const privyEvmWallet = privyUser!.linkedAccounts?.find(\n (w) => w.type === \"wallet\" && w.chainType === \"ethereum\" && w.walletClientType === \"privy\"\n ) as WalletWithMetadata | undefined;\n\n const hasPrivyEvmWallet = privyEvmWallet && isEthereumAddress(privyEvmWallet.address);\n\n logger.debug(\"finding cross-app accounts...\");\n // Cross-app accounts are always EVM addresses\n const crossAppAccounts = privyUser!.linkedAccounts?.filter?.((account) => account.type === \"cross_app\") || [];\n\n const otherAccounts = crossAppAccounts.filter(\n (account) =>\n account.providerApp?.id !== (useStagingTenant ? STAGING_GLYPH_PRIVY_APP_ID : GLYPH_PRIVY_APP_ID)\n );\n const otherAddresses = otherAccounts.map((account) => account.embeddedWallets[0].address);\n if (otherAddresses.length > 0) {\n address = otherAddresses[0];\n logger.log(\"using cross_app (non-Glyph) account\");\n if (otherAddresses.length > 1) {\n logger.warn(\"too many cross_app accounts\");\n }\n }\n\n const glyphAccounts = crossAppAccounts.filter(\n (account) =>\n account.providerApp?.id === (useStagingTenant ? STAGING_GLYPH_PRIVY_APP_ID : GLYPH_PRIVY_APP_ID)\n );\n const glyphAddresses = glyphAccounts.map((account) => account.embeddedWallets[0].address);\n if (glyphAddresses.length > 0) {\n address = glyphAddresses[0];\n logger.log(\"using cross_app (Glyph) account\");\n if (glyphAddresses.length > 1) {\n logger.warn(\"too many cross_app accounts\");\n }\n }\n\n if (address) {\n setUsesCrossapp(true);\n logger.log(\"using cross_app account\");\n } else if (hasPrivyEvmWallet) {\n address = privyEvmWallet.address;\n logger.log(\"using Privy (main) EVM embedded wallet\");\n }\n\n setWalletAddress(address ?? null);\n\n // Fetch user data from Glyph API\n const fetchUserData = async () => {\n // If no address is found, stop here\n if (!address) {\n logger.error(\"user has no wallet\");\n return;\n }\n\n const glyphApiFetch = createApiFetch(\n glyphUrl || WIDGET_API_BASE_URL,\n async () => (await getPrivyAccessToken())!,\n { \"x-evm-address\": address }\n );\n setApiFetch(() => glyphApiFetch);\n setLoading(false);\n };\n\n fetchUserData();\n }, [\n glyphUrl,\n privyAuthenticated,\n privyReady,\n privyUser,\n useStagingTenant,\n usesCrossapp,\n walletAddress,\n getPrivyAccessToken,\n privyLogout\n ]);\n\n const authenticate = useCallback(async () => {\n await privyLogin();\n onLogin?.();\n }, [onLogin, privyLogin]);\n\n const logout = useCallback(async () => {\n privyLogout();\n onLogout?.();\n }, [onLogout, privyLogout]);\n\n const signMessage = useCallback(\n async ({ message }: { message: string }) => {\n if (!walletAddress) throw new Error(\"No wallet address found\");\n\n return usesCrossapp\n ? crossAppSignMessage(message, { address: walletAddress })\n : (await privySignMessage({ message })).signature;\n },\n [walletAddress, usesCrossapp, crossAppSignMessage, privySignMessage]\n );\n\n const signTypedData = useCallback(\n async ({ data }: { data: SignTypedDataParams }) => {\n if (!walletAddress) throw new Error(\"No wallet address found\");\n return usesCrossapp\n ? crossAppSignTypedData(data, { address: walletAddress })\n : (await privySignTypedData(data)).signature;\n },\n [walletAddress, usesCrossapp, crossAppSignTypedData, privySignTypedData]\n );\n\n const sendTransaction = useCallback(\n async ({ transaction }: { transaction: UnsignedTransactionRequest }) => {\n if (!walletAddress) throw new Error(\"No wallet address found\");\n const tx = { ...transaction, chainId: transaction.chainId || chainId };\n\n return usesCrossapp\n ? crossAppSendTransaction(tx, { address: walletAddress })\n : (await privySendTransaction(tx, { address: walletAddress })).hash;\n },\n [chainId, usesCrossapp, walletAddress, crossAppSendTransaction, privySendTransaction]\n );\n\n return (\n <GlyphContext.Provider\n value={{\n ready: privyReady && !loading,\n authenticated: privyReady && privyAuthenticated,\n glyphUrl: glyphUrl as string, // Pass as string to avoid type error (we are passing fallback value in useGlyph hook at a common place)\n login: authenticate,\n logout,\n signMessage,\n signTypedData,\n sendTransaction,\n apiFetch: apiFetch!\n }}\n >\n {children}\n </GlyphContext.Provider>\n );\n};\n\nexport default memo(PrivyStrategy);\n"],"names":["logger","createLogger","PrivyStrategy","children","glyphUrl","onLogin","onLogout","useStagingTenant","loading","setLoading","useState","apiFetch","setApiFetch","walletAddress","setWalletAddress","usesCrossapp","setUsesCrossapp","chainId","useChainId","privyReady","privyAuthenticated","privyUser","getPrivyAccessToken","privyLogin","privyLogout","privySignMessage","privySignTypedData","privySendTransaction","usePrivy","crossAppSignMessage","crossAppSignTypedData","crossAppSendTransaction","useCrossAppAccounts","useEffect","address","privyEvmWallet","w","hasPrivyEvmWallet","isEthereumAddress","crossAppAccounts","account","otherAddresses","STAGING_GLYPH_PRIVY_APP_ID","GLYPH_PRIVY_APP_ID","glyphAddresses","glyphApiFetch","createApiFetch","WIDGET_API_BASE_URL","authenticate","useCallback","logout","signMessage","message","signTypedData","data","sendTransaction","transaction","tx","jsx","GlyphContext","PrivyStrategy_default","memo"],"mappings":"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"}
1
+ {"version":3,"file":"PrivyStrategy.js","sources":["../src/context/strategies/privyWallet.ts","../src/context/strategies/PrivyStrategy.tsx"],"sourcesContent":["import type { User } from \"@privy-io/react-auth\";\nimport { isEthereumAddress } from \"../../lib/utils\";\n\n/** Select supported EVM signers, preserving Glyph > other cross-app > native precedence. */\nexport function selectPrivyWallet(user: User | null, glyphAppId?: string) {\n const accounts = user?.linkedAccounts ?? [];\n const crossAppWallets = accounts.flatMap((account) => {\n if (account.type !== \"cross_app\" || !account.providerApp?.id) return [];\n const wallet = account.embeddedWallets?.find((wallet) => isEthereumAddress(wallet.address));\n return wallet ? [{ address: wallet.address, usesCrossapp: true, providerAppId: account.providerApp.id }] : [];\n });\n const crossApp = crossAppWallets.find((wallet) => wallet.providerAppId === glyphAppId) ?? crossAppWallets[0];\n if (crossApp) return crossApp;\n\n const native = accounts.find(\n (account) =>\n account.type === \"wallet\" &&\n account.chainType === \"ethereum\" &&\n account.walletClientType === \"privy\" &&\n isEthereumAddress(account.address)\n );\n return native?.type === \"wallet\" ? { address: native.address, usesCrossapp: false, providerAppId: null } : null;\n}\n","import { SignTypedDataParams, UnsignedTransactionRequest, useCrossAppAccounts, usePrivy } from \"@privy-io/react-auth\";\nimport react, { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useChainId } from \"wagmi\";\nimport { GLYPH_PRIVY_APP_ID, STAGING_GLYPH_PRIVY_APP_ID, WIDGET_API_BASE_URL } from \"../../lib/constants\";\nimport { BaseGlyphProviderOptions } from \"../../types\";\nimport { createApiFetch, GlyphApiFetch, GlyphContext } from \"../GlyphContext\";\nimport { selectPrivyWallet } from \"./privyWallet\";\n\nconst PrivyStrategy: react.FC<BaseGlyphProviderOptions> = ({\n children,\n glyphUrl,\n onLogin,\n onLogout,\n useStagingTenant\n}) => {\n const chainId = useChainId();\n const {\n ready: privyReady,\n authenticated: privyAuthenticated,\n user: privyUser,\n getAccessToken: getPrivyAccessToken,\n login: privyLogin,\n logout: privyLogout,\n signMessage: privySignMessage,\n signTypedData: privySignTypedData,\n sendTransaction: privySendTransaction\n } = usePrivy();\n const {\n signMessage: crossAppSignMessage,\n signTypedData: crossAppSignTypedData,\n sendTransaction: crossAppSendTransaction\n } = useCrossAppAccounts();\n\n // Ready means resolution has settled, not that this identity has an EVM wallet.\n // Derive capabilities during render so account changes never expose old state.\n const wallet =\n privyReady && privyAuthenticated && privyUser?.id\n ? selectPrivyWallet(privyUser, useStagingTenant ? STAGING_GLYPH_PRIVY_APP_ID : GLYPH_PRIVY_APP_ID)\n : null;\n const walletAddress = wallet?.address ?? null;\n const usesCrossapp = wallet?.usesCrossapp ?? false;\n const providerAppId = wallet?.providerAppId ?? null;\n const userId = privyUser?.id;\n const scope = useMemo(\n () => ({\n active: true,\n privyReady,\n privyAuthenticated,\n userId,\n walletAddress,\n usesCrossapp,\n providerAppId,\n glyphUrl,\n useStagingTenant\n }),\n [privyReady, privyAuthenticated, userId, walletAddress, usesCrossapp, providerAppId, glyphUrl, useStagingTenant]\n );\n const currentScope = useRef(scope);\n currentScope.current = scope;\n const [, rerender] = useState(0);\n useEffect(() => {\n scope.active = true;\n return () => {\n scope.active = false;\n };\n }, [scope]);\n\n const assertWalletScope = useCallback(() => {\n if (!walletAddress || !scope.active || currentScope.current !== scope) {\n throw new Error(\"Glyph wallet session is unavailable or changed\");\n }\n }, [scope, walletAddress]);\n\n const apiFetch = useMemo<GlyphApiFetch | null>(() => {\n if (!walletAddress || !scope.active) return null;\n return async (path, options) => {\n assertWalletScope();\n const token = await getPrivyAccessToken();\n assertWalletScope();\n if (!token) throw new Error(\"Privy access token is unavailable\");\n // Check scope after token resolution, before creating address-bound headers.\n const response = await createApiFetch(glyphUrl || WIDGET_API_BASE_URL, undefined, {\n Authorization: `Bearer ${token}`,\n \"x-evm-address\": walletAddress\n })(path, options);\n assertWalletScope();\n return response;\n };\n }, [walletAddress, scope, assertWalletScope, getPrivyAccessToken, glyphUrl]);\n\n const authenticate = useCallback(async () => {\n await privyLogin();\n onLogin?.();\n }, [onLogin, privyLogin]);\n\n const logout = useCallback(async () => {\n if (currentScope.current !== scope) throw new Error(\"Glyph wallet session changed\");\n // Revoke saved callbacks immediately, even while Privy logout is pending.\n scope.active = false;\n rerender((value) => value + 1);\n await privyLogout();\n onLogout?.();\n }, [scope, onLogout, privyLogout]);\n\n const signMessage = useCallback(\n async ({ message }: { message: string }) => {\n assertWalletScope();\n const signature = usesCrossapp\n ? await crossAppSignMessage(message, { address: walletAddress! })\n : (await privySignMessage({ message }, { address: walletAddress! })).signature;\n assertWalletScope();\n return signature;\n },\n [walletAddress, usesCrossapp, assertWalletScope, crossAppSignMessage, privySignMessage]\n );\n\n const signTypedData = useCallback(\n async ({ data }: { data: SignTypedDataParams }) => {\n assertWalletScope();\n const signature = usesCrossapp\n ? await crossAppSignTypedData(data, { address: walletAddress! })\n : (await privySignTypedData(data, { address: walletAddress! })).signature;\n assertWalletScope();\n return signature;\n },\n [walletAddress, usesCrossapp, assertWalletScope, crossAppSignTypedData, privySignTypedData]\n );\n\n const sendTransaction = useCallback(\n async ({ transaction }: { transaction: UnsignedTransactionRequest }) => {\n assertWalletScope();\n const tx = { ...transaction, chainId: transaction.chainId || chainId };\n const hash = usesCrossapp\n ? await crossAppSendTransaction(tx, { address: walletAddress! })\n : (await privySendTransaction(tx, { address: walletAddress! })).hash;\n assertWalletScope();\n return hash;\n },\n [chainId, usesCrossapp, walletAddress, assertWalletScope, crossAppSendTransaction, privySendTransaction]\n );\n\n const signIn = useCallback(async () => {\n try {\n await authenticate();\n return true;\n } catch {\n return false;\n }\n }, [authenticate]);\n\n return (\n <GlyphContext.Provider\n value={{\n ready: privyReady,\n authenticated: !!walletAddress && scope.active,\n glyphUrl: glyphUrl as string,\n login: authenticate,\n signIn,\n needsSignature: false,\n authError: null,\n logout,\n signMessage,\n signTypedData,\n sendTransaction,\n apiFetch: scope.active ? apiFetch : null\n }}\n >\n {children}\n </GlyphContext.Provider>\n );\n};\n\nexport default memo(PrivyStrategy);\n"],"names":["selectPrivyWallet","user","glyphAppId","accounts","crossAppWallets","account","wallet","isEthereumAddress","crossApp","native","PrivyStrategy","children","glyphUrl","onLogin","onLogout","useStagingTenant","chainId","useChainId","privyReady","privyAuthenticated","privyUser","getPrivyAccessToken","privyLogin","privyLogout","privySignMessage","privySignTypedData","privySendTransaction","usePrivy","crossAppSignMessage","crossAppSignTypedData","crossAppSendTransaction","useCrossAppAccounts","STAGING_GLYPH_PRIVY_APP_ID","GLYPH_PRIVY_APP_ID","walletAddress","usesCrossapp","providerAppId","userId","scope","useMemo","currentScope","useRef","rerender","useState","useEffect","assertWalletScope","useCallback","apiFetch","path","options","token","response","createApiFetch","WIDGET_API_BASE_URL","authenticate","logout","value","signMessage","message","signature","signTypedData","data","sendTransaction","transaction","tx","hash","signIn","jsx","GlyphContext","PrivyStrategy_default","memo"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { C as e, D as l, o as t, H as n, F as i, G as o, I as y, d as G, v as p, A as h, e as P, K as r, L as _, f as g, N as u, J as C, S as I, g as c, w as L, h as A, x as N, j as T, t as v, z as D, B as H, E as Y, s as B, n as O, k as W, l as d, u as S, m as R, q as E, p as f, r as m, y as w, M as F } from "./index.js";
1
+ import { C as e, D as l, d as t, e as n, f as i, a as o, h as y, j as p, k as G, l as h, m as P, I as r, L as _, n as g, N as u, o as C, S as I, p as c, q as L, r as A, s as N, t as T, g as v, u as D, v as H, w as Y, x as B, y as O, z as W, A as d, B as S, E as R, F as E, H as f, J as m, K as w, M as F } from "./index.js";
2
2
  export {
3
3
  e as ChainSelector,
4
4
  l as DB_OFFCHAIN_TX_TYPE,
@@ -7,8 +7,8 @@ export {
7
7
  i as GLYPH_ICON_URL,
8
8
  o as GLYPH_PRIVY_APP_ID,
9
9
  y as GlyphPrivyProvider,
10
- G as GlyphProvider,
11
- p as GlyphView,
10
+ p as GlyphProvider,
11
+ G as GlyphView,
12
12
  h as GlyphWalletProvider,
13
13
  P as GlyphWidget,
14
14
  r as InjectWagmiConnector,