Skip to content
Snippets Groups Projects
polkadotExtensionContext.tsx 2.62 KiB
Newer Older
Niklas P's avatar
Niklas P committed
import { createContext, useEffect, useState } from "react";
import type { InjectedAccountWithMeta, InjectedExtension, InjectedWindow } from "@polkadot/extension-inject/types";
Niklas P's avatar
Niklas P committed
import { isEqual } from 'lodash';
import { isDeepStrictEqual } from "util";
Niklas P's avatar
Niklas P committed

type PolkadotExtensionContextType = {
    accounts: any[];
Niklas P's avatar
Niklas P committed
    actingAccountIdx: number;
    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
    isWeb3Injected: boolean;
Niklas P's avatar
Niklas P committed
}

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

export const PolkadotExtensionProvider = ( props ) => {
    const [accounts, setAccounts] = useState<InjectedAccountWithMeta[]>([]);
Niklas P's avatar
Niklas P committed
    const [actingAccountIdx, setActingAccountIdx] = useState<number>(0);
    const [isWeb3Injected, setIsWeb3Injected] = useState<boolean>(false);
Niklas P's avatar
Niklas P committed
    const [injector, setInjector] = useState<InjectedExtension>();
Niklas P's avatar
Niklas P committed
    const [sources, setSources] = useState<any[]>([]);
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 ) )
    }
Niklas P's avatar
Niklas P committed

Niklas P's avatar
Niklas P committed
    const Accounts = async () => {      
      const { web3Accounts, web3Enable, web3FromAddress, web3AccountsSubscribe, web3EnablePromise, isWeb3Injected, } = await import(
Niklas P's avatar
Niklas P committed
        "@polkadot/extension-dapp"
      );
Niklas P's avatar
Niklas P committed

      setIsWeb3Injected( isWeb3Injected )
Niklas P's avatar
Niklas P committed
      // returns an array of all the injected sources
      // (this needs to be called first, before other requests)
      
Niklas P's avatar
Niklas P committed
      
      const allInjected = await web3Enable('Tokengated Polkadot Demo')
      const sources = await web3EnablePromise
Niklas P's avatar
Niklas P committed

Niklas P's avatar
Niklas P committed
      console.log( 'sources', sources )
Niklas P's avatar
Niklas P committed

Niklas P's avatar
Niklas P committed
      if ( allInjected.length === 0 ) {
        console.info('No extension found')
        return
Niklas P's avatar
Niklas P committed
      }

Niklas P's avatar
Niklas P committed
      const allAccounts = await web3Accounts()
Niklas P's avatar
Niklas P committed

Niklas P's avatar
Niklas P committed
      if ( ! isEqual ( accounts, allAccounts ) ) {
Niklas P's avatar
Niklas P committed
        setAccounts( allAccounts )
Niklas P's avatar
Niklas P committed
      }

      // we can use web3FromSource which will return an InjectedExtension type
      if ( allAccounts.length > 0 ) {      
        // finds an injector for an address
        const injector = await web3FromAddress(allAccounts[0].address);
        setInjector( injector )
Niklas P's avatar
Niklas P committed
      }
    }
  
    useEffect(() => {
      Accounts()
Niklas P's avatar
Niklas P committed
    }, [ sources ])
Niklas P's avatar
Niklas P committed

    return (
Niklas P's avatar
Niklas P committed
        <PolkadotExtensionContext.Provider value={ { 
          accounts,
          actingAccountIdx,
          setActingAccountIdx,
          setActingAccountByAddress,
          injector,
          isWeb3Injected,
        } }>
Niklas P's avatar
Niklas P committed
            {props.children}
        </PolkadotExtensionContext.Provider>
    )
}