From 59eb901e109cac1d879314419688f2984281039e Mon Sep 17 00:00:00 2001
From: guanbinrui <52657989+guanbinrui@users.noreply.github.com>
Date: Sat, 16 Nov 2024 00:31:36 +0800
Subject: [PATCH] [Release] Hotfix 2.28.0 => 2.28.1 (patch) (#11929)

* chore: bump version to 2.28.1

* chore: remove fortmatic wallet and maskbox plugin (#11923)

* chore: mf-6488 remove fortmatic wallet

* chore: mf-6374 remove maskbox

* fixup! chore: mf-6374 remove maskbox

* fix: prettier

---------

Co-authored-by: swkatmask <swkatmask@users.noreply.github.com>

* fixup! refactor: mf-6204 relation service use lowercase category name (#11922) (#11932)

* fix: lint

---------

Co-authored-by: Wukong Sun <swkatmask@gmail.com>
Co-authored-by: swkatmask <swkatmask@users.noreply.github.com>
---
 cspell.json                                   |   1 -
 package.json                                  |   3 +-
 packages/icons/icon-generated-as-jsx.js       |   5 -
 packages/icons/icon-generated-as-url.js       |   1 -
 packages/icons/plugins/MaskBox.svg            |   9 -
 packages/mask/package.json                    |   1 -
 .../popups/modals/ConnectProvider/index.tsx   |  10 +-
 packages/mask/shared/plugin-infra/register.js |   1 -
 packages/plugins/MaskBox/package.json         |  69 --
 .../SiteAdaptor/components/ArticlesTab.tsx    |  64 --
 .../components/CollectibleCard.tsx            | 111 ----
 .../src/SiteAdaptor/components/DetailsTab.tsx |  81 ---
 .../src/SiteAdaptor/components/DrawDialog.tsx | 287 --------
 .../components/DrawResultDialog.tsx           |  75 ---
 .../SiteAdaptor/components/PreviewCard.tsx    | 408 ------------
 .../src/SiteAdaptor/components/TokenCard.tsx  |  42 --
 .../plugins/MaskBox/src/SiteAdaptor/index.tsx |  85 ---
 packages/plugins/MaskBox/src/Worker/index.ts  |  10 -
 packages/plugins/MaskBox/src/apis/index.ts    |   2 -
 .../plugins/MaskBox/src/apis/merkleProof.ts   |  20 -
 packages/plugins/MaskBox/src/apis/storage.ts  |   7 -
 .../MaskBox/src/assets/FallbackImage.svg      |   1 -
 .../plugins/MaskBox/src/assets/bridge.png     | Bin 2326 -> 0 bytes
 .../plugins/MaskBox/src/assets/mask_box.png   | Bin 1828 -> 0 bytes
 packages/plugins/MaskBox/src/base.ts          |  25 -
 packages/plugins/MaskBox/src/constants.ts     |   5 -
 .../MaskBox/src/helpers/formatCountdown.ts    |   6 -
 .../plugins/MaskBox/src/hooks/useContext.ts   | 369 -----------
 .../MaskBox/src/hooks/useMaskBoxContract.ts   |  12 -
 .../hooks/useMaskBoxCreationSuccessEvent.ts   |  43 --
 .../MaskBox/src/hooks/useMaskBoxInfo.ts       |  11 -
 .../MaskBox/src/hooks/useMaskBoxMetadata.ts   |  10 -
 .../src/hooks/useMaskBoxPurchasedTokens.ts    |  11 -
 .../hooks/useMaskBoxQualificationContract.ts  |   9 -
 .../MaskBox/src/hooks/useMaskBoxStatus.ts     |  10 -
 .../src/hooks/useMaskBoxTokensForSale.ts      |  10 -
 .../MaskBox/src/hooks/useMerkleProof.ts       |  17 -
 .../src/hooks/useOpenBoxTransaction.ts        |  44 --
 .../MaskBox/src/hooks/useQualification.ts     |  16 -
 .../plugins/MaskBox/src/locale/en-US.json     |  20 -
 packages/plugins/MaskBox/src/locale/en-US.po  |  78 ---
 .../plugins/MaskBox/src/locale/ja-JP.json     |  20 -
 .../plugins/MaskBox/src/locale/ko-KR.json     |  20 -
 .../plugins/MaskBox/src/locale/languages.ts   |  24 -
 .../plugins/MaskBox/src/locale/zh-CN.json     |  20 -
 .../plugins/MaskBox/src/locale/zh-TW.json     |  20 -
 packages/plugins/MaskBox/src/messages.ts      |   4 -
 packages/plugins/MaskBox/src/register.ts      |  15 -
 packages/plugins/MaskBox/src/type.ts          |  74 ---
 packages/plugins/MaskBox/tsconfig.json        |  15 -
 .../components/Lens/FollowLensDialog.tsx      |   5 +-
 packages/plugins/tsconfig.json                |   1 -
 packages/shared-base/src/KVStorage/index.ts   |   1 -
 packages/shared-base/src/types/PluginID.ts    |   1 -
 .../PluginProviderRender.tsx                  | 278 +++-----
 packages/shared/src/UI/translate.ts           |   6 -
 packages/shared/src/locale/en-US.po           |  28 +-
 packages/shared/src/locale/ja-JP.po           |  28 +-
 packages/shared/src/locale/ko-KR.po           |  28 +-
 packages/shared/src/locale/zh-CN.po           |  28 +-
 packages/shared/src/locale/zh-TW.po           |  28 +-
 packages/web3-contracts/abis/MaskBox.json     | 625 ------------------
 .../abis/MaskBoxQualification.json            |  23 -
 packages/web3-contracts/types/MaskBox.d.ts    | 210 ------
 .../types/MaskBoxQualification.d.ts           |  43 --
 packages/web3-contracts/types/index.d.ts      |   2 -
 packages/web3-providers/package.json          |   1 -
 packages/web3-providers/src/NextID/proof.ts   |   5 +-
 .../src/Web3/EVM/interceptors/Fortmatic.ts    |  18 -
 .../src/Web3/EVM/middleware/Interceptor.ts    |   2 -
 .../src/Web3/EVM/providers/Fortmatic.ts       | 146 ----
 .../src/Web3/EVM/providers/index.ts           |   2 -
 .../Web3/EVM/state/TransactionFormatter.ts    |   2 -
 .../EVM/state/TransactionFormatter/abi.ts     |   2 -
 .../descriptors/MaskBox.ts                    |  51 --
 .../helpers/getAllMaskDappContractInfo.tsx    |  13 +-
 packages/web3-shared/base/src/specs/index.ts  |   9 -
 .../web3-shared/evm/src/assets/fortmatic.png  | Bin 8532 -> 0 bytes
 .../evm/src/constants/constants.ts            |   6 -
 .../evm/src/constants/descriptors.ts          |  18 -
 .../evm/src/helpers/getContractOwnerDomain.ts |   2 -
 packages/web3-shared/evm/src/types/index.ts   |   1 -
 patches/fortmatic@2.4.0.patch                 | 202 ------
 pnpm-lock.yaml                                |  83 ---
 tsconfig.json                                 |   1 -
 85 files changed, 164 insertions(+), 3936 deletions(-)
 delete mode 100644 packages/icons/plugins/MaskBox.svg
 delete mode 100644 packages/plugins/MaskBox/package.json
 delete mode 100644 packages/plugins/MaskBox/src/SiteAdaptor/components/ArticlesTab.tsx
 delete mode 100644 packages/plugins/MaskBox/src/SiteAdaptor/components/CollectibleCard.tsx
 delete mode 100644 packages/plugins/MaskBox/src/SiteAdaptor/components/DetailsTab.tsx
 delete mode 100644 packages/plugins/MaskBox/src/SiteAdaptor/components/DrawDialog.tsx
 delete mode 100644 packages/plugins/MaskBox/src/SiteAdaptor/components/DrawResultDialog.tsx
 delete mode 100644 packages/plugins/MaskBox/src/SiteAdaptor/components/PreviewCard.tsx
 delete mode 100644 packages/plugins/MaskBox/src/SiteAdaptor/components/TokenCard.tsx
 delete mode 100644 packages/plugins/MaskBox/src/SiteAdaptor/index.tsx
 delete mode 100644 packages/plugins/MaskBox/src/Worker/index.ts
 delete mode 100644 packages/plugins/MaskBox/src/apis/index.ts
 delete mode 100644 packages/plugins/MaskBox/src/apis/merkleProof.ts
 delete mode 100644 packages/plugins/MaskBox/src/apis/storage.ts
 delete mode 100644 packages/plugins/MaskBox/src/assets/FallbackImage.svg
 delete mode 100644 packages/plugins/MaskBox/src/assets/bridge.png
 delete mode 100644 packages/plugins/MaskBox/src/assets/mask_box.png
 delete mode 100644 packages/plugins/MaskBox/src/base.ts
 delete mode 100644 packages/plugins/MaskBox/src/constants.ts
 delete mode 100644 packages/plugins/MaskBox/src/helpers/formatCountdown.ts
 delete mode 100644 packages/plugins/MaskBox/src/hooks/useContext.ts
 delete mode 100644 packages/plugins/MaskBox/src/hooks/useMaskBoxContract.ts
 delete mode 100644 packages/plugins/MaskBox/src/hooks/useMaskBoxCreationSuccessEvent.ts
 delete mode 100644 packages/plugins/MaskBox/src/hooks/useMaskBoxInfo.ts
 delete mode 100644 packages/plugins/MaskBox/src/hooks/useMaskBoxMetadata.ts
 delete mode 100644 packages/plugins/MaskBox/src/hooks/useMaskBoxPurchasedTokens.ts
 delete mode 100644 packages/plugins/MaskBox/src/hooks/useMaskBoxQualificationContract.ts
 delete mode 100644 packages/plugins/MaskBox/src/hooks/useMaskBoxStatus.ts
 delete mode 100644 packages/plugins/MaskBox/src/hooks/useMaskBoxTokensForSale.ts
 delete mode 100644 packages/plugins/MaskBox/src/hooks/useMerkleProof.ts
 delete mode 100644 packages/plugins/MaskBox/src/hooks/useOpenBoxTransaction.ts
 delete mode 100644 packages/plugins/MaskBox/src/hooks/useQualification.ts
 delete mode 100644 packages/plugins/MaskBox/src/locale/en-US.json
 delete mode 100644 packages/plugins/MaskBox/src/locale/en-US.po
 delete mode 100644 packages/plugins/MaskBox/src/locale/ja-JP.json
 delete mode 100644 packages/plugins/MaskBox/src/locale/ko-KR.json
 delete mode 100644 packages/plugins/MaskBox/src/locale/languages.ts
 delete mode 100644 packages/plugins/MaskBox/src/locale/zh-CN.json
 delete mode 100644 packages/plugins/MaskBox/src/locale/zh-TW.json
 delete mode 100644 packages/plugins/MaskBox/src/messages.ts
 delete mode 100644 packages/plugins/MaskBox/src/register.ts
 delete mode 100644 packages/plugins/MaskBox/src/type.ts
 delete mode 100644 packages/plugins/MaskBox/tsconfig.json
 delete mode 100644 packages/web3-contracts/abis/MaskBox.json
 delete mode 100644 packages/web3-contracts/abis/MaskBoxQualification.json
 delete mode 100644 packages/web3-contracts/types/MaskBox.d.ts
 delete mode 100644 packages/web3-contracts/types/MaskBoxQualification.d.ts
 delete mode 100644 packages/web3-providers/src/Web3/EVM/interceptors/Fortmatic.ts
 delete mode 100644 packages/web3-providers/src/Web3/EVM/providers/Fortmatic.ts
 delete mode 100644 packages/web3-providers/src/Web3/EVM/state/TransactionFormatter/descriptors/MaskBox.ts
 delete mode 100644 packages/web3-shared/evm/src/assets/fortmatic.png
 delete mode 100644 patches/fortmatic@2.4.0.patch

diff --git a/cspell.json b/cspell.json
index 33e749eebf07..802ff9b768d2 100644
--- a/cspell.json
+++ b/cspell.json
@@ -118,7 +118,6 @@
         "looksrare",
         "magiceden",
         "maskbook",
-        "maskbox",
         "masknet",
         "masknetwork",
         "maskwallet",
diff --git a/package.json b/package.json
index ac5afe11ac4e..14cf83db0173 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,7 @@
     "yarn": ">=999.0.0",
     "npm": ">=999.0.0"
   },
-  "version": "2.28.0",
+  "version": "2.28.1",
   "private": true,
   "license": "AGPL-3.0-or-later",
   "scripts": {
@@ -145,7 +145,6 @@
       "@project-serum/sol-wallet-adapter@0.2.6": "patches/@project-serum__sol-wallet-adapter@0.2.6.patch",
       "@types/react-highlight-words@0.20.0": "patches/@types__react-highlight-words@0.20.0.patch",
       "@cyberlab/cyberconnect@4.2.2": "patches/@cyberlab__cyberconnect@4.2.2.patch",
-      "fortmatic@2.4.0": "patches/fortmatic@2.4.0.patch",
       "reflect-metadata@0.1.13": "patches/reflect-metadata@0.1.13.patch",
       "bloom-filters@3.0.0": "patches/bloom-filters@3.0.0.patch",
       "urlcat@3.1.0": "patches/urlcat@3.1.0.patch",
diff --git a/packages/icons/icon-generated-as-jsx.js b/packages/icons/icon-generated-as-jsx.js
index c3b027bcf9af..0b267575e82f 100644
--- a/packages/icons/icon-generated-as-jsx.js
+++ b/packages/icons/icon-generated-as-jsx.js
@@ -4122,11 +4122,6 @@ export const MarketsClaim = /*#__PURE__*/ __createIcon('MarketsClaim', [
         u: () => new URL('./plugins/MarketsClaim.svg', import.meta.url).href,
     },
 ])
-export const MaskBox = /*#__PURE__*/ __createIcon('MaskBox', [
-    {
-        u: () => new URL('./plugins/MaskBox.svg', import.meta.url).href,
-    },
-])
 export const NFTAvatar = /*#__PURE__*/ __createIcon('NFTAvatar', [
     {
         u: () => new URL('./plugins/NFTAvatar.svg', import.meta.url).href,
diff --git a/packages/icons/icon-generated-as-url.js b/packages/icons/icon-generated-as-url.js
index 122d994557be..2086a4f46c39 100644
--- a/packages/icons/icon-generated-as-url.js
+++ b/packages/icons/icon-generated-as-url.js
@@ -384,7 +384,6 @@ export function good_ghosting_dark_url() { return new URL("./plugins/GoodGhostin
 export function good_ghosting_light_url() { return new URL("./plugins/GoodGhosting.light.svg", import.meta.url).href }
 export function markets_url() { return new URL("./plugins/Markets.png", import.meta.url).href }
 export function markets_claim_url() { return new URL("./plugins/MarketsClaim.svg", import.meta.url).href }
-export function mask_box_url() { return new URL("./plugins/MaskBox.svg", import.meta.url).href }
 export function nft_avatar_url() { return new URL("./plugins/NFTAvatar.svg", import.meta.url).href }
 export function pool_together_url() { return new URL("./plugins/PoolTogether.png", import.meta.url).href }
 export function savings_url() { return new URL("./plugins/Savings.svg", import.meta.url).href }
diff --git a/packages/icons/plugins/MaskBox.svg b/packages/icons/plugins/MaskBox.svg
deleted file mode 100644
index 9d3ebae0b222..000000000000
--- a/packages/icons/plugins/MaskBox.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28">
-    <path fill="#2337b4" d="m13.678 0 12.123 6.999-12.122 6.999L1.556 6.999z"/>
-    <path fill="#ff9607" d="m12.468 13.302 1.212.7v2.8l-1.212-.7zm0-4.2 1.212.7v2.8l-1.212-.7zm1.212-2.1 1.213.7v1.4l-1.213-.7zm-4.849-1.4 1.223.706v4.2L8.83 9.802zm1.209-2.099 1.212.7v1.4l-1.212-.7zm4.853-1.4 1.212.7v4.2l-1.212-.7z"/>
-    <path fill="#ffd5be" d="m13.68 12.602 1.213.7-1.213.7-1.212-.7zm1.213-.7 1.212.7-1.212.7-1.213-.7zm-1.213-3.5 1.213.7-1.213.7-1.212-.7zm1.213-2.099 1.212.7-1.212.7-1.213-.7zm-4.853-1.4 1.212.7-1.212.7-1.212-.7zm6.065-4.9 1.226.708-6.061 3.5-1.227-.708z"/>
-    <path fill="#ffd5be" d="m17.317.703 1.213.7-1.213.7-1.212-.7z"/>
-    <path fill="#ff5900" fill-rule="evenodd" d="m12.465 3.5-1.213.7v1.399l1.213-.7zm4.849-1.4 1.212-.7v5.599l-1.212.7-1.212.7v2.8l-1.213.7-1.212.7v-2.8l1.212-.7v-1.4l1.213-.7v-4.2l-1.213.7-1.212.7-1.212.7V3.5l1.212-.7 1.212-.7 1.213-.7 1.212-.7zm-4.85 2.8L10.04 6.298v4.2l2.425-1.4v-4.2zm2.425 11.198-1.212.7v-2.8l1.212-.7 1.213-.7v2.8z" clip-rule="evenodd"/>
-    <path fill="#0057ff" d="M13.678 13.998 25.801 7v13.997l-12.122 7z"/>
-    <path fill="#367bff" d="m1.556 7.002 12.122 7v13.997L1.556 21z"/>
-</svg>
diff --git a/packages/mask/package.json b/packages/mask/package.json
index 7fe8b7b92857..bc27a935c9f7 100644
--- a/packages/mask/package.json
+++ b/packages/mask/package.json
@@ -56,7 +56,6 @@
     "@masknet/plugin-go-plus-security": "workspace:^",
     "@masknet/plugin-handle": "workspace:^",
     "@masknet/plugin-infra": "workspace:^",
-    "@masknet/plugin-maskbox": "workspace:^",
     "@masknet/plugin-nextid": "workspace:^",
     "@masknet/plugin-pets": "workspace:^",
     "@masknet/plugin-profilecard": "workspace:^",
diff --git a/packages/mask/popups/modals/ConnectProvider/index.tsx b/packages/mask/popups/modals/ConnectProvider/index.tsx
index 71c5909fc94a..1138c77268fb 100644
--- a/packages/mask/popups/modals/ConnectProvider/index.tsx
+++ b/packages/mask/popups/modals/ConnectProvider/index.tsx
@@ -7,7 +7,7 @@ import { makeStyles, usePopupCustomSnackbar } from '@masknet/theme'
 import { useNetworkContext, useProviderDescriptor, useWeb3State } from '@masknet/web3-hooks-base'
 import { PopupModalRoutes, type NetworkPluginID, PopupRoutes } from '@masknet/shared-base'
 import { EVMWeb3 } from '@masknet/web3-providers'
-import { ChainId, ProviderType } from '@masknet/web3-shared-evm'
+import { type ProviderType } from '@masknet/web3-shared-evm'
 import { ActionModal, type ActionModalBaseProps, useModalNavigate } from '../../components/index.js'
 import { Trans } from '@lingui/macro'
 
@@ -104,18 +104,14 @@ export const ConnectProviderModal = memo<ActionModalBaseProps>(function ConnectP
             const connect = async () => {
                 // wait for web3 state init
                 await delay(1500)
-                const chainId =
-                    providerType === ProviderType.Fortmatic ?
-                        ChainId.Mainnet
-                    :   await EVMWeb3.getChainId({ providerType })
+                const chainId = await EVMWeb3.getChainId({ providerType })
                 return EVMWeb3.connect({
                     chainId,
                     providerType: providerType as ProviderType,
                 })
             }
 
-            // Fortmatic takes extra time because it requires the user to enter an account and password, a verification code
-            const result = await timeout(connect(), providerType === ProviderType.Fortmatic ? 5 * 60 * 1000 : 30 * 1000)
+            const result = await timeout(connect(), 30 * 1000)
             if (!result) return
             navigate(PopupRoutes.ConnectWallet, {
                 replace: true,
diff --git a/packages/mask/shared/plugin-infra/register.js b/packages/mask/shared/plugin-infra/register.js
index 8c45bf0b51df..097dab4aade1 100644
--- a/packages/mask/shared/plugin-infra/register.js
+++ b/packages/mask/shared/plugin-infra/register.js
@@ -16,7 +16,6 @@ import '@masknet/plugin-collectible/register'
 import '@masknet/plugin-transak/register'
 import '@masknet/plugin-vcent/register'
 import '@masknet/plugin-avatar/register'
-import '@masknet/plugin-maskbox/register'
 import '@masknet/plugin-claim/register'
 import '@masknet/plugin-artblocks/register'
 import '@masknet/plugin-pets/register'
diff --git a/packages/plugins/MaskBox/package.json b/packages/plugins/MaskBox/package.json
deleted file mode 100644
index ef40b29782cc..000000000000
--- a/packages/plugins/MaskBox/package.json
+++ /dev/null
@@ -1,69 +0,0 @@
-{
-  "name": "@masknet/plugin-maskbox",
-  "private": true,
-  "sideEffects": [
-    "./src/register.ts"
-  ],
-  "type": "module",
-  "exports": {
-    ".": {
-      "mask-src": "./src/index.ts",
-      "default": "./dist/index.js"
-    },
-    "./register": {
-      "mask-src": "./src/register.ts",
-      "default": "./dist/register.js"
-    }
-  },
-  "dependencies": {
-    "@masknet/icons": "workspace:^",
-    "@masknet/plugin-infra": "workspace:^",
-    "@masknet/shared": "workspace:^",
-    "@masknet/shared-base": "workspace:^",
-    "@masknet/shared-base-ui": "workspace:^",
-    "@masknet/theme": "workspace:^",
-    "@masknet/typed-message": "workspace:^0.2.0",
-    "@masknet/web3-contracts": "workspace:^",
-    "@masknet/web3-helpers": "workspace:^",
-    "@masknet/web3-hooks-base": "workspace:^",
-    "@masknet/web3-hooks-evm": "workspace:^",
-    "@masknet/web3-providers": "workspace:^",
-    "@masknet/web3-shared-base": "workspace:^",
-    "@masknet/web3-shared-evm": "workspace:^",
-    "@types/color": "^3.0.6",
-    "bignumber.js": "9.1.2",
-    "buffer": "^6.0.3",
-    "color": "^4.2.3",
-    "date-fns": "^3.6.0",
-    "react-use": "^17.5.0",
-    "urlcat": "^3.1.0",
-    "web3-utils": "1.10.2"
-  },
-  "lingui": {
-    "compileNamespace": "json",
-    "locales": [
-      "en-US",
-      "ja-JP",
-      "ko-KR",
-      "zh-CN",
-      "zh-TW"
-    ],
-    "fallbackLocales": {
-      "zh-CN": "zh-TW",
-      "zh-TW": "zh-CN",
-      "default": "en-US"
-    },
-    "formatOptions": {
-      "origins": true,
-      "lineNumbers": false
-    },
-    "catalogs": [
-      {
-        "path": "src/locale/{locale}",
-        "include": [
-          "src"
-        ]
-      }
-    ]
-  }
-}
diff --git a/packages/plugins/MaskBox/src/SiteAdaptor/components/ArticlesTab.tsx b/packages/plugins/MaskBox/src/SiteAdaptor/components/ArticlesTab.tsx
deleted file mode 100644
index 98bb1911814b..000000000000
--- a/packages/plugins/MaskBox/src/SiteAdaptor/components/ArticlesTab.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import { makeStyles } from '@masknet/theme'
-import { type BoxMetadata, MediaType } from '../../type.js'
-import { Box } from '@mui/material'
-import { resolveIPFS_URL } from '@masknet/web3-shared-base'
-import { Video } from '@masknet/shared'
-
-const useStyles = makeStyles()((theme) => ({
-    main: {
-        padding: 16,
-    },
-    hero: {
-        display: 'flex',
-        alignItems: 'center',
-        justifyContent: 'center',
-        width: '100%',
-        height: 360,
-        objectFit: 'scale-down',
-    },
-}))
-
-interface ArticlesTabProps {
-    boxMetadata?: BoxMetadata
-}
-
-export function ArticlesTab(props: ArticlesTabProps) {
-    const { boxMetadata } = props
-    const { classes } = useStyles()
-
-    return (
-        <Box className={classes.main}>
-            <Box>
-                {(() => {
-                    if (!boxMetadata?.mediaType)
-                        return (
-                            <img
-                                className={classes.hero}
-                                src={new URL('../../assets/FallbackImage.svg', import.meta.url).toString()}
-                            />
-                        )
-                    switch (boxMetadata.mediaType) {
-                        case MediaType.Video:
-                            return (
-                                <Video
-                                    VideoProps={{ className: classes.hero, controls: true }}
-                                    src={resolveIPFS_URL(boxMetadata.mediaUrl) ?? ''}
-                                />
-                            )
-                        default:
-                            return (
-                                <img
-                                    className={classes.hero}
-                                    src={
-                                        boxMetadata.mediaUrl ?
-                                            resolveIPFS_URL(boxMetadata.mediaUrl)
-                                        :   new URL('../../assets/FallbackImage.svg', import.meta.url).toString()
-                                    }
-                                />
-                            )
-                    }
-                })()}
-            </Box>
-        </Box>
-    )
-}
diff --git a/packages/plugins/MaskBox/src/SiteAdaptor/components/CollectibleCard.tsx b/packages/plugins/MaskBox/src/SiteAdaptor/components/CollectibleCard.tsx
deleted file mode 100644
index 65c5707ee8f9..000000000000
--- a/packages/plugins/MaskBox/src/SiteAdaptor/components/CollectibleCard.tsx
+++ /dev/null
@@ -1,111 +0,0 @@
-import { memo, useMemo } from 'react'
-import { Card, Link } from '@mui/material'
-import { makeStyles } from '@masknet/theme'
-import { useWeb3Utils, useNetworkDescriptor } from '@masknet/web3-hooks-base'
-import type { Web3Helper } from '@masknet/web3-helpers'
-import { NetworkPluginID, type Wallet } from '@masknet/shared-base'
-import { AssetPreviewer, ImageIcon } from '@masknet/shared'
-import { NETWORK_DESCRIPTORS } from '@masknet/web3-shared-evm'
-import type { SourceType } from '@masknet/web3-shared-base'
-
-const useStyles = makeStyles()((theme) => ({
-    root: {
-        display: 'flex',
-        alignItems: 'center',
-        justifyContent: 'center',
-        borderRadius: '8px 8px 0 0',
-        position: 'absolute',
-        zIndex: 1,
-        backgroundColor: theme.palette.mode === 'light' ? '#F7F9FA' : '#2F3336',
-        width: '100%',
-        height: '100%',
-    },
-    networkIcon: {
-        position: 'absolute',
-        top: 6,
-        left: 6,
-    },
-    fallbackImage: {
-        minHeight: '0 !important',
-        maxWidth: 'none',
-        width: 30,
-        height: 30,
-    },
-    blocker: {
-        position: 'absolute',
-        zIndex: 2,
-        width: '100%',
-        height: '100%',
-    },
-    linkWrapper: {
-        position: 'relative',
-        display: 'block',
-    },
-}))
-
-interface CollectibleCardProps {
-    className?: string
-    provider: SourceType
-    wallet?: Wallet
-    asset: Web3Helper.NonFungibleAssetAll
-    link?: string
-    readonly?: boolean
-    pluginID?: NetworkPluginID
-    disableLink?: boolean
-    showNetworkIcon?: boolean
-}
-
-export const CollectibleCard = memo(function CollectibleCard({
-    className,
-    wallet,
-    asset,
-    readonly,
-    pluginID,
-    disableLink,
-    showNetworkIcon,
-    ...rest
-}: CollectibleCardProps) {
-    const { classes, cx } = useStyles()
-    const Utils = useWeb3Utils()
-
-    const networkDescriptor = useNetworkDescriptor(pluginID)
-
-    const networkIcon = useMemo(() => {
-        if (pluginID === NetworkPluginID.PLUGIN_EVM) {
-            return NETWORK_DESCRIPTORS.find((network) => network.chainId === asset.chainId)?.icon
-        }
-        return networkDescriptor?.icon
-    }, [asset.chainId, pluginID])
-
-    const content = (
-        <>
-            <div className={classes.blocker} />
-            <Card className={classes.root}>
-                <AssetPreviewer
-                    url={asset.metadata?.mediaURL || asset.metadata?.imageURL}
-                    classes={{
-                        fallbackImage: classes.fallbackImage,
-                    }}
-                />
-                {networkIcon ?
-                    <ImageIcon icon={networkIcon} size={24} className={classes.networkIcon} />
-                :   null}
-            </Card>
-        </>
-    )
-
-    if (disableLink) return <div className={cx(classes.linkWrapper, className)}>{content}</div>
-
-    return (
-        <Link
-            target="_blank"
-            rel="noopener noreferrer"
-            href={
-                asset.link ?? Utils.explorerResolver.nonFungibleTokenLink(asset.chainId, asset.address, asset.tokenId)
-            }
-            className={cx(classes.linkWrapper, className)}
-            {...rest}>
-            {content}
-        </Link>
-    )
-})
diff --git a/packages/plugins/MaskBox/src/SiteAdaptor/components/DetailsTab.tsx b/packages/plugins/MaskBox/src/SiteAdaptor/components/DetailsTab.tsx
deleted file mode 100644
index 6669a669d106..000000000000
--- a/packages/plugins/MaskBox/src/SiteAdaptor/components/DetailsTab.tsx
+++ /dev/null
@@ -1,81 +0,0 @@
-import { Box, Divider, Typography } from '@mui/material'
-import { makeStyles } from '@masknet/theme'
-import type { BoxMetadata } from '../../type.js'
-
-const useStyles = makeStyles()((theme) => ({
-    main: {
-        height: 360,
-        overflow: 'auto',
-        padding: theme.spacing(2),
-    },
-    section: {
-        border: `1px solid ${theme.palette.maskColor.publicLine}`,
-        borderRadius: 16,
-        padding: theme.spacing(2),
-        marginBottom: theme.spacing(2),
-        '&:last-child': {
-            marginBottom: theme.spacing(0),
-        },
-    },
-    line: {
-        borderColor: theme.palette.maskColor.publicLine,
-    },
-    placeholder: {
-        textAlign: 'center',
-        marginTop: 170,
-    },
-    title: {
-        fontSize: 18,
-        fontWeight: 700,
-        lineHeight: '22px',
-        paddingBottom: theme.spacing(2),
-        color: theme.palette.maskColor.dark,
-    },
-    content: {
-        lineHeight: '20px',
-        whiteSpace: 'pre-line',
-        fontSize: 16,
-        fontWeight: 400,
-        color: theme.palette.maskColor.dark,
-        paddingTop: theme.spacing(2),
-    },
-}))
-
-interface DetailsTabProps {
-    boxMetadata?: BoxMetadata
-}
-
-export function DetailsTab(props: DetailsTabProps) {
-    const { boxMetadata } = props
-    const { classes, theme } = useStyles()
-
-    const definitions = boxMetadata?.activities.map((x) => ({
-        title: x.title,
-        content: x.body,
-    }))
-
-    if (!definitions)
-        return (
-            <Box className={classes.main}>
-                <Typography className={classes.placeholder} color={theme.palette.maskColor.publicMain}>
-                    No detailed information.
-                </Typography>
-            </Box>
-        )
-
-    return (
-        <Box className={classes.main}>
-            {definitions.map((x, i) => (
-                <section className={classes.section} key={i}>
-                    <Typography className={classes.title} color={theme.palette.maskColor.publicMain} variant="h3">
-                        {x.title}
-                    </Typography>
-                    <Divider className={classes.line} />
-                    <Typography className={classes.content} color={theme.palette.maskColor.publicMain} variant="body2">
-                        {x.content}
-                    </Typography>
-                </section>
-            ))}
-        </Box>
-    )
-}
diff --git a/packages/plugins/MaskBox/src/SiteAdaptor/components/DrawDialog.tsx b/packages/plugins/MaskBox/src/SiteAdaptor/components/DrawDialog.tsx
deleted file mode 100644
index 0d1fb5a47cdd..000000000000
--- a/packages/plugins/MaskBox/src/SiteAdaptor/components/DrawDialog.tsx
+++ /dev/null
@@ -1,287 +0,0 @@
-import { useCallback } from 'react'
-import { useContainer } from '@masknet/shared-base-ui'
-import { makeStyles, ActionButton, MaskTextField } from '@masknet/theme'
-import { Add, Remove } from '@mui/icons-material'
-import { useChainContext, useProviderDescriptor } from '@masknet/web3-hooks-base'
-import { NUMERIC_INPUT_REGEXP_PATTERN } from '@masknet/shared-base'
-import {
-    FormattedAddress,
-    ImageIcon,
-    InjectedDialog,
-    PluginWalletStatusBar,
-    WalletConnectedBoundary,
-    TokenPrice,
-    EthereumERC20TokenApprovedBoundary,
-    GasSettingBar,
-} from '@masknet/shared'
-import { Box, Button, DialogActions, DialogContent, Typography } from '@mui/material'
-import { formatEthereumAddress, SchemaType, useMaskBoxConstants } from '@masknet/web3-shared-evm'
-import { formatBalance, formatCurrency, multipliedBy } from '@masknet/web3-shared-base'
-import type { NetworkPluginID } from '@masknet/shared-base'
-import type { BoxInfo } from '../../type.js'
-import { Context } from '../../hooks/useContext.js'
-import { Trans } from '@lingui/macro'
-
-const useStyles = makeStyles()((theme) => ({
-    main: {
-        padding: `${theme.spacing(2.5)} !important`,
-    },
-    caption: {
-        textAlign: 'center',
-    },
-    body: {
-        padding: theme.spacing(0, 2.5),
-    },
-    value: {
-        fontSize: 32,
-        lineHeight: '40px',
-        fontWeight: 'bold',
-        marginBottom: theme.spacing(1),
-        marginRight: theme.spacing(1),
-    },
-    section: {
-        padding: theme.spacing(2, 0),
-        justifyContent: 'space-between',
-    },
-    title: {
-        width: '50%',
-    },
-    content: {},
-    field: {
-        borderRadius: 0,
-        padding: theme.spacing(0),
-        height: '25px !important',
-        minWidth: 0,
-        minHeight: 0,
-        outline: 'none !important',
-        borderColor: `${theme.palette.divider} !important`,
-    },
-    textfield: {
-        width: 40,
-        textAlign: 'center',
-        '& .MuiOutlinedInput-root': {
-            '& fieldset': {
-                borderColor: theme.palette.divider,
-            },
-            '&:hover fieldset': {
-                borderColor: theme.palette.divider,
-            },
-            '&.Mui-focused fieldset': {
-                borderWidth: 1,
-                borderColor: theme.palette.divider,
-            },
-        },
-    },
-    number: {
-        '&::-webkit-outer-spin-button, &::-webkit-inner-spin-button': {
-            appearance: 'none',
-            margin: 0,
-        },
-        padding: 0,
-        appearance: 'textfield',
-        textAlign: 'center',
-        borderImage: 'none',
-    },
-}))
-
-interface DrawDialogProps {
-    boxInfo: BoxInfo
-    open: boolean
-    drawing?: boolean
-    onClose: () => void
-    onSubmit: () => Promise<void>
-}
-
-export function DrawDialog(props: DrawDialogProps) {
-    const { boxInfo, open, drawing, onClose, onSubmit } = props
-    const { classes } = useStyles()
-    const { MASK_BOX_CONTRACT_ADDRESS } = useMaskBoxConstants()
-
-    const {
-        paymentCount,
-        setPaymentCount,
-        paymentTokenPrice,
-        paymentTokenBalance,
-        paymentTokenDetailed,
-        isBalanceInsufficient,
-        isAllowanceEnough,
-
-        openBoxTransactionGasLimit,
-        setOpenBoxTransactionOverrides,
-    } = useContainer(Context)
-
-    const providerDescriptor = useProviderDescriptor()
-    const { account, chainId } = useChainContext<NetworkPluginID.PLUGIN_EVM>()
-
-    const onCount = useCallback(
-        (step: number) => {
-            setPaymentCount(paymentCount + step)
-        },
-        [paymentCount],
-    )
-
-    return (
-        <InjectedDialog title="Draw" open={open} onClose={onClose}>
-            <DialogContent className={classes.main}>
-                <Box>
-                    <Box className={classes.caption}>
-                        <Typography color="textPrimary">
-                            <span className={classes.value}>
-                                {formatCurrency(multipliedBy(paymentTokenPrice, paymentCount), '')}
-                            </span>
-                            <span>{paymentTokenDetailed?.symbol}</span>
-                        </Typography>
-                        {paymentTokenDetailed ?
-                            <Typography color="textPrimary">
-                                <span>&asymp;</span>
-                                <TokenPrice
-                                    chainId={chainId}
-                                    amount={formatCurrency(paymentTokenPrice, '')}
-                                    contractAddress={paymentTokenDetailed.address}
-                                />
-                            </Typography>
-                        :   null}
-                    </Box>
-                    <Box className={classes.body}>
-                        <Box className={classes.section} display="flex" alignItems="center">
-                            <Typography className={classes.title} color="textPrimary">
-                                Mystery Boxes:
-                            </Typography>
-                            <Box className={classes.content} display="flex" alignItems="center">
-                                <Button
-                                    className={classes.field}
-                                    variant="outlined"
-                                    color="inherit"
-                                    disabled={paymentCount <= 1}
-                                    onClick={() => onCount(-1)}>
-                                    <Remove color="inherit" />
-                                </Button>
-                                <MaskTextField
-                                    className={classes.textfield}
-                                    type="number"
-                                    size="small"
-                                    sx={{ marginLeft: 1, marginRight: 1 }}
-                                    value={paymentCount}
-                                    disabled={boxInfo.remaining === 0 || boxInfo.personalRemaining <= 1}
-                                    onChange={(ev) => {
-                                        const count = Number.parseInt(ev.target.value, 10)
-                                        if (count >= 1 && count <= boxInfo.availableAmount) {
-                                            setPaymentCount(count)
-                                        }
-                                    }}
-                                    InputProps={{
-                                        classes: {
-                                            root: classes.field,
-                                        },
-                                        autoFocus: true,
-                                        inputProps: {
-                                            className: classes.number,
-                                            autoComplete: 'off',
-                                            autoCorrect: 'off',
-                                            title: 'Token Amount',
-                                            inputMode: 'decimal',
-                                            min: 0,
-                                            max: 255,
-                                            minLength: 1,
-                                            pattern: NUMERIC_INPUT_REGEXP_PATTERN,
-                                            spellCheck: false,
-                                        },
-                                    }}
-                                />
-                                <Button
-                                    className={classes.field}
-                                    variant="outlined"
-                                    color="inherit"
-                                    disabled={
-                                        paymentCount >= boxInfo.availableAmount ||
-                                        boxInfo.remaining === 0 ||
-                                        boxInfo.personalRemaining === 1
-                                    }
-                                    onClick={() => onCount(1)}>
-                                    <Add color="inherit" />
-                                </Button>
-                            </Box>
-                        </Box>
-                        <Box className={classes.section} display="flex" alignItems="center">
-                            <Typography className={classes.title} color="textPrimary">
-                                Quantity Limit:
-                            </Typography>
-                            <Typography className={classes.content} color="textPrimary">
-                                {boxInfo.personalLimit}
-                            </Typography>
-                        </Box>
-                        <Box className={classes.section} display="flex" alignItems="center">
-                            <Typography className={classes.title} color="textPrimary">
-                                Available amount:
-                            </Typography>
-                            <Typography className={classes.content} color="textPrimary">
-                                {boxInfo.availableAmount}/{boxInfo.total}
-                            </Typography>
-                        </Box>
-                        <Box className={classes.section} display="flex" alignItems="center">
-                            <Typography className={classes.title} color="textPrimary">
-                                Current Wallet:
-                            </Typography>
-                            <Box className={classes.content} display="flex" alignItems="center">
-                                <ImageIcon size={16} icon={providerDescriptor?.icon} />
-                                <Typography color="textPrimary" sx={{ marginLeft: 1 }}>
-                                    <FormattedAddress address={account} size={6} formatter={formatEthereumAddress} />
-                                </Typography>
-                            </Box>
-                        </Box>
-                        <Box className={classes.section} display="flex" alignItems="center">
-                            <Typography className={classes.title} color="textPrimary">
-                                Available:
-                            </Typography>
-                            <Box className={classes.content}>
-                                <Typography color="textPrimary">
-                                    {formatBalance(paymentTokenBalance, paymentTokenDetailed?.decimals ?? 0, {
-                                        significant: 6,
-                                    })}{' '}
-                                    {paymentTokenDetailed?.symbol}
-                                </Typography>
-                            </Box>
-                        </Box>
-                        {isAllowanceEnough ?
-                            <Box className={classes.section} display="flex" alignItems="center">
-                                <Typography className={classes.title} color="textPrimary">
-                                    Gas Fee:
-                                </Typography>
-                                <Box className={classes.content}>
-                                    <GasSettingBar
-                                        gasLimit={openBoxTransactionGasLimit || 0}
-                                        onChange={setOpenBoxTransactionOverrides}
-                                    />
-                                </Box>
-                            </Box>
-                        :   null}
-                    </Box>
-                </Box>
-            </DialogContent>
-            <DialogActions style={{ padding: 0 }}>
-                <PluginWalletStatusBar>
-                    <WalletConnectedBoundary expectedChainId={chainId}>
-                        <EthereumERC20TokenApprovedBoundary
-                            amount={multipliedBy(paymentTokenPrice, paymentCount).toFixed()}
-                            spender={MASK_BOX_CONTRACT_ADDRESS}
-                            token={paymentTokenDetailed?.schema === SchemaType.ERC20 ? paymentTokenDetailed : undefined}
-                            ActionButtonProps={{ size: 'medium', sx: { marginTop: 2 } }}>
-                            <ActionButton
-                                size="medium"
-                                fullWidth
-                                sx={{ marginTop: 2 }}
-                                disabled={isBalanceInsufficient || drawing}
-                                onClick={onSubmit}>
-                                {isBalanceInsufficient ?
-                                    <Trans>Insufficient balance</Trans>
-                                : drawing ?
-                                    <Trans>Drawing</Trans>
-                                :   <Trans>Draw</Trans>}
-                            </ActionButton>
-                        </EthereumERC20TokenApprovedBoundary>
-                    </WalletConnectedBoundary>
-                </PluginWalletStatusBar>
-            </DialogActions>
-        </InjectedDialog>
-    )
-}
diff --git a/packages/plugins/MaskBox/src/SiteAdaptor/components/DrawResultDialog.tsx b/packages/plugins/MaskBox/src/SiteAdaptor/components/DrawResultDialog.tsx
deleted file mode 100644
index 2cf86363a2e4..000000000000
--- a/packages/plugins/MaskBox/src/SiteAdaptor/components/DrawResultDialog.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-import { difference } from 'lodash-es'
-import { useContainer } from '@masknet/shared-base-ui'
-import { makeStyles, ActionButton } from '@masknet/theme'
-import { Box, DialogContent } from '@mui/material'
-import type { BoxInfo } from '../../type.js'
-import { TokenCard } from './TokenCard.js'
-import { InjectedDialog } from '@masknet/shared'
-import { Context } from '../../hooks/useContext.js'
-import type { NonFungibleTokenContract } from '@masknet/web3-shared-base'
-import type { ChainId, SchemaType } from '@masknet/web3-shared-evm'
-import { Icons } from '@masknet/icons'
-import { usePostLink } from '@masknet/plugin-infra/content-script'
-import { share } from '@masknet/plugin-infra/content-script/context'
-import { useLingui } from '@lingui/react'
-import { msg } from '@lingui/macro'
-
-const useStyles = makeStyles()((theme) => ({
-    main: { padding: 8 },
-    list: {
-        height: 360,
-        overflow: 'auto',
-        marginBottom: theme.spacing(2),
-        display: 'grid',
-        flexWrap: 'wrap',
-        gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))',
-        gridGap: theme.spacing(1),
-        padding: 8,
-    },
-    token: {},
-}))
-
-interface DrawResultDialogProps {
-    open: boolean
-    onClose: () => void
-    boxInfo: BoxInfo
-    contractDetailed?: NonFungibleTokenContract<ChainId, SchemaType>
-}
-
-export function DrawResultDialog(props: DrawResultDialogProps) {
-    const { open, onClose, boxInfo, contractDetailed } = props
-    const { classes } = useStyles()
-    const { lastPurchasedTokenIds } = useContainer(Context)
-
-    const postLink = usePostLink()
-    const { _ } = useLingui()
-    const shareText =
-        _(msg`I just claimed a #MaskBox with @realMaskNetwork. Install mask.io and create your own NFT mystery box!`) +
-        `\n${postLink}`
-
-    const onShare = () => {
-        onClose()
-        share?.(shareText)
-    }
-
-    if (!contractDetailed) return null
-
-    return (
-        <InjectedDialog title="Successful" open={open} onClose={onClose}>
-            <DialogContent>
-                <Box className={classes.main}>
-                    <Box className={classes.list} display="flex" flexWrap="wrap">
-                        {difference(boxInfo.tokenIdsPurchased, lastPurchasedTokenIds).map((x, i) => (
-                            <Box className={classes.token} key={x} flex={1}>
-                                <TokenCard tokenId={x} contractDetailed={contractDetailed} />
-                            </Box>
-                        ))}
-                    </Box>
-                    <ActionButton startIcon={<Icons.Shared size={18} />} size="medium" fullWidth onClick={onShare}>
-                        Share
-                    </ActionButton>
-                </Box>
-            </DialogContent>
-        </InjectedDialog>
-    )
-}
diff --git a/packages/plugins/MaskBox/src/SiteAdaptor/components/PreviewCard.tsx b/packages/plugins/MaskBox/src/SiteAdaptor/components/PreviewCard.tsx
deleted file mode 100644
index 105878fb58e6..000000000000
--- a/packages/plugins/MaskBox/src/SiteAdaptor/components/PreviewCard.tsx
+++ /dev/null
@@ -1,408 +0,0 @@
-import { useCallback, useMemo, useState } from 'react'
-import Color from 'color'
-import { useContainer } from '@masknet/shared-base-ui'
-import { TabContext, TabPanel } from '@mui/lab'
-import { useChainContext, useNetworkDescriptor, useWeb3Utils } from '@masknet/web3-hooks-base'
-import type { ChainId } from '@masknet/web3-shared-evm'
-import { makeStyles, ActionButton, LoadingBase, useTabs, MaskTabList } from '@masknet/theme'
-import { Box, Button, Chip, Paper, Tab, Typography, useTheme } from '@mui/material'
-import { WalletConnectedBoundary, ChainBoundary, ImageIcon, TokenIcon } from '@masknet/shared'
-import { useTransactionCallback } from '@masknet/web3-hooks-evm'
-import { formatCurrency } from '@masknet/web3-shared-base'
-import { NetworkPluginID } from '@masknet/shared-base'
-import { Context } from '../../hooks/useContext.js'
-import { BoxState } from '../../type.js'
-import { ArticlesTab } from './ArticlesTab.js'
-import { DetailsTab } from './DetailsTab.js'
-import { DrawDialog } from './DrawDialog.js'
-import { DrawResultDialog } from './DrawResultDialog.js'
-import { Trans } from '@lingui/macro'
-
-const useTabsStyles = makeStyles()((theme) => ({
-    button: {
-        backgroundColor: theme.palette.maskColor.dark,
-        color: theme.palette.maskColor.white,
-        fontSize: 14,
-        fontWeight: 700,
-        width: '100%',
-        '&:hover': {
-            backgroundColor: theme.palette.maskColor.dark,
-        },
-        margin: '0 !important',
-    },
-    tab: {
-        whiteSpace: 'nowrap',
-        background: 'transparent',
-        color: theme.palette.maskColor.publicSecond,
-        '&:hover': {
-            background: 'transparent',
-        },
-    },
-    tabActive: {
-        background: theme.palette.maskColor.white,
-        color: theme.palette.maskColor.publicMain,
-        '&:hover': {
-            background: theme.palette.maskColor.white,
-        },
-    },
-    body: {
-        padding: 12,
-        paddingBottom: 0,
-    },
-    content: {
-        margin: '0 12px',
-        flex: 1,
-        backgroundColor: theme.palette.maskColor.white,
-        overflow: 'auto',
-        borderRadius: '0 0 12px 12px',
-        scrollbarWidth: 'none',
-        '&::-webkit-scrollbar': {
-            display: 'none',
-        },
-    },
-    header: {
-        gap: 24,
-        display: 'flex',
-        padding: 12,
-        alignItems: 'center',
-    },
-    imgBox: {
-        width: 50,
-        height: 50,
-        display: 'flex',
-        justifyContent: 'center',
-        alignItems: 'center',
-        position: 'relative',
-    },
-    name: {
-        color: theme.palette.maskColor.publicMain,
-        fontSize: 18,
-        fontWeight: 700,
-        whiteSpace: 'nowrap',
-        overflow: 'hidden',
-        textOverflow: 'ellipsis',
-        width: 250,
-    },
-    active: {
-        color: theme.palette.maskColor.white,
-        width: 65,
-        height: 32,
-        fontSize: 12,
-        fontWeight: 700,
-        backgroundColor: theme.palette.maskColor.success,
-    },
-    close: {
-        color: theme.palette.maskColor.white,
-        width: 65,
-        backgroundColor: new Color(theme.palette.maskColor.primary).alpha(0.1).toString(),
-        height: 32,
-        fontSize: 12,
-        fontWeight: 700,
-    },
-    iconBox: {
-        position: 'absolute',
-        bottom: 0,
-        right: -8,
-        padding: 1,
-        backgroundColor: theme.palette.maskColor.bg,
-        borderRadius: 9999,
-        lineHeight: 0,
-        alignItems: 'center',
-        justifyContent: 'center',
-        display: 'flex',
-    },
-    icon: {
-        width: 20,
-        height: 20,
-    },
-    statusBox: {
-        display: 'flex',
-        justifyContent: 'end',
-        alignItems: 'center',
-        height: 148,
-        flexDirection: 'column',
-    },
-}))
-
-export function PreviewCard() {
-    const { classes } = useTabsStyles()
-    const [openDrawDialog, setOpenDrawDialog] = useState(false)
-    const [openDrawResultDialog, setOpenDrawResultDialog] = useState(false)
-    const { chainId } = useChainContext()
-    const networkDescriptor = useNetworkDescriptor()
-    const theme = useTheme()
-    const {
-        boxState,
-        boxStateMessage,
-        boxInfo,
-        boxMetadata,
-        contractDetailed,
-        setPaymentCount,
-        paymentTokenAddress,
-        setPaymentTokenAddress,
-        paymentTokenPrice,
-        paymentTokenDetailed,
-
-        refreshLastPurchasedTokenIds,
-
-        // transaction
-        openBoxTransaction,
-        openBoxTransactionOverrides,
-        openBoxTransactionGasLimit,
-        setOpenBoxTransactionOverrides,
-
-        // retry
-        retryMaskBoxStatus,
-        retryMaskBoxInfo,
-        retryBoxInfo,
-        retryMaskBoxCreationSuccessEvent,
-        retryMaskBoxTokensForSale,
-        retryMaskBoxPurchasedTokens,
-    } = useContainer(Context)
-
-    const [currentTab, onChange, tabs] = useTabs('Articles', 'Details')
-
-    const txConfig = useMemo(() => {
-        return {
-            ...openBoxTransaction?.config,
-            gas: openBoxTransactionOverrides?.gas ?? openBoxTransactionGasLimit,
-        }
-    }, [openBoxTransaction?.config, openBoxTransactionOverrides, openBoxTransactionGasLimit])
-
-    // #region open box
-    const [{ loading: isOpening }, openBoxCallback] = useTransactionCallback(txConfig, openBoxTransaction?.method)
-    const onRefresh = useCallback(() => {
-        setPaymentCount(1)
-        setPaymentTokenAddress('')
-        retryMaskBoxInfo()
-        retryMaskBoxCreationSuccessEvent()
-        retryMaskBoxTokensForSale()
-        retryMaskBoxPurchasedTokens()
-    }, [retryMaskBoxInfo, retryMaskBoxCreationSuccessEvent, retryMaskBoxTokensForSale, retryMaskBoxPurchasedTokens])
-    const [drawing, setDrawing] = useState(false)
-    const onDraw = useCallback(async () => {
-        setDrawing(true)
-        refreshLastPurchasedTokenIds()
-        try {
-            await openBoxCallback()
-            onRefresh()
-            setOpenDrawResultDialog(true)
-            retryMaskBoxStatus()
-            setOpenDrawDialog(false)
-        } catch {}
-        setDrawing(false)
-    }, [openBoxCallback, refreshLastPurchasedTokenIds, onRefresh, retryMaskBoxStatus])
-    const Utils = useWeb3Utils()
-    // #endregion
-
-    if (boxState === BoxState.UNKNOWN)
-        return (
-            <Box className={classes.statusBox}>
-                <Box sx={{ display: 'flex', flex: 1, justifyContent: 'center', alignItems: 'center' }}>
-                    <LoadingBase />
-                </Box>
-            </Box>
-        )
-    if (boxState === BoxState.ERROR)
-        return (
-            <Box className={classes.statusBox}>
-                <Typography color="error">
-                    <Trans>Load failed</Trans>
-                </Typography>
-                <Button
-                    sx={{
-                        width: 254,
-                        backgroundColor: theme.palette.maskColor.publicMain,
-                        color: 'white',
-                        '&:hover': {
-                            backgroundColor: theme.palette.maskColor.publicMain,
-                        },
-                        height: 40,
-                        marginBottom: 2,
-                        marginTop: '26px',
-                    }}
-                    size="small"
-                    variant="roundedContained"
-                    onClick={retryBoxInfo}>
-                    <Trans>Reload</Trans>
-                </Button>
-            </Box>
-        )
-    if (boxState === BoxState.NOT_FOUND || !boxInfo)
-        return (
-            <Box className={classes.statusBox}>
-                <Typography color="error">
-                    <Trans>Load failed</Trans>
-                </Typography>
-                <Button
-                    sx={{
-                        width: 254,
-                        backgroundColor: theme.palette.maskColor.publicMain,
-                        color: 'white',
-                        '&:hover': {
-                            backgroundColor: theme.palette.maskColor.publicMain,
-                        },
-                        height: 40,
-                        marginBottom: 2,
-                        marginTop: '26px',
-                    }}
-                    size="small"
-                    variant="roundedContained"
-                    onClick={retryMaskBoxInfo}>
-                    <Trans>Reload</Trans>
-                </Button>
-            </Box>
-        )
-
-    const Tabs = [
-        {
-            value: tabs.Articles,
-            label: <Trans>Articles</Trans>,
-        },
-        {
-            value: tabs.Details,
-            label: <Trans>Details</Trans>,
-        },
-    ]
-
-    return (
-        <>
-            <TabContext value={currentTab}>
-                <Box className={classes.header}>
-                    <Box className={classes.imgBox}>
-                        <TokenIcon
-                            address={boxInfo.tokenAddress ?? ''}
-                            name={boxInfo.name}
-                            chainId={chainId}
-                            sx={{ width: 48, height: 48 }}
-                        />
-                        <Box className={classes.iconBox}>
-                            <ImageIcon size={24} icon={networkDescriptor?.icon} className={classes.icon} />
-                        </Box>
-                    </Box>
-                    <Box sx={{ flex: 1 }}>
-                        <Typography title={boxInfo.name} className={classes.name}>
-                            {boxInfo.name}
-                        </Typography>
-                        <Box sx={{ flex: 1, display: 'flex', flexDirection: 'row' }}>
-                            <Box sx={{ flex: 1, display: 'flex', flexDirection: 'row' }}>
-                                <Typography
-                                    sx={{ paddingRight: 1 }}
-                                    color={theme.palette.maskColor.publicSecond}
-                                    fontSize={14}
-                                    fontWeight={400}>
-                                    <Trans>Solid:</Trans>
-                                </Typography>
-                                <Typography color={theme.palette.maskColor.publicMain} fontSize={14} fontWeight="bold">
-                                    {boxInfo.sold}/{boxInfo.total}
-                                </Typography>
-                                <Typography
-                                    sx={{ paddingRight: 1, paddingLeft: 1 }}
-                                    color={theme.palette.maskColor.publicSecond}
-                                    fontSize={14}
-                                    fontWeight={400}>
-                                    <Trans>Limit:</Trans>
-                                </Typography>
-                                <Typography color={theme.palette.maskColor.publicMain} fontSize={14} fontWeight="bold">
-                                    {boxInfo.personalLimit}
-                                </Typography>
-                            </Box>
-                            <Box sx={{ display: 'flex', flexDirection: 'row' }}>
-                                <Typography
-                                    sx={{ paddingRight: 1 }}
-                                    color={theme.palette.maskColor.publicSecond}
-                                    fontSize={14}
-                                    fontWeight={400}>
-                                    <Trans>by</Trans>
-                                </Typography>
-                                <Typography
-                                    color={theme.palette.maskColor.publicMain}
-                                    fontSize={14}
-                                    fontWeight="bold"
-                                    title={boxInfo.creator}>
-                                    {Utils.formatAddress(boxInfo.creator, 4)}
-                                </Typography>
-                            </Box>
-                        </Box>
-                    </Box>
-                    <Chip
-                        className={boxState === BoxState.READY ? classes.active : classes.close}
-                        label={boxState === BoxState.READY ? <Trans>Active</Trans> : <Trans>Closed</Trans>}
-                    />
-                </Box>
-                <Box className={classes.body}>
-                    <MaskTabList variant="base" aria-label="maskbox" onChange={onChange}>
-                        {Tabs.map((x) => (
-                            <Tab
-                                key={x.value}
-                                value={x.value}
-                                label={x.label}
-                                className={x.value === currentTab ? classes.tabActive : classes.tab}
-                            />
-                        ))}
-                    </MaskTabList>
-                </Box>
-                <Paper className={classes.content}>
-                    <TabPanel value={tabs.Articles} key={tabs.Articles} sx={{ padding: 0 }}>
-                        {boxInfo ?
-                            <ArticlesTab boxMetadata={boxMetadata} />
-                        :   null}
-                    </TabPanel>
-                    <TabPanel value={tabs.Details} key={tabs.Details} sx={{ padding: 0 }}>
-                        {boxInfo ?
-                            <DetailsTab boxMetadata={boxMetadata} />
-                        :   null}
-                    </TabPanel>
-                </Paper>
-
-                <Box style={{ padding: 12 }}>
-                    <ChainBoundary
-                        expectedPluginID={NetworkPluginID.PLUGIN_EVM}
-                        expectedChainId={chainId as ChainId}
-                        ActionButtonPromiseProps={{ variant: 'roundedDark' }}>
-                        <WalletConnectedBoundary
-                            expectedChainId={chainId}
-                            ActionButtonProps={{ size: 'medium', variant: 'roundedDark' }}
-                            classes={{ button: classes.button }}>
-                            <ActionButton
-                                loading={isOpening}
-                                size="medium"
-                                variant="roundedDark"
-                                fullWidth
-                                disabled={boxState !== BoxState.READY || isOpening}
-                                onClick={() => setOpenDrawDialog(true)}>
-                                {(() => {
-                                    return boxState === BoxState.READY && paymentTokenAddress ?
-                                            <Trans>
-                                                {boxStateMessage} ({formatCurrency(paymentTokenPrice, '')}{' '}
-                                                {paymentTokenDetailed?.symbol ?? ''}/Time)
-                                            </Trans>
-                                        :   boxStateMessage
-                                })()}
-                            </ActionButton>
-                        </WalletConnectedBoundary>
-                    </ChainBoundary>
-                </Box>
-            </TabContext>
-            <DrawDialog
-                boxInfo={boxInfo}
-                open={openDrawDialog}
-                drawing={drawing}
-                onClose={() => {
-                    setOpenBoxTransactionOverrides(null)
-                    setOpenDrawDialog(false)
-                }}
-                onSubmit={onDraw}
-            />
-            <DrawResultDialog
-                boxInfo={boxInfo}
-                contractDetailed={contractDetailed}
-                open={openDrawResultDialog}
-                onClose={() => {
-                    refreshLastPurchasedTokenIds()
-                    setOpenDrawResultDialog(false)
-                }}
-            />
-        </>
-    )
-}
diff --git a/packages/plugins/MaskBox/src/SiteAdaptor/components/TokenCard.tsx b/packages/plugins/MaskBox/src/SiteAdaptor/components/TokenCard.tsx
deleted file mode 100644
index 27c8a0862d8e..000000000000
--- a/packages/plugins/MaskBox/src/SiteAdaptor/components/TokenCard.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { memo } from 'react'
-import { useNonFungibleAsset } from '@masknet/web3-hooks-base'
-import { LoadingBase, makeStyles } from '@masknet/theme'
-import { NetworkPluginID } from '@masknet/shared-base'
-import { type NonFungibleTokenContract, SourceType } from '@masknet/web3-shared-base'
-import type { ChainId, SchemaType } from '@masknet/web3-shared-evm'
-import { Typography } from '@mui/material'
-import { CollectibleCard } from './CollectibleCard.js'
-
-const useStyles = makeStyles()((theme) => ({
-    title: {
-        textAlign: 'center',
-        margin: theme.spacing(1, 0),
-        maxWidth: 160,
-    },
-    name: {
-        whiteSpace: 'nowrap',
-        textOverflow: 'ellipsis',
-        overflow: 'hidden',
-    },
-}))
-
-interface TokenCardProps {
-    tokenId: string
-    contractDetailed: NonFungibleTokenContract<ChainId, SchemaType>
-}
-
-export const TokenCard = memo<TokenCardProps>(({ contractDetailed, tokenId }: TokenCardProps) => {
-    const { classes } = useStyles()
-    const { data: tokenDetailed } = useNonFungibleAsset(NetworkPluginID.PLUGIN_EVM, contractDetailed.address, tokenId)
-
-    return tokenDetailed ?
-            <>
-                <CollectibleCard readonly provider={SourceType.OpenSea} asset={tokenDetailed} />
-                <div className={classes.title}>
-                    <Typography className={classes.name} color="textSecondary" variant="body2">
-                        {tokenDetailed.contract?.name ?? tokenId}
-                    </Typography>
-                </div>
-            </>
-        :   <LoadingBase />
-})
diff --git a/packages/plugins/MaskBox/src/SiteAdaptor/index.tsx b/packages/plugins/MaskBox/src/SiteAdaptor/index.tsx
deleted file mode 100644
index c73f84078df2..000000000000
--- a/packages/plugins/MaskBox/src/SiteAdaptor/index.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-import { useMemo } from 'react'
-import { type Plugin, usePluginWrapper, usePostInfoDetails } from '@masknet/plugin-infra/content-script'
-import { Icons } from '@masknet/icons'
-import { extractTextFromTypedMessage } from '@masknet/typed-message'
-import { parseURLs } from '@masknet/shared-base'
-import { ApplicationEntry } from '@masknet/shared'
-import { openWindow } from '@masknet/shared-base-ui'
-import { base } from '../base.js'
-import { PreviewCard } from './components/PreviewCard.js'
-import { Context } from '../hooks/useContext.js'
-import { Trans } from '@lingui/macro'
-
-const isMaskBox = (x: string) => x.startsWith('https://box-beta.mask.io') || x.startsWith('https://box.mask.io')
-
-const site: Plugin.SiteAdaptor.Definition = {
-    ...base,
-    DecryptedInspector(props) {
-        const link = useMemo(() => {
-            const x = extractTextFromTypedMessage(props.message)
-            if (x.isNone()) return null
-            return parseURLs(x.value).find(isMaskBox)
-        }, [props.message])
-        if (!link) return null
-        return <Renderer url={link} />
-    },
-    PostInspector() {
-        const links = usePostInfoDetails.mentionedLinks()
-        const link = links.find(isMaskBox)
-        if (!link) return null
-        return <Renderer url={link} />
-    },
-    ApplicationEntries: [
-        (() => {
-            const icon = <Icons.MaskBox />
-            const name = <Trans>MaskBox</Trans>
-            const iconFilterColor = 'rgba(0, 87, 255, 0.3)'
-            return {
-                ApplicationEntryID: base.ID,
-                RenderEntryComponent({ disabled }) {
-                    return (
-                        <ApplicationEntry
-                            title={name}
-                            disabled={disabled}
-                            iconFilterColor={iconFilterColor}
-                            icon={icon}
-                            onClick={() => openWindow('https://box.mask.io/#/')}
-                        />
-                    )
-                },
-                appBoardSortingDefaultPriority: 14,
-                marketListSortingPriority: 14,
-                icon,
-                tutorialLink: 'https://realmasknetwork.notion.site/d0941687649a4ef7a38d71f23ecbe4da',
-                description: (
-                    <Trans>Professional multi-chain decentralized platform for launching NFT blind boxes.</Trans>
-                ),
-                category: 'dapp',
-                iconFilterColor,
-                name,
-            }
-        })(),
-    ],
-}
-
-export default site
-
-function Renderer(
-    props: React.PropsWithChildren<{
-        url: string
-    }>,
-) {
-    const [, matchedChainId] = props.url.match(/chain=(\d+)/i) ?? []
-    const [, boxId] = props.url.match(/box=(\d+)/i) ?? []
-    const [, hashRoot] = props.url.match(/rootHash=([\dA-Za-z]+)/) ?? []
-
-    const shouldNotRender = !matchedChainId || !boxId
-    usePluginWrapper(!shouldNotRender)
-    if (shouldNotRender) return null
-
-    return (
-        <Context initialState={{ boxId, hashRoot }}>
-            <PreviewCard />
-        </Context>
-    )
-}
diff --git a/packages/plugins/MaskBox/src/Worker/index.ts b/packages/plugins/MaskBox/src/Worker/index.ts
deleted file mode 100644
index 46f16fbe24e0..000000000000
--- a/packages/plugins/MaskBox/src/Worker/index.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import type { Plugin } from '@masknet/plugin-infra'
-import { base } from '../base.js'
-
-const worker: Plugin.Worker.Definition = {
-    ...base,
-    init(signal, context) {
-        context.startService(import('../apis/index.js'))
-    },
-}
-export default worker
diff --git a/packages/plugins/MaskBox/src/apis/index.ts b/packages/plugins/MaskBox/src/apis/index.ts
deleted file mode 100644
index 1d6aa160d9f2..000000000000
--- a/packages/plugins/MaskBox/src/apis/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './storage.js'
-export * from './merkleProof.js'
diff --git a/packages/plugins/MaskBox/src/apis/merkleProof.ts b/packages/plugins/MaskBox/src/apis/merkleProof.ts
deleted file mode 100644
index e39e1d1e32bf..000000000000
--- a/packages/plugins/MaskBox/src/apis/merkleProof.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import urlcat from 'urlcat'
-import { MERKLE_PROOF_ENDPOINT } from '../constants.js'
-
-export async function getMerkleProof(leaf: string, root: string) {
-    try {
-        const response = await fetch(
-            urlcat(MERKLE_PROOF_ENDPOINT, {
-                leaf,
-                root: root.replace(/^0x/, ''),
-            }),
-        )
-        return (await response.json()) as {
-            proof?: string[]
-            message?: string
-            module?: string
-        }
-    } catch (err) {
-        throw new Error(Reflect.get(Object(err), 'message'))
-    }
-}
diff --git a/packages/plugins/MaskBox/src/apis/storage.ts b/packages/plugins/MaskBox/src/apis/storage.ts
deleted file mode 100644
index 54fed77ec3ed..000000000000
--- a/packages/plugins/MaskBox/src/apis/storage.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Web3Storage } from '@masknet/web3-providers'
-import type { BoxMetadata } from '../type.js'
-
-export async function getMaskBoxMetadata(boxId: string, creator: string) {
-    const stringStorage = Web3Storage.createFireflyStorage('MaskBox', creator)
-    return stringStorage.get<BoxMetadata>(boxId)
-}
diff --git a/packages/plugins/MaskBox/src/assets/FallbackImage.svg b/packages/plugins/MaskBox/src/assets/FallbackImage.svg
deleted file mode 100644
index 3e9552dbf513..000000000000
--- a/packages/plugins/MaskBox/src/assets/FallbackImage.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg fill="none" viewBox="0 0 498 527" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><filter id="a" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="524.353" width="497.298" x=".269" y="2.629"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_14560_369598" stdDeviation="37.241"/></filter><filter id="b" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="752.855" width="490.526" x="-82.445" y="127.882"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_14560_369598" stdDeviation="60.886"/></filter><filter id="c" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="673.719" width="452.15" x="163.555" y="-113.236"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_14560_369598" stdDeviation="60.886"/></filter><filter id="d" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="752.855" width="490.526" x="83.851" y="77.004"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_14560_369598" stdDeviation="60.886"/></filter><filter id="e" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="927.36" width="575.15" x="-108.029" y="-469.382"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_14560_369598" stdDeviation="60.886"/></filter><linearGradient id="f"><stop offset=".01" stop-color="#6298ea" stop-opacity=".2"/><stop offset="1" stop-color="#627eea" stop-opacity=".2"/></linearGradient><linearGradient id="g" gradientUnits="userSpaceOnUse" x1="25" x2="477" xlink:href="#f" y1="226.139" y2="226.139"/><linearGradient id="h"><stop offset="0" stop-color="#fff" stop-opacity="0"/><stop offset="1" stop-color="#fff" stop-opacity=".9"/></linearGradient><linearGradient id="i" gradientUnits="userSpaceOnUse" x1="251" x2="251" xlink:href="#h" y1=".139" y2="452.139"/><linearGradient id="j" gradientUnits="userSpaceOnUse" x1="201" x2="301" xlink:href="#f" y1="226.139" y2="226.139"/><linearGradient id="k" gradientUnits="userSpaceOnUse" x1="251" x2="251" xlink:href="#h" y1="176.139" y2="276.139"/><mask id="l" height="376" maskUnits="userSpaceOnUse" width="350" x="74" y="77"><rect fill="#fff" height="375.39" rx="23.645" width="348.336" x="74.751" y="77.11"/></mask><g filter="url(#a)"><g mask="url(#l)"><g filter="url(#b)"><ellipse cx="162.818" cy="504.309" fill="#1c68f3" rx="123.492" ry="254.656"/></g><g filter="url(#c)"><ellipse cx="389.63" cy="223.623" fill="#1c68f3" rx="104.304" ry="215.088"/></g><g filter="url(#d)"><ellipse cx="329.114" cy="453.431" fill="#1c68f3" rx="123.492" ry="254.656"/></g><g filter="url(#e)"><ellipse cx="179.546" cy="-5.702" fill="#b0b8a1" rx="165.804" ry="341.909"/></g></g></g><rect fill="#fff" height="452" rx="20" width="452" x="25" y=".139"/><rect fill="url(#g)" height="452" rx="20" width="452" x="25" y=".139"/><rect fill="url(#i)" height="452" rx="20" width="452" x="25" y=".139"/><rect fill="url(#j)" height="100" rx="50" width="100" x="201" y="176.139"/><rect fill="url(#k)" height="100" rx="50" width="100" x="201" y="176.139"/><path clip-rule="evenodd" d="m279.976 214.796v16.204h-50.374c2.199 9.832 10.927 17.176 21.36 17.176 8.624 0 16.084-5.02 19.653-12.315h9.361v13.611c0 3.222-2.595 5.833-5.796 5.833h-46.364c-3.201 0-5.795-2.611-5.795-5.833v-34.676zm-14.919 21.065c-3.074 4.523-8.24 7.491-14.095 7.491-5.856 0-11.022-2.968-14.096-7.491zm-26.455-17.176c-4.542 0-8.299 3.38-8.924 7.778h4.94a4.191 4.191 0 0 1 3.984-2.917 4.19 4.19 0 0 1 3.984 2.917h4.94c-.625-4.398-4.382-7.778-8.924-7.778zm24.792 0c-4.542 0-8.299 3.38-8.924 7.778h4.94a4.191 4.191 0 0 1 3.984-2.917 4.19 4.19 0 0 1 3.984 2.917h4.94c-.625-4.398-4.382-7.778-8.924-7.778zm10.786-21.713c3.201 0 5.796 2.612 5.796 5.833v7.13h-57.955v-7.13c0-3.221 2.594-5.833 5.795-5.833z" fill="#fff" fill-rule="evenodd"/></svg>
\ No newline at end of file
diff --git a/packages/plugins/MaskBox/src/assets/bridge.png b/packages/plugins/MaskBox/src/assets/bridge.png
deleted file mode 100644
index e2a12cd3cc726c5ec6ee1e6ea0780f6861b8d83b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2326
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

diff --git a/packages/plugins/MaskBox/src/assets/mask_box.png b/packages/plugins/MaskBox/src/assets/mask_box.png
deleted file mode 100644
index ba70034ba540983a42309fd81a4e585c9b7f3a1a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1828
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
D<&BHk

diff --git a/packages/plugins/MaskBox/src/base.ts b/packages/plugins/MaskBox/src/base.ts
deleted file mode 100644
index d235a5912101..000000000000
--- a/packages/plugins/MaskBox/src/base.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import type { Plugin } from '@masknet/plugin-infra'
-import { DEFAULT_PLUGIN_PUBLISHER, EnhanceableSite } from '@masknet/shared-base'
-import { languages } from './locale/languages.js'
-import { PLUGIN_ID } from './constants.js'
-
-export const base: Plugin.Shared.Definition = {
-    ID: PLUGIN_ID,
-    name: { fallback: 'MaskBox' },
-    description: { fallback: 'The mystery box with NFT inside which is provided by Mask Network.' },
-    publisher: DEFAULT_PLUGIN_PUBLISHER,
-    enableRequirement: {
-        supports: {
-            type: 'opt-out',
-            sites: {
-                [EnhanceableSite.Localhost]: true,
-            },
-        },
-        target: 'stable',
-    },
-    experimentalMark: true,
-    i18n: languages,
-    contribution: {
-        postContent: new Set(['https://box-beta.mask.io', 'https://box.mask.io']),
-    },
-}
diff --git a/packages/plugins/MaskBox/src/constants.ts b/packages/plugins/MaskBox/src/constants.ts
deleted file mode 100644
index 3cb383071749..000000000000
--- a/packages/plugins/MaskBox/src/constants.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { PluginID } from '@masknet/shared-base'
-
-export const PLUGIN_ID = PluginID.MaskBox
-export const MERKLE_PROOF_ENDPOINT =
-    'https://lf8d031acj.execute-api.ap-east-1.amazonaws.com/api/v1/merkle_tree/leaf_exists'
diff --git a/packages/plugins/MaskBox/src/helpers/formatCountdown.ts b/packages/plugins/MaskBox/src/helpers/formatCountdown.ts
deleted file mode 100644
index fb8d73aae7f3..000000000000
--- a/packages/plugins/MaskBox/src/helpers/formatCountdown.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { formatDuration, intervalToDuration } from 'date-fns'
-
-export function formatCountdown(from: number, to: number) {
-    const duration = intervalToDuration({ start: from, end: to })
-    return formatDuration(duration)
-}
diff --git a/packages/plugins/MaskBox/src/hooks/useContext.ts b/packages/plugins/MaskBox/src/hooks/useContext.ts
deleted file mode 100644
index a69bed4e516f..000000000000
--- a/packages/plugins/MaskBox/src/hooks/useContext.ts
+++ /dev/null
@@ -1,369 +0,0 @@
-import { useEffect, useMemo, useState, useCallback } from 'react'
-import { useAsyncRetry } from 'react-use'
-import { fromUnixTime, addDays, subDays } from 'date-fns'
-import { omit, clamp, first, uniq } from 'lodash-es'
-import { BigNumber } from 'bignumber.js'
-import { createContainer } from '@masknet/shared-base-ui'
-import { unreachable } from '@masknet/kit'
-import { useERC20TokenAllowance } from '@masknet/web3-hooks-evm'
-import {
-    useMaskBoxConstants,
-    isZeroAddress,
-    SchemaType,
-    isNativeTokenAddress,
-    abiCoder,
-} from '@masknet/web3-shared-evm'
-import type { NonPayableTx } from '@masknet/web3-contracts/types/types.js'
-import { type BoxInfo, BoxState } from '../type.js'
-import { useMaskBoxInfo } from './useMaskBoxInfo.js'
-import { useMerkleProof } from './useMerkleProof.js'
-import { useMaskBoxStatus } from './useMaskBoxStatus.js'
-import { useMaskBoxCreationSuccessEvent } from './useMaskBoxCreationSuccessEvent.js'
-import { useMaskBoxTokensForSale } from './useMaskBoxTokensForSale.js'
-import { useMaskBoxPurchasedTokens } from './useMaskBoxPurchasedTokens.js'
-import { formatCountdown } from '../helpers/formatCountdown.js'
-import { useOpenBoxTransaction } from './useOpenBoxTransaction.js'
-import { useMaskBoxMetadata } from './useMaskBoxMetadata.js'
-import { useQualification } from './useQualification.js'
-import {
-    formatBalance,
-    isGreaterThan,
-    isGreaterThanOrEqualTo,
-    isLessThanOrEqualTo,
-    isSameAddress,
-    multipliedBy,
-} from '@masknet/web3-shared-base'
-import { NetworkPluginID, EMPTY_LIST } from '@masknet/shared-base'
-import {
-    useChainContext,
-    useBalance,
-    useFungibleToken,
-    useFungibleTokenBalance,
-    useFungibleTokens,
-    useNonFungibleTokenContract,
-} from '@masknet/web3-hooks-base'
-
-function useContext(initialState?: { boxId: string; hashRoot: string }) {
-    const now = new Date()
-    const { account } = useChainContext<NetworkPluginID.PLUGIN_EVM>()
-
-    const { MASK_BOX_CONTRACT_ADDRESS } = useMaskBoxConstants()
-
-    const [boxId, setBoxId] = useState(initialState?.boxId ?? '')
-    const rootHash = initialState?.hashRoot || ''
-    const [paymentTokenAddress, setPaymentTokenAddress] = useState('')
-
-    // #region the box info
-    const {
-        value: maskBoxInfo = null,
-        error: errorMaskBoxInfo,
-        loading: loadingMaskBoxInfo,
-        retry: retryMaskBoxInfo,
-    } = useMaskBoxInfo(boxId)
-
-    const {
-        value: maskBoxStatus = null,
-        error: errorMaskBoxStatus,
-        loading: loadingMaskBoxStatus,
-        retry: retryMaskBoxStatus,
-    } = useMaskBoxStatus(boxId)
-    const { value: maskBoxCreationSuccessEvent = null, retry: retryMaskBoxCreationSuccessEvent } =
-        useMaskBoxCreationSuccessEvent(maskBoxInfo?.creator ?? '', maskBoxInfo?.nft_address ?? '', boxId)
-    const { value: paymentTokens = EMPTY_LIST } = useFungibleTokens(
-        NetworkPluginID.PLUGIN_EVM,
-        maskBoxStatus?.payment?.map(([address]) => address) ?? [],
-    )
-    const { value: allTokens = EMPTY_LIST, retry: retryMaskBoxTokensForSale } = useMaskBoxTokensForSale(boxId)
-    const { value: purchasedTokens = EMPTY_LIST, retry: retryMaskBoxPurchasedTokens } = useMaskBoxPurchasedTokens(
-        boxId,
-        account,
-    )
-
-    const {
-        value: boxInfo = null,
-        error: errorBoxInfo,
-        loading: loadingBoxInfo,
-        retry: retryBoxInfo,
-    } = useAsyncRetry<BoxInfo | null>(async () => {
-        if (!maskBoxInfo || !maskBoxStatus || !maskBoxInfo.creator || isZeroAddress(maskBoxInfo.creator)) return null
-        const personalLimit = Number.parseInt(maskBoxInfo.personal_limit, 10)
-        const remaining = Number.parseInt(maskBoxStatus.remaining, 10) // the current balance of the creator's account
-        const total = Number.parseInt(maskBoxStatus.total, 10) // the total amount of tokens in the box
-        const totalComputed = total && remaining && remaining > total ? remaining : total
-        const sold = Math.max(0, totalComputed - remaining)
-        const personalRemaining = Math.max(0, personalLimit - purchasedTokens.length)
-        const startAt = Number.parseInt(maskBoxCreationSuccessEvent?.returnValues.start_time || '0', 10)
-        const endAt = Number.parseInt(maskBoxCreationSuccessEvent?.returnValues.end_time || '0', 10)
-        const info: BoxInfo = {
-            boxId,
-            creator: maskBoxInfo.creator,
-            name: maskBoxInfo.name,
-            sellAll: maskBoxCreationSuccessEvent?.returnValues.sell_all ?? false,
-            personalLimit,
-            personalRemaining,
-            remaining,
-            availableAmount: Math.min(personalRemaining, remaining),
-            startAt: startAt === 0 ? subDays(new Date(), 1) : fromUnixTime(startAt),
-            endAt: endAt === 0 ? addDays(new Date(), 1) : fromUnixTime(endAt),
-            started: maskBoxStatus.started,
-            total: totalComputed,
-            sold,
-            canceled: maskBoxStatus.canceled,
-            tokenIds: allTokens,
-            tokenIdsPurchased: purchasedTokens,
-            payments: paymentTokens.map((token, i) => {
-                return {
-                    token,
-                    price: maskBoxStatus.payment[i][1],
-                    receivableAmount: maskBoxStatus.payment[i][2],
-                }
-            }),
-            tokenAddress: maskBoxInfo.nft_address,
-            heroImageURL: '',
-            qualificationAddress: maskBoxInfo.qualification,
-            holderTokenAddress: maskBoxInfo.holder_token_addr,
-            holderMinTokenAmount: maskBoxInfo.holder_min_token_amount,
-        }
-        return info
-    }, [allTokens, purchasedTokens, paymentTokens, maskBoxInfo, maskBoxStatus, maskBoxCreationSuccessEvent])
-    // #endregion
-
-    // #region qualification
-    const { value, error: errorProof, loading: loadingProof } = useMerkleProof(rootHash)
-    const proofBytes =
-        value?.proof ? abiCoder.encodeParameters(['bytes32[]'], [value.proof.map((p) => `0x${p}`) ?? []]) : undefined
-    const qualification = useQualification(
-        boxInfo?.qualificationAddress,
-        account,
-        value?.proof ? abiCoder.encodeParameters(['bytes', 'bytes32'], [proofBytes, rootHash]) : undefined,
-    )
-
-    // not in whitelist
-    const notInWhiteList = value?.message === 'leaf not found'
-
-    // at least hold token amount
-    const { data: holderToken } = useFungibleToken(NetworkPluginID.PLUGIN_EVM, boxInfo?.holderTokenAddress)
-    const { data: holderTokenBalance = '0' } = useFungibleTokenBalance(NetworkPluginID.PLUGIN_EVM, holderToken?.address)
-    const holderMinTokenAmountBN = new BigNumber(boxInfo?.holderMinTokenAmount ?? 0)
-    const insufficientHolderToken =
-        isGreaterThan(holderMinTokenAmountBN, 0) && !holderMinTokenAmountBN.lte(holderTokenBalance)
-    // #endregion
-
-    const boxState = useMemo(() => {
-        if (notInWhiteList) {
-            return BoxState.NOT_IN_WHITELIST
-        }
-        if (insufficientHolderToken) return BoxState.INSUFFICIENT_HOLDER_TOKEN
-        if (qualification?.error_msg) return BoxState.NOT_QUALIFIED
-        if (errorMaskBoxInfo || errorMaskBoxStatus || errorBoxInfo || (rootHash ? errorProof : false))
-            return BoxState.ERROR
-        if (loadingMaskBoxInfo || loadingMaskBoxStatus || loadingBoxInfo || (rootHash ? loadingProof : false)) {
-            if (!maskBoxInfo && !boxInfo) return BoxState.UNKNOWN
-        }
-        if (maskBoxInfo && !boxInfo) return BoxState.UNKNOWN
-        if (!maskBoxInfo || !maskBoxStatus || !boxInfo) return BoxState.NOT_FOUND
-        if (maskBoxStatus.canceled) return BoxState.CANCELED
-        if (isGreaterThanOrEqualTo(boxInfo.tokenIdsPurchased.length, boxInfo.personalLimit)) return BoxState.DREW_OUT
-        if (isLessThanOrEqualTo(boxInfo.remaining, 0)) return BoxState.SOLD_OUT
-        if (boxInfo.startAt > now || !boxInfo.started) return BoxState.NOT_READY
-        if (boxInfo.endAt < now || maskBoxStatus?.expired) return BoxState.EXPIRED
-        return BoxState.READY
-    }, [
-        boxInfo,
-        loadingBoxInfo,
-        errorBoxInfo,
-        maskBoxInfo,
-        loadingMaskBoxInfo,
-        errorMaskBoxInfo,
-        qualification,
-        loadingProof,
-        errorProof,
-        rootHash,
-        notInWhiteList,
-        insufficientHolderToken,
-    ])
-
-    const boxStateMessage = useMemo(() => {
-        switch (boxState) {
-            case BoxState.UNKNOWN:
-                return 'Loading...'
-            case BoxState.CANCELED:
-                return 'Canceled'
-            case BoxState.READY:
-                return 'Draw'
-            case BoxState.EXPIRED:
-                return 'Ended'
-            case BoxState.NOT_READY:
-                const nowAt = now.getTime()
-                const startAt = boxInfo?.startAt.getTime() ?? 0
-                if (startAt <= nowAt) return 'Syncing status...'
-                const countdown = formatCountdown(startAt, nowAt)
-                return countdown ? `Start sale in ${countdown}` : 'Loading...'
-            case BoxState.SOLD_OUT:
-                return 'Sold Out'
-            case BoxState.NOT_IN_WHITELIST:
-                return 'You are not in the whitelist.'
-            case BoxState.INSUFFICIENT_HOLDER_TOKEN:
-                const { symbol, decimals } = holderToken ?? {}
-                const tokenPrice = `${formatBalance(boxInfo?.holderMinTokenAmount, decimals)} $${symbol}`
-                return `You must hold at least ${tokenPrice}.`
-            case BoxState.NOT_QUALIFIED:
-                return qualification?.error_msg ?? 'Not qualified.'
-            case BoxState.DREW_OUT:
-                return 'Purchase limit exceeded.'
-            case BoxState.ERROR:
-                return 'Something went wrong.'
-            case BoxState.NOT_FOUND:
-                return 'Failed to load box info.'
-            default:
-                unreachable(boxState)
-        }
-    }, [holderToken, boxState, boxInfo?.startAt, qualification])
-
-    useEffect(() => {
-        if (!boxInfo || boxInfo.started) return
-
-        if (boxInfo.startAt < now) {
-            retryMaskBoxStatus()
-        }
-    }, [boxInfo])
-
-    // #region the box metadata
-    const { value: boxMetadata, retry: retryBoxMetadata } = useMaskBoxMetadata(boxId, boxInfo?.creator ?? '')
-    // #endregion
-
-    // #region the erc721 contract detailed
-    const { value: contractDetailed } = useNonFungibleTokenContract(
-        NetworkPluginID.PLUGIN_EVM,
-        maskBoxInfo?.nft_address ?? '',
-        SchemaType.ERC721,
-        { account },
-    )
-    // #endregion
-
-    // #region the payment count
-    const [paymentCount, setPaymentCount] = useState(1)
-    const setPaymentCount_ = useCallback(
-        (count: number) => {
-            setPaymentCount(clamp(count || 1, 1, boxInfo?.personalRemaining ?? 1))
-        },
-        [boxInfo?.personalRemaining],
-    )
-    // #endregion
-
-    // #region token ids
-    const [lastAllTokenIds, setLastAllTokenIds] = useState<string[]>([])
-    const [lastPurchasedTokenIds, setLastPurchasedTokenIds] = useState<string[]>([])
-    const refreshLastPurchasedTokenIds = useCallback(() => {
-        setLastPurchasedTokenIds((tokenIds) => uniq([...tokenIds, ...purchasedTokens]))
-    }, [purchasedTokens.length])
-    // #endregion
-
-    // #region the payment token
-    const { data: paymentNativeTokenBalance = '0' } = useBalance()
-    const { data: paymentERC20TokenBalance = '0' } = useFungibleTokenBalance(
-        NetworkPluginID.PLUGIN_EVM,
-        isNativeTokenAddress(paymentTokenAddress) ? '' : paymentTokenAddress,
-    )
-    const paymentTokenInfo = boxInfo?.payments.find((x) => isSameAddress(x.token.address, paymentTokenAddress))
-    const paymentTokenIndex =
-        boxInfo?.payments.findIndex((x) => isSameAddress(x.token.address ?? '', paymentTokenAddress)) ?? -1
-    const paymentTokenPrice = paymentTokenInfo?.price ?? '0'
-    const costAmount = multipliedBy(paymentTokenPrice, paymentCount)
-    const isNativeToken = isNativeTokenAddress(paymentTokenAddress)
-    const paymentTokenBalance = isNativeToken ? paymentNativeTokenBalance : paymentERC20TokenBalance
-    const paymentTokenDetailed = paymentTokenInfo?.token ?? null
-    const isBalanceInsufficient = costAmount.gt(paymentTokenBalance)
-
-    {
-        const firstPaymentTokenAddress = first(boxInfo?.payments)?.token.address
-        if (paymentTokenAddress === '' && firstPaymentTokenAddress) setPaymentTokenAddress(firstPaymentTokenAddress)
-    }
-    // #endregion
-
-    // #region transactions
-    const [openBoxTransactionOverrides, setOpenBoxTransactionOverrides] = useState<NonPayableTx | null>(null)
-    const openBoxTransaction = useOpenBoxTransaction(
-        boxId,
-        paymentCount,
-        paymentTokenIndex,
-        paymentTokenPrice,
-        paymentTokenDetailed,
-        proofBytes,
-        openBoxTransactionOverrides,
-    )
-    const { data: erc20Allowance, refetch: retryAllowance } = useERC20TokenAllowance(
-        isNativeToken ? undefined : paymentTokenAddress,
-        MASK_BOX_CONTRACT_ADDRESS,
-    )
-    const canPurchase = !isBalanceInsufficient && !!boxInfo?.personalRemaining
-    const allowToPurchase = boxState === BoxState.READY
-    const isAllowanceEnough = isNativeToken ? true : costAmount.lte(erc20Allowance ?? '0')
-    const { value: openBoxTransactionGasLimit } = useAsyncRetry(async () => {
-        if (!openBoxTransaction || !canPurchase || !allowToPurchase || !isAllowanceEnough) return
-        const estimatedGas = await openBoxTransaction.method.estimateGas(omit(openBoxTransaction.config, 'gas'))
-        return new BigNumber(estimatedGas).toNumber()
-    }, [openBoxTransaction, canPurchase, allowToPurchase, isAllowanceEnough])
-    // #endregion
-
-    return {
-        // box id
-        boxId,
-        setBoxId,
-
-        // box info & metadata
-        boxInfo,
-        boxMetadata,
-
-        // box state
-        boxState,
-        boxStateMessage,
-
-        // erc721 contract detailed
-        contractDetailed,
-
-        // payment count
-        paymentCount,
-        setPaymentCount: setPaymentCount_,
-
-        // payment address
-        paymentTokenAddress: paymentTokenAddress || (first(boxInfo?.payments)?.token.address ?? ''),
-        setPaymentTokenAddress: (address: string) => {
-            if (boxInfo?.payments.some((x) => isSameAddress(x.token.address ?? '', address)))
-                setPaymentTokenAddress(address)
-        },
-
-        // token ids
-        lastAllTokenIds,
-        setLastAllTokenIds,
-        lastPurchasedTokenIds,
-        setLastPurchasedTokenIds,
-        refreshLastPurchasedTokenIds,
-
-        // payment token
-        paymentTokenPrice,
-        paymentTokenIndex,
-        paymentTokenBalance,
-        paymentTokenDetailed,
-        isBalanceInsufficient,
-        isAllowanceEnough,
-
-        // transactions
-        openBoxTransaction,
-        openBoxTransactionGasLimit,
-        openBoxTransactionOverrides,
-        setOpenBoxTransactionOverrides,
-
-        // retry callbacks
-        retryAllowance,
-        retryMaskBoxInfo,
-        retryMaskBoxStatus,
-        retryBoxInfo,
-        retryBoxMetadata,
-        retryMaskBoxCreationSuccessEvent,
-        retryMaskBoxTokensForSale,
-        retryMaskBoxPurchasedTokens,
-    }
-}
-
-export const Context = createContainer(useContext)
diff --git a/packages/plugins/MaskBox/src/hooks/useMaskBoxContract.ts b/packages/plugins/MaskBox/src/hooks/useMaskBoxContract.ts
deleted file mode 100644
index 6a3b904c60be..000000000000
--- a/packages/plugins/MaskBox/src/hooks/useMaskBoxContract.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import type { AbiItem } from 'web3-utils'
-import type { MaskBox } from '@masknet/web3-contracts/types/MaskBox.js'
-import MASK_BOX_ABI from '@masknet/web3-contracts/abis/MaskBox.json' with { type: 'json' }
-import { useMaskBoxConstants, type ChainId } from '@masknet/web3-shared-evm'
-import { useChainContext } from '@masknet/web3-hooks-base'
-import { useContract } from '@masknet/web3-hooks-evm'
-
-export function useMaskBoxContract() {
-    const { chainId } = useChainContext()
-    const { MASK_BOX_CONTRACT_ADDRESS } = useMaskBoxConstants(chainId)
-    return useContract<MaskBox>(chainId as ChainId, MASK_BOX_CONTRACT_ADDRESS, MASK_BOX_ABI as AbiItem[])
-}
diff --git a/packages/plugins/MaskBox/src/hooks/useMaskBoxCreationSuccessEvent.ts b/packages/plugins/MaskBox/src/hooks/useMaskBoxCreationSuccessEvent.ts
deleted file mode 100644
index 72bf686dc1fb..000000000000
--- a/packages/plugins/MaskBox/src/hooks/useMaskBoxCreationSuccessEvent.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { first, range as rangeNum } from 'lodash-es'
-import { useAsyncRetry } from 'react-use'
-import type { CreationSuccess } from '@masknet/web3-contracts/types/MaskBox.js'
-import { useMaskBoxConstants } from '@masknet/web3-shared-evm'
-import { EVMWeb3 } from '@masknet/web3-providers'
-import { useMaskBoxContract } from './useMaskBoxContract.js'
-
-// dynamically set the block range window size
-const FRAGMENT_SIZE = 3000
-const MAX_PAGE_SIZE = 10
-
-export function useMaskBoxCreationSuccessEvent(creatorAddress: string, tokenAddress: string, boxId: string) {
-    const maskBoxContract = useMaskBoxContract()
-    const { MASK_BOX_CONTRACT_FROM_BLOCK } = useMaskBoxConstants()
-
-    return useAsyncRetry(async () => {
-        if (!maskBoxContract) return null
-
-        const getPastEvents = (fromBlock: number, toBlock: number) => {
-            return maskBoxContract.getPastEvents('CreationSuccess', {
-                filter: {
-                    creator: creatorAddress,
-                    nft_address: tokenAddress,
-                    box_id: boxId,
-                },
-                fromBlock,
-                toBlock,
-            })
-        }
-
-        const blockNumber = await EVMWeb3.getBlockNumber()
-        const range = blockNumber - (MASK_BOX_CONTRACT_FROM_BLOCK ?? Math.max(0, blockNumber - FRAGMENT_SIZE))
-        const size = Math.min(MAX_PAGE_SIZE, Math.ceil(range / FRAGMENT_SIZE))
-        const allSettled = await Promise.allSettled(
-            rangeNum(size).map((index) =>
-                getPastEvents(blockNumber - FRAGMENT_SIZE * (index + 1), blockNumber - FRAGMENT_SIZE * index - 1),
-            ),
-        )
-        const events = allSettled.flatMap((x) => (x.status === 'fulfilled' ? x.value : []))
-        const filtered = (events as unknown as CreationSuccess[]).filter((evt) => evt.returnValues.box_id === boxId)
-        return first(filtered)
-    }, [boxId, creatorAddress, tokenAddress, maskBoxContract, MASK_BOX_CONTRACT_FROM_BLOCK])
-}
diff --git a/packages/plugins/MaskBox/src/hooks/useMaskBoxInfo.ts b/packages/plugins/MaskBox/src/hooks/useMaskBoxInfo.ts
deleted file mode 100644
index 18be0bdff01f..000000000000
--- a/packages/plugins/MaskBox/src/hooks/useMaskBoxInfo.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { useAsyncRetry } from 'react-use'
-import { useMaskBoxContract } from './useMaskBoxContract.js'
-
-export function useMaskBoxInfo(id: string | number) {
-    const maskBoxContract = useMaskBoxContract()
-    return useAsyncRetry(async () => {
-        if (!maskBoxContract) return null
-        const info = await maskBoxContract.methods.getBoxInfo(id).call()
-        return info
-    }, [id, maskBoxContract])
-}
diff --git a/packages/plugins/MaskBox/src/hooks/useMaskBoxMetadata.ts b/packages/plugins/MaskBox/src/hooks/useMaskBoxMetadata.ts
deleted file mode 100644
index 6f6fc471eb18..000000000000
--- a/packages/plugins/MaskBox/src/hooks/useMaskBoxMetadata.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { useAsyncRetry } from 'react-use'
-import { isValidAddress } from '@masknet/web3-shared-evm'
-import { MaskBoxRPC } from '../messages.js'
-
-export function useMaskBoxMetadata(boxId: string, creator: string) {
-    return useAsyncRetry(async () => {
-        if (!boxId || !creator || !isValidAddress(creator)) return
-        return MaskBoxRPC.getMaskBoxMetadata(boxId, creator)
-    }, [creator])
-}
diff --git a/packages/plugins/MaskBox/src/hooks/useMaskBoxPurchasedTokens.ts b/packages/plugins/MaskBox/src/hooks/useMaskBoxPurchasedTokens.ts
deleted file mode 100644
index ae6078acd174..000000000000
--- a/packages/plugins/MaskBox/src/hooks/useMaskBoxPurchasedTokens.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { useAsyncRetry } from 'react-use'
-import { EMPTY_LIST } from '@masknet/shared-base'
-import { useMaskBoxContract } from './useMaskBoxContract.js'
-
-export function useMaskBoxPurchasedTokens(id: string | number, customer: string) {
-    const maskBoxContract = useMaskBoxContract()
-    return useAsyncRetry(async () => {
-        if (!maskBoxContract) return EMPTY_LIST
-        return maskBoxContract.methods.getPurchasedNft(id, customer).call()
-    }, [id, customer, maskBoxContract])
-}
diff --git a/packages/plugins/MaskBox/src/hooks/useMaskBoxQualificationContract.ts b/packages/plugins/MaskBox/src/hooks/useMaskBoxQualificationContract.ts
deleted file mode 100644
index 1a8dfecbb723..000000000000
--- a/packages/plugins/MaskBox/src/hooks/useMaskBoxQualificationContract.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import type { AbiItem } from 'web3-utils'
-import type { ChainId } from '@masknet/web3-shared-evm'
-import type { MaskBoxQualification } from '@masknet/web3-contracts/types/MaskBoxQualification.js'
-import MASK_BOX_QUALIFICATION_CONTRACT from '@masknet/web3-contracts/abis/MaskBoxQualification.json' with { type: 'json' }
-import { useContract } from '@masknet/web3-hooks-evm'
-
-export function useMaskBoxQualificationContract(chainId: ChainId, address?: string) {
-    return useContract<MaskBoxQualification>(chainId, address, MASK_BOX_QUALIFICATION_CONTRACT as AbiItem[])
-}
diff --git a/packages/plugins/MaskBox/src/hooks/useMaskBoxStatus.ts b/packages/plugins/MaskBox/src/hooks/useMaskBoxStatus.ts
deleted file mode 100644
index f0d915792f51..000000000000
--- a/packages/plugins/MaskBox/src/hooks/useMaskBoxStatus.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { useAsyncRetry } from 'react-use'
-import { useMaskBoxContract } from './useMaskBoxContract.js'
-
-export function useMaskBoxStatus(id: string | number) {
-    const maskBoxContract = useMaskBoxContract()
-    return useAsyncRetry(async () => {
-        if (!maskBoxContract) return null
-        return maskBoxContract.methods.getBoxStatus(id).call()
-    }, [id, maskBoxContract])
-}
diff --git a/packages/plugins/MaskBox/src/hooks/useMaskBoxTokensForSale.ts b/packages/plugins/MaskBox/src/hooks/useMaskBoxTokensForSale.ts
deleted file mode 100644
index f3bbbab5115c..000000000000
--- a/packages/plugins/MaskBox/src/hooks/useMaskBoxTokensForSale.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { useAsyncRetry } from 'react-use'
-import { useMaskBoxContract } from './useMaskBoxContract.js'
-
-export function useMaskBoxTokensForSale(id: string | number) {
-    const maskBoxContract = useMaskBoxContract()
-    return useAsyncRetry(async () => {
-        if (!maskBoxContract) return []
-        return maskBoxContract.methods.getNftListForSale(id, 0, 100).call()
-    }, [id, maskBoxContract])
-}
diff --git a/packages/plugins/MaskBox/src/hooks/useMerkleProof.ts b/packages/plugins/MaskBox/src/hooks/useMerkleProof.ts
deleted file mode 100644
index f09c28e0ab74..000000000000
--- a/packages/plugins/MaskBox/src/hooks/useMerkleProof.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { useAsyncRetry } from 'react-use'
-import { useChainContext } from '@masknet/web3-hooks-base'
-import type { NetworkPluginID } from '@masknet/shared-base'
-import { getMerkleProof } from '../apis/index.js'
-
-export function useMerkleProof(root?: string) {
-    const { account } = useChainContext<NetworkPluginID.PLUGIN_EVM>()
-    return useAsyncRetry(async () => {
-        if (!root) return
-
-        const leaf = Buffer.from(
-            (account.replace(/0x/, '').match(/.{2}/g) ?? []).map((x) => Number.parseInt(x, 16)),
-        ).toString('base64')
-
-        return getMerkleProof(leaf, root)
-    }, [account, root])
-}
diff --git a/packages/plugins/MaskBox/src/hooks/useOpenBoxTransaction.ts b/packages/plugins/MaskBox/src/hooks/useOpenBoxTransaction.ts
deleted file mode 100644
index 0a541ab148e0..000000000000
--- a/packages/plugins/MaskBox/src/hooks/useOpenBoxTransaction.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { useMemo } from 'react'
-import { useChainContext } from '@masknet/web3-hooks-base'
-import type { NonPayableTx } from '@masknet/web3-contracts/types/types.js'
-import { type FungibleToken, multipliedBy } from '@masknet/web3-shared-base'
-import type { NetworkPluginID } from '@masknet/shared-base'
-import { type ChainId, SchemaType } from '@masknet/web3-shared-evm'
-import { useMaskBoxContract } from './useMaskBoxContract.js'
-
-export function useOpenBoxTransaction(
-    boxId: string,
-    amount: number,
-    paymentTokenIndex: number,
-    paymentTokenPrice: string,
-    paymentTokenDetailed: FungibleToken<ChainId, SchemaType> | null,
-    proof?: string,
-    overrides?: NonPayableTx | null,
-) {
-    const { account } = useChainContext<NetworkPluginID.PLUGIN_EVM>()
-    const maskBoxContract = useMaskBoxContract()
-    return useMemo(() => {
-        if (!boxId || amount <= 0 || !maskBoxContract) return
-        return {
-            config: {
-                ...overrides,
-                from: account,
-                value:
-                    paymentTokenDetailed?.schema === SchemaType.Native ?
-                        multipliedBy(paymentTokenPrice, amount).toFixed()
-                    :   undefined,
-            },
-            method: maskBoxContract.methods.openBox(boxId, amount, paymentTokenIndex, proof ?? '0x00'),
-        }
-    }, [
-        account,
-        amount,
-        boxId,
-        maskBoxContract,
-        paymentTokenIndex,
-        paymentTokenPrice,
-        paymentTokenDetailed,
-        proof,
-        overrides,
-    ])
-}
diff --git a/packages/plugins/MaskBox/src/hooks/useQualification.ts b/packages/plugins/MaskBox/src/hooks/useQualification.ts
deleted file mode 100644
index c9c553b52b2b..000000000000
--- a/packages/plugins/MaskBox/src/hooks/useQualification.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { useChainContext } from '@masknet/web3-hooks-base'
-import type { NetworkPluginID } from '@masknet/shared-base'
-import { useAsyncRetry } from 'react-use'
-import { useMaskBoxQualificationContract } from './useMaskBoxQualificationContract.js'
-
-export function useQualification(address?: string, account?: string, proof?: string) {
-    const { chainId } = useChainContext<NetworkPluginID.PLUGIN_EVM>()
-    const qualificationContract = useMaskBoxQualificationContract(chainId, address)
-    const { value: qualification = { qualified: false, error_msg: '' } } = useAsyncRetry(async () => {
-        if (!qualificationContract || !account) return null
-        return qualificationContract.methods.is_qualified(account, proof ?? '0x00').call({
-            from: account,
-        })
-    }, [account, qualificationContract, proof])
-    return qualification
-}
diff --git a/packages/plugins/MaskBox/src/locale/en-US.json b/packages/plugins/MaskBox/src/locale/en-US.json
deleted file mode 100644
index 683f4068e9be..000000000000
--- a/packages/plugins/MaskBox/src/locale/en-US.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "messages": {
-        "Xmf1TZ": [["boxStateMessage"], " (", ["0"], " ", ["1"], "/Time)"],
-        "F6pfE9": "Active",
-        "Tt5T6+": "Articles",
-        "Vi2Pqx": "by",
-        "D87pha": "Closed",
-        "URmyfc": "Details",
-        "2vTp2v": "Draw",
-        "rFkZD1": "Drawing",
-        "EexGwP": "I just claimed a #MaskBox with @realMaskNetwork. Install mask.io and create your own NFT mystery box!",
-        "znqB4T": "Insufficient balance",
-        "ml4bvW": "Limit:",
-        "0Lp4o6": "Load failed",
-        "WNjtSq": "MaskBox",
-        "r0A2o4": "Professional multi-chain decentralized platform for launching NFT blind boxes.",
-        "HpK/8d": "Reload",
-        "WbEaq/": "Solid:"
-    }
-}
diff --git a/packages/plugins/MaskBox/src/locale/en-US.po b/packages/plugins/MaskBox/src/locale/en-US.po
deleted file mode 100644
index 45417c41857d..000000000000
--- a/packages/plugins/MaskBox/src/locale/en-US.po
+++ /dev/null
@@ -1,78 +0,0 @@
-msgid ""
-msgstr ""
-"Project-Id-Version: \n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: \n"
-"PO-Revision-Date: \n"
-"Last-Translator: \n"
-"Language: \n"
-"Language-Team: \n"
-"Content-Type: \n"
-"Content-Transfer-Encoding: \n"
-"Plural-Forms: \n"
-
-#: src/SiteAdaptor/components/PreviewCard.tsx
-msgid "{boxStateMessage} ({0} {1}/Time)"
-msgstr ""
-
-#: src/SiteAdaptor/components/PreviewCard.tsx
-msgid "Active"
-msgstr ""
-
-#: src/SiteAdaptor/components/PreviewCard.tsx
-msgid "Articles"
-msgstr ""
-
-#: src/SiteAdaptor/components/PreviewCard.tsx
-msgid "by"
-msgstr ""
-
-#: src/SiteAdaptor/components/PreviewCard.tsx
-msgid "Closed"
-msgstr ""
-
-#: src/SiteAdaptor/components/PreviewCard.tsx
-msgid "Details"
-msgstr ""
-
-#: src/SiteAdaptor/components/DrawDialog.tsx
-msgid "Draw"
-msgstr ""
-
-#: src/SiteAdaptor/components/DrawDialog.tsx
-msgid "Drawing"
-msgstr ""
-
-#: src/SiteAdaptor/components/DrawResultDialog.tsx
-msgid "I just claimed a #MaskBox with @realMaskNetwork. Install mask.io and create your own NFT mystery box!"
-msgstr ""
-
-#: src/SiteAdaptor/components/DrawDialog.tsx
-msgid "Insufficient balance"
-msgstr ""
-
-#: src/SiteAdaptor/components/PreviewCard.tsx
-msgid "Limit:"
-msgstr ""
-
-#: src/SiteAdaptor/components/PreviewCard.tsx
-#: src/SiteAdaptor/components/PreviewCard.tsx
-msgid "Load failed"
-msgstr ""
-
-#: src/SiteAdaptor/index.tsx
-msgid "MaskBox"
-msgstr ""
-
-#: src/SiteAdaptor/index.tsx
-msgid "Professional multi-chain decentralized platform for launching NFT blind boxes."
-msgstr ""
-
-#: src/SiteAdaptor/components/PreviewCard.tsx
-#: src/SiteAdaptor/components/PreviewCard.tsx
-msgid "Reload"
-msgstr ""
-
-#: src/SiteAdaptor/components/PreviewCard.tsx
-msgid "Solid:"
-msgstr ""
diff --git a/packages/plugins/MaskBox/src/locale/ja-JP.json b/packages/plugins/MaskBox/src/locale/ja-JP.json
deleted file mode 100644
index 1ac97b8140fe..000000000000
--- a/packages/plugins/MaskBox/src/locale/ja-JP.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "messages": {
-        "Xmf1TZ": [["boxStateMessage"], " (", ["0"], " ", ["1"], "/Time)"],
-        "F6pfE9": "アクティブ",
-        "Tt5T6+": "記事",
-        "Vi2Pqx": "によって",
-        "D87pha": "終了",
-        "URmyfc": "詳細",
-        "2vTp2v": "引く",
-        "rFkZD1": "引く中",
-        "EexGwP": "I just claimed a #MaskBox with @realMaskNetwork. Install mask.io and create your own NFT mystery box!",
-        "znqB4T": "残高不足",
-        "ml4bvW": "制限:",
-        "0Lp4o6": "読み込みに失敗しました",
-        "WNjtSq": "MaskBox",
-        "r0A2o4": "Professional multi-chain decentralized platform for launching NFT blind boxes.",
-        "HpK/8d": "再度読み込み",
-        "WbEaq/": "安定した"
-    }
-}
diff --git a/packages/plugins/MaskBox/src/locale/ko-KR.json b/packages/plugins/MaskBox/src/locale/ko-KR.json
deleted file mode 100644
index 8a4e55682ebb..000000000000
--- a/packages/plugins/MaskBox/src/locale/ko-KR.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "messages": {
-        "Xmf1TZ": [["boxStateMessage"], " (", ["0"], " ", ["1"], "/Time)"],
-        "F6pfE9": "활성화",
-        "Tt5T6+": "아티클",
-        "Vi2Pqx": "by",
-        "D87pha": "종료됨",
-        "URmyfc": "디테일",
-        "2vTp2v": "뽑기",
-        "rFkZD1": "뽑는 중",
-        "EexGwP": "I just claimed a #MaskBox with @realMaskNetwork. Install mask.io and create your own NFT mystery box!",
-        "znqB4T": "잔액 부족",
-        "ml4bvW": "제한:",
-        "0Lp4o6": "로딩 실패",
-        "WNjtSq": "MaskBox",
-        "r0A2o4": "Professional multi-chain decentralized platform for launching NFT blind boxes.",
-        "HpK/8d": "다시 로드",
-        "WbEaq/": "Solid:"
-    }
-}
diff --git a/packages/plugins/MaskBox/src/locale/languages.ts b/packages/plugins/MaskBox/src/locale/languages.ts
deleted file mode 100644
index 783646a15ac5..000000000000
--- a/packages/plugins/MaskBox/src/locale/languages.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-// This file is auto generated. DO NOT EDIT
-// Run `npx gulp sync-languages` to regenerate.
-// Default fallback language in a family of languages are chosen by the alphabet order
-// To overwrite this, please overwrite packages/scripts/src/locale-kit-next/index.ts
-import en_US from './en-US.json' with { type: 'json' }
-import ja_JP from './ja-JP.json' with { type: 'json' }
-import ko_KR from './ko-KR.json' with { type: 'json' }
-import zh_CN from './zh-CN.json' with { type: 'json' }
-import zh_TW from './zh-TW.json' with { type: 'json' }
-export const languages = {
-    en: en_US,
-    ja: ja_JP,
-    ko: ko_KR,
-    'zh-CN': zh_CN,
-    zh: zh_TW,
-}
-// @ts-ignore
-import.meta.webpackHot?.accept(['./en-US.json', './ja-JP.json', './ko-KR.json', './zh-CN.json', './zh-TW.json'], () =>
-    globalThis.dispatchEvent?.(
-        new CustomEvent('MASK_I18N_HMR_LINGUI', {
-            detail: { en: en_US, ja: ja_JP, ko: ko_KR, 'zh-CN': zh_CN, zh: zh_TW },
-        }),
-    ),
-)
diff --git a/packages/plugins/MaskBox/src/locale/zh-CN.json b/packages/plugins/MaskBox/src/locale/zh-CN.json
deleted file mode 100644
index 3bedce9baade..000000000000
--- a/packages/plugins/MaskBox/src/locale/zh-CN.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "messages": {
-        "Xmf1TZ": [["boxStateMessage"], " (", ["0"], " ", ["1"], "/Time)"],
-        "F6pfE9": "启用",
-        "Tt5T6+": "文章",
-        "Vi2Pqx": "由",
-        "D87pha": "已关闭",
-        "URmyfc": "详情",
-        "2vTp2v": "抽取",
-        "rFkZD1": "抽取中",
-        "EexGwP": "I just claimed a #MaskBox with @realMaskNetwork. Install mask.io and create your own NFT mystery box!",
-        "znqB4T": "余额不足",
-        "ml4bvW": "上限:",
-        "0Lp4o6": "加载失败",
-        "WNjtSq": "Mask盲盒",
-        "r0A2o4": "Professional multi-chain decentralized platform for launching NFT blind boxes.",
-        "HpK/8d": "重新加载",
-        "WbEaq/": "卖出"
-    }
-}
diff --git a/packages/plugins/MaskBox/src/locale/zh-TW.json b/packages/plugins/MaskBox/src/locale/zh-TW.json
deleted file mode 100644
index 3bedce9baade..000000000000
--- a/packages/plugins/MaskBox/src/locale/zh-TW.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "messages": {
-        "Xmf1TZ": [["boxStateMessage"], " (", ["0"], " ", ["1"], "/Time)"],
-        "F6pfE9": "启用",
-        "Tt5T6+": "文章",
-        "Vi2Pqx": "由",
-        "D87pha": "已关闭",
-        "URmyfc": "详情",
-        "2vTp2v": "抽取",
-        "rFkZD1": "抽取中",
-        "EexGwP": "I just claimed a #MaskBox with @realMaskNetwork. Install mask.io and create your own NFT mystery box!",
-        "znqB4T": "余额不足",
-        "ml4bvW": "上限:",
-        "0Lp4o6": "加载失败",
-        "WNjtSq": "Mask盲盒",
-        "r0A2o4": "Professional multi-chain decentralized platform for launching NFT blind boxes.",
-        "HpK/8d": "重新加载",
-        "WbEaq/": "卖出"
-    }
-}
diff --git a/packages/plugins/MaskBox/src/messages.ts b/packages/plugins/MaskBox/src/messages.ts
deleted file mode 100644
index bd4e1151150c..000000000000
--- a/packages/plugins/MaskBox/src/messages.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import { getPluginRPC } from '@masknet/plugin-infra'
-import { PLUGIN_ID } from './constants.js'
-
-export const MaskBoxRPC = getPluginRPC<typeof import('./apis/index.js')>(PLUGIN_ID)
diff --git a/packages/plugins/MaskBox/src/register.ts b/packages/plugins/MaskBox/src/register.ts
deleted file mode 100644
index aa1f8a4cd9d5..000000000000
--- a/packages/plugins/MaskBox/src/register.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { registerPlugin } from '@masknet/plugin-infra'
-import { base } from './base.js'
-
-registerPlugin({
-    ...base,
-    SiteAdaptor: {
-        load: () => import('./SiteAdaptor/index.js'),
-        hotModuleReload: (hot) =>
-            import.meta.webpackHot?.accept('./SiteAdaptor', () => hot(import('./SiteAdaptor/index.js'))),
-    },
-    Worker: {
-        load: () => import('./Worker/index.js'),
-        hotModuleReload: (hot) => import.meta.webpackHot?.accept('./Worker', () => hot(import('./Worker/index.js'))),
-    },
-})
diff --git a/packages/plugins/MaskBox/src/type.ts b/packages/plugins/MaskBox/src/type.ts
deleted file mode 100644
index 983cb35ecdb7..000000000000
--- a/packages/plugins/MaskBox/src/type.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import type { FungibleToken } from '@masknet/web3-shared-base'
-import type { ChainId, SchemaType } from '@masknet/web3-shared-evm'
-
-export enum BoxState {
-    UNKNOWN = 0,
-    NOT_READY = 1,
-    READY = 2,
-    EXPIRED = 3,
-    /** sold all tokens out */
-    SOLD_OUT = 4,
-    /** drew all personal limited tokens */
-    DREW_OUT = 5,
-    /** canceled */
-    CANCELED = 6,
-    /** error occur */
-    ERROR = 7,
-    /** 404 */
-    NOT_FOUND = 8,
-    /** leaf not found */
-    NOT_IN_WHITELIST = 9,
-    /** insufficient holder token */
-    INSUFFICIENT_HOLDER_TOKEN = 10,
-    /** not qualified */
-    NOT_QUALIFIED = 11,
-}
-
-interface PaymentInfo {
-    token: FungibleToken<ChainId, SchemaType>
-    price: string
-    receivableAmount: string
-}
-
-export interface BoxInfo {
-    boxId: string
-    creator: string
-    name: string
-    sellAll: boolean
-    personalLimit: number
-    personalRemaining: number
-    payments: PaymentInfo[]
-    remaining: number
-    availableAmount: number
-    total: number
-    sold: number
-    startAt: Date
-    endAt: Date
-    started: boolean
-    tokenIds: string[]
-    tokenIdsPurchased: string[]
-    tokenAddress: string
-    heroImageURL: string
-    qualificationAddress: string
-    canceled: boolean
-    holderMinTokenAmount: string
-    holderTokenAddress: string
-}
-
-export enum MediaType {
-    Audio = 'audio',
-    Image = 'image',
-    Video = 'video',
-    Unknown = 'unknown',
-}
-
-export interface BoxMetadata {
-    id: string
-    name: string
-    mediaType: MediaType
-    mediaUrl: string
-    activities: Array<{
-        title: string
-        body: string
-    }>
-}
diff --git a/packages/plugins/MaskBox/tsconfig.json b/packages/plugins/MaskBox/tsconfig.json
deleted file mode 100644
index 5df655c29b15..000000000000
--- a/packages/plugins/MaskBox/tsconfig.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "extends": "../tsconfig.json",
-  "compilerOptions": {
-    "rootDir": "src",
-    "outDir": "dist",
-    "tsBuildInfoFile": "dist/.tsbuildinfo"
-  },
-  "include": ["src", "src/**/*.json"],
-  "references": [
-    { "path": "../../plugin-infra/tsconfig.json" },
-    { "path": "../../shared-base/tsconfig.json" },
-    { "path": "../../web3-hooks/evm/tsconfig.json" },
-    { "path": "../../shared/tsconfig.json" }
-  ]
-}
diff --git a/packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx b/packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx
index 36fe368fe406..ce34c95522a0 100644
--- a/packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx
+++ b/packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx
@@ -11,7 +11,7 @@ import { useChainContext, useFungibleTokenBalance, useNetworkContext, useWallet
 import { Lens } from '@masknet/web3-providers'
 import { FollowModuleType, type LensBaseAPI } from '@masknet/web3-providers/types'
 import { ZERO, formatBalance, isLessThan, isSameAddress } from '@masknet/web3-shared-base'
-import { ChainId, ProviderType, createERC20Token, formatAmount } from '@masknet/web3-shared-evm'
+import { ChainId, createERC20Token, formatAmount } from '@masknet/web3-shared-evm'
 import { Avatar, Box, Button, CircularProgress, DialogContent, Typography, buttonClasses } from '@mui/material'
 import { useQuery } from '@tanstack/react-query'
 import { first } from 'lodash-es'
@@ -250,7 +250,6 @@ export function FollowLensDialog({ handle, onClose }: Props) {
             !currentProfile ||
             !!wallet?.owner ||
             pluginID !== NetworkPluginID.PLUGIN_EVM ||
-            providerType === ProviderType.Fortmatic ||
             followLoading ||
             unfollowLoading ||
             profile?.followModule?.type === FollowModuleType.UnknownFollowModule ||
@@ -296,7 +295,7 @@ export function FollowLensDialog({ handle, onClose }: Props) {
     }, [isFollowing, isHovering, profile])
 
     const tips = useMemo(() => {
-        if (wallet?.owner || pluginID !== NetworkPluginID.PLUGIN_EVM || providerType === ProviderType.Fortmatic)
+        if (wallet?.owner || pluginID !== NetworkPluginID.PLUGIN_EVM)
             return <Trans>Current wallet does not support to interact with Lens protocol.</Trans>
         else if (profile?.followModule?.type === FollowModuleType.ProfileFollowModule && !defaultProfile)
             return <Trans>Only holding lens handle can follow.</Trans>
diff --git a/packages/plugins/tsconfig.json b/packages/plugins/tsconfig.json
index a14264f891dc..b4bc6516fde2 100644
--- a/packages/plugins/tsconfig.json
+++ b/packages/plugins/tsconfig.json
@@ -14,7 +14,6 @@
     { "path": "./Gitcoin/tsconfig.json" },
     { "path": "./GoPlusSecurity/tsconfig.json" },
     { "path": "./Handle/tsconfig.json" },
-    { "path": "./MaskBox/tsconfig.json" },
     { "path": "./NextID/tsconfig.json" },
     { "path": "./Pets/tsconfig.json" },
     { "path": "./ProfileCard/tsconfig.json" },
diff --git a/packages/shared-base/src/KVStorage/index.ts b/packages/shared-base/src/KVStorage/index.ts
index 9f4cb747894f..3bbd3ef675e2 100644
--- a/packages/shared-base/src/KVStorage/index.ts
+++ b/packages/shared-base/src/KVStorage/index.ts
@@ -67,7 +67,6 @@ export const PersistentStorages = {
             [PluginID.RedPacket]: false,
             [PluginID.FileService]: false,
             [PluginID.CrossChainBridge]: false,
-            [PluginID.MaskBox]: false,
             [PluginID.Savings]: false,
             [PluginID.Avatar]: false,
             [PluginID.Trader]: false,
diff --git a/packages/shared-base/src/types/PluginID.ts b/packages/shared-base/src/types/PluginID.ts
index 8c38aa5bccfc..de54ef339809 100644
--- a/packages/shared-base/src/types/PluginID.ts
+++ b/packages/shared-base/src/types/PluginID.ts
@@ -18,7 +18,6 @@ export enum PluginID {
     Handle = 'com.maskbook.handle',
     NextID = 'com.mask.next_id',
     Gitcoin = 'co.gitcoin',
-    MaskBox = 'com.maskbook.box',
     Trader = 'com.maskbook.trader',
     Tips = 'com.maskbook.tip',
     Transak = 'com.maskbook.transak',
diff --git a/packages/shared/src/UI/modals/SelectProviderModal/PluginProviderRender.tsx b/packages/shared/src/UI/modals/SelectProviderModal/PluginProviderRender.tsx
index c659ad6f0b57..402fbf41323e 100644
--- a/packages/shared/src/UI/modals/SelectProviderModal/PluginProviderRender.tsx
+++ b/packages/shared/src/UI/modals/SelectProviderModal/PluginProviderRender.tsx
@@ -1,34 +1,22 @@
-import { memo, useCallback, useMemo, useState } from 'react'
-import { useAsyncFn } from 'react-use'
-import {
-    alpha,
-    Box,
-    Dialog,
-    DialogContent,
-    DialogTitle,
-    IconButton,
-    List,
-    ListItem,
-    ListItemButton,
-    Typography,
-} from '@mui/material'
-import type { Web3Helper } from '@masknet/web3-helpers'
+import { Trans } from '@lingui/macro'
 import { getSiteType, NetworkPluginID } from '@masknet/shared-base'
+import { makeStyles, ShadowRootTooltip } from '@masknet/theme'
+import type { Web3Helper } from '@masknet/web3-helpers'
 import { getAllPluginsWeb3State, getConnection } from '@masknet/web3-providers'
-import { makeStyles, ShadowRootTooltip, usePortalShadowRoot } from '@masknet/theme'
 import { type NetworkDescriptor } from '@masknet/web3-shared-base'
 import { ChainId, NETWORK_DESCRIPTORS as EVM_NETWORK_DESCRIPTORS, ProviderType } from '@masknet/web3-shared-evm'
-import {
-    NETWORK_DESCRIPTORS as SOL_NETWORK_DESCRIPTORS,
-    ProviderType as SolProviderType,
-} from '@masknet/web3-shared-solana'
 import {
     NETWORK_DESCRIPTORS as FLOW_NETWORK_DESCRIPTORS,
     ProviderType as FlowProviderType,
 } from '@masknet/web3-shared-flow'
-import { DialogDismissIconUI, ImageIcon } from '@masknet/shared'
+import {
+    NETWORK_DESCRIPTORS as SOL_NETWORK_DESCRIPTORS,
+    ProviderType as SolProviderType,
+} from '@masknet/web3-shared-solana'
+import { Box, List, ListItem, Typography } from '@mui/material'
+import { memo, useCallback, useMemo } from 'react'
+import { useAsyncFn } from 'react-use'
 import { ProviderItem } from './ProviderItem.js'
-import { Trans } from '@lingui/macro'
 
 const descriptors: Record<
     NetworkPluginID,
@@ -88,49 +76,6 @@ const useStyles = makeStyles()((theme) => {
                 background: theme.palette.maskColor.bg,
             },
         },
-        dialogTitle: {
-            fontSize: 18,
-            fontWeight: 700,
-            color: theme.palette.maskColor.main,
-            textAlign: 'center',
-        },
-        dialogCloseButton: {
-            color: theme.palette.text.primary,
-            padding: 0,
-            width: 24,
-            height: 24,
-            '& > svg': {
-                fontSize: 24,
-            },
-        },
-        list: {
-            display: 'grid',
-            gridTemplateColumns: 'repeat(2, 1fr)',
-            gridGap: '12px 12px',
-        },
-        listItem: {
-            padding: theme.spacing(1.5),
-            display: 'flex',
-            flexDirection: 'column',
-            alignItems: 'center',
-            justifyContent: 'center',
-            rowGap: 12,
-            borderRadius: 12,
-        },
-        listItemText: {
-            fontSize: 12,
-            fontWeight: 700,
-            color: theme.palette.maskColor.main,
-        },
-        dialogPaper: {
-            margin: 0,
-            maxWidth: 400,
-            background: theme.palette.maskColor.bottom,
-            boxShadow:
-                theme.palette.mode === 'dark' ?
-                    '0px 0px 20px rgba(255, 255, 255, 0.12)'
-                :   '0px 0px 20px rgba(0, 0, 0, 0.05)',
-        },
     }
 })
 
@@ -150,16 +95,9 @@ export const PluginProviderRender = memo(function PluginProviderRender({
     requiredSupportPluginID,
 }: PluginProviderRenderProps) {
     const { classes, theme, cx } = useStyles()
-    const [selectChainDialogOpen, setSelectChainDialogOpen] = useState(false)
-
-    const fortmaticProviderDescriptor = providers.find((x) => x.type === ProviderType.Fortmatic)
 
     const [, handleClick] = useAsyncFn(
         async (provider: Web3Helper.ProviderDescriptorAll, expectedChainId?: Web3Helper.ChainIdAll) => {
-            if (provider.type === ProviderType.Fortmatic && !expectedChainId) {
-                setSelectChainDialogOpen(true)
-                return
-            }
             const target = getAllPluginsWeb3State()[provider.providerAdaptorPluginID]
             // note: unsafe cast, we cannot ensure provider.type is the isReady implementation we intended to call
             const isReady = target?.Provider?.isReady(provider.type as any as never)
@@ -189,8 +127,6 @@ export const PluginProviderRender = memo(function PluginProviderRender({
             return <Trans>Phantom only supports the Solana chain.</Trans>
         } else if (provider === FlowProviderType.Blocto) {
             return <Trans>Blocto only supports the Flow chain.</Trans>
-        } else if (provider === ProviderType.Fortmatic) {
-            return <Trans>Fortmatic only supports the ETH and BNB chain.</Trans>
         }
 
         return <Trans>Only supports EVM chains, ETH, BNB chain, Polygon, Arb, Op, etc.</Trans>
@@ -235,128 +171,80 @@ export const PluginProviderRender = memo(function PluginProviderRender({
         return [availableProviders, unavailableProviders]
     }, [orderedProviders])
     return (
-        <>
-            <Box className={classes.root}>
-                <section className={classes.section}>
-                    <List className={classes.wallets}>
-                        {availableProviders.map((provider) => (
-                            <ShadowRootTooltip
-                                title={getDisabled(provider) ? '' : getTips(provider.type)}
-                                arrow
-                                placement="top"
-                                disableInteractive
-                                key={provider.ID}>
-                                <ListItem
-                                    className={cx(
-                                        classes.walletItem,
-                                        getDisabled(provider) ? classes.disabledWalletItem : '',
-                                    )}
-                                    disabled={getDisabled(provider)}
-                                    onClick={() => {
-                                        if (provider.type === ProviderType.WalletConnect) {
-                                            handleClick(provider, ChainId.Mainnet)
-                                        } else {
-                                            handleClick(provider)
-                                        }
-                                    }}>
-                                    <ProviderItem
-                                        className={classes.providerIcon}
-                                        icon={provider.icon}
-                                        name={provider.name}
-                                        iconFilterColor={provider.iconFilterColor}
-                                    />
-                                </ListItem>
-                            </ShadowRootTooltip>
-                        ))}
-                    </List>
-                </section>
-                {unavailableProviders.length ?
-                    <>
-                        <Typography mt={2} color={theme.palette.maskColor.second} fontSize={14}>
-                            <Trans>The following wallets are not installed or in conflict with others</Trans>
-                        </Typography>
-                        <section className={classes.section}>
-                            <List className={classes.wallets}>
-                                {unavailableProviders.map((provider) => (
-                                    <ShadowRootTooltip
-                                        title={getDisabled(provider) ? '' : getTips(provider.type)}
-                                        arrow
-                                        placement="top"
-                                        disableInteractive
-                                        key={provider.ID}>
-                                        <ListItem
-                                            className={cx(
-                                                classes.walletItem,
-                                                getDisabled(provider) ? classes.disabledWalletItem : '',
-                                            )}
-                                            disabled={getDisabled(provider)}
-                                            onClick={() => {
-                                                if (provider.type === ProviderType.WalletConnect) {
-                                                    handleClick(provider, ChainId.Mainnet)
-                                                } else {
-                                                    handleClick(provider)
-                                                }
-                                            }}>
-                                            <ProviderItem
-                                                className={classes.providerIcon}
-                                                icon={provider.icon}
-                                                name={provider.name}
-                                                iconFilterColor={provider.iconFilterColor}
-                                            />
-                                        </ListItem>
-                                    </ShadowRootTooltip>
-                                ))}
-                            </List>
-                        </section>
-                    </>
-                :   null}
-            </Box>
-            {usePortalShadowRoot((container) => (
-                <Dialog
-                    container={container}
-                    open={selectChainDialogOpen}
-                    classes={{ paper: classes.dialogPaper }}
-                    onClose={() => setSelectChainDialogOpen(false)}>
-                    <DialogTitle
-                        sx={{
-                            whiteSpace: 'nowrap',
-                            display: 'grid',
-                            alignItems: 'center',
-                            gridTemplateColumns: '50px auto 50px',
-                        }}>
-                        <IconButton
-                            className={classes.dialogCloseButton}
-                            onClick={() => setSelectChainDialogOpen(false)}>
-                            <DialogDismissIconUI />
-                        </IconButton>
-                        <Typography className={classes.dialogTitle}>
-                            <Trans>Choose Network</Trans>
-                        </Typography>
-                    </DialogTitle>
-                    <DialogContent sx={{ minWidth: 352 }}>
-                        <List className={classes.list}>
-                            {EVM_NETWORK_DESCRIPTORS.filter((x) =>
-                                [ChainId.Mainnet, ChainId.BSC].includes(x.chainId),
-                            ).map((x) => (
-                                <ListItemButton
-                                    key={x.chainId}
-                                    className={classes.listItem}
-                                    onClick={() => {
-                                        if (!fortmaticProviderDescriptor) return
-                                        handleClick(fortmaticProviderDescriptor, x.chainId)
-                                    }}>
-                                    <ImageIcon
-                                        icon={x.icon}
-                                        size={30}
-                                        iconFilterColor={x.iconColor ? alpha(x.iconColor, 0.2) : undefined}
-                                    />
-                                    <Typography className={classes.listItemText}>{x.name}</Typography>
-                                </ListItemButton>
+        <Box className={classes.root}>
+            <section className={classes.section}>
+                <List className={classes.wallets}>
+                    {availableProviders.map((provider) => (
+                        <ShadowRootTooltip
+                            title={getDisabled(provider) ? '' : getTips(provider.type)}
+                            arrow
+                            placement="top"
+                            disableInteractive
+                            key={provider.ID}>
+                            <ListItem
+                                className={cx(
+                                    classes.walletItem,
+                                    getDisabled(provider) ? classes.disabledWalletItem : '',
+                                )}
+                                disabled={getDisabled(provider)}
+                                onClick={() => {
+                                    if (provider.type === ProviderType.WalletConnect) {
+                                        handleClick(provider, ChainId.Mainnet)
+                                    } else {
+                                        handleClick(provider)
+                                    }
+                                }}>
+                                <ProviderItem
+                                    className={classes.providerIcon}
+                                    icon={provider.icon}
+                                    name={provider.name}
+                                    iconFilterColor={provider.iconFilterColor}
+                                />
+                            </ListItem>
+                        </ShadowRootTooltip>
+                    ))}
+                </List>
+            </section>
+            {unavailableProviders.length ?
+                <>
+                    <Typography mt={2} color={theme.palette.maskColor.second} fontSize={14}>
+                        <Trans>The following wallets are not installed or in conflict with others</Trans>
+                    </Typography>
+                    <section className={classes.section}>
+                        <List className={classes.wallets}>
+                            {unavailableProviders.map((provider) => (
+                                <ShadowRootTooltip
+                                    title={getDisabled(provider) ? '' : getTips(provider.type)}
+                                    arrow
+                                    placement="top"
+                                    disableInteractive
+                                    key={provider.ID}>
+                                    <ListItem
+                                        className={cx(
+                                            classes.walletItem,
+                                            getDisabled(provider) ? classes.disabledWalletItem : '',
+                                        )}
+                                        disabled={getDisabled(provider)}
+                                        onClick={() => {
+                                            if (provider.type === ProviderType.WalletConnect) {
+                                                handleClick(provider, ChainId.Mainnet)
+                                            } else {
+                                                handleClick(provider)
+                                            }
+                                        }}>
+                                        <ProviderItem
+                                            className={classes.providerIcon}
+                                            icon={provider.icon}
+                                            name={provider.name}
+                                            iconFilterColor={provider.iconFilterColor}
+                                        />
+                                    </ListItem>
+                                </ShadowRootTooltip>
                             ))}
                         </List>
-                    </DialogContent>
-                </Dialog>
-            ))}
-        </>
+                    </section>
+                </>
+            :   null}
+        </Box>
     )
 })
diff --git a/packages/shared/src/UI/translate.ts b/packages/shared/src/UI/translate.ts
index 1846f62f6a50..58ee2a14fe11 100644
--- a/packages/shared/src/UI/translate.ts
+++ b/packages/shared/src/UI/translate.ts
@@ -34,7 +34,6 @@ const map: Record<
     'Failed to claim Lucky Drop.': msg`Failed to claim Lucky Drop.`,
     'Failed to create Lucky Drop.': msg`Failed to create Lucky Drop.`,
     'Failed to deposit token.': msg`Failed to deposit token.`,
-    'Failed to purchase Maskbox NFT.': msg`Failed to purchase Maskbox NFT.`,
     'Failed to refund Lucky Drop.': msg`Failed to refund Lucky Drop.`,
     'Failed to revoke token contract.': msg`Failed to revoke token contract.`,
     'Failed to send token.': msg`Failed to send token.`,
@@ -43,11 +42,9 @@ const map: Record<
     'Failed to unlock token contract.': msg`Failed to unlock token contract.`,
     'Lucky Drop claimed.': msg`Lucky Drop claimed.`,
     'Lucky Drop refunded.': msg`Lucky Drop refunded.`,
-    'Maskbox NFT purchased.': msg`Maskbox NFT purchased.`,
     'NFT Lucky Drop claimed.': msg`NFT Lucky Drop claimed.`,
     'NFT Lucky Drop created.': msg`NFT Lucky Drop created.`,
     'Owner changed.': msg`Owner changed.`,
-    'Purchase Maskbox NFT.': msg`Purchase Maskbox NFT.`,
     'Refund your expired Lucky Drop.': msg`Refund your expired Lucky Drop.`,
     'Revoke the approval for token': msg`Revoke the approval for token`,
     'The token approval revoked.': msg`The token approval revoked.`,
@@ -70,7 +67,6 @@ const map: Record<
     'Deploy Smarty Pay wallet': msg`Deploy Smarty Pay wallet`,
     'Deposit token': msg`Deposit token`,
     'Follow User': msg`Follow User`,
-    'Purchase Maskbox NFT': msg`Purchase Maskbox NFT`,
     'Refund Lucky drop': msg`Refund Lucky drop`,
     'Revoke Token': msg`Revoke Token`,
     'Transfer NFT': msg`Transfer NFT`,
@@ -114,8 +110,6 @@ export function useFormatMessage() {
                     return _(msg`${message.symbol} NFT Lucky Drop created.`)
                 case '{token} deposited.':
                     return _(msg`${message.token} deposited.`)
-                case 'Maskbox NFT with {token} purchased.':
-                    return _(msg`Maskbox NFT with ${message.token} purchased.`)
                 case 'Lucky Drop with {token} refunded.':
                     return _(msg`Lucky Drop with ${message.token} refunded.`)
                 case '{token} sent.':
diff --git a/packages/shared/src/locale/en-US.po b/packages/shared/src/locale/en-US.po
index db7cac975a9c..5bd74b5f9a32 100644
--- a/packages/shared/src/locale/en-US.po
+++ b/packages/shared/src/locale/en-US.po
@@ -229,8 +229,8 @@ msgid "Check out the official website"
 msgstr ""
 
 #: src/UI/modals/SelectProviderModal/PluginProviderRender.tsx
-msgid "Choose Network"
-msgstr ""
+#~ msgid "Choose Network"
+#~ msgstr ""
 
 #: src/UI/components/FungibleCoinMarketTable/index.tsx
 #: src/UI/components/FungibleCoinMarketTable/index.tsx
@@ -590,8 +590,8 @@ msgid "Failed to load MASK. Click to retry."
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Failed to purchase Maskbox NFT."
-msgstr ""
+#~ msgid "Failed to purchase Maskbox NFT."
+#~ msgstr ""
 
 #: src/UI/translate.ts
 msgid "Failed to refund Lucky Drop."
@@ -646,8 +646,8 @@ msgid "Following"
 msgstr ""
 
 #: src/UI/modals/SelectProviderModal/PluginProviderRender.tsx
-msgid "Fortmatic only supports the ETH and BNB chain."
-msgstr ""
+#~ msgid "Fortmatic only supports the ETH and BNB chain."
+#~ msgstr ""
 
 #: src/UI/components/SelectGasSettingsToolbar/index.tsx
 msgid "Gas Fee"
@@ -805,12 +805,12 @@ msgid "Mask Network requires the permission of following websites before using i
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Maskbox NFT purchased."
-msgstr ""
+#~ msgid "Maskbox NFT purchased."
+#~ msgstr ""
 
 #: src/UI/translate.ts
-msgid "Maskbox NFT with {0} purchased."
-msgstr ""
+#~ msgid "Maskbox NFT with {0} purchased."
+#~ msgstr ""
 
 #: src/UI/modals/GasSettingModal/GasSetting1559.tsx
 msgid "Max fee"
@@ -1033,12 +1033,12 @@ msgid "Provided by plugin \"{0}\""
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Purchase Maskbox NFT"
-msgstr ""
+#~ msgid "Purchase Maskbox NFT"
+#~ msgstr ""
 
 #: src/UI/translate.ts
-msgid "Purchase Maskbox NFT."
-msgstr ""
+#~ msgid "Purchase Maskbox NFT."
+#~ msgstr ""
 
 #: src/UI/translate.ts
 msgid "Refund Lucky drop"
diff --git a/packages/shared/src/locale/ja-JP.po b/packages/shared/src/locale/ja-JP.po
index 98a038e4f8c6..6451170e47ac 100644
--- a/packages/shared/src/locale/ja-JP.po
+++ b/packages/shared/src/locale/ja-JP.po
@@ -229,8 +229,8 @@ msgid "Check out the official website"
 msgstr "公式サイトをチェックする"
 
 #: src/UI/modals/SelectProviderModal/PluginProviderRender.tsx
-msgid "Choose Network"
-msgstr "ネットワークを選択"
+#~ msgid "Choose Network"
+#~ msgstr "ネットワークを選択"
 
 #: src/UI/components/FungibleCoinMarketTable/index.tsx
 #: src/UI/components/FungibleCoinMarketTable/index.tsx
@@ -590,8 +590,8 @@ msgid "Failed to load MASK. Click to retry."
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Failed to purchase Maskbox NFT."
-msgstr ""
+#~ msgid "Failed to purchase Maskbox NFT."
+#~ msgstr ""
 
 #: src/UI/translate.ts
 msgid "Failed to refund Lucky Drop."
@@ -646,8 +646,8 @@ msgid "Following"
 msgstr "フォロー中"
 
 #: src/UI/modals/SelectProviderModal/PluginProviderRender.tsx
-msgid "Fortmatic only supports the ETH and BNB chain."
-msgstr "FortmaticはETHとBNBチェーンのみを対応しています。"
+#~ msgid "Fortmatic only supports the ETH and BNB chain."
+#~ msgstr "FortmaticはETHとBNBチェーンのみを対応しています。"
 
 #: src/UI/components/SelectGasSettingsToolbar/index.tsx
 msgid "Gas Fee"
@@ -805,12 +805,12 @@ msgid "Mask Network requires the permission of following websites before using i
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Maskbox NFT purchased."
-msgstr ""
+#~ msgid "Maskbox NFT purchased."
+#~ msgstr ""
 
 #: src/UI/translate.ts
-msgid "Maskbox NFT with {0} purchased."
-msgstr ""
+#~ msgid "Maskbox NFT with {0} purchased."
+#~ msgstr ""
 
 #: src/UI/modals/GasSettingModal/GasSetting1559.tsx
 msgid "Max fee"
@@ -1033,12 +1033,12 @@ msgid "Provided by plugin \"{0}\""
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Purchase Maskbox NFT"
-msgstr ""
+#~ msgid "Purchase Maskbox NFT"
+#~ msgstr ""
 
 #: src/UI/translate.ts
-msgid "Purchase Maskbox NFT."
-msgstr ""
+#~ msgid "Purchase Maskbox NFT."
+#~ msgstr ""
 
 #: src/UI/translate.ts
 msgid "Refund Lucky drop"
diff --git a/packages/shared/src/locale/ko-KR.po b/packages/shared/src/locale/ko-KR.po
index 2f240d0fa7ae..896577ac19a5 100644
--- a/packages/shared/src/locale/ko-KR.po
+++ b/packages/shared/src/locale/ko-KR.po
@@ -229,8 +229,8 @@ msgid "Check out the official website"
 msgstr ""
 
 #: src/UI/modals/SelectProviderModal/PluginProviderRender.tsx
-msgid "Choose Network"
-msgstr "네트워크 선택"
+#~ msgid "Choose Network"
+#~ msgstr "네트워크 선택"
 
 #: src/UI/components/FungibleCoinMarketTable/index.tsx
 #: src/UI/components/FungibleCoinMarketTable/index.tsx
@@ -590,8 +590,8 @@ msgid "Failed to load MASK. Click to retry."
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Failed to purchase Maskbox NFT."
-msgstr ""
+#~ msgid "Failed to purchase Maskbox NFT."
+#~ msgstr ""
 
 #: src/UI/translate.ts
 msgid "Failed to refund Lucky Drop."
@@ -646,8 +646,8 @@ msgid "Following"
 msgstr "팔로잉"
 
 #: src/UI/modals/SelectProviderModal/PluginProviderRender.tsx
-msgid "Fortmatic only supports the ETH and BNB chain."
-msgstr "Fortmatic는 ETH 및 BNB에만 지원합니다."
+#~ msgid "Fortmatic only supports the ETH and BNB chain."
+#~ msgstr "Fortmatic는 ETH 및 BNB에만 지원합니다."
 
 #: src/UI/components/SelectGasSettingsToolbar/index.tsx
 msgid "Gas Fee"
@@ -805,12 +805,12 @@ msgid "Mask Network requires the permission of following websites before using i
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Maskbox NFT purchased."
-msgstr ""
+#~ msgid "Maskbox NFT purchased."
+#~ msgstr ""
 
 #: src/UI/translate.ts
-msgid "Maskbox NFT with {0} purchased."
-msgstr ""
+#~ msgid "Maskbox NFT with {0} purchased."
+#~ msgstr ""
 
 #: src/UI/modals/GasSettingModal/GasSetting1559.tsx
 msgid "Max fee"
@@ -1033,12 +1033,12 @@ msgid "Provided by plugin \"{0}\""
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Purchase Maskbox NFT"
-msgstr ""
+#~ msgid "Purchase Maskbox NFT"
+#~ msgstr ""
 
 #: src/UI/translate.ts
-msgid "Purchase Maskbox NFT."
-msgstr ""
+#~ msgid "Purchase Maskbox NFT."
+#~ msgstr ""
 
 #: src/UI/translate.ts
 msgid "Refund Lucky drop"
diff --git a/packages/shared/src/locale/zh-CN.po b/packages/shared/src/locale/zh-CN.po
index 8cdac84de631..9a0743debe53 100644
--- a/packages/shared/src/locale/zh-CN.po
+++ b/packages/shared/src/locale/zh-CN.po
@@ -229,8 +229,8 @@ msgid "Check out the official website"
 msgstr ""
 
 #: src/UI/modals/SelectProviderModal/PluginProviderRender.tsx
-msgid "Choose Network"
-msgstr "选择网络"
+#~ msgid "Choose Network"
+#~ msgstr "选择网络"
 
 #: src/UI/components/FungibleCoinMarketTable/index.tsx
 #: src/UI/components/FungibleCoinMarketTable/index.tsx
@@ -590,8 +590,8 @@ msgid "Failed to load MASK. Click to retry."
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Failed to purchase Maskbox NFT."
-msgstr ""
+#~ msgid "Failed to purchase Maskbox NFT."
+#~ msgstr ""
 
 #: src/UI/translate.ts
 msgid "Failed to refund Lucky Drop."
@@ -646,8 +646,8 @@ msgid "Following"
 msgstr "已关注"
 
 #: src/UI/modals/SelectProviderModal/PluginProviderRender.tsx
-msgid "Fortmatic only supports the ETH and BNB chain."
-msgstr "Formatic 仅支持 ETH 和 BNB 链。"
+#~ msgid "Fortmatic only supports the ETH and BNB chain."
+#~ msgstr "Formatic 仅支持 ETH 和 BNB 链。"
 
 #: src/UI/components/SelectGasSettingsToolbar/index.tsx
 msgid "Gas Fee"
@@ -805,12 +805,12 @@ msgid "Mask Network requires the permission of following websites before using i
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Maskbox NFT purchased."
-msgstr ""
+#~ msgid "Maskbox NFT purchased."
+#~ msgstr ""
 
 #: src/UI/translate.ts
-msgid "Maskbox NFT with {0} purchased."
-msgstr ""
+#~ msgid "Maskbox NFT with {0} purchased."
+#~ msgstr ""
 
 #: src/UI/modals/GasSettingModal/GasSetting1559.tsx
 msgid "Max fee"
@@ -1033,12 +1033,12 @@ msgid "Provided by plugin \"{0}\""
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Purchase Maskbox NFT"
-msgstr ""
+#~ msgid "Purchase Maskbox NFT"
+#~ msgstr ""
 
 #: src/UI/translate.ts
-msgid "Purchase Maskbox NFT."
-msgstr ""
+#~ msgid "Purchase Maskbox NFT."
+#~ msgstr ""
 
 #: src/UI/translate.ts
 msgid "Refund Lucky drop"
diff --git a/packages/shared/src/locale/zh-TW.po b/packages/shared/src/locale/zh-TW.po
index 2e177050e3da..930831b5a8e7 100644
--- a/packages/shared/src/locale/zh-TW.po
+++ b/packages/shared/src/locale/zh-TW.po
@@ -229,8 +229,8 @@ msgid "Check out the official website"
 msgstr ""
 
 #: src/UI/modals/SelectProviderModal/PluginProviderRender.tsx
-msgid "Choose Network"
-msgstr ""
+#~ msgid "Choose Network"
+#~ msgstr ""
 
 #: src/UI/components/FungibleCoinMarketTable/index.tsx
 #: src/UI/components/FungibleCoinMarketTable/index.tsx
@@ -590,8 +590,8 @@ msgid "Failed to load MASK. Click to retry."
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Failed to purchase Maskbox NFT."
-msgstr ""
+#~ msgid "Failed to purchase Maskbox NFT."
+#~ msgstr ""
 
 #: src/UI/translate.ts
 msgid "Failed to refund Lucky Drop."
@@ -646,8 +646,8 @@ msgid "Following"
 msgstr ""
 
 #: src/UI/modals/SelectProviderModal/PluginProviderRender.tsx
-msgid "Fortmatic only supports the ETH and BNB chain."
-msgstr ""
+#~ msgid "Fortmatic only supports the ETH and BNB chain."
+#~ msgstr ""
 
 #: src/UI/components/SelectGasSettingsToolbar/index.tsx
 msgid "Gas Fee"
@@ -805,12 +805,12 @@ msgid "Mask Network requires the permission of following websites before using i
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Maskbox NFT purchased."
-msgstr ""
+#~ msgid "Maskbox NFT purchased."
+#~ msgstr ""
 
 #: src/UI/translate.ts
-msgid "Maskbox NFT with {0} purchased."
-msgstr ""
+#~ msgid "Maskbox NFT with {0} purchased."
+#~ msgstr ""
 
 #: src/UI/modals/GasSettingModal/GasSetting1559.tsx
 msgid "Max fee"
@@ -1033,12 +1033,12 @@ msgid "Provided by plugin \"{0}\""
 msgstr ""
 
 #: src/UI/translate.ts
-msgid "Purchase Maskbox NFT"
-msgstr ""
+#~ msgid "Purchase Maskbox NFT"
+#~ msgstr ""
 
 #: src/UI/translate.ts
-msgid "Purchase Maskbox NFT."
-msgstr ""
+#~ msgid "Purchase Maskbox NFT."
+#~ msgstr ""
 
 #: src/UI/translate.ts
 msgid "Refund Lucky drop"
diff --git a/packages/web3-contracts/abis/MaskBox.json b/packages/web3-contracts/abis/MaskBox.json
deleted file mode 100644
index f70d7f424344..000000000000
--- a/packages/web3-contracts/abis/MaskBox.json
+++ /dev/null
@@ -1,625 +0,0 @@
-[
-    {
-        "anonymous": false,
-        "inputs": [
-            {
-                "indexed": true,
-                "internalType": "uint256",
-                "name": "box_id",
-                "type": "uint256"
-            },
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "creator",
-                "type": "address"
-            }
-        ],
-        "name": "CancelSuccess",
-        "type": "event"
-    },
-    {
-        "anonymous": false,
-        "inputs": [
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "creator",
-                "type": "address"
-            },
-            {
-                "indexed": true,
-                "internalType": "uint256",
-                "name": "box_id",
-                "type": "uint256"
-            },
-            {
-                "indexed": false,
-                "internalType": "address",
-                "name": "token_address",
-                "type": "address"
-            },
-            {
-                "indexed": false,
-                "internalType": "uint256",
-                "name": "amount",
-                "type": "uint256"
-            },
-            {
-                "indexed": false,
-                "internalType": "uint256",
-                "name": "timestamp",
-                "type": "uint256"
-            }
-        ],
-        "name": "ClaimPayment",
-        "type": "event"
-    },
-    {
-        "anonymous": false,
-        "inputs": [
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "creator",
-                "type": "address"
-            },
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "nft_address",
-                "type": "address"
-            },
-            {
-                "indexed": false,
-                "internalType": "uint256",
-                "name": "box_id",
-                "type": "uint256"
-            },
-            {
-                "indexed": false,
-                "internalType": "string",
-                "name": "name",
-                "type": "string"
-            },
-            {
-                "indexed": false,
-                "internalType": "uint32",
-                "name": "start_time",
-                "type": "uint32"
-            },
-            {
-                "indexed": false,
-                "internalType": "uint32",
-                "name": "end_time",
-                "type": "uint32"
-            },
-            {
-                "indexed": false,
-                "internalType": "bool",
-                "name": "sell_all",
-                "type": "bool"
-            }
-        ],
-        "name": "CreationSuccess",
-        "type": "event"
-    },
-    {
-        "anonymous": false,
-        "inputs": [
-            {
-                "indexed": true,
-                "internalType": "uint256",
-                "name": "box_id",
-                "type": "uint256"
-            },
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "customer",
-                "type": "address"
-            },
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "nft_address",
-                "type": "address"
-            },
-            {
-                "indexed": false,
-                "internalType": "uint256",
-                "name": "amount",
-                "type": "uint256"
-            }
-        ],
-        "name": "OpenSuccess",
-        "type": "event"
-    },
-    {
-        "anonymous": false,
-        "inputs": [
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "previousOwner",
-                "type": "address"
-            },
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "newOwner",
-                "type": "address"
-            }
-        ],
-        "name": "OwnershipTransferred",
-        "type": "event"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address[]",
-                "name": "addrs",
-                "type": "address[]"
-            }
-        ],
-        "name": "addAdmin",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "box_id",
-                "type": "uint256"
-            },
-            {
-                "internalType": "uint256[]",
-                "name": "nft_id_list",
-                "type": "uint256[]"
-            }
-        ],
-        "name": "addNftIntoBox",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address[]",
-                "name": "addrs",
-                "type": "address[]"
-            }
-        ],
-        "name": "addWhitelist",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "",
-                "type": "address"
-            }
-        ],
-        "name": "admin",
-        "outputs": [
-            {
-                "internalType": "bool",
-                "name": "",
-                "type": "bool"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "box_id",
-                "type": "uint256"
-            }
-        ],
-        "name": "cancelBox",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256[]",
-                "name": "box_ids",
-                "type": "uint256[]"
-            }
-        ],
-        "name": "claimPayment",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "nft_address",
-                "type": "address"
-            },
-            {
-                "internalType": "string",
-                "name": "name",
-                "type": "string"
-            },
-            {
-                "components": [
-                    {
-                        "internalType": "address",
-                        "name": "token_addr",
-                        "type": "address"
-                    },
-                    {
-                        "internalType": "uint256",
-                        "name": "price",
-                        "type": "uint256"
-                    }
-                ],
-                "internalType": "struct MysteryBox.PaymentOption[]",
-                "name": "payment",
-                "type": "tuple[]"
-            },
-            {
-                "internalType": "uint32",
-                "name": "personal_limit",
-                "type": "uint32"
-            },
-            {
-                "internalType": "uint32",
-                "name": "start_time",
-                "type": "uint32"
-            },
-            {
-                "internalType": "uint32",
-                "name": "end_time",
-                "type": "uint32"
-            },
-            {
-                "internalType": "bool",
-                "name": "sell_all",
-                "type": "bool"
-            },
-            {
-                "internalType": "uint256[]",
-                "name": "nft_id_list",
-                "type": "uint256[]"
-            },
-            {
-                "internalType": "address",
-                "name": "qualification",
-                "type": "address"
-            },
-            {
-                "internalType": "address",
-                "name": "holder_token_addr",
-                "type": "address"
-            },
-            {
-                "internalType": "uint256",
-                "name": "holder_min_token_amount",
-                "type": "uint256"
-            },
-            {
-                "internalType": "bytes32",
-                "name": "qualification_data",
-                "type": "bytes32"
-            }
-        ],
-        "name": "createBox",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "box_id",
-                "type": "uint256"
-            }
-        ],
-        "name": "getBoxInfo",
-        "outputs": [
-            {
-                "internalType": "address",
-                "name": "creator",
-                "type": "address"
-            },
-            {
-                "internalType": "address",
-                "name": "nft_address",
-                "type": "address"
-            },
-            {
-                "internalType": "string",
-                "name": "name",
-                "type": "string"
-            },
-            {
-                "internalType": "uint32",
-                "name": "personal_limit",
-                "type": "uint32"
-            },
-            {
-                "internalType": "address",
-                "name": "qualification",
-                "type": "address"
-            },
-            {
-                "internalType": "address",
-                "name": "holder_token_addr",
-                "type": "address"
-            },
-            {
-                "internalType": "uint256",
-                "name": "holder_min_token_amount",
-                "type": "uint256"
-            },
-            {
-                "internalType": "bytes32",
-                "name": "qualification_data",
-                "type": "bytes32"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "box_id",
-                "type": "uint256"
-            }
-        ],
-        "name": "getBoxStatus",
-        "outputs": [
-            {
-                "components": [
-                    {
-                        "internalType": "address",
-                        "name": "token_addr",
-                        "type": "address"
-                    },
-                    {
-                        "internalType": "uint256",
-                        "name": "price",
-                        "type": "uint256"
-                    },
-                    {
-                        "internalType": "uint256",
-                        "name": "receivable_amount",
-                        "type": "uint256"
-                    }
-                ],
-                "internalType": "struct MysteryBox.PaymentInfo[]",
-                "name": "payment",
-                "type": "tuple[]"
-            },
-            {
-                "internalType": "bool",
-                "name": "started",
-                "type": "bool"
-            },
-            {
-                "internalType": "bool",
-                "name": "expired",
-                "type": "bool"
-            },
-            {
-                "internalType": "bool",
-                "name": "canceled",
-                "type": "bool"
-            },
-            {
-                "internalType": "uint256",
-                "name": "remaining",
-                "type": "uint256"
-            },
-            {
-                "internalType": "uint256",
-                "name": "total",
-                "type": "uint256"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "box_id",
-                "type": "uint256"
-            },
-            {
-                "internalType": "uint256",
-                "name": "cursor",
-                "type": "uint256"
-            },
-            {
-                "internalType": "uint256",
-                "name": "amount",
-                "type": "uint256"
-            }
-        ],
-        "name": "getNftListForSale",
-        "outputs": [
-            {
-                "internalType": "uint256[]",
-                "name": "nft_id_list",
-                "type": "uint256[]"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "box_id",
-                "type": "uint256"
-            },
-            {
-                "internalType": "address",
-                "name": "customer",
-                "type": "address"
-            }
-        ],
-        "name": "getPurchasedNft",
-        "outputs": [
-            {
-                "internalType": "uint256[]",
-                "name": "nft_id_list",
-                "type": "uint256[]"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [],
-        "name": "initialize",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "box_id",
-                "type": "uint256"
-            },
-            {
-                "internalType": "uint8",
-                "name": "amount",
-                "type": "uint8"
-            },
-            {
-                "internalType": "uint8",
-                "name": "payment_token_index",
-                "type": "uint8"
-            },
-            {
-                "internalType": "bytes",
-                "name": "proof",
-                "type": "bytes"
-            }
-        ],
-        "name": "openBox",
-        "outputs": [],
-        "stateMutability": "payable",
-        "type": "function"
-    },
-    {
-        "inputs": [],
-        "name": "owner",
-        "outputs": [
-            {
-                "internalType": "address",
-                "name": "",
-                "type": "address"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address[]",
-                "name": "addrs",
-                "type": "address[]"
-            }
-        ],
-        "name": "removeAdmin",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address[]",
-                "name": "addrs",
-                "type": "address[]"
-            }
-        ],
-        "name": "removeWhitelist",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [],
-        "name": "renounceOwnership",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "box_id",
-                "type": "uint256"
-            },
-            {
-                "internalType": "bytes32",
-                "name": "qualification_data",
-                "type": "bytes32"
-            }
-        ],
-        "name": "setQualificationData",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "newOwner",
-                "type": "address"
-            }
-        ],
-        "name": "transferOwnership",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "",
-                "type": "address"
-            }
-        ],
-        "name": "whitelist",
-        "outputs": [
-            {
-                "internalType": "bool",
-                "name": "",
-                "type": "bool"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    }
-]
diff --git a/packages/web3-contracts/abis/MaskBoxQualification.json b/packages/web3-contracts/abis/MaskBoxQualification.json
deleted file mode 100644
index c63ad4479e30..000000000000
--- a/packages/web3-contracts/abis/MaskBoxQualification.json
+++ /dev/null
@@ -1,23 +0,0 @@
-[
-    { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" },
-    {
-        "inputs": [
-            { "internalType": "address", "name": "account", "type": "address" },
-            { "internalType": "bytes", "name": "proof", "type": "bytes" }
-        ],
-        "name": "is_qualified",
-        "outputs": [
-            { "internalType": "bool", "name": "qualified", "type": "bool" },
-            { "internalType": "string", "name": "error_msg", "type": "string" }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [],
-        "name": "version",
-        "outputs": [{ "internalType": "uint32", "name": "", "type": "uint32" }],
-        "stateMutability": "view",
-        "type": "function"
-    }
-]
diff --git a/packages/web3-contracts/types/MaskBox.d.ts b/packages/web3-contracts/types/MaskBox.d.ts
deleted file mode 100644
index 298ad7439a61..000000000000
--- a/packages/web3-contracts/types/MaskBox.d.ts
+++ /dev/null
@@ -1,210 +0,0 @@
-/* Autogenerated file. Do not edit manually. */
-/* tslint:disable */
-/* eslint-disable */
-
-import type BN from 'bn.js'
-import type { ContractOptions } from 'web3-eth-contract'
-import type { EventLog } from 'web3-core'
-import type { EventEmitter } from 'events'
-import type {
-    Callback,
-    PayableTransactionObject,
-    NonPayableTransactionObject,
-    BlockType,
-    ContractEventLog,
-    BaseContract,
-} from './types.js'
-
-export interface EventOptions {
-    filter?: object
-    fromBlock?: BlockType
-    topics?: string[]
-}
-
-export type CancelSuccess = ContractEventLog<{
-    box_id: string
-    creator: string
-    0: string
-    1: string
-}>
-export type ClaimPayment = ContractEventLog<{
-    creator: string
-    box_id: string
-    token_address: string
-    amount: string
-    timestamp: string
-    0: string
-    1: string
-    2: string
-    3: string
-    4: string
-}>
-export type CreationSuccess = ContractEventLog<{
-    creator: string
-    nft_address: string
-    box_id: string
-    name: string
-    start_time: string
-    end_time: string
-    sell_all: boolean
-    0: string
-    1: string
-    2: string
-    3: string
-    4: string
-    5: string
-    6: boolean
-}>
-export type OpenSuccess = ContractEventLog<{
-    box_id: string
-    customer: string
-    nft_address: string
-    amount: string
-    0: string
-    1: string
-    2: string
-    3: string
-}>
-export type OwnershipTransferred = ContractEventLog<{
-    previousOwner: string
-    newOwner: string
-    0: string
-    1: string
-}>
-
-export interface MaskBox extends BaseContract {
-    constructor(jsonInterface: any[], address?: string, options?: ContractOptions): MaskBox
-    clone(): MaskBox
-    methods: {
-        addAdmin(addrs: string[]): NonPayableTransactionObject<void>
-
-        addNftIntoBox(
-            box_id: number | string | BN,
-            nft_id_list: (number | string | BN)[],
-        ): NonPayableTransactionObject<void>
-
-        addWhitelist(addrs: string[]): NonPayableTransactionObject<void>
-
-        admin(arg0: string): NonPayableTransactionObject<boolean>
-
-        cancelBox(box_id: number | string | BN): NonPayableTransactionObject<void>
-
-        claimPayment(box_ids: (number | string | BN)[]): NonPayableTransactionObject<void>
-
-        createBox(
-            nft_address: string,
-            name: string,
-            payment: [string, number | string | BN][],
-            personal_limit: number | string | BN,
-            start_time: number | string | BN,
-            end_time: number | string | BN,
-            sell_all: boolean,
-            nft_id_list: (number | string | BN)[],
-            qualification: string,
-            holder_token_addr: string,
-            holder_min_token_amount: number | string | BN,
-            qualification_data: string | number[],
-        ): NonPayableTransactionObject<void>
-
-        getBoxInfo(box_id: number | string | BN): NonPayableTransactionObject<{
-            creator: string
-            nft_address: string
-            name: string
-            personal_limit: string
-            qualification: string
-            holder_token_addr: string
-            holder_min_token_amount: string
-            qualification_data: string
-            0: string
-            1: string
-            2: string
-            3: string
-            4: string
-            5: string
-            6: string
-            7: string
-        }>
-
-        getBoxStatus(box_id: number | string | BN): NonPayableTransactionObject<{
-            payment: [string, string, string][]
-            started: boolean
-            expired: boolean
-            canceled: boolean
-            remaining: string
-            total: string
-            0: [string, string, string][]
-            1: boolean
-            2: boolean
-            3: boolean
-            4: string
-            5: string
-        }>
-
-        getNftListForSale(
-            box_id: number | string | BN,
-            cursor: number | string | BN,
-            amount: number | string | BN,
-        ): NonPayableTransactionObject<string[]>
-
-        getPurchasedNft(box_id: number | string | BN, customer: string): NonPayableTransactionObject<string[]>
-
-        initialize(): NonPayableTransactionObject<void>
-
-        openBox(
-            box_id: number | string | BN,
-            amount: number | string | BN,
-            payment_token_index: number | string | BN,
-            proof: string | number[],
-        ): PayableTransactionObject<void>
-
-        owner(): NonPayableTransactionObject<string>
-
-        removeAdmin(addrs: string[]): NonPayableTransactionObject<void>
-
-        removeWhitelist(addrs: string[]): NonPayableTransactionObject<void>
-
-        renounceOwnership(): NonPayableTransactionObject<void>
-
-        setQualificationData(
-            box_id: number | string | BN,
-            qualification_data: string | number[],
-        ): NonPayableTransactionObject<void>
-
-        transferOwnership(newOwner: string): NonPayableTransactionObject<void>
-
-        whitelist(arg0: string): NonPayableTransactionObject<boolean>
-    }
-    events: {
-        CancelSuccess(cb?: Callback<CancelSuccess>): EventEmitter
-        CancelSuccess(options?: EventOptions, cb?: Callback<CancelSuccess>): EventEmitter
-
-        ClaimPayment(cb?: Callback<ClaimPayment>): EventEmitter
-        ClaimPayment(options?: EventOptions, cb?: Callback<ClaimPayment>): EventEmitter
-
-        CreationSuccess(cb?: Callback<CreationSuccess>): EventEmitter
-        CreationSuccess(options?: EventOptions, cb?: Callback<CreationSuccess>): EventEmitter
-
-        OpenSuccess(cb?: Callback<OpenSuccess>): EventEmitter
-        OpenSuccess(options?: EventOptions, cb?: Callback<OpenSuccess>): EventEmitter
-
-        OwnershipTransferred(cb?: Callback<OwnershipTransferred>): EventEmitter
-        OwnershipTransferred(options?: EventOptions, cb?: Callback<OwnershipTransferred>): EventEmitter
-
-        allEvents(options?: EventOptions, cb?: Callback<EventLog>): EventEmitter
-    }
-
-    once(event: 'CancelSuccess', cb: Callback<CancelSuccess>): void
-    once(event: 'CancelSuccess', options: EventOptions, cb: Callback<CancelSuccess>): void
-
-    once(event: 'ClaimPayment', cb: Callback<ClaimPayment>): void
-    once(event: 'ClaimPayment', options: EventOptions, cb: Callback<ClaimPayment>): void
-
-    once(event: 'CreationSuccess', cb: Callback<CreationSuccess>): void
-    once(event: 'CreationSuccess', options: EventOptions, cb: Callback<CreationSuccess>): void
-
-    once(event: 'OpenSuccess', cb: Callback<OpenSuccess>): void
-    once(event: 'OpenSuccess', options: EventOptions, cb: Callback<OpenSuccess>): void
-
-    once(event: 'OwnershipTransferred', cb: Callback<OwnershipTransferred>): void
-    once(event: 'OwnershipTransferred', options: EventOptions, cb: Callback<OwnershipTransferred>): void
-}
diff --git a/packages/web3-contracts/types/MaskBoxQualification.d.ts b/packages/web3-contracts/types/MaskBoxQualification.d.ts
deleted file mode 100644
index c81b97f593a3..000000000000
--- a/packages/web3-contracts/types/MaskBoxQualification.d.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Autogenerated file. Do not edit manually. */
-/* tslint:disable */
-/* eslint-disable */
-
-import type BN from 'bn.js'
-import type { ContractOptions } from 'web3-eth-contract'
-import type { EventLog } from 'web3-core'
-import type { EventEmitter } from 'events'
-import type {
-    Callback,
-    PayableTransactionObject,
-    NonPayableTransactionObject,
-    BlockType,
-    ContractEventLog,
-    BaseContract,
-} from './types.js'
-
-export interface EventOptions {
-    filter?: object
-    fromBlock?: BlockType
-    topics?: string[]
-}
-
-export interface MaskBoxQualification extends BaseContract {
-    constructor(jsonInterface: any[], address?: string, options?: ContractOptions): MaskBoxQualification
-    clone(): MaskBoxQualification
-    methods: {
-        is_qualified(
-            account: string,
-            proof: string | number[],
-        ): NonPayableTransactionObject<{
-            qualified: boolean
-            error_msg: string
-            0: boolean
-            1: string
-        }>
-
-        version(): NonPayableTransactionObject<string>
-    }
-    events: {
-        allEvents(options?: EventOptions, cb?: Callback<EventLog>): EventEmitter
-    }
-}
diff --git a/packages/web3-contracts/types/index.d.ts b/packages/web3-contracts/types/index.d.ts
index 81b47b86ba59..f3fc247bcfb8 100644
--- a/packages/web3-contracts/types/index.d.ts
+++ b/packages/web3-contracts/types/index.d.ts
@@ -29,8 +29,6 @@ export type { LensHub } from './LensHub.js'
 export type { Lido } from './Lido.js'
 export type { LidoStETH } from './LidoStETH.js'
 export type { LidoWithdraw } from './LidoWithdraw.js'
-export type { MaskBox } from './MaskBox.js'
-export type { MaskBoxQualification } from './MaskBoxQualification.js'
 export type { Multicall } from './Multicall.js'
 export type { NftRedPacket } from './NftRedPacket.js'
 export type { Paymaster } from './Paymaster.js'
diff --git a/packages/web3-providers/package.json b/packages/web3-providers/package.json
index 0397ec103249..9473733142e4 100644
--- a/packages/web3-providers/package.json
+++ b/packages/web3-providers/package.json
@@ -65,7 +65,6 @@
     "bs58": "^5.0.0",
     "buffer": "^6.0.3",
     "date-fns": "^3.6.0",
-    "fortmatic": "^2.4.0",
     "fuse.js": "^7.0.0",
     "graphql-request": "^7.0.1",
     "immer": "^10.1.1",
diff --git a/packages/web3-providers/src/NextID/proof.ts b/packages/web3-providers/src/NextID/proof.ts
index f636de0d12eb..5fdd010bd036 100644
--- a/packages/web3-providers/src/NextID/proof.ts
+++ b/packages/web3-providers/src/NextID/proof.ts
@@ -498,7 +498,10 @@ export class NextIDProof {
             mode: 'cors',
             body: JSON.stringify({
                 operationName: 'GET_LENS_PROFILES',
-                variables: { domainSystem: 'lens', domain: lowerCaseId },
+                variables: {
+                    domainSystem: 'lens',
+                    domain: lowerCaseId.endsWith('.lens') ? lowerCaseId : `${lowerCaseId}.lens`,
+                },
                 query: `
                     query GET_LENS_PROFILES($domainSystem: String, $domain: String) {
                         ${relationServiceDomainQuery(depth)}
diff --git a/packages/web3-providers/src/Web3/EVM/interceptors/Fortmatic.ts b/packages/web3-providers/src/Web3/EVM/interceptors/Fortmatic.ts
deleted file mode 100644
index 232bb1606168..000000000000
--- a/packages/web3-providers/src/Web3/EVM/interceptors/Fortmatic.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { EthereumMethodType, type Middleware } from '@masknet/web3-shared-evm'
-import type { ConnectionContext } from '../libs/ConnectionContext.js'
-
-export class Fortmatic implements Middleware<ConnectionContext> {
-    async fn(context: ConnectionContext, next: () => Promise<void>) {
-        switch (context.request.method) {
-            case EthereumMethodType.personal_sign:
-                context.requestArguments = {
-                    ...context.requestArguments,
-                    params: [...context.requestArguments.params.slice(0, 2), ''],
-                }
-                break
-            default:
-                break
-        }
-        await next()
-    }
-}
diff --git a/packages/web3-providers/src/Web3/EVM/middleware/Interceptor.ts b/packages/web3-providers/src/Web3/EVM/middleware/Interceptor.ts
index 2ea2721e6392..9b5f50941463 100644
--- a/packages/web3-providers/src/Web3/EVM/middleware/Interceptor.ts
+++ b/packages/web3-providers/src/Web3/EVM/middleware/Interceptor.ts
@@ -4,7 +4,6 @@ import { NoneWallet } from '../interceptors/None.js'
 import { MaskWallet } from '../interceptors/MaskWallet.js'
 import { WalletConnect } from '../interceptors/WalletConnect.js'
 import { MetaMaskLike } from '../interceptors/MetaMaskLike.js'
-import { Fortmatic } from '../interceptors/Fortmatic.js'
 import { ContractWallet } from '../interceptors/ContractWallet.js'
 import { Popups } from '../interceptors/Popups.js'
 import { CustomNetwork } from '../interceptors/CustomNetwork.js'
@@ -35,7 +34,6 @@ export class Interceptor implements Middleware<ConnectionContext> {
             [ProviderType.OKX]: Composer.from(new MetaMaskLike(ProviderType.OKX)),
             [ProviderType.WalletConnect]: Composer.from(new WalletConnect()),
             [ProviderType.Coin98]: Composer.from(new MetaMaskLike(ProviderType.Coin98)),
-            [ProviderType.Fortmatic]: Composer.from(new Fortmatic()),
             [ProviderType.Opera]: Composer.from(new MetaMaskLike(ProviderType.Opera)),
             [ProviderType.Rabby]: Composer.from(new MetaMaskLike(ProviderType.Rabby)),
             [ProviderType.Rainbow]: Composer.from(new MetaMaskLike(ProviderType.Rainbow)),
diff --git a/packages/web3-providers/src/Web3/EVM/providers/Fortmatic.ts b/packages/web3-providers/src/Web3/EVM/providers/Fortmatic.ts
deleted file mode 100644
index f4e1e0cc8f7b..000000000000
--- a/packages/web3-providers/src/Web3/EVM/providers/Fortmatic.ts
+++ /dev/null
@@ -1,146 +0,0 @@
-import { first } from 'lodash-es'
-import Fortmatic from 'fortmatic'
-import * as web3_utils from /* webpackDefer: true */ 'web3-utils'
-import { timeout } from '@masknet/kit'
-import type { FmProvider } from 'fortmatic/dist/cjs/src/core/fm-provider.js'
-import { ChainId, ProviderURL, ProviderType, type RequestArguments } from '@masknet/web3-shared-evm'
-import { createLookupTableResolver } from '@masknet/shared-base'
-import { EVMChainResolver } from '../apis/ResolverAPI.js'
-import { BaseEVMWalletProvider } from './Base.js'
-
-// #region create in-page fortmatic provider
-
-/* spell-checker: disable-next-line */
-const TEST_KEY = 'pk_test_D9EAF9A8ACEC9627'
-
-/* spell-checker: disable-next-line */
-const LIVE_KEY = 'pk_live_331BE8AA24445030'
-
-const resolveAPI_Key = createLookupTableResolver<ChainIdFortmatic, string>(
-    {
-        [ChainId.Mainnet]: LIVE_KEY,
-        [ChainId.BSC]: LIVE_KEY,
-        [ChainId.Polygon]: LIVE_KEY,
-        [ChainId.Rinkeby]: TEST_KEY,
-        [ChainId.Ropsten]: TEST_KEY,
-        [ChainId.Kovan]: TEST_KEY,
-    },
-    '',
-)
-
-const isFortmaticSupported = (chainId: ChainId): chainId is ChainIdFortmatic => {
-    return [ChainId.Mainnet, ChainId.BSC].includes(chainId)
-}
-
-type ChainIdFortmatic =
-    | ChainId.Mainnet
-    | ChainId.BSC
-    | ChainId.Polygon
-    | ChainId.Rinkeby
-    | ChainId.Ropsten
-    | ChainId.Kovan
-
-export class FortmaticProvider extends BaseEVMWalletProvider {
-    /**
-     * If the internal chain id exists, it means the connection was created.
-     * Otherwise, no connection was created before.
-     */
-    private chainId_: ChainIdFortmatic | null = null
-    private providerPool = new Map<ChainId, FmProvider>()
-
-    private get chainId(): ChainIdFortmatic {
-        const chainId = this.chainId_
-        if (!chainId) throw new Error('No fortmatic connection.')
-        if (!isFortmaticSupported(chainId)) throw new Error(`The chain id ${chainId} is not supported.`)
-        return chainId
-    }
-
-    private set chainId(newChainId: ChainId) {
-        const chainId = newChainId
-        if (!isFortmaticSupported(chainId)) throw new Error(`The chain id ${chainId} is not supported.`)
-        this.chainId_ = chainId
-    }
-
-    constructor() {
-        super(ProviderType.Fortmatic)
-    }
-
-    protected onAccountsChanged(accounts: string[]) {
-        this.emitter.emit('accounts', accounts)
-    }
-
-    protected onChainChanged(chainId: string) {
-        this.emitter.emit('chainId', chainId)
-    }
-
-    protected onConnect(connected: { account: string; chainId: ChainId }) {
-        this.emitter.emit('connect', connected)
-    }
-
-    private createFortmatic(chainId: ChainIdFortmatic) {
-        return new Fortmatic(resolveAPI_Key(chainId), {
-            chainId,
-            rpcUrl: ProviderURL.from(chainId),
-        })
-    }
-
-    private createProvider() {
-        if (this.providerPool.has(this.chainId)) return this.providerPool.get(this.chainId)!
-
-        const fm = this.createFortmatic(this.chainId)
-        const provider = fm.getProvider()
-        this.providerPool.set(this.chainId, provider)
-        return provider
-    }
-
-    private login() {
-        const fm = this.createFortmatic(this.chainId)
-        return fm.user.login()
-    }
-
-    private async logout() {
-        const fm = this.createFortmatic(this.chainId)
-        return fm.user.logout()
-    }
-
-    override async switchChain(chainId: ChainId): Promise<void> {
-        if (!isFortmaticSupported(chainId)) throw new Error('Invalid chain id.')
-        await this.connect(chainId)
-    }
-
-    override async connect(chainId: ChainId) {
-        try {
-            this.chainId = chainId
-            const accounts = await this.login()
-            if (!accounts.length)
-                throw new Error(`Failed to connect to ${EVMChainResolver.chainFullName(this.chainId)}.`)
-
-            const connected = {
-                account: first(accounts)!,
-                chainId,
-            }
-
-            this.onAccountsChanged(accounts)
-            this.onChainChanged(web3_utils.toHex(chainId))
-            this.onConnect(connected)
-            return connected
-        } catch (error) {
-            this.chainId_ = null
-            throw error
-        }
-    }
-
-    override async disconnect() {
-        try {
-            await timeout(this.logout(), 3000, 'Timeout to logout fortmatic account.')
-        } catch {
-            // do nothing
-        } finally {
-            this.chainId_ = null
-        }
-    }
-
-    override request<T>(requestArguments: RequestArguments) {
-        return this.createProvider().send<T>(requestArguments.method, requestArguments.params)
-    }
-}
diff --git a/packages/web3-providers/src/Web3/EVM/providers/index.ts b/packages/web3-providers/src/Web3/EVM/providers/index.ts
index c515def94b04..b05135dedc37 100644
--- a/packages/web3-providers/src/Web3/EVM/providers/index.ts
+++ b/packages/web3-providers/src/Web3/EVM/providers/index.ts
@@ -12,7 +12,6 @@ import { RainbowProvider } from './Rainbow.js'
 import { OneKeyProvider } from './OneKey.js'
 import { RabbyProvider } from './Rabby.js'
 import { CloverProvider } from './Clover.js'
-import { FortmaticProvider } from './Fortmatic.js'
 import { OperaProvider } from './Opera.js'
 import { ZerionProvider } from './Zerion.js'
 import { MaskWalletProvider, setMaskWalletProviderInstance } from './MaskWallet.js'
@@ -54,7 +53,6 @@ export function createEVMWalletProviders(
         [ProviderType.Trust]: new TrustProvider(),
         [ProviderType.TokenPocket]: new TokenPocketProvider(),
         [ProviderType.Clover]: new CloverProvider(),
-        [ProviderType.Fortmatic]: new FortmaticProvider(),
         [ProviderType.Opera]: new OperaProvider(),
         [ProviderType.Zerion]: new ZerionProvider(),
         [ProviderType.CustomEvent]: new EVMCustomEventProvider(),
diff --git a/packages/web3-providers/src/Web3/EVM/state/TransactionFormatter.ts b/packages/web3-providers/src/Web3/EVM/state/TransactionFormatter.ts
index a15c738bde3c..333845fb1e9f 100644
--- a/packages/web3-providers/src/Web3/EVM/state/TransactionFormatter.ts
+++ b/packages/web3-providers/src/Web3/EVM/state/TransactionFormatter.ts
@@ -21,7 +21,6 @@ import { ContractDeploymentDescriptor } from './TransactionFormatter/descriptors
 import { CancelDescriptor } from './TransactionFormatter/descriptors/Cancel.js'
 import { BaseDescriptor } from './TransactionFormatter/descriptors/Base.js'
 import { GitcoinDescriptor } from './TransactionFormatter/descriptors/Gitcoin.js'
-import { MaskBoxDescriptor } from './TransactionFormatter/descriptors/MaskBox.js'
 import { RedPacketDescriptor } from './TransactionFormatter/descriptors/RedPacket.js'
 import { ERC20Descriptor } from './TransactionFormatter/descriptors/ERC20.js'
 import { ERC721Descriptor } from './TransactionFormatter/descriptors/ERC721.js'
@@ -40,7 +39,6 @@ export class EVMTransactionFormatter extends TransactionFormatterState<ChainId,
             new LensDescriptor(),
             new SavingsDescriptor(),
             new GitcoinDescriptor(),
-            new MaskBoxDescriptor(),
             new RedPacketDescriptor(),
             new SmartPayDescriptor(),
             new ERC20Descriptor(),
diff --git a/packages/web3-providers/src/Web3/EVM/state/TransactionFormatter/abi.ts b/packages/web3-providers/src/Web3/EVM/state/TransactionFormatter/abi.ts
index 238206d38fa1..c59afab43afa 100644
--- a/packages/web3-providers/src/Web3/EVM/state/TransactionFormatter/abi.ts
+++ b/packages/web3-providers/src/Web3/EVM/state/TransactionFormatter/abi.ts
@@ -9,7 +9,6 @@ import NftRedPacket from '@masknet/web3-contracts/abis/NftRedPacket.json' with {
 import HappyRedPacketV4 from '@masknet/web3-contracts/abis/HappyRedPacketV4.json' with { type: 'json' }
 import ERC20 from '@masknet/web3-contracts/abis/ERC20.json' with { type: 'json' }
 import ERC721 from '@masknet/web3-contracts/abis/ERC721.json' with { type: 'json' }
-import MaskBox from '@masknet/web3-contracts/abis/MaskBox.json' with { type: 'json' }
 import WETH from '@masknet/web3-contracts/abis/WETH.json' with { type: 'json' }
 import Lido from '@masknet/web3-contracts/abis/Lido.json' with { type: 'json' }
 import AaveLendingPool from '@masknet/web3-contracts/abis/AaveLendingPool.json' with { type: 'json' }
@@ -27,7 +26,6 @@ class ABI {
         this.construct(BulkCheckout as AbiItem[]) // donate gitcoin grants
         this.construct(NftRedPacket as AbiItem[])
         this.construct(HappyRedPacketV4 as AbiItem[])
-        this.construct(MaskBox as AbiItem[])
         this.construct(ERC721 as AbiItem[])
         this.construct(ERC20 as AbiItem[])
         this.construct(WETH as AbiItem[]) // wrap & unwrap
diff --git a/packages/web3-providers/src/Web3/EVM/state/TransactionFormatter/descriptors/MaskBox.ts b/packages/web3-providers/src/Web3/EVM/state/TransactionFormatter/descriptors/MaskBox.ts
deleted file mode 100644
index 60c04c4c7709..000000000000
--- a/packages/web3-providers/src/Web3/EVM/state/TransactionFormatter/descriptors/MaskBox.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import type { AbiItem } from 'web3-utils'
-import { type TransactionContext, isSameAddress } from '@masknet/web3-shared-base'
-import { type ChainId, getMaskBoxConstants, type TransactionParameter } from '@masknet/web3-shared-evm'
-import MaskBox_ABI from '@masknet/web3-contracts/abis/MaskBox.json' with { type: 'json' }
-import type { TransactionDescriptorFormatResult } from '../types.js'
-import { DescriptorWithTransactionDecodedReceipt, getTokenAmountDescription } from '../utils.js'
-
-export class MaskBoxDescriptor extends DescriptorWithTransactionDecodedReceipt {
-    async getPurchaseTokenInfo(chainId: ChainId, contractAddress: string | undefined, hash: string | undefined) {
-        const events = await this.getReceipt(chainId, contractAddress, MaskBox_ABI as AbiItem[], hash)
-
-        const { amount, token_address } = (events?.ClaimPayment?.returnValues ?? {}) as {
-            amount: string
-            token_address: string
-        }
-        if (!token_address) return
-
-        const token = await this.Hub.getFungibleToken(token_address ?? '', { chainId })
-        if (!token) return
-
-        return getTokenAmountDescription(amount, token)
-    }
-
-    override async compute(
-        context_: TransactionContext<ChainId, TransactionParameter>,
-    ): Promise<TransactionDescriptorFormatResult | undefined> {
-        const context = context_ as TransactionContext<ChainId>
-
-        const { MASK_BOX_CONTRACT_ADDRESS } = getMaskBoxConstants(context.chainId)
-        if (!isSameAddress(context.to, MASK_BOX_CONTRACT_ADDRESS)) return
-        const method = context.methods?.find((x) => ['claimPayment'].includes(x.name ?? ''))
-
-        if (method?.name === 'claimPayment') {
-            const token = await this.getPurchaseTokenInfo(context.chainId, MASK_BOX_CONTRACT_ADDRESS, context.hash)
-            return {
-                chainId: context.chainId,
-                title: 'Purchase Maskbox NFT',
-                description: 'Purchase Maskbox NFT.',
-                snackbar: {
-                    successfulDescription:
-                        token ? { key: 'Maskbox NFT with {token} purchased.', token } : 'Maskbox NFT purchased.',
-                    failedDescription: 'Failed to purchase Maskbox NFT.',
-                },
-                popup: {
-                    method: method.name,
-                },
-            }
-        }
-        return
-    }
-}
diff --git a/packages/web3-providers/src/helpers/getAllMaskDappContractInfo.tsx b/packages/web3-providers/src/helpers/getAllMaskDappContractInfo.tsx
index d782610477cb..451b5c48ef27 100644
--- a/packages/web3-providers/src/helpers/getAllMaskDappContractInfo.tsx
+++ b/packages/web3-providers/src/helpers/getAllMaskDappContractInfo.tsx
@@ -1,9 +1,4 @@
-import {
-    type ChainId,
-    getMaskBoxConstant,
-    getRedPacketConstant,
-    getNftRedPacketConstant,
-} from '@masknet/web3-shared-evm'
+import { type ChainId, getRedPacketConstant, getNftRedPacketConstant } from '@masknet/web3-shared-evm'
 import { Icons } from '@masknet/icons'
 
 export function getAllMaskDappContractInfo(chainId: ChainId, type: 'token' | 'nft') {
@@ -11,7 +6,6 @@ export function getAllMaskDappContractInfo(chainId: ChainId, type: 'token' | 'nf
     const HAPPY_RED_PACKET_ADDRESS_V2 = getRedPacketConstant(chainId, 'HAPPY_RED_PACKET_ADDRESS_V2')
     const HAPPY_RED_PACKET_ADDRESS_V3 = getRedPacketConstant(chainId, 'HAPPY_RED_PACKET_ADDRESS_V3')
     const HAPPY_RED_PACKET_ADDRESS_V4 = getRedPacketConstant(chainId, 'HAPPY_RED_PACKET_ADDRESS_V4')
-    const MASK_BOX_CONTRACT_ADDRESS = getMaskBoxConstant(chainId, 'MASK_BOX_CONTRACT_ADDRESS')
     const RED_PACKET_NFT_ADDRESS = getNftRedPacketConstant(chainId, 'RED_PACKET_NFT_ADDRESS')
     return type === 'token' ?
             [
@@ -37,11 +31,6 @@ export function getAllMaskDappContractInfo(chainId: ChainId, type: 'token' | 'nf
                 },
             ]
         :   [
-                {
-                    address: MASK_BOX_CONTRACT_ADDRESS,
-                    name: 'Mask Box',
-                    logo: <Icons.MaskBox />,
-                },
                 {
                     address: RED_PACKET_NFT_ADDRESS,
                     name: 'NFT Lucky Drop',
diff --git a/packages/web3-shared/base/src/specs/index.ts b/packages/web3-shared/base/src/specs/index.ts
index 42b99efad89d..f1837d63c4e4 100644
--- a/packages/web3-shared/base/src/specs/index.ts
+++ b/packages/web3-shared/base/src/specs/index.ts
@@ -767,8 +767,6 @@ export type FormattedTransactionTitle =
     | 'Follow User'
     // Gitcoin
     | 'Donate'
-    // MaskBox
-    | 'Purchase Maskbox NFT'
     // RedPacket
     | 'Claim Lucky Drop'
     | 'Claim NFT Lucky Drop'
@@ -799,8 +797,6 @@ export type FormattedTransactionDescription =
     | { key: 'Unlock {symbol} NFT contract.'; symbol: string }
     // Airdrop
     | 'Transaction submitted.'
-    // MaskBox
-    | 'Purchase Maskbox NFT.'
     // RedPacket
     | 'Claim your Lucky Drop.'
     | 'Claim your NFT Lucky Drop'
@@ -861,9 +857,6 @@ export type FormattedTransactionSnackbarSuccessDescription =
     | { key: 'Lucky Drop with {token} refunded.'; token: string }
     | { key: 'Lucky Drop with {token} claimed.'; token: string }
     | { key: 'Lucky drop with {token} created.'; token: string }
-    // MaskBox
-    | 'Maskbox NFT purchased.'
-    | { key: 'Maskbox NFT with {token} purchased.'; token: string }
     // Savings
     | { key: '{token} withdrawn.'; token: string }
     | { key: '{token} deposited.'; token: string }
@@ -891,8 +884,6 @@ export type FormattedTransactionSnackbarFailedDescription =
     | 'Failed to deposit token.'
     | { key: 'Failed to deposit {symbol}.'; symbol: string }
     | { key: 'Failed to withdraw {symbol}.'; symbol: string }
-    // MaskBox
-    | 'Failed to purchase Maskbox NFT.'
 
 export interface TransactionDescriptorPopup {
     /** The spender address of erc20 approve */
diff --git a/packages/web3-shared/evm/src/assets/fortmatic.png b/packages/web3-shared/evm/src/assets/fortmatic.png
deleted file mode 100644
index e92ecd3fe75128385a5fedce7e24929413da85b2..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 8532
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

diff --git a/packages/web3-shared/evm/src/constants/constants.ts b/packages/web3-shared/evm/src/constants/constants.ts
index e39e99678a6c..9798f4c3099d 100644
--- a/packages/web3-shared/evm/src/constants/constants.ts
+++ b/packages/web3-shared/evm/src/constants/constants.ts
@@ -13,7 +13,6 @@ import GoPlusLabs from '@masknet/web3-constants/evm/gopluslabs.json' with { type
 import LensProfile from '@masknet/web3-constants/evm/lens-profile.json' with { type: 'json' }
 import Lens from '@masknet/web3-constants/evm/lens.json' with { type: 'json' }
 import Lido from '@masknet/web3-constants/evm/lido.json' with { type: 'json' }
-import MaskBox from '@masknet/web3-constants/evm/mask-box.json' with { type: 'json' }
 import NftRedPacket from '@masknet/web3-constants/evm/nft-red-packet.json' with { type: 'json' }
 import OpenOcean from '@masknet/web3-constants/evm/openocean.json' with { type: 'json' }
 import Pet from '@masknet/web3-constants/evm/pet.json' with { type: 'json' }
@@ -82,11 +81,6 @@ export const getTrendingConstants = transformAll(ChainId, Trending)
 export const useTrendingConstant = transformHook(getTrendingConstants)
 export const useTrendingConstants = transformAllHook(getTrendingConstants)
 
-export const getMaskBoxConstant = transform(ChainId, MaskBox)
-export const getMaskBoxConstants = transformAll(ChainId, MaskBox)
-export const useMaskBoxConstant = transformHook(getMaskBoxConstants)
-export const useMaskBoxConstants = transformAllHook(getMaskBoxConstants)
-
 export const getRPCConstant = transform(ChainId, RPC)
 export const getRPCConstants = transformAll(ChainId, RPC)
 export const useRPCConstant = transformHook(getRPCConstants)
diff --git a/packages/web3-shared/evm/src/constants/descriptors.ts b/packages/web3-shared/evm/src/constants/descriptors.ts
index e60f6f8e3286..29b30c4b0226 100644
--- a/packages/web3-shared/evm/src/constants/descriptors.ts
+++ b/packages/web3-shared/evm/src/constants/descriptors.ts
@@ -610,24 +610,6 @@ export const PROVIDER_DESCRIPTORS: ReadonlyArray<ProviderDescriptor<ChainId, Pro
         shortenLink: 'clv.org',
         downloadLink: 'https://clv.org/?type=wallet',
     },
-    {
-        ID: `${PLUGIN_ID}_fortmatic`,
-        providerAdaptorPluginID: PLUGIN_ID,
-        type: ProviderType.Fortmatic,
-        name: 'Fortmatic',
-        icon: new URL('../assets/fortmatic.png', import.meta.url).href,
-        enableRequirements: {
-            supportedChainIds: Sniffings.is_firefox ? [] : [ChainId.Mainnet, ChainId.BSC],
-            supportedEnhanceableSites: Sniffings.is_firefox ? [] : EnhanceableSiteList,
-            supportedExtensionSites: Sniffings.is_firefox ? [] : ExtensionSiteList,
-        },
-        homeLink: 'https://fortmatic.com',
-        shortenLink: 'fortmatic.com',
-        downloadLink: 'https://fortmatic.com',
-        iconFilterColor: 'rgba(104, 81, 255, 0.2)',
-        backgroundGradient:
-            'linear-gradient(90deg, rgba(104, 81, 255, 0.2) 0%, rgba(98, 126, 234, 0.2) 100%), linear-gradient(0deg, #FFFFFF, #FFFFFF)',
-    },
     {
         ID: `${PLUGIN_ID}_bitget`,
         providerAdaptorPluginID: PLUGIN_ID,
diff --git a/packages/web3-shared/evm/src/helpers/getContractOwnerDomain.ts b/packages/web3-shared/evm/src/helpers/getContractOwnerDomain.ts
index a1595c8edf7b..91edcc2259a5 100644
--- a/packages/web3-shared/evm/src/helpers/getContractOwnerDomain.ts
+++ b/packages/web3-shared/evm/src/helpers/getContractOwnerDomain.ts
@@ -3,7 +3,6 @@ import Aave from '@masknet/web3-constants/evm/aave.json' with { type: 'json' }
 import ArtBlocks from '@masknet/web3-constants/evm/artblocks.json' with { type: 'json' }
 import Gitcoin from '@masknet/web3-constants/evm/gitcoin.json' with { type: 'json' }
 import Lido from '@masknet/web3-constants/evm/lido.json' with { type: 'json' }
-import MaskBox from '@masknet/web3-constants/evm/mask-box.json' with { type: 'json' }
 import NftRedPacket from '@masknet/web3-constants/evm/nft-red-packet.json' with { type: 'json' }
 import RedPacket from '@masknet/web3-constants/evm/red-packet.json' with { type: 'json' }
 
@@ -34,7 +33,6 @@ const domainAddressMap: Record<string, string[]> = {
             'HAPPY_RED_PACKET_ADDRESS_V4',
         ]),
         ...collect(NftRedPacket, ['RED_PACKET_NFT_ADDRESS']),
-        ...collect(MaskBox, ['MASK_BOX_CONTRACT_ADDRESS']),
     ],
 }
 
diff --git a/packages/web3-shared/evm/src/types/index.ts b/packages/web3-shared/evm/src/types/index.ts
index 01638fd7e785..7c8bbd389696 100644
--- a/packages/web3-shared/evm/src/types/index.ts
+++ b/packages/web3-shared/evm/src/types/index.ts
@@ -327,7 +327,6 @@ export enum ProviderType {
     MaskWallet = 'Maskbook',
     MetaMask = 'MetaMask',
     WalletConnect = 'WalletConnect',
-    Fortmatic = 'Fortmatic',
     Coin98 = 'Coin98',
     Coinbase = 'Coinbase',
     Crypto = 'Crypto',
diff --git a/patches/fortmatic@2.4.0.patch b/patches/fortmatic@2.4.0.patch
deleted file mode 100644
index 27f2f3fd4e35..000000000000
--- a/patches/fortmatic@2.4.0.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-diff --git a/dist/cjs/fortmatic.js b/dist/cjs/fortmatic.cjs
-similarity index 100%
-rename from dist/cjs/fortmatic.js
-rename to dist/cjs/fortmatic.cjs
-diff --git a/dist/cjs/src/core/fm-payload-transport.d.ts b/dist/cjs/src/core/fm-payload-transport.d.ts
-index 5a8ddb844fc45f42570980e88089c1bf2ebf6691..ed9eb4fe13faeaeef82e9d8941533ff8b69d9fcb 100644
---- a/dist/cjs/src/core/fm-payload-transport.d.ts
-+++ b/dist/cjs/src/core/fm-payload-transport.d.ts
-@@ -1,5 +1,5 @@
--import { FmIncomingWindowMessage, FmMessageEvent, FmOutgoingWindowMessage, JsonRpcBatchRequestPayload, JsonRpcRequestPayload, JsonRpcResponsePayload } from '../types';
--import { FmIframeController } from './fm-iframe-controller';
-+import { FmIncomingWindowMessage, FmMessageEvent, FmOutgoingWindowMessage, JsonRpcBatchRequestPayload, JsonRpcRequestPayload, JsonRpcResponsePayload } from '../types/index.js';
-+import { FmIframeController } from './fm-iframe-controller.js';
- interface RemoveEventListenerFunction {
-     /**
-      * Stop listening on the event associated with this `FmFetchOffFunction`
-diff --git a/dist/cjs/src/core/fm-provider.d.ts b/dist/cjs/src/core/fm-provider.d.ts
-index 3fae1acc32ca87baea50d24794cb1f6ff57aedc7..f9d834b0e6e23e31d458635540ac1cc64c4eb89d 100644
---- a/dist/cjs/src/core/fm-provider.d.ts
-+++ b/dist/cjs/src/core/fm-provider.d.ts
-@@ -1,4 +1,4 @@
--import { JsonRpcBatchRequestPayload, JsonRpcRequestCallback, JsonRpcRequestPayload, JsonRpcResponsePayload } from '../types';
-+import { JsonRpcBatchRequestPayload, JsonRpcRequestCallback, JsonRpcRequestPayload, JsonRpcResponsePayload } from '../types/index.js';
- /**
-  * Fortmatic's Web3-compliant provider.
-  */
-diff --git a/dist/cjs/src/core/json-rpc-response.d.ts b/dist/cjs/src/core/json-rpc-response.d.ts
-index 9c0cac28c2849353e0a0291037d0c8f65be1305d..e5fd4a163c62b21327b9b4bc3452f9566d0c8ba9 100644
---- a/dist/cjs/src/core/json-rpc-response.d.ts
-+++ b/dist/cjs/src/core/json-rpc-response.d.ts
-@@ -1,4 +1,4 @@
--import { JsonRpcBatchRequestPayload, JsonRpcError, JsonRpcRequestPayload, JsonRpcResponsePayload } from '../types';
-+import { JsonRpcBatchRequestPayload, JsonRpcError, JsonRpcRequestPayload, JsonRpcResponsePayload } from '../types/index.js';
- /**
-  * A class which standardizes JSON RPC responses to ensure the correct
-  * formatting.
-diff --git a/dist/cjs/src/core/sdk-exceptions.d.ts b/dist/cjs/src/core/sdk-exceptions.d.ts
-index bf6f4c611fbb2c1c14d6a0695a169f255dac673e..c4fae5cbb3607155ca599b41512207fa0f1c0829 100644
---- a/dist/cjs/src/core/sdk-exceptions.d.ts
-+++ b/dist/cjs/src/core/sdk-exceptions.d.ts
-@@ -1,4 +1,4 @@
--import { SDKErrorCode, SDKWarningCode, JsonRpcError, RPCErrorCode } from '../types';
-+import { SDKErrorCode, SDKWarningCode, JsonRpcError, RPCErrorCode } from '../types/index.js';
- export declare class FortmaticError extends Error {
-     code: SDKErrorCode;
-     __proto__: ErrorConstructor;
-diff --git a/dist/cjs/src/core/sdk.d.ts b/dist/cjs/src/core/sdk.d.ts
-index 311d81decb72319d4123b9e9bb7d778f72494e39..faccfb212db6f5de541276fde8f7950528cac4c0 100644
---- a/dist/cjs/src/core/sdk.d.ts
-+++ b/dist/cjs/src/core/sdk.d.ts
-@@ -1,9 +1,9 @@
--import { PhantomUser } from '../modules/phantom-mode/phantom-user';
--import { TransactionsModule } from '../modules/widget-mode/transactions-module';
--import { UserModule } from '../modules/widget-mode/user-module';
--import { LoginWithMagicLinkConfiguration, WidgetModeConfiguration, WidgetModeGSNConfiguration } from '../types';
--import { FmProvider } from './fm-provider';
--import { QueryParameters } from '../util/query-params';
-+import { PhantomUser } from '../modules/phantom-mode/phantom-user.js';
-+import { TransactionsModule } from '../modules/widget-mode/transactions-module.js';
-+import { UserModule } from '../modules/widget-mode/user-module.js';
-+import { LoginWithMagicLinkConfiguration, WidgetModeConfiguration, WidgetModeGSNConfiguration } from '../types/index.js';
-+import { FmProvider } from './fm-provider.js';
-+import { QueryParameters } from '../util/query-params.js';
- /**
-  * Base class for Fortmatic SDKs
-  */
-diff --git a/dist/cjs/src/index.d.ts b/dist/cjs/src/index.d.ts
-index 7f30790a2e3fd4563c44b66960fac0f138dd759d..8270fd03ccc991007f3119b090e2ff34b99eca83 100644
---- a/dist/cjs/src/index.d.ts
-+++ b/dist/cjs/src/index.d.ts
-@@ -1,5 +1,5 @@
--import { Fortmatic } from './core/sdk';
--import { FortmaticError, FortmaticWarning, RpcError } from './core/sdk-exceptions';
-+import { Fortmatic } from './core/sdk.js';
-+import { FortmaticError, FortmaticWarning, RpcError } from './core/sdk-exceptions.js';
- export { Fortmatic as default };
- export { FortmaticError, FortmaticWarning, RpcError };
--export * from './types';
-+export * from './types/index.js';
-diff --git a/dist/cjs/src/modules/base-module.d.ts b/dist/cjs/src/modules/base-module.d.ts
-index 0728cd576f7cc4681cf5aa03c48b764bfcd3327d..ce22aab02d2b75924fc8d8f6c62b618564c0626d 100644
---- a/dist/cjs/src/modules/base-module.d.ts
-+++ b/dist/cjs/src/modules/base-module.d.ts
-@@ -1,4 +1,4 @@
--import { SDK } from '../core/sdk';
-+import { SDK } from '../core/sdk.js';
- export declare class BaseModule {
-     protected readonly sdk: SDK;
-     constructor(sdk: SDK);
-diff --git a/dist/cjs/src/modules/phantom-mode/phantom-user.d.ts b/dist/cjs/src/modules/phantom-mode/phantom-user.d.ts
-index 71b092ec620911aa5ee9b38e8341d2a9806fb401..d3ff2af290a501e44b7f0fa8b9e0414f84dbd918 100644
---- a/dist/cjs/src/modules/phantom-mode/phantom-user.d.ts
-+++ b/dist/cjs/src/modules/phantom-mode/phantom-user.d.ts
-@@ -1,5 +1,5 @@
--import { GetIdTokenConfiguration, PhantomModeUserMetadata } from '../../types';
--import { BaseModule } from '../base-module';
-+import { GetIdTokenConfiguration, PhantomModeUserMetadata } from '../../types/index.js';
-+import { BaseModule } from '../base-module.js';
- /**
-  * A stateless object representing the current Fortmatic Auth user.
-  */
-diff --git a/dist/cjs/src/modules/widget-mode/transactions-module.d.ts b/dist/cjs/src/modules/widget-mode/transactions-module.d.ts
-index dcbf535b9081f39fd2464d5c0165083534b804a7..2427ce4dbbfc7939fc20b1913242f016a043aa48 100644
---- a/dist/cjs/src/modules/widget-mode/transactions-module.d.ts
-+++ b/dist/cjs/src/modules/widget-mode/transactions-module.d.ts
-@@ -1,5 +1,5 @@
--import { ComposeTransactionConfig } from '../../types';
--import { BaseModule } from '../base-module';
-+import { ComposeTransactionConfig } from '../../types/index.js';
-+import { BaseModule } from '../base-module.js';
- /**
-  *
-  */
-diff --git a/dist/cjs/src/modules/widget-mode/user-module.d.ts b/dist/cjs/src/modules/widget-mode/user-module.d.ts
-index 2ae620d70ee74b5261e55b2cb568ae80d7551d4b..694ec5c001c51be3b02673df557a51f693885600 100644
---- a/dist/cjs/src/modules/widget-mode/user-module.d.ts
-+++ b/dist/cjs/src/modules/widget-mode/user-module.d.ts
-@@ -1,5 +1,5 @@
--import { DepositConfiguration } from '../../types';
--import { BaseModule } from '../base-module';
-+import { DepositConfiguration } from '../../types/index.js';
-+import { BaseModule } from '../base-module.js';
- /**
-  *
-  */
-diff --git a/dist/cjs/src/types/core/index.d.ts b/dist/cjs/src/types/core/index.d.ts
-index ea8aecd1420ffc953a544a9caaf67dc9fa69fecc..e280dd97b136c052d2e9da01de6cb86d51f901ad 100644
---- a/dist/cjs/src/types/core/index.d.ts
-+++ b/dist/cjs/src/types/core/index.d.ts
-@@ -1,4 +1,4 @@
--export * from './json-rpc-types';
--export * from './provider-types';
--export * from './fm-message-types';
--export * from './exception-types';
-+export * from './json-rpc-types.js';
-+export * from './provider-types.js';
-+export * from './fm-message-types.js';
-+export * from './exception-types.js';
-diff --git a/dist/cjs/src/types/core/provider-types.d.ts b/dist/cjs/src/types/core/provider-types.d.ts
-index f351288980508833db711288270fa1e37261ffb0..51c9f2060c8bb5810837ed73fc71098de468a8ae 100644
---- a/dist/cjs/src/types/core/provider-types.d.ts
-+++ b/dist/cjs/src/types/core/provider-types.d.ts
-@@ -1,4 +1,4 @@
--import { JsonRpcBatchRequestPayload, JsonRpcError, JsonRpcRequestCallback, JsonRpcRequestPayload, JsonRpcResponsePayload } from './json-rpc-types';
-+import { JsonRpcBatchRequestPayload, JsonRpcError, JsonRpcRequestCallback, JsonRpcRequestPayload, JsonRpcResponsePayload } from './json-rpc-types.js';
- /**
-  * The shape of payloads encoded by `FmProvider` while they are queued.
-  */
-diff --git a/dist/cjs/src/types/index.d.ts b/dist/cjs/src/types/index.d.ts
-index 1a409b557e613e63234630feb52dcd1b9eaace04..ec2e991aeff1385bd05a754d5fdada77587961d5 100644
---- a/dist/cjs/src/types/index.d.ts
-+++ b/dist/cjs/src/types/index.d.ts
-@@ -1,3 +1,3 @@
--export * from './core';
--export * from './widget-mode';
--export * from './phantom-mode';
-+export * from './core/index.js';
-+export * from './widget-mode.js';
-+export * from './phantom-mode.js';
-diff --git a/dist/cjs/src/util/emit-payload-promise.d.ts b/dist/cjs/src/util/emit-payload-promise.d.ts
-index 8dc89ad4a40c79d4c4d390b7c361b3c2a9fb5ea8..350b7a0dda32e9aeb9ac0c3dff89f27bffc8fe9c 100644
---- a/dist/cjs/src/util/emit-payload-promise.d.ts
-+++ b/dist/cjs/src/util/emit-payload-promise.d.ts
-@@ -1,5 +1,5 @@
--import { FmProvider } from '../core/fm-provider';
--import { JsonRpcRequestPayload } from '../types';
-+import { FmProvider } from '../core/fm-provider.js';
-+import { JsonRpcRequestPayload } from '../types/index.js';
- /**
-  * Emit a payload to the provider asynchronously using native JavaScript
-  * Promises.
-diff --git a/dist/cjs/src/util/json-rpc-helpers.d.ts b/dist/cjs/src/util/json-rpc-helpers.d.ts
-index f0ed19c7065db7c5e65b0f22a88bbf36059ff278..c34800039768167736f3d45b96e9272ea9f556b8 100644
---- a/dist/cjs/src/util/json-rpc-helpers.d.ts
-+++ b/dist/cjs/src/util/json-rpc-helpers.d.ts
-@@ -1,4 +1,4 @@
--import { ComposeTransactionConfig, JsonRpcBatchRequestPayload, JsonRpcRequestPayload } from '../types';
-+import { ComposeTransactionConfig, JsonRpcBatchRequestPayload, JsonRpcRequestPayload } from '../types/index.js';
- export declare const JSON_RPC_VERSION = "2.0";
- /**
-  * Build a valid JSON RPC payload for emitting to the Ethereum node or Fortmatic
-diff --git a/package.json b/package.json
-index 70fc2b9252138b2bc36447313d5ed28d2ec2e110..c56f462bbd386a24b85a3a71bc7d042cb44fe211 100644
---- a/package.json
-+++ b/package.json
-@@ -2,6 +2,8 @@
-   "name": "fortmatic",
-   "version": "2.4.0",
-   "description": "Fortmatic Javascript SDK",
-+  "type": "module",
-+  "main": "dist/cjs/fortmatic.cjs",
-   "author": "Fortmatic <team@fortmatic.com> (https://fortmatic.com/)",
-   "license": "MIT",
-   "repository": {
-@@ -20,7 +22,6 @@
-     "dapp"
-   ],
-   "homepage": "https://www.fortmatic.com",
--  "main": "dist/cjs/fortmatic.js",
-   "types": "dist/cjs/src/index.d.ts",
-   "scripts": {
-     "start": "npm run clean:build && ./scripts/start.sh",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 04d5b8a3b019..55b8bc4c32f2 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -53,9 +53,6 @@ patchedDependencies:
   eslint-plugin-i@2.29.1:
     hash: zgide6rxzjqivhxxv36ouq6c4y
     path: patches/eslint-plugin-i@2.29.1.patch
-  fortmatic@2.4.0:
-    hash: tlk6cnwltokwhdaixd62dypmxe
-    path: patches/fortmatic@2.4.0.patch
   gulp@5.0.0:
     hash: 43h33nymtjr4cs2ejuui5ulgfe
     path: patches/gulp@5.0.0.patch
@@ -428,9 +425,6 @@ importers:
       '@masknet/plugin-infra':
         specifier: workspace:^
         version: link:../plugin-infra
-      '@masknet/plugin-maskbox':
-        specifier: workspace:^
-        version: link:../plugins/MaskBox
       '@masknet/plugin-nextid':
         specifier: workspace:^
         version: link:../plugins/NextID
@@ -1403,75 +1397,6 @@ importers:
         specifier: workspace:^
         version: link:../../web3-shared/evm
 
-  packages/plugins/MaskBox:
-    dependencies:
-      '@masknet/icons':
-        specifier: workspace:^
-        version: link:../../icons
-      '@masknet/plugin-infra':
-        specifier: workspace:^
-        version: link:../../plugin-infra
-      '@masknet/shared':
-        specifier: workspace:^
-        version: link:../../shared
-      '@masknet/shared-base':
-        specifier: workspace:^
-        version: link:../../shared-base
-      '@masknet/shared-base-ui':
-        specifier: workspace:^
-        version: link:../../shared-base-ui
-      '@masknet/theme':
-        specifier: workspace:^
-        version: link:../../theme
-      '@masknet/typed-message':
-        specifier: workspace:^0.2.0
-        version: link:../../typed-message/base
-      '@masknet/web3-contracts':
-        specifier: workspace:^
-        version: link:../../web3-contracts
-      '@masknet/web3-helpers':
-        specifier: workspace:^
-        version: link:../../web3-helpers
-      '@masknet/web3-hooks-base':
-        specifier: workspace:^
-        version: link:../../web3-hooks/base
-      '@masknet/web3-hooks-evm':
-        specifier: workspace:^
-        version: link:../../web3-hooks/evm
-      '@masknet/web3-providers':
-        specifier: workspace:^
-        version: link:../../web3-providers
-      '@masknet/web3-shared-base':
-        specifier: workspace:^
-        version: link:../../web3-shared/base
-      '@masknet/web3-shared-evm':
-        specifier: workspace:^
-        version: link:../../web3-shared/evm
-      '@types/color':
-        specifier: ^3.0.6
-        version: 3.0.6
-      bignumber.js:
-        specifier: 9.1.2
-        version: 9.1.2
-      buffer:
-        specifier: ^6.0.3
-        version: 6.0.3
-      color:
-        specifier: ^4.2.3
-        version: 4.2.3
-      date-fns:
-        specifier: ^3.6.0
-        version: 3.6.0
-      react-use:
-        specifier: ^17.5.0
-        version: 17.5.0(patch_hash=tokvlmgj4xqkhjmndck4f7nw3q)(react-dom@0.0.0-experimental-58af67a8f8-20240628(react@0.0.0-experimental-58af67a8f8-20240628))(react@0.0.0-experimental-58af67a8f8-20240628)
-      urlcat:
-        specifier: ^3.1.0
-        version: 3.1.0(patch_hash=scyjp2cqyqu6oq4kmzjh3isyxa)
-      web3-utils:
-        specifier: 1.10.2
-        version: 1.10.2
-
   packages/plugins/NextID:
     dependencies:
       '@masknet/icons':
@@ -2906,9 +2831,6 @@ importers:
       date-fns:
         specifier: ^3.6.0
         version: 3.6.0
-      fortmatic:
-        specifier: ^2.4.0
-        version: 2.4.0(patch_hash=tlk6cnwltokwhdaixd62dypmxe)
       fuse.js:
         specifier: ^7.0.0
         version: 7.0.0
@@ -9863,9 +9785,6 @@ packages:
     resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
     engines: {node: '>=12.20.0'}
 
-  fortmatic@2.4.0:
-    resolution: {integrity: sha512-4LVxybyWcz8eFkTjIW12JRyRCUV9/qih435l0+5ncTVIb+zzXjvjQ5dZU0eBAXXyAgmV9BIRYkQL9H/lc76w/w==}
-
   forwarded@0.2.0:
     resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
     engines: {node: '>= 0.6'}
@@ -25089,8 +25008,6 @@ snapshots:
     dependencies:
       fetch-blob: 3.2.0
 
-  fortmatic@2.4.0(patch_hash=tlk6cnwltokwhdaixd62dypmxe): {}
-
   forwarded@0.2.0: {}
 
   fresh@0.5.2: {}
diff --git a/tsconfig.json b/tsconfig.json
index 0a03cdb377f4..1c801c57d347 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -124,7 +124,6 @@
       "@masknet/plugin-gitcoin": ["./packages/plugins/Gitcoin/src/index.ts"],
       "@masknet/plugin-avatar": ["./packages/plugins/Avatar/src/index.ts"],
       "@masknet/plugin-redpacket": ["./packages/plugins/RedPacket/src/index.ts"],
-      "@masknet/plugin-maskbox": ["./packages/plugins/MaskBox/src/index.ts"],
       "@masknet/plugin-smart-pay": ["./packages/plugins/SmartPay/src/index.ts"],
       "@masknet/plugin-transak": ["./packages/plugins/Transak/src/index.ts"],
       "@masknet/plugin-vcent": ["./packages/plugins/VCent/src/index.ts"],