UNPKG

@0xfutbol/id

Version:

React component library with shared providers for 0xFutbol ID

486 lines (485 loc) 18.3 kB
'use strict';var index=require('./index-gEYw6hWC.js');require('react'),require('react/jsx-runtime'),require('@0xfutbol/id-sign'),require('react-use'),require('@0xfutbol/constants'),require('thirdweb'),require('@matchain/matchid-sdk-react'),require('@tanstack/react-query'),require('@matchain/matchid-sdk-react/index.css'),require('react-dom');const getUrl = (url) => url;class RpcRequestError extends index.B { constructor({ body, error, url, }) { super('RPC Request failed.', { cause: error, details: error.message, metaMessages: [`URL: ${getUrl(url)}`, `Request body: ${index.q(body)}`], name: 'RpcRequestError', }); Object.defineProperty(this, "code", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "data", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.code = error.code; this.data = error.data; } }const unknownErrorCode = -1; class RpcError extends index.B { constructor(cause, { code, docsPath, metaMessages, name, shortMessage, }) { super(shortMessage, { cause, docsPath, metaMessages: metaMessages || cause?.metaMessages, name: name || 'RpcError', }); Object.defineProperty(this, "code", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.name = name || cause.name; this.code = (cause instanceof RpcRequestError ? cause.code : (code ?? unknownErrorCode)); } } class ProviderRpcError extends RpcError { constructor(cause, options) { super(cause, options); Object.defineProperty(this, "data", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.data = options.data; } } class UserRejectedRequestError extends ProviderRpcError { constructor(cause) { super(cause, { code: UserRejectedRequestError.code, name: 'UserRejectedRequestError', shortMessage: 'User rejected the request.', }); } } Object.defineProperty(UserRejectedRequestError, "code", { enumerable: true, configurable: true, writable: true, value: 4001 }); class SwitchChainError extends ProviderRpcError { constructor(cause) { super(cause, { code: SwitchChainError.code, name: 'SwitchChainError', shortMessage: 'An error occurred when attempting to switch chain.', }); } } Object.defineProperty(SwitchChainError, "code", { enumerable: true, configurable: true, writable: true, value: 4902 });const ADD_ETH_CHAIN_METHOD = "wallet_addEthereumChain"; const defaultShowQrModal = true; const storageKeys = { requestedChains: "tw.wc.requestedChains", lastUsedChainId: "tw.wc.lastUsedChainId", }; /** * @internal */ async function connectWC(options, emitter, walletId, storage, sessionHandler) { const provider = await initProvider(options, walletId, sessionHandler); const wcOptions = options.walletConnect; let { onDisplayUri } = wcOptions || {}; // use default sessionHandler unless onDisplayUri is explicitly provided if (!onDisplayUri && sessionHandler) { const walletInfo = await index.x(walletId); const deeplinkHandler = (uri) => { const appUrl = walletInfo.mobile.native || walletInfo.mobile.universal; if (!appUrl) { // generic wc uri sessionHandler(uri); return; } const fullUrl = index.A(appUrl, uri).redirect; sessionHandler(fullUrl); }; onDisplayUri = deeplinkHandler; } if (onDisplayUri) { provider.events.addListener("display_uri", onDisplayUri); } let optionalChains = wcOptions?.optionalChains; let chainToRequest = options.chain; // ignore the given options chains - and set the safe supported chains if (walletId === "global.safe") { optionalChains = chainsToRequestForSafe.map(index.h); if (chainToRequest && !optionalChains.includes(chainToRequest)) { chainToRequest = undefined; } } const { rpcMap, requiredChain, optionalChains: chainsToRequest, } = getChainsToRequest({ client: options.client, chain: chainToRequest, optionalChains: optionalChains, }); if (provider.session) { await provider.connect({ ...(wcOptions?.pairingTopic ? { pairingTopic: wcOptions?.pairingTopic } : {}), optionalChains: chainsToRequest, chains: requiredChain ? [requiredChain.id] : undefined, rpcMap: rpcMap, }); } setRequestedChainsIds(chainsToRequest, storage); // If session exists and chains are authorized, enable provider for required chain const addresses = await provider.enable(); const address = addresses[0]; if (!address) { throw new Error("No accounts found on provider."); } const providerChainId = index.v(provider.chainId); const chain = options.chain && options.chain.id === providerChainId ? options.chain : index.h(providerChainId); if (options) { const savedParams = { optionalChains: options.walletConnect?.optionalChains, chain: options.chain, pairingTopic: options.walletConnect?.pairingTopic, }; if (storage) { index.y(storage, walletId, savedParams); } } if (wcOptions?.onDisplayUri) { provider.events.removeListener("display_uri", wcOptions.onDisplayUri); } return onConnect(address, chain, provider, emitter, storage, options.client); } /** * Auto connect to already connected wallet connect session. * @internal */ async function autoConnectWC(options, emitter, walletId, storage, sessionHandler) { const savedConnectParams = storage ? await index.u(storage, walletId) : null; const provider = await initProvider(savedConnectParams ? { chain: savedConnectParams.chain, client: options.client, walletConnect: { pairingTopic: savedConnectParams.pairingTopic, optionalChains: savedConnectParams.optionalChains, }, } : { client: options.client, walletConnect: {}, }, walletId, sessionHandler, true); const address = provider.accounts[0]; if (!address) { throw new Error("No accounts found on provider."); } const providerChainId = index.v(provider.chainId); const chain = options.chain && options.chain.id === providerChainId ? options.chain : index.h(providerChainId); return onConnect(address, chain, provider, emitter, storage, options.client); } // Connection utils ----------------------------------------------------------------------------------------------- async function initProvider(options, walletId, sessionRequestHandler, isAutoConnect = false) { const walletInfo = await index.x(walletId); const wcOptions = options.walletConnect; const { EthereumProvider, OPTIONAL_EVENTS, OPTIONAL_METHODS } = await Promise.resolve().then(function(){return require('./index.es-NQ1EIp1U.js')}); let optionalChains = wcOptions?.optionalChains; let chainToRequest = options.chain; // ignore the given options chains - and set the safe supported chains if (walletId === "global.safe") { optionalChains = chainsToRequestForSafe.map(index.h); if (chainToRequest && !optionalChains.includes(chainToRequest)) { chainToRequest = undefined; } } const { rpcMap, requiredChain, optionalChains: chainsToRequest, } = getChainsToRequest({ client: options.client, chain: chainToRequest, optionalChains: optionalChains, }); const provider = await EthereumProvider.init({ showQrModal: wcOptions?.showQrModal === undefined ? sessionRequestHandler ? false : defaultShowQrModal : wcOptions.showQrModal, projectId: wcOptions?.projectId || index.D, optionalMethods: OPTIONAL_METHODS, optionalEvents: OPTIONAL_EVENTS, optionalChains: chainsToRequest, chains: requiredChain ? [requiredChain.id] : undefined, metadata: { name: wcOptions?.appMetadata?.name || index.z().name, description: wcOptions?.appMetadata?.description || index.z().description, url: wcOptions?.appMetadata?.url || index.z().url, icons: [ wcOptions?.appMetadata?.logoUrl || index.z().logoUrl, ], }, rpcMap: rpcMap, qrModalOptions: wcOptions?.qrModalOptions, disableProviderPing: true, }); provider.events.setMaxListeners(Number.POSITIVE_INFINITY); // disconnect the provider if chains are stale when (if not auto connecting) if (!isAutoConnect) { // const isStale = await isChainsStale(provider, chainsToRequest); if (provider.session) { await provider.disconnect(); } } if (walletId !== "walletConnect") { async function handleSessionRequest() { const walletLinkToOpen = provider.session?.peer?.metadata?.redirect?.native || walletInfo.mobile.native || walletInfo.mobile.universal; if (sessionRequestHandler && walletLinkToOpen) { // TODO: propagate error when this fails await sessionRequestHandler(walletLinkToOpen); } } provider.signer.client.on("session_request_sent", handleSessionRequest); provider.events.addListener("disconnect", () => { provider.signer.client.off("session_request_sent", handleSessionRequest); }); } return provider; } function createAccount({ provider, address, client, }) { const account = { address: address, async sendTransaction(tx) { const transactionHash = (await provider.request({ method: "eth_sendTransaction", params: [ { gas: tx.gas ? index.H(tx.gas) : undefined, value: tx.value ? index.H(tx.value) : undefined, from: index.d(address), to: tx.to, data: tx.data, }, ], })); index.t({ client: client, walletAddress: index.d(address), walletType: "walletConnect", transactionHash, chainId: tx.chainId, contractAddress: tx.to ?? undefined, gasPrice: tx.gasPrice, }); return { transactionHash, }; }, async signMessage({ message }) { const messageToSign = (() => { if (typeof message === "string") { return index.M(message); } if (message.raw instanceof Uint8Array) { return index.N(message.raw); } return message.raw; })(); return provider.request({ method: "personal_sign", params: [messageToSign, this.address], }); }, async signTypedData(_data) { const data = index.p(_data); const { domain, message, primaryType } = data; const types = { EIP712Domain: index.J({ domain }), ...data.types, }; // Need to do a runtime validation check on addresses, byte ranges, integer ranges, etc // as we can't statically check this with TypeScript. index.K({ domain, message, primaryType, types }); const typedData = index.L({ domain: domain ?? {}, message, primaryType, types, }); return await provider.request({ method: "eth_signTypedData_v4", params: [this.address, typedData], }); }, }; return account; } function onConnect(address, chain, provider, emitter, storage, client) { const account = createAccount({ provider, address, client }); async function disconnect() { provider.removeListener("accountsChanged", onAccountsChanged); provider.removeListener("chainChanged", onChainChanged); provider.removeListener("disconnect", onDisconnect); await provider.disconnect(); } function onDisconnect() { setRequestedChainsIds([], storage); storage?.removeItem(storageKeys.lastUsedChainId); disconnect(); emitter.emit("disconnect", undefined); } function onAccountsChanged(accounts) { if (accounts[0]) { const newAccount = createAccount({ provider, address: index.d(accounts[0]), client, }); emitter.emit("accountChanged", newAccount); emitter.emit("accountsChanged", accounts); } else { onDisconnect(); } } function onChainChanged(newChainId) { const newChain = index.h(index.v(newChainId)); emitter.emit("chainChanged", newChain); storage?.setItem(storageKeys.lastUsedChainId, String(newChainId)); } provider.on("accountsChanged", onAccountsChanged); provider.on("chainChanged", onChainChanged); provider.on("disconnect", onDisconnect); provider.on("session_delete", onDisconnect); return [ account, chain, disconnect, (newChain) => switchChainWC(provider, newChain, storage), ]; } // Storage utils ----------------------------------------------------------------------------------------------- function getNamespaceMethods(provider) { return provider.session?.namespaces[index.O]?.methods || []; } function getNamespaceChainsIds(provider) { const chainIds = provider.session?.namespaces[index.O]?.chains?.map((chain) => Number.parseInt(chain.split(":")[1] || "")); return chainIds ?? []; } async function switchChainWC(provider, chain, storage) { const chainId = chain.id; try { const namespaceChains = getNamespaceChainsIds(provider); const namespaceMethods = getNamespaceMethods(provider); const isChainApproved = namespaceChains.includes(chainId); if (!isChainApproved && namespaceMethods.includes(ADD_ETH_CHAIN_METHOD)) { const apiChain = await index.F(chain); const blockExplorerUrls = [ ...new Set([ ...(chain.blockExplorers?.map((x) => x.url) || []), ...(apiChain.explorers?.map((x) => x.url) || []), ]), ]; await provider.request({ method: ADD_ETH_CHAIN_METHOD, params: [ { chainId: index.H(apiChain.chainId), chainName: apiChain.name, nativeCurrency: apiChain.nativeCurrency, rpcUrls: index.G(apiChain), // no clientId on purpose blockExplorerUrls: blockExplorerUrls.length > 0 ? blockExplorerUrls : undefined, }, ], }); const requestedChains = await getRequestedChainsIds(storage); requestedChains.push(chainId); setRequestedChainsIds(requestedChains, storage); } await provider.request({ method: "wallet_switchEthereumChain", params: [{ chainId: index.H(chainId) }], }); } catch (error) { const message = typeof error === "string" ? error : error?.message; if (/user rejected request/i.test(message)) { throw new UserRejectedRequestError(error); } throw new SwitchChainError(error); } } /** * Set the requested chains to the storage. * @internal */ function setRequestedChainsIds(chains, storage) { storage?.setItem(storageKeys.requestedChains, index.s(chains)); } /** * Get the last requested chains from the storage. * @internal */ async function getRequestedChainsIds(storage) { const data = await storage.getItem(storageKeys.requestedChains); return data ? JSON.parse(data) : []; } function getChainsToRequest(options) { const rpcMap = {}; if (options.chain) { rpcMap[options.chain.id] = index.E({ chain: options.chain, client: options.client, }); } // limit optional chains to 10 const optionalChains = (options?.optionalChains || []).slice(0, 10); for (const chain of optionalChains) { rpcMap[chain.id] = index.E({ chain: chain, client: options.client, }); } if (!options.chain && optionalChains.length === 0) { rpcMap[1] = index.h(1).rpc; } return { rpcMap, requiredChain: options.chain ? options.chain : undefined, optionalChains: optionalChains.length > 0 ? optionalChains.map((x) => x.id) : [1], }; } const chainsToRequestForSafe = [ 1, // Ethereum Mainnet 11155111, // Sepolia Testnet 42161, // Arbitrum One Mainnet 43114, // Avalanche Mainnet 8453, // Base Mainnet 1313161554, // Aurora Mainnet 84532, // Base Sepolia Testnet 56, // Binance Smart Chain Mainnet 42220, // Celo Mainnet 100, // Gnosis Mainnet 10, // Optimism Mainnet 137, // Polygon Mainnet 1101, // Polygon zkEVM Mainnet 324, // zkSync Era mainnet 534352, // Scroll mainnet ];exports.autoConnectWC=autoConnectWC;exports.connectWC=connectWC;//# sourceMappingURL=controller-Ccs74LWA.js.map