Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@edgeandnode/graph-auth-kit

Package Overview
Dependencies
Maintainers
0
Versions
294
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@edgeandnode/graph-auth-kit

Wallet authentication connect kit in The Graph suite of applications

  • 0.4.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
1.2K
increased by17.11%
Maintainers
0
Weekly downloads
 
Created
Source

@edgeandnode/graph-auth-kit

Authentication Kit for connecting The Graph apps/dapps to a wallet.

Relies on/requires wagmi + viem for allowing users to connect their wallets and interact with the connected auth state context.

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.

Install

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.

# with bun
bun add @edgeandnode/graph-auth-kit \
  @edgeandnode/common \
  @edgeandnode/gds \
  @edgeandnode/go \
  @emotion/react \
  @safe-global/api-kit \
  @safe-global/protocol-kit \
  @safe-global/safe-core-sdk-types \
  @tanstack/react-query \
  cookies-next \
  ethers@5.7.2 \
  theme-ui \
  viem@2.x \
  wagmi

# with pnpm
pnpm add @edgeandnode/graph-auth-kit \
  @edgeandnode/common \
  @edgeandnode/gds \
  @edgeandnode/go \
  @emotion/react \
  @safe-global/api-kit \
  @safe-global/protocol-kit \
  @safe-global/safe-core-sdk-types \
  @tanstack/react-query \
  cookies-next \
  ethers@5.7.2 \
  theme-ui \
  viem@2.x \
  wagmi

Usage

Properties:

  • queryClient -> [OPTIONAL]. The GraphAuthKitProvider renders a QueryClientProvider instance. Pass in an instantiated QueryClient to use, otherwise, GraphAuthKit will instantiate its own.
  • initialStateCookie -> [OPTIONAL] wagmi auth state cookie. passed to the GraphAuthKitProvider -> WagmiProvider
    • we use the exported AUTH_STORAGE_KEY from @edgeandnode/graph-auth-kit for our wagmi cookie storage.
  • infuraKey -> [REQUIRED]
  • walletConnectProjectID -> [REQUIRED]
  • meta -> [REQUIRED]. information about the app using the lib
  • chains -> the allowed chains/networks for the given app. default is ALL
    • ALL allowed to connect to: L2 Mainnet (arbitrum-one), L2 Testnet (arbitrum-sepolia), L1 Mainnet (ethereum), L1 Testnet (sepolia)
    • MAINNET -> only allowed to connect to L2 Mainnet and L1 Mainnet
    • TESTNET -> only allowed to connect to L2 Testnet and L1 Testnet

Example

  • Setup the GraphAuthKitProvider.
    • Note you do not need to add the ConnectModal component, the GraphAuthKitProvider renders it for us
    • Note you do not need to add the QueryClientProvider as GraphAuthKitProvider instantiates and renders it
      • you can pass a QueryClient instance to the GraphAuthKitProvider, otherwise, it will instantiate its own
// _app.tsx

import { QueryClient } from '@tanstack/react-query'
import { getCookie } from 'cookies-next'
import { AppProps } from 'next'
import { useRef } from 'react'

import { AnalyticsProvider, GDSProvider } from '@edgeandnode/gds'
import { AUTH_STORAGE_KEY, GraphAuthKitProvider } from '@edgeandnode/graph-auth-kit'

import { FutureNextLink } from '../components/FutureNextLink'
import { Layout } from '../components/Layout'

const infuraKey = process.env.INFURA_KEY!
const walletConnectProjectID = process.env.WALLETCONNECT_PROJECT_ID!

import '@edgeandnode/gds/style.css'
import '../app.css'

export default function App({ Component, router, pageProps }: AppProps) {
  const queryClient = useRef<QueryClient>()
  if (!queryClient.current) {
    queryClient.current = new QueryClient({
      defaultOptions: {
        queries: {
          // With SSR, we usually want to set some default staleTime
          // above 0 to avoid refetching immediately on the client
          staleTime: 60 * 1000,
        },
      },
    })
  }
  const cookies = getCookies()
  const initialStateCookie =
    // The nextjs pages router does not make it trivial to retrieve the cookies (app router does though).
    // But, `getServerSideProps` _can_ be used to retrieve the cookies from the request headers,
    // and then passed down as props, which would be available here as `pageProps.cookies`.
    // Otherwise, can parse the cookies uing `getCookies`.
    pageProps.cookies ||
    Object.entries(cookies)
      .filter(([key]) => key.toLowerCase().startsWith(AUTH_STORAGE_KEY.toLowerCase()))
      .reduce<string>(
        (accum, [key, val], idx) => (val == null ? accum : idx === 0 ? `${key}=${val}` : `${accum}; ${key}=${val}`),
        '',
      )

  return (
    <GDSProvider clientRouter={router} clientLink={FutureNextLink} useLegacyTheme>
      <AnalyticsProvider
        app="EXPLORER"
        clientRouter={router}
        mixpanel={{
          sdk: mixpanel,
          token: process.env.MIXPANEL_TOKEN ?? null,
        }}
        googleAnalytics={{
          sdk: googleAnalytics,
          measurementId: process.env.GOOGLE_ANALYTICS_MEASUREMENT_ID ?? null,
        }}
      >
        <GraphAuthKitProvider
          queryClient={queryClient.current}
          initialStateCookie={initialStateCookie}
          infuraKey={infuraKey}
          walletConnectProjectID={walletConnectProjectID}
          meta={{
            name: 'Graph Explorer',
            url: 'https://thegraph.com/explorer',
          }}
          chains="MAINNET"
        >
          <Layout>
            <DefaultSeo {...defaultSEO} />
            <Component {...pageProps} />
          </Layout>
          <ReactQueryDevtools initialIsOpen={false} />
        </GraphAuthKitProvider>
      </AnalyticsProvider>
    </GDSProvider>
  )
}
  • Usage in a component
// components/Layout.tsx

import { ReactNode } from 'react'
import { useAccountEffect, useEnsName } from 'wagmi'

import { Layout as GDSLayout, UserProfile } from '@edgeandnode/gds'
import { GlobalFooter, GlobalHeader, NPSForm } from '@edgeandnode/go'
import { L1Chain, useGraphAuthKitConnector, useGraphAuthKit, useGraphAuthKitAccount } from '@edgeandnode/graph-auth-kit/hooks'

import { NavDropDownMenu } from './NavDropDownMenu'

export function Layout({ children }: Readonly<{ children: ReactNode }>) {
  const authkit = useGraphAuthKit()
  const { address } = useGraphAuthKitAccount()
  const { data: ens } = useEnsName({ address, blockTag: 'latest', chainId: L1Chain.id })
  const connector = useGraphAuthKitConnector()

  const walletConnected = Boolean(address)

  useAccountEffect({
    onConnect(data) {
      console.log('user connected wallet', {data})
    },
    onDisconnect() {
      console.log('user disconnected wallet')
    },
  })

  return (
    <GDSLayout
      header={
        <GlobalHeader
          activeProduct="EXPLORER"
          basePath="/explorer"
          showSupportButton={walletConnected}
          rigtContent={(defaultContent) => (
            <>
              {!walletConnected ?
                <GlobalHeader.ConnectButton onClick={() => authkit.openConnectModal()} />
              ) : (
                <UserProfile
                  ethereumAccount={address}
                  graphAccount={...}
                  ens={ens}
                  profileUrl={`/profile/${address}?view=Overview`}
                  profileUrlAs={`/profile/${address}?view=Overview`}
                  onConnect={() => authkit.openConnectModal()}
                  onDisconnect={() => authkit.disconnect()}
                  userDropDownMenu={<NavDropDownMenu />}
                  accountTag={connector === 'safe' ? 'multisig' : undefined}
                />
              )}
            </>
          )}
        />
      }
      footer={
        <>
          <NPSForm sx={{ mb: Spacing['64px'] }} />
          <GlobalFooter />
        </>
      }
    >
      {children}
    </GDSLayout>
  )
}

Hooks

  • useGraphAuthKitAccount -> This is an override of the wagmi useAccount hook. 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.
  • useGraphAuthKitConnector -> The user selected wallet/connector option.

Components

  • Connected -> renders the passed in children only if the user is connected.
import { Connected } from '@edgeandnode/graph-auth-kit'

export function ShowMeConnected() {
  return <Connected>{(account) => <div>Connected Wallet: {account.address}</div>}</Connected>
}
  • Disconnected -> renders the passed in children only if the user id disconnected. Useful for rendering components like a "Connect Wallet" CTA that should only render if the user is not authenticated.
import { ExperimentalButton as Button } from '@edgeandnode/gds'
import { Disconnected, useGraphAuthKit } from '@edgeandnode/graph-auth-kit'

export function ShowMeDisconnected() {
  const authkit = useGraphAuthKit()

  return (
    <Disconnected>
      <Button variant="primary" onClick={() => authkit.openConnectModal()}>
        Connect Wallet
      </Button>
    </Disconnected>
  )
}

References

FAQs

Package last updated on 13 Aug 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc