npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@past3lle/web3-modal

v2.3.2

Published

PAST3LLE's Web3 connection modal

Downloads

2,700

Readme

Web3 Modal

Example implementation

Feel free to split the files how you'd like, but here's the way we do it in our own apps.

1: Create a theme.ts file

Create a new modal theme via the createTheme helper function:

import { createTheme } from '@past3lle/web3-modal'

export const PALETTE = {
  mainBg: 'rgb(21, 142, 155)',
  mainBgOpaque: '#148f9cad',
  blackOpaque1: 'rgba(0, 0, 0, 0.88)',
  blackOpaque3: '#00000042',
  text: 'ghostwhite',
  textInverse: 'black'
}
const modalTheme = createTheme({
  DEFAULT: {
    modals: {
      connection: {
        backgroundImg: 'SOME_IMAGE_URL',
        title: {
          color: PALETTE.text
        },
        button: {
          backgroundColor: PALETTE.mainBgOpaque,
          fontWeight: 600,
          letterSpacing: '-1.7px',
          fontStyle: 'normal',
          textShadow: '3px 2px 2px #00000078'
        }
      }
    }
  }
})

export default modalTheme

2: Create a config.ts file

import { PstlWeb3ModalProps, addConnector } from '@past3lle/web3-modal'
import { mainnet } from '@wagmi/chains'
import modalTheme, { PALETTE } from 'theme'

import { LedgerConnector } from 'wagmi/connectors/ledger'
import { LedgerHIDConnector } from '@past3lle/wagmi-connectors'

// Ranks wallet connectors on modal (higher number = higher in modal list)
enum WalletRank {
  'ledger' = 10,
  'walletConnect' = 2,
  'web3auth' = 1,
  'injected' = 0
}

// Z index for 
enum ZIndices {
  BASE = 500,
  W3M = 600,
  W3A = 700
}

// app accepted chains
// import from wagmi (see above)
const chains = [mainnet]
// cloud.walletconnect.com
const WALLETCONNECT_PROJECT_ID = 'WALLETCONNECT_PROJECT_ID'
// dashboard.web3auth.io
const WEB3AUTH_PROJECT_ID = 'WEB3AUTH_PROJECT_ID'

const config = {
  appName: 'Test App',
  chains,
  connectors: [
      // Adds LedgerHID connector
      addConnector(LedgerHIDConnector, {}),
      // Adds LedgerLive modal connector
      addConnector(LedgerConnector, { 
        projectId: WALLETCONNECT_PROJECT_ID, 
        walletConnectVersion: 2 
      }),
      // Adds MetaMask injected connector
      addConnector(InjectedConnector, {
        name: 'MetaMask',
        shimDisconnect: true,
        getProvider() {
          try {
            // You may need to (window as any)?.ethereum? ...
            // Or create a declarations.d.ts file in your /src/ root
            const provider = window?.ethereum?.providers?.find((provider) => provider?.isMetaMask)
            if (!provider) devWarn('Connector', this.name || 'unknown', 'not found!')
            return provider
          } catch (error) {
            return undefined
          }
        }
      }),
  ],
  options: {
    // How often to poll for new data
    pollingInterval: 20_000,
    // If you want to try and load chain/network data from URL
    // WARNING: this can be unreliable depending on the base app's existing URL logic
    chainFromUrlOptions: { 
      // Type: 'network' | 'chain' (network == name of network & chain == chainId)
      type: 'network', 
      // URL key to look for
      // e.g { type: 'network', key: 'web3-network' } ==> https://your-dapp-url.io/?web3-network=goerli
      // e.g { type: 'chain', key: 'web3-chain' } ==> https://your-dapp-url.io/?web3-chain=5
      key: 'web3-modal-network' 
    },
  },
  // frameConnectors : [], <-- Connectors to use ONLY in iFrame Dapp browsers (e.g LedgerLive)
  // Defaults to IFrameEthereum connector in iFrame mode so there is likely nothing you need to add here
  modals: { 
    root: {
      // Auto detect connection and close modal
      closeModalOnConnect: true,
      // Base z-index of root modal. Should be lowest in the hierarchy of modals, but higher than your lower app
      zIndex: ZIndices.BASE,
      title: 'TITLE HERE',
      // Create a theme object via the aptly named, `createTheme` function
      themeConfig: {
        theme: modalTheme
      },
      // Hide (non-specified) injected wallets from modal
      // E.g you add MetaMask in the connectors prop above but don't want detection for Taho if user has it
      hideInjectedFromRoot: true,
      // Key/value pair of connector UI overrides
      connectorDisplayOverrides: {
        ledger: {
          logo:
            'https://play-lh.googleusercontent.com/mHjR3KaAMw3RGA15-t8gXNAy_Onr4ZYUQ07Z9fG2vd51IXO5rd7wtdqEWbNMPTgdqrk',
          customName: 'LEDGER LIVE',
          infoText: {
            title: 'What is this option?',
            content: 'Choose this to connect with your Ledger hardware wallet via the LedgerLive desktop app!'
          },
          rank: WalletRank['ledger']
        },
        metamask: {
          logo: 'https://metamask-logo.io',
          customName: 'Annoying FOX provider',
          rank: 100,
          // Optional. Open a new tab to this URL if provider/connector not injected/found.
          downloadUrl: 'https://metamask.io/download/'
        }
      }
    },
    // Web3Auth is built in. Leave this undefined (or empty) to not include as a connector/provider
    web3auth: {
      appName: 'Test App',
      projectId: WEB3AUTH_PROJECT_ID,
      network: 'testnet',
      preset: 'DISALLOW_EXTERNAL_WALLETS'
    },
    // WalletConnect Web3Modal props.
    walletConnect: {
      // test id, don't use in prod!
      projectId: WALLETCONNECT_PROJECT_ID,
      zIndex: 1000,
      themeMode: 'dark',
      themeVariables: {
        '--w3m-overlay-background-color': PALETTE.blackOpaque3,
        '--w3m-background-color': PALETTE.mainBg,
        '--w3m-background-image-url': 'SOME_OTHER_BACKGROUND_LOGO.png',
        '--w3m-accent-color': PALETTE.mainBg,
        '--w3m-color-bg-1': PALETTE.blackOpaque1
      }
    }
  }
} as PstlWeb3ModalProps<number>

export default config

3: Add to app somewhere (like App.tsx, for example)

import PSTL_MODAL_CONFIG from './config'
import { PstlW3Providers, usePstlConnection } from '@past3lle/web3-modal'

export default function App() {
  return (
    <PstlW3Providers config={PSTL_MODAL_CONFIG}>
      <InnerApp />
    </PstlW3Providers>
  )
}

Modal Props

// Required. App name registered to providers.
appName: string
// Required. App chains. Import them from "@wagmi/chains" or "wagmi/chains" or "viem"
chains: Chain[]
// Optional. Array of connectors creator functions to add. E.g LedgerConnector as shown in the example implementation.
connectors?: ((chains: Chain[]) => Connector<any, any>)[] // Default: undefined
options?: {
  // Optional. Options for getting the chain info from URL.
  // type: 'network' expects url schema: "someUrl.com/?network=goerli
  // type: 'id' expects url schema: "someUrl.com/?id=5
  chainFromUrlOptions?: { key: string; type: 'network' | 'id' }
  // Optional. Polling interval in milliseconds.
  pollingInterval?: number // Default: 4000 (4s)
  // Optional. Reconnects last connected provider on reload.
  autoConnect?: boolean // Default: false
}
// Optional. Advanced. 
// WagmiClient props. 
// We recommended NOT changing/adding anything here and letting the app handle this.
// If you need more options, use the root.options prop (see above)
wagmiClient?: {
    // Optional. Client is automatically created for you if left undefined here.
    // We recommend not passing a client here and letting the app create one for you.
    client?: WagmiClient
    // Optional. Wagmi creation options. Using the root "options" prop WILL OVERRIDE props of the same name.
    options?: {
        // Optional. Array of publicClient objects in order of importance (lower index = higher importance)
        // Clients are normally created via Wagmi's configureChains function
        publicClients?: (typeof publicProvider)[]
        // Optional. Array of connectors to add. E.g LedgerConnector as shown in the example implementation.
        connectors?: Connector<any, any>[] // Default: undefined
        // Optional. Polling interval in milliseconds.
        pollingInterval?: number // Default: 4000 (4s)
        // Optional. Reconnects last connected provider on reload.
        autoConnect?: boolean // Default: false
    }
}
// Optional. Advanced.
// Ethereum client props.
// If blank, app handles creation of Ethereum client.
// We recommend NOT passing your own and letting the app handle this.
ethereumClient?: EthereumClient
modals: {
    root?: {
        // Optional. Modal title.
        title?: string // Default: "WALLET CONNECTION"
        // Optional. Base modal z-index value.
        zIndex?: number // Default: 999
        // Optional.
        themeConfig?: {
            // Optional. Modal theme; return value from constructing a modal theme via fn createTheme(...)
            theme: ReturnType<typeof createTheme>
            // Optional. Pass outer theme from upper level of surrounding app to sync theme modes
            mode?: 'DEFAULT' | 'DARK' | 'LIGHT' | string
        }
        // Optional. Displays modal in a grid or list view.
        walletView?: 'list' | 'grid' // Default: 'list'
        // Optional. Web3Auth modal loading props.
        loaderProps?: LoadingScreenProps
        // Optional. Base modal button style props.
        buttonProps?: ButtonProps
        // Optional. Auto close modal on successful connector connect?
        closeModalOnConnect?: boolean
        // Optional. Hide injected wallets from root modal, useful when using Web3Modal
        // and you only want to show the Web3Modal connect button
        hideInjectedFromRoot?: boolean
        // Optional. Map of connector.id keys to visual extras
        connectorDisplayOverrides?: { 
            [connectorId: string]: {
                // Optional. Custom name to display on modal
                customName?: string // Default: undefined
                // Optional. Custom logo image to display on modal
                logo?: string // Default: undefined
                // Optional. 
                details?: string // Default: undefined
                // Optional. If defined, renders a dropdown-able text to describe connector
                infoText?: InfoTextMap // Default: undefined
                // Optional. If true, adds label on connector to flag that it is recommended
                isRecommended?: boolean // Default: false
                // Optional. Connector rank for sorting order in modal
                // e.g rank 20 will be above a rank 10 connector and be displayed before
                rank?: number // Default: 0
            }
        }
        // Optional.
        tabIndex?: 0 | -1
        // Optional.
        minHeight?: string
        // Optional.
        maxHeight?: string // Default: "600px"
        // Optional.
        maxWidth?: string // Default: "360px"
        // Optional.
        margin?: string // Default: "0px"
        // Optional. 
        initialFocusRef?: React.RefObject<any>
        // Optional.
        className?: string
        // Optional. React children to render inside Modal
        children?: React.ReactNode
    }
    // Optional. Omit to remove Web3Auth connector
    web3auth: {
        // Required. Web3Auth app name
        appName: string
        // Required. Web3Auth projectId from https://dashboard.web3auth.io
        projectId: WEB3AUTH_PROJECT_ID
        // Required. Web3Auth network.
        network: "mainnet" | "cyan" | "development" | "aqua"
        // Optional. Preset settings
        // "DISALLOW_EXTERNAL_WALLETS" = don't show external wallets
        // "ALLOW_EXTERNAL_WALLETS" = show external wallets to connect to (e.g injected)
        preset?: 'DISALLOW_EXTERNAL_WALLETS' | 'ALLOW_EXTERNAL_WALLETS' // Default: undefined
        // Optional. Storage save type: 'session' or 'local'
        storageKey?:'session' | 'local' // Default: 'local'
        // Optional. MFA level for web3auth
        mfaLevel?: 'default' | 'optional' | 'mandatory' | 'none' // Default: 'optional'
        // Optional. Web3Auth uxmode
        uxMode?: 'redirect' | 'popup' // Default: 'popup'
        // Optional. Configure function for adding connectors into web3auth.
        configureAdditionalConnectors?: (() => IPlugin[] | undefined) // Default: undefined
    }
    // WalletConnect -> Web3Modal props
    walletConnect: {
        // WalletConnect projectId. Get yours at https://cloud.walletconnect.com
        projectId: string
        // Optional. WalletConnect modal z-index.
        zIndex?: number // Default: 1000
        // Optional. Overridable WalletConnect modal theme variables.
        themeVariables?: {
            '--w3m-z-index'?: string;
            '--w3m-accent-color'?: string;
            '--w3m-accent-fill-color'?: string;
            '--w3m-background-color'?: string;
            '--w3m-background-image-url'?: string;
            '--w3m-logo-image-url'?: string;
            '--w3m-background-border-radius'?: string;
            '--w3m-container-border-radius'?: string;
            '--w3m-wallet-icon-border-radius'?: string;
            '--w3m-wallet-icon-large-border-radius'?: string;
            '--w3m-wallet-icon-small-border-radius'?: string;
            '--w3m-input-border-radius'?: string;
            '--w3m-notification-border-radius'?: string;
            '--w3m-button-border-radius'?: string;
            '--w3m-secondary-button-border-radius'?: string;
            '--w3m-icon-button-border-radius'?: string;
            '--w3m-button-hover-highlight-border-radius'?: string;
            '--w3m-font-family'?: string;
            '--w3m-font-feature-settings'?: string;
            '--w3m-text-big-bold-size'?: string;
            '--w3m-text-big-bold-weight'?: string;
            '--w3m-text-big-bold-line-height'?: string;
            '--w3m-text-big-bold-letter-spacing'?: string;
            '--w3m-text-big-bold-text-transform'?: string;
            '--w3m-text-big-bold-font-family'?: string;
            '--w3m-text-medium-regular-size'?: string;
            '--w3m-text-medium-regular-weight'?: string;
            '--w3m-text-medium-regular-line-height'?: string;
            '--w3m-text-medium-regular-letter-spacing'?: string;
            '--w3m-text-medium-regular-text-transform'?: string;
            '--w3m-text-medium-regular-font-family'?: string;
            '--w3m-text-small-regular-size'?: string;
            '--w3m-text-small-regular-weight'?: string;
            '--w3m-text-small-regular-line-height'?: string;
            '--w3m-text-small-regular-letter-spacing'?: string;
            '--w3m-text-small-regular-text-transform'?: string;
            '--w3m-text-small-regular-font-family'?: string;
            '--w3m-text-small-thin-size'?: string;
            '--w3m-text-small-thin-weight'?: string;
            '--w3m-text-small-thin-line-height'?: string;
            '--w3m-text-small-thin-letter-spacing'?: string;
            '--w3m-text-small-thin-text-transform'?: string;
            '--w3m-text-small-thin-font-family'?: string;
            '--w3m-text-xsmall-bold-size'?: string;
            '--w3m-text-xsmall-bold-weight'?: string;
            '--w3m-text-xsmall-bold-line-height'?: string;
            '--w3m-text-xsmall-bold-letter-spacing'?: string;
            '--w3m-text-xsmall-bold-text-transform'?: string;
            '--w3m-text-xsmall-bold-font-family'?: string;
            '--w3m-text-xsmall-regular-size'?: string;
            '--w3m-text-xsmall-regular-weight'?: string;
            '--w3m-text-xsmall-regular-line-height'?: string;
            '--w3m-text-xsmall-regular-letter-spacing'?: string;
            '--w3m-text-xsmall-regular-text-transform'?: string;
            '--w3m-text-xsmall-regular-font-family'?: string;
            '--w3m-overlay-background-color'?: string;
            '--w3m-overlay-backdrop-filter'?: string;
        };
        // Optional. WalletConnect modal theme.
        themeMode?: 'dark' | 'light'; // Default: 'light'
    }