-
-
Save robksawyer/0af079e4a1b2a241cc648be9eb89df4e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Autogenerated file. Do not edit manually. */ | |
/* tslint:disable */ | |
/* eslint-disable */ | |
import { providers, Signer, ethers } from "ethers"; | |
import React, { useEffect, useState } from "react"; | |
import Web3Modal, { IProviderOptions } from "web3modal"; | |
const emptyContract = { | |
instance: undefined, | |
factory: undefined | |
}; | |
const defaultProvider: providers.Provider | undefined = undefined; | |
export const ProviderContext = React.createContext<[providers.Provider | undefined, React.Dispatch<React.SetStateAction<providers.Provider | undefined>>]>([defaultProvider, () => { }]); | |
const defaultCurrentAddress: string = ""; | |
export const CurrentAddressContext = React.createContext<[string, React.Dispatch<React.SetStateAction<string>>]>([defaultCurrentAddress, () => { }]); | |
const defaultSigner: Signer | undefined = undefined; | |
export const SignerContext = React.createContext<[Signer | undefined, React.Dispatch<React.SetStateAction<Signer | undefined>>]>([defaultSigner, () => { }]); | |
const defaultSymfoniContext: SymfoniContextInterface = { | |
currentHardhatProvider: "", | |
init: () => { throw Error("Symfoni context not initialized") }, | |
loading: false, | |
messages: [], | |
providers: [] | |
}; | |
export const SymfoniContext = React.createContext<SymfoniContextInterface>(defaultSymfoniContext); | |
export interface SymfoniContextInterface { | |
init: (provider?: string) => void; | |
loading: boolean; | |
messages: string[]; | |
currentHardhatProvider: string; | |
providers: string[]; | |
} | |
export interface SymfoniProps { | |
autoInit?: boolean; | |
showLoading?: boolean; | |
loadingComponent?: React.ReactNode; | |
} | |
export const Symfoni: React.FC<SymfoniProps> = ({ | |
showLoading = true, | |
autoInit = true, | |
...props | |
}) => { | |
const [initializeCounter, setInitializeCounter] = useState(0); | |
const [currentHardhatProvider, setCurrentHardhatProvider] = useState(""); | |
const [loading, setLoading] = useState(false); | |
const [messages, setMessages] = useState<string[]>([]); | |
const [signer, setSigner] = useState<Signer | undefined>(defaultSigner); | |
const [provider, setProvider] = useState<providers.Provider | undefined>(defaultProvider); | |
const [currentAddress, setCurrentAddress] = useState<string>(defaultCurrentAddress); | |
const [fallbackProvider] = useState<string | undefined>(undefined); | |
const [providerPriority, setProviderPriority] = useState<string[]>(["web3modal", "hardhat"]); | |
useEffect(() => { | |
if (messages.length > 0) | |
console.debug(messages.pop()) | |
}, [messages]) | |
const getProvider = async (): Promise<{ provider: providers.Provider, hardhatProviderName: string } | undefined> => { | |
let hardhatProviderName = "Not set"; | |
let _providerPriority = [...providerPriority]; | |
// Fallback provider | |
if (fallbackProvider && autoInit && initializeCounter === 0) { | |
if (localStorage.getItem("WEB3_CONNECT_CACHED_PROVIDER") === null) { | |
_providerPriority = _providerPriority.sort((a, b) => { | |
return a === fallbackProvider ? -1 : b === fallbackProvider ? 1 : 0; | |
}) | |
} | |
} | |
const provider = await _providerPriority.reduce(async (maybeProvider: Promise<providers.Provider | undefined>, providerIdentification) => { | |
let foundProvider = await maybeProvider | |
if (foundProvider) { | |
return Promise.resolve(foundProvider) | |
} | |
else { | |
switch (providerIdentification.toLowerCase()) { | |
case "web3modal": | |
try { | |
const provider = await getWeb3ModalProvider() | |
const web3provider = new ethers.providers.Web3Provider(provider); | |
hardhatProviderName = "web3modal"; | |
return Promise.resolve(web3provider) | |
} catch (error) { | |
return Promise.resolve(undefined) | |
} | |
case "hardhat": | |
try { | |
const provider = new ethers.providers.JsonRpcProvider({ | |
url: "http://127.0.0.1:8545", | |
}); | |
hardhatProviderName = "hardhat"; | |
return Promise.resolve(provider) | |
} catch (error) { | |
return Promise.resolve(undefined) | |
} default: | |
return Promise.resolve(undefined) | |
} | |
} | |
}, Promise.resolve(undefined)) // end reduce | |
return provider ? { provider, hardhatProviderName } : undefined | |
}; | |
const getSigner = async (_provider: providers.Provider, hardhatProviderName: string): Promise<Signer | undefined> => { | |
switch (hardhatProviderName) { | |
case "web3modal": | |
const web3provider = _provider as ethers.providers.Web3Provider | |
return await web3provider.getSigner() | |
case "hardhat": | |
return ethers.Wallet.fromMnemonic("test test test test test test test test test test test junk").connect(_provider) | |
default: | |
return undefined | |
} | |
}; | |
const getWeb3ModalProvider = async (): Promise<any> => { | |
const providerOptions: IProviderOptions = { | |
}; | |
const web3Modal = new Web3Modal({ | |
// network: "mainnet", | |
cacheProvider: false, | |
providerOptions, // required | |
}); | |
return await web3Modal.connect(); | |
}; | |
useEffect(() => { | |
let subscribed = true | |
const doAsync = async () => { | |
const finish = (text: string) => { | |
setLoading(false) | |
setMessages(old => [...old, text]) | |
} | |
const finishWithContracts = (text: string) => { | |
finish(text) | |
} | |
if (!autoInit && initializeCounter === 0) return finish("Auto init turned off.") | |
setLoading(true) | |
setMessages(old => [...old, "Initiating Symfoni React"]) | |
const providerObject = await getProvider() // getProvider can actually return undefined, see issue https://github.com/microsoft/TypeScript/issues/11094 | |
if (!subscribed || !providerObject) return finish("No provider or signer.") | |
const _provider = providerObject.provider | |
setProvider(_provider) | |
setMessages(old => [...old, "Useing " + providerObject.hardhatProviderName]) | |
setCurrentHardhatProvider(providerObject.hardhatProviderName) | |
const _signer = await getSigner(_provider, providerObject.hardhatProviderName); | |
if (!subscribed || !_signer) return finishWithContracts("Provider, without signer.") | |
setSigner(_signer) | |
setMessages(old => [...old, "Useing signer"]) | |
const address = await _signer.getAddress() | |
if (!subscribed || !address) return finishWithContracts("Provider and signer, without address.") | |
setCurrentAddress(address) | |
return finishWithContracts("Completed Symfoni context initialization.") | |
}; | |
doAsync(); | |
return () => { subscribed = false } | |
}, [initializeCounter]) | |
const handleInitProvider = (provider?: string) => { | |
if (provider) { | |
setProviderPriority(old => old.sort((a, b) => { | |
return a === provider ? -1 : b === provider ? 1 : 0; | |
})) | |
} | |
setInitializeCounter(initializeCounter + 1) | |
} | |
return ( | |
<SymfoniContext.Provider value={{ init: (provider) => handleInitProvider(provider), providers: providerPriority, currentHardhatProvider, loading, messages }}> | |
<ProviderContext.Provider value={[provider, setProvider]}> | |
<SignerContext.Provider value={[signer, setSigner]}> | |
<CurrentAddressContext.Provider value={[currentAddress, setCurrentAddress]}> | |
{showLoading && loading ? | |
props.loadingComponent | |
? props.loadingComponent | |
: <div> | |
{messages.map((msg, i) => ( | |
<p key={i}>{msg}</p> | |
))} | |
</div> | |
: props.children | |
} | |
</CurrentAddressContext.Provider> | |
</SignerContext.Provider> | |
</ProviderContext.Provider> | |
</SymfoniContext.Provider> | |
) | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment