@edgeandnode/graph-auth-kit 0.2.0

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 (57) hide show
  1. package/README.md +238 -0
  2. package/dist/Components/ConnectModal.d.ts +2 -0
  3. package/dist/Components/ConnectModal.d.ts.map +1 -0
  4. package/dist/Components/ConnectorOption.d.ts +13 -0
  5. package/dist/Components/ConnectorOption.d.ts.map +1 -0
  6. package/dist/Components/MultisigSignerOptions.d.ts +2 -0
  7. package/dist/Components/MultisigSignerOptions.d.ts.map +1 -0
  8. package/dist/Components/PrimaryConnectOptions.d.ts +2 -0
  9. package/dist/Components/PrimaryConnectOptions.d.ts.map +1 -0
  10. package/dist/Components/SafeInputForm.d.ts +2 -0
  11. package/dist/Components/SafeInputForm.d.ts.map +1 -0
  12. package/dist/Components/SafeSelection.d.ts +2 -0
  13. package/dist/Components/SafeSelection.d.ts.map +1 -0
  14. package/dist/GraphAuthKit.context-DBwb2jco.js +936 -0
  15. package/dist/GraphAuthKit.context.d.ts +80 -0
  16. package/dist/GraphAuthKit.context.d.ts.map +1 -0
  17. package/dist/GraphAuthKitInner.context.d.ts +109 -0
  18. package/dist/GraphAuthKitInner.context.d.ts.map +1 -0
  19. package/dist/client.d.ts +8612 -0
  20. package/dist/client.d.ts.map +1 -0
  21. package/dist/constants.d.ts +329 -0
  22. package/dist/constants.d.ts.map +1 -0
  23. package/dist/errors.d.ts +21 -0
  24. package/dist/errors.d.ts.map +1 -0
  25. package/dist/hooks.d.ts +74 -0
  26. package/dist/hooks.d.ts.map +1 -0
  27. package/dist/index.d.ts +8 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +442 -0
  30. package/dist/safe/SafeEthersSigner.d.ts +37 -0
  31. package/dist/safe/SafeEthersSigner.d.ts.map +1 -0
  32. package/dist/safe/SafeMinimal.abi.d.ts +80 -0
  33. package/dist/safe/SafeMinimal.abi.d.ts.map +1 -0
  34. package/dist/safe/constants.d.ts +26 -0
  35. package/dist/safe/constants.d.ts.map +1 -0
  36. package/dist/safe/index.d.ts +3 -0
  37. package/dist/safe/index.d.ts.map +1 -0
  38. package/dist/safe/index.js +11 -0
  39. package/dist/safe/safeViemActions.d.ts +4 -0
  40. package/dist/safe/safeViemActions.d.ts.map +1 -0
  41. package/dist/safe/utils.d.ts +38 -0
  42. package/dist/safe/utils.d.ts.map +1 -0
  43. package/dist/safe/utils.test.d.ts +2 -0
  44. package/dist/safe/utils.test.d.ts.map +1 -0
  45. package/dist/test-harness/MockGraphAuthKit.context.d.ts +102 -0
  46. package/dist/test-harness/MockGraphAuthKit.context.d.ts.map +1 -0
  47. package/dist/test-harness/index.d.ts +2 -0
  48. package/dist/test-harness/index.d.ts.map +1 -0
  49. package/dist/test-harness/index.js +63 -0
  50. package/dist/types.d.ts +54 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/utils-KuRu9vB-.js +218 -0
  53. package/dist/utils.d.ts +18 -0
  54. package/dist/utils.d.ts.map +1 -0
  55. package/dist/utils.test.d.ts +2 -0
  56. package/dist/utils.test.d.ts.map +1 -0
  57. package/package.json +93 -0
package/README.md ADDED
@@ -0,0 +1,238 @@
1
+ # @edgeandnode/graph-auth-kit
2
+
3
+ Authentication Kit for connecting The Graph apps/dapps to a wallet.
4
+
5
+ Relies on/requires [`wagmi`](https://wagmi.sh/) + [`viem`](https://viem.sh/) for allowing users to connect their wallets and interact with the connected auth state context.
6
+
7
+ Exposes a simple `useGraphAuthKit` hook that lets the app open the connect modal, letting users connect to their wallet of choice (one of: injected/MetaMask, coinbase, WalletConnect, Safe). See integration example below.
8
+
9
+ ## Install
10
+
11
+ Currently, `graph-auth-kit` has a lot of peer deps needed to interact with the library. But this may change after testing. At the very least, `wagmi, viem, @tanstack/react-query` will be needed.
12
+
13
+ ```bash
14
+ # with bun
15
+ bun add @edgeandnode/graph-auth-kit \
16
+ @edgeandnode/common \
17
+ @edgeandnode/gds \
18
+ @edgeandnode/go \
19
+ @emotion/react \
20
+ @safe-global/api-kit \
21
+ @safe-global/protocol-kit \
22
+ @safe-global/safe-core-sdk-types \
23
+ @tanstack/react-query \
24
+ cookies-next \
25
+ ethers@5.7.2 \
26
+ theme-ui \
27
+ viem@2.x \
28
+ wagmi
29
+
30
+ # with pnpm
31
+ pnpm add @edgeandnode/graph-auth-kit \
32
+ @edgeandnode/common \
33
+ @edgeandnode/gds \
34
+ @edgeandnode/go \
35
+ @emotion/react \
36
+ @safe-global/api-kit \
37
+ @safe-global/protocol-kit \
38
+ @safe-global/safe-core-sdk-types \
39
+ @tanstack/react-query \
40
+ cookies-next \
41
+ ethers@5.7.2 \
42
+ theme-ui \
43
+ viem@2.x \
44
+ wagmi
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ Properties:
50
+
51
+ - `queryClient` -> [OPTIONAL]. The `GraphAuthKitProvider` renders a `QueryClientProvider` instance. Pass in an instantiated `QueryClient` to use, otherwise, `GraphAuthKit` will instantiate its own.
52
+ - `initialStateCookie` -> [OPTIONAL] wagmi auth state cookie. passed to the `GraphAuthKitProvider` -> `WagmiProvider`
53
+ - we use the exported `AUTH_STORAGE_KEY` from `@edgeandnode/graph-auth-kit` for our wagmi cookie storage.
54
+ - `infuraKey` -> [REQUIRED]
55
+ - `walletConnectProjectID` -> [REQUIRED]
56
+ - `meta` -> [REQUIRED]. information about the app using the lib
57
+ - `meta.name` -> [REQUIRED]. either `Graph Explorer` or `Subgraph Studio`
58
+ - `meta.url` -> the app URL.
59
+ - defaults to: https://thegraph.com/explorer or https://thegraph.com/studio
60
+ - replace with local, staging, dev/testnet as needed
61
+ - `chains` -> the allowed chains/networks for the given app. default is `ALL`
62
+ - `ALL` allowed to connect to: L2 Mainnet (arbitrum-one), L2 Testnet (arbitrum-sepolia), L1 Mainnet (ethereum), L1 Testnet (sepolia)
63
+ - `MAINNET` -> only allowed to connect to L2 Mainnet and L1 Mainnet
64
+ - `TESTNET` -> only allowed to connect to L2 Testnet and L1 Testnet
65
+
66
+ ### Example
67
+
68
+ - Setup the `GraphAuthKitProvider`.
69
+ - **Note** you do not need to add the `ConnectModal` component, the `GraphAuthKitProvider` renders it for us
70
+ - **Note** you do not need to add the `QueryClientProvider` as `GraphAuthKitProvider` instantiates and renders it
71
+ - you can pass a `QueryClient` instance to the `GraphAuthKitProvider`, otherwise, it will instantiate its own
72
+
73
+ ```tsx
74
+ // _app.tsx
75
+
76
+ import { QueryClient } from '@tanstack/react-query'
77
+ import { getCookie } from 'cookies-next'
78
+ import { AppProps } from 'next'
79
+ import { useRef } from 'react'
80
+
81
+ import { AnalyticsProvider, GDSProvider } from '@edgeandnode/gds'
82
+ import { AUTH_STORAGE_KEY, GraphAuthKitProvider } from '@edgeandnode/graph-auth-kit'
83
+
84
+ import { FutureNextLink } from '../components/FutureNextLink'
85
+ import { Layout } from '../components/Layout'
86
+
87
+ const infuraKey = process.env.INFURA_KEY!
88
+ const walletConnectProjectID = process.env.WALLETCONNECT_PROJECT_ID!
89
+
90
+ import '@edgeandnode/gds/style.css'
91
+ import '../app.css'
92
+
93
+ export default function App({ Component, router, pageProps }: AppProps) {
94
+ const queryClient = useRef<QueryClient>()
95
+ if (!queryClient.current) {
96
+ queryClient.current = new QueryClient({
97
+ defaultOptions: {
98
+ queries: {
99
+ // With SSR, we usually want to set some default staleTime
100
+ // above 0 to avoid refetching immediately on the client
101
+ staleTime: 60 * 1000,
102
+ },
103
+ },
104
+ })
105
+ }
106
+ const cookies = getCookies()
107
+ const initialStateCookie =
108
+ // The nextjs pages router does not make it trivial to retrieve the cookies (app router does though).
109
+ // But, `getServerSideProps` _can_ be used to retrieve the cookies from the request headers,
110
+ // and then passed down as props, which would be available here as `pageProps.cookies`.
111
+ // Otherwise, can parse the cookies uing `getCookies`.
112
+ pageProps.cookies ||
113
+ Object.entries(cookies)
114
+ .filter(([key]) => key.toLowerCase().startsWith(AUTH_STORAGE_KEY.toLowerCase()))
115
+ .reduce<string>(
116
+ (accum, [key, val], idx) => (val == null ? accum : idx === 0 ? `${key}=${val}` : `${accum}; ${key}=${val}`),
117
+ '',
118
+ )
119
+
120
+ return (
121
+ <GDSProvider clientRouter={router} clientLink={FutureNextLink} useLegacyTheme>
122
+ <AnalyticsProvider
123
+ app="EXPLORER"
124
+ clientRouter={router}
125
+ mixpanel={{
126
+ sdk: mixpanel,
127
+ token: process.env.MIXPANEL_TOKEN ?? null,
128
+ }}
129
+ googleAnalytics={{
130
+ sdk: googleAnalytics,
131
+ measurementId: process.env.GOOGLE_ANALYTICS_MEASUREMENT_ID ?? null,
132
+ }}
133
+ >
134
+ <GraphAuthKitProvider
135
+ queryClient={queryClient.current}
136
+ initialStateCookie={initialStateCookie}
137
+ infuraKey={infuraKey}
138
+ walletConnectProjectID={walletConnectProjectID}
139
+ meta={{
140
+ name: 'Graph Explorer',
141
+ url: 'https://thegraph.com/explorer',
142
+ }}
143
+ chains="MAINNET"
144
+ >
145
+ <Layout>
146
+ <DefaultSeo {...defaultSEO} />
147
+ <Component {...pageProps} />
148
+ </Layout>
149
+ <ReactQueryDevtools initialIsOpen={false} />
150
+ </GraphAuthKitProvider>
151
+ </AnalyticsProvider>
152
+ </GDSProvider>
153
+ )
154
+ }
155
+ ```
156
+
157
+ - Usage in a component
158
+
159
+ ```tsx
160
+ // components/Layout.tsx
161
+
162
+ import { ReactNode } from 'react'
163
+ import { useAccountEffect, useEnsName } from 'wagmi'
164
+
165
+ import { Layout as GDSLayout, UserProfile } from '@edgeandnode/gds'
166
+ import { GlobalFooter, GlobalHeader, NPSForm } from '@edgeandnode/go'
167
+ import { L1Chain, useGraphAuthKitConnector, useGraphAuthKit, useGraphAuthKitAccount } from '@edgeandnode/graph-auth-kit/hooks'
168
+
169
+ import { NavDropDownMenu } from './NavDropDownMenu'
170
+
171
+ export function Layout({ children }: Readonly<{ children: ReactNode }>) {
172
+ const authkit = useGraphAuthKit()
173
+ const { address } = useGraphAuthKitAccount()
174
+ const { data: ens } = useEnsName({ address, blockTag: 'latest', chainId: L1Chain.id })
175
+ const connector = useGraphAuthKitConnector()
176
+
177
+ const walletConnected = Boolean(address)
178
+
179
+ useAccountEffect({
180
+ onConnect(data) {
181
+ console.log('user connected wallet', {data})
182
+ },
183
+ onDisconnect() {
184
+ console.log('user disconnected wallet')
185
+ },
186
+ })
187
+
188
+ return (
189
+ <GDSLayout
190
+ header={
191
+ <GlobalHeader
192
+ activeProduct="EXPLORER"
193
+ basePath="/explorer"
194
+ showSupportButton={walletConnected}
195
+ rigtContent={(defaultContent) => (
196
+ <>
197
+ {!walletConnected ?
198
+ <GlobalHeader.ConnectButton onClick={() => authkit.openConnectModal()} />
199
+ ) : (
200
+ <UserProfile
201
+ ethereumAccount={address}
202
+ graphAccount={...}
203
+ ens={ens}
204
+ profileUrl={`/profile/${address}?view=Overview`}
205
+ profileUrlAs={`/profile/${address}?view=Overview`}
206
+ onConnect={() => authkit.openConnectModal()}
207
+ onDisconnect={() => authkit.disconnect()}
208
+ userDropDownMenu={<NavDropDownMenu />}
209
+ accountTag={connector === 'safe' ? 'multisig' : undefined}
210
+ />
211
+ )}
212
+ </>
213
+ )}
214
+ />
215
+ }
216
+ footer={
217
+ <>
218
+ <NPSForm sx={{ mb: Spacing['64px'] }} />
219
+ <GlobalFooter />
220
+ </>
221
+ }
222
+ >
223
+ {children}
224
+ </GDSLayout>
225
+ )
226
+ }
227
+ ```
228
+
229
+ ## Hooks
230
+
231
+ - `useGraphAuthKitAccount` -> This is an override of the [wagmi useAccount hook](https://wagmi.sh/react/api/hooks/useAccount). The reason is, if the user connects with a multisig, the wagmi context is connected with the user-selected EoA, so all of the wagmi context hooks reference this EoA and not the Safe. This returns the wagmi `UseAccountReturnType` but the `address` and `addresses` values include the entered Safe address. It also adds an `eoa` property that is the connected EoA address.
232
+ - `useGraphAuthKitConnector` -> The user selected wallet/connector option.
233
+
234
+ ## References
235
+
236
+ - [`wagmi`](https://wagmi.sh/)
237
+ - [`viem`](https://viem.sh/)
238
+ - [Engineering Plan](https://www.notion.so/edgeandnode/Replace-Wallet-Connection-Library-0e4c5e1e015b428dbb52b1f627b712f0)
@@ -0,0 +1,2 @@
1
+ export declare function ConnectModal(): import("react").JSX.Element;
2
+ //# sourceMappingURL=ConnectModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConnectModal.d.ts","sourceRoot":"","sources":["../../src/Components/ConnectModal.tsx"],"names":[],"mappings":"AAQA,wBAAgB,YAAY,gCAsC3B"}
@@ -0,0 +1,13 @@
1
+ import { type ElementType, type ReactNode } from 'react';
2
+ import { type GraphAuthKitConnector } from '../types';
3
+ export type ConnectorOptionProps = {
4
+ connector: GraphAuthKitConnector;
5
+ title: ReactNode;
6
+ selected?: boolean;
7
+ disabled?: boolean;
8
+ description?: ReactNode;
9
+ Image: ElementType;
10
+ onClick(): void;
11
+ };
12
+ export declare function ConnectorOption(props: ConnectorOptionProps): import("react").JSX.Element;
13
+ //# sourceMappingURL=ConnectorOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConnectorOption.d.ts","sourceRoot":"","sources":["../../src/Components/ConnectorOption.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAExD,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAErD,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,qBAAqB,CAAA;IAChC,KAAK,EAAE,SAAS,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,KAAK,EAAE,WAAW,CAAA;IAClB,OAAO,IAAI,IAAI,CAAA;CAChB,CAAA;AACD,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,+BAqB1D"}
@@ -0,0 +1,2 @@
1
+ export declare function MultisigSignerOptions(): import("react").JSX.Element;
2
+ //# sourceMappingURL=MultisigSignerOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultisigSignerOptions.d.ts","sourceRoot":"","sources":["../../src/Components/MultisigSignerOptions.tsx"],"names":[],"mappings":"AA8BA,wBAAgB,qBAAqB,gCAuHpC"}
@@ -0,0 +1,2 @@
1
+ export declare function PrimaryConnectOptions(): import("react").JSX.Element;
2
+ //# sourceMappingURL=PrimaryConnectOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PrimaryConnectOptions.d.ts","sourceRoot":"","sources":["../../src/Components/PrimaryConnectOptions.tsx"],"names":[],"mappings":"AAgCA,wBAAgB,qBAAqB,gCAiDpC"}
@@ -0,0 +1,2 @@
1
+ export declare function SafeInputForm(): import("react").JSX.Element;
2
+ //# sourceMappingURL=SafeInputForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SafeInputForm.d.ts","sourceRoot":"","sources":["../../src/Components/SafeInputForm.tsx"],"names":[],"mappings":"AAyEA,wBAAgB,aAAa,gCA2L5B"}
@@ -0,0 +1,2 @@
1
+ export declare function SafeSelection(): import("react").JSX.Element;
2
+ //# sourceMappingURL=SafeSelection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SafeSelection.d.ts","sourceRoot":"","sources":["../../src/Components/SafeSelection.tsx"],"names":[],"mappings":"AAkBA,wBAAgB,aAAa,gCA+F5B"}