@bwalletx/connect 0.4.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +6 -2
  3. package/assets/protocol/401.jpg +0 -0
  4. package/assets/protocol/401.mp4 +0 -0
  5. package/assets/protocol/402.jpg +0 -0
  6. package/assets/protocol/402.mp4 +0 -0
  7. package/assets/protocol/403.jpg +0 -0
  8. package/assets/protocol/403.mp4 +0 -0
  9. package/dist/access-Dp0eKIOc.d.cts +118 -0
  10. package/dist/access-Dp0eKIOc.d.ts +118 -0
  11. package/dist/bwalletx-connect.global.js +20 -17
  12. package/dist/bwalletx-connect.global.js.map +1 -1
  13. package/dist/{chunk-NNMUSWPG.js → chunk-IUDD7YTQ.js} +200 -10
  14. package/dist/chunk-IUDD7YTQ.js.map +1 -0
  15. package/dist/chunk-MWD4BCO5.js +182 -0
  16. package/dist/chunk-MWD4BCO5.js.map +1 -0
  17. package/dist/{chunk-FUQ46RJV.js → chunk-PI42H3XY.js} +65 -10
  18. package/dist/chunk-PI42H3XY.js.map +1 -0
  19. package/dist/{chunk-7NAKOJGZ.js → chunk-QRXFL66W.js} +220 -10
  20. package/dist/chunk-QRXFL66W.js.map +1 -0
  21. package/dist/element.cjs +290 -14
  22. package/dist/element.cjs.map +1 -1
  23. package/dist/element.js +2 -1
  24. package/dist/element.js.map +1 -1
  25. package/dist/index.cjs +437 -32
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +71 -1
  28. package/dist/index.d.ts +71 -1
  29. package/dist/index.js +36 -4
  30. package/dist/index.js.map +1 -1
  31. package/dist/next.cjs +377 -9
  32. package/dist/next.cjs.map +1 -1
  33. package/dist/next.d.cts +52 -2
  34. package/dist/next.d.ts +52 -2
  35. package/dist/next.js +92 -1
  36. package/dist/next.js.map +1 -1
  37. package/dist/react.cjs +561 -226
  38. package/dist/react.cjs.map +1 -1
  39. package/dist/react.d.cts +5 -0
  40. package/dist/react.d.ts +5 -0
  41. package/dist/react.js +12 -3
  42. package/dist/react.js.map +1 -1
  43. package/dist/server.cjs +406 -9
  44. package/dist/server.cjs.map +1 -1
  45. package/dist/server.d.cts +111 -1
  46. package/dist/server.d.ts +111 -1
  47. package/dist/server.js +47 -1
  48. package/package.json +12 -11
  49. package/dist/chunk-7NAKOJGZ.js.map +0 -1
  50. package/dist/chunk-FUQ46RJV.js.map +0 -1
  51. package/dist/chunk-NNMUSWPG.js.map +0 -1
package/dist/react.d.cts CHANGED
@@ -101,6 +101,11 @@ interface BwalletXProviderProps {
101
101
  extraWallets?: WalletOption[];
102
102
  /** Probe desktop wallets on localhost. Default false. */
103
103
  probeLocal?: boolean;
104
+ /**
105
+ * A theme the wallet already bundles (e.g. 'npgx') for bWalletX to wear while this site is connected and is the
106
+ * active tab. Declared only while connecting or connected; withdrawn on disconnect. See declareWalletTheme.
107
+ */
108
+ theme?: string;
104
109
  discoverMs?: number;
105
110
  payOptions?: PayOptions;
106
111
  onError?: (e: Error) => void;
package/dist/react.d.ts CHANGED
@@ -101,6 +101,11 @@ interface BwalletXProviderProps {
101
101
  extraWallets?: WalletOption[];
102
102
  /** Probe desktop wallets on localhost. Default false. */
103
103
  probeLocal?: boolean;
104
+ /**
105
+ * A theme the wallet already bundles (e.g. 'npgx') for bWalletX to wear while this site is connected and is the
106
+ * active tab. Declared only while connecting or connected; withdrawn on disconnect. See declareWalletTheme.
107
+ */
108
+ theme?: string;
104
109
  discoverMs?: number;
105
110
  payOptions?: PayOptions;
106
111
  onError?: (e: Error) => void;
package/dist/react.js CHANGED
@@ -2,6 +2,7 @@ import {
2
2
  PaymentError,
3
3
  brc100Option,
4
4
  buyToken,
5
+ declareWalletTheme,
5
6
  discoverWallets,
6
7
  handcashAdapter,
7
8
  pairingModal,
@@ -9,12 +10,14 @@ import {
9
10
  pay,
10
11
  pickWallet,
11
12
  tip
12
- } from "./chunk-FUQ46RJV.js";
13
+ } from "./chunk-PI42H3XY.js";
13
14
  import {
15
+ atStage,
14
16
  clearPairing,
15
17
  defineBwalletxSignin,
16
18
  signInWithBwalletX
17
- } from "./chunk-NNMUSWPG.js";
19
+ } from "./chunk-IUDD7YTQ.js";
20
+ import "./chunk-MWD4BCO5.js";
18
21
 
19
22
  // src/react.ts
20
23
  import {
@@ -105,6 +108,12 @@ function BwalletXProvider(p) {
105
108
  props.current.onError?.(err);
106
109
  return err;
107
110
  }, []);
111
+ const themeOn = !!p.theme && (state.status === "connecting" || state.status === "connected");
112
+ useEffect(() => {
113
+ if (!themeOn) return;
114
+ declareWalletTheme(p.theme);
115
+ return () => declareWalletTheme(null);
116
+ }, [themeOn, p.theme]);
108
117
  useEffect(() => {
109
118
  const url = p.sessionUrl;
110
119
  if (!url) return;
@@ -155,7 +164,7 @@ function BwalletXProvider(p) {
155
164
  wallet: cw.wallet,
156
165
  challenge: (identityKey) => postJson(c.challengeUrl, { identityKey })
157
166
  });
158
- const v = await postJson(c.verifyUrl, { identityKey: r.identityKey, nonce: r.nonce, signature: r.signature });
167
+ const v = await atStage("verify", () => postJson(c.verifyUrl, { identityKey: r.identityKey, nonce: r.nonce, signature: r.signature }));
159
168
  handle = v.handle ?? handle;
160
169
  paymail = v.paymail ?? paymail;
161
170
  signedIn = true;
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react.ts"],"sourcesContent":["/**\n * React wrapper for <bwalletx-signin>. React is an optional peer dependency; the button itself is\n * the web component, so markup and behaviour are identical everywhere.\n *\n * import { BwalletxSignin } from '@bwalletx/connect/react';\n * <BwalletxSignin challengeUrl=\"/auth/bwalletx/challenge\" verifyUrl=\"/auth/bwalletx/verify\"\n * onSignedIn={(d) => router.refresh()} />\n */\nimport {\n createContext,\n createElement,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport type { WalletInterface } from '@bsv/sdk';\nimport { clearPairing } from './pair.js';\nimport { signInWithBwalletX, type Challenge } from './signin.js';\nimport { pairingModal } from './modal.js';\nimport { pickWallet } from './modal.js';\nimport { discoverWallets, type ConnectedWallet, type WalletOption } from './wallets.js';\nimport { PaymentError, buyToken, pay, tip, type BuyTokenRequest, type PayOptions, type PayRequest, type PayResult } from './pay.js';\nimport { defineBwalletxSignin, type SigninBrand, type SigninLabel, type SigninSize, type SigninTheme } from './element.js';\n\nexport interface SignedInDetail {\n identityKey: string;\n method: string;\n nonce: string;\n signature: number[];\n response: unknown;\n}\n\nexport interface BwalletxSigninProps {\n size?: SigninSize;\n theme?: SigninTheme;\n label?: SigninLabel;\n brand?: SigninBrand;\n /** true/undefined = default, false = hidden, string = custom text. */\n subtitle?: boolean | string;\n fullWidth?: boolean;\n loading?: boolean;\n disabled?: boolean;\n challengeUrl?: string;\n verifyUrl?: string;\n getUrl?: string;\n webUrl?: string;\n href?: string;\n authorizeUrl?: string;\n clientId?: string;\n redirectUri?: string;\n scope?: string;\n discoverMs?: number;\n 'aria-label'?: string;\n className?: string;\n style?: CSSProperties;\n id?: string;\n /** Every click. Call e.preventDefault() to skip the built-in flow. */\n onClick?: (e: CustomEvent<{ element: HTMLElement }>) => void;\n onSignedIn?: (d: SignedInDetail) => void;\n onNotFound?: () => void;\n onError?: (error: unknown) => void;\n}\n\nexport function BwalletxSignin(props: BwalletxSigninProps): ReactElement {\n const ref = useRef<HTMLElement>(null);\n const cb = useRef(props);\n cb.current = props;\n\n useEffect(() => {\n defineBwalletxSignin();\n const el = ref.current;\n if (!el) return;\n const on: [string, EventListener][] = [\n ['bwalletx-signin', (e) => cb.current.onClick?.(e as CustomEvent<{ element: HTMLElement }>)],\n ['bwalletx-signed-in', (e) => cb.current.onSignedIn?.((e as CustomEvent<SignedInDetail>).detail)],\n ['bwalletx-not-found', () => cb.current.onNotFound?.()],\n ['bwalletx-error', (e) => cb.current.onError?.((e as CustomEvent<{ error: unknown }>).detail.error)],\n ];\n for (const [t, f] of on) el.addEventListener(t, f);\n return () => { for (const [t, f] of on) el.removeEventListener(t, f); };\n }, []);\n\n const p = props;\n const flag = (v: boolean | undefined) => (v ? '' : undefined);\n return createElement('bwalletx-signin', {\n ref,\n id: p.id,\n class: p.className,\n style: p.style,\n size: p.size,\n theme: p.theme,\n label: p.label,\n brand: p.brand,\n subtitle: p.subtitle === false ? 'off' : typeof p.subtitle === 'string' ? p.subtitle : undefined,\n 'full-width': flag(p.fullWidth),\n loading: flag(p.loading),\n disabled: flag(p.disabled),\n 'challenge-url': p.challengeUrl,\n 'verify-url': p.verifyUrl,\n 'get-url': p.getUrl,\n 'web-url': p.webUrl,\n href: p.href,\n 'authorize-url': p.authorizeUrl,\n 'client-id': p.clientId,\n 'redirect-uri': p.redirectUri,\n scope: p.scope,\n 'discover-ms': p.discoverMs,\n 'aria-label': p['aria-label'],\n });\n}\n\nexport default BwalletxSignin;\n\nexport type BwalletXStatus = 'idle' | 'restoring' | 'connecting' | 'connected' | 'error';\n\nexport interface BwalletXState {\n status: BwalletXStatus;\n identityKey: string | null;\n handle: string | null;\n paymail: string | null;\n /** The BRC-100 wallet. null until connect() (a session restored from the cookie has no wallet yet). */\n wallet: WalletInterface | null;\n /** Which option connected (e.g. 'com.bwalletx.extension', 'bwalletx-pairing', 'handcash'). */\n walletId: string | null;\n /** True while the transitional HandCash adapter is in use. */\n transitional: boolean;\n /** The server session (verifyUrl/sessionUrl) is in place. */\n signedIn: boolean;\n error: Error | null;\n}\n\nexport interface BwalletXContextValue extends BwalletXState {\n /** Find wallets, show the picker if there is a choice, connect, and sign in if verifyUrl is set. */\n connect(opts?: { walletId?: string }): Promise<ConnectedWallet | null>;\n disconnect(): Promise<void>;\n /** The wallets found on the last connect() (or listWallets()). */\n wallets: WalletOption[];\n listWallets(): Promise<WalletOption[]>;\n pay(req: PayRequest): Promise<PayResult>;\n tip(req: PayRequest): Promise<PayResult>;\n buyToken(req: BuyTokenRequest): Promise<PayResult>;\n}\n\nexport interface BwalletXProviderProps {\n children?: ReactNode;\n /** POST { identityKey } → challenge. With verifyUrl, connect() also signs in. */\n challengeUrl?: string;\n /** POST { identityKey, nonce, signature } → { identityKey, handle?, paymail? } and sets the cookie. */\n verifyUrl?: string;\n /** POST to clear the cookie on disconnect(). */\n logoutUrl?: string;\n /** GET → { identityKey, handle?, paymail? } to restore a session on load. */\n sessionUrl?: string;\n /** Offer phone pairing with the built-in QR modal. Default true. */\n pairing?: boolean;\n /** Show the built-in picker when more than one wallet is available. Default true. */\n picker?: boolean;\n /** Extra options, e.g. [handcashAdapter({ login })]. */\n extraWallets?: WalletOption[];\n /** Probe desktop wallets on localhost. Default false. */\n probeLocal?: boolean;\n discoverMs?: number;\n payOptions?: PayOptions;\n onError?: (e: Error) => void;\n}\n\nconst empty: BwalletXState = {\n status: 'idle', identityKey: null, handle: null, paymail: null, wallet: null, walletId: null, transitional: false, signedIn: false, error: null,\n};\n\nconst Ctx = createContext<BwalletXContextValue | null>(null);\n\nasync function postJson(url: string, body: unknown): Promise<Record<string, unknown>> {\n const r = await fetch(url, { method: 'POST', credentials: 'same-origin', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) });\n const j = (await r.json().catch(() => ({}))) as Record<string, unknown>;\n if (!r.ok) throw Object.assign(new Error(String(j.error ?? `${url} answered ${r.status}`)), { status: r.status, code: j.code });\n return j;\n}\n\n/** Holds the connected wallet and session for the tree. Renders nothing itself; SSR-safe. */\nexport function BwalletXProvider(p: BwalletXProviderProps): ReactElement {\n const [state, setState] = useState<BwalletXState>(empty);\n const [wallets, setWallets] = useState<WalletOption[]>([]);\n const props = useRef(p);\n props.current = p;\n const payer = useRef<ConnectedWallet['payer']>(null);\n\n const fail = useCallback((e: unknown) => {\n const err = e instanceof Error ? e : new Error(String(e));\n setState((s) => ({ ...s, status: 'error', error: err }));\n props.current.onError?.(err);\n return err;\n }, []);\n\n useEffect(() => {\n const url = p.sessionUrl;\n if (!url) return;\n let live = true;\n setState((s) => ({ ...s, status: 'restoring' }));\n fetch(url, { credentials: 'same-origin' })\n .then((r) => r.json())\n .then((j: { identityKey?: string | null; handle?: string; paymail?: string }) => {\n if (!live) return;\n setState((s) =>\n j.identityKey\n ? { ...s, status: 'connected', identityKey: j.identityKey, handle: j.handle ?? null, paymail: j.paymail ?? null, signedIn: true }\n : { ...s, status: s.status === 'restoring' ? 'idle' : s.status },\n );\n })\n .catch(() => live && setState((s) => ({ ...s, status: s.status === 'restoring' ? 'idle' : s.status })));\n return () => {\n live = false;\n };\n }, [p.sessionUrl]);\n\n const listWallets = useCallback(async () => {\n const c = props.current;\n const list = await discoverWallets({\n ms: c.discoverMs,\n probeLocal: c.probeLocal,\n extra: c.extraWallets,\n pairing: c.pairing === false ? undefined : () => pairingModal(),\n });\n setWallets(list);\n return list;\n }, []);\n\n const connect = useCallback(\n async (opts: { walletId?: string } = {}) => {\n const c = props.current;\n setState((s) => ({ ...s, status: 'connecting', error: null }));\n try {\n const list = await listWallets();\n let choice: WalletOption | null | undefined = opts.walletId ? list.find((w) => w.id === opts.walletId) : undefined;\n if (!choice) {\n const direct = list.filter((w) => w.kind !== 'pairing');\n choice = c.picker !== false && list.length > 1 ? await pickWallet(list) : (direct[0] ?? list[0] ?? null);\n }\n if (!choice) {\n if (!list.length) throw Object.assign(new Error('No wallet found. Get bWalletX at bwalletx.com.'), { code: 'NOT_FOUND' });\n setState((s) => ({ ...s, status: s.identityKey ? 'connected' : 'idle' }));\n return null;\n }\n const cw = await choice.connect();\n let { handle = null, paymail = null } = cw as { handle?: string | null; paymail?: string | null };\n let signedIn = false;\n if (cw.wallet && c.challengeUrl && c.verifyUrl) {\n const r = await signInWithBwalletX({\n wallet: cw.wallet,\n challenge: (identityKey) => postJson(c.challengeUrl!, { identityKey }) as unknown as Promise<Challenge>,\n });\n const v = await postJson(c.verifyUrl, { identityKey: r.identityKey, nonce: r.nonce, signature: r.signature });\n handle = (v.handle as string | undefined) ?? handle;\n paymail = (v.paymail as string | undefined) ?? paymail;\n signedIn = true;\n }\n payer.current = cw.payer;\n setState({\n status: 'connected',\n identityKey: cw.identityKey,\n handle,\n paymail,\n wallet: cw.wallet,\n walletId: cw.optionId,\n transitional: !!cw.transitional,\n signedIn,\n error: null,\n });\n return cw;\n } catch (e) {\n if ((e as Error)?.message === 'cancelled') {\n setState((s) => ({ ...s, status: s.identityKey ? 'connected' : 'idle' }));\n return null;\n }\n throw fail(e);\n }\n },\n [fail, listWallets],\n );\n\n const disconnect = useCallback(async () => {\n const c = props.current;\n if (c.logoutUrl) await postJson(c.logoutUrl, {}).catch(() => {});\n if (state.walletId === 'bwalletx-pairing') await clearPairing();\n payer.current = null;\n setState(empty);\n }, [state.walletId]);\n\n const need = () => {\n if (!payer.current) throw new PaymentError('NOT_SUPPORTED', 'Connect a wallet first (connect()).');\n return payer.current;\n };\n\n const value = useMemo<BwalletXContextValue>(\n () => ({\n ...state,\n wallets,\n connect,\n disconnect,\n listWallets,\n pay: (req) => pay(need(), req, props.current.payOptions),\n tip: (req) => tip(need(), req, props.current.payOptions),\n buyToken: (req) => buyToken(need(), req),\n }),\n [state, wallets, connect, disconnect, listWallets],\n );\n\n return createElement(Ctx.Provider, { value }, p.children);\n}\n\n/** The wallet + session state. Must be inside <BwalletXProvider>. */\nexport function useBwalletX(): BwalletXContextValue {\n const v = useContext(Ctx);\n if (!v) throw new Error('useBwalletX() must be used inside <BwalletXProvider>');\n return v;\n}\n\nexport { handcashAdapter, brc100Option, pairingOption, discoverWallets } from './wallets.js';\nexport type { WalletOption, ConnectedWallet, HandCashAdapterOptions } from './wallets.js';\nexport { PaymentError } from './pay.js';\nexport type { PayRequest, PayResult, BuyTokenRequest, PayOptions } from './pay.js';\n/** Alias with the casing used by <BwalletxSignin>. */\nexport const BwalletxProvider = BwalletXProvider;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/react.ts"],"sourcesContent":["/**\n * React wrapper for <bwalletx-signin>. React is an optional peer dependency; the button itself is\n * the web component, so markup and behaviour are identical everywhere.\n *\n * import { BwalletxSignin } from '@bwalletx/connect/react';\n * <BwalletxSignin challengeUrl=\"/auth/bwalletx/challenge\" verifyUrl=\"/auth/bwalletx/verify\"\n * onSignedIn={(d) => router.refresh()} />\n */\nimport {\n createContext,\n createElement,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport type { WalletInterface } from '@bsv/sdk';\nimport { clearPairing } from './pair.js';\nimport { declareWalletTheme } from './theme.js';\nimport { atStage, signInWithBwalletX, type Challenge } from './signin.js';\nimport { pairingModal } from './modal.js';\nimport { pickWallet } from './modal.js';\nimport { discoverWallets, type ConnectedWallet, type WalletOption } from './wallets.js';\nimport { PaymentError, buyToken, pay, tip, type BuyTokenRequest, type PayOptions, type PayRequest, type PayResult } from './pay.js';\nimport { defineBwalletxSignin, type SigninBrand, type SigninLabel, type SigninSize, type SigninTheme } from './element.js';\n\nexport interface SignedInDetail {\n identityKey: string;\n method: string;\n nonce: string;\n signature: number[];\n response: unknown;\n}\n\nexport interface BwalletxSigninProps {\n size?: SigninSize;\n theme?: SigninTheme;\n label?: SigninLabel;\n brand?: SigninBrand;\n /** true/undefined = default, false = hidden, string = custom text. */\n subtitle?: boolean | string;\n fullWidth?: boolean;\n loading?: boolean;\n disabled?: boolean;\n challengeUrl?: string;\n verifyUrl?: string;\n getUrl?: string;\n webUrl?: string;\n href?: string;\n authorizeUrl?: string;\n clientId?: string;\n redirectUri?: string;\n scope?: string;\n discoverMs?: number;\n 'aria-label'?: string;\n className?: string;\n style?: CSSProperties;\n id?: string;\n /** Every click. Call e.preventDefault() to skip the built-in flow. */\n onClick?: (e: CustomEvent<{ element: HTMLElement }>) => void;\n onSignedIn?: (d: SignedInDetail) => void;\n onNotFound?: () => void;\n onError?: (error: unknown) => void;\n}\n\nexport function BwalletxSignin(props: BwalletxSigninProps): ReactElement {\n const ref = useRef<HTMLElement>(null);\n const cb = useRef(props);\n cb.current = props;\n\n useEffect(() => {\n defineBwalletxSignin();\n const el = ref.current;\n if (!el) return;\n const on: [string, EventListener][] = [\n ['bwalletx-signin', (e) => cb.current.onClick?.(e as CustomEvent<{ element: HTMLElement }>)],\n ['bwalletx-signed-in', (e) => cb.current.onSignedIn?.((e as CustomEvent<SignedInDetail>).detail)],\n ['bwalletx-not-found', () => cb.current.onNotFound?.()],\n ['bwalletx-error', (e) => cb.current.onError?.((e as CustomEvent<{ error: unknown }>).detail.error)],\n ];\n for (const [t, f] of on) el.addEventListener(t, f);\n return () => { for (const [t, f] of on) el.removeEventListener(t, f); };\n }, []);\n\n const p = props;\n const flag = (v: boolean | undefined) => (v ? '' : undefined);\n return createElement('bwalletx-signin', {\n ref,\n id: p.id,\n class: p.className,\n style: p.style,\n size: p.size,\n theme: p.theme,\n label: p.label,\n brand: p.brand,\n subtitle: p.subtitle === false ? 'off' : typeof p.subtitle === 'string' ? p.subtitle : undefined,\n 'full-width': flag(p.fullWidth),\n loading: flag(p.loading),\n disabled: flag(p.disabled),\n 'challenge-url': p.challengeUrl,\n 'verify-url': p.verifyUrl,\n 'get-url': p.getUrl,\n 'web-url': p.webUrl,\n href: p.href,\n 'authorize-url': p.authorizeUrl,\n 'client-id': p.clientId,\n 'redirect-uri': p.redirectUri,\n scope: p.scope,\n 'discover-ms': p.discoverMs,\n 'aria-label': p['aria-label'],\n });\n}\n\nexport default BwalletxSignin;\n\nexport type BwalletXStatus = 'idle' | 'restoring' | 'connecting' | 'connected' | 'error';\n\nexport interface BwalletXState {\n status: BwalletXStatus;\n identityKey: string | null;\n handle: string | null;\n paymail: string | null;\n /** The BRC-100 wallet. null until connect() (a session restored from the cookie has no wallet yet). */\n wallet: WalletInterface | null;\n /** Which option connected (e.g. 'com.bwalletx.extension', 'bwalletx-pairing', 'handcash'). */\n walletId: string | null;\n /** True while the transitional HandCash adapter is in use. */\n transitional: boolean;\n /** The server session (verifyUrl/sessionUrl) is in place. */\n signedIn: boolean;\n error: Error | null;\n}\n\nexport interface BwalletXContextValue extends BwalletXState {\n /** Find wallets, show the picker if there is a choice, connect, and sign in if verifyUrl is set. */\n connect(opts?: { walletId?: string }): Promise<ConnectedWallet | null>;\n disconnect(): Promise<void>;\n /** The wallets found on the last connect() (or listWallets()). */\n wallets: WalletOption[];\n listWallets(): Promise<WalletOption[]>;\n pay(req: PayRequest): Promise<PayResult>;\n tip(req: PayRequest): Promise<PayResult>;\n buyToken(req: BuyTokenRequest): Promise<PayResult>;\n}\n\nexport interface BwalletXProviderProps {\n children?: ReactNode;\n /** POST { identityKey } → challenge. With verifyUrl, connect() also signs in. */\n challengeUrl?: string;\n /** POST { identityKey, nonce, signature } → { identityKey, handle?, paymail? } and sets the cookie. */\n verifyUrl?: string;\n /** POST to clear the cookie on disconnect(). */\n logoutUrl?: string;\n /** GET → { identityKey, handle?, paymail? } to restore a session on load. */\n sessionUrl?: string;\n /** Offer phone pairing with the built-in QR modal. Default true. */\n pairing?: boolean;\n /** Show the built-in picker when more than one wallet is available. Default true. */\n picker?: boolean;\n /** Extra options, e.g. [handcashAdapter({ login })]. */\n extraWallets?: WalletOption[];\n /** Probe desktop wallets on localhost. Default false. */\n probeLocal?: boolean;\n /**\n * A theme the wallet already bundles (e.g. 'npgx') for bWalletX to wear while this site is connected and is the\n * active tab. Declared only while connecting or connected; withdrawn on disconnect. See declareWalletTheme.\n */\n theme?: string;\n discoverMs?: number;\n payOptions?: PayOptions;\n onError?: (e: Error) => void;\n}\n\nconst empty: BwalletXState = {\n status: 'idle', identityKey: null, handle: null, paymail: null, wallet: null, walletId: null, transitional: false, signedIn: false, error: null,\n};\n\nconst Ctx = createContext<BwalletXContextValue | null>(null);\n\nasync function postJson(url: string, body: unknown): Promise<Record<string, unknown>> {\n const r = await fetch(url, { method: 'POST', credentials: 'same-origin', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) });\n const j = (await r.json().catch(() => ({}))) as Record<string, unknown>;\n if (!r.ok) throw Object.assign(new Error(String(j.error ?? `${url} answered ${r.status}`)), { status: r.status, code: j.code });\n return j;\n}\n\n/** Holds the connected wallet and session for the tree. Renders nothing itself; SSR-safe. */\nexport function BwalletXProvider(p: BwalletXProviderProps): ReactElement {\n const [state, setState] = useState<BwalletXState>(empty);\n const [wallets, setWallets] = useState<WalletOption[]>([]);\n const props = useRef(p);\n props.current = p;\n const payer = useRef<ConnectedWallet['payer']>(null);\n\n const fail = useCallback((e: unknown) => {\n const err = e instanceof Error ? e : new Error(String(e));\n setState((s) => ({ ...s, status: 'error', error: err }));\n props.current.onError?.(err);\n return err;\n }, []);\n\n const themeOn = !!p.theme && (state.status === 'connecting' || state.status === 'connected');\n useEffect(() => {\n if (!themeOn) return;\n declareWalletTheme(p.theme);\n return () => declareWalletTheme(null);\n }, [themeOn, p.theme]);\n\n useEffect(() => {\n const url = p.sessionUrl;\n if (!url) return;\n let live = true;\n setState((s) => ({ ...s, status: 'restoring' }));\n fetch(url, { credentials: 'same-origin' })\n .then((r) => r.json())\n .then((j: { identityKey?: string | null; handle?: string; paymail?: string }) => {\n if (!live) return;\n setState((s) =>\n j.identityKey\n ? { ...s, status: 'connected', identityKey: j.identityKey, handle: j.handle ?? null, paymail: j.paymail ?? null, signedIn: true }\n : { ...s, status: s.status === 'restoring' ? 'idle' : s.status },\n );\n })\n .catch(() => live && setState((s) => ({ ...s, status: s.status === 'restoring' ? 'idle' : s.status })));\n return () => {\n live = false;\n };\n }, [p.sessionUrl]);\n\n const listWallets = useCallback(async () => {\n const c = props.current;\n const list = await discoverWallets({\n ms: c.discoverMs,\n probeLocal: c.probeLocal,\n extra: c.extraWallets,\n pairing: c.pairing === false ? undefined : () => pairingModal(),\n });\n setWallets(list);\n return list;\n }, []);\n\n const connect = useCallback(\n async (opts: { walletId?: string } = {}) => {\n const c = props.current;\n setState((s) => ({ ...s, status: 'connecting', error: null }));\n try {\n const list = await listWallets();\n let choice: WalletOption | null | undefined = opts.walletId ? list.find((w) => w.id === opts.walletId) : undefined;\n if (!choice) {\n const direct = list.filter((w) => w.kind !== 'pairing');\n choice = c.picker !== false && list.length > 1 ? await pickWallet(list) : (direct[0] ?? list[0] ?? null);\n }\n if (!choice) {\n if (!list.length) throw Object.assign(new Error('No wallet found. Get bWalletX at bwalletx.com.'), { code: 'NOT_FOUND' });\n setState((s) => ({ ...s, status: s.identityKey ? 'connected' : 'idle' }));\n return null;\n }\n const cw = await choice.connect();\n let { handle = null, paymail = null } = cw as { handle?: string | null; paymail?: string | null };\n let signedIn = false;\n if (cw.wallet && c.challengeUrl && c.verifyUrl) {\n const r = await signInWithBwalletX({\n wallet: cw.wallet,\n challenge: (identityKey) => postJson(c.challengeUrl!, { identityKey }) as unknown as Promise<Challenge>,\n });\n const v = await atStage('verify', () => postJson(c.verifyUrl!, { identityKey: r.identityKey, nonce: r.nonce, signature: r.signature }));\n handle = (v.handle as string | undefined) ?? handle;\n paymail = (v.paymail as string | undefined) ?? paymail;\n signedIn = true;\n }\n payer.current = cw.payer;\n setState({\n status: 'connected',\n identityKey: cw.identityKey,\n handle,\n paymail,\n wallet: cw.wallet,\n walletId: cw.optionId,\n transitional: !!cw.transitional,\n signedIn,\n error: null,\n });\n return cw;\n } catch (e) {\n if ((e as Error)?.message === 'cancelled') {\n setState((s) => ({ ...s, status: s.identityKey ? 'connected' : 'idle' }));\n return null;\n }\n throw fail(e);\n }\n },\n [fail, listWallets],\n );\n\n const disconnect = useCallback(async () => {\n const c = props.current;\n if (c.logoutUrl) await postJson(c.logoutUrl, {}).catch(() => {});\n if (state.walletId === 'bwalletx-pairing') await clearPairing();\n payer.current = null;\n setState(empty);\n }, [state.walletId]);\n\n const need = () => {\n if (!payer.current) throw new PaymentError('NOT_SUPPORTED', 'Connect a wallet first (connect()).');\n return payer.current;\n };\n\n const value = useMemo<BwalletXContextValue>(\n () => ({\n ...state,\n wallets,\n connect,\n disconnect,\n listWallets,\n pay: (req) => pay(need(), req, props.current.payOptions),\n tip: (req) => tip(need(), req, props.current.payOptions),\n buyToken: (req) => buyToken(need(), req),\n }),\n [state, wallets, connect, disconnect, listWallets],\n );\n\n return createElement(Ctx.Provider, { value }, p.children);\n}\n\n/** The wallet + session state. Must be inside <BwalletXProvider>. */\nexport function useBwalletX(): BwalletXContextValue {\n const v = useContext(Ctx);\n if (!v) throw new Error('useBwalletX() must be used inside <BwalletXProvider>');\n return v;\n}\n\nexport { handcashAdapter, brc100Option, pairingOption, discoverWallets } from './wallets.js';\nexport type { WalletOption, ConnectedWallet, HandCashAdapterOptions } from './wallets.js';\nexport { PaymentError } from './pay.js';\nexport type { PayRequest, PayResult, BuyTokenRequest, PayOptions } from './pay.js';\n/** Alias with the casing used by <BwalletxSignin>. */\nexport const BwalletxProvider = BwalletXProvider;\n"],"mappings":"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","names":[]}