diff --git a/package.json b/package.json index fcacd9941..8179f9ce0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "scroll.io", - "version": "5.0.40", + "version": "5.0.41", "private": false, "license": "MIT", "scripts": { @@ -41,7 +41,7 @@ "@mui/icons-material": "^5.8.4", "@mui/lab": "^5.0.0-alpha.108", "@mui/material": "^5.11.15", - "@rainbow-me/rainbowkit": "^1.1.3", + "@rainbow-me/rainbowkit": "^1.2.0", "@sentry/react": "^7.43.0", "@sentry/tracing": "^7.43.0", "@types/jest": "^27.5.2", diff --git a/src/contexts/RainbowProvider.tsx b/src/contexts/RainbowProvider.tsx deleted file mode 100644 index fdc2b26bf..000000000 --- a/src/contexts/RainbowProvider.tsx +++ /dev/null @@ -1,195 +0,0 @@ -import { Chain, RainbowKitProvider, connectorsForWallets, useConnectModal } from "@rainbow-me/rainbowkit" -import "@rainbow-me/rainbowkit/styles.css" -import { braveWallet, coinbaseWallet, injectedWallet, metaMaskWallet, walletConnectWallet } from "@rainbow-me/rainbowkit/wallets" -import { type WalletClient } from "@wagmi/core" -import { BrowserProvider, ethers, parseUnits } from "ethers" -import produce from "immer" -import { createContext, useCallback, useContext, useMemo } from "react" -import { WagmiConfig, configureChains, createConfig, mainnet, sepolia, useAccount, useDisconnect, useNetwork, useWalletClient } from "wagmi" -import { jsonRpcProvider } from "wagmi/providers/jsonRpc" -import { publicProvider } from "wagmi/providers/public" - -import { CHAIN_ID, ETH_SYMBOL, L2_NAME, RPC_URL } from "@/constants" -import { networkType, requireEnv } from "@/utils" - -type RainbowContextProps = { - provider: ethers.BrowserProvider | null - walletCurrentAddress?: `0x${string}` - chainId?: number - connect: () => void - disconnect: () => void - walletName: string | undefined - checkConnectedChainId: (chainId: number) => boolean -} - -export const scrollChain: Chain = { - id: CHAIN_ID.L2, - name: L2_NAME, - network: L2_NAME, - iconUrl: "https://scroll.io/logo.png", - iconBackground: "#fff", - nativeCurrency: { - decimals: 18, - name: L2_NAME, - symbol: ETH_SYMBOL, - }, - rpcUrls: { - default: { - http: [RPC_URL.L2], - }, - public: { - http: [RPC_URL.L2], - }, - }, - blockExplorers: { - default: { name: "Scrollscan", url: requireEnv("REACT_APP_EXTERNAL_EXPLORER_URI_L2") }, - }, -} - -const sepoliaChain = produce(sepolia, draft => { - draft.rpcUrls.public.http = [RPC_URL.L1 as any] - draft.fees = { - // adopt MetaMask params - baseFeeMultiplier: 1, - defaultPriorityFee() { - return parseUnits("1.5", "gwei") - }, - } -}) - -const mainnetChain = produce(mainnet, draft => { - draft.rpcUrls.public.http = [RPC_URL.L1 as any] - draft.fees = { - // adopt MetaMask params - baseFeeMultiplier: 1, - // defaultPriorityFee: parseUnits("0.05", "gwei"), - defaultPriorityFee() { - return parseUnits("0.05", "gwei") - }, - } -}) - -const projectId = requireEnv("REACT_APP_CONNECT_WALLET_PROJECT_ID") - -const RainbowContext = createContext(undefined) - -const { chains, publicClient } = configureChains( - // ankr - [mainnetChain, sepoliaChain, scrollChain], - [ - publicProvider(), - jsonRpcProvider({ - rpc: chain => ({ http: chain.rpcUrls.default.http[0] }), - }), - ], -) - -const connectors = connectorsForWallets([ - { - groupName: "Popular", - wallets: [ - // TODO: rainbowkit/injectedWallet.ts "Browser Wallet" and "injectedWallet.svg" -> need to detect automaticlly - injectedWallet({ chains }), - braveWallet({ chains }), - coinbaseWallet({ appName: "Scroll", chains }), - metaMaskWallet({ chains, projectId }), - walletConnectWallet({ - projectId, - chains, - options: { - metadata: { - name: "Scroll", - description: `Get started with our ${networkType} now.`, - url: "https://scroll.io/", - icons: ["https://scroll.io/logo_walletconnect.png"], - }, - qrModalOptions: { - explorerRecommendedWalletIds: [ - // metamask - "c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96", - // trust - "4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0", - // uniswap - "c03dfee351b6fcc421b4494ea33b9d4b92a984f87aa76d1663bb28705e95034a", - ], - }, - }, - } as any), - ], - }, -]) - -const wagmiConfig = createConfig({ - autoConnect: true, - connectors, - publicClient, -}) - -function walletClientToSigner(walletClient: WalletClient) { - const { chain, transport } = walletClient - const network = { - chainId: chain.id, - name: chain.name, - ensAddress: chain.contracts?.ensRegistry?.address, - } - const provider = new BrowserProvider(transport, network) - return provider -} - -const RainbowProvider = props => { - return ( - - - {props.children} - - - ) -} - -const Web3ContextProvider = props => { - const { data: walletClient } = useWalletClient() - - const { openConnectModal } = useConnectModal() - const { disconnect } = useDisconnect() - - const { connector: activeConnector, address, isConnected } = useAccount() - const { chain } = useNetwork() - - const provider = useMemo(() => { - if (walletClient) return walletClientToSigner(walletClient) - return null - }, [walletClient]) - - const checkConnectedChainId = useCallback( - chainId => { - return isConnected && chain?.id === chainId - }, - [isConnected, chain], - ) - - return ( - void, - disconnect, - checkConnectedChainId, - }} - > - {props.children} - - ) -} - -export function useRainbowContext() { - const ctx = useContext(RainbowContext) - if (!ctx) { - throw new Error("Rainbow error") - } - return ctx -} - -export default RainbowProvider diff --git a/src/contexts/RainbowProvider/configs.tsx b/src/contexts/RainbowProvider/configs.tsx new file mode 100644 index 000000000..8904b10fc --- /dev/null +++ b/src/contexts/RainbowProvider/configs.tsx @@ -0,0 +1,152 @@ +import { Chain, Wallet } from "@rainbow-me/rainbowkit" +import "@rainbow-me/rainbowkit/styles.css" +import { + braveWallet, + coinbaseWallet, + frameWallet, + imTokenWallet, + injectedWallet, + metaMaskWallet, // okxWallet, + rabbyWallet, + rainbowWallet, + safeWallet, + walletConnectWallet, +} from "@rainbow-me/rainbowkit/wallets" +import { parseUnits } from "ethers" +import produce from "immer" +import { configureChains, mainnet, sepolia } from "wagmi" +import { jsonRpcProvider } from "wagmi/providers/jsonRpc" +import { publicProvider } from "wagmi/providers/public" + +import { CHAIN_ID, ETH_SYMBOL, L2_NAME, RPC_URL } from "@/constants" +import { networkType, requireEnv } from "@/utils" + +interface WalletConfig { + name: string + wallet: Wallet + visible: boolean + fixedWallet?: boolean +} + +const createWalletConfig = (name: string, walletFunction: () => Wallet, condition: boolean, fixedWallet?: boolean): WalletConfig => { + return { + name, + wallet: walletFunction(), + visible: condition, + fixedWallet, + } +} + +export const scrollChain: Chain = { + id: CHAIN_ID.L2, + name: L2_NAME, + network: L2_NAME, + iconUrl: "https://scroll.io/logo.png", + iconBackground: "#fff", + nativeCurrency: { + decimals: 18, + name: L2_NAME, + symbol: ETH_SYMBOL, + }, + rpcUrls: { + default: { + http: [RPC_URL.L2], + }, + public: { + http: [RPC_URL.L2], + }, + }, + blockExplorers: { + default: { name: "Scrollscan", url: requireEnv("REACT_APP_EXTERNAL_EXPLORER_URI_L2") }, + }, +} + +const sepoliaChain = produce(sepolia, draft => { + draft.rpcUrls.public.http = [RPC_URL.L1 as any] + draft.fees = { + // adopt MetaMask params + baseFeeMultiplier: 1, + defaultPriorityFee() { + return parseUnits("1.5", "gwei") + }, + } +}) + +const mainnetChain = produce(mainnet, draft => { + draft.rpcUrls.public.http = [RPC_URL.L1 as any] + draft.fees = { + // adopt MetaMask params + baseFeeMultiplier: 1, + // defaultPriorityFee: parseUnits("0.05", "gwei"), + defaultPriorityFee() { + return parseUnits("0.05", "gwei") + }, + } +}) + +const projectId = requireEnv("REACT_APP_CONNECT_WALLET_PROJECT_ID") + +const { chains, publicClient } = configureChains( + // ankr + [mainnetChain, sepoliaChain, scrollChain], + [ + publicProvider(), + jsonRpcProvider({ + rpc: chain => ({ http: chain.rpcUrls.default.http[0] }), + }), + ], +) + +const walletConfigs: WalletConfig[] = [ + createWalletConfig("MetaMask", () => metaMaskWallet({ chains, projectId }), window.ethereum?.isMetaMask === true, true), + createWalletConfig("Coinbase", () => coinbaseWallet({ appName: "Scroll", chains }), window.ethereum?.isCoinbaseWallet === true, true), + createWalletConfig("Brave", () => braveWallet({ chains }), window.ethereum?.isBraveWallet === true), + createWalletConfig("Rainbow", () => rainbowWallet({ chains, projectId }), window.ethereum?.isRainbow === true), + createWalletConfig("Safe", () => safeWallet({ chains }), window.ethereum?.isSafeWallet === true), + createWalletConfig("Frame", () => frameWallet({ chains }), window.ethereum?.isFrame === true), + createWalletConfig("imToken", () => imTokenWallet({ chains, projectId }), window.ethereum?.isImToken === true), + // createWalletConfig("Okx Wallet", () => okxWallet({ chains, projectId }), window.okxwallet?.isOKExWallet || window.okxwallet?.isOkxWallet === true), + createWalletConfig("Rabby", () => rabbyWallet({ chains }), window.ethereum?.isRabby && !window.ethereum?.isMetaMask === true), + // Add any additional wallets here +] + +const sortWallets = (a, b) => { + if (a.visible === b.visible) return 0 + if (a.visible || a.fixedWallet) return -1 + return 1 +} + +const activeWallets: Wallet[] = walletConfigs + .filter(wallet => wallet.visible || wallet.fixedWallet) + .sort(sortWallets) + .map(wallet => wallet.wallet) + +const Wallets = [ + // TODO: rainbowkit/injectedWallet.ts "Browser Wallet" and "injectedWallet.svg" -> need to detect automaticlly + injectedWallet({ chains }), + ...activeWallets, + walletConnectWallet({ + projectId, + chains, + options: { + metadata: { + name: "Scroll", + description: `Get started with our ${networkType} now.`, + url: "https://scroll.io/", + icons: ["https://scroll.io/logo_walletconnect.png"], + }, + qrModalOptions: { + explorerRecommendedWalletIds: [ + // metamask + "c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96", + // trust + "4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0", + // uniswap + "c03dfee351b6fcc421b4494ea33b9d4b92a984f87aa76d1663bb28705e95034a", + ], + }, + }, + } as any), +] + +export { Wallets, chains, publicClient } diff --git a/src/contexts/RainbowProvider/index.tsx b/src/contexts/RainbowProvider/index.tsx new file mode 100644 index 000000000..4e05efe27 --- /dev/null +++ b/src/contexts/RainbowProvider/index.tsx @@ -0,0 +1,102 @@ +import { RainbowKitProvider, connectorsForWallets, useConnectModal } from "@rainbow-me/rainbowkit" +import "@rainbow-me/rainbowkit/styles.css" +import { type WalletClient } from "@wagmi/core" +import { BrowserProvider, ethers } from "ethers" +import { createContext, useCallback, useContext, useMemo } from "react" +import { WagmiConfig, createConfig, useAccount, useDisconnect, useNetwork, useWalletClient } from "wagmi" + +import { Wallets, chains, publicClient } from "./configs" + +type RainbowContextProps = { + provider: ethers.BrowserProvider | null + walletCurrentAddress?: `0x${string}` + chainId?: number + connect: () => void + disconnect: () => void + walletName: string | undefined + checkConnectedChainId: (chainId: number) => boolean +} + +const RainbowContext = createContext(undefined) + +const connectors = connectorsForWallets([ + { + groupName: "Popular", + wallets: Wallets, + }, +]) + +const wagmiConfig = createConfig({ + autoConnect: true, + connectors, + publicClient, +}) + +function walletClientToSigner(walletClient: WalletClient) { + const { chain, transport } = walletClient + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new BrowserProvider(transport, network) + return provider +} + +const RainbowProvider = props => { + return ( + + + {props.children} + + + ) +} + +const Web3ContextProvider = props => { + const { data: walletClient } = useWalletClient() + + const { openConnectModal } = useConnectModal() + const { disconnect } = useDisconnect() + + const { connector: activeConnector, address, isConnected } = useAccount() + const { chain } = useNetwork() + + const provider = useMemo(() => { + if (walletClient) return walletClientToSigner(walletClient) + return null + }, [walletClient]) + + const checkConnectedChainId = useCallback( + chainId => { + return isConnected && chain?.id === chainId + }, + [isConnected, chain], + ) + + return ( + void, + disconnect, + checkConnectedChainId, + }} + > + {props.children} + + ) +} + +export function useRainbowContext() { + const ctx = useContext(RainbowContext) + if (!ctx) { + throw new Error("Rainbow error") + } + return ctx +} + +export default RainbowProvider diff --git a/src/pages/privacyPolicy/index.tsx b/src/pages/privacyPolicy/index.tsx index d5f627582..7b08d52d6 100644 --- a/src/pages/privacyPolicy/index.tsx +++ b/src/pages/privacyPolicy/index.tsx @@ -291,9 +291,11 @@ const PrivacyPolicy = () => { reorganization, dissolution, or other sale or transfer of some or all of Our assets, whether as a going concern or as part of bankruptcy, liquidation, or similar proceeding, in which Personal Data held by Us about our Service users is among the assets transferred. -
  • For compliance purposes: such as to prevent fraud and/or money laundering.
  • - For other purposes: we may use Your information for other purposes, such as data analysis, identifying usage trends, + For compliance purposes: such as to prevent fraud and/or money laundering. +
  • +
  • + For other purposes: we may use Your information for other purposes, such as data analysis, identifying usage trends, determining the effectiveness of our promotional campaigns and to evaluate and improve our Service, products, functionality, services, marketing and your experience.
  • @@ -324,7 +326,7 @@ const PrivacyPolicy = () => { of Your activity. Similarly, other users will be able to view descriptions of Your activity, communicate with You and view Your profile.
  • - With Your consent: we may disclose Your personal information for any other purpose with Your consent. + With Your consent: we may disclose Your personal information for any other purpose with Your consent.
  • Retention of Your Personal Data

    diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts index 783ea1aec..eaf42998c 100644 --- a/src/react-app-env.d.ts +++ b/src/react-app-env.d.ts @@ -16,6 +16,10 @@ interface Window { removeListener?: (...args: any[]) => void } web3?: {} + okxwallet?: { + isOKExWallet?: boolean + isOkxWallet?: boolean + } } declare module "content-hash" { diff --git a/yarn.lock b/yarn.lock index bad6ca047..4cb43c7af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2828,10 +2828,10 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.7.tgz#ccab5c8f7dc557a52ca3288c10075c9ccd37fff7" integrity sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw== -"@rainbow-me/rainbowkit@1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@rainbow-me/rainbowkit/-/rainbowkit-1.1.3.tgz#593d11e7f5bdee5be35b4c8d890eb55884632730" - integrity sha512-sgklyUmKFFholbRxjbnkQwzlC0wsP0GnCKl6d+4qTpBbQK3P2kfCM9AcDWdkTv3XVQ40fByE8mc3jJ+rI8JdIw== +"@rainbow-me/rainbowkit@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@rainbow-me/rainbowkit/-/rainbowkit-1.2.0.tgz#8ddcb3acef5408ef375e3df349429144aa230e12" + integrity sha512-XjdeX31GwFdRR/1rCRqPXiO94nbq2qOlnaox5P4K/KMRIUwyelKzak27uWw8Krmor/Hcrd5FisfepGDS0tUfEA== dependencies: "@vanilla-extract/css" "1.9.1" "@vanilla-extract/dynamic" "2.0.2" @@ -2840,6 +2840,7 @@ i18n-js "^4.3.2" qrcode "1.5.0" react-remove-scroll "2.5.4" + ua-parser-js "^1.0.35" "@remix-run/router@1.5.0": version "1.5.0" @@ -14388,6 +14389,11 @@ ua-parser-js@^0.7.24: resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.35.tgz#8bda4827be4f0b1dda91699a29499575a1f1d307" integrity sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g== +ua-parser-js@^1.0.35: + version "1.0.37" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.37.tgz#b5dc7b163a5c1f0c510b08446aed4da92c46373f" + integrity sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ== + uint8arrays@^3.0.0, uint8arrays@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0"