Skip to content
Snippets Groups Projects
polkadotExtensionContext.tsx 4.22 KiB
Newer Older
Niklas P's avatar
Niklas P committed
import { ReactNode, createContext, useEffect, useState } from "react";
import type { InjectedExtension, InjectedAccountWithMeta, InjectedWindow } from "@polkadot/extension-inject/types";
Niklas P's avatar
Niklas P committed
import { SubscriptionFn, WalletAccount, getWallets, isWalletInstalled } from "@talismn/connect-wallets";
Niklas P's avatar
Niklas P committed

type PolkadotExtensionContextType = {
    accounts: InjectedAccountWithMeta[];
Niklas P's avatar
Niklas P committed
    actingAccountIdx: number | undefined;
Niklas P's avatar
Niklas P committed
    setActingAccountIdx: (idx: number) => void;
    setActingAccountByAddress: (address: string) => void;
Niklas P's avatar
Niklas P committed
    injector: InjectedExtension | undefined;
Niklas P's avatar
Niklas P committed
    isInitialized: boolean;
Niklas P's avatar
Niklas P committed
}

export const PolkadotExtensionContext = 
    createContext<PolkadotExtensionContextType>({} as PolkadotExtensionContextType);

Niklas P's avatar
Niklas P committed
export const PolkadotExtensionProvider = ( { children } : { children : ReactNode }) => {
Niklas P's avatar
Niklas P committed
  const [isInitialized, setIsInitialized ] = useState<boolean>( false )
  const [accounts, setAccounts] = useState<InjectedAccountWithMeta[]>([]);
Niklas P's avatar
Niklas P committed
  const [actingAccountIdx, setActingAccountIdx] = useState<number | undefined>( undefined );
  const [isWeb3Injected, setIsWeb3Injected] = useState<boolean>(false);
  const [injector, setInjector] = useState<InjectedExtension>();
  const [ allowExtensionConnection, setAllowExtensionConnection ] = useState<boolean>( false )
Niklas P's avatar
Niklas P committed

Niklas P's avatar
Niklas P committed
  const setActingAccountByAddress = (address: string) => {
    setActingAccountIdx( accounts?.findIndex( account => account.address === address ) )
  }
  const initWalletExtension = async () => {     
    const { web3AccountsSubscribe, web3Enable } = await import( "@polkadot/extension-dapp" );

    if (!allowExtensionConnection) {
      return setAccounts([])
Niklas P's avatar
Niklas P committed
    }

    // let unsubscribePromise = Promise.resolve<SubscriptionFn>( () => {} )

    if ( typeof window !== "undefined" ) {
      const unsubscribePromise = web3Enable(process.env.REACT_APP_APPLICATION_NAME ?? 'Talisman').then(() =>
        web3AccountsSubscribe(accounts => {
          console.log( 'accounts', accounts)
          setAccounts( accounts )
          setActingAccountIdx( 0 )
        })
      )
    }

    // return () => {
    //   unsubscribePromise.then(unsubscribe => unsubscribe())
    // }

    // if (typeof window !== "undefined" ) {
    //   const installedWallets = getWallets().filter(wallet => wallet.installed)
    //   console.log( 'installedWallets', installedWallets )
    //   const firstWallet = installedWallets[0]
    //   console.log( 'firstWallet', firstWallet )

    //   // enable the wallet
    //   if (firstWallet) {
    //     try {
    //       await firstWallet?.enable( "Polkadot Tokengated Demo" )
    //       await firstWallet?.subscribeAccounts((allAccounts: WalletAccount[] | undefined) => {
    //           console.log("got accounts via talisman connect", allAccounts)
    //           if ( accounts === undefined || accounts.length === 0 ) {
    //             setAccounts( allAccounts )
    //             setActingAccountIdx( 0 )
    //           }
    //       });
    //     } catch (error) {
    //       console.log( error )
    //     } 
    //     setIsInitialized( true )
    //   }
    // }
Niklas P's avatar
Niklas P committed
  }
  useEffect(() => {
    if ( typeof window !== "undefined" ) {
      const getInjector = async() => {
        const { web3FromSource } = await import( "@polkadot/extension-dapp" );
        const actingAccount = actingAccountIdx !== undefined ? accounts[actingAccountIdx] : undefined
        if ( actingAccount?.meta.source ) {
          const injector = await web3FromSource(actingAccount?.meta.source);
          setInjector( injector )
        }
      }

      getInjector()
    }
  }, [actingAccountIdx, accounts] )

  useEffect(() => {
    initWalletExtension()
  }, [allowExtensionConnection, setAccounts])

  useEffect(() => {
    if ( typeof window !== "undefined" ) {
      const w = Object.keys((globalThis as InjectedWindow).injectedWeb3 )
      if ( w && w !== undefined && Object.keys((globalThis as InjectedWindow).injectedWeb3 ).length > 0 ) {
        setAllowExtensionConnection(true)
      }
Niklas P's avatar
Niklas P committed
  return (
      <PolkadotExtensionContext.Provider value={ { 
        accounts,
        actingAccountIdx,
        setActingAccountIdx,
        setActingAccountByAddress,
        injector,
Niklas P's avatar
Niklas P committed
        isInitialized,
Niklas P's avatar
Niklas P committed
      } }>
          {children}
      </PolkadotExtensionContext.Provider>
  )
Niklas P's avatar
Niklas P committed
}