@ethersproject/providers#Web3Provider JavaScript Examples

The following examples show how to use @ethersproject/providers#Web3Provider. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: getLibrary.js    From Artion-Client with GNU General Public License v3.0 6 votes vote down vote up
export default function getLibrary(provider) {
  const library = new Web3Provider(
    provider,
    typeof provider.chainId === 'number'
      ? provider.chainId
      : typeof provider.chainId === 'string'
      ? parseInt(provider.chainId)
      : 'any'
  );
  library.pollingInterval = 15_000;
  library.detectNetwork();
  return library;
}
Example #2
Source File: UserProvider.js    From nft-e2e-example with MIT License 6 votes vote down vote up
useUserProvider = (injectedProvider, localProvider) =>
  useMemo(() => {
    if (injectedProvider) {
      console.log("? Using injected provider");
      return injectedProvider;
    }
    if (!localProvider) return undefined;

    const burnerConfig = {};

    if (window.location.pathname) {
      if (window.location.pathname.indexOf("/pk") >= 0) {
        const incomingPK = window.location.hash.replace("#", "");
        let rawPK;
        if (incomingPK.length === 64 || incomingPK.length === 66) {
          console.log("? Incoming Private Key...");
          rawPK = incomingPK;
          burnerConfig.privateKey = rawPK;
          window.history.pushState({}, "", "/");
          const currentPrivateKey = window.localStorage.getItem("metaPrivateKey");
          if (currentPrivateKey && currentPrivateKey !== rawPK) {
            window.localStorage.setItem("metaPrivateKey_backup" + Date.now(), currentPrivateKey);
          }
          window.localStorage.setItem("metaPrivateKey", rawPK);
        }
      }
    }

    console.log("? Using burner provider", burnerConfig);
    if (localProvider.connection && localProvider.connection.url) {
      burnerConfig.rpcUrl = localProvider.connection.url;
      return new Web3Provider(new BurnerProvider(burnerConfig));
    }
    // eslint-disable-next-line no-underscore-dangle
    const networkName = localProvider._network && localProvider._network.name;
    burnerConfig.rpcUrl = `https://${networkName || "mainnet"}.infura.io/v3/${INFURA_ID}`;
    return new Web3Provider(new BurnerProvider(burnerConfig));
  }, [injectedProvider, localProvider])
Example #3
Source File: UserProvider.js    From moonshot with MIT License 6 votes vote down vote up
useUserProvider = (injectedProvider, localProvider) =>
useMemo(() => {
  if (injectedProvider) {
    console.log("? Using injected provider");
    return injectedProvider;
  }
  if (!localProvider) return undefined;

  let burnerConfig = {}

  if(window.location.pathname){
    if(window.location.pathname.indexOf("/pk")>=0){
      let incomingPK = window.location.hash.replace("#","")
      let rawPK
      if(incomingPK.length===64||incomingPK.length===66){
        console.log("? Incoming Private Key...");
        rawPK=incomingPK
        burnerConfig.privateKey = rawPK
        window.history.pushState({},"", "/");
        let currentPrivateKey = window.localStorage.getItem("metaPrivateKey");
        if(currentPrivateKey && currentPrivateKey!==rawPK){
          window.localStorage.setItem("metaPrivateKey_backup"+Date.now(),currentPrivateKey);
        }
        window.localStorage.setItem("metaPrivateKey",rawPK);
      }
    }
  }

  console.log("? Using burner provider",burnerConfig);
  if (localProvider.connection && localProvider.connection.url) {
    burnerConfig.rpcUrl = localProvider.connection.url
    return new Web3Provider(new BurnerProvider(burnerConfig));
  }else{
    // eslint-disable-next-line no-underscore-dangle
    const networkName = localProvider._network && localProvider._network.name;
    burnerConfig.rpcUrl = `https://${networkName || "mainnet"}.infura.io/v3/${INFURA_ID}`
    return new Web3Provider(new BurnerProvider(burnerConfig));
  }
}, [injectedProvider, localProvider])
Example #4
Source File: UserSigner.js    From Tai-Shang-NFT-Wallet with MIT License 6 votes vote down vote up
parseProviderOrSigner = async providerOrSigner => {
  let signer = undefined;
  let provider;
  let providerNetwork;
  if (providerOrSigner && (providerOrSigner instanceof JsonRpcProvider || providerOrSigner instanceof Web3Provider)) {
    const accounts = await providerOrSigner.listAccounts();
    if (accounts && accounts.length > 0) {
      signer = providerOrSigner.getSigner();
    }
    provider = providerOrSigner;
    providerNetwork = await providerOrSigner.getNetwork();
  }
  if (!signer && providerOrSigner instanceof Signer) {
    signer = providerOrSigner;
    provider = signer.provider;
    providerNetwork = provider && (await provider.getNetwork());
  }
  return { signer, provider, providerNetwork };
}
Example #5
Source File: withWeb3Provider.js    From origin-dollar with MIT License 6 votes vote down vote up
withWeb3Provider = (WrappedComponent) => {
  function getLibrary(provider) {
    const library = new Web3Provider(provider)
    library.pollingInterval = 12000
    return library
  }

  const Wrapper = (props) => {
    return (
      <Web3ReactProvider getLibrary={getLibrary}>
        <WrappedComponent {...props} />
      </Web3ReactProvider>
    )
  }

  if (WrappedComponent.getInitialProps) {
    Wrapper.getInitialProps = async (ctx) => {
      const componentProps = await WrappedComponent.getInitialProps(ctx)
      return componentProps
    }
  }

  return Wrapper
}
Example #6
Source File: index.js    From gnosis-safe-delegate-dapp with MIT License 5 votes vote down vote up
function getLibrary(provider) {
    const library = new Web3Provider(provider)
    library.pollingInterval = 12000

    return library
}
Example #7
Source File: index.js    From dshop with MIT License 5 votes vote down vote up
function getLibrary(provider) {
  const library = new Web3Provider(provider)
  library.pollingInterval = 12000
  return library
}
Example #8
Source File: unlock.jsx    From crv.finance with MIT License 5 votes vote down vote up
function getLibrary(provider) {

  const library = new Web3Provider(provider);
  library.pollingInterval = 8000;
  return library;
}
Example #9
Source File: unlock.js    From vote-incentives with GNU General Public License v3.0 5 votes vote down vote up
function getLibrary(provider) {
  const library = new Web3Provider(provider);
  library.pollingInterval = 8000;
  return library;
}
Example #10
Source File: index.js    From dshop with MIT License 5 votes vote down vote up
function getLibrary(provider) {
  const library = new Web3Provider(provider)
  library.pollingInterval = 12000
  return library
}
Example #11
Source File: index.js    From sorbet-finance with GNU General Public License v3.0 5 votes vote down vote up
function getLibrary(provider) {
  const library = new Web3Provider(provider)
  library.pollingInterval = 15000
  return library
}
Example #12
Source File: Dashboard.jsx    From soundly with MIT License 5 votes vote down vote up
sf = new SuperfluidSDK.Framework({
      ethers: new Web3Provider(window.ethereum),
      tokens: ['fDAI']
})
Example #13
Source File: unlock.jsx    From yuni.finance with MIT License 5 votes vote down vote up
function getLibrary(provider) {
  const library = new Web3Provider(provider);
  library.pollingInterval = 8000;
  return library;
}
Example #14
Source File: unlock.jsx    From ygov-finance with MIT License 5 votes vote down vote up
function getLibrary(provider) {

  const library = new Web3Provider(provider);
  library.pollingInterval = 8000;
  return library;
}
Example #15
Source File: index.js    From pine-interface with GNU General Public License v3.0 5 votes vote down vote up
function getLibrary(provider) {
  const library = new Web3Provider(provider)
  library.pollingInterval = 15000
  return library
}
Example #16
Source File: App.jsx    From locked.fyi with MIT License 5 votes vote down vote up
/**
 *
 * @param {*} provider
 */
function getLibrary(provider) {
  return new Web3Provider(provider)
}
Example #17
Source File: unlock.jsx    From ileverage-finance with MIT License 5 votes vote down vote up
function getLibrary(provider) {

  const library = new Web3Provider(provider);
  library.pollingInterval = 8000;
  return library;
}
Example #18
Source File: unlock.jsx    From iliquidate-finance with MIT License 5 votes vote down vote up
function getLibrary(provider) {

  const library = new Web3Provider(provider);
  library.pollingInterval = 8000;
  return library;
}
Example #19
Source File: BasicLayout.js    From acy-dex-interface with MIT License 4 votes vote down vote up
BasicLayout =props=> {
  // constructor(props) {
  //   super(props);
  //   getPageTitle = memoizeOne(getPageTitle);
  //   matchParamsPath = memoizeOne(matchParamsPath, isEqual);
  // }

  // componentDidMount() {
  //   const {
  //     dispatch,
  //     route: { routes, authority },
  //   } = props;
  //   // dispatch({
  //   //   type: 'user/fetchCurrent',
  //   // });
  //   dispatch({
  //     type: 'setting/getSetting',
  //   });
  //   dispatch({
  //     type: 'menu/getMenuData',
  //     payload: { routes, authority },
  //   });
  // }
  useEffect(() => {
    const {
      dispatch,
      route: { routes, authority },
    } = props;
    // dispatch({
    //   type: 'user/fetchCurrent',
    // });
    dispatch({
      type: 'setting/getSetting',
    });
    dispatch({
      type: 'menu/getMenuData',
      payload: { routes, authority },
    });
  },[])
  // 根据不同页面切换背景色
  const [bgColor,setBgColor]=useState('radialBg');
  useEffect(() => {
    const {
      location: { pathname },
    } = props;
    if(pathname.indexOf('/market')>-1){
      setBgColor('marketRadialBg');
    }
    if(pathname.indexOf('/exchange')>-1){
      setBgColor('radialBg');
    }
    if(pathname.indexOf('/liquidity')>-1){
      setBgColor('liquidityRadialBg');
    }
    if(pathname.indexOf('/farms')>-1){
      setBgColor('farmsRadialBg');
    }
    if(pathname.indexOf('/dao')>-1){
      setBgColor('daoRadialBg');
    }
    if(pathname.indexOf('/launchpad')>-1){
      setBgColor('launchpadRadialBg');
    }
    if(pathname.indexOf('/perpetual')>-1){
      setBgColor('launchpadRadialBg');
    }
    if(pathname.indexOf('/stablecoin')>-1){
      setBgColor('stableCoinRadialBg');
    }
    if(pathname.indexOf('/stats')>-1){
      setBgColor('statsRadialBg');
    }
  })
  // componentDidUpdate(preProps) {
  //   // After changing to phone mode,
  //   // if collapsed is true, you need to click twice to display
  //   const { collapsed, isMobile } = props;
  //   if (isMobile && !preProps.isMobile && !collapsed) {
  //     handleMenuCollapse(false);
  //   }
  // }

 const  getContext=()=> {
    const { location, breadcrumbNameMap } = props;
    return {
      location,
      breadcrumbNameMap,
    };
  }

  const matchParamsPath = (pathname, breadcrumbNameMap) => {
    const pathKey = Object.keys(breadcrumbNameMap).find(key => pathToRegexp(key).test(pathname));
    return breadcrumbNameMap[pathKey];
  };

  const getRouterAuthority = (pathname, routeData) => {
    let routeAuthority = ['noAuthority'];
    const getAuthority = (key, routes) => {
      routes.forEach(route => {
        if (route.path && pathToRegexp(route.path).test(key)) {
          routeAuthority = route.authority;
        } else if (route.routes) {
          routeAuthority = getAuthority(key, route.routes);
        }
        return route;
      });
      return routeAuthority;
    };
    return getAuthority(pathname, routeData);
  };

  const getPageTitle = (pathname, breadcrumbNameMap) => {
    const currRouterData = matchParamsPath(pathname, breadcrumbNameMap);

    if (!currRouterData) {
      return title;
    }
    const pageName = formatMessage({
      id: currRouterData.locale || currRouterData.name,
      defaultMessage: currRouterData.name,
    });

    return `${pageName} - ${title}`;
  };

  const getLayoutStyle = () => {
    const { fixSiderbar, isMobile, collapsed, layout } = props;
    if (fixSiderbar && layout !== 'topmenu' && !isMobile) {
      return {
        paddingLeft: collapsed ? '80px' : '256px',
      };
    }
    return null;
  };

  const handleMenuCollapse = collapsed => {
    const { dispatch } = props;
    dispatch({
      type: 'global/changeLayoutCollapsed',
      payload: collapsed,
    });
  };

  const renderSettingDrawer = () => {
    // Do not render SettingDrawer in production
    // unless it is deployed in preview.pro.ant.design as demo
    if (process.env.NODE_ENV === 'production' && APP_TYPE !== 'site') {
      return null;
    }
    return <SettingDrawer />;
  };

  const getLibrary=(provider, connector)=> {
    return new Web3Provider(provider); // this will vary according to whether you use e.g. ethers or web3.js
  }
  
    const {
      navTheme,
      layout: PropsLayout,
      children,
      location: { pathname },
      isMobile,
      menuData,
      breadcrumbNameMap,
      route: { routes },
      fixedHeader,
    } = props;
    const isTop = PropsLayout === 'topmenu';
    const routerConfig = getRouterAuthority(pathname, routes);
    const contentStyle = !fixedHeader ? { paddingTop: 0 } : {};
    const layout = 
      <Layout>
        {/* Conditional rendering: show Sidebar only in certain pages */}
        {pathname.indexOf('/launchpad')>-1 && false &&
        <Sidebar />
        }
        <Layout 
          style={{ ...getLayoutStyle(), minHeight: '100vh' }
            // background: styles.radialBg
          } 
          className={styles[bgColor]}
        >
          <SideMenu menuData={menuData} handleMenuCollapse={handleMenuCollapse} logo={logo} isMobile={isMobile} {...props} />
          <Content className={styles.content} style={contentStyle}>
            <Header menuData={menuData} handleMenuCollapse={handleMenuCollapse} logo={logo} isMobile={isMobile} {...props} />
            {children}
          </Content>
          {/* <Footer /> */}
        </Layout>
      </Layout>;
    return (
      <React.Fragment>
        <DocumentTitle title={getPageTitle(pathname, breadcrumbNameMap)}>
          <ContainerQuery query={query}>
            {params => (
              <Context.Provider value={getContext()}>
                <Web3ReactProvider getLibrary={getLibrary}>
                  <div className={classNames(params)}>{layout}</div>
                </Web3ReactProvider>
              </Context.Provider>
            )}
          </ContainerQuery>
        </DocumentTitle>
        {/* <Suspense fallback={<PageLoading />}>{renderSettingDrawer()}</Suspense> */}
      </React.Fragment>
    );
}
Example #20
Source File: App.jsx    From nft-e2e-example with MIT License 4 votes vote down vote up
function App(props) {
  const mainnetProvider = scaffoldEthProvider && scaffoldEthProvider._network ? scaffoldEthProvider : mainnetInfura;

  const [injectedProvider, setInjectedProvider] = useState();
  /* ? This hook will get the price of ETH from ? Uniswap: */
  const price = useExchangePrice(targetNetwork, mainnetProvider);

  /* ? This hook will get the price of Gas from ⛽️ EtherGasStation */
  const gasPrice = useGasPrice(targetNetwork, "fast");
  // Use your injected provider from ? Metamask or if you don't have it then instantly generate a ? burner wallet.
  const userProvider = useUserProvider(injectedProvider, localProvider);
  const address = useUserAddress(userProvider);

  // You can warn the user if you would like them to be on a specific network
  const localChainId = localProvider && localProvider._network && localProvider._network.chainId;
  const selectedChainId = userProvider && userProvider._network && userProvider._network.chainId;

  // For more hooks, check out ?eth-hooks at: https://www.npmjs.com/package/eth-hooks

  // The transactor wraps transactions and provides notificiations
  const tx = Transactor(userProvider, gasPrice);

  // Faucet Tx can be used to send funds from the faucet
  const faucetTx = Transactor(localProvider, gasPrice);

  // ? scaffold-eth is full of handy hooks like this one to get your balance:
  const yourLocalBalance = useBalance(localProvider, address);

  // Just plug in different ? providers to get your balance on different chains:
  const yourMainnetBalance = useBalance(mainnetProvider, address);

  // Load in your local ? contract and read a value from it:
  const readContracts = useContractLoader(localProvider);

  // If you want to make ? write transactions to your contracts, use the userProvider:
  const writeContracts = useContractLoader(userProvider);


  /*
  const addressFromENS = useResolveName(mainnetProvider, "austingriffith.eth");
  console.log("? Resolved austingriffith.eth as:",addressFromENS)
  */

  //
  // ? DEBUG ??‍?
  //
  useEffect(() => {
    if (
      DEBUG &&
      mainnetProvider &&
      address &&
      selectedChainId &&
      yourLocalBalance &&
      yourMainnetBalance &&
      readContracts &&
      writeContracts
    ) {
      console.log("_____________________________________ ? scaffold-eth _____________________________________");
      console.log("? mainnetProvider", mainnetProvider);
      console.log("? localChainId", localChainId);
      console.log("?‍? selected address:", address);
      console.log("??‍♂️ selectedChainId:", selectedChainId);
      console.log("? yourLocalBalance", yourLocalBalance ? formatEther(yourLocalBalance) : "...");
      console.log("? yourMainnetBalance", yourMainnetBalance ? formatEther(yourMainnetBalance) : "...");
      console.log("? readContracts", readContracts);
      console.log("? writeContracts", writeContracts);
    }
  }, [
    mainnetProvider,
    address,
    selectedChainId,
    yourLocalBalance,
    yourMainnetBalance,
    readContracts,
    writeContracts,
  ]);

  let networkDisplay = "";
  if (localChainId && selectedChainId && localChainId !== selectedChainId) {
    const networkSelected = NETWORK(selectedChainId);
    const networkLocal = NETWORK(localChainId);
    if (selectedChainId === 1337 && localChainId === 31337) {
      networkDisplay = (
        <div style={{ zIndex: 2, position: "absolute", right: 0, top: 60, padding: 16 }}>
          <Alert
            message="⚠️ Wrong Network ID"
            description={
              <div>
                You have <b>chain id 1337</b> for localhost and you need to change it to <b>31337</b> to work with
                HardHat.
                <div>(MetaMask -&gt; Settings -&gt; Networks -&gt; Chain ID -&gt; 31337)</div>
              </div>
            }
            type="error"
            closable={false}
          />
        </div>
      );
    } else {
      networkDisplay = (
        <div style={{ zIndex: 2, position: "absolute", right: 0, top: 60, padding: 16 }}>
          <Alert
            message="⚠️ Wrong Network"
            description={
              <div>
                You have <b>{networkSelected && networkSelected.name}</b> selected and you need to be on{" "}
                <b>{networkLocal && networkLocal.name}</b>.
              </div>
            }
            type="error"
            closable={false}
          />
        </div>
      );
    }
  } else {
    networkDisplay = (
      <div style={{ zIndex: -1, position: "absolute", right: 154, top: 28, padding: 16, color: targetNetwork.color }}>
        {targetNetwork.name}
      </div>
    );
  }

  const loadWeb3Modal = useCallback(async () => {
    const provider = await web3Modal.connect();
    setInjectedProvider(new Web3Provider(provider));
  }, [setInjectedProvider]);

  useEffect(() => {
    if (web3Modal.cachedProvider) {
      loadWeb3Modal();
    }
  }, [loadWeb3Modal]);

  const [route, setRoute] = useState();
  useEffect(() => {
    setRoute(window.location.pathname);
  }, [setRoute]);

  let faucetHint = "";
  const faucetAvailable = localProvider && localProvider.connection && targetNetwork.name === "localhost";

  if (faucetAvailable) {
    faucetHint = (
      <div style={{ padding: 16 }}>
        <Button
          type="primary"
          onClick={() => {
            faucetTx({
              to: address,
              value: parseEther("0.01"),
            });
          }}
        >
          ? Grab funds from the faucet ⛽️
        </Button>
      </div>
    );
  }

  return (
    <div className="App">
      <Header />
      {networkDisplay}
      <BrowserRouter>
        <Menu style={{ textAlign: "center" }} selectedKeys={[route]} mode="horizontal">
        <Menu.Item key="/">
            <Link
              onClick={() => {
                setRoute("/");
              }}
              to="/"
            >
              Mint an NFT
            </Link>
          </Menu.Item>
          <Menu.Item key="/view">
            <Link
              onClick={() => { setRoute("/view"); }}
              to="/view">View an NFT</Link>
          </Menu.Item>
          <Menu.Item key="/contract">
            <Link
              onClick={() => {
                setRoute("/contract");
              }}
              to="/contract"
            >
              NFTMinter Contract
            </Link>
          </Menu.Item>
        </Menu>

        <Switch>
          <Route exact path="/">
          <Minter
              signer={userProvider.getSigner()}
              provider={localProvider}
              address={address}
              blockExplorer={blockExplorer}
            />
          </Route>

          <Route path="/view">
              <NFTViewer
                provider={localProvider}
                address={address}
                blockExplorer={blockExplorer}
              />
          </Route>

          <Route exact path="/contract">
            <Contract
              name="NFTMinter"
              signer={userProvider.getSigner()}
              provider={localProvider}
              address={address}
              blockExplorer={blockExplorer}
            />
          </Route>
        </Switch>
      </BrowserRouter>

      <ThemeSwitch />

      {/* ?‍? Your account is in the top right with a wallet at connect options */}
      <div style={{ position: "fixed", textAlign: "right", right: 0, top: 0, padding: 10 }}>
        <Account
          address={address}
          localProvider={localProvider}
          userProvider={userProvider}
          mainnetProvider={mainnetProvider}
          price={price}
          web3Modal={web3Modal}
          loadWeb3Modal={loadWeb3Modal}
          logoutOfWeb3Modal={logoutOfWeb3Modal}
          blockExplorer={blockExplorer}
        />
        {faucetHint}
      </div>


    </div>
  );
}
Example #21
Source File: App.jsx    From scaffold-directory with MIT License 4 votes vote down vote up
function App() {
  const [providers, setProviders] = useState({
    mainnet: { provider: null, isReady: false },
    local: { provider: null, isReady: false },
  });

  useEffect(() => {
    // ? providers

    /*
    //This code is needed if you want a local and a mainnet provider

    // ? What chain are your contracts deployed to?
    const targetNetwork = NETWORKS.mainnet; // <------- select your target frontend network (localhost, rinkeby, xdai, mainnet)

    // ? Your local provider is usually pointed at your local blockchain
    const localProviderUrl = targetNetwork.rpcUrl;

    // as you deploy to other networks you can set REACT_APP_PROVIDER=https://dai.poa.network in packages/react-app/.env
    const localProviderUrlFromEnv = process.env.REACT_APP_PROVIDER ? process.env.REACT_APP_PROVIDER : localProviderUrl;

    const localProviderPromise = providerPromiseWrapper(new StaticJsonRpcProvider(localProviderUrlFromEnv));
    */

    if (DEBUG) console.log("? Connecting to Mainnet Ethereum");
    const scaffoldEthProviderPromise = providerPromiseWrapper(
      new StaticJsonRpcProvider("https://rpc.scaffoldeth.io:48544"),
    );

    // attempt to connect to our own scaffold eth rpc and if that fails fall back to infura...
    // Using StaticJsonRpcProvider as the chainId won't change see https://github.com/ethers-io/ethers.js/issues/901
    scaffoldEthProviderPromise
      .then(provider => {
        if (DEBUG) console.log("? Connected to Mainnet Ethereum using the scaffold eth provider");
        setProviders({ mainnet: { provider, isReady: true } });
      })
      .catch(() => {
        if (DEBUG) console.log("❌ ? Connection to Mainnet Ethereum using the scaffold eth provider failed");
        const mainnetInfuraProviderPromise = providerPromiseWrapper(new InfuraProvider("mainnet", INFURA_ID));
        mainnetInfuraProviderPromise
          .then(provider => {
            if (DEBUG) console.log("? Connected to Mainnet Ethereum using the infura provider as callback");
            setProviders({ mainnet: { provider, isReady: true } });
          })
          .catch(() => {
            if (DEBUG) console.log("❌ ? Connection to Mainnet Ethereum using the infura provider as fallback failed");
            // ( ⚠️ Getting "failed to meet quorum" errors? Check your INFURA_ID)
          });
      });
  }, []);

  const mainnetProvider = providers.mainnet?.provider;

  const [injectedProvider, setInjectedProvider] = useState();

  // Use your injected provider from ? Metamask or if you don't have it then instantly generate a ? burner wallet.
  // TODO move the userProvider into the "providers" state, which is sent into the BlockchainProvidersContext
  const userProvider = useUserProvider(injectedProvider);
  // TODO address is derived from userProvider, so we should just send userProvider
  const address = useUserAddress(userProvider);

  // You can warn the user if you would like them to be on a specific network
  const selectedChainId = userProvider && userProvider._network && userProvider._network.chainId;

  //
  // ? DEBUG ??‍?
  //
  useEffect(() => {
    if (DEBUG && mainnetProvider && address && selectedChainId) {
      console.log("_____________________________________ ? scaffold-eth _____________________________________");
      console.log("? mainnetProvider", mainnetProvider);
      console.log("?‍? selected address:", address);
      console.log("??‍♂️ selectedChainId:", selectedChainId);
    }
  }, [mainnetProvider, address, selectedChainId]);

  const loadWeb3Modal = useCallback(async () => {
    const provider = await web3Modal.connect();
    setInjectedProvider(new Web3Provider(provider));
  }, [setInjectedProvider]);

  const logoutOfWeb3Modal = async () => {
    await web3Modal.clearCachedProvider();
    if (injectedProvider && injectedProvider.provider && typeof injectedProvider.provider.disconnect == "function") {
      await injectedProvider.provider.disconnect();
    }
    setTimeout(() => {
      window.location.reload();
    }, 1);
  };

  useEffect(() => {
    if (web3Modal.cachedProvider) {
      loadWeb3Modal();
    }
  }, [loadWeb3Modal]);

  const [userRole, setUserRole] = useState(null);
  const [connectedBuilder, setConnectedBuilder] = useState(null);

  useEffect(() => {
    async function fetchUserData() {
      console.log("getting user data");
      try {
        const fetchedUserObject = await axios.get(serverUrl + `/user`, {
          params: { address },
        });
        setUserRole(USER_ROLES[fetchedUserObject.data.role] ?? USER_ROLES.registered);
        setConnectedBuilder(fetchedUserObject.data);
      } catch (e) {
        setUserRole(USER_ROLES.anonymous);
      }
    }

    if (address) {
      fetchUserData();
    }
  }, [address]);

  return (
    <BlockchainProvidersContext.Provider value={providers}>
      <div className="App">
        {/* ✏️ Edit the header and change the title to your project name */}
        <Header
          injectedProvider={injectedProvider}
          userRole={userRole}
          address={address}
          mainnetProvider={mainnetProvider}
          userProvider={userProvider}
          loadWeb3Modal={loadWeb3Modal}
          logoutOfWeb3Modal={logoutOfWeb3Modal}
          setUserRole={setUserRole}
        />
        <Switch>
          <Route exact path="/">
            <HomeView connectedBuilder={connectedBuilder} />
          </Route>
          <Route exact path="/portfolio">
            {address && <Redirect to={"/builders/" + address} />}
          </Route>
          <Route path="/builders" exact>
            <BuilderListView serverUrl={serverUrl} mainnetProvider={mainnetProvider} userRole={userRole} />
          </Route>
          <Route path="/builders/:builderAddress">
            <BuilderProfileView
              serverUrl={serverUrl}
              mainnetProvider={mainnetProvider}
              address={address}
              userRole={userRole}
              userProvider={userProvider}
            />
          </Route>
          <Route path="/challenge/:challengeId">
            <ChallengeDetailView
              serverUrl={serverUrl}
              address={address}
              userProvider={userProvider}
              userRole={userRole}
              loadWeb3Modal={loadWeb3Modal}
            />
          </Route>
          {/* ToDo: Protect this route on the frontend? */}
          <Route path="/submission-review" exact>
            <SubmissionReviewView userProvider={userProvider} mainnetProvider={mainnetProvider} />
          </Route>
          <Route path="/activity" exact>
            <ActivityView />
          </Route>
        </Switch>
        <ColorModeSwitcher />
      </div>
    </BlockchainProvidersContext.Provider>
  );
}
Example #22
Source File: FooterMusicPlayer.jsx    From soundly with MIT License 4 votes vote down vote up
function FooterMusicPlayer({ music }) {
  const { user, isAuthenticated } = useMoralis();
  const [{ id, name, author_name, img, musicName, artistAddress }, setCurrTrack] = useState(music);
  const [isRepeatClicked, setRepeatClick] = useState(false);
  const [isPrevClicked, setPrevClicked] = useState(false);
  const [isNextClicked, setNextClicked] = useState(false);
  const [isPlaying, setPlayPauseClicked] = useState(false);
  const [isVolumeClicked, setVolumeClicked] = useState(false);
  const [volume, setVolume] = useState(50);
  const [seekTime, setSeekTime] = useState(0);
  const [duration, setDuration] = useState(0);
  const [currTime, setCurrTime] = useState(0);
  const [bannerToggle, setBannerToggle] = useState(false);

  const audioElement = useRef();
  const dispatch = useDispatch();
  // start a payment stream aka flow
  const sf = new SuperfluidSDK.Framework({
      ethers: new Web3Provider(window.ethereum),
      tokens: ['fDAI']
    });

  const testFlow = async () => {
    // console.log(sf);
    await sf.initialize();
    const carol = sf.user({
      address: user.get("ethAddress"),
      token: sf.tokens.fDAIx.address
    });
  
    await carol.flow({
      recipient: '0xA8f3447922d786045CB582B0C825723B744a54df',
      flowRate: "385802469135802"
    });
    
    const details = await carol.details();
    console.log(details);
};

  async function stopFlow(toAddress="0xA8f3447922d786045CB582B0C825723B744a54df") {
    const carol = sf.user({
      address: user.get("ethAddress"),
      token: sf.tokens.fDAIx.address
    });
    
   await carol.flow({
        toAddress,
        flowRate: 0
    });
}

  const { playlists } = useSelector(state => state.musicReducer);
  const useStyle = useContext(ThemeContext);
  const pointer = { cursor: "pointer", color: useStyle.theme };

  const handleToggle = (type, val) => {
    switch (type) {
      case "repeat":
        setRepeatClick(val);
        break;
      case "prev":
        setPrevClicked(val);
        break;
      case "play-pause":
        setPlayPauseClicked(val);
        break;
      case "next":
        setNextClicked(val);
        break;
      case "volume":
        setVolumeClicked(val);
        break;
      default:
        break;
    }
  };
  const handleSeekChange = (event, newValue) => {
    audioElement.current.currentTime = (newValue * duration) / 100;
    setSeekTime(newValue);
  };
  const handleVolumeChange = (event, newValue) => {
    setVolume(newValue);
  };
  const handleBannerToggle = () => {
    setBannerToggle(!bannerToggle);
  };

  useEffect(() => {
   
  }, [])

  useEffect(() => {
    dispatch(setBannerOpen(bannerToggle));
  }, [dispatch, bannerToggle]);

  useEffect(() => {
    isPlaying
      ? audioElement.current
          .play()
          .then(() => {})
          .catch(e => {
            audioElement.current.pause();
            audioElement.current.currentTime = 0;
          })
      : audioElement.current.pause();
    audioElement.current.loop = isRepeatClicked;
    audioElement.current.volume = volume / 100;
    audioElement.current.muted = isVolumeClicked;
    audioElement.current.onloadeddata = () => {
      if (audioElement.current != null) setDuration(audioElement.current.duration);
    };
    setInterval(() => {
      if (audioElement.current !== null) setCurrTime(audioElement.current.currentTime);
    });
  });

  useEffect(() => {
    setCurrTrack(music);
  }, [music]);

  useEffect(() => {
    setSeekTime(currTime / (duration / 100));
  }, [currTime, duration]);

  useEffect(() => {
    audioElement.current.onended = () => {
      setNextClicked(true);
    };
  });

  useEffect(() => {
    if (isNextClicked) {
      let currTrackId = (id + 1) % playlists.length;
      dispatch(setCurrentPlaying(playlists[currTrackId]));
      setNextClicked(false);
    }
    if (isPrevClicked) {
      let currTrackId = (id - 1) % playlists.length;
      if (id - 1 < 0) {
        currTrackId = playlists.length - 1;
      }
      dispatch(setCurrentPlaying(playlists[currTrackId]));
      setPrevClicked(false);
    }
  }, [dispatch, id, isNextClicked, isPrevClicked, playlists]);

  function formatTime(secs) {
    const t = new Date(1970, 0, 1);
    t.setSeconds(secs);
    let s = t.toTimeString().substr(0, 8);
    if (secs > 86399) s = Math.floor((t - Date.parse("1/1/70")) / 3600000) + s.substr(2);
    return s.substring(3);
  }
  return (
    <div className={"footer-player"}>
      <Button onClick={handleBannerToggle} className="curr-music-container">
        <img src={require("../assets/img/" + img).default} alt={name} className="music-art" />
        <div className="curr-music-details">
          <Name name={name} className={"song-name"} length={name.length} />
          <Name name={author_name} className={"author-name"} length={author_name.length} />
        </div>
      </Button>
      <div className="playback-controls">
        <div>
          <ControlsToggleButton
            style={pointer}
            type={"repeat"}
            defaultIcon={<RepeatIcon fontSize={"large"} />}
            changeIcon={<RepeatOneIcon fontSize={"large"} />}
            onClicked={handleToggle}
          />

          <ControlsToggleButton
            style={pointer}
            type={"prev"}
            defaultIcon={<SkipPreviousIcon fontSize={"large"} />}
            changeIcon={<SkipPreviousIcon fontSize={"large"} />}
            onClicked={handleToggle}
          />

          <audio ref={audioElement} src={require("../assets/music/" + musicName).default} preload={"metadata"} />

          <ControlsToggleButton
            style={pointer}
            type={"play-pause"}
            defaultIcon={<PlayArrowIcon fontSize={"large"} />}
            changeIcon={<PauseIcon fontSize={"large"} />}
            onClicked={handleToggle}
          />

          <ControlsToggleButton
            style={pointer}
            type={"next"}
            defaultIcon={<SkipNextIcon fontSize={"large"} />}
            changeIcon={<SkipNextIcon fontSize={"large"} />}
            onClicked={handleToggle}
          />
        </div>
        <div>
          <div className="playback">
            {!isNaN(seekTime) && (
              <>
                {" "}
                <span style={{ fontSize: "10px" }}>{formatTime(currTime)}</span>
                <Slider
                  style={{ color: useStyle.theme }}
                  className={"playback-completed"}
                  value={seekTime}
                  onChange={handleSeekChange}
                />
                <span style={{ fontSize: "10px" }}>{formatTime(duration)}</span>
              </>
            )}
          </div>
        </div>
      </div>

      <button onClick={testFlow}>Stream</button>
      <button onClick={stopFlow}>Stop</button>
      
      <div className="playback-widgets">
        <ControlsToggleButton
          style={pointer}
          type={"volume"}
          defaultIcon={<VolumeUpIcon />}
          changeIcon={<VolumeOffIcon />}
          onClicked={handleToggle}
        />
        <div className={"slider"}>
          <Slider style={{ color: useStyle.theme }} value={volume} onChange={handleVolumeChange} />
        </div>
      </div>
    </div>
  );
}
Example #23
Source File: Moonshot.jsx    From moonshot with MIT License 4 votes vote down vote up
function Moonshot(props) {
  const mainnetProvider = scaffoldEthProvider && scaffoldEthProvider._network ? scaffoldEthProvider : mainnetInfura;

  const [injectedProvider, setInjectedProvider] = useState();
  /* ? This hook will get the price of ETH from ? Uniswap: */
  const price = useExchangePrice(targetNetwork, mainnetProvider);

  /* ? This hook will get the price of Gas from ⛽️ EtherGasStation */
  const gasPrice = useGasPrice(targetNetwork, "fast");
  // Use your injected provider from ? Metamask or if you don't have it then instantly generate a ? burner wallet.
  const userProvider = useUserProvider(injectedProvider, localProvider);
  const address = useUserAddress(userProvider);

  // You can warn the user if you would like them to be on a specific network
  const localChainId = localProvider && localProvider._network && localProvider._network.chainId;
  const selectedChainId = userProvider && userProvider._network && userProvider._network.chainId;

  // For more hooks, check out ?eth-hooks at: https://www.npmjs.com/package/eth-hooks

  // The transactor wraps transactions and provides notificiations
  const tx = Transactor(userProvider, gasPrice);

  // Faucet Tx can be used to send funds from the faucet
  const faucetTx = Transactor(localProvider, gasPrice);

  // ? scaffold-eth is full of handy hooks like this one to get your balance:
  const yourLocalBalance = useBalance(localProvider, address);

  // Just plug in different ? providers to get your balance on different chains:
  // const yourMainnetBalance = useBalance(mainnetProvider, address);

  // Load in your local ? contract and read a value from it:
  // const readContracts = useContractLoader(localProvider)

  // If you want to make ? write transactions to your contracts, use the userProvider:
  // const writeContracts = useContractLoader(userProvider)

  // EXTERNAL CONTRACT EXAMPLE:
  //
  // If you want to bring in the mainnet DAI contract it would look like:
  //  const mainnetDAIContract = useExternalContractLoader(mainnetProvider, DAI_ADDRESS, DAI_ABI)

  // If you want to call a function on a new block
  useOnBlock(mainnetProvider, () => {
    console.log(`⛓ A new mainnet block is here: ${mainnetProvider._lastBlockNumber}`);
  });

  // Then read your DAI balance like:
  //  const myMainnetDAIBalance = useContractReader({DAI: mainnetDAIContract},"DAI", "balanceOf",["0x34aA3F359A9D614239015126635CE7732c18fDF3"])

  // keep track of a variable from the contract in the local React state:
  // const purpose = useContractReader(readContracts,"YourContract", "purpose")

  // ? Listen for broadcast events
  // const setPurposeEvents = useEventListener(readContracts, "YourContract", "SetPurpose", localProvider, 1);

  /*
  const addressFromENS = useResolveName(mainnetProvider, "austingriffith.eth");
  console.log("? Resolved austingriffith.eth as:",addressFromENS)
  */

  //
  // ? DEBUG ??‍?
  //
  useEffect(() => {
    if (
      DEBUG &&
      mainnetProvider &&
      address &&
      selectedChainId &&
      yourLocalBalance /* &&  yourMainnetBalance &&readContracts && writeContracts && mainnetDAIContract */
    ) {
      console.log("_____________________________________ ? scaffold-eth _____________________________________");
      console.log("? mainnetProvider", mainnetProvider);
      console.log("? localChainId", localChainId);
      console.log("?‍? selected address:", address);
      console.log("??‍♂️ selectedChainId:", selectedChainId);
      console.log("? yourLocalBalance", yourLocalBalance ? formatEther(yourLocalBalance) : "...");
      /* console.log("? yourMainnetBalance",yourMainnetBalance?formatEther(yourMainnetBalance):"...") */
      /*  console.log("? readContracts",readContracts) */
      /* console.log("? DAI contract on mainnet:",mainnetDAIContract) */
      /*  console.log("? writeContracts",writeContracts) */
    }
  }, [
    mainnetProvider,
    address,
    selectedChainId,
    yourLocalBalance /* yourMainnetBalance, readContracts, writeContracts, mainnetDAIContract */,
  ]);

  let networkDisplay = "";
  if (localChainId && selectedChainId && localChainId != selectedChainId) {
    networkDisplay = (
      <div style={{ zIndex: 2, position: "absolute", right: 0, top: 0, padding: 16 }}>
        <Alert
          message="⚠️ Wrong Network"
          description={
            <div>
              You have <b>{NETWORK(selectedChainId).name}</b> selected and you need to be on{" "}
              <b>{NETWORK(localChainId).name}</b>.
            </div>
          }
          type="error"
          closable={false}
        />
      </div>
    );
  } else {
    networkDisplay = (
      <div style={{ zIndex: -1, position: "absolute", right: 154, top: 8, padding: 16, color: targetNetwork.color }}>
        {targetNetwork.name}
      </div>
    );
  }

  const loadWeb3Modal = useCallback(async () => {
    const provider = await web3Modal.connect();
    setInjectedProvider(new Web3Provider(provider));
  }, [setInjectedProvider]);

  useEffect(() => {
    if (web3Modal.cachedProvider) {
      loadWeb3Modal();
    }
  }, [loadWeb3Modal]);

  const [route, setRoute] = useState();
  useEffect(() => {
    setRoute(window.location.pathname);
  }, [setRoute]);

  let faucetHint = "";
  const faucetAvailable = localProvider && localProvider.connection && targetNetwork.name == "localhost";

  const [faucetClicked, setFaucetClicked] = useState(false);
  if (
    !faucetClicked &&
    localProvider &&
    localProvider._network &&
    localProvider._network.chainId == 31337 &&
    yourLocalBalance &&
    formatEther(yourLocalBalance) <= 0
  ) {
    faucetHint = (
      <div style={{ padding: 16 }}>
        <Button
          type="primary"
          onClick={() => {
            faucetTx({
              to: address,
              value: parseEther("0.01"),
            });
            setFaucetClicked(true);
          }}
        >
          ? Grab funds from the faucet ⛽️
        </Button>
      </div>
    );
  }

  const isSigner = injectedProvider && injectedProvider.getSigner && injectedProvider.getSigner()._isSigner;

  const [loading, setLoading] = useState();

  const [result, setResult] = useState();

  const [email, setEmail] = useState();

  let display = "";
  if (result) {
    // maybe you want to check of the backend supplied a transaction id to look up?
    // let possibleTxId = result.substr(-66)
    // console.log("possibleTxId",possibleTxId)
    // let extraLink = ""
    // if(possibleTxId.indexOf("0x")==0){
    //  extraLink = <a href={blockExplorer+"tx/"+possibleTxId} target="_blank">view transaction on etherscan</a>
    // }else{
    //  possibleTxId=""
    // }

    // maybe you want to parse and display a youtube if the link is to a video?
    if (result.indexOf("https://youtu.be/") == 0) {
      display = (
        <div style={{ marginTop: 32 }}>
          <div className="video-responsive">
            <iframe
              width="853"
              height="480"
              src={`https://www.youtube.com/embed/${result.replace("https://youtu.be/", "")}`}
              frameBorder="0"
              allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
              allowFullScreen
              title="Embedded youtube"
            />
          </div>
        </div>
      );
    } else {
      display = (
        <div style={{ marginTop: 32 }}>
          <ReactMarkdown>{result}</ReactMarkdown>
        </div>
      );
    }
  } else if (isSigner) {
    display = (
      <div>
        <div style={{ width: 400, margin: "auto", marginTop: 32 }}>
          <div>Enter your email to receive updates:</div>
          <Input
            placeholder="[email protected]"
            value={email}
            onChange={e => {
              setEmail(e.target.value);
            }}
          />
        </div>
        <Button
          disabled={!email}
          loading={loading}
          style={{ marginTop: 32 }}
          type="primary"
          onClick={async () => {
            setLoading(true);
            try {
              const msgToSign = await axios.get(serverUrl);
              console.log("msgToSign", msgToSign);
              if (msgToSign.data && msgToSign.data.length > 32) {
                // <--- traffic escape hatch?
                let currentLoader = setTimeout(() => {
                  setLoading(false);
                }, 4000);
                const message = msgToSign.data.replace("**EMAIL**", email);
                const sig = await userProvider.send("personal_sign", [message, address]);
                clearTimeout(currentLoader);
                currentLoader = setTimeout(() => {
                  setLoading(false);
                }, 4000);
                console.log("sig", sig);
                const res = await axios.post(serverUrl, {
                  email,
                  address,
                  message,
                  signature: sig,
                });
                clearTimeout(currentLoader);
                setLoading(false);
                console.log("RESULT:", res);
                if (res.data) {
                  setResult(res.data);
                }
              } else {
                setLoading(false);
                setResult(
                  "? Sorry, the server is overloaded. ⏳ Maybe just email [email protected] and I'll add you to the list manually ?",
                );
              }
            } catch (e) {
              message.error(" Sorry, the server is overloaded. ???");
              console.log("FAILED TO GET...");
            }
          }}
        >
          <span style={{ marginRight: 8 }}>?</span> <span style={{ marginRight: 8 }}>sign as </span>
          <Address noLink style={{ zIndex: -1 }} value={address} fontSize={16} ensProvider={mainnetProvider} />
        </Button>
      </div>
    );
  }

  return (
    <div className="App">
      {/* ✏️ Edit the header and change the title to your project name */}
      <Header />

      {networkDisplay}

      <div style={{ width: 500, margin: "auto", marginTop: 32 }}>
        <img src="./moonshot.gif" style={{ minWidth: 524 }} />

        <div style={{ marginTop: 16 }}>
          For the first time ever it's possible to program our values into our money. We value coordination, so why not
          use programmable money to create better coordination tools?
        </div>
        <div style={{ marginTop: 16 }}>
          The moonshot collective is a group of builders & web3 community members who are looking to prototype
          experiments in coordination (whether thats public goods, private goods, governance tools).
        </div>
        <div style={{ marginTop: 16 }}>Got dev skills + want to help build the future? Get Involved:</div>
      </div>

      <div style={{ textAlign: "center", padding: 10, marginTop: 32 }}>
        <Account
          connectText={
            <div>
              <img src="./rocket_3.svg" style={{ position: "absolute", left: -54, top: -4, maxHeight: 48 }} />
              Connect Ethereum Wallet
            </div>
          }
          onlyShowButton={!isSigner}
          address={address}
          localProvider={localProvider}
          userProvider={userProvider}
          mainnetProvider={mainnetProvider}
          price={price}
          web3Modal={web3Modal}
          loadWeb3Modal={loadWeb3Modal}
          logoutOfWeb3Modal={logoutOfWeb3Modal}
          blockExplorer={blockExplorer}
        />
        {faucetHint}
      </div>

      {display}

      <div style={{ paddingTop: 64 }}>
        <h1>First Meeting: Monday, July 19!!!</h1>
      </div>
      <div>
        Please support the:
        <a href="https://gitcoin.co/grants/3004/moonshot-collective" target="_blank">
          Gitcoin Grant
        </a>
      </div>
    </div>
  );
}
Example #24
Source File: App.jsx    From moonshot with MIT License 4 votes vote down vote up
function App(props) {
  const mainnetProvider = scaffoldEthProvider && scaffoldEthProvider._network ? scaffoldEthProvider : mainnetInfura;

  const [injectedProvider, setInjectedProvider] = useState();
  /* ? This hook will get the price of ETH from ? Uniswap: */
  const price = useExchangePrice(targetNetwork, mainnetProvider);

  /* ? This hook will get the price of Gas from ⛽️ EtherGasStation */
  const gasPrice = useGasPrice(targetNetwork, "fast");
  // Use your injected provider from ? Metamask or if you don't have it then instantly generate a ? burner wallet.
  const userProvider = useUserProvider(injectedProvider, localProvider);
  const address = useUserAddress(userProvider);

  // You can warn the user if you would like them to be on a specific network
  const localChainId = localProvider && localProvider._network && localProvider._network.chainId;
  const selectedChainId = userProvider && userProvider._network && userProvider._network.chainId;

  // For more hooks, check out ?eth-hooks at: https://www.npmjs.com/package/eth-hooks

  // The transactor wraps transactions and provides notificiations
  const tx = Transactor(userProvider, gasPrice);

  // Faucet Tx can be used to send funds from the faucet
  const faucetTx = Transactor(localProvider, gasPrice);

  // ? scaffold-eth is full of handy hooks like this one to get your balance:
  const yourLocalBalance = useBalance(localProvider, address);
  const mainnetBalance = useBalance(injectedProvider, address);

  // Just plug in different ? providers to get your balance on different chains:
  // const yourMainnetBalance = useBalance(mainnetProvider, address);

  // Load in your local ? contract and read a value from it:
  // const readContracts = useContractLoader(localProvider)

  // If you want to make ? write transactions to your contracts, use the userProvider:
  // const writeContracts = useContractLoader(userProvider)

  // EXTERNAL CONTRACT EXAMPLE:
  //
  // If you want to bring in the mainnet DAI contract it would look like:
  //  const mainnetDAIContract = useExternalContractLoader(mainnetProvider, DAI_ADDRESS, DAI_ABI)

  // If you want to call a function on a new block
  useOnBlock(mainnetProvider, () => {
    console.log(`⛓ A new mainnet block is here: ${mainnetProvider._lastBlockNumber}`);
  });

  // Then read your DAI balance like:
  //  const myMainnetDAIBalance = useContractReader({DAI: mainnetDAIContract},"DAI", "balanceOf",["0x34aA3F359A9D614239015126635CE7732c18fDF3"])

  // keep track of a variable from the contract in the local React state:
  // const purpose = useContractReader(readContracts,"YourContract", "purpose")

  // ? Listen for broadcast events
  // const setPurposeEvents = useEventListener(readContracts, "YourContract", "SetPurpose", localProvider, 1);

  /*
  const addressFromENS = useResolveName(mainnetProvider, "austingriffith.eth");
  console.log("? Resolved austingriffith.eth as:",addressFromENS)
  */

  //
  // ? DEBUG ??‍?
  //
  useEffect(() => {
    if (
      DEBUG &&
      mainnetProvider &&
      address &&
      selectedChainId &&
      yourLocalBalance /* &&  yourMainnetBalance &&readContracts && writeContracts && mainnetDAIContract */
    ) {
      console.log("_____________________________________ ? scaffold-eth _____________________________________");
      console.log("? mainnetProvider", mainnetProvider);
      console.log("? localChainId", localChainId);
      console.log("?‍? selected address:", address);
      console.log("??‍♂️ selectedChainId:", selectedChainId);
      console.log("? yourLocalBalance", yourLocalBalance ? formatEther(yourLocalBalance) : "...");
      /* console.log("? yourMainnetBalance",yourMainnetBalance?formatEther(yourMainnetBalance):"...") */
      /*  console.log("? readContracts",readContracts) */
      /* console.log("? DAI contract on mainnet:",mainnetDAIContract) */
      /*  console.log("? writeContracts",writeContracts) */
    }
  }, [
    mainnetProvider,
    address,
    selectedChainId,
    yourLocalBalance /* yourMainnetBalance, readContracts, writeContracts, mainnetDAIContract */,
  ]);

  const loadWeb3Modal = useCallback(async () => {
    const provider = await web3Modal.connect();
    setInjectedProvider(new Web3Provider(provider));
  }, [setInjectedProvider]);

  const disconnectWallet = useCallback(() => {
    console.log("logging out..");
    logoutOfWeb3Modal();
  }, [injectedProvider]);

  useEffect(() => {
    if (web3Modal.cachedProvider) {
      loadWeb3Modal();
    }
  }, [loadWeb3Modal]);

  const [route, setRoute] = useState();
  useEffect(() => {
    setRoute(window.location.pathname);
  }, [setRoute]);

  let faucetHint = "";
  const faucetAvailable = localProvider && localProvider.connection && targetNetwork.name == "localhost";

  const [faucetClicked, setFaucetClicked] = useState(false);
  if (
    !faucetClicked &&
    localProvider &&
    localProvider._network &&
    localProvider._network.chainId == 31337 &&
    yourLocalBalance &&
    formatEther(yourLocalBalance) <= 0
  ) {
    faucetHint = (
      <div style={{ padding: 16 }}>
        <Button
          type="primary"
          onClick={() => {
            faucetTx({
              to: address,
              value: parseEther("0.01"),
            });
            setFaucetClicked(true);
          }}
        >
          ? Grab funds from the faucet ⛽️
        </Button>
      </div>
    );
  }

  const isSigner = injectedProvider && injectedProvider.getSigner && injectedProvider.getSigner()._isSigner;

  const [loading, setLoading] = useState();

  const [result, setResult] = useState();

  const [email, setEmail] = useState("");

  const display = "";
  // if (result) {
  // maybe you want to check of the backend supplied a transaction id to look up?
  // let possibleTxId = result.substr(-66)
  // console.log("possibleTxId",possibleTxId)
  // let extraLink = ""
  // if(possibleTxId.indexOf("0x")==0){
  //  extraLink = <a href={blockExplorer+"tx/"+possibleTxId} target="_blank">view transaction on etherscan</a>
  // }else{
  //  possibleTxId=""
  // }

  // maybe you want to parse and display a youtube if the link is to a video?
  //   if (result.indexOf("https://youtu.be/") == 0) {
  //     display = (
  //       <div style={{ marginTop: 32 }}>
  //         <div className="video-responsive">
  //           <iframe
  //             width="853"
  //             height="480"
  //             src={`https://www.youtube.com/embed/${result.replace("https://youtu.be/", "")}`}
  //             frameBorder="0"
  //             allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
  //             allowFullScreen
  //             title="Embedded youtube"
  //           />
  //         </div>
  //       </div>
  //     );
  //   } else {
  //     display = (
  //       <div style={{ marginTop: 32 }}>
  //         <ReactMarkdown>{result}</ReactMarkdown>
  //       </div>
  //     );
  //   }
  // } else if (isSigner) {
  //   display = (
  //     <div>
  //       <div style={{ width: 400, margin: "auto", marginTop: 32 }}>
  //         <div>Enter your email to receive updates:</div>
  //         <Input
  //           placeholder="[email protected]"
  //           value={email}
  //           onChange={e => {
  //             setEmail(e.target.value);
  //           }}
  //         />
  //       </div>
  //       <Button
  //         disabled={!email}
  //         loading={loading}
  //         style={{ marginTop: 32 }}
  //         type="primary"
  //         onClick={async () => {
  //           setLoading(true);
  //           try {
  //             const msgToSign = await axios.get(serverUrl);
  //             console.log("msgToSign", msgToSign);
  //             if (msgToSign.data && msgToSign.data.length > 32) {
  //               // <--- traffic escape hatch?
  //               let currentLoader = setTimeout(() => {
  //                 setLoading(false);
  //               }, 4000);
  //               const message = msgToSign.data.replace("**EMAIL**", email);
  //               const sig = await userProvider.send("personal_sign", [message, address]);
  //               clearTimeout(currentLoader);
  //               currentLoader = setTimeout(() => {
  //                 setLoading(false);
  //               }, 4000);
  //               console.log("sig", sig);
  //               const res = await axios.post(serverUrl, {
  //                 email,
  //                 address,
  //                 message,
  //                 signature: sig,
  //               });
  //               clearTimeout(currentLoader);
  //               setLoading(false);
  //               console.log("RESULT:", res);
  //               if (res.data) {
  //                 setResult(res.data);
  //               }
  //             } else {
  //               setLoading(false);
  //               setResult(
  //                 "? Sorry, the server is overloaded. ⏳ Maybe just email [email protected] and I'll add you to the list manually ?",
  //               );
  //             }
  //           } catch (e) {
  //             message.error(" Sorry, the server is overloaded. ???");
  //             console.log("FAILED TO GET...");
  //           }
  //         }}
  //       >
  //         <span style={{ marginRight: 8 }}>?</span> <span style={{ marginRight: 8 }}>sign as </span>
  //         <Address noLink style={{ zIndex: -1 }} value={address} fontSize={16} ensProvider={mainnetProvider} />
  //       </Button>
  //     </div>
  //   );
  // }

  const signAndSubscribe = async () => {
    setLoading(true);
    try {
      const msgToSign = await axios.get(serverUrl);
      console.log("msgToSign", msgToSign);
      if (msgToSign.data && msgToSign.data.length > 32) {
        // <--- traffic escape hatch?
        // let currentLoader = setTimeout(() => {
        //   setLoading(false);
        // }, 4000);
        const message = msgToSign.data.replace("**EMAIL**", email);
        const sig = await userProvider.send("personal_sign", [message, address]);
        // clearTimeout(currentLoader);
        // currentLoader = setTimeout(() => {
        //   setLoading(false);
        // }, 4000);
        console.log("sig", sig);
        const res = await axios.post(serverUrl, {
          email,
          address,
          message,
          signature: sig,
        });
        // clearTimeout(currentLoader);
        setLoading(false);
        setEmail("");
        console.log("RESULT:", res);
        if (res.data) {
          setResult(res.data);
        }
      } else {
        setLoading(false);
        setResult(
          "? Sorry, the server is overloaded. ⏳ Maybe just email [email protected] and I'll add you to the list manually ?",
        );
      }
    } catch (e) {
      setLoading(false);
      message.error(" Sorry, the server is overloaded. ???");
      console.log("FAILED TO GET...");
    }
  };

  const [walletMenu, setWalletMenu] = useState(false);
  const [pageMenu, setPageMenu] = useState(false);
  const [statics, setStatics] = useState({ members: [], projects: [] });

  useEffect(() => {
    (async () => {
      const fetchStatics = async () => await axios.get("/static-info.json");
      try {
        const { data } = await fetchStatics();
        setStatics(data);
      } catch (e) {
        console.error("fetch statics failed");
      }
    })();
  }, []);

  return (
    <div>
      {/* HEADER */}
      <header>
        {/* left logo */}
        <div className="header-logo">
          <a data-kinetics-attraction href="/">
            {/* pls load as regular svg inline with react */}
            {/* <object type="image/svg+xml" data="assets/images/logo-moon.svg" /> */}
            {/* <LogoMoon /> */}
            {/* <img src={LogoMoonSvg} /> */}
            {/* <ReactSVG src="assets/images/logo-moon.svg" /> */}
            <SVG src="assets/images/logo-moon.svg" height="auto" />
          </a>
        </div>
        {/* right nav */}
        <div className="header-navigation">
          {/* page navigation */}
          <nav id="pageMenu" className={pageMenu && "visible"}>
            <ul>
              <a href>
                <li aria-current="page">Home</li>
              </a>
              <a
                target="_Blank"
                href=" https://gitcoin.notion.site/Moonshot-Collective-e8a5bbb2b6f3494db109849d159e1b51"
              >
                <li>Notion</li>
              </a>
              <a target="_Blank" href="https://discord.gg/SdKHH4brrE">
                <li>Discord</li>
              </a>
              <a target="_Blank" href="https://github.com/moonshotcollective">
                <li>GitHub</li>
              </a>
            </ul>
          </nav>
          {/* mobile buger ui */}
          <div data-kinetics-attraction className="burger">
            <div id="openMenu" className={classnames("icon", pageMenu && "hide")} onClick={() => setPageMenu(true)}>
              {/* pls load "assets/images/menu.svg" inline instead */}
              <SVG src="assets/images/menu.svg" />
              {/* <svg xmlns="http://www.w3.org/2000/svg" width={64} height={64} viewBox="0 0 64 64">
                <line x1={16} y1={32} x2={48} y2={32} />
                <line x1={16} y1={20} x2={48} y2={20} />
                <line x1={16} y1={44} x2={48} y2={44} />
              </svg> */}
            </div>
            <div id="closeMenu" className={classnames("icon", !pageMenu && "hide")} onClick={() => setPageMenu(false)}>
              {/* pls load "assets/images/close.svg" inline instead */}
              <SVG src="assets/images/close.svg" />
              {/* <svg xmlns="http://www.w3.org/2000/svg" width={64} height={64} viewBox="0 0 64 64">
                <line x1={16} y1={16} x2={48} y2={48} />
                <line x1={48} y1={16} x2={16} y2={48} />
              </svg> */}
            </div>
          </div>
          {isSigner && (
            <div
              id="openWalletMenu"
              className="wallet-status"
              data-kinetics-attraction
              onClick={() => setWalletMenu(true)}
            >
              {/* example ( will probably come from walletconnect i assume ) */}
              <SVG src="assets/images/metamask.svg" width="48px" height="48px" />
              {/* <img
                id="openWalletMenu"
                src="assets/images/metamask.svg"
                alt=""
                style={{ width: "48px", height: "48px", marginLeft: "0em" }}
              /> */}
            </div>
          )}
          {/* wallet */}
          {/* <div id="openWalletMenu" className="wallet-status" data-kinetics-attraction> */}
          <div className="provider" onClick={loadWeb3Modal}>
            {/* hide if connected to a provider */}
            {!isSigner && (
              <div className="icon">
                {/* pls load "assets/images/wallet.svg" inline instead */}
                <SVG src="assets/images/wallet.svg" />
                {/* <svg xmlns="http://www.w3.org/2000/svg" width={64} height={64} viewBox="0 0 64 64" fill="none">
                  <path d="M52 26V16a4 4 0 0 0-4-4H12a4 4 0 0 0-4 4v32a4 4 0 0 0 4 4h36a4 4 0 0 0 4-4V38" />
                  <rect x={48} y={26} width={8} height={12} />
                </svg> */}
              </div>
            )}
            {/* hide if not connected to a provider */}
          </div>
        </div>
      </header>
      {/* WALLET-MENU */}
      <div id="walletMenu" className={classnames("wallet-menu", walletMenu && "visible")}>
        <div id="closeWalletMenu" className="action" onClick={() => setWalletMenu(false)}>
          <span>Wallet</span>
          <div className="icon">
            {/* pls load "assets/images/close.svg" inline instead */}
            <SVG src="assets/images/close.svg" width="64px" height="64px" />
            {/* <svg xmlns="http://www.w3.org/2000/svg" width={64} height={64} viewBox="0 0 64 64">
              <line x1={16} y1={16} x2={48} y2={48} />
              <line x1={48} y1={16} x2={16} y2={48} />
            </svg> */}
          </div>
        </div>
        <div className="wallet-detail" style={selectedChainId !== 1 ? { background: "none" } : null}>
          {selectedChainId === 1 ? (
            <>
              <div className="network">mainnet</div>
              <div className="address">{formatAddress(address)}</div>
              <div className="balance">
                {mainnetBalance ? parseFloat(formatEther(mainnetBalance).toString()).toFixed(2) : "..."} ETH
              </div>
            </>
          ) : (
            <div>Wrong chain. Please connect to mainnet.</div>
          )}
          {/* <div className="token">1337 MATIC</div> */}
        </div>
        {/* <div className="action">
          <span>Change Provider</span>
          <div className="icon">
            <svg xmlns="http://www.w3.org/2000/svg" width={64} height={64} viewBox="0 0 64 64">
              <polygon points="8 20 8 44 32 56 56 44 56 20 32 8 8 20" />
              <line x1={32} y1={32} x2={56} y2={20} />
              <line x1={32} y1={56} x2={32} y2={32} />
              <line x1={56} y1={44} x2={32} y2={32} />
              <line x1={8} y1={44} x2={32} y2={32} />
              <line x1={8} y1={20} x2={32} y2={32} />
              <line x1={32} y1={8} x2={32} y2={32} />
            </svg>
          </div>
        </div> */}
        {/* <div className="action">
          <span>Connect</span>
          <div className="icon">
            <svg xmlns="http://www.w3.org/2000/svg" width={64} height={64} viewBox="0 0 64 64">
              <path d="M49,15A24,24,0,1,1,15,15" />
              <line x1={32} y1={8} x2={32} y2={32} />
            </svg>
          </div>
        </div> */}
        <div className="action" onClick={disconnectWallet}>
          <span>Disconnect</span>
          <div className="icon">
            {/* pls load "assets/images/disconnect.svg" inline instead */}
            <SVG src="assets/images/disconnect.svg" />
            {/* <svg xmlns="http://www.w3.org/2000/svg" width={64} height={64} viewBox="0 0 64 64">
              <path d="M49,15A24,24,0,1,1,15,15" />
              <line x1={32} y1={8} x2={32} y2={32} />
            </svg> */}
          </div>
        </div>
      </div>
      {/* INTRO */}
      <article id="intro">
        <section className="content-intro">
          <div>
            <h1>What</h1>
            <p>
              The moonshot collective is a collection of builders & web3 community members who are looking to prototype
              experiments in coordination (whether thats public goods, private goods, governance tools).
            </p>
            <div style={{ fontSize: 22, marginTop: 32 }}>Got dev skills + want to help build the future?</div>
            <div style={{ fontSize: 32, marginTop: 32 }}>
              <a href="#subscribe">Get Involved.</a>
            </div>
          </div>
          <figure>
            {/* not needed to be inline */}
            <img src="assets/images/collab-animation.svg" />
          </figure>
        </section>
      </article>
      {/* moonify filter ( transform images yellow ) */}
      <svg>
        <filter id="moonify">
          <feColorMatrix
            colorInterpolationFilters="sRGB"
            type="matrix"
            values="1 0 0 0 0 0 0.8 0 0 0 0 0 0 0 0 0 0 0 1 0"
          />
        </filter>
      </svg>
      {/* MEMBERS */}
      {/* the images will be probably be replaced by a lot regular images i assume */}
      <article id="members">
        <section className="column">
          <h1>Who</h1>
        </section>
        <section className="content-members">
          <figure data-kinetics-attraction>
            <a href="#">
              <img className="moonify" src="assets/images/members/test.jpg" />
              <figcaption>Austin</figcaption>
            </a>
          </figure>
          {statics.members.map(({ name }) => (
            <figure data-kinetics-attraction key={name}>
              <a href="#">
                <img src="assets/images/moon-40.svg" />
                <figcaption>{name}</figcaption>
              </a>
            </figure>
          ))}
          <figure data-kinetics-attraction>
            <a href="#">
              <img src="assets/images/moon-100.svg" />
              <figcaption>You</figcaption>
            </a>
          </figure>
        </section>
      </article>
      {/* EXPLAIN */}
      <article id="explain">
        <section className="column">
          <h1>How it works</h1>
          <p>
            Moonshot collective provides ideas, devs, funding as builders grow their public goods funding experiments.
          </p>
        </section>
        <section className="content-explain">
          <figure data-kinetics-attraction>
            <SVG src="assets/images/prototype.svg" />
            <figcaption>
              <span>1.</span>Prototype
            </figcaption>
          </figure>
          <figure data-kinetics-attraction>
            <SVG src="assets/images/marketvalidation.svg" />
            {/* <object type="image/svg+xml" data="assets/images/marketvalidation.svg" /> */}
            <figcaption>
              <span>2.</span>Market Validation
            </figcaption>
          </figure>
          <figure data-kinetics-attraction>
            <SVG src="assets/images/growth.svg" />
            <figcaption>
              <span>3.</span>Growth
            </figcaption>
          </figure>
          <figure data-kinetics-attraction>
            <SVG src="assets/images/decentralize.svg" />
            <figcaption>
              <span>4.</span>Decentralize
            </figcaption>
          </figure>
        </section>
      </article>
      {/* PROECTS */}
      <article id="projects">
        <section className="column">
          <h1>Projects</h1>
        </section>
        <section className="content-projects">
          {statics.projects.map(({ name, link }) => (
            <figure data-kinetics-attraction key={name}>
              <a href={link}>
                <SVG src="assets/images/project-3.svg" />
                <figcaption>{name}</figcaption>
              </a>
            </figure>
          ))}
          <figure data-kinetics-attraction>
            <a href="#">
              {/* pls load as regular svg line with react */}
              <SVG src="assets/images/project-7.svg" />
              {/* <object type="image/svg+xml" data="assets/images/project-7.svg" /> */}
              <figcaption>Yours</figcaption>
            </a>
          </figure>
        </section>
      </article>
      {/* SUBSCRIBE */}
      <article id="subscribe">
        <section className="column">
          <h1>Get Involved</h1>
          <p>Are you a builder who wants to work on public goods? Click below to join the workstream email group.</p>
        </section>
        <section className="content-subscribe">
          {isSigner ? (
            <>
              <div className="wrapper">
                <input
                  type="text"
                  name
                  placeholder="moon@shot"
                  value={email}
                  onChange={e => setEmail(e.target.value)}
                />
              </div>
              <button
                data-kinetics-attraction
                className="btn"
                disabled={email.indexOf("@") === -1 || loading}
                type="button"
                onClick={signAndSubscribe}
              >
                {!loading ? "Sign and subscribe" : "Loading.."}
              </button>
              <p style={{ marginTop: "20px" }}>{result}</p>
              {/* <span style={{ marginRight: 8 }}>?</span> <span style={{ marginRight: 8 }}>sign as </span>
              <Address noLink style={{ zIndex: -1 }} value={address} fontSize={16} ensProvider={mainnetProvider} /> */}
            </>
          ) : (
            <button data-kinetics-attraction className="btn" onClick={loadWeb3Modal}>
              Connect wallet
            </button>
          )}
        </section>
      </article>
      <footer>
        <div className="wrapper" style={{ marginBottom: "40px" }}>
          {/* pls load as regular svg inline with react */}
          <figure data-kinetics-attraction>
            <SVG src="assets/images/colorado.svg" />
          </figure>
          <div>
            Built with &lt;3 in Colorado
            <br />
            <a href="https://twitter.com/MoonshotCollect">Twitter</a> |{" "}
            <a href="https://www.youtube.com/channel/UCfbOba7iD19HyrB9QbV6Uww">YouTube</a> |{" "}
            <a href="https://buidlguidl.com">Buidl Guidl</a>
            <br />
            <a href="https://gitcoin.co">Gitcoin</a> | <a href="https://gitcoin.co/discord">Gitcoin Discord</a> |{" "}
            <a href="https://gov.gitcoin.co/">Gitcoin Governance</a>
          </div>
        </div>
      </footer>
    </div>
  );
}