@stacknet/userutils 0.2.42 → 0.2.55

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.
package/README.md ADDED
@@ -0,0 +1,397 @@
1
+ # @stacknet/userutils
2
+
3
+ Authentication, session management, and billing for StackNet apps.
4
+
5
+ Web3 wallet login (Solana, Ethereum), cross-domain SSO via auth bridge, CSRF protection, and billing/subscription hooks.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @stacknet/userutils
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ### 1. Set up environment variables
16
+
17
+ ```bash
18
+ # .env.local
19
+ AUTH_SECRET=your-hmac-secret-min-32-chars
20
+ NEXT_PUBLIC_STACK_ID=stk_your_stack_id
21
+ NEXT_PUBLIC_STACKNET_URL=https://stacknet.magma-rpc.com
22
+ ```
23
+
24
+ ### 2. Create API routes
25
+
26
+ Three server-side routes are required. These handle JWT signing, session validation, and logout — keeping secrets off the client.
27
+
28
+ ```typescript
29
+ // app/api/auth/callback/route.ts
30
+ import { createAuthCallback } from '@stacknet/userutils/server'
31
+
32
+ const handler = createAuthCallback({
33
+ authSecret: process.env.AUTH_SECRET!,
34
+ stacknetUrl: process.env.NEXT_PUBLIC_STACKNET_URL || 'https://stacknet.magma-rpc.com',
35
+ stackId: process.env.NEXT_PUBLIC_STACK_ID!,
36
+ secureCookies: process.env.NODE_ENV === 'production',
37
+ })
38
+
39
+ export async function POST(request: Request) {
40
+ return handler(request)
41
+ }
42
+ ```
43
+
44
+ ```typescript
45
+ // app/api/auth/session/route.ts
46
+ import { createSessionHandler } from '@stacknet/userutils/server'
47
+
48
+ const handler = createSessionHandler({
49
+ authSecret: process.env.AUTH_SECRET!,
50
+ secureCookies: process.env.NODE_ENV === 'production',
51
+ })
52
+
53
+ export async function GET(request: Request) {
54
+ return handler(request)
55
+ }
56
+ ```
57
+
58
+ ```typescript
59
+ // app/api/auth/logout/route.ts
60
+ import { createLogoutHandler } from '@stacknet/userutils/server'
61
+
62
+ const handler = createLogoutHandler({
63
+ stacknetUrl: process.env.NEXT_PUBLIC_STACKNET_URL || 'https://stacknet.magma-rpc.com',
64
+ secureCookies: process.env.NODE_ENV === 'production',
65
+ })
66
+
67
+ export async function POST(request: Request) {
68
+ return handler(request)
69
+ }
70
+ ```
71
+
72
+ ### 3. Wrap your app with the provider
73
+
74
+ ```tsx
75
+ // components/auth-provider.tsx
76
+ 'use client'
77
+
78
+ import { UserUtilsProvider } from '@stacknet/userutils/components'
79
+
80
+ const config = {
81
+ apiBaseUrl: '', // same-origin — hooks call your /api/auth/* routes
82
+ stackId: process.env.NEXT_PUBLIC_STACK_ID,
83
+ stacknetUrl: process.env.NEXT_PUBLIC_STACKNET_URL,
84
+ theme: 'dark',
85
+ }
86
+
87
+ export function AuthProvider({ children }) {
88
+ return (
89
+ <UserUtilsProvider config={config}>
90
+ {children}
91
+ </UserUtilsProvider>
92
+ )
93
+ }
94
+ ```
95
+
96
+ ```tsx
97
+ // app/layout.tsx
98
+ import { AuthProvider } from '../components/auth-provider'
99
+
100
+ export default function RootLayout({ children }) {
101
+ return (
102
+ <html>
103
+ <body>
104
+ <AuthProvider>{children}</AuthProvider>
105
+ </body>
106
+ </html>
107
+ )
108
+ }
109
+ ```
110
+
111
+ ### 4. Add a connect page
112
+
113
+ ```tsx
114
+ // app/connect/page.tsx
115
+ 'use client'
116
+
117
+ import { ConnectWidget } from '@stacknet/userutils/components'
118
+
119
+ export default function ConnectPage() {
120
+ return (
121
+ <ConnectWidget
122
+ config={{
123
+ apiBaseUrl: '',
124
+ stackId: process.env.NEXT_PUBLIC_STACK_ID,
125
+ stacknetUrl: process.env.NEXT_PUBLIC_STACKNET_URL,
126
+ }}
127
+ onSuccess={() => { window.location.href = '/' }}
128
+ showWallets={['phantom', 'metamask']}
129
+ showOTP={false}
130
+ />
131
+ )
132
+ }
133
+ ```
134
+
135
+ ### 5. Show auth state in your header
136
+
137
+ ```tsx
138
+ // components/header.tsx
139
+ 'use client'
140
+
141
+ import { useSession, useStackAuth } from '@stacknet/userutils/hooks'
142
+ import Link from 'next/link'
143
+
144
+ export function Header() {
145
+ const { isAuthenticated, loading } = useSession()
146
+ const { session, logout, wallet } = useStackAuth()
147
+
148
+ const displayAddress = wallet.address
149
+ ? `${wallet.address.slice(0, 4)}...${wallet.address.slice(-4)}`
150
+ : session?.userId?.slice(0, 8) ?? ''
151
+
152
+ if (loading) return <div>Loading...</div>
153
+
154
+ if (isAuthenticated) {
155
+ return (
156
+ <div>
157
+ <span>{displayAddress}</span>
158
+ <button onClick={logout}>Logout</button>
159
+ </div>
160
+ )
161
+ }
162
+
163
+ return <Link href="/connect">Log in</Link>
164
+ }
165
+ ```
166
+
167
+ ## Auth Flow
168
+
169
+ ```
170
+ 1. User clicks wallet button in ConnectWidget
171
+ 2. useStackAuth calls StackNet: POST /api/v2/stacks/{stackId}/auth/web3/challenge
172
+ 3. User signs the challenge message with their wallet
173
+ 4. Client POSTs signature to your /api/auth/callback
174
+ 5. Server verifies with StackNet, re-signs JWT with AUTH_SECRET
175
+ 6. Server sets three cookies:
176
+ - stackauth_jwt (HttpOnly) — server-side session validation
177
+ - stackauth_session (readable) — client-side UI state
178
+ - __csrf — CSRF protection token
179
+ 7. useSession() reads stackauth_session cookie → isAuthenticated: true
180
+ 8. UI updates to show authenticated state
181
+ ```
182
+
183
+ ## Cookies
184
+
185
+ | Cookie | HttpOnly | Purpose |
186
+ |--------|----------|---------|
187
+ | `stackauth_jwt` | Yes | Server-side JWT (15 min, auto-refreshes) |
188
+ | `stackauth_session` | No | Public session for UI (userId, address, chain, expiresAt) |
189
+ | `__csrf` | No | CSRF double-submit token |
190
+
191
+ The JWT auto-refreshes when `/api/auth/session` is called and the token is within 5 minutes of expiry.
192
+
193
+ ## Hooks
194
+
195
+ ### useSession()
196
+
197
+ Reads the public session cookie. No network calls.
198
+
199
+ ```typescript
200
+ const { session, loading, isAuthenticated, refresh, readSession } = useSession()
201
+
202
+ // session: { userId, address, chain, expiresAt, planId, authMethod } | null
203
+ // isAuthenticated: boolean (session exists and not expired)
204
+ ```
205
+
206
+ ### useStackAuth(config?)
207
+
208
+ Full auth engine — wallet connection, challenge/sign/verify, logout, bridge.
209
+
210
+ ```typescript
211
+ const {
212
+ session, // PublicSession | null
213
+ isAuthenticated, // boolean
214
+ wallet, // { connected, address, chain, provider }
215
+ loading, // boolean (auth in progress)
216
+ error, // string | null
217
+ authenticateSolana, // (provider?: 'phantom' | 'solflare') => Promise<boolean>
218
+ authenticateEVM, // () => Promise<boolean>
219
+ authenticateOTP, // (code: string) => Promise<boolean>
220
+ logout, // () => Promise<void>
221
+ refresh, // () => Promise<any>
222
+ stackId, // effective stack ID
223
+ bridge, // { ready, known, identity, identityCount, resolvedStackId }
224
+ } = useStackAuth({
225
+ apiBaseUrl: '',
226
+ stackId: 'stk_...',
227
+ stacknetUrl: 'https://stacknet.magma-rpc.com',
228
+ autoConnect: false, // true = auto-login if bridge has known identity
229
+ })
230
+ ```
231
+
232
+ ### useAuthBridge(opts?)
233
+
234
+ Cross-domain auth state detection via iframe.
235
+
236
+ ```typescript
237
+ const bridge = useAuthBridge()
238
+
239
+ // bridge.ready — iframe loaded
240
+ // bridge.known — previous auth found
241
+ // bridge.identity — { address, chain, method, stackCount }
242
+ // bridge.resolvedStackId — last stackId used on this domain
243
+ // bridge.reportConnected({ address, chain, method, stackId })
244
+ // bridge.reportDisconnected({ address, chain, stackId })
245
+ ```
246
+
247
+ The bridge never transmits JWTs — only public metadata (address, chain, method, stackId).
248
+
249
+ ### useWeb3Wallet()
250
+
251
+ Low-level wallet connection. Used internally by useStackAuth.
252
+
253
+ ```typescript
254
+ const { wallet, connectSolana, connectEVM, signMessage, disconnect } = useWeb3Wallet()
255
+ ```
256
+
257
+ ### useCSRFToken(cookieName?, headerName?)
258
+
259
+ Reads CSRF token for mutation requests.
260
+
261
+ ```typescript
262
+ const { token, headers } = useCSRFToken()
263
+ // headers = { 'x-csrf-token': '...' }
264
+ ```
265
+
266
+ ### Billing hooks
267
+
268
+ ```typescript
269
+ const { plans, loading } = usePlans(apiBaseUrl?)
270
+ const { subscription, subscribe, cancel } = useSubscription(apiBaseUrl?)
271
+ const { usage, refresh } = useUsage(apiBaseUrl?)
272
+ const { purchase, verifySession } = usePrepaidCheckout(apiBaseUrl?)
273
+ const { records, refresh } = useBillingHistory(apiBaseUrl?, { limit, offset })
274
+ ```
275
+
276
+ ## Components
277
+
278
+ ### ConnectWidget
279
+
280
+ Drop-in wallet connect UI.
281
+
282
+ ```tsx
283
+ <ConnectWidget
284
+ config={config} // UserUtilsConfig (required)
285
+ onSuccess={() => {}} // Called after successful auth
286
+ title="Connect" // Heading text
287
+ showWallets={['phantom', 'metamask']} // Which wallets to show
288
+ showOTP={false} // Show access code option
289
+ className="" // CSS classes
290
+ />
291
+ ```
292
+
293
+ ### UserUtilsProvider
294
+
295
+ React context provider. Wrap your app with this.
296
+
297
+ ```tsx
298
+ <UserUtilsProvider config={config} callbacks={callbacks?}>
299
+ {children}
300
+ </UserUtilsProvider>
301
+ ```
302
+
303
+ ## Server Exports
304
+
305
+ ```typescript
306
+ import {
307
+ // Auth route handlers
308
+ createAuthCallback, // POST /api/auth/callback
309
+ createSessionHandler, // GET /api/auth/session
310
+ createLogoutHandler, // POST /api/auth/logout
311
+ createOTPHandler, // POST /api/auth/otp
312
+
313
+ // Billing proxy
314
+ createBillingProxy, // All billing routes
315
+ createWebhookHandler, // Stripe webhooks
316
+
317
+ // JWT utilities
318
+ signJWT,
319
+ verifyJWT,
320
+ verifyJWTSignature,
321
+ decodeJWTPayload,
322
+ maybeRefreshJWT,
323
+ extractJwt,
324
+
325
+ // Security
326
+ createCSRFProtection,
327
+ securityHeaders,
328
+ withSecurityHeaders,
329
+ nextSecurityHeaders,
330
+ extractIP,
331
+ generateToken,
332
+
333
+ // StackNet proxy
334
+ buildStackNetHeaders,
335
+ resignForStackNet,
336
+
337
+ // Rate limiting
338
+ createInMemoryRateLimiter,
339
+ createInMemoryReplayStore,
340
+ } from '@stacknet/userutils/server'
341
+ ```
342
+
343
+ ## Server Config
344
+
345
+ ```typescript
346
+ interface ServerConfig {
347
+ authSecret: string // HMAC-SHA256 secret for signing JWTs
348
+ stacknetUrl: string // https://stacknet.magma-rpc.com
349
+ stackId: string // Your stack ID
350
+ stacknetJwtSecret?: string // For re-signing to StackNet (defaults to authSecret)
351
+ cookieDomain?: string // For subdomain sharing (e.g. '.geoff.ai')
352
+ secureCookies?: boolean // Secure flag on cookies (default: true)
353
+ sessionMaxAge?: number // Session duration in seconds (default: 604800 = 7 days)
354
+ jwtExpiry?: number // JWT expiry in seconds (default: 900 = 15 min)
355
+ }
356
+ ```
357
+
358
+ ## Auth Bridge
359
+
360
+ The auth bridge enables cross-domain session detection via an invisible iframe loaded from `https://stacknet.magma-rpc.com/auth/bridge`.
361
+
362
+ When a user authenticates on one stack app, the bridge stores their public identity (address, chain, method). When they visit another stack app, `useAuthBridge()` detects the known identity and can auto-trigger wallet connection if `autoConnect: true`.
363
+
364
+ The bridge uses postMessage with the `stacknet-auth-bridge` protocol. It never stores or transmits JWTs.
365
+
366
+ ## Proxying to StackNet
367
+
368
+ If your app needs to call StackNet APIs on behalf of the user, store the original StackNet JWT in a separate cookie during callback:
369
+
370
+ ```typescript
371
+ // In your custom /api/auth/callback handler:
372
+ const originalJwt = sessionData.jwt
373
+ headers.append('Set-Cookie',
374
+ `stacknet_jwt=${originalJwt}; Path=/; HttpOnly; SameSite=Lax; Max-Age=604800${secureSuffix}`
375
+ )
376
+
377
+ // In your proxy routes:
378
+ import { extractJwt } from '@stacknet/userutils/server'
379
+
380
+ const jwt = extractJwt(request) // reads stackauth_jwt cookie
381
+ const headers = buildStackNetHeaders(jwt, process.env.STACKNET_JWT_SECRET!)
382
+ await fetch(`https://stacknet.magma-rpc.com/api/...`, { headers })
383
+ ```
384
+
385
+ ## Security
386
+
387
+ - **HttpOnly cookies** prevent XSS token theft
388
+ - **SameSite=Lax** prevents CSRF on state-changing requests
389
+ - **Secure flag** enforces HTTPS in production
390
+ - **CSRF double-submit** validates cookie matches header on mutations
391
+ - **Short JWT expiry** (15 min) with transparent auto-refresh
392
+ - **Rate limiting** on auth callback (10 req/min per IP)
393
+ - **Constant-time comparison** for JWT signature validation
394
+
395
+ ## License
396
+
397
+ MIT
@@ -1,2 +1,2 @@
1
- 'use strict';var react=require('react'),jsxRuntime=require('react/jsx-runtime');var ge=react.createContext(null);function We(){let e=react.useContext(ge);if(!e)throw new Error("useUserUtilsContext must be used within <UserUtilsProvider>");return e}function Re({config:e,callbacks:n,children:r}){return jsxRuntime.jsx(ge.Provider,{value:{config:e,callbacks:n},children:r})}function he(){let[e,n]=react.useState({connected:false,address:null,chain:null,provider:null}),[r,l]=react.useState(null),h=react.useCallback(async(p="phantom")=>{l(null);try{let d=typeof window<"u"?window:null,N=p==="phantom"?d?.phantom?.solana||d?.solana:d?.solflare;if(!N)return l(`${p} wallet not found`),null;let u=(await N.connect()).publicKey.toString();return n({connected:!0,address:u,chain:"solana",provider:p}),u}catch(d){return l(d.message||"Failed to connect wallet"),null}},[]),y=react.useCallback(async()=>{l(null);try{let d=(typeof window<"u"?window:null)?.ethereum;if(!d)return l("MetaMask not found"),null;let N=d;d.providers?.length&&(N=d.providers.find(t=>t.isMetaMask)||d);let u=(await N.request({method:"eth_requestAccounts"}))[0];return u?(n({connected:!0,address:u,chain:"ethereum",provider:"metamask"}),u):(l("No account selected"),null)}catch(p){return l(p.message||"Failed to connect wallet"),null}},[]),g=react.useCallback(async(p,d)=>{l(null);let N=d?.chain||e.chain,s=d?.provider||e.provider,u=d?.address||e.address;try{if(N==="solana"){let t=typeof window<"u"?window:null,o=s==="solflare"?t?.solflare:t?.phantom?.solana||t?.solana;if(!o)throw new Error("Wallet not available");let c=new TextEncoder().encode(p),w=await o.signMessage(c,"utf8"),I=new Uint8Array(w.signature||w),b="";for(let S=0;S<I.byteLength;S++)b+=String.fromCharCode(I[S]);return btoa(b)}if(N==="ethereum"){let o=(typeof window<"u"?window:null)?.ethereum;if(o?.providers?.length&&(o=o.providers.find(w=>w.isMetaMask)||o),!o)throw new Error("MetaMask not available");return await o.request({method:"personal_sign",params:[p,u]})}throw new Error("No wallet connected")}catch(t){return l(t.message||"Signing failed"),null}},[e]),i=react.useCallback(()=>{n({connected:false,address:null,chain:null,provider:null}),l(null);},[]);return {wallet:e,error:r,connectSolana:h,connectEVM:y,signMessage:g,disconnect:i}}function ke(){if(typeof document>"u")return null;try{let e=document.cookie.split(";").map(r=>r.trim()).find(r=>r.startsWith("stackauth_session="));if(!e)return null;let n=e.slice(18);return JSON.parse(atob(n.replace(/-/g,"+").replace(/_/g,"/")))}catch{return null}}function ye(e="__csrf"){if(typeof document>"u")return null;let n=document.cookie.split(";").map(r=>r.trim()).find(r=>r.startsWith(`${e}=`));return n?n.slice(e.length+1):null}function Ne(){let[e,n]=react.useState(null),[r,l]=react.useState(true),h=react.useCallback(()=>{let i=ke();i&&i.expiresAt>Date.now()?n({userId:i.userId,address:i.address,chain:i.chain,expiresAt:i.expiresAt,planId:i.planId,authMethod:i.authMethod}):n(null),l(false);},[]);react.useEffect(()=>{h();},[h]);let y=react.useCallback(async(i="")=>{try{let p=await fetch(`${i}/api/auth/session`);if(p.ok){let d=await p.json();if(d.session)return n(d.session),d.session}return n(null),null}catch{return null}},[]),g=!!e&&e.expiresAt>Date.now();return {session:e,loading:r,isAuthenticated:g,refresh:y,readSession:h}}function xe(e="__csrf",n="x-csrf-token"){let[r,l]=react.useState(null);react.useEffect(()=>{l(ye(e));},[e]);let h=r?{[n]:r}:{};return {token:r,headers:h}}var Ge="https://stacknet.magma-rpc.com/auth/bridge",J="stacknet-auth-bridge";function Ce(e){let n=e?.bridgeUrl||Ge,r=e?.disabled||false,l=react.useRef(null),[h,y]=react.useState({ready:false,known:false,identity:null,identityCount:0,resolvedStackId:null}),g=react.useRef([]),i=react.useRef(false),p=react.useCallback(t=>{let o={...t,protocol:J};i.current&&l.current?.contentWindow?l.current.contentWindow.postMessage(o,new URL(n).origin):g.current.push(o);},[n]);react.useEffect(()=>{if(r)return;let t=c=>{if(!(!c.data||c.data.protocol!==J)){try{if(c.origin!==new URL(n).origin)return}catch{return}switch(c.data.type){case "bridge:ready":i.current=true,y(w=>({...w,ready:true}));for(let w of g.current)l.current?.contentWindow?.postMessage(w,c.origin);g.current=[],l.current?.contentWindow?.postMessage({protocol:J,type:"auth:check"},c.origin),l.current?.contentWindow?.postMessage({protocol:J,type:"auth:resolve-stack"},c.origin);break;case "auth:status":y(w=>({...w,known:c.data.known,identity:c.data.identity,identityCount:c.data.identityCount||0}));break;case "auth:resolved-stack":y(w=>({...w,resolvedStackId:c.data.stackId||null}));break;}}};window.addEventListener("message",t);let o=document.createElement("iframe");return o.src=n,o.style.display="none",o.setAttribute("aria-hidden","true"),o.setAttribute("tabindex","-1"),o.setAttribute("sandbox","allow-scripts allow-same-origin"),document.body.appendChild(o),l.current=o,()=>{window.removeEventListener("message",t),o.parentNode&&o.parentNode.removeChild(o),l.current=null,i.current=false;}},[n,r]);let d=react.useCallback(t=>{p({type:"auth:connected",...t});},[p]),N=react.useCallback(t=>{p({type:"auth:disconnected",...t});},[p]),s=react.useCallback(()=>{p({type:"auth:clear"}),y({ready:h.ready,known:false,identity:null,identityCount:0,resolvedStackId:null});},[p,h.ready]),u=react.useCallback(()=>{p({type:"auth:check"});},[p]);return {...h,reportConnected:d,reportDisconnected:N,clearAll:s,refresh:u}}async function Me(e,n,r,l){let h=e.apiVersion||"v2",y=`${e.baseUrl}/api/${h}${r}`;try{let g=await fetch(y,{method:n,headers:{"Content-Type":"application/json"},body:l?JSON.stringify(l):void 0}),i=await g.json();return g.ok?i.success&&i.data!==void 0?{success:!0,data:i.data}:{success:!0,data:i}:{success:!1,error:i.error||{code:"UNKNOWN_ERROR",message:"Unknown error"}}}catch(g){return {success:false,error:{code:"NETWORK_ERROR",message:g instanceof Error?g.message:"Network error"}}}}function ve(e){return {getNetworkStatus:()=>Me(e,"GET","/network/status"),getWeb3Challenge:(n,r)=>Me(e,"POST",`/stacks/${e.stackId}/auth/web3/challenge`,{chain:n,address:r})}}function Ie(e={apiBaseUrl:""}){let{wallet:n,connectSolana:r,connectEVM:l,signMessage:h,disconnect:y}=he(),{session:g,isAuthenticated:i,refresh:p,readSession:d}=Ne(),{headers:N}=xe(),s=Ce({disabled:typeof window>"u"}),[u,t]=react.useState(false),[o,c]=react.useState(null),[w,I]=react.useState(false),b=e.apiBaseUrl||"",S=e.stacknetUrl||"https://stacknet.magma-rpc.com",U=e.stackId||s.resolvedStackId||"",C=ve({baseUrl:S,stackId:U}),v=react.useCallback(async(k,x,R,D)=>{t(true),c(null);try{let L=x;if(!L){let E=await R();if(!E)return t(!1),!1;L=E;}let T=await C.getWeb3Challenge(k,L);if(!T.success||!T.data)return c("Failed to get challenge"),t(!1),!1;let _=await h(T.data.message,{chain:k,provider:D,address:L});if(!_)return t(!1),!1;let B={chain:k,message:T.data.message,signature:_,stackId:U};k==="solana"&&(B.publicKey=L);let O=await fetch(`${b}/api/auth/callback`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(B)});if(!O.ok){let E=await O.json().catch(()=>({}));return c(E.error||"Authentication failed"),t(!1),!1}return s.reportConnected({address:L,chain:k,method:D||(k==="solana"?"phantom":"metamask"),stackId:U}),d(),t(!1),!0}catch(L){return c(L.message||"Authentication failed"),t(false),false}},[b,C,h,d,s,U]),P=react.useCallback(async(k="phantom")=>{let x=await r(k);return x?v("solana",x,()=>r(k),k):false},[r,v]),z=react.useCallback(async()=>{let k=await l();return k?v("ethereum",k,l,"metamask"):false},[l,v]),Z=react.useCallback(async k=>{t(true),c(null);try{let x=await fetch(`${b}/api/auth/otp`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:k})});if(!x.ok){let R=await x.json().catch(()=>({}));return c(R.error||"Invalid code"),t(!1),!1}return d(),t(!1),!0}catch(x){return c(x.message||"OTP verification failed"),t(false),false}},[b,d]),V=react.useCallback(async()=>{n.address&&n.chain&&s.reportDisconnected({address:n.address,chain:n.chain,stackId:U});try{await fetch(`${b}/api/auth/logout`,{method:"POST",headers:N});}catch{}y(),d();},[b,N,y,d,n,s,U]);return react.useEffect(()=>{if(!e.autoConnect||w||i||!s.ready||!s.known||!s.identity)return;I(true);let{chain:k,method:x}=s.identity;k==="solana"&&(x==="phantom"||x==="solflare")?P(x):k==="ethereum"&&z();},[e.autoConnect,w,i,s,P,z]),{session:g,isAuthenticated:i,wallet:n,loading:u,error:o,authenticateSolana:P,authenticateEVM:z,authenticateOTP:Z,logout:V,refresh:()=>p(b),stackId:U,bridge:{ready:s.ready,known:s.known,identity:s.identity,identityCount:s.identityCount,resolvedStackId:s.resolvedStackId}}}function Le(e,n="https://stacknet.magma-rpc.com"){let[r,l]=react.useState(null),[h,y]=react.useState(false),[g,i]=react.useState(null),p=react.useCallback(async N=>{y(true),i(null);try{let s=await fetch(`${n}/api/v2/stacks/${N}`);if(!s.ok)return i("Stack not found"),y(!1),null;let u=await s.json(),t=u.data?.stack||u.stack||u,o={id:t.id,name:t.name,displayName:t.displayName||t.name,description:t.description,logoUrl:t.logoUrl,webPageUrl:t.webPageUrl,allowedChains:t.allowedChains||[],features:t.features,stripeProvider:t.stripeProvider,oauthProviders:t.oauthProviders?.map(c=>({provider:c.provider,enabled:c.enabled!==!1}))};return l(o),y(!1),o}catch(s){return i(s.message),y(false),null}},[n]);react.useEffect(()=>{e&&p(e);},[e,p]);let d=r?Ke(r):[];return {config:r,loading:h,error:g,identityProviders:d,fetchConfig:p}}function Ke(e){let n=[];if(e.features?.web3Auth!==false&&(e.allowedChains.includes("solana")&&(n.push({type:"wallet",id:"phantom",name:"Phantom",chain:"solana"}),n.push({type:"wallet",id:"solflare",name:"Solflare",chain:"solana"})),(e.allowedChains.includes("ethereum")||e.allowedChains.includes("polygon")||e.allowedChains.includes("base"))&&n.push({type:"wallet",id:"metamask",name:"MetaMask",chain:"ethereum"})),e.features?.apiKeyAuth!==false&&n.push({type:"otp",id:"otp",name:"Access Code"}),e.features?.oauthAuth&&e.oauthProviders)for(let r of e.oauthProviders)r.enabled&&n.push({type:"oauth",id:r.provider,name:r.provider});return n}function q({length:e=6,onComplete:n,disabled:r=false,error:l,className:h="",inputClassName:y=""}){let [g,i]=react.useState(Array(e).fill("")),p=react.useCallback((s,u)=>{if(u.length>1){let o=u.replace(/\D/g,"").slice(0,e).split(""),c=[...g];o.forEach((I,b)=>{s+b<e&&(c[s+b]=I);}),i(c);let w=Math.min(s+o.length,e-1);document.getElementById(`userutils-otp-${w}`)?.focus(),c.every(I=>I!=="")&&setTimeout(()=>n(c.join("")),100);return}if(!/^\d?$/.test(u))return;let t=[...g];t[s]=u,i(t),u&&s<e-1&&document.getElementById(`userutils-otp-${s+1}`)?.focus(),u&&s===e-1&&t.every(o=>o!=="")&&setTimeout(()=>n(t.join("")),100);},[g,e,n]),d=react.useCallback((s,u)=>{if(u.key==="Backspace"&&!g[s]&&s>0){document.getElementById(`userutils-otp-${s-1}`)?.focus();let t=[...g];t[s-1]="",i(t);}if(u.key==="Enter"){let t=g.join("");t.length===e&&n(t);}},[g,e,n]);react.useCallback(()=>{i(Array(e).fill("")),document.getElementById("userutils-otp-0")?.focus();},[e]);return jsxRuntime.jsxs("div",{className:h,children:[jsxRuntime.jsx("div",{className:"flex gap-2 justify-center",children:g.map((s,u)=>jsxRuntime.jsx("input",{id:`userutils-otp-${u}`,type:"text",inputMode:"numeric",maxLength:e,value:s,onChange:t=>p(u,t.target.value),onKeyDown:t=>d(u,t),disabled:r,autoFocus:u===0,className:`w-12 h-14 text-center text-xl font-mono bg-secondary border border-primary/10 text-foreground focus:outline-none focus:border-primary/30 disabled:opacity-50 ${y}`},u))}),l&&jsxRuntime.jsx("p",{className:"text-center text-sm text-red-400 mt-2",children:l})]})}q.displayName="OTPInput";var Xe="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTA4IiBoZWlnaHQ9IjEwOCIgdmlld0JveD0iMCAwIDEwOCAxMDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxMDgiIGhlaWdodD0iMTA4IiByeD0iMjYiIGZpbGw9IiNBQjlGRjIiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00Ni41MjY3IDY5LjkyMjlDNDIuMDA1NCA3Ni44NTA5IDM0LjQyOTIgODUuNjE4MiAyNC4zNDggODUuNjE4MkMxOS41ODI0IDg1LjYxODIgMTUgODMuNjU2MyAxNSA3NS4xMzQyQzE1IDUzLjQzMDUgNDQuNjMyNiAxOS44MzI3IDcyLjEyNjggMTkuODMyN0M4Ny43NjggMTkuODMyNyA5NCAzMC42ODQ2IDk0IDQzLjAwNzlDOTQgNTguODI1OCA4My43MzU1IDc2LjkxMjIgNzMuNTMyMSA3Ni45MTIyQzcwLjI5MzkgNzYuOTEyMiA2OC43MDUzIDc1LjEzNDIgNjguNzA1MyA3Mi4zMTRDNjguNzA1MyA3MS41NzgzIDY4LjgyNzUgNzAuNzgxMiA2OS4wNzE5IDY5LjkyMjlDNjUuNTg5MyA3NS44Njk5IDU4Ljg2ODUgODEuMzg3OCA1Mi41NzU0IDgxLjM4NzhDNDcuOTkzIDgxLjM4NzggNDUuNjcxMyA3OC41MDYzIDQ1LjY3MTMgNzQuNDU5OEM0NS42NzEzIDcyLjk4ODQgNDUuOTc2OCA3MS40NTU2IDQ2LjUyNjcgNjkuOTIyOVpNODMuNjc2MSA0Mi41Nzk0QzgzLjY3NjEgNDYuMTcwNCA4MS41NTc1IDQ3Ljk2NTggNzkuMTg3NSA0Ny45NjU4Qzc2Ljc4MTYgNDcuOTY1OCA3NC42OTg5IDQ2LjE3MDQgNzQuNjk4OSA0Mi41Nzk0Qzc0LjY5ODkgMzguOTg4NSA3Ni43ODE2IDM3LjE5MzEgNzkuMTg3NSAzNy4xOTMxQzgxLjU1NzUgMzcuMTkzMSA4My42NzYxIDM4Ljk4ODUgODMuNjc2MSA0Mi41Nzk0Wk03MC4yMTAzIDQyLjU3OTVDNzAuMjEwMyA0Ni4xNzA0IDY4LjA5MTYgNDcuOTY1OCA2NS43MjE2IDQ3Ljk2NThDNjMuMzE1NyA0Ny45NjU4IDYxLjIzMyA0Ni4xNzA0IDYxLjIzMyA0Mi41Nzk1QzYxLjIzMyAzOC45ODg1IDYzLjMxNTcgMzcuMTkzMSA2NS43MjE2IDM3LjE5MzFDNjguMDkxNiAzNy4xOTMxIDcwLjIxMDMgMzguOTg4NSA3MC4yMTAzIDQyLjU3OTVaIiBmaWxsPSIjRkZGREY4Ii8+Cjwvc3ZnPgo=";function X({className:e}){return jsxRuntime.jsx("img",{src:Xe,alt:"Phantom",className:e})}function ee({className:e}){return jsxRuntime.jsxs("svg",{className:e,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 507.83 470.86",children:[jsxRuntime.jsx("polygon",{fill:"#e2761b",stroke:"#e2761b",strokeLinecap:"round",strokeLinejoin:"round",points:"482.09 0.5 284.32 147.38 320.9 60.72 482.09 0.5"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"25.54 0.5 221.72 148.77 186.93 60.72 25.54 0.5"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"410.93 340.97 358.26 421.67 470.96 452.67 503.36 342.76 410.93 340.97"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"4.67 342.76 36.87 452.67 149.57 421.67 96.9 340.97 4.67 342.76"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"143.21 204.62 111.8 252.13 223.7 257.1 219.73 136.85 143.21 204.62"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"364.42 204.62 286.91 135.46 284.32 257.1 396.03 252.13 364.42 204.62"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"149.57 421.67 216.75 388.87 158.71 343.55 149.57 421.67"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"290.88 388.87 358.26 421.67 348.92 343.55 290.88 388.87"}),jsxRuntime.jsx("polygon",{fill:"#d7c1b3",stroke:"#d7c1b3",strokeLinecap:"round",strokeLinejoin:"round",points:"358.26 421.67 290.88 388.87 296.25 432.8 295.65 451.28 358.26 421.67"}),jsxRuntime.jsx("polygon",{fill:"#d7c1b3",stroke:"#d7c1b3",strokeLinecap:"round",strokeLinejoin:"round",points:"149.57 421.67 212.18 451.28 211.78 432.8 216.75 388.87 149.57 421.67"}),jsxRuntime.jsx("polygon",{fill:"#233447",stroke:"#233447",strokeLinecap:"round",strokeLinejoin:"round",points:"213.17 314.54 157.12 298.04 196.67 279.95 213.17 314.54"}),jsxRuntime.jsx("polygon",{fill:"#233447",stroke:"#233447",strokeLinecap:"round",strokeLinejoin:"round",points:"294.46 314.54 310.96 279.95 350.71 298.04 294.46 314.54"}),jsxRuntime.jsx("polygon",{fill:"#cd6116",stroke:"#cd6116",strokeLinecap:"round",strokeLinejoin:"round",points:"149.57 421.67 159.11 340.97 96.9 342.76 149.57 421.67"}),jsxRuntime.jsx("polygon",{fill:"#cd6116",stroke:"#cd6116",strokeLinecap:"round",strokeLinejoin:"round",points:"348.72 340.97 358.26 421.67 410.93 342.76 348.72 340.97"}),jsxRuntime.jsx("polygon",{fill:"#cd6116",stroke:"#cd6116",strokeLinecap:"round",strokeLinejoin:"round",points:"396.03 252.13 284.32 257.1 294.66 314.54 311.16 279.95 350.91 298.04 396.03 252.13"}),jsxRuntime.jsx("polygon",{fill:"#cd6116",stroke:"#cd6116",strokeLinecap:"round",strokeLinejoin:"round",points:"157.12 298.04 196.87 279.95 213.17 314.54 223.7 257.1 111.8 252.13 157.12 298.04"}),jsxRuntime.jsx("polygon",{fill:"#e4751f",stroke:"#e4751f",strokeLinecap:"round",strokeLinejoin:"round",points:"111.8 252.13 158.71 343.55 157.12 298.04 111.8 252.13"}),jsxRuntime.jsx("polygon",{fill:"#e4751f",stroke:"#e4751f",strokeLinecap:"round",strokeLinejoin:"round",points:"350.91 298.04 348.92 343.55 396.03 252.13 350.91 298.04"}),jsxRuntime.jsx("polygon",{fill:"#e4751f",stroke:"#e4751f",strokeLinecap:"round",strokeLinejoin:"round",points:"223.7 257.1 213.17 314.54 226.29 382.31 229.27 293.07 223.7 257.1"}),jsxRuntime.jsx("polygon",{fill:"#e4751f",stroke:"#e4751f",strokeLinecap:"round",strokeLinejoin:"round",points:"284.32 257.1 278.96 292.87 281.34 382.31 294.66 314.54 284.32 257.1"}),jsxRuntime.jsx("polygon",{fill:"#f6851b",stroke:"#f6851b",strokeLinecap:"round",strokeLinejoin:"round",points:"294.66 314.54 281.34 382.31 290.88 388.87 348.92 343.55 350.91 298.04 294.66 314.54"}),jsxRuntime.jsx("polygon",{fill:"#f6851b",stroke:"#f6851b",strokeLinecap:"round",strokeLinejoin:"round",points:"157.12 298.04 158.71 343.55 216.75 388.87 226.29 382.31 213.17 314.54 157.12 298.04"}),jsxRuntime.jsx("polygon",{fill:"#c0ad9e",stroke:"#c0ad9e",strokeLinecap:"round",strokeLinejoin:"round",points:"295.65 451.28 296.25 432.8 291.28 428.42 216.35 428.42 211.78 432.8 212.18 451.28 149.57 421.67 171.43 439.55 215.75 470.36 291.88 470.36 336.4 439.55 358.26 421.67 295.65 451.28"}),jsxRuntime.jsx("polygon",{fill:"#161616",stroke:"#161616",strokeLinecap:"round",strokeLinejoin:"round",points:"290.88 388.87 281.34 382.31 226.29 382.31 216.75 388.87 211.78 432.8 216.35 428.42 291.28 428.42 296.25 432.8 290.88 388.87"}),jsxRuntime.jsx("polygon",{fill:"#763d16",stroke:"#763d16",strokeLinecap:"round",strokeLinejoin:"round",points:"490.44 156.92 507.33 75.83 482.09 0.5 290.88 142.41 364.42 204.62 468.37 235.03 491.43 208.2 481.49 201.05 497.39 186.54 485.07 177 500.97 164.87 490.44 156.92"}),jsxRuntime.jsx("polygon",{fill:"#763d16",stroke:"#763d16",strokeLinecap:"round",strokeLinejoin:"round",points:"0.5 75.83 17.39 156.92 6.66 164.87 22.56 177 10.44 186.54 26.34 201.05 16.4 208.2 39.26 235.03 143.21 204.62 216.75 142.41 25.54 0.5 0.5 75.83"}),jsxRuntime.jsx("polygon",{fill:"#f6851b",stroke:"#f6851b",strokeLinecap:"round",strokeLinejoin:"round",points:"468.37 235.03 364.42 204.62 396.03 252.13 348.92 343.55 410.93 342.76 503.36 342.76 468.37 235.03"}),jsxRuntime.jsx("polygon",{fill:"#f6851b",stroke:"#f6851b",strokeLinecap:"round",strokeLinejoin:"round",points:"143.21 204.62 39.26 235.03 4.67 342.76 96.9 342.76 158.71 343.55 111.8 252.13 143.21 204.62"}),jsxRuntime.jsx("polygon",{fill:"#f6851b",stroke:"#f6851b",strokeLinecap:"round",strokeLinejoin:"round",points:"284.32 257.1 290.88 142.41 321.1 60.72 186.93 60.72 216.75 142.41 223.7 257.1 226.09 293.27 226.29 382.31 281.34 382.31 281.74 293.27 284.32 257.1"})]})}function le({className:e}){return jsxRuntime.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",className:e||"h-5 w-5",children:[jsxRuntime.jsxs("linearGradient",{id:"sol-g",x1:"7.233",x2:"24.766",y1:"24.766",y2:"7.234",gradientUnits:"userSpaceOnUse",children:[jsxRuntime.jsx("stop",{offset:"0",stopColor:"#9945ff"}),jsxRuntime.jsx("stop",{offset:"0.2",stopColor:"#7962e7"}),jsxRuntime.jsx("stop",{offset:"1",stopColor:"#00d18c"})]}),jsxRuntime.jsx("path",{fill:"#10111a",d:"M0 0h32v32H0z"}),jsxRuntime.jsx("path",{fill:"url(#sol-g)",fillRule:"evenodd",d:"M9.873 20.41a.65.65 0 0 1 .476-.21l14.662.012a.323.323 0 0 1 .238.54l-3.123 3.438a.64.64 0 0 1-.475.21l-14.662-.012a.323.323 0 0 1-.238-.54zm15.376-2.862a.322.322 0 0 1-.238.54l-14.662.012a.64.64 0 0 1-.476-.21l-3.122-3.44a.323.323 0 0 1 .238-.54l14.662-.012a.64.64 0 0 1 .475.21zM9.873 7.81a.64.64 0 0 1 .476-.21l14.662.012a.322.322 0 0 1 .238.54l-3.123 3.438a.64.64 0 0 1-.475.21l-14.662-.012a.323.323 0 0 1-.238-.54z",clipRule:"evenodd"})]})}function de({className:e}){return jsxRuntime.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",className:e||"h-5 w-5",children:[jsxRuntime.jsx("rect",{width:"20",height:"20",rx:"4",fill:"#627EEA",fillOpacity:"0.2"}),jsxRuntime.jsx("path",{fill:"#627EEA",d:"M10 3l-4 6.5 4 2.5 4-2.5L10 3z"}),jsxRuntime.jsx("path",{fill:"#627EEA",fillOpacity:"0.6",d:"M6 9.5L10 12l4-2.5L10 17 6 9.5z"})]})}function st({config:e,onSuccess:n,title:r="Log in or Sign up",showWallets:l,showOTP:h,className:y=""}){let g=Ie(e),{isAuthenticated:i,wallet:p,loading:d,error:N,authenticateSolana:s,authenticateEVM:u,authenticateOTP:t,bridge:o,stackId:c}=g,w=!e.stackId&&!c,I=e.stacknetUrl||"https://stacknet.magma-rpc.com",{config:b,identityProviders:S,loading:U}=Le(c||e.stackId||null,I),[C,v]=react.useState(w?"stack-select":"select"),[P,z]=react.useState(null),[Z,V]=react.useState(false),[k,x]=react.useState("idle"),[R,D]=react.useState(""),[L,T]=react.useState([]),[_,B]=react.useState(e.stackId||null),[O,E]=react.useState(false),[ze,Ae]=react.useState(false);react.useEffect(()=>{if(typeof window>"u")return;let m=()=>{let W=window;E(!!(W.phantom?.solana?.isPhantom||W.solana?.isPhantom));let H=W.ethereum;Ae(!!(H?.isMetaMask||H?.providers?.some(Q=>Q.isMetaMask)));};m(),window.addEventListener("ethereum#initialized",m);let A=setTimeout(m,500);return ()=>{window.removeEventListener("ethereum#initialized",m),clearTimeout(A);}},[]),react.useEffect(()=>{C==="stack-select"&&c&&(B(c),v("select"));},[C,c]),react.useEffect(()=>{if(!(!o.ready||!w)&&o.identity){let m=[];o.resolvedStackId&&m.push({stackId:o.resolvedStackId,domain:typeof window<"u"?window.location.origin:""}),Promise.all(m.map(async A=>{try{let W=await fetch(`${I}/api/v2/stacks/${A.stackId}`);if(W.ok){let H=await W.json(),Q=H.data?.stack||H;A.name=Q.displayName||Q.name,A.logoUrl=Q.logoUrl;}}catch{}return A})).then(T);}},[o.ready,o.identity,o.resolvedStackId,w,I]),react.useEffect(()=>{i&&C==="success"&&n?.();},[i,C,n]);let ue=l||(S.length>0?S.filter(m=>m.type==="wallet").map(m=>m.id):["phantom","metamask"]),pe=h!==void 0?h:S.length>0?S.some(m=>m.type==="otp"):true,Pe=async()=>{z("phantom"),v("connecting");let m=await s("phantom");v(m?"success":"error");},De=async()=>{z("metamask"),v("connecting");let m=await u();v(m?"success":"error");},Te=async m=>{x("verifying"),D(""),await t(m)?(x("success"),v("success")):(x("error"),D("Invalid or expired code"),setTimeout(()=>x("idle"),2e3));},fe=()=>{v(w&&!_?"stack-select":"select"),z(null),V(false),x("idle"),D("");};return jsxRuntime.jsxs("div",{className:`w-full max-w-md space-y-3 ${y}`,children:[jsxRuntime.jsxs("div",{className:"mb-6 text-center",children:[b?.logoUrl&&C!=="stack-select"&&jsxRuntime.jsx("img",{src:b.logoUrl,alt:"",className:"h-10 w-10 mx-auto mb-3"}),jsxRuntime.jsx("h1",{className:"font-semibold text-2xl text-white",children:r}),b?.displayName&&C!=="stack-select"&&jsxRuntime.jsx("p",{className:"text-sm text-zinc-400 mt-1",children:b.displayName})]}),C==="stack-select"&&jsxRuntime.jsxs("div",{className:"space-y-3",children:[jsxRuntime.jsx("p",{className:"text-center text-sm text-zinc-400 mb-4",children:L.length>0?"Select a network to continue":"No previous connections found. Enter a Stack ID to continue."}),L.map(m=>jsxRuntime.jsxs("button",{onClick:()=>{B(m.stackId),v("select");},className:"flex w-full items-center gap-4 border border-zinc-800 bg-[#25252f] p-4 transition-colors hover:bg-[#2d2d3a]",children:[m.logoUrl?jsxRuntime.jsx("img",{src:m.logoUrl,alt:"",className:"h-10 w-10 flex-shrink-0"}):jsxRuntime.jsx("div",{className:"h-10 w-10 flex-shrink-0 bg-zinc-700 flex items-center justify-center text-zinc-400 text-sm font-mono",children:m.name?.[0]?.toUpperCase()||"S"}),jsxRuntime.jsxs("div",{className:"flex-1 text-left",children:[jsxRuntime.jsx("span",{className:"font-medium text-white",children:m.name||m.stackId}),jsxRuntime.jsx("p",{className:"text-xs text-zinc-500",children:m.domain})]}),jsxRuntime.jsx("span",{className:"text-xs text-zinc-600",children:"Previously connected"})]},m.stackId)),o.ready&&!o.known&&jsxRuntime.jsx("p",{className:"text-center text-xs text-zinc-600 mt-4",children:"Connect to a stack for the first time to get started."})]}),C==="select"&&U&&jsxRuntime.jsx("div",{className:"flex items-center justify-center py-8",children:jsxRuntime.jsx("div",{className:"h-6 w-6 border-2 border-zinc-600 border-t-white animate-spin",style:{borderRadius:"50%"}})}),N&&C==="error"&&jsxRuntime.jsxs("div",{className:"mb-4 border border-red-500/30 bg-red-500/10 p-4",children:[jsxRuntime.jsx("p",{className:"text-center text-red-400 text-sm",children:N}),jsxRuntime.jsx("button",{className:"mt-3 w-full text-sm text-zinc-400 hover:text-white",onClick:fe,children:"Try Again"})]}),C==="success"&&jsxRuntime.jsxs("div",{className:"border border-green-500/30 bg-green-500/10 p-6 text-center",children:[jsxRuntime.jsx("p",{className:"font-medium text-green-400 text-sm",children:"Connected!"}),jsxRuntime.jsx("p",{className:"mt-1 text-xs text-zinc-400",children:"Redirecting..."})]}),C==="connecting"&&d&&jsxRuntime.jsxs("div",{className:"border border-zinc-800 bg-[#25252f] p-6 text-center",children:[jsxRuntime.jsxs("div",{className:"mx-auto mb-3 h-14 w-14 animate-pulse",children:[P==="phantom"&&jsxRuntime.jsx(X,{className:"h-14 w-14"}),P==="metamask"&&jsxRuntime.jsx(ee,{className:"h-14 w-14"})]}),jsxRuntime.jsx("p",{className:"font-medium text-sm text-white",children:p.connected?"Signing message...":"Connecting wallet..."}),jsxRuntime.jsx("p",{className:"mt-1 text-xs text-zinc-500",children:"Please confirm in your wallet"}),jsxRuntime.jsx("button",{className:"mt-4 text-sm text-zinc-500 hover:text-white",onClick:fe,children:"Cancel"})]}),C==="select"&&!d&&!U&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[ue.includes("phantom")&&jsxRuntime.jsxs("button",{onClick:Pe,disabled:!O,className:`flex w-full items-center gap-4 border border-zinc-800 bg-[#25252f] p-4 transition-colors hover:bg-[#2d2d3a] ${O?"":"cursor-not-allowed opacity-50"}`,children:[jsxRuntime.jsx(X,{className:"h-14 w-14 flex-shrink-0"}),jsxRuntime.jsxs("div",{className:"flex-1 text-left",children:[jsxRuntime.jsx("span",{className:"font-medium text-lg text-white",children:"Phantom"}),!O&&jsxRuntime.jsx("p",{className:"text-xs text-zinc-500",children:"Not installed"})]}),jsxRuntime.jsx(le,{className:"h-8 w-8"})]}),ue.includes("metamask")&&ze&&jsxRuntime.jsxs("button",{onClick:De,className:"flex w-full items-center gap-4 border border-zinc-800 bg-[#25252f] p-4 transition-colors hover:bg-[#2d2d3a]",children:[jsxRuntime.jsx("div",{className:"flex h-14 w-14 flex-shrink-0 items-center justify-center bg-white p-2",children:jsxRuntime.jsx(ee,{className:"h-10 w-10"})}),jsxRuntime.jsx("div",{className:"flex-1 text-left",children:jsxRuntime.jsx("span",{className:"font-medium text-lg text-white",children:"MetaMask"})}),jsxRuntime.jsx(de,{className:"h-8 w-8"})]}),pe&&!Z&&jsxRuntime.jsxs("button",{onClick:()=>V(true),className:"flex w-full items-center gap-4 border border-zinc-800 bg-[#25252f] p-4 transition-colors hover:bg-[#2d2d3a]",children:[jsxRuntime.jsx("div",{className:"flex h-14 w-14 flex-shrink-0 items-center justify-center border border-zinc-700 bg-[#2a2a3e]",children:jsxRuntime.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",height:"28px",viewBox:"0 -960 960 960",width:"28px",fill:"#e3e3e3",children:jsxRuntime.jsx("path",{d:"M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Z"})})}),jsxRuntime.jsx("div",{className:"flex-1 text-left",children:jsxRuntime.jsx("span",{className:"font-medium text-lg text-white",children:"Access Code"})})]}),pe&&Z&&jsxRuntime.jsxs("div",{className:"border border-zinc-800 bg-[#25252f] p-6 space-y-4",children:[jsxRuntime.jsx("p",{className:"text-center text-sm text-zinc-400",children:"Enter your 6-digit access code"}),jsxRuntime.jsx(q,{onComplete:Te,disabled:k==="verifying",error:R}),k==="verifying"&&jsxRuntime.jsx("p",{className:"text-center text-sm text-zinc-400 animate-pulse",children:"Verifying..."}),k==="success"&&jsxRuntime.jsx("p",{className:"text-center text-sm text-green-400",children:"Verified!"}),b?.webPageUrl&&k==="idle"&&jsxRuntime.jsx("a",{href:`${b.webPageUrl}/connect/pair`,target:"_blank",rel:"noopener noreferrer",className:"block text-center text-sm text-zinc-500 hover:text-white transition-colors",children:"Get code"})]})]})]})}function rt({className:e}){return jsxRuntime.jsxs("svg",{className:e||"h-8 w-8",viewBox:"0 0 33 32",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{x:"0.5",width:"32",height:"32",rx:"4",fill:"black"}),jsxRuntime.jsx("path",{d:"M8.53901 8L14.7164 16.2153L8.5 22.8947H9.89907L15.3415 17.0468L19.7389 22.8947H24.5L17.975 14.2173L23.7612 8H22.3621L17.3499 13.3858L13.3001 8H8.53901ZM10.5964 9.02501H12.7837L22.4422 21.8695H20.255L10.5964 9.02501Z",fill:"#F7F7F7"})]})}function it({className:e}){return jsxRuntime.jsxs("svg",{className:e||"h-8 w-8",viewBox:"0 0 33 32",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{x:"0.5",width:"32",height:"32",rx:"4",fill:"#F1F2F9"}),jsxRuntime.jsx("path",{d:"M26.1001 16.2273C26.1001 15.5182 26.0365 14.8364 25.9183 14.1818H16.5001V18.05H21.8819C21.6501 19.3 20.9456 20.3591 19.8865 21.0682V23.5773H23.1183C25.0092 21.8364 26.1001 19.2727 26.1001 16.2273Z",fill:"#4285F4"}),jsxRuntime.jsx("path",{d:"M16.5001 26C19.2001 26 21.4637 25.1046 23.1182 23.5773L19.8864 21.0682C18.991 21.6682 17.8455 22.0227 16.5001 22.0227C13.8955 22.0227 11.691 20.2637 10.9046 17.9H7.56372V20.4909C9.20917 23.7591 12.591 26 16.5001 26Z",fill:"#34A853"}),jsxRuntime.jsx("path",{d:"M10.9047 17.8999C10.7047 17.2999 10.591 16.659 10.591 15.9999C10.591 15.3408 10.7047 14.6999 10.9047 14.0999V11.509H7.56376C6.86376 12.9025 6.49951 14.4405 6.50012 15.9999C6.50012 17.6136 6.88649 19.1408 7.56376 20.4908L10.9047 17.8999Z",fill:"#FBBC05"}),jsxRuntime.jsx("path",{d:"M16.5001 9.97726C17.9682 9.97726 19.2864 10.4818 20.3228 11.4727L23.191 8.60454C21.4591 6.99091 19.1955 6 16.5001 6C12.591 6 9.20917 8.2409 7.56372 11.5091L10.9046 14.1C11.691 11.7364 13.8955 9.97726 16.5001 9.97726Z",fill:"#EA4335"})]})}function ct({className:e}){return jsxRuntime.jsxs("svg",{className:e||"h-8 w-8",viewBox:"0 0 33 32",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{x:"0.5",width:"32",height:"32",rx:"4",fill:"#5462EB"}),jsxRuntime.jsx("path",{d:"M23.5433 8.87438C22.2479 8.26174 20.8587 7.81038 19.4063 7.55187C19.3799 7.54688 19.3534 7.55934 19.3398 7.58428C19.1612 7.91179 18.9633 8.33905 18.8247 8.67487C17.2625 8.43382 15.7084 8.43382 14.1782 8.67487C14.0396 8.33158 13.8345 7.91179 13.6551 7.58428C13.6414 7.56018 13.615 7.54771 13.5886 7.55187C12.1369 7.80955 10.7478 8.26092 9.45159 8.87438C9.44037 8.87937 9.43075 8.88769 9.42437 8.89849C6.78947 12.9558 6.06766 16.9134 6.42176 20.8219C6.42336 20.841 6.43378 20.8593 6.4482 20.871C8.18663 22.1868 9.87059 22.9857 11.5233 23.5152C11.5497 23.5235 11.5778 23.5135 11.5946 23.491C11.9855 22.9408 12.334 22.3606 12.6328 21.7504C12.6505 21.7147 12.6336 21.6723 12.5976 21.6581C12.0448 21.442 11.5185 21.1785 11.0122 20.8793C10.9721 20.8552 10.9689 20.7961 11.0058 20.7679C11.1123 20.6856 11.2189 20.6 11.3206 20.5135C11.339 20.4977 11.3647 20.4944 11.3863 20.5044C14.7125 22.0696 18.3136 22.0696 21.6006 20.5044C21.6222 20.4936 21.6479 20.4969 21.6671 20.5127C21.7688 20.5991 21.8754 20.6856 21.9827 20.7679C22.0196 20.7961 22.0172 20.8552 21.9771 20.8793C21.4708 21.1843 20.9445 21.442 20.3909 21.6573C20.3548 21.6715 20.3388 21.7147 20.3564 21.7504C20.6617 22.3597 21.0101 22.9399 21.3939 23.4902C21.4099 23.5135 21.4387 23.5235 21.4652 23.5152C23.1259 22.9857 24.8099 22.1868 26.5483 20.871C26.5635 20.8593 26.5731 20.8419 26.5747 20.8228C26.9985 16.3041 25.8649 12.3789 23.5697 8.89931C23.5641 8.88769 23.5545 8.87937 23.5433 8.87438Z",fill:"#F7F7F7"})]})}function ut({className:e}){return jsxRuntime.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 512 512",className:e||"h-8 w-8",children:[jsxRuntime.jsx("rect",{width:"512",height:"512",rx:"15%",fill:"#37aee2"}),jsxRuntime.jsx("path",{fill:"#c8daea",d:"M199 404c-11 0-10-4-13-14l-32-105 245-144"}),jsxRuntime.jsx("path",{fill:"#a9c9dd",d:"M199 404c7 0 11-4 16-8l45-43-56-34"}),jsxRuntime.jsx("path",{fill:"#f6fbfe",d:"M204 319l135 99c14 9 26 4 30-14l55-258c5-22-9-32-24-25L79 245c-21 8-21 21-4 26l83 26 190-121c9-5 17-3 11 4"})]})}
2
- exports.ConnectWidget=st;exports.DiscordIcon=ct;exports.EthereumIcon=de;exports.GoogleIcon=it;exports.MetaMaskIcon=ee;exports.OTPInput=q;exports.PhantomIcon=X;exports.SolanaIcon=le;exports.TelegramIcon=ut;exports.TwitterIcon=rt;exports.UserUtilsProvider=Re;exports.useUserUtilsContext=We;
1
+ 'use strict';var react=require('react'),jsxRuntime=require('react/jsx-runtime');var we=react.createContext(null);function Qe(){let e=react.useContext(we);if(!e)throw new Error("useUserUtilsContext must be used within <UserUtilsProvider>");return e}function Ye({config:e,callbacks:n,children:a}){return jsxRuntime.jsx(we.Provider,{value:{config:e,callbacks:n},children:a})}function xe(){let[e,n]=react.useState({connected:false,address:null,chain:null,provider:null}),[a,l]=react.useState(null),w=react.useCallback(async(p="phantom")=>{l(null);try{let c=typeof window<"u"?window:null,v=p==="phantom"?c?.phantom?.solana||c?.solana:c?.solflare;if(!v)return l(`${p} wallet not found`),null;let d=(await v.connect()).publicKey.toString();return n({connected:!0,address:d,chain:"solana",provider:p}),d}catch(c){return l(c.message||"Failed to connect wallet"),null}},[]),m=react.useCallback(async()=>{l(null);try{let c=(typeof window<"u"?window:null)?.ethereum;if(!c)return l("MetaMask not found"),null;let v=c;c.providers?.length&&(v=c.providers.find(t=>t.isMetaMask)||c);let d=(await v.request({method:"eth_requestAccounts"}))[0];return d?(n({connected:!0,address:d,chain:"ethereum",provider:"metamask"}),d):(l("No account selected"),null)}catch(p){return l(p.message||"Failed to connect wallet"),null}},[]),g=react.useCallback(async(p,c)=>{l(null);let v=c?.chain||e.chain,s=c?.provider||e.provider,d=c?.address||e.address;try{if(v==="solana"){let t=typeof window<"u"?window:null,r=s==="solflare"?t?.solflare:t?.phantom?.solana||t?.solana;if(!r)throw new Error("Wallet not available");let o=new TextEncoder().encode(p),f=await r.signMessage(o,"utf8"),y=new Uint8Array(f.signature||f),h="";for(let S=0;S<y.byteLength;S++)h+=String.fromCharCode(y[S]);return btoa(h)}if(v==="ethereum"){let r=(typeof window<"u"?window:null)?.ethereum;if(r?.providers?.length&&(r=r.providers.find(f=>f.isMetaMask)||r),!r)throw new Error("MetaMask not available");return await r.request({method:"personal_sign",params:[p,d]})}throw new Error("No wallet connected")}catch(t){return l(t.message||"Signing failed"),null}},[e]),i=react.useCallback(()=>{n({connected:false,address:null,chain:null,provider:null}),l(null);},[]);return {wallet:e,error:a,connectSolana:w,connectEVM:m,signMessage:g,disconnect:i}}function ve(){if(typeof document>"u")return null;try{let e=document.cookie.split(";").map(a=>a.trim()).find(a=>a.startsWith("stackauth_session="));if(!e)return null;let n=e.slice(18);return JSON.parse(atob(n.replace(/-/g,"+").replace(/_/g,"/")))}catch{return null}}function Ne(e="__csrf"){if(typeof document>"u")return null;let n=document.cookie.split(";").map(a=>a.trim()).find(a=>a.startsWith(`${e}=`));return n?n.slice(e.length+1):null}function Se(){let[e,n]=react.useState(null),[a,l]=react.useState(true),w=react.useCallback(()=>{let i=ve();i&&i.expiresAt>Date.now()?n({userId:i.userId,address:i.address,chain:i.chain,expiresAt:i.expiresAt,planId:i.planId,authMethod:i.authMethod}):n(null),l(false);},[]);react.useEffect(()=>{w();},[w]);let m=react.useCallback(async(i="")=>{try{let p=await fetch(`${i}/api/auth/session`);if(p.ok){let c=await p.json();if(c.session)return n(c.session),c.session}return n(null),null}catch{return null}},[]),g=!!e&&e.expiresAt>Date.now();return {session:e,loading:a,isAuthenticated:g,refresh:m,readSession:w}}function Ie(e="__csrf",n="x-csrf-token"){let[a,l]=react.useState(null);react.useEffect(()=>{l(Ne(e));},[e]);let w=a?{[n]:a}:{};return {token:a,headers:w}}var qe="https://stacknet.magma-rpc.com/auth/bridge",X="stacknet-auth-bridge";function Le(e){let n=e?.bridgeUrl||qe,a=e?.disabled||false,l=react.useRef(null),[w,m]=react.useState({ready:false,known:false,identity:null,identityCount:0,resolvedStackId:null}),g=react.useRef([]),i=react.useRef(false),p=react.useCallback(t=>{let r={...t,protocol:X};i.current&&l.current?.contentWindow?l.current.contentWindow.postMessage(r,new URL(n).origin):g.current.push(r);},[n]);react.useEffect(()=>{if(a)return;let t=o=>{if(!(!o.data||o.data.protocol!==X)){try{if(o.origin!==new URL(n).origin)return}catch{return}switch(o.data.type){case "bridge:ready":i.current=true,m(f=>({...f,ready:true}));for(let f of g.current)l.current?.contentWindow?.postMessage(f,o.origin);g.current=[],l.current?.contentWindow?.postMessage({protocol:X,type:"auth:check"},o.origin),l.current?.contentWindow?.postMessage({protocol:X,type:"auth:resolve-stack"},o.origin);break;case "auth:status":m(f=>({...f,known:o.data.known,identity:o.data.identity,identityCount:o.data.identityCount||0}));break;case "auth:resolved-stack":m(f=>({...f,resolvedStackId:o.data.stackId||null}));break;}}};window.addEventListener("message",t);let r=document.createElement("iframe");return r.src=n,r.style.display="none",r.setAttribute("aria-hidden","true"),r.setAttribute("tabindex","-1"),r.setAttribute("sandbox","allow-scripts allow-same-origin"),document.body.appendChild(r),l.current=r,()=>{window.removeEventListener("message",t),r.parentNode&&r.parentNode.removeChild(r),l.current=null,i.current=false;}},[n,a]);let c=react.useCallback(t=>{p({type:"auth:connected",...t});},[p]),v=react.useCallback(t=>{p({type:"auth:disconnected",...t});},[p]),s=react.useCallback(()=>{p({type:"auth:clear"}),m({ready:w.ready,known:false,identity:null,identityCount:0,resolvedStackId:null});},[p,w.ready]),d=react.useCallback(()=>{p({type:"auth:check"});},[p]);return {...w,reportConnected:c,reportDisconnected:v,clearAll:s,refresh:d}}async function Ue(e,n,a,l){let w=e.apiVersion||"v2",m=`${e.baseUrl}/api/${w}${a}`;try{let g=await fetch(m,{method:n,headers:{"Content-Type":"application/json"},body:l?JSON.stringify(l):void 0}),i=await g.json();return g.ok?i.success&&i.data!==void 0?{success:!0,data:i.data}:{success:!0,data:i}:{success:!1,error:i.error||{code:"UNKNOWN_ERROR",message:"Unknown error"}}}catch(g){return {success:false,error:{code:"NETWORK_ERROR",message:g instanceof Error?g.message:"Network error"}}}}function Pe(e){return {getNetworkStatus:()=>Ue(e,"GET","/network/status"),getWeb3Challenge:(n,a)=>Ue(e,"POST",`/stacks/${e.stackId}/auth/web3/challenge`,{chain:n,address:a})}}function Ae(e={apiBaseUrl:""}){let{wallet:n,connectSolana:a,connectEVM:l,signMessage:w,disconnect:m}=xe(),{session:g,isAuthenticated:i,refresh:p,readSession:c}=Se(),{headers:v}=Ie(),s=Le({disabled:typeof window>"u"}),[d,t]=react.useState(false),[r,o]=react.useState(null),[f,y]=react.useState(false),h=e.apiBaseUrl||"",S=e.stacknetUrl||"https://stacknet.magma-rpc.com",N=e.stackId||s.resolvedStackId||"",M=Pe({baseUrl:S,stackId:N}),L=react.useCallback(async(x,C,$,W)=>{t(true),o(null);try{let A=C;if(!A){let F=await $();if(!F)return t(!1),!1;A=F;}let R=await M.getWeb3Challenge(x,A);if(!R.success||!R.data)return o("Failed to get challenge"),t(!1),!1;let K=await w(R.data.message,{chain:x,provider:W,address:A});if(!K)return t(!1),!1;let Q={chain:x,message:R.data.message,signature:K,stackId:N};x==="solana"&&(Q.publicKey=A);let B=await fetch(`${h}/api/auth/callback`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(Q)});if(!B.ok){let F=await B.json().catch(()=>({}));return o(F.error||"Authentication failed"),t(!1),!1}return s.reportConnected({address:A,chain:x,method:W||(x==="solana"?"phantom":"metamask"),stackId:N}),c(),t(!1),!0}catch(A){return o(A.message||"Authentication failed"),t(false),false}},[h,M,w,c,s,N]),D=react.useCallback(async(x="phantom")=>{let C=await a(x);return C?L("solana",C,()=>a(x),x):false},[a,L]),j=react.useCallback(async()=>{let x=await l();return x?L("ethereum",x,l,"metamask"):false},[l,L]),P=react.useCallback(async x=>{t(true),o(null);try{let C=await fetch(`${h}/api/auth/otp`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:x})});if(!C.ok){let $=await C.json().catch(()=>({}));return o($.error||"Invalid code"),t(!1),!1}return c(),t(!1),!0}catch(C){return o(C.message||"OTP verification failed"),t(false),false}},[h,c]),O=react.useCallback(async()=>{n.address&&n.chain&&s.reportDisconnected({address:n.address,chain:n.chain,stackId:N});try{await fetch(`${h}/api/auth/logout`,{method:"POST",headers:v});}catch{}m(),c();},[h,v,m,c,n,s,N]);return react.useEffect(()=>{if(!e.autoConnect||f||i||!s.ready||!s.known||!s.identity)return;y(true);let{chain:x,method:C}=s.identity;x==="solana"&&(C==="phantom"||C==="solflare")?D(C):x==="ethereum"&&j();},[e.autoConnect,f,i,s,D,j]),{session:g,isAuthenticated:i,wallet:n,loading:d,error:r,authenticateSolana:D,authenticateEVM:j,authenticateOTP:P,logout:O,refresh:()=>p(h),stackId:N,bridge:{ready:s.ready,known:s.known,identity:s.identity,identityCount:s.identityCount,resolvedStackId:s.resolvedStackId}}}function je(e,n="https://stacknet.magma-rpc.com"){let[a,l]=react.useState(null),[w,m]=react.useState(false),[g,i]=react.useState(null),p=react.useCallback(async v=>{m(true),i(null);try{let s=await fetch(`${n}/api/v2/stacks/${v}`);if(!s.ok)return i("Stack not found"),m(!1),null;let d=await s.json(),t=d.data?.stack||d.stack||d,r={id:t.id,name:t.name,displayName:t.displayName||t.name,description:t.description,logoUrl:t.logoUrl,webPageUrl:t.webPageUrl,allowedChains:t.allowedChains||[],features:t.features,stripeProvider:t.stripeProvider,oauthProviders:t.oauthProviders?.map(o=>({provider:o.provider,enabled:o.enabled!==!1}))};return l(r),m(!1),r}catch(s){return i(s.message),m(false),null}},[n]);react.useEffect(()=>{e&&p(e);},[e,p]);let c=a?nt(a):[];return {config:a,loading:w,error:g,identityProviders:c,fetchConfig:p}}function nt(e){let n=[];if(e.features?.web3Auth!==false&&(e.allowedChains.includes("solana")&&(n.push({type:"wallet",id:"phantom",name:"Phantom",chain:"solana"}),n.push({type:"wallet",id:"solflare",name:"Solflare",chain:"solana"})),(e.allowedChains.includes("ethereum")||e.allowedChains.includes("polygon")||e.allowedChains.includes("base"))&&n.push({type:"wallet",id:"metamask",name:"MetaMask",chain:"ethereum"})),e.features?.apiKeyAuth!==false&&n.push({type:"otp",id:"otp",name:"Access Code"}),e.features?.oauthAuth&&e.oauthProviders)for(let a of e.oauthProviders)a.enabled&&n.push({type:"oauth",id:a.provider,name:a.provider});return n}function ee({length:e=6,onComplete:n,disabled:a=false,error:l,className:w="",inputClassName:m=""}){let [g,i]=react.useState(Array(e).fill("")),p=react.useCallback((s,d)=>{if(d.length>1){let r=d.replace(/\D/g,"").slice(0,e).split(""),o=[...g];r.forEach((y,h)=>{s+h<e&&(o[s+h]=y);}),i(o);let f=Math.min(s+r.length,e-1);document.getElementById(`userutils-otp-${f}`)?.focus(),o.every(y=>y!=="")&&setTimeout(()=>n(o.join("")),100);return}if(!/^\d?$/.test(d))return;let t=[...g];t[s]=d,i(t),d&&s<e-1&&document.getElementById(`userutils-otp-${s+1}`)?.focus(),d&&s===e-1&&t.every(r=>r!=="")&&setTimeout(()=>n(t.join("")),100);},[g,e,n]),c=react.useCallback((s,d)=>{if(d.key==="Backspace"&&!g[s]&&s>0){document.getElementById(`userutils-otp-${s-1}`)?.focus();let t=[...g];t[s-1]="",i(t);}if(d.key==="Enter"){let t=g.join("");t.length===e&&n(t);}},[g,e,n]);react.useCallback(()=>{i(Array(e).fill("")),document.getElementById("userutils-otp-0")?.focus();},[e]);return jsxRuntime.jsxs("div",{className:w,children:[jsxRuntime.jsx("div",{className:"flex gap-2 justify-center",children:g.map((s,d)=>jsxRuntime.jsx("input",{id:`userutils-otp-${d}`,type:"text",inputMode:"numeric",maxLength:e,value:s,onChange:t=>p(d,t.target.value),onKeyDown:t=>c(d,t),disabled:a,autoFocus:d===0,className:`w-12 h-14 text-center text-xl font-mono bg-secondary border border-primary/10 text-foreground focus:outline-none focus:border-primary/30 disabled:opacity-50 ${m}`},d))}),l&&jsxRuntime.jsx("p",{className:"text-center text-sm text-red-400 mt-2",children:l})]})}ee.displayName="OTPInput";var rt="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTA4IiBoZWlnaHQ9IjEwOCIgdmlld0JveD0iMCAwIDEwOCAxMDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxMDgiIGhlaWdodD0iMTA4IiByeD0iMjYiIGZpbGw9IiNBQjlGRjIiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00Ni41MjY3IDY5LjkyMjlDNDIuMDA1NCA3Ni44NTA5IDM0LjQyOTIgODUuNjE4MiAyNC4zNDggODUuNjE4MkMxOS41ODI0IDg1LjYxODIgMTUgODMuNjU2MyAxNSA3NS4xMzQyQzE1IDUzLjQzMDUgNDQuNjMyNiAxOS44MzI3IDcyLjEyNjggMTkuODMyN0M4Ny43NjggMTkuODMyNyA5NCAzMC42ODQ2IDk0IDQzLjAwNzlDOTQgNTguODI1OCA4My43MzU1IDc2LjkxMjIgNzMuNTMyMSA3Ni45MTIyQzcwLjI5MzkgNzYuOTEyMiA2OC43MDUzIDc1LjEzNDIgNjguNzA1MyA3Mi4zMTRDNjguNzA1MyA3MS41NzgzIDY4LjgyNzUgNzAuNzgxMiA2OS4wNzE5IDY5LjkyMjlDNjUuNTg5MyA3NS44Njk5IDU4Ljg2ODUgODEuMzg3OCA1Mi41NzU0IDgxLjM4NzhDNDcuOTkzIDgxLjM4NzggNDUuNjcxMyA3OC41MDYzIDQ1LjY3MTMgNzQuNDU5OEM0NS42NzEzIDcyLjk4ODQgNDUuOTc2OCA3MS40NTU2IDQ2LjUyNjcgNjkuOTIyOVpNODMuNjc2MSA0Mi41Nzk0QzgzLjY3NjEgNDYuMTcwNCA4MS41NTc1IDQ3Ljk2NTggNzkuMTg3NSA0Ny45NjU4Qzc2Ljc4MTYgNDcuOTY1OCA3NC42OTg5IDQ2LjE3MDQgNzQuNjk4OSA0Mi41Nzk0Qzc0LjY5ODkgMzguOTg4NSA3Ni43ODE2IDM3LjE5MzEgNzkuMTg3NSAzNy4xOTMxQzgxLjU1NzUgMzcuMTkzMSA4My42NzYxIDM4Ljk4ODUgODMuNjc2MSA0Mi41Nzk0Wk03MC4yMTAzIDQyLjU3OTVDNzAuMjEwMyA0Ni4xNzA0IDY4LjA5MTYgNDcuOTY1OCA2NS43MjE2IDQ3Ljk2NThDNjMuMzE1NyA0Ny45NjU4IDYxLjIzMyA0Ni4xNzA0IDYxLjIzMyA0Mi41Nzk1QzYxLjIzMyAzOC45ODg1IDYzLjMxNTcgMzcuMTkzMSA2NS43MjE2IDM3LjE5MzFDNjguMDkxNiAzNy4xOTMxIDcwLjIxMDMgMzguOTg4NSA3MC4yMTAzIDQyLjU3OTVaIiBmaWxsPSIjRkZGREY4Ii8+Cjwvc3ZnPgo=";function te({className:e}){return jsxRuntime.jsx("img",{src:rt,alt:"Phantom",className:e})}function ne({className:e}){return jsxRuntime.jsxs("svg",{className:e,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 507.83 470.86",children:[jsxRuntime.jsx("polygon",{fill:"#e2761b",stroke:"#e2761b",strokeLinecap:"round",strokeLinejoin:"round",points:"482.09 0.5 284.32 147.38 320.9 60.72 482.09 0.5"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"25.54 0.5 221.72 148.77 186.93 60.72 25.54 0.5"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"410.93 340.97 358.26 421.67 470.96 452.67 503.36 342.76 410.93 340.97"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"4.67 342.76 36.87 452.67 149.57 421.67 96.9 340.97 4.67 342.76"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"143.21 204.62 111.8 252.13 223.7 257.1 219.73 136.85 143.21 204.62"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"364.42 204.62 286.91 135.46 284.32 257.1 396.03 252.13 364.42 204.62"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"149.57 421.67 216.75 388.87 158.71 343.55 149.57 421.67"}),jsxRuntime.jsx("polygon",{fill:"#e4761b",stroke:"#e4761b",strokeLinecap:"round",strokeLinejoin:"round",points:"290.88 388.87 358.26 421.67 348.92 343.55 290.88 388.87"}),jsxRuntime.jsx("polygon",{fill:"#d7c1b3",stroke:"#d7c1b3",strokeLinecap:"round",strokeLinejoin:"round",points:"358.26 421.67 290.88 388.87 296.25 432.8 295.65 451.28 358.26 421.67"}),jsxRuntime.jsx("polygon",{fill:"#d7c1b3",stroke:"#d7c1b3",strokeLinecap:"round",strokeLinejoin:"round",points:"149.57 421.67 212.18 451.28 211.78 432.8 216.75 388.87 149.57 421.67"}),jsxRuntime.jsx("polygon",{fill:"#233447",stroke:"#233447",strokeLinecap:"round",strokeLinejoin:"round",points:"213.17 314.54 157.12 298.04 196.67 279.95 213.17 314.54"}),jsxRuntime.jsx("polygon",{fill:"#233447",stroke:"#233447",strokeLinecap:"round",strokeLinejoin:"round",points:"294.46 314.54 310.96 279.95 350.71 298.04 294.46 314.54"}),jsxRuntime.jsx("polygon",{fill:"#cd6116",stroke:"#cd6116",strokeLinecap:"round",strokeLinejoin:"round",points:"149.57 421.67 159.11 340.97 96.9 342.76 149.57 421.67"}),jsxRuntime.jsx("polygon",{fill:"#cd6116",stroke:"#cd6116",strokeLinecap:"round",strokeLinejoin:"round",points:"348.72 340.97 358.26 421.67 410.93 342.76 348.72 340.97"}),jsxRuntime.jsx("polygon",{fill:"#cd6116",stroke:"#cd6116",strokeLinecap:"round",strokeLinejoin:"round",points:"396.03 252.13 284.32 257.1 294.66 314.54 311.16 279.95 350.91 298.04 396.03 252.13"}),jsxRuntime.jsx("polygon",{fill:"#cd6116",stroke:"#cd6116",strokeLinecap:"round",strokeLinejoin:"round",points:"157.12 298.04 196.87 279.95 213.17 314.54 223.7 257.1 111.8 252.13 157.12 298.04"}),jsxRuntime.jsx("polygon",{fill:"#e4751f",stroke:"#e4751f",strokeLinecap:"round",strokeLinejoin:"round",points:"111.8 252.13 158.71 343.55 157.12 298.04 111.8 252.13"}),jsxRuntime.jsx("polygon",{fill:"#e4751f",stroke:"#e4751f",strokeLinecap:"round",strokeLinejoin:"round",points:"350.91 298.04 348.92 343.55 396.03 252.13 350.91 298.04"}),jsxRuntime.jsx("polygon",{fill:"#e4751f",stroke:"#e4751f",strokeLinecap:"round",strokeLinejoin:"round",points:"223.7 257.1 213.17 314.54 226.29 382.31 229.27 293.07 223.7 257.1"}),jsxRuntime.jsx("polygon",{fill:"#e4751f",stroke:"#e4751f",strokeLinecap:"round",strokeLinejoin:"round",points:"284.32 257.1 278.96 292.87 281.34 382.31 294.66 314.54 284.32 257.1"}),jsxRuntime.jsx("polygon",{fill:"#f6851b",stroke:"#f6851b",strokeLinecap:"round",strokeLinejoin:"round",points:"294.66 314.54 281.34 382.31 290.88 388.87 348.92 343.55 350.91 298.04 294.66 314.54"}),jsxRuntime.jsx("polygon",{fill:"#f6851b",stroke:"#f6851b",strokeLinecap:"round",strokeLinejoin:"round",points:"157.12 298.04 158.71 343.55 216.75 388.87 226.29 382.31 213.17 314.54 157.12 298.04"}),jsxRuntime.jsx("polygon",{fill:"#c0ad9e",stroke:"#c0ad9e",strokeLinecap:"round",strokeLinejoin:"round",points:"295.65 451.28 296.25 432.8 291.28 428.42 216.35 428.42 211.78 432.8 212.18 451.28 149.57 421.67 171.43 439.55 215.75 470.36 291.88 470.36 336.4 439.55 358.26 421.67 295.65 451.28"}),jsxRuntime.jsx("polygon",{fill:"#161616",stroke:"#161616",strokeLinecap:"round",strokeLinejoin:"round",points:"290.88 388.87 281.34 382.31 226.29 382.31 216.75 388.87 211.78 432.8 216.35 428.42 291.28 428.42 296.25 432.8 290.88 388.87"}),jsxRuntime.jsx("polygon",{fill:"#763d16",stroke:"#763d16",strokeLinecap:"round",strokeLinejoin:"round",points:"490.44 156.92 507.33 75.83 482.09 0.5 290.88 142.41 364.42 204.62 468.37 235.03 491.43 208.2 481.49 201.05 497.39 186.54 485.07 177 500.97 164.87 490.44 156.92"}),jsxRuntime.jsx("polygon",{fill:"#763d16",stroke:"#763d16",strokeLinecap:"round",strokeLinejoin:"round",points:"0.5 75.83 17.39 156.92 6.66 164.87 22.56 177 10.44 186.54 26.34 201.05 16.4 208.2 39.26 235.03 143.21 204.62 216.75 142.41 25.54 0.5 0.5 75.83"}),jsxRuntime.jsx("polygon",{fill:"#f6851b",stroke:"#f6851b",strokeLinecap:"round",strokeLinejoin:"round",points:"468.37 235.03 364.42 204.62 396.03 252.13 348.92 343.55 410.93 342.76 503.36 342.76 468.37 235.03"}),jsxRuntime.jsx("polygon",{fill:"#f6851b",stroke:"#f6851b",strokeLinecap:"round",strokeLinejoin:"round",points:"143.21 204.62 39.26 235.03 4.67 342.76 96.9 342.76 158.71 343.55 111.8 252.13 143.21 204.62"}),jsxRuntime.jsx("polygon",{fill:"#f6851b",stroke:"#f6851b",strokeLinecap:"round",strokeLinejoin:"round",points:"284.32 257.1 290.88 142.41 321.1 60.72 186.93 60.72 216.75 142.41 223.7 257.1 226.09 293.27 226.29 382.31 281.34 382.31 281.74 293.27 284.32 257.1"})]})}function pe({className:e}){return jsxRuntime.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",className:e||"h-5 w-5",children:[jsxRuntime.jsxs("linearGradient",{id:"sol-g",x1:"7.233",x2:"24.766",y1:"24.766",y2:"7.234",gradientUnits:"userSpaceOnUse",children:[jsxRuntime.jsx("stop",{offset:"0",stopColor:"#9945ff"}),jsxRuntime.jsx("stop",{offset:"0.2",stopColor:"#7962e7"}),jsxRuntime.jsx("stop",{offset:"1",stopColor:"#00d18c"})]}),jsxRuntime.jsx("path",{fill:"#10111a",d:"M0 0h32v32H0z"}),jsxRuntime.jsx("path",{fill:"url(#sol-g)",fillRule:"evenodd",d:"M9.873 20.41a.65.65 0 0 1 .476-.21l14.662.012a.323.323 0 0 1 .238.54l-3.123 3.438a.64.64 0 0 1-.475.21l-14.662-.012a.323.323 0 0 1-.238-.54zm15.376-2.862a.322.322 0 0 1-.238.54l-14.662.012a.64.64 0 0 1-.476-.21l-3.122-3.44a.323.323 0 0 1 .238-.54l14.662-.012a.64.64 0 0 1 .475.21zM9.873 7.81a.64.64 0 0 1 .476-.21l14.662.012a.322.322 0 0 1 .238.54l-3.123 3.438a.64.64 0 0 1-.475.21l-14.662-.012a.323.323 0 0 1-.238-.54z",clipRule:"evenodd"})]})}function ge({className:e}){return jsxRuntime.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",className:e||"h-5 w-5",children:[jsxRuntime.jsx("rect",{width:"20",height:"20",rx:"4",fill:"#627EEA",fillOpacity:"0.2"}),jsxRuntime.jsx("path",{fill:"#627EEA",d:"M10 3l-4 6.5 4 2.5 4-2.5L10 3z"}),jsxRuntime.jsx("path",{fill:"#627EEA",fillOpacity:"0.6",d:"M6 9.5L10 12l4-2.5L10 17 6 9.5z"})]})}function ct({config:e,onSuccess:n,title:a="Log in or Sign up",showWallets:l,showOTP:w,className:m=""}){let g=Ae(e),{isAuthenticated:i,wallet:p,loading:c,error:v,authenticateSolana:s,authenticateEVM:d,authenticateOTP:t,bridge:r,stackId:o}=g,f=!e.stackId&&!o,y=e.stacknetUrl||"https://stacknet.magma-rpc.com",{config:h,identityProviders:S,loading:N}=je(o||e.stackId||null,y),[M,L]=react.useState(f?"stack-select":"select"),[D,j]=react.useState(null),[P,O]=react.useState(false),[x,C]=react.useState("idle"),[$,W]=react.useState(""),[A,R]=react.useState([]),[K,Q]=react.useState(e.stackId||null),[B,F]=react.useState(false),[Ee,We]=react.useState(false);react.useEffect(()=>{if(typeof window>"u")return;let b=()=>{let H=window;F(!!(H.phantom?.solana?.isPhantom||H.solana?.isPhantom));let Y=H.ethereum;We(!!(Y?.isMetaMask||Y?.providers?.some(G=>G.isMetaMask)));};b(),window.addEventListener("ethereum#initialized",b);let E=setTimeout(b,500);return ()=>{window.removeEventListener("ethereum#initialized",b),clearTimeout(E);}},[]),react.useEffect(()=>{M==="stack-select"&&o&&(Q(o),L("select"));},[M,o]),react.useEffect(()=>{if(!(!r.ready||!f)&&r.identity){let b=[];r.resolvedStackId&&b.push({stackId:r.resolvedStackId,domain:typeof window<"u"?window.location.origin:""}),Promise.all(b.map(async E=>{try{let H=await fetch(`${y}/api/v2/stacks/${E.stackId}`);if(H.ok){let Y=await H.json(),G=Y.data?.stack||Y;E.name=G.displayName||G.name,E.logoUrl=G.logoUrl;}}catch{}return E})).then(R);}},[r.ready,r.identity,r.resolvedStackId,f,y]),react.useEffect(()=>{i&&M==="success"&&n?.();},[i,M,n]);let he=l||(S.length>0?S.filter(b=>b.type==="wallet").map(b=>b.id):["phantom","metamask"]),ye=w!==void 0?w:S.length>0?S.some(b=>b.type==="otp"):true,Re=async()=>{j("phantom"),L("connecting");let b=await s("phantom");L(b?"success":"error");},Be=async()=>{j("metamask"),L("connecting");let b=await d();L(b?"success":"error");},Fe=async b=>{C("verifying"),W(""),await t(b)?(C("success"),L("success")):(C("error"),W("Invalid or expired code"),setTimeout(()=>C("idle"),2e3));},ke=()=>{L(f&&!K?"stack-select":"select"),j(null),O(false),C("idle"),W("");};return jsxRuntime.jsxs("div",{className:`w-full max-w-md space-y-3 ${m}`,children:[jsxRuntime.jsxs("div",{className:"mb-6 text-center",children:[h?.logoUrl&&M!=="stack-select"&&jsxRuntime.jsx("img",{src:h.logoUrl,alt:"",className:"h-10 w-10 mx-auto mb-3"}),jsxRuntime.jsx("h1",{className:"font-semibold text-2xl text-white",children:a}),h?.displayName&&M!=="stack-select"&&jsxRuntime.jsx("p",{className:"text-sm text-zinc-400 mt-1",children:h.displayName})]}),M==="stack-select"&&jsxRuntime.jsxs("div",{className:"space-y-3",children:[jsxRuntime.jsx("p",{className:"text-center text-sm text-zinc-400 mb-4",children:A.length>0?"Select a network to continue":"No previous connections found. Enter a Stack ID to continue."}),A.map(b=>jsxRuntime.jsxs("button",{onClick:()=>{Q(b.stackId),L("select");},className:"flex w-full items-center gap-4 border border-zinc-800 bg-[#25252f] p-4 transition-colors hover:bg-[#2d2d3a]",children:[b.logoUrl?jsxRuntime.jsx("img",{src:b.logoUrl,alt:"",className:"h-10 w-10 flex-shrink-0"}):jsxRuntime.jsx("div",{className:"h-10 w-10 flex-shrink-0 bg-zinc-700 flex items-center justify-center text-zinc-400 text-sm font-mono",children:b.name?.[0]?.toUpperCase()||"S"}),jsxRuntime.jsxs("div",{className:"flex-1 text-left",children:[jsxRuntime.jsx("span",{className:"font-medium text-white",children:b.name||b.stackId}),jsxRuntime.jsx("p",{className:"text-xs text-zinc-500",children:b.domain})]}),jsxRuntime.jsx("span",{className:"text-xs text-zinc-600",children:"Previously connected"})]},b.stackId)),r.ready&&!r.known&&jsxRuntime.jsx("p",{className:"text-center text-xs text-zinc-600 mt-4",children:"Connect to a stack for the first time to get started."})]}),M==="select"&&N&&jsxRuntime.jsx("div",{className:"flex items-center justify-center py-8",children:jsxRuntime.jsx("div",{className:"h-6 w-6 border-2 border-zinc-600 border-t-white animate-spin",style:{borderRadius:"50%"}})}),v&&M==="error"&&jsxRuntime.jsxs("div",{className:"mb-4 border border-red-500/30 bg-red-500/10 p-4",children:[jsxRuntime.jsx("p",{className:"text-center text-red-400 text-sm",children:v}),jsxRuntime.jsx("button",{className:"mt-3 w-full text-sm text-zinc-400 hover:text-white",onClick:ke,children:"Try Again"})]}),M==="success"&&jsxRuntime.jsxs("div",{className:"border border-green-500/30 bg-green-500/10 p-6 text-center",children:[jsxRuntime.jsx("p",{className:"font-medium text-green-400 text-sm",children:"Connected!"}),jsxRuntime.jsx("p",{className:"mt-1 text-xs text-zinc-400",children:"Redirecting..."})]}),M==="connecting"&&c&&jsxRuntime.jsxs("div",{className:"border border-zinc-800 bg-[#25252f] p-6 text-center",children:[jsxRuntime.jsxs("div",{className:"mx-auto mb-3 h-14 w-14 animate-pulse",children:[D==="phantom"&&jsxRuntime.jsx(te,{className:"h-14 w-14"}),D==="metamask"&&jsxRuntime.jsx(ne,{className:"h-14 w-14"})]}),jsxRuntime.jsx("p",{className:"font-medium text-sm text-white",children:p.connected?"Signing message...":"Connecting wallet..."}),jsxRuntime.jsx("p",{className:"mt-1 text-xs text-zinc-500",children:"Please confirm in your wallet"}),jsxRuntime.jsx("button",{className:"mt-4 text-sm text-zinc-500 hover:text-white",onClick:ke,children:"Cancel"})]}),M==="select"&&!c&&!N&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[he.includes("phantom")&&jsxRuntime.jsxs("button",{onClick:Re,disabled:!B,className:`flex w-full items-center gap-4 border border-zinc-800 bg-[#25252f] p-4 transition-colors hover:bg-[#2d2d3a] ${B?"":"cursor-not-allowed opacity-50"}`,children:[jsxRuntime.jsx(te,{className:"h-14 w-14 flex-shrink-0"}),jsxRuntime.jsxs("div",{className:"flex-1 text-left",children:[jsxRuntime.jsx("span",{className:"font-medium text-lg text-white",children:"Phantom"}),!B&&jsxRuntime.jsx("p",{className:"text-xs text-zinc-500",children:"Not installed"})]}),jsxRuntime.jsx(pe,{className:"h-8 w-8"})]}),he.includes("metamask")&&Ee&&jsxRuntime.jsxs("button",{onClick:Be,className:"flex w-full items-center gap-4 border border-zinc-800 bg-[#25252f] p-4 transition-colors hover:bg-[#2d2d3a]",children:[jsxRuntime.jsx("div",{className:"flex h-14 w-14 flex-shrink-0 items-center justify-center bg-white p-2",children:jsxRuntime.jsx(ne,{className:"h-10 w-10"})}),jsxRuntime.jsx("div",{className:"flex-1 text-left",children:jsxRuntime.jsx("span",{className:"font-medium text-lg text-white",children:"MetaMask"})}),jsxRuntime.jsx(ge,{className:"h-8 w-8"})]}),ye&&!P&&jsxRuntime.jsxs("button",{onClick:()=>O(true),className:"flex w-full items-center gap-4 border border-zinc-800 bg-[#25252f] p-4 transition-colors hover:bg-[#2d2d3a]",children:[jsxRuntime.jsx("div",{className:"flex h-14 w-14 flex-shrink-0 items-center justify-center border border-zinc-700 bg-[#2a2a3e]",children:jsxRuntime.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",height:"28px",viewBox:"0 -960 960 960",width:"28px",fill:"#e3e3e3",children:jsxRuntime.jsx("path",{d:"M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Z"})})}),jsxRuntime.jsx("div",{className:"flex-1 text-left",children:jsxRuntime.jsx("span",{className:"font-medium text-lg text-white",children:"Access Code"})})]}),ye&&P&&jsxRuntime.jsxs("div",{className:"border border-zinc-800 bg-[#25252f] p-6 space-y-4",children:[jsxRuntime.jsx("p",{className:"text-center text-sm text-zinc-400",children:"Enter your 6-digit access code"}),jsxRuntime.jsx(ee,{onComplete:Fe,disabled:x==="verifying",error:$}),x==="verifying"&&jsxRuntime.jsx("p",{className:"text-center text-sm text-zinc-400 animate-pulse",children:"Verifying..."}),x==="success"&&jsxRuntime.jsx("p",{className:"text-center text-sm text-green-400",children:"Verified!"}),h?.webPageUrl&&x==="idle"&&jsxRuntime.jsx("a",{href:`${h.webPageUrl}/connect/pair`,target:"_blank",rel:"noopener noreferrer",className:"block text-center text-sm text-zinc-500 hover:text-white transition-colors",children:"Get code"})]})]})]})}function pt(){if(typeof document>"u")return null;let e=document.cookie.split(";").map(n=>n.trim()).find(n=>n.startsWith("__csrf="));return e?e.slice(7):null}function De(e,n){let[a,l]=react.useState(null),[w,m]=react.useState(true),[g,i]=react.useState(false),[p,c]=react.useState(null),v=n?.apiBaseUrl??"",s=n?.scope??"global",d=react.useCallback(o=>s==="global"?`${v}/api/user/profile/${o}`:`${v}/api/v2/stacks/${s.stackId}/members/${o}/profile`,[v,s]),t=react.useCallback(async()=>{if(!e){l(null),m(false);return}m(true),c(null);try{let o=await fetch(d(e));if(o.ok){let f=await o.json(),y=f.profile||f.data?.profile||f;l({mid:y.mid||e,username:y.username||"",avatarUrl:y.avatar_url||y.avatarUrl,bio:y.bio,createdAt:y.created_at||y.createdAt,updatedAt:y.updated_at||y.updatedAt});}else if(o.status===404)l({mid:e,username:""});else throw new Error(`${o.status}`)}catch(o){c(o instanceof Error?o.message:"Failed to load profile");}finally{m(false);}},[e,d]);react.useEffect(()=>{t();},[t]);let r=react.useCallback(async o=>{if(!e)return false;i(true),c(null);try{let f=pt(),y=await fetch(d(e),{method:"PUT",headers:{"Content-Type":"application/json",...f?{"x-csrf-token":f}:{}},credentials:"same-origin",body:JSON.stringify({username:o.username,avatar_url:o.avatarUrl,bio:o.bio})});if(!y.ok){let N=await y.json().catch(()=>({}));throw new Error(N.error||N.message||`Update failed: ${y.status}`)}let h=await y.json(),S=h.profile||h.data?.profile||h;return l(N=>({mid:N?.mid||e,username:o.username??N?.username??"",avatarUrl:o.avatarUrl??N?.avatarUrl,bio:o.bio??N?.bio,createdAt:N?.createdAt,updatedAt:S.updated_at||S.updatedAt||Date.now()})),!0}catch(f){return c(f instanceof Error?f.message:"Update failed"),false}finally{i(false);}},[e,d]);return {profile:a,loading:w,saving:g,error:p,updateProfile:r,refresh:t}}function mt({mid:e,apiBaseUrl:n="",scope:a,onSave:l,className:w}){let{profile:m,loading:g,saving:i,error:p,updateProfile:c}=De(e,{apiBaseUrl:n,scope:a}),[v,s]=react.useState(null),[d,t]=react.useState(null),[r,o]=react.useState(null),f=react.useRef(null),[y,h]=react.useState(false),S=v??m?.username??"",N=d??m?.bio??"",M=r??m?.avatarUrl,L=react.useCallback(P=>{let O=P.target.files?.[0];if(!O)return;let x=new FileReader;x.onload=()=>{o(x.result),h(true);},x.readAsDataURL(O);},[]),D=async()=>{await c({username:S||void 0,avatarUrl:r??m?.avatarUrl,bio:N||void 0})&&(h(false),l?.());};if(g)return jsxRuntime.jsxs("div",{className:w,style:{display:"grid",gap:"1.5rem"},children:[jsxRuntime.jsx("div",{style:{height:40,background:"var(--x-color-neutral-800, #333)",animation:"pulse 2s infinite"}}),jsxRuntime.jsx("div",{style:{height:40,background:"var(--x-color-neutral-800, #333)",animation:"pulse 2s infinite"}})]});let j=a==="global"||!a?"Global profile":`Stack profile (${a.stackId})`;return jsxRuntime.jsxs("div",{className:w,style:{display:"grid",gap:"1.5rem"},children:[jsxRuntime.jsx("p",{style:{fontSize:11,color:"var(--x-color-neutral-500, #91918D)",textTransform:"uppercase",letterSpacing:"0.05em"},children:j}),jsxRuntime.jsxs("div",{style:{display:"grid",gap:"1.5rem",gridTemplateColumns:"1fr 1fr"},children:[jsxRuntime.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem"},children:[jsxRuntime.jsx("label",{style:{fontSize:14,color:"var(--x-color-neutral-400, #91918D)"},children:"Username"}),jsxRuntime.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.75rem"},children:[jsxRuntime.jsx("button",{type:"button",onClick:()=>f.current?.click(),style:{width:40,height:40,flexShrink:0,cursor:"pointer",overflow:"hidden",background:"var(--x-color-neutral-800, #262625)",border:"none",position:"relative",display:"flex",alignItems:"center",justifyContent:"center"},children:M?jsxRuntime.jsx("img",{src:M,alt:"",style:{width:"100%",height:"100%",objectFit:"cover"}}):jsxRuntime.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",style:{color:"var(--x-color-neutral-500, #91918D)"},children:[jsxRuntime.jsx("path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"}),jsxRuntime.jsx("circle",{cx:"12",cy:"7",r:"4"})]})}),jsxRuntime.jsx("input",{type:"text",value:S,onChange:P=>{s(P.target.value),h(true);},placeholder:"Enter username",maxLength:30,style:{flex:1,padding:"0.75rem 1rem",fontSize:14,background:"var(--x-color-neutral-800, #262625)",color:"var(--x-color-neutral-100, #FAFAF7)",border:"none",outline:"none"}})]}),jsxRuntime.jsx("input",{ref:f,type:"file",accept:"image/*",onChange:L,style:{display:"none"}})]}),jsxRuntime.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem"},children:[jsxRuntime.jsx("label",{style:{fontSize:14,color:"var(--x-color-neutral-400, #91918D)"},children:"Bio"}),jsxRuntime.jsx("input",{type:"text",value:N,onChange:P=>{t(P.target.value),h(true);},placeholder:"Tell us about yourself",maxLength:200,style:{width:"100%",padding:"0.75rem 1rem",fontSize:14,background:"var(--x-color-neutral-800, #262625)",color:"var(--x-color-neutral-100, #FAFAF7)",border:"none",outline:"none"}})]})]}),p&&jsxRuntime.jsx("p",{style:{fontSize:13,color:"var(--x-color-red-500, #BF4D43)"},children:p}),y&&jsxRuntime.jsxs("div",{style:{display:"flex",gap:"0.5rem"},children:[jsxRuntime.jsx("button",{onClick:D,disabled:i,style:{padding:"0.5rem 1.25rem",fontSize:13,fontWeight:700,background:"var(--x-color-blue-600, #165DFC)",color:"#FFF",border:"none",cursor:i?"wait":"pointer",opacity:i?.6:1},children:i?"Saving...":"Save"}),jsxRuntime.jsx("button",{onClick:()=>{s(null),t(null),o(null),h(false);},style:{padding:"0.5rem 1.25rem",fontSize:13,background:"var(--x-color-neutral-800, #262625)",color:"var(--x-color-neutral-400, #91918D)",border:"none",cursor:"pointer"},children:"Cancel"}),jsxRuntime.jsx("p",{style:{fontSize:11,color:"var(--x-color-neutral-500, #666663)",alignSelf:"center",marginLeft:"0.5rem"},children:"Profile updates cost 100M tokens"})]})]})}function ht({className:e}){return jsxRuntime.jsxs("svg",{className:e||"h-8 w-8",viewBox:"0 0 33 32",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{x:"0.5",width:"32",height:"32",rx:"4",fill:"black"}),jsxRuntime.jsx("path",{d:"M8.53901 8L14.7164 16.2153L8.5 22.8947H9.89907L15.3415 17.0468L19.7389 22.8947H24.5L17.975 14.2173L23.7612 8H22.3621L17.3499 13.3858L13.3001 8H8.53901ZM10.5964 9.02501H12.7837L22.4422 21.8695H20.255L10.5964 9.02501Z",fill:"#F7F7F7"})]})}function kt({className:e}){return jsxRuntime.jsxs("svg",{className:e||"h-8 w-8",viewBox:"0 0 33 32",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{x:"0.5",width:"32",height:"32",rx:"4",fill:"#F1F2F9"}),jsxRuntime.jsx("path",{d:"M26.1001 16.2273C26.1001 15.5182 26.0365 14.8364 25.9183 14.1818H16.5001V18.05H21.8819C21.6501 19.3 20.9456 20.3591 19.8865 21.0682V23.5773H23.1183C25.0092 21.8364 26.1001 19.2727 26.1001 16.2273Z",fill:"#4285F4"}),jsxRuntime.jsx("path",{d:"M16.5001 26C19.2001 26 21.4637 25.1046 23.1182 23.5773L19.8864 21.0682C18.991 21.6682 17.8455 22.0227 16.5001 22.0227C13.8955 22.0227 11.691 20.2637 10.9046 17.9H7.56372V20.4909C9.20917 23.7591 12.591 26 16.5001 26Z",fill:"#34A853"}),jsxRuntime.jsx("path",{d:"M10.9047 17.8999C10.7047 17.2999 10.591 16.659 10.591 15.9999C10.591 15.3408 10.7047 14.6999 10.9047 14.0999V11.509H7.56376C6.86376 12.9025 6.49951 14.4405 6.50012 15.9999C6.50012 17.6136 6.88649 19.1408 7.56376 20.4908L10.9047 17.8999Z",fill:"#FBBC05"}),jsxRuntime.jsx("path",{d:"M16.5001 9.97726C17.9682 9.97726 19.2864 10.4818 20.3228 11.4727L23.191 8.60454C21.4591 6.99091 19.1955 6 16.5001 6C12.591 6 9.20917 8.2409 7.56372 11.5091L10.9046 14.1C11.691 11.7364 13.8955 9.97726 16.5001 9.97726Z",fill:"#EA4335"})]})}function bt({className:e}){return jsxRuntime.jsxs("svg",{className:e||"h-8 w-8",viewBox:"0 0 33 32",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[jsxRuntime.jsx("rect",{x:"0.5",width:"32",height:"32",rx:"4",fill:"#5462EB"}),jsxRuntime.jsx("path",{d:"M23.5433 8.87438C22.2479 8.26174 20.8587 7.81038 19.4063 7.55187C19.3799 7.54688 19.3534 7.55934 19.3398 7.58428C19.1612 7.91179 18.9633 8.33905 18.8247 8.67487C17.2625 8.43382 15.7084 8.43382 14.1782 8.67487C14.0396 8.33158 13.8345 7.91179 13.6551 7.58428C13.6414 7.56018 13.615 7.54771 13.5886 7.55187C12.1369 7.80955 10.7478 8.26092 9.45159 8.87438C9.44037 8.87937 9.43075 8.88769 9.42437 8.89849C6.78947 12.9558 6.06766 16.9134 6.42176 20.8219C6.42336 20.841 6.43378 20.8593 6.4482 20.871C8.18663 22.1868 9.87059 22.9857 11.5233 23.5152C11.5497 23.5235 11.5778 23.5135 11.5946 23.491C11.9855 22.9408 12.334 22.3606 12.6328 21.7504C12.6505 21.7147 12.6336 21.6723 12.5976 21.6581C12.0448 21.442 11.5185 21.1785 11.0122 20.8793C10.9721 20.8552 10.9689 20.7961 11.0058 20.7679C11.1123 20.6856 11.2189 20.6 11.3206 20.5135C11.339 20.4977 11.3647 20.4944 11.3863 20.5044C14.7125 22.0696 18.3136 22.0696 21.6006 20.5044C21.6222 20.4936 21.6479 20.4969 21.6671 20.5127C21.7688 20.5991 21.8754 20.6856 21.9827 20.7679C22.0196 20.7961 22.0172 20.8552 21.9771 20.8793C21.4708 21.1843 20.9445 21.442 20.3909 21.6573C20.3548 21.6715 20.3388 21.7147 20.3564 21.7504C20.6617 22.3597 21.0101 22.9399 21.3939 23.4902C21.4099 23.5135 21.4387 23.5235 21.4652 23.5152C23.1259 22.9857 24.8099 22.1868 26.5483 20.871C26.5635 20.8593 26.5731 20.8419 26.5747 20.8228C26.9985 16.3041 25.8649 12.3789 23.5697 8.89931C23.5641 8.88769 23.5545 8.87937 23.5433 8.87438Z",fill:"#F7F7F7"})]})}function vt({className:e}){return jsxRuntime.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 512 512",className:e||"h-8 w-8",children:[jsxRuntime.jsx("rect",{width:"512",height:"512",rx:"15%",fill:"#37aee2"}),jsxRuntime.jsx("path",{fill:"#c8daea",d:"M199 404c-11 0-10-4-13-14l-32-105 245-144"}),jsxRuntime.jsx("path",{fill:"#a9c9dd",d:"M199 404c7 0 11-4 16-8l45-43-56-34"}),jsxRuntime.jsx("path",{fill:"#f6fbfe",d:"M204 319l135 99c14 9 26 4 30-14l55-258c5-22-9-32-24-25L79 245c-21 8-21 21-4 26l83 26 190-121c9-5 17-3 11 4"})]})}
2
+ exports.ConnectWidget=ct;exports.DiscordIcon=bt;exports.EthereumIcon=ge;exports.GoogleIcon=kt;exports.MetaMaskIcon=ne;exports.OTPInput=ee;exports.PhantomIcon=te;exports.ProfileSettings=mt;exports.SolanaIcon=pe;exports.TelegramIcon=vt;exports.TwitterIcon=ht;exports.UserUtilsProvider=Ye;exports.useUserUtilsContext=Qe;
@@ -1,6 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { f as UserUtilsConfig, e as UserUtilsCallbacks } from '../index-BrziGArs.cjs';
3
+ import { f as UserUtilsConfig, e as UserUtilsCallbacks } from '../config-BrziGArs.cjs';
4
+ import { ProfileScope } from '../types/index.cjs';
4
5
 
5
6
  interface UserUtilsContextValue {
6
7
  config: UserUtilsConfig;
@@ -39,6 +40,20 @@ declare namespace OTPInput {
39
40
  var displayName: string;
40
41
  }
41
42
 
43
+ interface ProfileSettingsProps {
44
+ /** The user's MID (global_id or address) */
45
+ mid: string;
46
+ /** API base URL (empty = same-origin) */
47
+ apiBaseUrl?: string;
48
+ /** 'global' (default) or { stackId: 'stk_...' } for stack-scoped profiles */
49
+ scope?: ProfileScope;
50
+ /** Called after successful save */
51
+ onSave?: () => void;
52
+ /** CSS class name */
53
+ className?: string;
54
+ }
55
+ declare function ProfileSettings({ mid, apiBaseUrl, scope, onSave, className, }: ProfileSettingsProps): react_jsx_runtime.JSX.Element;
56
+
42
57
  declare function PhantomIcon({ className }: {
43
58
  className?: string;
44
59
  }): react_jsx_runtime.JSX.Element;
@@ -71,4 +86,4 @@ declare function TelegramIcon({ className }: {
71
86
  className?: string;
72
87
  }): react_jsx_runtime.JSX.Element;
73
88
 
74
- export { ConnectWidget, type ConnectWidgetProps, DiscordIcon, EthereumIcon, GoogleIcon, MetaMaskIcon, OTPInput, type OTPInputProps, PhantomIcon, SolanaIcon, TelegramIcon, TwitterIcon, UserUtilsProvider, type UserUtilsProviderProps, useUserUtilsContext };
89
+ export { ConnectWidget, type ConnectWidgetProps, DiscordIcon, EthereumIcon, GoogleIcon, MetaMaskIcon, OTPInput, type OTPInputProps, PhantomIcon, ProfileSettings, type ProfileSettingsProps, SolanaIcon, TelegramIcon, TwitterIcon, UserUtilsProvider, type UserUtilsProviderProps, useUserUtilsContext };