From 80261fee3df24aef47c3f4b6aaaf070d0402ff9f Mon Sep 17 00:00:00 2001
From: nuanyang233 <nuanyang233@gmail.com>
Date: Tue, 14 Jun 2022 11:20:18 +0800
Subject: [PATCH 1/3] fix: bugfix for mask wallet (#6530)

* fix: bugfix for mask wallet

* fix: add fallback empty array for debank and zerion

* fix: make offer only support mainnet
---
 .../SNSAdaptor/OpenSea/ActionBar.tsx          |  9 +++--
 .../plugin-infra/src/web3-state/Provider.ts   |  2 +-
 .../src/web3/useFungibleAssets.ts             |  1 +
 packages/plugins/EVM/src/state/Provider.ts    | 38 ++++++++++++++++++-
 packages/web3-providers/src/debank/index.ts   |  4 ++
 packages/web3-providers/src/helpers.ts        |  8 ++++
 packages/web3-providers/src/zerion/index.ts   |  2 +
 7 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/OpenSea/ActionBar.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/OpenSea/ActionBar.tsx
index dd1557b11135..cce3789f3c96 100644
--- a/packages/mask/src/plugins/Collectible/SNSAdaptor/OpenSea/ActionBar.tsx
+++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/OpenSea/ActionBar.tsx
@@ -8,9 +8,10 @@ import { MakeOfferDialog } from './MakeOfferDialog'
 import { PostListingDialog } from './PostListingDialog'
 import { CheckoutDialog } from './CheckoutDialog'
 import { ChainBoundary } from '../../../../web3/UI/ChainBoundary'
-import { useAccount, useChainId } from '@masknet/plugin-infra/web3'
+import { useAccount } from '@masknet/plugin-infra/web3'
 import { isSameAddress, NetworkPluginID } from '@masknet/web3-shared-base'
 import { useAssetOrder } from '../../hooks/useAssetOrder'
+import { ChainId } from '@masknet/web3-shared-evm'
 
 const useStyles = makeStyles()((theme) => {
     return {
@@ -35,7 +36,6 @@ export function ActionBar(props: ActionBarProps) {
     const { classes } = useStyles()
     const { asset } = CollectibleState.useContainer()
     const account = useAccount(NetworkPluginID.PLUGIN_EVM)
-    const chainId = useChainId(NetworkPluginID.PLUGIN_EVM)
     const { value: assetOrder } = useAssetOrder(asset.value?.address, asset.value?.tokenId)
 
     const {
@@ -54,7 +54,10 @@ export function ActionBar(props: ActionBarProps) {
     const isOwner = isSameAddress(asset.value.owner?.address, account)
     return (
         <Box className={classes.root} sx={{ padding: 1.5 }} display="flex" justifyContent="center">
-            <ChainBoundary expectedPluginID={NetworkPluginID.PLUGIN_EVM} expectedChainId={chainId} renderInTimeline>
+            <ChainBoundary
+                expectedPluginID={NetworkPluginID.PLUGIN_EVM}
+                expectedChainId={ChainId.Mainnet}
+                renderInTimeline>
                 {!isOwner && asset.value.auction ? (
                     <ActionButton
                         className={classes.button}
diff --git a/packages/plugin-infra/src/web3-state/Provider.ts b/packages/plugin-infra/src/web3-state/Provider.ts
index bf6a8898ce01..fc9c1e5464b3 100644
--- a/packages/plugin-infra/src/web3-state/Provider.ts
+++ b/packages/plugin-infra/src/web3-state/Provider.ts
@@ -72,7 +72,7 @@ export class ProviderState<
         this.setupProviders()
     }
 
-    private setupSubscriptions() {
+    protected setupSubscriptions() {
         const site = this.site
         if (!site) return
 
diff --git a/packages/plugin-infra/src/web3/useFungibleAssets.ts b/packages/plugin-infra/src/web3/useFungibleAssets.ts
index c68fc1bfcf7a..9ad4595ab5c0 100644
--- a/packages/plugin-infra/src/web3/useFungibleAssets.ts
+++ b/packages/plugin-infra/src/web3/useFungibleAssets.ts
@@ -45,6 +45,7 @@ export function useFungibleAssets<S extends 'all' | void = void, T extends Netwo
             })
         })
         const assets = await asyncIteratorToArray(iterator)
+
         const filteredAssets = assets.length && schemaType ? assets.filter((x) => x.schema === schemaType) : assets
 
         return filteredAssets
diff --git a/packages/plugins/EVM/src/state/Provider.ts b/packages/plugins/EVM/src/state/Provider.ts
index 3cb9c019728f..6bed3a8cc4cc 100644
--- a/packages/plugins/EVM/src/state/Provider.ts
+++ b/packages/plugins/EVM/src/state/Provider.ts
@@ -12,7 +12,8 @@ import {
     isValidChainId,
 } from '@masknet/web3-shared-evm'
 import { Providers } from './Connection/provider'
-import { ExtensionSite } from '@masknet/shared-base'
+import { ExtensionSite, mapSubscription, mergeSubscription } from '@masknet/shared-base'
+import { getEnumAsArray } from '@dimensiondev/kit'
 
 export class Provider extends ProviderState<ChainId, ProviderType, NetworkType, Web3Provider, Web3> {
     constructor(context: Plugin.Shared.SharedContext) {
@@ -23,9 +24,42 @@ export class Provider extends ProviderState<ChainId, ProviderType, NetworkType,
             getDefaultChainId: () => ChainId.Mainnet,
             getDefaultNetworkType: () => NetworkType.Ethereum,
             getDefaultProviderType: (site) =>
-                site === ExtensionSite.Popup ? ProviderType.MaskWallet : ProviderType.None,
+                getEnumAsArray(ExtensionSite).some(({ value }) => value === site)
+                    ? ProviderType.MaskWallet
+                    : ProviderType.None,
             getNetworkTypeFromChainId: (chainId: ChainId) =>
                 chainResolver.chainNetworkType(chainId) ?? NetworkType.Ethereum,
         })
     }
+
+    override setupSubscriptions() {
+        const site = this.site
+        if (!site) return
+
+        this.providerType = mapSubscription(this.storage.providers.subscription, (providers) => providers[site])
+
+        this.chainId = mapSubscription(
+            mergeSubscription(this.providerType, this.storage.accounts.subscription, this.context.chainId),
+            ([providerType, accounts, chainId]) => {
+                if (providerType === ProviderType.MaskWallet) return chainId
+                return accounts[providerType].chainId
+            },
+        )
+        this.account = mapSubscription(
+            mergeSubscription(this.providerType, this.storage.accounts.subscription, this.context.account),
+            ([providerType, accounts, maskAccount]) => {
+                if (providerType === ProviderType.MaskWallet) return maskAccount
+
+                return accounts[providerType].account
+            },
+        )
+        this.networkType = mapSubscription(
+            mergeSubscription(this.providerType, this.storage.accounts.subscription, this.context.chainId),
+            ([providerType, accounts, chainId]) => {
+                if (providerType === ProviderType.MaskWallet) return this.options.getNetworkTypeFromChainId(chainId)
+
+                return this.options.getNetworkTypeFromChainId(accounts[providerType].chainId)
+            },
+        )
+    }
 }
diff --git a/packages/web3-providers/src/debank/index.ts b/packages/web3-providers/src/debank/index.ts
index c0e264d10d3f..1eff214e7f8f 100644
--- a/packages/web3-providers/src/debank/index.ts
+++ b/packages/web3-providers/src/debank/index.ts
@@ -11,6 +11,7 @@ import {
 import { formatAssets, formatTransactions } from './format'
 import type { WalletTokenRecord, HistoryResponse, GasPriceDictResponse } from './type'
 import type { FungibleTokenAPI, HistoryAPI, GasOptionAPI } from '../types'
+import { getAllEVMNativeAssets } from '../helpers'
 
 const DEBANK_API = 'https://api.debank.com'
 const DEBANK_OPEN_API = 'https://openapi.debank.com'
@@ -73,6 +74,9 @@ export class DeBankAPI
             }),
         )
         const result = (await response.json()) as WalletTokenRecord[] | undefined
+        if (!result?.length) {
+            return createPageable(getAllEVMNativeAssets(), createIndicator(options?.indicator))
+        }
         try {
             return createPageable(
                 formatAssets(
diff --git a/packages/web3-providers/src/helpers.ts b/packages/web3-providers/src/helpers.ts
index 9dc385ce6bea..46d4c2353f6d 100644
--- a/packages/web3-providers/src/helpers.ts
+++ b/packages/web3-providers/src/helpers.ts
@@ -1,4 +1,5 @@
 import urlcat from 'urlcat'
+import { createNativeToken, NETWORK_DESCRIPTORS } from '@masknet/web3-shared-evm'
 
 export function isProxyENV() {
     try {
@@ -18,3 +19,10 @@ const CORS_PROXY = 'https://cors.r2d2.to'
 export function courier(url: string) {
     return urlcat(`${CORS_PROXY}?:url`, { url })
 }
+
+export function getAllEVMNativeAssets() {
+    return NETWORK_DESCRIPTORS.filter((x) => x.isMainnet).map((x) => ({
+        ...createNativeToken(x.chainId),
+        balance: '0',
+    }))
+}
diff --git a/packages/web3-providers/src/zerion/index.ts b/packages/web3-providers/src/zerion/index.ts
index 3c72631d0e69..1d782edd53a8 100644
--- a/packages/web3-providers/src/zerion/index.ts
+++ b/packages/web3-providers/src/zerion/index.ts
@@ -14,6 +14,7 @@ import type {
 } from './type'
 import { formatAssets, formatTransactions } from './format'
 import type { FungibleTokenAPI, HistoryAPI } from '../types'
+import { getAllEVMNativeAssets } from '../helpers'
 
 const ZERION_API = 'wss://api-v4.zerion.io'
 // cspell:disable-next-line
@@ -130,6 +131,7 @@ export class ZerionAPI
             result = [...result, ...assets.flat()]
         }
 
+        if (!result.length) return createPageable(getAllEVMNativeAssets(), createIndicator(options?.indicator))
         return createPageable(result, createIndicator(options?.indicator))
     }
 

From 9d4f48398bea08fba8730b2883a70b7da531ebf4 Mon Sep 17 00:00:00 2001
From: nuanyang233 <nuanyang233@gmail.com>
Date: Tue, 14 Jun 2022 14:42:07 +0800
Subject: [PATCH 2/3] fix: adjust instagram some dom selectors

---
 packages/mask/shared-ui/locales/en-US.json                 | 2 +-
 .../instagram.com/injection/NFT/NFTAvatarInTimeline.tsx    | 1 +
 .../instagram.com/injection/NFT/ProfileNFTAvatar.tsx       | 7 ++++++-
 .../social-network-adaptor/instagram.com/utils/selector.ts | 6 ++++--
 4 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/packages/mask/shared-ui/locales/en-US.json b/packages/mask/shared-ui/locales/en-US.json
index 8ffb8947f6e7..343b6943b3b8 100644
--- a/packages/mask/shared-ui/locales/en-US.json
+++ b/packages/mask/shared-ui/locales/en-US.json
@@ -886,7 +886,7 @@
     "popups_social_account": "Social Accounts",
     "popups_connected_wallets": "Connected Wallets",
     "popups_loading": "Loading",
-    "popups_connect_your_web2_social_accounts": "Connect your web2 social accounts",
+    "popups_connect_your_web2_social_accounts": "Connect your social media accounts",
     "popups_connect_social_account": "Connect Social Account",
     "popups_disconnect_success": " Disconnect successfully. ",
     "popups_disconnect_failed": "Disconnect failed.",
diff --git a/packages/mask/src/social-network-adaptor/instagram.com/injection/NFT/NFTAvatarInTimeline.tsx b/packages/mask/src/social-network-adaptor/instagram.com/injection/NFT/NFTAvatarInTimeline.tsx
index 8df7016e9da9..ade5e6a9b7f8 100644
--- a/packages/mask/src/social-network-adaptor/instagram.com/injection/NFT/NFTAvatarInTimeline.tsx
+++ b/packages/mask/src/social-network-adaptor/instagram.com/injection/NFT/NFTAvatarInTimeline.tsx
@@ -51,6 +51,7 @@ function _(selector: () => LiveSelector<HTMLImageElement, false>, signal: AbortS
 
                 if (!id) return
 
+                console.log(id)
                 const info = getInjectNodeInfo(element)
 
                 if (!info) return
diff --git a/packages/mask/src/social-network-adaptor/instagram.com/injection/NFT/ProfileNFTAvatar.tsx b/packages/mask/src/social-network-adaptor/instagram.com/injection/NFT/ProfileNFTAvatar.tsx
index 4b3fd6fc0e95..ee1f7d0dcf91 100644
--- a/packages/mask/src/social-network-adaptor/instagram.com/injection/NFT/ProfileNFTAvatar.tsx
+++ b/packages/mask/src/social-network-adaptor/instagram.com/injection/NFT/ProfileNFTAvatar.tsx
@@ -1,14 +1,19 @@
 import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit'
-import { searchInstagramAvatarListSelector } from '../../utils/selector'
+import { searchInstagramAvatarEditPageSettingDialog, searchInstagramAvatarListSelector } from '../../utils/selector'
 import { createReactRootShadowed, MaskMessages, startWatch, useI18N, useLocationChange } from '../../../../utils'
 import { makeStyles } from '@masknet/theme'
 import { useCallback, useLayoutEffect, useState } from 'react'
 import { useLocation } from 'react-use'
+import { NFTAvatarSettingDialog } from './NFTAvatarSettingDialog'
 
 export async function injectProfileNFTAvatarInInstagram(signal: AbortSignal) {
     const watcher = new MutationObserverWatcher(searchInstagramAvatarListSelector())
     startWatch(watcher, signal)
     createReactRootShadowed(watcher.firstDOMProxy.afterShadow, { signal }).render(<NFTAvatarButtonInDialog />)
+
+    const dialogWatcher = new MutationObserverWatcher(searchInstagramAvatarEditPageSettingDialog())
+    startWatch(dialogWatcher, signal)
+    createReactRootShadowed(dialogWatcher.firstDOMProxy.afterShadow, { signal }).render(<NFTAvatarSettingDialog />)
 }
 
 const useStyles = makeStyles<StyleProps>()((theme, props) => ({
diff --git a/packages/mask/src/social-network-adaptor/instagram.com/utils/selector.ts b/packages/mask/src/social-network-adaptor/instagram.com/utils/selector.ts
index 384765459c04..9bfb792a37a2 100644
--- a/packages/mask/src/social-network-adaptor/instagram.com/utils/selector.ts
+++ b/packages/mask/src/social-network-adaptor/instagram.com/utils/selector.ts
@@ -41,7 +41,7 @@ export const searchUserIdSelector = () =>
     querySelector('#ssrb_root_start').closest(1).querySelector<HTMLHeadingElement>('section main header section h2')
 
 export const searchUserIdInEditPageSelector = () =>
-    querySelector('#ssrb_root_start').closest(1).querySelector('button > img').closest(4).querySelector('h1')
+    querySelector('#react-root').querySelector('button > img').closest(4).querySelector('h1')
 
 export const searchProfileTabArticlePageSelector = () =>
     querySelector('#ssrb_root_start').closest(1).querySelector<E>('section main div[role="tablist"]')
@@ -63,6 +63,8 @@ export const searchInstagramProfileAvatarButtonSelector = () =>
 
 export const searchInstagramAvatarSettingDialog = () => querySelector('#ssrb_root_start').closest<E>(1)
 
+export const searchInstagramAvatarEditPageSettingDialog = () => querySelector('#react-root')
+
 export const searchInstagramProfileSettingButtonSelector = () =>
     querySelector('#ssrb_root_start')
         .closest(1)
@@ -75,5 +77,5 @@ export const searchInstagramProfileEditButton = () =>
 
 export const searchInstagramPostAvatarSelector = () =>
     new LiveSelector<HTMLImageElement, false>().querySelectorAll<HTMLImageElement>(
-        '[role="button"] > a > img[data-testid="user-avatar"]',
+        '[role="button"] > a > img[crossorigin="anonymous"]',
     )

From 04a4de7859693ceeef73fe432b73e0f3ba299a92 Mon Sep 17 00:00:00 2001
From: guanbinrui <52657989+guanbinrui@users.noreply.github.com>
Date: Tue, 14 Jun 2022 18:14:16 +0800
Subject: [PATCH 3/3] refactor: remove log

---
 .../instagram.com/injection/NFT/NFTAvatarInTimeline.tsx          | 1 -
 1 file changed, 1 deletion(-)

diff --git a/packages/mask/src/social-network-adaptor/instagram.com/injection/NFT/NFTAvatarInTimeline.tsx b/packages/mask/src/social-network-adaptor/instagram.com/injection/NFT/NFTAvatarInTimeline.tsx
index ade5e6a9b7f8..8df7016e9da9 100644
--- a/packages/mask/src/social-network-adaptor/instagram.com/injection/NFT/NFTAvatarInTimeline.tsx
+++ b/packages/mask/src/social-network-adaptor/instagram.com/injection/NFT/NFTAvatarInTimeline.tsx
@@ -51,7 +51,6 @@ function _(selector: () => LiveSelector<HTMLImageElement, false>, signal: AbortS
 
                 if (!id) return
 
-                console.log(id)
                 const info = getInjectNodeInfo(element)
 
                 if (!info) return
