import { Vessel } from "@opensea/vessel" import { CreateEmbeddedWalletPayload, CreateEmbeddedWalletResponse, GetUserResponse, LoginWithCodeResponse, SendLoginCodePayload, SendLoginCodeResponse, } from "@opensea/wallet-messages" import { EIP1193Provider } from "./EIP1193Provider" import { getState } from "./intialize" let provider: EIP1193Provider | undefined = undefined export const getProvider = async () => { if (typeof document === "undefined") { return undefined } const { vessel } = await getState() if (!provider) { provider = new EIP1193Provider({ vessel }) } return provider } const getProviderStrict = async () => { const provider = await getProvider() if (!provider) { throw new Error("Wallet module not initialized") } return provider } type Address = `0x${string}` type ConnectResponse = { accounts: readonly Address[] chainId: number } const CONNECTION_TIMEOUT_MS = 5_000 export const connect = async (): Promise => { const timeout = setTimeout(() => { throw new Error("Connect method timed out") }, CONNECTION_TIMEOUT_MS) if (typeof document === "undefined") { return { accounts: [], chainId: 1 } } const provider = await getProviderStrict() const [accounts, chainId] = await Promise.all([ provider.request({ method: "eth_accounts" }), provider.request({ method: "eth_chainId" }), ]) clearTimeout(timeout) return { accounts, chainId: Number(chainId) } } export const disconnect = async (): Promise => { const provider = await getProviderStrict() await provider.disconnect() } export const getAccounts = async (): Promise => { if (typeof document === "undefined") { return [] } const provider = await getProviderStrict() return provider.request({ method: "eth_accounts" }) } export const getChainId = async (): Promise => { if (typeof document === "undefined") { return 1 } const provider = await getProviderStrict() const chainId = await provider.request({ method: "eth_chainId" }) return Number(chainId) } export const isAuthorized = async (): Promise => { if (typeof document === "undefined") { return false } let vessel: Vessel try { vessel = await getState().then(state => state.vessel) } catch (e) { return false } try { const authenticated = await vessel.send({ type: "action", action: "CheckAuthStatus", }) return authenticated } catch (e) { console.error(e) return false } } export const switchChain = async (chainId: number): Promise => { const provider = await getProviderStrict() await provider.request({ method: "wallet_switchEthereumChain", params: [{ chainId: `0x${chainId.toString(16)}` }], }) } export const sendLoginCode = async ( email: string, ): Promise => { const { vessel } = await getState() return await vessel.send({ type: "action", action: "SendLoginCode", email, }) } export const loginWithCode = async ( code: string, ): Promise => { const { vessel } = await getState() return await vessel.send({ type: "action", action: "LoginWithCode", code, }) } export const createWallet = async (): Promise => { const { vessel } = await getState() return await vessel.send< CreateEmbeddedWalletResponse, CreateEmbeddedWalletPayload >({ type: "action", action: "CreateEmbeddedWallet", }) } export const getUser = async (): Promise => { const { vessel } = await getState() const user = await vessel.send({ type: "action", action: "GetUser", }) return user } export const exportPrivateKey = async (): Promise => { const { vessel } = await getState() await vessel.send({ type: "action", action: "ExportPrivateKey", }) }