diff --git a/cspell.json b/cspell.json
index 3f36db44c5e..99ed3e7fdf1 100644
--- a/cspell.json
+++ b/cspell.json
@@ -74,9 +74,7 @@
"dompurify",
"dotbit",
"dsearch",
- "efprpc",
"enhanceable",
- "ethfollow",
"evmos",
"farcaster",
"favourites",
diff --git a/packages/icons/icon-generated-as-jsx.js b/packages/icons/icon-generated-as-jsx.js
index f5e72371885..2bc5d6d2eb6 100644
--- a/packages/icons/icon-generated-as-jsx.js
+++ b/packages/icons/icon-generated-as-jsx.js
@@ -4156,11 +4156,6 @@ export const DecentralizedSearch = /*#__PURE__*/ __createIcon('DecentralizedSear
u: () => new URL('./plugins/DecentralizedSearch.svg', import.meta.url).href,
},
])
-export const EFP = /*#__PURE__*/ __createIcon('EFP', [
- {
- u: () => new URL('./plugins/EFP.svg', import.meta.url).href,
- },
-])
export const ENS = /*#__PURE__*/ __createIcon('ENS', [
{
u: () => new URL('./plugins/ENS.png', import.meta.url).href,
diff --git a/packages/icons/icon-generated-as-url.js b/packages/icons/icon-generated-as-url.js
index 2aba1749d45..d8cff431469 100644
--- a/packages/icons/icon-generated-as-url.js
+++ b/packages/icons/icon-generated-as-url.js
@@ -366,7 +366,6 @@ export function cross_bridge_url() { return new URL("./plugins/CrossBridge.png",
export function cyber_connect_dark_url() { return new URL("./plugins/CyberConnect.dark.svg", import.meta.url).href }
export function cyber_connect_light_url() { return new URL("./plugins/CyberConnect.light.svg", import.meta.url).href }
export function decentralized_search_url() { return new URL("./plugins/DecentralizedSearch.svg", import.meta.url).href }
-export function efp_url() { return new URL("./plugins/EFP.svg", import.meta.url).href }
export function ens_url() { return new URL("./plugins/ENS.png", import.meta.url).href }
export function ens_cover_url() { return new URL("./plugins/ENSCover.svg", import.meta.url).href }
export function file_service_url() { return new URL("./plugins/FileService.svg", import.meta.url).href }
diff --git a/packages/icons/plugins/EFP.svg b/packages/icons/plugins/EFP.svg
deleted file mode 100644
index 33fb22532c5..00000000000
--- a/packages/icons/plugins/EFP.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
diff --git a/packages/mask/package.json b/packages/mask/package.json
index 46ca1ca4b7b..bc00fb19b53 100644
--- a/packages/mask/package.json
+++ b/packages/mask/package.json
@@ -44,7 +44,6 @@
"@masknet/plugin-calendar": "workspace:^",
"@masknet/plugin-cross-chain-bridge": "workspace:^",
"@masknet/plugin-debugger": "workspace:^",
- "@masknet/plugin-efp": "workspace:^",
"@masknet/plugin-file-service": "workspace:^",
"@masknet/plugin-gitcoin": "workspace:^",
"@masknet/plugin-go-plus-security": "workspace:^",
diff --git a/packages/mask/shared/plugin-infra/register.js b/packages/mask/shared/plugin-infra/register.js
index 77d34da1760..9842c6ab44c 100644
--- a/packages/mask/shared/plugin-infra/register.js
+++ b/packages/mask/shared/plugin-infra/register.js
@@ -7,7 +7,6 @@ import '@masknet/plugin-go-plus-security/register'
import '@masknet/plugin-cross-chain-bridge/register'
import '@masknet/plugin-web3-profile/register'
import '@masknet/plugin-handle/register'
-import '@masknet/plugin-efp/register'
import '@masknet/plugin-approval/register'
import '@masknet/plugin-gitcoin/register'
import '@masknet/plugin-scam-warning/register'
diff --git a/packages/plugins/EFP/README.md b/packages/plugins/EFP/README.md
deleted file mode 100644
index 45bfa183bd2..00000000000
--- a/packages/plugins/EFP/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Ethereum Follow Protocol plugin
-
-## Referenced resources
-
-- https://efp.app
-- https://docs.efp.app
-- https://data.ethfollow.xyz/api/v1
-- https://github.com/ethereumfollowprotocol/app
-- https://github.com/ethereumfollowprotocol/api-v2
-
-## Known issues / Caveats
-
-- The card intentionally accepts only direct one-segment profile/list URLs with an optional `topEight=true` query.
-- Reserved EFP app routes such as `/api`, `/og`, `/assets`, `/leaderboard`, `/integrations`, `/team`, and `/swipe` are ignored.
-- The embed uses EFP-generated preview images instead of arbitrary ENS avatar or header records to keep CSP changes narrow.
diff --git a/packages/plugins/EFP/package.json b/packages/plugins/EFP/package.json
deleted file mode 100644
index ec4d05eaeaf..00000000000
--- a/packages/plugins/EFP/package.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "name": "@masknet/plugin-efp",
- "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-base": "workspace:^",
- "@masknet/theme": "workspace:^",
- "@masknet/typed-message": "workspace:^"
- }
-}
diff --git a/packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx b/packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
deleted file mode 100644
index ecb3df72a80..00000000000
--- a/packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
+++ /dev/null
@@ -1,232 +0,0 @@
-import { Icons } from '@masknet/icons'
-import { Trans } from '@lingui/react/macro'
-import { makeStyles } from '@masknet/theme'
-import { Box, Link, Stack, Typography } from '@mui/material'
-import { useQuery } from '@tanstack/react-query'
-import { useMemo, useState, type ReactNode } from 'react'
-import { EFP_FALLBACK_IMAGE_URL } from '../constants.js'
-import type { EFPProfileLink } from '../helpers/url.js'
-import { PluginEFPRPC } from '../messages.js'
-import type { EFPProfileResponse } from '../Worker/apis/index.js'
-
-interface ProfileCardProps {
- profileLink: EFPProfileLink
-}
-
-const formatter = new Intl.NumberFormat('en', {
- notation: 'compact',
- maximumFractionDigits: 1,
-})
-
-const useStyles = makeStyles()((theme) => ({
- root: {
- padding: theme.spacing(1.5),
- paddingTop: 0,
- },
- card: {
- overflow: 'hidden',
- borderRadius: 8,
- border: `1px solid ${theme.vars.palette.maskColor.line}`,
- color: theme.vars.palette.maskColor.main,
- background: theme.vars.palette.maskColor.bottom,
- },
- image: {
- display: 'block',
- width: '100%',
- aspectRatio: '1.91 / 1',
- objectFit: 'cover',
- background: theme.vars.palette.maskColor.bg,
- },
- imageFallback: {
- display: 'flex',
- width: '100%',
- aspectRatio: '1.91 / 1',
- alignItems: 'center',
- justifyContent: 'center',
- background: 'linear-gradient(135deg, #f1f3fe 0%, #dff2fb 45%, #ecfffd 100%)',
- color: '#333333',
- },
- body: {
- padding: theme.spacing(1.5),
- gap: theme.spacing(1),
- },
- eyebrow: {
- color: theme.vars.palette.maskColor.second,
- fontWeight: 700,
- lineHeight: 1,
- },
- title: {
- fontWeight: 700,
- wordBreak: 'break-word',
- lineHeight: 1.25,
- },
- description: {
- color: theme.vars.palette.maskColor.second,
- display: '-webkit-box',
- overflow: 'hidden',
- WebkitBoxOrient: 'vertical',
- WebkitLineClamp: 2,
- },
- metrics: {
- display: 'flex',
- flexWrap: 'wrap',
- gap: theme.spacing(1),
- },
- metric: {
- minWidth: 86,
- borderRadius: 8,
- padding: theme.spacing(0.75, 1),
- background: theme.vars.palette.maskColor.bg,
- },
- metricValue: {
- fontWeight: 700,
- lineHeight: 1.2,
- },
- metricLabel: {
- color: theme.vars.palette.maskColor.second,
- lineHeight: 1.2,
- },
- footer: {
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'space-between',
- gap: theme.spacing(1),
- },
- link: {
- display: 'inline-flex',
- alignItems: 'center',
- gap: theme.spacing(0.5),
- fontWeight: 700,
- textDecoration: 'none',
- },
-}))
-
-export function ProfileCard({ profileLink }: ProfileCardProps) {
- const { classes } = useStyles()
- const { data, isPending: loading } = useQuery({
- queryKey: ['efp', 'profile', profileLink.apiPath],
- queryFn: () => PluginEFPRPC.fetchEFPProfile(profileLink.apiPath),
- select: (raw) => (isProfileResponse(raw) ? raw : null),
- })
- const displayName = useMemo(() => getDisplayName(profileLink, data), [profileLink, data])
- const description = data?.ens?.records?.description
- const primaryList = data?.primary_list
-
- return (
-
-
-
-
-
- {profileLink.topEight ?
- EFP Top 8
- : Ethereum Follow Protocol}
-
-
- {displayName}
-
- {description ?
-
- {description}
-
- : null}
-
- Followers}
- value={loading ? '--' : formatCount(data?.followers_count)}
- />
- Following}
- value={loading ? '--' : formatCount(data?.following_count)}
- />
- {primaryList ?
- Primary List} value={`#${primaryList}`} />
- : profileLink.type === 'list' ?
- List} value={`#${profileLink.user}`} />
- : null}
-
-
-
- {profileLink.type === 'list' ?
- EFP list
- : EFP profile}
-
-
- View on EFP
-
-
-
-
-
-
- )
-}
-
-function ProfileImage({ profileLink }: ProfileCardProps) {
- const { classes } = useStyles()
- const [imageUrl, setImageUrl] = useState(profileLink.imageUrl)
- const [failed, setFailed] = useState(false)
-
- if (failed) {
- return (
-
-
-
- )
- }
-
- return (
-
{
- if (imageUrl === EFP_FALLBACK_IMAGE_URL) {
- setFailed(true)
- return
- }
- setImageUrl(EFP_FALLBACK_IMAGE_URL)
- }}
- />
- )
-}
-
-function Metric({ label, value }: { label: ReactNode; value: string }) {
- const { classes } = useStyles()
- return (
-
-
- {value}
-
-
- {label}
-
-
- )
-}
-
-function isProfileResponse(value: EFPProfileResponse | null): value is EFPProfileResponse {
- return !!value && (typeof value.address === 'string' || typeof value.primary_list === 'string')
-}
-
-function getDisplayName(profileLink: EFPProfileLink, data: EFPProfileResponse | null | undefined) {
- const ensName = data?.ens?.name
- if (ensName) return ensName
- if (profileLink.type === 'list') return `List #${profileLink.user}`
- return truncateAddress(profileLink.user)
-}
-
-function truncateAddress(value: string) {
- if (!/^0x[\dA-Fa-f]{40}$/u.test(value)) return value
- return `${value.slice(0, 6)}...${value.slice(-4)}`
-}
-
-function formatCount(value: string | number | undefined) {
- const count = Number(value)
- if (!Number.isFinite(count)) return '--'
- return formatter.format(count)
-}
diff --git a/packages/plugins/EFP/src/SiteAdaptor/index.tsx b/packages/plugins/EFP/src/SiteAdaptor/index.tsx
deleted file mode 100644
index 69a99f5570d..00000000000
--- a/packages/plugins/EFP/src/SiteAdaptor/index.tsx
+++ /dev/null
@@ -1,230 +0,0 @@
-import { Icons } from '@masknet/icons'
-import { Trans } from '@lingui/react/macro'
-import {
- type Plugin,
- PostInfoContext,
- usePluginWrapper,
- usePostInfoMentionedLinks,
- usePostInfoRawMessage,
-} from '@masknet/plugin-infra/content-script'
-import { resolveTCOLink } from '@masknet/plugin-infra/dom/context'
-import { EMPTY_LIST, parseURLs } from '@masknet/shared-base'
-import { extractTextFromTypedMessage } from '@masknet/typed-message'
-import { useQuery } from '@tanstack/react-query'
-import { useContext, useEffect, useMemo, useState, type JSX } from 'react'
-import { base } from '../base.js'
-import { EFP_HOSTS, PLUGIN_NAME } from '../constants.js'
-import { parseEFPProfileLink, type EFPProfileLink } from '../helpers/url.js'
-import { ProfileCard } from './ProfileCard.js'
-
-function Renderer({ profileLink }: { profileLink: EFPProfileLink }) {
- // Read rootNode/isFocusing through the context directly. The usePostInfoDetails proxy
- // also works, but trips react-compiler's hook-as-value rule at the call site for fields
- // (like rootNode) that the proxy returns as plain values rather than via a real hook.
- const postInfo = useContext(PostInfoContext)
- const rootNode = postInfo?.rootNode ?? null
- const isFocusing = postInfo?.isFocusing ?? false
- usePluginWrapper(true, { name: PLUGIN_NAME })
- useHideNativeTwitterCard(rootNode, isFocusing)
-
- return
-}
-
-function useHideNativeTwitterCard(rootNode: HTMLElement | null, isFocusing: boolean) {
- useEffect(() => {
- if (!rootNode) return
-
- const article = rootNode.closest('article')
- // Timeline: scope to the article so we don't hide cards in sibling tweets whose Twitter
- // preview happens to mention efp.app/ethfollow.xyz in its title or description. Detail
- // view: the post's card can live in a sibling subtree of the article (per Twitter's
- // postsContentSelector), so widen one level.
- const searchRoot = isFocusing ? article?.parentElement : article
- if (!searchRoot) return
-
- // Track every element we modify so the cleanup can restore the Twitter card if the plugin
- // unmounts (navigation, post leaves the viewport, plugin disabled). Without this, hidden
- // cards stay hidden forever even after the React tree is gone.
- const modified = new Map()
-
- const hide = () => {
- for (const card of searchRoot.querySelectorAll('[data-testid="card.wrapper"]')) {
- if (!isEFPCard(card)) continue
- const container = getCardContainer(card)
- // For link-only tweets the rootNode IS the card.wrapper, and our React tree mounts
- // in rootElement.afterShadow — a sibling of the card. Hiding the card itself is
- // fine, but we must not hide any ancestor of rootNode or we'd take our own
- // injection down with it.
- const target = container.contains(rootNode) ? card : container
- if (modified.has(target)) continue
- modified.set(target, {
- display: target.style.display,
- ariaHidden: target.getAttribute('aria-hidden'),
- })
- target.style.display = 'none'
- target.setAttribute('aria-hidden', 'true')
- }
- }
-
- hide()
- const observer = new MutationObserver(hide)
- observer.observe(searchRoot, { childList: true, subtree: true })
- return () => {
- observer.disconnect()
- for (const [target, prev] of modified) {
- target.style.display = prev.display
- // eslint-disable-next-line unicorn/prefer-toggle-attribute -- "" and "true" are both aria-hidden, toggle need more code
- if (prev.ariaHidden === null) target.removeAttribute('aria-hidden')
- else target.setAttribute('aria-hidden', prev.ariaHidden)
- }
- modified.clear()
- }
- }, [rootNode, isFocusing])
-}
-
-// Twitter renders the visible card as a parent that's `aria-labelledby` the card.wrapper id and
-// also holds the "From " footer as a sibling of the wrapper. Hide the parent so the footer
-// goes away with the card; fall back to the wrapper when the structure doesn't match.
-function getCardContainer(card: HTMLElement): HTMLElement {
- const parent = card.parentElement
- if (!parent || !card.id) return card
- const labelledBy = parent.getAttribute('aria-labelledby')
- if (labelledBy?.split(/\s+/u).includes(card.id)) return parent
- return card
-}
-
-// Twitter wraps external links in t.co redirects, so the card anchor's href is usually opaque.
-// We identify an EFP card from two precise signals, never a substring scan (which would
-// false-positive on cards whose title/description merely mentions efp.app, or on a look-alike
-// host that contains it as a substring):
-// 1. The href or visible text already is a valid EFP URL (direct, non-t.co links).
-// 2. The card's source host — the first whitespace token of the media anchor's aria-label,
-// e.g. "efp.app vitalik.eth" — exactly equals one of the EFP hosts. That token is Twitter's
-// declared card domain, so exact equality is safe.
-function isEFPCard(card: HTMLElement) {
- for (const anchor of card.querySelectorAll('a[href]')) {
- if (parseEFPProfileLink(anchor.href)) return true
- const text = anchor.textContent?.trim()
- if (text && parseEFPProfileLink(text)) return true
- const sourceHost = anchor.getAttribute('aria-label')?.trim().split(/\s+/u, 1)[0]?.toLowerCase()
- if (sourceHost && (EFP_HOSTS as readonly string[]).includes(sourceHost)) return true
- }
- return false
-}
-
-// When X renders a link-preview card it strips the URL from the tweet text, so the card anchor's
-// t.co href is the only machine-readable trace of the EFP link. The site adaptor does collect and
-// resolve card anchors into mentionedLinks, but that collection runs when the post's text node is
-// first processed and never re-runs — a card that mounts later (common on slow connections) is
-// missed entirely. Watch the post's card area ourselves, scoped exactly like
-// useHideNativeTwitterCard so detection and hiding agree, and resolve the card link directly.
-function useEFPCardLink(enabled: boolean): EFPProfileLink | null {
- const postInfo = useContext(PostInfoContext)
- const rootNode = postInfo?.rootNode ?? null
- const isFocusing = postInfo?.isFocusing ?? false
- const [hrefs, setHrefs] = useState(EMPTY_LIST)
-
- useEffect(() => {
- if (!enabled || !rootNode) return
-
- const article = rootNode.closest('article')
- const searchRoot = isFocusing ? article?.parentElement : article
- if (!searchRoot) return
-
- const scan = () => {
- const found = new Set()
- for (const card of searchRoot.querySelectorAll('[data-testid="card.wrapper"]')) {
- if (!isEFPCard(card)) continue
- for (const anchor of card.querySelectorAll('a[href]')) found.add(anchor.href)
- }
- const next = [...found].toSorted((a, b) => a.localeCompare(b))
- // eslint-disable-next-line @eslint-react/set-state-in-effect
- setHrefs((prev) => (prev.length === next.length && prev.every((x, i) => x === next[i]) ? prev : next))
- }
-
- scan()
- const observer = new MutationObserver(scan)
- observer.observe(searchRoot, { childList: true, subtree: true })
- return () => {
- observer.disconnect()
- setHrefs(EMPTY_LIST)
- }
- }, [enabled, rootNode, isFocusing])
-
- const { data = null } = useQuery({
- enabled: enabled && hrefs.length > 0,
- queryKey: ['efp', 'card-link', hrefs],
- queryFn: async () => {
- for (const href of hrefs) {
- const direct = parseEFPProfileLink(href)
- if (direct) return direct
- if (!href.startsWith('https://t.co/')) continue
- const resolved = await resolveTCOLink(href)
- const link = resolved ? parseEFPProfileLink(resolved) : null
- if (link) return link
- }
- return null
- },
- })
- return data
-}
-
-const site: Plugin.SiteAdaptor.Definition = {
- ...base,
- DecryptedInspector(props): JSX.Element | null {
- const profileLink = useMemo(() => {
- const text = extractTextFromTypedMessage(props.message)
- if (text.isNone()) return null
- for (const url of parseURLs(text.value, false)) {
- const link = parseEFPProfileLink(url)
- if (link) return link
- }
- return null
- }, [props.message])
-
- if (!profileLink) return null
- return
- },
- PostInspector(): JSX.Element | null {
- const message = usePostInfoRawMessage()
- const mentionedLinks = usePostInfoMentionedLinks()
- const profileLink = useMemo(() => {
- // mentionedLinks carries the links Maskbook resolves from t.co redirects. That is how
- // an EFP URL surfaces when X truncates a long address URL with an ellipsis.
- // parseURLs(rawMessage, false) additionally catches protocol-less links typed directly
- // in the body (e.g. efp.app/vitalik.eth) without waiting on that async resolution.
- const text = extractTextFromTypedMessage(message)
- const candidates = text.isNone() ? mentionedLinks : [...mentionedLinks, ...parseURLs(text.value, false)]
- for (const url of candidates) {
- const link = parseEFPProfileLink(url)
- if (link) return link
- }
- return null
- }, [message, mentionedLinks])
- // Link-preview cards leave no URL in the tweet text, so when the body and collected links
- // yield nothing, detect the EFP card from the card DOM itself.
- const cardLink = useEFPCardLink(!profileLink)
-
- const link = profileLink ?? cardLink
- if (!link) return null
- return
- },
- ApplicationEntries: [
- {
- ApplicationEntryID: base.ID,
- category: 'dapp',
- marketListSortingPriority: 18,
- description: A native Ethereum protocol for following and tagging Ethereum accounts.,
- name: Ethereum Follow Protocol,
- icon: ,
- tutorialLink: 'https://docs.efp.app/intro',
- },
- ],
- wrapperProps: {
- icon: ,
- backgroundGradient:
- 'linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.8) 100%), linear-gradient(90deg, rgba(255, 224, 103, 0.2) 0%, rgba(211, 234, 244, 0.2) 100%), #FFFFFF',
- },
-}
-
-export default site
diff --git a/packages/plugins/EFP/src/Worker/apis/index.ts b/packages/plugins/EFP/src/Worker/apis/index.ts
deleted file mode 100644
index 2ac9b393310..00000000000
--- a/packages/plugins/EFP/src/Worker/apis/index.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { EFP_API_URL } from '../../constants.js'
-
-export interface EFPProfileResponse {
- address?: string
- ens?: {
- name?: string | null
- records?: { [recordName: string]: string | undefined } | null
- } | null
- followers_count?: number | string
- following_count?: number | string
- primary_list?: string | null
-}
-
-export async function fetchEFPProfile(apiPath: string): Promise {
- const url = `${EFP_API_URL}${apiPath}`
- const response = await fetch(url, {
- headers: {
- Accept: 'application/json',
- },
- })
- if (!response.ok) {
- throw new Error(`Failed to fetch EFP profile from ${apiPath} (status: ${response.status})`)
- }
- return response.json() as Promise
-}
diff --git a/packages/plugins/EFP/src/Worker/index.ts b/packages/plugins/EFP/src/Worker/index.ts
deleted file mode 100644
index 2c2b03ab7fd..00000000000
--- a/packages/plugins/EFP/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/EFP/src/base.ts b/packages/plugins/EFP/src/base.ts
deleted file mode 100644
index 4f9a47cdab0..00000000000
--- a/packages/plugins/EFP/src/base.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import type { Plugin } from '@masknet/plugin-infra'
-import { DEFAULT_PLUGIN_PUBLISHER, EnhanceableSite } from '@masknet/shared-base'
-import { EFP_PROFILE_URL_PATTERN, PLUGIN_DESCRIPTION, PLUGIN_ID, PLUGIN_NAME } from './constants.js'
-
-export const base: Plugin.Shared.Definition = {
- ID: PLUGIN_ID,
- name: { fallback: PLUGIN_NAME },
- description: { fallback: PLUGIN_DESCRIPTION },
- publisher: DEFAULT_PLUGIN_PUBLISHER,
- enableRequirement: {
- supports: {
- type: 'opt-out',
- sites: {
- [EnhanceableSite.Localhost]: true,
- },
- },
- target: 'stable',
- },
- contribution: {
- postContent: new Set([EFP_PROFILE_URL_PATTERN]),
- },
-}
diff --git a/packages/plugins/EFP/src/constants.ts b/packages/plugins/EFP/src/constants.ts
deleted file mode 100644
index 38831a9ae34..00000000000
--- a/packages/plugins/EFP/src/constants.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { PluginID } from '@masknet/shared-base'
-
-export const PLUGIN_ID = PluginID.EFP
-export const PLUGIN_NAME = 'Ethereum Follow Protocol'
-export const PLUGIN_DESCRIPTION = 'A native Ethereum protocol for following and tagging Ethereum accounts.'
-export const EFP_APP_URL = 'https://efp.app'
-export const EFP_API_URL = 'https://data.ethfollow.xyz/api/v1'
-export const EFP_FALLBACK_IMAGE_URL = `${EFP_APP_URL}/assets/art/default-header.svg`
-
-export const EFP_HOSTS = ['efp.app', 'www.efp.app', 'ethfollow.xyz', 'www.ethfollow.xyz'] as const
-export const RESERVED_EFP_PATHS = ['api', 'og', 'assets', 'leaderboard', 'integrations', 'team', 'swipe'] as const
-
-const ENS_LABEL_PATTERN = '[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?'
-const EFP_USER_PATTERN = String.raw`(?:0x[\dA-Fa-f]{40}|[1-9]\d*|(?:${ENS_LABEL_PATTERN}\.)+${ENS_LABEL_PATTERN})`
-const RESERVED_ROUTE_PATTERN = RESERVED_EFP_PATHS.map((path) => `${path}(?:[/?#]|$)`).join('|')
-
-export const EFP_PROFILE_URL_PATTERN = new RegExp(
- String.raw`^(?:https?:\/\/)?(?:www\.)?(?:ethfollow\.xyz|efp\.app)\/(?!${RESERVED_ROUTE_PATTERN})${EFP_USER_PATTERN}(?:\?topEight=true)?$`,
- 'u',
-)
diff --git a/packages/plugins/EFP/src/env.d.ts b/packages/plugins/EFP/src/env.d.ts
deleted file mode 100644
index 868322d5ff3..00000000000
--- a/packages/plugins/EFP/src/env.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-///
diff --git a/packages/plugins/EFP/src/helpers/url.ts b/packages/plugins/EFP/src/helpers/url.ts
deleted file mode 100644
index cf345e314cf..00000000000
--- a/packages/plugins/EFP/src/helpers/url.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import { EFP_APP_URL, EFP_HOSTS, RESERVED_EFP_PATHS } from '../constants.js'
-
-const EFP_HOST_SET: ReadonlySet = new Set(EFP_HOSTS)
-const RESERVED_PATH_SET: ReadonlySet = new Set(RESERVED_EFP_PATHS)
-const ADDRESS_PATTERN = /^0x[\dA-Fa-f]{40}$/u
-const LIST_PATTERN = /^[1-9]\d*$/u
-const ENS_LABEL_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?$/u
-
-export interface EFPProfileLink {
- user: string
- type: 'list' | 'user'
- topEight: boolean
- profileUrl: string
- imageUrl: string
- apiPath: string
-}
-
-export function parseEFPProfileLink(link: string): EFPProfileLink | null {
- const url = parseURL(link)
- if (!url) return null
- // http is accepted because X rewrites protocol-less links into http:// t.co redirect targets,
- // so EFP links resolved from t.co cards arrive with the http protocol. Every URL we emit is
- // built from the https EFP_APP_URL constant regardless of the input protocol.
- if (url.protocol !== 'https:' && url.protocol !== 'http:') return null
- if (!EFP_HOST_SET.has(url.hostname)) return null
- if (url.hash) return null
-
- const segments = url.pathname.split('/').filter(Boolean)
- if (segments.length !== 1) return null
-
- const user = safeDecodeURIComponent(segments[0])
- if (!user) return null
- if (RESERVED_PATH_SET.has(user.toLowerCase())) return null
- if (!isSupportedUser(user)) return null
-
- const searchParams = url.searchParams.entries().toArray()
- const topEight = searchParams.length === 1 && searchParams[0][0] === 'topEight' && searchParams[0][1] === 'true'
- if (url.search && !topEight) return null
-
- const type = LIST_PATTERN.test(user) ? 'list' : 'user'
- const encodedUser = encodeURIComponent(user)
- const query = topEight ? '?topEight=true' : ''
-
- return {
- user,
- type,
- topEight,
- profileUrl: `${EFP_APP_URL}/${encodedUser}${query}`,
- imageUrl:
- topEight ? `${EFP_APP_URL}/api/top-eight?user=${encodedUser}` : `${EFP_APP_URL}/og?user=${encodedUser}`,
- apiPath: `/${type === 'list' ? 'lists' : 'users'}/${encodedUser}/details`,
- }
-}
-
-export function isEFPProfileLink(link: string): boolean {
- return parseEFPProfileLink(link) !== null
-}
-
-function parseURL(link: string) {
- try {
- return new URL(/^https?:\/\//u.test(link) ? link : `https://${link}`)
- } catch {
- return null
- }
-}
-
-function safeDecodeURIComponent(value: string) {
- try {
- return decodeURIComponent(value)
- } catch {
- return ''
- }
-}
-
-function isSupportedUser(user: string) {
- if (ADDRESS_PATTERN.test(user)) return true
- if (LIST_PATTERN.test(user)) return true
- const labels = user.split('.')
- if (labels.length < 2) return false
- return labels.every((label) => ENS_LABEL_PATTERN.test(label))
-}
diff --git a/packages/plugins/EFP/src/index.ts b/packages/plugins/EFP/src/index.ts
deleted file mode 100644
index 5ba94dda145..00000000000
--- a/packages/plugins/EFP/src/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './constants.js'
-export * from './helpers/url.js'
diff --git a/packages/plugins/EFP/src/messages.ts b/packages/plugins/EFP/src/messages.ts
deleted file mode 100644
index f76bc272a9a..00000000000
--- a/packages/plugins/EFP/src/messages.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { getPluginRPC } from '@masknet/plugin-infra'
-import { PLUGIN_ID } from './constants.js'
-
-import.meta.webpackHot?.accept()
-export const PluginEFPRPC = getPluginRPC(PLUGIN_ID)
diff --git a/packages/plugins/EFP/src/register.ts b/packages/plugins/EFP/src/register.ts
deleted file mode 100644
index aa1f8a4cd9d..00000000000
--- a/packages/plugins/EFP/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/EFP/src/tests/url.ts b/packages/plugins/EFP/src/tests/url.ts
deleted file mode 100644
index c3cbc8fb118..00000000000
--- a/packages/plugins/EFP/src/tests/url.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-/* eslint-disable unicorn/prefer-https */
-import { describe, expect, it } from 'vitest'
-import { EFP_PROFILE_URL_PATTERN } from '../constants.js'
-import { parseEFPProfileLink } from '../helpers/url.js'
-
-describe('EFP profile links', () => {
- it.each([
- ['ethfollow.xyz/vitalik.eth', { user: 'vitalik.eth', type: 'user', topEight: false }],
- [
- 'https://efp.app/0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
- { user: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045', type: 'user', topEight: false },
- ],
- ['https://ethfollow.xyz/6509', { user: '6509', type: 'list', topEight: false }],
- ['https://efp.app/vitalik.eth?topEight=true', { user: 'vitalik.eth', type: 'user', topEight: true }],
- // X rewrites protocol-less links into http:// t.co redirect targets, so links resolved
- // from t.co cards arrive with the http protocol.
- ['http://ethfollow.xyz/6509', { user: '6509', type: 'list', topEight: false }],
- ['http://efp.app/vitalik.eth', { user: 'vitalik.eth', type: 'user', topEight: false }],
- ] as const)('parses %s', (link, expected) => {
- const result = parseEFPProfileLink(link)
-
- expect(result).toMatchObject(expected)
- expect(result?.profileUrl).toContain(`/${expected.user}`)
- })
-
- it.each([
- 'https://ethfollow.xyz/api',
- 'https://efp.app/og?user=vitalik.eth',
- 'https://efp.app/assets/logo.svg',
- 'https://efp.app/leaderboard',
- 'https://efp.app/integrations',
- 'https://efp.app/team',
- 'https://efp.app/swipe',
- 'https://ethfollow.xyz/vitalik.eth/followers',
- 'https://example.com/vitalik.eth',
- 'https://efp.app/not a valid name',
- 'https://efp.app/not..valid.eth',
- 'https://efp.app/vitalik.eth?topEight=false',
- 'https://efp.app/vitalik.eth?foo=bar',
- 'https://efp.app/vitalik.eth#profile',
- 'ftp://efp.app/vitalik.eth',
- ])('rejects %s', (link) => {
- expect(parseEFPProfileLink(link)).toBeNull()
- })
-
- it.each([
- 'https://ethfollow.xyz/vitalik.eth',
- 'https://efp.app/0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
- 'https://ethfollow.xyz/6509',
- 'https://efp.app/vitalik.eth?topEight=true',
- 'http://ethfollow.xyz/6509',
- ])('contribution pattern matches %s', (link) => {
- expect(EFP_PROFILE_URL_PATTERN.test(link)).toBe(true)
- })
-
- it.each([
- 'https://efp.app/api',
- 'https://efp.app/og?user=vitalik.eth',
- 'https://efp.app/vitalik.eth/followers',
- 'https://efp.app/not a valid name',
- 'https://efp.app/not..valid.eth',
- 'https://efp.app/vitalik.eth?topEight=false',
- 'https://efp.app/vitalik.eth#profile',
- ])('contribution pattern rejects %s', (link) => {
- expect(EFP_PROFILE_URL_PATTERN.test(link)).toBe(false)
- })
-})
diff --git a/packages/plugins/EFP/tsconfig.json b/packages/plugins/EFP/tsconfig.json
deleted file mode 100644
index 909554b29dc..00000000000
--- a/packages/plugins/EFP/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": "../../theme/tsconfig.json" },
- { "path": "../../typed-message/base/tsconfig.json" }
- ]
-}
diff --git a/packages/plugins/tsconfig.json b/packages/plugins/tsconfig.json
index b3b1ee7bf84..1ae97cc6598 100644
--- a/packages/plugins/tsconfig.json
+++ b/packages/plugins/tsconfig.json
@@ -5,7 +5,6 @@
{ "path": "./Calendar/tsconfig.json" },
{ "path": "./CrossChainBridge/tsconfig.json" },
{ "path": "./Debugger/tsconfig.json" },
- { "path": "./EFP/tsconfig.json" },
{ "path": "./FileService/tsconfig.json" },
{ "path": "./Gitcoin/tsconfig.json" },
{ "path": "./GoPlusSecurity/tsconfig.json" },
diff --git a/packages/shared-base-ui/src/locale/en-US.po b/packages/shared-base-ui/src/locale/en-US.po
index 939722d5bcf..9797624f380 100644
--- a/packages/shared-base-ui/src/locale/en-US.po
+++ b/packages/shared-base-ui/src/locale/en-US.po
@@ -611,8 +611,8 @@ msgid "A blacklist is found. Some addresses may not be able to trade normally, w
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/index.tsx
-msgid "A native Ethereum protocol for following and tagging Ethereum accounts."
-msgstr ""
+#~ msgid "A native Ethereum protocol for following and tagging Ethereum accounts."
+#~ msgstr ""
#: packages/mask/content-script/components/CompositionDialog/useSubmit.ts
msgid "a token"
@@ -2368,16 +2368,16 @@ msgid "Editor"
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP list"
-msgstr ""
+#~ msgid "EFP list"
+#~ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP profile"
-msgstr ""
+#~ msgid "EFP profile"
+#~ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP Top 8"
-msgstr ""
+#~ msgid "EFP Top 8"
+#~ msgstr ""
#: packages/mask/content-script/components/shared/SelectProfileUI/SelectProfileUI.tsx
#: packages/mask/content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx
@@ -2549,8 +2549,8 @@ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/index.tsx
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Ethereum Follow Protocol"
-msgstr ""
+#~ msgid "Ethereum Follow Protocol"
+#~ msgstr ""
#: packages/plugins/Calendar/src/SiteAdaptor/CalendarContent.tsx
msgid "Events"
@@ -2883,10 +2883,9 @@ msgid "Follow User"
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Followers"
-msgstr ""
+#~ msgid "Followers"
+#~ msgstr ""
-#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
#: packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx
#: packages/plugins/Web3Profile/src/SiteAdaptor/components/SocialBadges/LensList.tsx
#: packages/shared/src/UI/components/SocialAccountList/SocialListItem.tsx
@@ -3611,8 +3610,8 @@ msgid "Link"
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "List"
-msgstr ""
+#~ msgid "List"
+#~ msgstr ""
#: packages/shared/src/UI/modals/ApplicationBoardModal/ApplicationSettingPluginList.tsx
msgid "Listed"
@@ -4872,8 +4871,8 @@ msgstr ""
#~ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Primary List"
-msgstr ""
+#~ msgid "Primary List"
+#~ msgstr ""
#: packages/plugins/Trader/src/SiteAdaptor/trader/views/NetworkFee/index.tsx
msgid "Priority fee"
@@ -6720,8 +6719,8 @@ msgid "View multiple accounts Web3 profile by hovering over the mini Mask icon a
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "View on EFP"
-msgstr ""
+#~ msgid "View on EFP"
+#~ msgstr ""
#: packages/mask/content-script/components/InjectedComponents/ProfileCard/ProfileBar.tsx
#: packages/mask/popups/pages/Personas/ConnectWallet/index.tsx
diff --git a/packages/shared-base-ui/src/locale/ja-JP.po b/packages/shared-base-ui/src/locale/ja-JP.po
index 7ab45d213e8..1ea7f00f7b3 100644
--- a/packages/shared-base-ui/src/locale/ja-JP.po
+++ b/packages/shared-base-ui/src/locale/ja-JP.po
@@ -616,8 +616,8 @@ msgid "A blacklist is found. Some addresses may not be able to trade normally, w
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/index.tsx
-msgid "A native Ethereum protocol for following and tagging Ethereum accounts."
-msgstr ""
+#~ msgid "A native Ethereum protocol for following and tagging Ethereum accounts."
+#~ msgstr ""
#: packages/mask/content-script/components/CompositionDialog/useSubmit.ts
msgid "a token"
@@ -2373,16 +2373,16 @@ msgid "Editor"
msgstr "編集者"
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP list"
-msgstr ""
+#~ msgid "EFP list"
+#~ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP profile"
-msgstr ""
+#~ msgid "EFP profile"
+#~ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP Top 8"
-msgstr ""
+#~ msgid "EFP Top 8"
+#~ msgstr ""
#: packages/mask/content-script/components/shared/SelectProfileUI/SelectProfileUI.tsx
#: packages/mask/content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx
@@ -2554,8 +2554,8 @@ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/index.tsx
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Ethereum Follow Protocol"
-msgstr ""
+#~ msgid "Ethereum Follow Protocol"
+#~ msgstr ""
#: packages/plugins/Calendar/src/SiteAdaptor/CalendarContent.tsx
msgid "Events"
@@ -2888,10 +2888,9 @@ msgid "Follow User"
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Followers"
-msgstr "フォロワー"
+#~ msgid "Followers"
+#~ msgstr "フォロワー"
-#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
#: packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx
#: packages/plugins/Web3Profile/src/SiteAdaptor/components/SocialBadges/LensList.tsx
#: packages/shared/src/UI/components/SocialAccountList/SocialListItem.tsx
@@ -3616,8 +3615,8 @@ msgid "Link"
msgstr "リンク"
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "List"
-msgstr ""
+#~ msgid "List"
+#~ msgstr ""
#: packages/shared/src/UI/modals/ApplicationBoardModal/ApplicationSettingPluginList.tsx
msgid "Listed"
@@ -4877,8 +4876,8 @@ msgstr "価格統計"
#~ msgstr "価格:"
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Primary List"
-msgstr ""
+#~ msgid "Primary List"
+#~ msgstr ""
#: packages/plugins/Trader/src/SiteAdaptor/trader/views/NetworkFee/index.tsx
msgid "Priority fee"
@@ -6725,8 +6724,8 @@ msgid "View multiple accounts Web3 profile by hovering over the mini Mask icon a
msgstr "タイムラインのアバターやトークンタグの隅にあるミニMaskアイコンに合わせると、複数のアカウントのWeb3プロフィールが表示されます。"
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "View on EFP"
-msgstr ""
+#~ msgid "View on EFP"
+#~ msgstr ""
#: packages/mask/content-script/components/InjectedComponents/ProfileCard/ProfileBar.tsx
#: packages/mask/popups/pages/Personas/ConnectWallet/index.tsx
diff --git a/packages/shared-base-ui/src/locale/ko-KR.po b/packages/shared-base-ui/src/locale/ko-KR.po
index 9f6ce3fa824..c7ec0ddda48 100644
--- a/packages/shared-base-ui/src/locale/ko-KR.po
+++ b/packages/shared-base-ui/src/locale/ko-KR.po
@@ -616,8 +616,8 @@ msgid "A blacklist is found. Some addresses may not be able to trade normally, w
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/index.tsx
-msgid "A native Ethereum protocol for following and tagging Ethereum accounts."
-msgstr ""
+#~ msgid "A native Ethereum protocol for following and tagging Ethereum accounts."
+#~ msgstr ""
#: packages/mask/content-script/components/CompositionDialog/useSubmit.ts
msgid "a token"
@@ -2373,16 +2373,16 @@ msgid "Editor"
msgstr "에디터"
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP list"
-msgstr ""
+#~ msgid "EFP list"
+#~ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP profile"
-msgstr ""
+#~ msgid "EFP profile"
+#~ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP Top 8"
-msgstr ""
+#~ msgid "EFP Top 8"
+#~ msgstr ""
#: packages/mask/content-script/components/shared/SelectProfileUI/SelectProfileUI.tsx
#: packages/mask/content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx
@@ -2554,8 +2554,8 @@ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/index.tsx
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Ethereum Follow Protocol"
-msgstr ""
+#~ msgid "Ethereum Follow Protocol"
+#~ msgstr ""
#: packages/plugins/Calendar/src/SiteAdaptor/CalendarContent.tsx
msgid "Events"
@@ -2888,10 +2888,9 @@ msgid "Follow User"
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Followers"
-msgstr "팔로워"
+#~ msgid "Followers"
+#~ msgstr "팔로워"
-#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
#: packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx
#: packages/plugins/Web3Profile/src/SiteAdaptor/components/SocialBadges/LensList.tsx
#: packages/shared/src/UI/components/SocialAccountList/SocialListItem.tsx
@@ -3616,8 +3615,8 @@ msgid "Link"
msgstr "링크"
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "List"
-msgstr ""
+#~ msgid "List"
+#~ msgstr ""
#: packages/shared/src/UI/modals/ApplicationBoardModal/ApplicationSettingPluginList.tsx
msgid "Listed"
@@ -4877,8 +4876,8 @@ msgstr "가격 통계"
#~ msgstr "가격:"
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Primary List"
-msgstr ""
+#~ msgid "Primary List"
+#~ msgstr ""
#: packages/plugins/Trader/src/SiteAdaptor/trader/views/NetworkFee/index.tsx
msgid "Priority fee"
@@ -6725,8 +6724,8 @@ msgid "View multiple accounts Web3 profile by hovering over the mini Mask icon a
msgstr "아바타 오른쪽 아래에 있는 미니 Mask 아이콘이나 타임라인의 토큰 태그 위에 마우스를 올려놓아 여러 계정의 웹3 프로필을 볼 수 있습니다."
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "View on EFP"
-msgstr ""
+#~ msgid "View on EFP"
+#~ msgstr ""
#: packages/mask/content-script/components/InjectedComponents/ProfileCard/ProfileBar.tsx
#: packages/mask/popups/pages/Personas/ConnectWallet/index.tsx
diff --git a/packages/shared-base-ui/src/locale/zh-CN.po b/packages/shared-base-ui/src/locale/zh-CN.po
index 199d9794c7e..ff811608823 100644
--- a/packages/shared-base-ui/src/locale/zh-CN.po
+++ b/packages/shared-base-ui/src/locale/zh-CN.po
@@ -616,8 +616,8 @@ msgid "A blacklist is found. Some addresses may not be able to trade normally, w
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/index.tsx
-msgid "A native Ethereum protocol for following and tagging Ethereum accounts."
-msgstr ""
+#~ msgid "A native Ethereum protocol for following and tagging Ethereum accounts."
+#~ msgstr ""
#: packages/mask/content-script/components/CompositionDialog/useSubmit.ts
msgid "a token"
@@ -2373,16 +2373,16 @@ msgid "Editor"
msgstr "编辑器"
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP list"
-msgstr ""
+#~ msgid "EFP list"
+#~ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP profile"
-msgstr ""
+#~ msgid "EFP profile"
+#~ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP Top 8"
-msgstr ""
+#~ msgid "EFP Top 8"
+#~ msgstr ""
#: packages/mask/content-script/components/shared/SelectProfileUI/SelectProfileUI.tsx
#: packages/mask/content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx
@@ -2554,8 +2554,8 @@ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/index.tsx
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Ethereum Follow Protocol"
-msgstr ""
+#~ msgid "Ethereum Follow Protocol"
+#~ msgstr ""
#: packages/plugins/Calendar/src/SiteAdaptor/CalendarContent.tsx
msgid "Events"
@@ -2888,10 +2888,9 @@ msgid "Follow User"
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Followers"
-msgstr "粉丝"
+#~ msgid "Followers"
+#~ msgstr "粉丝"
-#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
#: packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx
#: packages/plugins/Web3Profile/src/SiteAdaptor/components/SocialBadges/LensList.tsx
#: packages/shared/src/UI/components/SocialAccountList/SocialListItem.tsx
@@ -3616,8 +3615,8 @@ msgid "Link"
msgstr "交易记录"
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "List"
-msgstr ""
+#~ msgid "List"
+#~ msgstr ""
#: packages/shared/src/UI/modals/ApplicationBoardModal/ApplicationSettingPluginList.tsx
msgid "Listed"
@@ -4877,8 +4876,8 @@ msgstr "价格统计数据"
#~ msgstr "价格:"
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Primary List"
-msgstr ""
+#~ msgid "Primary List"
+#~ msgstr ""
#: packages/plugins/Trader/src/SiteAdaptor/trader/views/NetworkFee/index.tsx
msgid "Priority fee"
@@ -6725,8 +6724,8 @@ msgid "View multiple accounts Web3 profile by hovering over the mini Mask icon a
msgstr "鼠标悬停于头像右下角的 Mask 图标或时间线上的代币话题标签,浏览多元化账户的 Web3 足迹。"
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "View on EFP"
-msgstr ""
+#~ msgid "View on EFP"
+#~ msgstr ""
#: packages/mask/content-script/components/InjectedComponents/ProfileCard/ProfileBar.tsx
#: packages/mask/popups/pages/Personas/ConnectWallet/index.tsx
diff --git a/packages/shared-base-ui/src/locale/zh-TW.po b/packages/shared-base-ui/src/locale/zh-TW.po
index 4166644d71e..67eb160e25b 100644
--- a/packages/shared-base-ui/src/locale/zh-TW.po
+++ b/packages/shared-base-ui/src/locale/zh-TW.po
@@ -616,8 +616,8 @@ msgid "A blacklist is found. Some addresses may not be able to trade normally, w
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/index.tsx
-msgid "A native Ethereum protocol for following and tagging Ethereum accounts."
-msgstr ""
+#~ msgid "A native Ethereum protocol for following and tagging Ethereum accounts."
+#~ msgstr ""
#: packages/mask/content-script/components/CompositionDialog/useSubmit.ts
msgid "a token"
@@ -2373,16 +2373,16 @@ msgid "Editor"
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP list"
-msgstr ""
+#~ msgid "EFP list"
+#~ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP profile"
-msgstr ""
+#~ msgid "EFP profile"
+#~ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "EFP Top 8"
-msgstr ""
+#~ msgid "EFP Top 8"
+#~ msgstr ""
#: packages/mask/content-script/components/shared/SelectProfileUI/SelectProfileUI.tsx
#: packages/mask/content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx
@@ -2554,8 +2554,8 @@ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/index.tsx
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Ethereum Follow Protocol"
-msgstr ""
+#~ msgid "Ethereum Follow Protocol"
+#~ msgstr ""
#: packages/plugins/Calendar/src/SiteAdaptor/CalendarContent.tsx
msgid "Events"
@@ -2888,10 +2888,9 @@ msgid "Follow User"
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Followers"
-msgstr ""
+#~ msgid "Followers"
+#~ msgstr ""
-#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
#: packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx
#: packages/plugins/Web3Profile/src/SiteAdaptor/components/SocialBadges/LensList.tsx
#: packages/shared/src/UI/components/SocialAccountList/SocialListItem.tsx
@@ -3616,8 +3615,8 @@ msgid "Link"
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "List"
-msgstr ""
+#~ msgid "List"
+#~ msgstr ""
#: packages/shared/src/UI/modals/ApplicationBoardModal/ApplicationSettingPluginList.tsx
msgid "Listed"
@@ -4877,8 +4876,8 @@ msgstr ""
#~ msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "Primary List"
-msgstr ""
+#~ msgid "Primary List"
+#~ msgstr ""
#: packages/plugins/Trader/src/SiteAdaptor/trader/views/NetworkFee/index.tsx
msgid "Priority fee"
@@ -6725,8 +6724,8 @@ msgid "View multiple accounts Web3 profile by hovering over the mini Mask icon a
msgstr ""
#: packages/plugins/EFP/src/SiteAdaptor/ProfileCard.tsx
-msgid "View on EFP"
-msgstr ""
+#~ msgid "View on EFP"
+#~ msgstr ""
#: packages/mask/content-script/components/InjectedComponents/ProfileCard/ProfileBar.tsx
#: packages/mask/popups/pages/Personas/ConnectWallet/index.tsx
diff --git a/packages/shared-base/src/types/PluginID.ts b/packages/shared-base/src/types/PluginID.ts
index 22aea4d4de5..3524d758761 100644
--- a/packages/shared-base/src/types/PluginID.ts
+++ b/packages/shared-base/src/types/PluginID.ts
@@ -26,7 +26,6 @@ export enum PluginID {
Savings = 'com.savings',
Wallet = 'com.maskbook.wallet',
FileService = 'com.maskbook.fileservice',
- EFP = 'xyz.ethfollow',
GoPlusSecurity = 'io.gopluslabs.security',
CrossChainBridge = 'io.mask.cross-chain-bridge',
Web3Profile = 'io.mask.web3-profile',
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index dfd7d060ff2..24f7478b4e1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -394,9 +394,6 @@ importers:
'@masknet/plugin-debugger':
specifier: workspace:^
version: link:../plugins/Debugger
- '@masknet/plugin-efp':
- specifier: workspace:^
- version: link:../plugins/EFP
'@masknet/plugin-file-service':
specifier: workspace:^
version: link:../plugins/FileService
@@ -924,24 +921,6 @@ importers:
specifier: workspace:^
version: link:../../web3-telemetry
- packages/plugins/EFP:
- dependencies:
- '@masknet/icons':
- specifier: workspace:^
- version: link:../../icons
- '@masknet/plugin-infra':
- specifier: workspace:^
- version: link:../../plugin-infra
- '@masknet/shared-base':
- specifier: workspace:^
- version: link:../../shared-base
- '@masknet/theme':
- specifier: workspace:^
- version: link:../../theme
- '@masknet/typed-message':
- specifier: workspace:^
- version: link:../../typed-message/base
-
packages/plugins/FileService:
dependencies:
'@dimensiondev/common-protocols':
diff --git a/security/content-security-policy.json b/security/content-security-policy.json
index c69de59d7bc..42716f06e9b 100644
--- a/security/content-security-policy.json
+++ b/security/content-security-policy.json
@@ -59,7 +59,6 @@
"https://prod-api.kosetto.com",
"https://grants-stack-indexer-v2.gitcoin.co/",
- "https://data.ethfollow.xyz",
"https://t.co",
@@ -81,7 +80,6 @@
"https://imagedelivery.net",
"https://bridge.metis.io",
"https://static.okx.com",
- "https://efp.app",
"https://dzyb4dm7r8k8w.cloudfront.net",
"https://purecatamphetamine.github.io/country-flag-icons/"
],