@powerhousedao/reactor-browser 6.2.2-dev.12 → 6.2.2-dev.13

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 CHANGED
@@ -9,6 +9,7 @@ This document contains all documentation comments for the hooks exported from `p
9
9
  - [Config: Editor](#config-editor)
10
10
  - [Config: Set Config by Object](#config-set-config-by-object)
11
11
  - [Config: Use Value by Key](#config-use-value-by-key)
12
+ - [Renown in-page sign-in](#renown-in-page-sign-in)
12
13
  - [Document by ID](#document-by-id)
13
14
  - [Document Cache](#document-cache)
14
15
  - [Document of Type](#document-of-type)
@@ -507,3 +508,180 @@ Strongly typed, inferred from type definition for the key.
507
508
  Gets the value of an item in the global document config for a given key.
508
509
 
509
510
  Strongly typed, inferred from type definition for the key.
511
+
512
+ ---
513
+
514
+ ## Renown in-page sign-in
515
+
516
+ Let users authenticate with Renown **inside your app** — no redirect to the
517
+ Renown portal — using pluggable wallet adapters (RainbowKit for external
518
+ wallets, Privy for social/email). This is the same integration Connect and the
519
+ `test-fusion` app use. Import from `@powerhousedao/reactor-browser/renown` (or
520
+ the package root).
521
+
522
+ ### Quick start — `RenownProvider`
523
+
524
+ Mount one provider high in your tree. It initializes the SDK, seeds the first
525
+ render (from a server session cookie for SSR, or `localStorage` for client-only
526
+ apps), mounts the wallet adapters (lazy-loaded on the first login click), keeps a
527
+ server-readable session cookie in sync when running under SSR, and revalidates
528
+ the stored credential against the switchboard.
529
+
530
+ ```tsx
531
+ import { RenownProvider } from "@powerhousedao/reactor-browser/renown";
532
+
533
+ <RenownProvider
534
+ appName="my-app"
535
+ namespace="my-app"
536
+ switchboardUrl="https://switchboard.example/graphql"
537
+ adapters={{
538
+ rainbow: { walletConnectProjectId: "..." },
539
+ privy: { appId: "...", methods: ["google", "email"] },
540
+ }}
541
+ theme="light" // "light" | "dark" | { mode, accentColor?, accentColorForeground? }
542
+ >
543
+ <App />
544
+ </RenownProvider>;
545
+ ```
546
+
547
+ The provider is **SSR-safe** — it renders on the server without `ssr: false`;
548
+ the wallet libraries only load client-side on the first login click.
549
+
550
+ Then build the login UI with `useRenownLoginMethods` (derives the button list
551
+ from the config) and `useRenownAuth` (login + user state):
552
+
553
+ ```tsx
554
+ import {
555
+ useRenownAuth,
556
+ useRenownLoginMethods,
557
+ } from "@powerhousedao/reactor-browser/renown";
558
+
559
+ function Login({ adapters }) {
560
+ const { user, login, pending, error, logout } = useRenownAuth();
561
+ const methods = useRenownLoginMethods(adapters);
562
+ if (user) return <button onClick={() => void logout()}>Log out</button>;
563
+ return (
564
+ <>
565
+ {methods.map((m) => (
566
+ <button key={m.id} disabled={pending} onClick={() => login(undefined, m.id)}>
567
+ {m.label}
568
+ </button>
569
+ ))}
570
+ {error ? <p>{error.message}</p> : null}
571
+ </>
572
+ );
573
+ }
574
+ ```
575
+
576
+ `login(session?, method?)` activates the adapters on click, routes `method` to
577
+ the adapter that supports it, produces a `WalletSession`, and completes the
578
+ Renown credential sign-in via the switchboard — falling back to the redirect
579
+ flow when no switchboard/adapter is available.
580
+
581
+ ### À la carte
582
+
583
+ `RenownProvider` composes pieces you can also mount yourself — use them directly
584
+ only when you need a custom tree:
585
+
586
+ - `<Renown appName namespace switchboardUrl revalidate? />` — SDK init (renders
587
+ `null`; place high in the tree).
588
+ - `RenownWalletProvider` — wallet adapters (below).
589
+ - `RenownInitialUserProvider` — seeds the first render with a `User` (see
590
+ [Server-side rendering](#server-side-rendering-ssr)).
591
+
592
+ ### Auth state — `useRenownAuth` / `useRenownAuthAsync`
593
+
594
+ `useRenownAuth()` returns the live auth: `{ user, status, pending, error, login,
595
+ logout, displayName, displayAddress, ... }`. Gate on it with a plain `if` — no
596
+ wrapper component is needed:
597
+
598
+ ```tsx
599
+ function EditButton() {
600
+ const { user } = useRenownAuth();
601
+ if (!user) return null;
602
+ return <button>Edit</button>;
603
+ }
604
+ ```
605
+
606
+ `useRenownAuthAsync()` adds a collapsed `state: "authenticated" | "resolving" |
607
+ "unauthenticated"` (and `isResolving`) so you can show a skeleton during the
608
+ resolving window **without a Suspense boundary** — handy for client-only apps:
609
+
610
+ ```tsx
611
+ function EditButton() {
612
+ const { state } = useRenownAuthAsync();
613
+ if (state === "resolving") return <EditSkeleton />;
614
+ if (state === "unauthenticated") return null;
615
+ return <button>Edit</button>;
616
+ }
617
+ ```
618
+
619
+ ### Server-side rendering (SSR)
620
+
621
+ The provider tree is SSR-safe, so the logged-out shell renders on the server with
622
+ no `ssr: false`. To render **authenticated** content on the server (no flash),
623
+ give `RenownProvider` a server-resolved `session`:
624
+
625
+ ```tsx
626
+ // app/layout.tsx (server component)
627
+ import { verifySession } from "@/lib/dal";
628
+
629
+ const session = await verifySession(); // reads + verifies the session cookie
630
+ <RenownProvider appName="my-app" session={session}>
631
+ {children}
632
+ </RenownProvider>;
633
+ ```
634
+
635
+ Passing `session` also enables the **session-cookie sync**: after each login the
636
+ client mints a bearer token and POSTs it to `sessionEndpoint` (default
637
+ `/api/renown/session`), and clears it on logout. Your app provides the route
638
+ handler that sets an HttpOnly cookie, and a Data Access Layer that verifies it
639
+ with `verifyRenownSession` from `@renown/sdk/node` (see that package's README).
640
+
641
+ ### Client-only apps
642
+
643
+ Omit `session` and the provider seeds the first render synchronously from
644
+ `localStorage` (`readPersistedUser`), so a returning user renders authenticated
645
+ on the first paint — no server, no flash. The stored credential is revalidated in
646
+ the background (see below); `useRenownAuthAsync` exposes `resolving` for the cold
647
+ start with no stored session.
648
+
649
+ ### Revalidation
650
+
651
+ On mount the provider revalidates the restored credential against the switchboard
652
+ and logs the user out if it was revoked or expired (`revalidate` prop, default
653
+ `"always"`; set `"never"` to skip). In the browser this runs **non-blocking** in
654
+ the background (fail-open — a transient outage keeps the session); Node scripts
655
+ block on it (see `@renown/sdk`). This does not replace server-side checks: the
656
+ switchboard enforces the credential on every real operation.
657
+
658
+ ### `RenownWalletProvider`
659
+
660
+ Registers the login activator, lazy-mounts the configured adapters, and merges
661
+ them into one controller for `useRenownAuth`. The wallet Provider tree wraps
662
+ only the adapter bridges (each library's modal portals to `<body>`), never your
663
+ `children`, so activating login never remounts your app. Props: `adapters`
664
+ (config), `theme?`, `children`.
665
+
666
+ ### `useRenownLoginMethods(adapters, labels?)`
667
+
668
+ Returns `{ id, label }[]` — one per configured login method (wallet + Privy
669
+ methods, deduped) — reading config only (no wallet libraries load). Override
670
+ labels via the second argument. Wire each to `login(undefined, id)`.
671
+
672
+ ### Testing (mock adapter)
673
+
674
+ For e2e/dev, enable the **mock adapter** (`@renown/sdk/wallet/mock`) via the
675
+ `mock` key. It's a headless signer backed by a viem local account — real EIP-712
676
+ signatures, **no wallet extension or OAuth** — so sign-in runs deterministically
677
+ in CI. **TEST/DEV ONLY; never enable in production** (it signs with a known key).
678
+
679
+ ```tsx
680
+ <RenownWalletProvider adapters={{ mock: { methods: ["wallet", "google", "email"] } }}>
681
+ <App />
682
+ </RenownWalletProvider>
683
+ ```
684
+
685
+ See `test/test-fusion/e2e` (Playwright + mock adapter) and `test/vetra-e2e`
686
+ (Connect login surface) for runnable examples, and the Powerhouse Academy
687
+ "Renown authentication flow" guide for the full walkthrough.
@@ -0,0 +1,14 @@
1
+ import { T as SdkFunctionWrapper, c as ReactorGraphQLClient } from "./types-CVZRGBXo.js";
2
+ import { GraphQLClient } from "graphql-request";
3
+
4
+ //#region src/graphql/client.d.ts
5
+ /**
6
+ * Creates a GraphQL client for the Reactor Subgraph API.
7
+ * @param urlOrGQLClient The URL of the GraphQL API or a GraphQL client instance.
8
+ * @param middleware An optional middleware function to wrap the GraphQL client calls.
9
+ * @returns A GraphQL client for the Reactor Subgraph API.
10
+ */
11
+ declare function createClient(urlOrGQLClient: string | GraphQLClient, middleware?: SdkFunctionWrapper): ReactorGraphQLClient;
12
+ //#endregion
13
+ export { createClient as t };
14
+ //# sourceMappingURL=client-DAJGpNZH.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-DAJGpNZH.d.ts","names":[],"sources":["../src/graphql/client.ts"],"mappings":";;;;AA4BA;;;;;;AAAA,iBAAgB,YAAA,CACd,cAAA,WAAyB,aAAA,EACzB,UAAA,GAAa,kBAAA,GACZ,oBAAA"}
@@ -0,0 +1,144 @@
1
+ import { n as PGliteInterface, r as Results } from "./pglite-CntadC_p-BgIvrYtV.js";
2
+
3
+ //#region ../../node_modules/.pnpm/@electric-sql+pglite@0.3.15/node_modules/@electric-sql/pglite/dist/live/index.d.ts
4
+ interface LiveQueryOptions<T = {
5
+ [key: string]: any;
6
+ }> {
7
+ query: string;
8
+ params?: any[] | null;
9
+ offset?: number;
10
+ limit?: number;
11
+ callback?: (results: Results<T>) => void;
12
+ signal?: AbortSignal;
13
+ }
14
+ interface LiveChangesOptions<T = {
15
+ [key: string]: any;
16
+ }> {
17
+ query: string;
18
+ params?: any[] | null;
19
+ key: string;
20
+ callback?: (changes: Array<Change<T>>) => void;
21
+ signal?: AbortSignal;
22
+ }
23
+ interface LiveIncrementalQueryOptions<T = {
24
+ [key: string]: any;
25
+ }> {
26
+ query: string;
27
+ params?: any[] | null;
28
+ key: string;
29
+ callback?: (results: Results<T>) => void;
30
+ signal?: AbortSignal;
31
+ }
32
+ interface LiveNamespace {
33
+ /**
34
+ * Create a live query
35
+ * @param query - The query to run
36
+ * @param params - The parameters to pass to the query
37
+ * @param callback - A callback to run when the query is updated
38
+ * @returns A promise that resolves to an object with the initial results,
39
+ * an unsubscribe function, and a refresh function
40
+ */
41
+ query<T = {
42
+ [key: string]: any;
43
+ }>(query: string, params?: any[] | null, callback?: (results: Results<T>) => void): Promise<LiveQuery<T>>;
44
+ /**
45
+ * Create a live query
46
+ * @param options - The options to pass to the query
47
+ * @returns A promise that resolves to an object with the initial results,
48
+ * an unsubscribe function, and a refresh function
49
+ */
50
+ query<T = {
51
+ [key: string]: any;
52
+ }>(options: LiveQueryOptions<T>): Promise<LiveQuery<T>>;
53
+ /**
54
+ * Create a live query that returns the changes to the query results
55
+ * @param query - The query to run
56
+ * @param params - The parameters to pass to the query
57
+ * @param callback - A callback to run when the query is updated
58
+ * @returns A promise that resolves to an object with the initial changes,
59
+ * an unsubscribe function, and a refresh function
60
+ */
61
+ changes<T = {
62
+ [key: string]: any;
63
+ }>(query: string, params: any[] | undefined | null, key: string, callback?: (changes: Array<Change<T>>) => void): Promise<LiveChanges<T>>;
64
+ /**
65
+ * Create a live query that returns the changes to the query results
66
+ * @param options - The options to pass to the query
67
+ * @returns A promise that resolves to an object with the initial changes,
68
+ * an unsubscribe function, and a refresh function
69
+ */
70
+ changes<T = {
71
+ [key: string]: any;
72
+ }>(options: LiveChangesOptions<T>): Promise<LiveChanges<T>>;
73
+ /**
74
+ * Create a live query with incremental updates
75
+ * @param query - The query to run
76
+ * @param params - The parameters to pass to the query
77
+ * @param callback - A callback to run when the query is updated
78
+ * @returns A promise that resolves to an object with the initial results,
79
+ * an unsubscribe function, and a refresh function
80
+ */
81
+ incrementalQuery<T = {
82
+ [key: string]: any;
83
+ }>(query: string, params: any[] | undefined | null, key: string, callback?: (results: Results<T>) => void): Promise<LiveQuery<T>>;
84
+ /**
85
+ * Create a live query with incremental updates
86
+ * @param options - The options to pass to the query
87
+ * @returns A promise that resolves to an object with the initial results,
88
+ * an unsubscribe function, and a refresh function
89
+ */
90
+ incrementalQuery<T = {
91
+ [key: string]: any;
92
+ }>(options: LiveIncrementalQueryOptions<T>): Promise<LiveQuery<T>>;
93
+ }
94
+ interface LiveQueryResults<T> extends Results<T> {
95
+ totalCount?: number;
96
+ offset?: number;
97
+ limit?: number;
98
+ }
99
+ interface LiveQuery<T> {
100
+ initialResults: LiveQueryResults<T>;
101
+ subscribe: (callback: (results: LiveQueryResults<T>) => void) => void;
102
+ unsubscribe: (callback?: (results: LiveQueryResults<T>) => void) => Promise<void>;
103
+ refresh: (options?: {
104
+ offset?: number;
105
+ limit?: number;
106
+ }) => Promise<void>;
107
+ }
108
+ interface LiveChanges<T = {
109
+ [key: string]: any;
110
+ }> {
111
+ fields: {
112
+ name: string;
113
+ dataTypeID: number;
114
+ }[];
115
+ initialChanges: Array<Change<T>>;
116
+ subscribe: (callback: (changes: Array<Change<T>>) => void) => void;
117
+ unsubscribe: (callback?: (changes: Array<Change<T>>) => void) => Promise<void>;
118
+ refresh: () => Promise<void>;
119
+ }
120
+ type ChangeInsert<T> = {
121
+ __changed_columns__: string[];
122
+ __op__: 'INSERT';
123
+ __after__: number;
124
+ } & T;
125
+ type ChangeDelete<T> = {
126
+ __changed_columns__: string[];
127
+ __op__: 'DELETE';
128
+ __after__: undefined;
129
+ } & T;
130
+ type ChangeUpdate<T> = {
131
+ __changed_columns__: string[];
132
+ __op__: 'UPDATE';
133
+ __after__: number;
134
+ } & T;
135
+ type ChangeReset<T> = {
136
+ __op__: 'RESET';
137
+ } & T;
138
+ type Change<T> = ChangeInsert<T> | ChangeDelete<T> | ChangeUpdate<T> | ChangeReset<T>;
139
+ type PGliteWithLive = PGliteInterface & {
140
+ live: LiveNamespace;
141
+ };
142
+ //#endregion
143
+ export { LiveQueryResults as n, PGliteWithLive as r, LiveNamespace as t };
144
+ //# sourceMappingURL=index-B3keszpu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-B3keszpu.d.ts","names":["R","Results","d","PGliteInterface","LiveQueryOptions","T","AbortSignal","key","query","params","offset","limit","callback","results","signal","LiveChangesOptions","Change","Array","changes","LiveIncrementalQueryOptions","LiveNamespace","LiveQuery","Promise","LiveChanges","options","incrementalQuery","LiveQueryResults","totalCount","initialResults","subscribe","unsubscribe","refresh","fields","name","dataTypeID","initialChanges","ChangeInsert","__changed_columns__","__op__","__after__","ChangeDelete","ChangeUpdate","ChangeReset","live","setup","pg","_emscriptenOpts","namespaceObj","PGliteWithLive"],"sources":["../../../node_modules/.pnpm/@electric-sql+pglite@0.3.15/node_modules/@electric-sql/pglite/dist/live/index.d.ts"],"x_google_ignoreList":[0],"mappings":"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"}