diff --git a/.github/ISSUE_TEMPLATE/evm.md b/.github/ISSUE_TEMPLATE/evm.md
new file mode 100644
index 000000000000..e7298aaae56a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/evm.md
@@ -0,0 +1,32 @@
+---
+name: Deploy Contract Request
+about: Request to deploy contracts on a new EVM-compatible chain.
+title: '[EVM Chain] Request to deploy contracts on '
+labels: ''
+assignees: DimensionDev/dev-smartcontract
+---
+
+Request to depoly contracts on .
+
+
+
+## Chain Info
+
+| Name | Content |
+| ------------ | ------- |
+| Name | \- |
+| ChainId | \- |
+| Website | \- |
+| RPC Endponit | \- |
+
+
+## Checklist
+
+The following contracts are requested.
+
++ [RedPacket](https://github.com/DimensionDev/RedPacket)
++ [Initial Twitter Offer](https://github.com/DimensionDev/InitialTwitterOffering)
++ Dummy Qualification
++ BalanceChecker
++ Multicall
++ UniswapInterfaceMulticall
diff --git a/.github/workflows/deploy-proxy.yml b/.github/workflows/deploy-proxy.yml
deleted file mode 100644
index 9bd3176fa268..000000000000
--- a/.github/workflows/deploy-proxy.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: Publish Proxy Package
-
-on:
- workflow_dispatch:
-jobs:
- build:
- runs-on: ubuntu-20.04
- permissions:
- packages: write
- contents: read
- steps:
- - uses: actions/checkout@v2
- with:
- ref: ${{ github.event.pull_request.head.sha }}
- fetch-depth: 0
- - uses: pnpm/action-setup@v2.2.1
- - uses: actions/setup-node@v2
- with:
- cache: pnpm
- - uses: DimensionDev/github-token-action@latest
- with:
- registry: true
- - run: pnpm install
- - run: pnpm build
- name: Build solution
- - run: pnpm build
- name: Build provider-proxy Package
- working-directory: packages/provider-proxy
- - run: npm publish
- working-directory: packages/provider-proxy/dist
diff --git a/.i18n-codegen.json b/.i18n-codegen.json
index 6b40857beeb0..2da603920852 100644
--- a/.i18n-codegen.json
+++ b/.i18n-codegen.json
@@ -32,8 +32,7 @@
"type": "i18next/react-hooks",
"hooks": "useSharedI18N",
"namespace": "shared",
- "trans": "SharedTrans",
- "sourceMap": "inline"
+ "trans": "SharedTrans"
}
},
{
@@ -44,8 +43,7 @@
"type": "i18next/react-hooks",
"hooks": "useSharedBaseI18N",
"namespace": "shareBase",
- "trans": "SharedBaseTrans",
- "sourceMap": "inline"
+ "trans": "SharedBaseTrans"
}
},
{
@@ -56,8 +54,7 @@
"type": "i18next/react-hooks",
"hooks": "useDashboardI18N",
"namespace": "dashboard",
- "trans": "DashboardTrans",
- "sourceMap": "inline"
+ "trans": "DashboardTrans"
}
},
{
@@ -68,8 +65,7 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "io.mask.example",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
}
},
{
@@ -80,8 +76,7 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "io.mask.debugger",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
}
},
{
@@ -92,8 +87,7 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "com.maskbook.wallet",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
}
},
{
@@ -104,8 +98,7 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "com.mask.flow",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
}
},
{
@@ -116,8 +109,7 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "com.maskbook.fileservice",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
}
},
{
@@ -128,8 +120,7 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "com.maskbook.cyberconnect",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
}
},
{
@@ -140,8 +131,7 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "bio.rss3",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
}
},
{
@@ -152,8 +142,18 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "money.juicebox",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
+ }
+ },
+ {
+ "input": "./packages/plugins/EVM/src/locales/en-US.json",
+ "output": "./packages/plugins/EVM/src/locales/i18n_generated",
+ "parser": { "type": "i18next", "contextSeparator": "$", "pluralSeparator": "_" },
+ "generator": {
+ "type": "i18next/react-hooks",
+ "hooks": "useI18N",
+ "namespace": "com.mask.evm",
+ "trans": "Translate"
}
},
{
@@ -164,8 +164,7 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "com.maskbook.solana",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
}
},
{
@@ -176,8 +175,7 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "com.mask.next_id",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
}
},
{
@@ -188,8 +186,7 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "__template__",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
}
},
{
@@ -200,8 +197,7 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "io.gopluslabs.security",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
}
},
{
@@ -212,8 +208,18 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "io.mask.cross-chain-bridge",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
+ }
+ },
+ {
+ "input": "./packages/mask/src/plugins/RedPacket/locales/en-US.json",
+ "output": "./packages/mask/src/plugins/RedPacket/locales/i18n_generated",
+ "parser": { "type": "i18next", "contextSeparator": "$", "pluralSeparator": "_" },
+ "generator": {
+ "type": "i18next/react-hooks",
+ "hooks": "useI18N",
+ "namespace": "com.maskbook.red_packet",
+ "trans": "Translate"
}
},
{
@@ -236,8 +242,7 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "com.maskbook.tip",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
}
},
{
@@ -248,8 +253,29 @@
"type": "i18next/react-hooks",
"hooks": "useI18N",
"namespace": "com.maskbook.avatar",
- "trans": "Translate",
- "sourceMap": "inline"
+ "trans": "Translate"
+ }
+ },
+ {
+ "input": "./packages/mask/src/plugins/Trader/locales/en-US.json",
+ "output": "./packages/mask/src/plugins/Trader/locales/i18n_generated",
+ "parser": { "type": "i18next", "contextSeparator": "$", "pluralSeparator": "_" },
+ "generator": {
+ "type": "i18next/react-hooks",
+ "hooks": "useI18N",
+ "namespace": "com.maskbook.trader",
+ "trans": "Translate"
+ }
+ },
+ {
+ "input": "./packages/mask/src/plugins/Gitcoin/locales/en-US.json",
+ "output": "./packages/mask/src/plugins/Gitcoin/locales/i18n_generated",
+ "parser": { "type": "i18next", "contextSeparator": "$", "pluralSeparator": "_" },
+ "generator": {
+ "type": "i18next/react-hooks",
+ "hooks": "useI18N",
+ "namespace": "com.maskbook.gitcoin",
+ "trans": "Translate"
}
},
{
diff --git a/.prettierignore b/.prettierignore
index b3703149f7e7..0f8cab04ff43 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -168,3 +168,7 @@ common/autoinstallers/*/.npmrc
packages/storybook-shared/*.js
packages/storybook-shared/*.map
packages/storybook-shared/*.d.ts
+
+# Requires Prettier support for typescript 4.7
+# https://github.com/prettier/prettier/issues/12640
+packages/web3-shared/base/src/specs/index.ts
diff --git a/cspell.json b/cspell.json
index 5b2abfcf4b11..73ea8057f0bb 100644
--- a/cspell.json
+++ b/cspell.json
@@ -149,6 +149,7 @@
"pressable",
"promi",
"proxied",
+ "portto",
"pushstate",
"pvtsutils",
"qrcode",
@@ -180,6 +181,7 @@
"subrepo",
"sushiswap",
"swappable",
+ "solflare",
"testid",
"thegraph",
"timelock",
@@ -195,6 +197,7 @@
"typechain",
"typehash",
"typeson",
+ "toruslabs",
"unencrypted",
"unreviewed",
"unstake",
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
deleted file mode 100644
index e9c4c414a9c4..000000000000
--- a/docs/ARCHITECTURE.md
+++ /dev/null
@@ -1,53 +0,0 @@
----
-author: Jack-Works
-maintainer:
- - Jack-Works
- - Septs
----
-
-# Mask Network Architecture Overview
-
-![WIP](https://img.shields.io/badge/status-wip-orange.svg?style=flat-square)
-
-> This document describes the Mask Network protocols, the subsystems,
-> the interfaces, and how it all fits together.
-> It delegates non-interface details to other specs as much as possible.
-> This is meant as a top-level view of the protocol and how the system fits together.
-
-## Subsystems
-
-### Background service
-
-The entry point is `packages/mask/src/background-service.ts`
-
-Background service is like a "backend" or "server" in a normal web app.
-It is running on a web page that not visible to the user ([background page in Web Extensions][background-page]).
-The background page hosts mosts of our non-UI-related work in the Mask Network. If you see code like
-
-[background-page]: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#background_scripts
-
-```js
-Services.Crypto.encrypt(...)
-```
-
-It is sending the request to the background service.
-
-### Content scripts
-
-The entry point is `packages/mask/src/content-script.ts`.
-
-All UI on the Twitter/Facebook are rendered by the content scripts.
-
-### Options page (or Dashboard)
-
-The entry point is `packages/mask/src/extension/options-page/index.tsx`.
-
-This is a normal web app that interacts with the background page.
-
-### Injected scripts
-
-The entry point is `packages/mask/src/extension/injected-script/index.ts`.
-
-Generally, you don't need to modify this. It provides the ability to change the main Realm of the web page. (Thus we can emulate some DOM events).
-
-![Architecture overview](https://user-images.githubusercontent.com/5390719/109270562-28f4a700-7849-11eb-9a7a-b364318bdeec.png)
diff --git a/docs/FAQ.md b/docs/FAQ.md
deleted file mode 100644
index 543bef8d0847..000000000000
--- a/docs/FAQ.md
+++ /dev/null
@@ -1,103 +0,0 @@
-# FAQ
-
-## How to resolve merge conflicts in `pnpm-lock.yaml`?
-
-Merge the target branch into yours and never mind those conflicts in `pnpm-lock.yaml`. And checkout the file to be the one on the target branch to revert changes your branch took in. Then run `pnpm install` to up the lockfile to date.
-
-E.g., your `feat/fantasy` branch conflicts with `develop` branch.
-
-```bash
-> git branch --show-current
-feat/fantasy
-
-# merge the develop branch and never manually handle the conflicts in lock file
-> git merge develop
-
-# check out the lock file from the base branch
-> git checkout develop -- pnpm-lock.yaml
-
-# up the lockfile to date
-> pnpm install
-```
-
-## Why my Git hooks don't work?
-
-```bash
-npx husky install # on project root directory
-```
-
-## How to fix cspell errors in CI?
-
-This project uses [cspell](https://github.com/streetsidesoftware/cspell) for checking typos. You can add unlisted words into `cspell.json` to bypass cspell checking. After you update the configuration file, you could run checking locally before pushing it to make sure your patch is working.
-
-```bash
-npx cspell lint pattern_that_match_your_files
-
-# e.g. check spell of the RSS3 plugin
-npx cspell lint ./packages/plugins/RSS3/**/*
-```
-
-Learn more: [`cspell.json`](https://cspell.org/configuration/#cspelljson)
-
-## Why were my components rendered many times?
-
-All components should working in [Strict Mode](https://reactjs.org/docs/strict-mode.html) and React 18 new [Strict Effects](https://github.com/reactwg/react-18/discussions/19).
-
-If you found your code not working correctly, please read the documentation above. In addition, you can comment out `` temporarily to verify if it is a problem with your component not supporting Strict Mode.
-
-DO NOT remove ``.
-
-## How to download CI builds?
-
-| Name | Description |
-| ----------------------------- | ----------------------------------------------------------------------- |
-| MaskNetwork.base.zip | The default build, currently is the same as the Chromium build. |
-| MaskNetwork.chromium-beta.zip | Build for Chromium based browsers with some insider features turned on. |
-| MaskNetwork.chromium.zip | Build for Chromium based browsers |
-| MaskNetwork.firefox.zip | Build for Firefox |
-| MaskNetwork.gecko.zip | Build for Android native Mask app |
-| MaskNetwork.iOS.zip | Build for iOS native Mask app |
-
-You can download these builds in two places.
-
-- Github: Open the pull request page, and click the **Actions** tab. Then on the opened page, click the **build** sub-item on the **Compile** item. On the action detailed page, click the **Summary** tab. Now you can download builds on the **Artifacts** section.
-
- E.g.,
-
-- CircleCI: Open the pull request page, and scroll down to the review status card. Click **Show all checks** to find the **
- ci/circleci: build** item, and click the **details** link. On the opened CircleCI page, click the **ARTIFACTS** tab.
-
- E.g.,
-
-## How to resolve "No CORS Headers" problem
-
-Please contact the service maintainer to add CORS headers, the extension will send requests in following origins:
-
-| Browser | Origin |
-| -------- | --------------------------------------------------- |
-| Chromium | chrome-extension://jkoeaghipilijlahjplgbfiocjhldnap |
-| Firefox | moz-extension://id |
-
-The Chromium extension has a fixed id, but only on production mode. And the Firefox browser will set a new id each time it boots an extension. So, in summary, it's better to allow all origins which match the regexp below.
-
-```txt
-/.*-extension:\/\/[^\S]+/
-```
-
-If you cannot reach the service maintainer another workaround is to use a proxy server to add CORS headers. To enable it try to change the request URL into `https://cors.r2d2.to/?=[url]`.
-
-```ts
-// before
-fetch('https://api.com')
-
-// after
-fetch('https://cors.r2d2.to/?=https://api.com')
-```
-
-## How to clear the local settings?
-
-Open the background.html of the extension and execute the following scripts in the console.
-
-```js
-browser.storage.local.clear()
-```
diff --git a/docs/blockchain-integration.md b/docs/blockchain-integration.md
deleted file mode 100644
index 7b625e76c890..000000000000
--- a/docs/blockchain-integration.md
+++ /dev/null
@@ -1 +0,0 @@
-# Blockchain Integration
diff --git a/docs/bounty-development-guide.md b/docs/bounty-development-guide.md
deleted file mode 100644
index 2e3f8887d93e..000000000000
--- a/docs/bounty-development-guide.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# Bounty Development Guide
-
-Hi, Awesome people! Welcome to start a bounty task on Mask Network.
-
-## Tech Requirements
-
-Mask Network extension is written in TypeScript. The UI is written by React and [@mui](https://mui.com/) framework. We write CSS in [CSS-in-JS](css-in-js.md) style.
-
-We prefer widely adopting tech solutions that include:
-
-- [Web3.js](https://web3js.readthedocs.io/) Ethereum JavaScript API
-- [react-use](https://streamich.github.io/react-use/) React Hooks — 👍
-- [bignumber.js](https://mikemcl.github.io/bignumber.js/) A JavaScript library for arbitrary-precision arithmetic.
-- [lodash](https://lodash.com/docs/) A modern JavaScript utility library delivering modularity, performance & extras.
-- [urlcat](https://urlcat.dev/) A URL builder library for JavaScript.
-
-> If your bounty task is related to another project, it could have extra requirements that need to consider.
-
-If you are familiar with these libraries mentioned above, it will take less effort for you to get started.
-The codebase is open-sourced under the AGPLv3 license.
-
-## Packages
-
-After cloning the repository and [set up the development environment](setup.md). The codebase is constructed as a monorepo with many internal packages. Each package serves a specific purpose. Let's take a quick tour.
-
-### Core Packages
-
-- `packages/mask` The main extension which has multiple websites supports, keeps the user's data safe and hosts a plugin system.
-- `packages/encryption` The encryption & decryption of mask network.
-- `packages/plugin-infra` The definition of the plugin system, with a bunch of APIs to expose the core abilities to plugins.
-
-### Plugin Packages
-
-- `packages/plugins/*` All of integrated plugins.
-
-### Shared Packages
-
-- `packages/shared` Shared UI components and utilities.
-- `packages/shared-base` Shared types, constants, and atomic units. Must be as pure as possible and testable.
-
-### Web3 Packages
-
-- `packages/web3-constants` Each Web3 constant must set up for all known chain IDs.
-- `packages/web3-contracts` EVM contract ABIs and compiled TypeScript definitions.
-- `packages/web3-provider` A hub of APIs for external data source.
-- `packages/web3-shared-*` Shared hooks, utilities, types for each network.
-
-## Learn Through Examples
-
-Almost all bounty tasks for the Mask Network plugin relate to a plugin. After learning the basics, checkout those pull requests or plugins to learn quick from examples.
-
-### Dapp Plugins
-
-| Plugin | Pull Request Links |
-| ----------- | ----------------------------------------------------------------------------------------------- |
-| Collectible | |
-| Trader | |
-| Savings | |
-
-### Network Plugins
-
-| Plugin | Pull Request Links |
-| ---------- | -------------------------------------------------------------------------------------- |
-| EVM Chains | |
-
-## Pull Request Conversions
-
-After bounty hacker opening a pull request. Reviewer will label it with `Type: Bounty`, and update a status tag while the progress on-going.
-
-| Status | Description |
-| ------------------- | ---------------------------------------------------------------------------- |
-| `Bounty: Started` | The DEV team noticed your request. You will receive comments from reviewers. |
-| `Bounty: Reviewed` | The QA team noticed your request. You will receive bugs from reviewers. |
-| `Bounty: Qualified` | Your request is qualifed. It will ship soon. |
diff --git a/docs/concepts.md b/docs/concepts.md
deleted file mode 100644
index 8f2f9615e826..000000000000
--- a/docs/concepts.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Concepts
-
-## Persona
-
-## Post Payload
-
-## Wallet
-
-## Dashboard
-
-## Popup
-
-## SNS Provider
-
-## Wallet Provider
-
-## Plugin
-
-## Network
-
-## ChainId
diff --git a/docs/css-in-js.md b/docs/css-in-js.md
deleted file mode 100644
index d92374225867..000000000000
--- a/docs/css-in-js.md
+++ /dev/null
@@ -1,104 +0,0 @@
----
-author: Jack-Works
-maintainer:
- - Jack-Works
- - Septs
----
-
-# CSS in JS guide in Mask Network
-
-## General guides
-
-- ✅ For recommendations
-- ⚠ For warnings
-- 🚫 For forbidden
-- ✅ Use [the Box component provided by the library](https://next.material-ui.com/components/box/#main-content)
- when the CSS is simple and only used once.
-- ✅ CSS custom variables is OK but do not abuse it.
- Get the variable from the theme if it is possible.
-- ✅ CSS grid is OK but you may want to use the `Grid` component.
- Choose the fit one based on your need.
-- 🚫 DO NOT use mystery abbreviations in the `sx` properties, e.g. ``
- (DON'T) but `` (DO, easier to read).
-
-## Guides on the `makeStyles` style
-
-```ts
-const useStyle = makeStyles()((theme) => ({
- root: { margin: theme.spacing(4) },
-}))
-```
-
-### Change style of MUI components
-
-✅ DO
-
-```js
-
-```
-
-## Guides on the `styled component`
-
-```js
-const Title = style.div`
- display: flex;
-`
-```
-
-### ✅ ⚠ You can use `styled component` in the project
-
-#### 🚫 DO NOT use dynamic styles
-
-```js
-// 🚫 Bad
-const Title = style(Typography)(
- ({ theme }) => `
- margin-left: ${theme.spacing(4)};
-`,
-)
-
-// 🚫 Bad
-const Title = style(Typography)(({ theme }) => ({
- marginLeft: theme.spacing(4),
-}))
-```
-
-### 🚫 Direct selector to the deeper elements of the library
-
-```js
-const Title = style.div`
- & .Mui-Button-root { display: flex; }
-`
-```
-
-DO NOT do this.
-
-Reason: Not type-checked. Easy to get things wrong.
-
-### 🚫 Selector used in the styled component
-
-Please use `makeStyles` in this case.
-
-```js
-const Dialog1 = style(Dialog)`
- & > .Mui-Some-Mui-Selector {}
-`
-```
-
-### ✅ `components` or `*Component` style
-
-Overwriting styles in this way is acceptable.
-
-```js
-const MyExample = styled(Example)`
- /* CSS goes here */
-`
-
-// Use it via:
-
-// Or:
-
-```
-
-⚠ No every component has this kind of API that allowing to overwrite
-the inner component so this method may not be able to use.
diff --git a/docs/dependencies.md b/docs/dependencies.md
deleted file mode 100644
index 788a75dbdae4..000000000000
--- a/docs/dependencies.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Dependencies upgrading
-
-- `@dimensiondev/webextension-shim`: MUST match the version from the iOS side.
-- `@dimensiondev/stego-js`: See
-- `stream-http`: DO NOT upgrade to version 3, it is used as a polyfill in Webpack but version 3 seems breaking.
-- Blockchain related: contact @guanbinrui
-
-Other dependencies
diff --git a/docs/evm-integration.md b/docs/evm-integration.md
deleted file mode 100644
index 33c899b3d298..000000000000
--- a/docs/evm-integration.md
+++ /dev/null
@@ -1,123 +0,0 @@
-# EVM Chain Integration
-
-It's easy to integrate an EVM-compatible chain into Mask Network. After you add a new `ChainId` and `NetworkType` in `packages/web3-shared/evm/types/index.ts`. You can follow the TypeScript compiler. By fixing these errors, the integration progress will keep moving forward. Here is a complete instruction list to ensure you wouldn't miss anything.
-
-## Integration Instructions
-
-### Setup Metadata
-
-- [ ] Add a logo image
- - `packages/mask/src/plugins/EVM/assets/`
-- [ ] Add metadata data
- - `packages/web3-shared/evm/assets/chains.json`
-- [ ] Add an HTTP RPC node
- - `packages/web3-constants/evm/rpc.json`
-- [ ] Set network descriptor
- - `PLUGIN_NETWORKS` in `packages/mask/src/plugins/EVM/constants.ts`
-
-### Setup External APIs
-
-Mask Network fetches on-chain data from various data sources. Therefore, you can configure the identification data of the chain on those providers.
-
-| Provider | Configuration Path |
-| ------------- | ------------------------------------------------ |
-| DeBank | `packages/web3-constants/evm/debank.json` |
-| CoinGecko | `packages/web3-constants/evm/coingecko.json` |
-| CoinMarketCap | `packages/web3-constants/evm/coinmarketcap.json` |
-| Zerion | `packages/web3-constants/evm/zerion.json` |
-
-#### Learn more
-
--
-
-### Web3 Constants Compile Config
-
-Add the chain name to `compileConstants()` in `packages/web3-constants/compile-constants.ts`.
-
-### Token List
-
-The team maintains a token list . So free feel to create one for the chain. And add the token list link to `packages/web3-constants/evm/token-list.json`.
-
-### Token Icon
-
-The token icon could be read from the token list. Or in case of a network problem from a fallback link. Add the fallback links into `packages/web3-constants/evm/token-asset-base-url.json`.
-
-### DEX
-
-Mask Network has integrated Uniswap V2 and Uniswap V3 into the trader plugin. If the DEX of the chain is a fork from them can be easily configured. Learn more: `packages/web3-constants/evm/trader.json`.
-
-For API-based DEX, please ref to how other DEXes integrated:
-
-| DEX | Pull Request Link |
-| --------- | ---------------------------------------------------- |
-| DODO | |
-| OpenOcean | |
-
-### Deploy Contracts
-
-If there is no one deployed [these contracts](https://github.com/DimensionDev/misc_smart_contract) on the chain. Please contact the team.
-
-- [ ] Multicall Contract
-- [ ] BalanceChecker
-- [ ] Other contracts from the Mask team
-
-### Translate JSON-RPC
-
-For a chain that follows a different JSON-RPC protocol with the [Ethereum](https://eth.wiki/json-rpc/API), a transactor is used to `encode` and `decode` each request and make the chain just like an EVM-compatible one.
-
-E.g., the CELO chain can pay the transaction fee with non-native tokens. It supports to use [`feeCurrency`](https://docs.celo.org/celo-codebase/protocol/transactions/erc20-transaction-fees) field to set the token address, which doesn't exist in the original [`eth_sendTransaction`](https://eth.wiki/json-rpc/API#eth_sendtransaction) payload. You can fulfill this requirement by a transactor without altering any JSON-RPC facilities.
-
-```ts
-class CeloTranslator extends Base {
- override encode(context: Context) {
- context.config = {
- ...context.config,
- feeCurrency: '0x0000000000000000000000000000000000000001', // suppose it's a token address
- }
- }
-}
-```
-
-### 🎉
-
-Congratulation! You have done the coding part.
-
-## Testing Checklist
-
-Here is the chain abilities checklist. If you are working on a bounty task, please do each task in list before inviting the team to review your pull request.
-
-- [ ] Check if the asset list and transaction history on the dashboard page work when you choose the chain as the network.
- - Setup the chain for DeBank API.
-- [ ] Check if the trending view is working. Try to hover a new chain token in any tweets.
-
- - Setup the chain for Coingecko API.
- - Setup the chain for CoinMarketCap API.
-
-- [ ] Check if the gas estimate dialog is working.
-
- - Setup the chain for CoinGecko API.
-
-- [ ] Trade with the DEX on the chain.
-
- - Integrate a DEX for the chain.
- - Estimate gas will be showed on DEX card and sort correctly.
-
-- [ ] Send a transaction and check if the explorer links are working.
-
- - Setup metadata and RPC for the chain.
- - Transaction sent to wallet with medium gas fee setting.
- - Required to unlock ERC20 token before swapping ERC20 to any other tokens.
-
-- [ ] Transfer token on the transfer page of Dashboard and the wallet tab of the plugin popup.
-
-## Examples
-
-| Chain | Pull Request Link |
-| --------- | ---------------------------------------------------- |
-| CELO | |
-| Fantom | |
-| xDai | |
-| Arbitrum | |
-| Avalanche | |
-| Harmony | |
-| Moonbeam | |
diff --git a/docs/failed-checklist.md b/docs/failed-checklist.md
deleted file mode 100644
index 437f72e5ad89..000000000000
--- a/docs/failed-checklist.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Checklist
-
-## Build error / Runtime crash
-
-1. Run `npx gulp clean`, Cleanup cache and build files
-
-## CI failed
-
-1. Cannot connect to git@github.com, public key rejected
- 1. Run `npx gulp fix-lockfile`
-
-## I18n strings error
-
-1. Run `npx gulp sync-languages`
-1. Run `npx gulp i18n-codegen`
diff --git a/docs/form-guide.md b/docs/form-guide.md
deleted file mode 100644
index 2186017f0e68..000000000000
--- a/docs/form-guide.md
+++ /dev/null
@@ -1,104 +0,0 @@
-# Form Guide
-
-## General content
-
-We use [`react-hook-form`](https://react-hook-form.com/) and [`zod`](https://github.com/colinhacks/zod#error-formatting) to create the form. Here are the basic steps to create a simple form
-
-### 1. Use `zod` to create form field schema
-
-You can set error message with i18n, you can read this file to learn about [i18n](i18n-guide.md)
-
-```tsx
-import { z as zod } from 'zod'
-
-export function ComponentForm() {
- const t = useComponentI18N() // Set error message with i18n.
- const schema = zod.object({
- name: zod.string(), // string
- age: zod.number(t.needBeNumber()).positive(t.needGreaterThanZero()), // > 0
- country: zod.string(t.countyNeedBeString()).optional(), // string | undefined
- address: zod
- .string()
- .min(1)
- .refine((address) => ValidAddress(address), t.InvalidAddress), // You can use other methods to validate this field
- })
-
- // ...
-}
-```
-
-### 2. Call `useForm` to get the method collection
-
-```tsx
-import { zodResolver } from '@hookform/resolvers/zod'
-import { useForm } from 'react-hook-form'
-
-const methods = useForm({
- resolver: zodResolver(schema),
- defaultValues: {
- name: '',
- age: 1,
- address: '',
- },
-})
-```
-
-`react-hook-form` provides [optional arguments](https://react-hook-form.com/api/useform), you can change it on demand.
-
-### 3. Create form UI with `Controller` and Material-UI component
-
-The `react-hook-form` provides the `Controller` component without import other packages to support UI libraries
-
-```tsx
-const {
- control,
- handleSubmit,
- formState: { errors, dirtyFields, isDirty },
-} = useForm(options)
-
-const onSubmit = handleSubmit((data) => doSomething())
-
-return (
-
-)
-```
-
-## Caveats
-
-### Use `useFormContext` to get methods in children component
-
-In practice, you may need to get form methods in the children component. You can use `useFormContext` and `FormProvider` to resolve this problem.
-
-```tsx
-// Parent component
-const methods = useForm()
-return ....
-
-// Children component
-const { control, register, formState } = useFormContext()
-```
-
-### Set field
-
-Sometimes we need set some field from remote data. You can use `setValue` to change these field. If you want to trigger valid while setting the field, you can add the `shouldValid` option
-
-```tsx
-const { watch, setValue } = useForm()
-
-// You can use watch to monitor some field change
-const address = watch('address')
-useEffect(() => {
- const { symbol } = fetchDataByAddress(address)
- setValue('symbol', symbol, { shouldValid: true })
-}, [address])
-```
-
-### Be careful with watch
-
-Sometimes we need to listen to the field update to do something. Although you can use `watch` to react to a field. But it will cause extra renders and cause a potential performance problem. Try to use `getValues` if that suits you.
diff --git a/docs/i18n-guide.md b/docs/i18n-guide.md
deleted file mode 100644
index 25a41f69ee7d..000000000000
--- a/docs/i18n-guide.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# Internationalization Guide (i18n guide)
-
-[![Crowdin](https://badges.crowdin.net/mask-network/localized.svg)](https://crowdin.com/project/mask-network)
-
-> We're currently not accepting new language support in Mask Network.
-
-## Submit community translation
-
-Welcome to or you can join our [Discord server](https://discord.gg/4SVXvj7)
-
-## Caveats
-
-1. We using [ISO 639-1][iso-639-1] two-letter code for locale file names.
-
-2. Add a new language new support
-
- Please send to [Discord server](https://discord.gg/4SVXvj7) - `idea` channel
-
-3. When add a new i18n text, add English version only,
- leave the rest to professional translators
-
-[iso-639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
diff --git a/docs/local-or-remote-dialog.md b/docs/local-or-remote-dialog.md
deleted file mode 100644
index 18ae0e6167f5..000000000000
--- a/docs/local-or-remote-dialog.md
+++ /dev/null
@@ -1,71 +0,0 @@
----
-author: zhouhancheng
-maintainer:
- - zhouhancheng
----
-
-# Local Dialog vs Remote Dialog
-
-## What is remote-dialog
-
-```ts
-function useRemoteControlledDialog<
- T extends {
- open: boolean
- },
->(
- event: UnboundedRegistry,
- onUpdateByRemote?: ((ev: T) => void) | undefined,
- tabType?: 'self' | 'activated',
-): readonly [boolean, (ev: T) => void]
-```
-
-`remote-dialog` serves a special universal scene.
-
-e.g: Ethereum transaction state track dialog, Select wallet dialog, they are used at lot of places.
-
-It is a global singleton:
-
-```tsx
-export const EthereumPluginDefine: PluginConfig = {
- PageComponent() {
- return
- },
-}
-```
-
-## What is local-dialog
-
-`local-dialog` serves for detailed business logic.
-Its props provided by parent component,
-since it is part of the detailed business actually,
-its code located under the parent component which open/close it.
-
-```tsx
-
- //...
- setOpen(false)}
- choiceText={choices[choice - 1]}
- message={message}
- power={power}
- onVoteConfirm={onVoteConfirm}
- />
-
-```
-
-## When not to use remote-dialog
-
-1. If you render `remote-dialog` under twitter timeline payload post component.
- As you click the open dialog button, you will find several dialogs would be opened,
- because each instance has been loaded
- when there're multiple payload posts at the timeline and are listening to the open dialog event.
-
-2. `remote-dialog` loads in advance, usually it only loads once after the web page loads,
- which leads to that data returned by its network request hooks isn't the latest.
- Even a dialog is not rendered under on timeline,
- there's only one instance rendered at the same time.
- If you want it to fetch the latest network data each time when you open it,
- consider using `local-dialog`.
diff --git a/docs/mask-flavored-jsonrpc-api.md b/docs/mask-flavored-jsonrpc-api.md
deleted file mode 100644
index 0403bdebfe94..000000000000
--- a/docs/mask-flavored-jsonrpc-api.md
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-# Mask Flavored JSON RPC API
-
-## Transaction
-
-### `mask_watchTransaction`
-
-Periodically retrieve the transaction receipt and cache the result in the background.
-
-> Note: The [`eth_getTransactionReceipt`](https://eth.wiki/json-rpc/API#eth_gettransactionreceipt) will read receipt from the cache instead of the RPC provider. If you really need the instant receipt you should use `mask_getTransactionReceipt`.
-
-#### Parameters
-
-- `string` the hash of transaction
-- `config` the transaction config object. Learn more: [`eth_sendTransaction`](https://eth.wiki/json-rpc/API#eth_sendtransaction).
-
-#### Returns
-
-- `void`
-
-### `mask_unwatchTransaction`
-
-Stop watching a transaction. It means invoke [`eth_getTransactionReceipt`](https://eth.wiki/json-rpc/API#eth_gettransactionreceipt) with the given hash will always return `null`.
-
-#### Parameters
-
-- `string` the hash of transaction
-
-#### Returns
-
-- `void`
-
-### `mask_getTransactionReceipt`
-
-The non-hijacked version of [`eth_getTransactionReceipt`](https://eth.wiki/json-rpc/API#eth_gettransactionreceipt).
-
-### `mask_replaceTransaction`
-
-Replace a transaction with the given one.
-
-#### Parameters
-
-- `string` the hash of the transaction to be replaced
-- `config` the transaction config object. Learn more: [`eth_sendTransaction`](https://eth.wiki/json-rpc/API#eth_sendtransaction).
-
-#### Returns
-
-- `void`
-
-### `mask_cancelTransaction`
-
-Cancel the given transaction.
-
-#### Parameters
-
-- `string` the hash of the transaction to be canceled
-- `config` the transaction config object. Learn more: [`eth_sendTransaction`](https://eth.wiki/json-rpc/API#eth_sendtransaction).
-
-#### Returns
-
-- `void`
-
-### `mask_confirmTransaction`
-
-Confirm to send a risk transaction.
-
-#### Parameters
-
-- `void`
-
-#### Returns
-
-- `void`
-
-### `mask_rejectTransaction`
-
-Reject to send a risk transaction.
-
-#### Parameters
-
-- `void`
-
-#### Returns
-
-- `void`
-
-## Wallet
-
-### `mask_requestAccounts`
-
-Connect to any wallet on the back of Mask Network.
-
-#### Parameters
-
-- `number` or `void` the chain id of the expected chain
-- `string` or `void` the network id of the expected chain (`NetworkPluginID`)
-
-#### Returns
-
-- `void`
-
-### `mask_dismissAccounts`
-
-Disconnect with the connected wallet.
-
-#### Parameters
-
-- `void`
-
-#### Returns
-
-- `void`
diff --git a/docs/npm-scope.md b/docs/npm-scope.md
deleted file mode 100644
index 95120ca31878..000000000000
--- a/docs/npm-scope.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# npm scope
-
-We controlled the following npm scope by [@yisiliu](https://github.com/yisiliu)
-
--
--
--
--
--
diff --git a/docs/payload-format/payload-container.md b/docs/payload-format/payload-container.md
deleted file mode 100644
index 2101fe8f7a84..000000000000
--- a/docs/payload-format/payload-container.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# `PayloadContainer`
-
-> Status: This format has not been shipped to production yet. It might change at any time.
-
-## Abstract
-
-This is a simple binary format that describes a binary message and its signature (optionally).
-
-It is used in the encryption of Mask Network.
-
-## Format
-
-The 0th byte is a switch. The interpretation of the rest part depends on the 0th byte.
-
-### 0th byte is `0x00`
-
-If the payload length is less than 33 bytes, it is invalid.
-
-- Byte 1 to 32 is the `SHA-256` hash of the `message`.
-- Byte 33 to the end is the `message`.
-
-### 0th byte is `0x01`
-
-- Byte 1 to the end is the `message`.
-
-### 0th-byte other value
-
-It's an invalid payload.
-
-## Next step
-
-Once you parsed the `message` out as a binary, you should further try to parse the `message` as a [Payload37](./payload-v37.md) object.
diff --git a/docs/payload-format/payload-v37.md b/docs/payload-format/payload-v37.md
deleted file mode 100644
index 3846bdf00741..000000000000
--- a/docs/payload-format/payload-v37.md
+++ /dev/null
@@ -1,189 +0,0 @@
-# Payload version -37
-
-> Status: This format has not been shipped to production yet. It might change at any time.
-
-## Abstract
-
-This is a binary format that is used to represent an encrypted message in the Mask Network.
-
-The implementor SHOULD implement a tolerate parser for the payload.
-
-## Encoding
-
-To avoid reinvention of a new binary format that is hard to parse/generate, this specification chooses to represent data in the [MessagePack][msgpack-spec] binary format.
-
-Type `Integer`, `Float`, `Nil`, `Boolean`, `String`, `Binary`, `Array` and `Map` are defined in the [msgpack specification][msgpack-spec]. Other type defined in this RFC is written in the TypeScript syntax.
-
-To avoid encoding field names into the binary (which is space-wasting), this RFC chooses to use a tuple (represented by `Array` in MessagePack), in which the order of the fields represented its meaning.
-
-In extra, we define the following helper types:
-
-```typescript
-type Number = Integer | Float
-type Any = Integer | Nil | Boolean | Float | String | Binary | Array | Map
-```
-
-In this specification, any form of MessagePack extension (like a timestamp) is NOT used. An implementation MAY treat data including extensions as invalid.
-
-`Array` in this specification is used as `Tuple` with an arbitrary size, which means items in the Array don't have to be the same type.
-
-> e.g. both `[1, "string"]` and `["string", 1]` are valid `Array`s that has the type `Array`.
-> But if the order is meaningful, the type should be `[Integer, String]`.
-
-All Tuple in this specification MUST be treated as non-fixed length. This means `[1, "string", true]` is valid when `[Integer, String]` is required. An implementation MUST NOT fail due to the extra item unless especially specified.
-
-### `Payload37`
-
-```typescript
-type PayloadAlpha37 = [
- version: Integer,
- authorNetwork: String | SocialNetworkEnum | Nil,
- authorID: String | Nil,
- authorPublicKeyAlgorithm: String | PublicKeyAlgorithmEnum,
- authorPublicKey: Binary | Nil,
- encryption: Encryption,
- data: Binary,
-]
-enum SocialNetworkEnum {
- Facebook = 0,
- Twitter = 1,
- Instagram = 2,
- Minds = 3,
-}
-enum PublicKeyAlgorithmEnum {
- ed25519 = 0,
- secp256p1 = 1, // P-256
- secp256k1 = 2, // K-256
-}
-```
-
-#### `version` field
-
-This field represents the format version.
-
-The first and the current binary version is `0`.
-
-#### `authorNetwork` field
-
-This field represents the social network that the author of this payload belongs to.
-
-When it is `SocialNetworkEnum`, it represents a SocialNetwork that is supported by the Mask Network.
-
-When it is `String`, it represents a SocialNetwork cannot be expressed within the enum. e.g. A decentralized SNS like Mastodon.
-
-When it is `Nil`, it represents no information is available (due to software defeat or user choice to opt out).
-
-#### `authorID` field
-
-This field represents the identifiable ID of the author of this payload `Nil`.
-
-When it is `Nil`, it represents no information is available (due to software defeat or user choice to opt out).
-
-#### `authorPublicKeyAlgorithm` field
-
-This field represents the algorithm that the public key is using.
-
-When it is `PublicKeyAlgorithmEnum`, it represents a well-known asymmetric algorithm.
-
-When it is `String`, it represents an asymmetric algorithm that is not covered in this specification.
-
-The implementation MUST NOT fail if the algorithm is not supported.
-
-#### `authorPublicKey` field
-
-This field represents the public key of the author.
-
-The value is in the compressed format of the EC key.
-
-> TODO: clarify "compressed" format
-
-When it is `Nil`, it represents no information is available (due to software defeat or user choice to opt out).
-
-#### `encryption` field
-
-This field represents how this payload is encrypted. There are two types of encryption, `PublicEncrypted` and `PeerToPeerEncrypted`
-
-```typescript
-type Encryption = PublicEncrypted | PeerToPeerEncrypted
-enum EncryptionKind {
- Public = 0,
- PeerToPeer = 1,
-}
-```
-
-The `Encryption` type is a tagged Tuple (the first item is the tag).
-
-##### `PublicEncrypted`
-
-This type represents this payload is encrypted, but the AES key is shared with everyone (and encoded in the payload).
-
-This means the message is NOT privately encrypted.
-
-```typescript
-type PublicEncrypted = [
- //
- kind: EncryptionKind.Public,
- AES_KEY: Binary,
- iv: Binary,
-]
-```
-
-###### `AES_KEY`
-
-This field represents the raw AES-256-GCM key of this payload.
-
-###### `iv` field
-
-This field represents the iv used to encrypt the message.
-
-##### `PeerToPeerEncrypted`
-
-```typescript
-type PeerToPeerEncrypted = [
- kind: EncryptionKind.PeerToPeer,
- ownerAESKeyEncrypted: Binary,
- iv: Binary,
- authorEphemeralPublicKey: Map,
-]
-```
-
-###### `ownerAESKeyEncrypted` field
-
-This field represents an encrypted AES key of this payload that is encrypted with the author's public key via ECDH.
-
-###### `authorEphemeralPublicKey` field
-
-This field is a Map of the compressed format of the EC key.
-
-> TODO: clarify "compressed" format
-
-The key indicates its format.
-
-The implementation MUST NOT fail when an unknown key appears.
-
-The implementation MUST ignore the invalid key for the given public key format.
-
-This field is used to support ephemeral encryption with different curves.
-
-#### `data` field
-
-This field represents the encrypted result of a [TypedMessage binary format](./typed-message.md).
-
-## References
-
-- secp256k1:
-- [MessagePack][msgpack-spec]
-
-[msgpack-spec]: https://github.com/msgpack/msgpack/blob/master/spec.md
-
-## Next step
-
-Once you parsed the `Payload37`, you should use the information in the payload to decrypt the message.
-
-Once the message is decrypted, you should parse the message by [the TypedMessage spec](./typed-message.md).
-
-## FAQ
-
-### Why the version number is negative?
-
-The pre 1.0 version of the Mask Network extension uses `-42` as its initial payload version. The number `42` comes from the book _The Hitchhiker's Guide to the Galaxy_ and the minus sign indicates this is an early version. When a new payload format is drafted, it's a natural idea that the version number should add by 1, therefore it should be `-41`. At the time of this spec written, the latest payload is version `-38`, therefore this spec follows the convention to mark the version as `-37`.
diff --git a/docs/payload-format/typed-message.md b/docs/payload-format/typed-message.md
deleted file mode 100644
index a50fc8a8bffd..000000000000
--- a/docs/payload-format/typed-message.md
+++ /dev/null
@@ -1,121 +0,0 @@
-# TypedMessage binary format
-
-
-
-> Status: This format has not been shipped to production yet. It might change at any time.
-
-## Abstract
-
-This is a binary format that is used to represent a rich document (text, images, ...etc).
-
-## Encoding
-
-Following the [encoding convention of Payload37](./payload-v37.md#encoding).
-
-### `Document` type
-
-This is the top-most data type.
-
-```typescript
-type Document = [version: Integer, ...Any]
-```
-
-- When `version` is `0`:
- - This is a `TypedMessageText`.
- - It should be parsed in the following way:
-
-```typescript
-type Document = [version: 0, text: String, meta?: Map | Nil]
-```
-
-- When `version` is `1`:
- - The rest of the fields are `TypedMessage`.
- - It should be parsed in the following way:
-
-```typescript
-type Document = [version: 1, ...TypedMessage]
-
-function parse(doc: Array) {
- // drop the version field, and treat the rest as a TypedMessage
- if (doc[0] === 1) return parseTypedMessage(doc.slice(1))
-}
-```
-
-### `TypedMessage`
-
-All `TypedMessage` must start with the following fields:
-
-```typescript
-type TypedMessageBase = [
- type: TypedMessageTypeEnum | String,
- version: Integer,
- metadata: Map | Nil,
- ...rest: Array,
-]
-enum TypedMessageTypeEnum {
- Tuple = 0,
- Text = 1,
-}
-```
-
-#### `type` field
-
-This field represents the type of this TypedMessage.
-
-It is a `TypedMessageTypeEnum` or a UTF-8 string.
-
-When it is `TypedMessageTypeEnum`, it represents a well-known TypedMessage defined in this specification.
-
-When it is a `String`, it represents a custom extension of TypedMessage.
-
-An implementation MAY ignore an unknown type or render a hint.
-
-#### `version`
-
-This field represents the version of this TypedMessage contains.
-
-#### `metadata`
-
-This field represents the metadata this TypedMessage contains.
-
-An implementation MUST NOT assume the data structure inside the metadata.
-
-### `TypedMessageText`
-
-```typescript
-type TypedMessageText = [
- //
- type: TypedMessageTypeEnum.Text,
- metadata: Map | Nil,
- content: String,
- textFormat?: TextFormat,
-]
-enum TextFormat {
- PlainText = 0,
- Markdown = 1,
-}
-```
-
-#### `content` field
-
-This field represents a text message. The interpretation of content depends on the `textFormat` field.
-
-#### `textFormat` field
-
-This is an optional field that represents the interpretation of the `content` field.
-
-`PlainText` means it is plain text.
-
-`Markdown` means it is a Markdown. The Markdown flavor is not specified so the rendering effect might be different depending on the library.
-
-When decoding, the lack of content field should be treated as `TextFormat.PlainText`
-
-### `TypedMessageTuple`
-
-```typescript
-type TypedMessageTuple = [
- type: TypedMessageTypeEnum.Tuple
- metadata: Map | Nil,
- items: Array,
-]
-```
diff --git a/docs/plugin-development-guide.md b/docs/plugin-development-guide.md
deleted file mode 100644
index 42c2ef8676cc..000000000000
--- a/docs/plugin-development-guide.md
+++ /dev/null
@@ -1,92 +0,0 @@
----
-author: Jack-Works
-maintainer:
- - Jack-Works
- - Septs
----
-
-# Plugin Development Guide
-
-## Run
-
-> npx gulp new-pkg
-
-To create a new plugin
-
-## Minimum File Structure
-
-The following folder is automatically created by the command above.
-
-```plaintext
-packages/mask/src/plugins/{your-plugin-name}
-├── README.md # see `README driven development`
-├── index.ts # Plugin registration
-├── base.ts # Basic definition of a plugin
-├── constants.ts # Constant definition, e.g: api end-point, etc
-├── types.ts # Provide common typing definitions
-├── SNSAdaptor/index.ts # (Optional) Provide SNSAdaptor part of the plugin
-├── Dashboard/index.ts # (Optional) Provide Dashboard part of the plugin
-├── Worker/index.ts # (Optional) Provide Worker part of the plugin
-└── utils.ts # Provide common utils function
-```
-
-## About `README.md` file
-
-see [README driven development](https://tom.preston-werner.com/2010/08/23/readme-driven-development.html)
-
-The file need to provide this information:
-
-- Feature-set as TODOs
-- Reference resource list
-- Known issues / Caveats
-
-## Plugin APIs
-
-- Plugin definition: `packages/plugin-infra/src/types.ts`
-- Database: `context.getDatabaseStorage()` (2nd parameter of the `init` method of your `Worker` definition). See example in `packages/plugins/example/src/Worker/index.ts`.
-- Message emitter: `createPluginMessage` exported from `@masknet/plugin-infra`
-- RPC: `createPluginRPC` exported from `@masknet/plugin-infra`
-- Metadata reader: `createTypedMessageMetadataReader` in `@masknet/shared-base`
-- React renderer with metadata reader: `createRenderWithMetadata` in `@masknet/shared-base`
-
-## Architecture
-
-The extension we talk about here is a bunch of code compiled and running in the Mask Network extension.
-This plugin system is for decoupling purposes.
-It doesn't allow load the new plugin dynamically without compiling the whole extension from the source code.
-If you're looking for a dynamic plugin system,
-you're probably looking for [External plugin][external-plugin] that still in the very early stage.
-
-[external-plugin]: https://github.com/DimensionDev/Maskbook/pull/2621
-
-### Plugin state
-
-- _Registered_, the default state. The plugin has been registered in the plug-in registry.
-- _Loaded_, the deferred definition of the plugin has been loaded.
-- _Activated_, the plugin is activated in the current context.
-
-State transition:
-
-- _Registered_ => _Loaded_
-- _Loaded_ => _Activated_ (enable/start the plugin)
-- _Activated_ => _Loaded_ (disable the plugin)
-
-## Metadata guide
-
-Metadata is JSON compatible data that's can be inserted into a post.
-
-The most common use case of the metadata is the following.
-
-Add a new entry in the composition dialogue, therefore,
-the user can interact with your plugin. When it's finished,
-you can insert your metadata into the post and it will be contained in the encrypted payload.
-When you see metadata in the post payload,
-you should render some UI to reveal the information in the metadata and allow the user to interact with it.
-
-Notice please treat the metadata you received as non trustable data,
-make sure you have validated the formats and the data range.
-We provided a utility to read the data from the post and validate it with JSON schema.
-
-## Form guide
-
-If you want to create a form in your plugin, please follow [Form guide](form-guide.md)
diff --git a/docs/plugin-development-quickstart.md b/docs/plugin-development-quickstart.md
deleted file mode 100644
index f547d25093ec..000000000000
--- a/docs/plugin-development-quickstart.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-author: Randolph
----
-
-# Quick start for Plugin Development
-
-## 1. Start a plugin file
-
-input following code to start a plugin file
-
-> npx gulp new-pkg
-
-...(a brief introduction about the files generated)
-
-## 2. How to inject ui
-
-1. change definitions in SNSAdaptor to add entry
-2. what is metadata and how to decode and encode metadata
- if we want to inject ui in a post, we need metadata that contains related information
-3. write ui by our component
-
-## 3. How to interact with worker
-
-1. how to write Service to manage data
-2. a brief introduction about backend page
-
-## 4. How to interact with blockchain
-
-1. how to send a transaction
-2. how to get data stored in the blockchain
-3. a brief introduction about transaction process
diff --git a/docs/setup.md b/docs/setup.md
deleted file mode 100644
index 680a4b983d4f..000000000000
--- a/docs/setup.md
+++ /dev/null
@@ -1,104 +0,0 @@
-# Setup
-
-Hi, Welcome to the Mask Network. This guide will quickly take you through setting up the extension development environment.
-
-## Requirements
-
-Here is a snippet of engines requirements in the [`package.json`](../package.json) of Mask Network. As you can see, `NodeJS` and `pnpm` are required at least a specific version.
-
-We suggest you to use the latest Node.js version, and enable [corepack](https://nodejs.org/api/corepack.html).
-
-## Install
-
-### pnpm
-
-The [pnpm](https://pnpm.io/) is a disk space-efficient package manager. After NodeJS is preinstalled.
-
-If you have [corepack](https://nodejs.org/api/corepack.html) enabled, you can skip the `pnpm` section, `pnpm` is already available!
-
-If you want to setup pnpm manually, here is the [installation guide from pnpm](https://pnpm.io/installation).
-
-Now, you will need to have tools installed to start development.
-
-```bash
-pnpm install
-```
-
-> If you encounter with error `EACCES: permission denied, open...'`, please run `chown -R $USER /pathToYourProject/Mask` to solve.
-
-### Start the local development server
-
-For Chromium-based browsers (Chrome, Opera, Edge, etc.), please run `pnpm start`. It's preset of many development commands.
-
-If you need to develop in other environments (for example, Firefox), please run `npx dev --help` to see the documentation.
-
-### Load the extension into your browser
-
-Mask Network has a huge codebase, and it might take time to let the webpack fully startup. It outcomes the `dist/` folder, which contains the unpacked source files of a development version of the Mask Network extension.
-
-For Chrome,
-
-- Open `chrome://extensions` or `Settings -> Extensions`.
-- Turn on the `Developer mode` on the top right corner.
-- It will present a top toolbar with an action button `Load unpacked` on it. Click it and choose the `dist/` folder to load the unpacked version of the Mask Network extension. You can drag and drop the `dist` folder into this page.
-- If everything goes fine. Then, the Mask Network will guide you to the setup process.
-
-For Firefox, it's quite the same process.
-
-- Open `about:debugging#/runtime/this-firefox`
-- Click the `Load Temporary Add-on…` and select the `dist/` folder to load the unpacked extension.
-- If everything goes fine. The Mask Network will start to guide you to the setup process.
-
-## Debugging
-
-There is no difference between extension development and normal web development. In normal web development, you only have a single web page (SPA), but an extension could have more than one page.
-
-There is an invisible "background page" running all the time and an "options page" like a normal web page. Moreover, an extension could inject "content script" into the currently visiting web page.
-
-### Debug the background page
-
-The background page of the Mask Network extension maintains a bunch of fundamental services for front-end functions. Like Crypto Algorithm, Web3 SDKs, APIs to many third-party data providers, etc. They are stand-by all the time, once to be called for a specific task.
-
-To debug _background service_, click links right after **Inspect views**.
-
-![An image displaying Chrome extension manage page](https://user-images.githubusercontent.com/5390719/103509131-5ce0cb00-4e9d-11eb-9aec-b24b9888b863.png)
-
-### Debug the content script
-
-Mask Network only injects content script with permission from the user.
-
-For every new website that Mask Network is going to support, it will show a prompt dialog to ask permission dynamically, rather than asking for all permission when the plugin is installed.
-
-![An image displaying the Mask Network is asking the permission from the user](https://user-images.githubusercontent.com/52657989/158566232-30c52a17-0168-488c-a292-4fc4059ecb9c.png)
-
-To debug _content script_, open the dev tools in the web page, then you can select context as the following picture describes.
-
-![An image displaying how to select Mask Network as the debug context](https://user-images.githubusercontent.com/5390719/103509436-1a6bbe00-4e9e-11eb-9b18-bde021337944.png)
-
-It's important to select the correct context when you're debugging,
-otherwise, you cannot access all the global variables,
-_save as temp variables_ also fails.
-
-### Use React Devtools
-
-Run the following command to start the React Devtools. It doesn't work if you install it as a browser extension.
-
-> pnpx react-devtools
-
-And start the development by the following command:
-
-> pnpx dev --profile
-
-## Contribute your working
-
-### Git conversions
-
-The `develop` branch is our developing branch, and the `released` branch points to the latest released version.
-
-Your commit message should follow [Conventional Commits](https://www.conventionalcommits.org).
-
-### Using Git
-
-- [Using git rebase on the command line](https://docs.github.com/en/github/getting-started-with-github/using-git-rebase-on-the-command-line)
-- [Configuring a remote for a fork](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/configuring-a-remote-for-a-fork)
-- [Syncing a fork](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests)
diff --git a/docs/toc.md b/docs/toc.md
deleted file mode 100644
index f7c90098a1f4..000000000000
--- a/docs/toc.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# TOC
-
-## Quick Start
-
-## Setup
-
-[setup](./setup.md)
-
-## Concepts
-
-- Persona
-- Post Payload
-- Wallet
-- Dashboard
-- Pop up
-- SNS Provider
-- Wallet Provider
-- Plugin
-- Network (Network as Plugin)
-- ChainID
-
-## Guides
-
-- [Bounty Development Guide](./bounty-development-guide.md)
-- [Plugin Development Guide](./plugin-development-guide.md)
-- Website Integration Guide
-- Blockchain Integration Guide
-- [Wallet Integration Guide](./wallet-integration.md)
-- i18n
-- Form Guide
-
-## UI Components
-
-- shared
-- Mask Icons
-
-## Ecosystem
-
-- [MaskBox](https://box.mask.io/)
-- [MaskBridge](http://bridge.mask.io/)
-
-## Reference
-
-- TypedMessage
-- [Mask Flavored EVM JSON RPC methods](./mask-flavored-jsonrpc-api.md)
-- @mask/plugin-infra
-- @mask/web3-constants
-- @mask/web3-contracts
-- @mask/web3-shared
-- @mask/web3-providers
-
-## FAQ
-
-- Why there are two plugins folder in the codebase?
-- How to bypass the CSP constraint?
-- Help! My API server doesn’t return a CORS header.
-- How to read and clean my local settings?
-- How to fix cspell errors?
-- How to close react strict mode?
diff --git a/docs/wallet-integration.md b/docs/wallet-integration.md
deleted file mode 100644
index fafa581c988e..000000000000
--- a/docs/wallet-integration.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Wallet Integration
-
-Any wallet available in a browser environment can integrate into Mask Network. Well know wallets like [MetaMask](https://metamask.io/), [WalletConnect](https://docs.walletconnect.com/) and [Fortmatic](https://fortmatic.com/) have already been integrated. Besides that, Mask Network is also able to host accounts by itself.
-
-## Overview
-
-```txt
- Front End Page Background Page
-+------------------+ +-----------------+
-| User | - Messaging API ---------- | RPC Composer |
-+------------------+ +-----------------+
- | |
-+------------------+ +-----------------+ +-----------------+
-| Bridge Component | - Event Emitter-- | Other Wallets | | Mask Wallet |
-+------------------+ +-----------------+ +-----------------+
- | |
-+------------------+ |
-| Wallet SDK | |
-+------------------+ |
- | |
- +------------------------- Network --------------------------+
-```
-
-Above is an architecture overview illustrating how Mask Network integrates multiple wallets simultaneously. Roughly speaking, it includes two parts: the bridge component on the front end, and the JSON-RPC composer on the background end. They communicate with each other by leveraging the [Messaging Passing API](https://developer.chrome.com/docs/extensions/mv3/messaging/).
-
-As a quick example to let you know how all stuff spins. Here is a UI button that will emit an `eth_getBlockNumber` request once it is clicked.
-
-```tsx
-import { useWeb3 } from '@masknet/web3-shared-evm'
-
-function Example() {
- const web3 = useWeb3()
- const onClick = useCallback(async () => {
- const blockNumber = await web3.eth.getBlockNumber()
- console.log(`The current block number is ${blockNumber}.`)
- }, [web3])
- return
-}
-```
-
-First of all, it creates a [Web3](https://web3js.readthedocs.io/) instance which redirects all JSON-RPC requests to the [request](https://github.com/DimensionDev/Maskbook/blob/develop/packages/mask/src/extension/background-script/EthereumServices/request.ts) service on the background page. If you'd like to read the source code, you will realise that there is a [Koa.js](https://koajs.com/) styled [composer](https://github.com/koajs/compose) built-in. A list of middleware is used and serve different purposes: a middleware stores transactions into DB, a middleware watches transaction status, a middleware notifies transaction progress, and so on.
-
-At the current stage, there are two kinds of wallets: Mask Wallet and other wallets.
-
-Mask Wallet sends requests to the network directly on the background page. If the request takes the response, then the user will get notified.
-
-But it's not that simple for other wallets. They are supported only on the front end. E.g., the [Fortmatic](https://docs.fortmatic.com/) SDK injects an iframe on the currently visiting page. Mask Network cannot invoke those SDKs on the background page as an extension. Because of that, they should take their requests to the front end and handle them there. Many mounted components, so-called `ProviderBridge`, listen to the `PROVIDER_RPC_REQUEST` event and call the corresponding SDK once they receive any request from the background. After the SKD finishes the work, they return the result to the bridged provider on the background page with the `PROVIDER_RPC_RESPONSE` event.
-
-It takes a quite long detour, but the benefit is all requests can leverage Mask Wallet abilities.
-
-## A Wallet on a bridged provider
-
-If the wallet that only works on the front end. It needs to use the bridged provider way.
-
-On the front end:
-
-- create a bridged provider by implementing the [`EIP1193Provider`](https://github.com/DimensionDev/Maskbook/blob/develop/packages/web3-shared/evm/types/index.ts) interface.
-- instantiate the bridged provider in [useBridgedProvider](https://github.com/DimensionDev/Maskbook/blob/develop/packages/mask/src/plugins/EVM/hooks/useBridgedProvider.ts) which was used by [``](https://github.com/DimensionDev/Maskbook/blob/develop/packages/mask/src/plugins/EVM/UI/components/ProviderBridge.tsx).
-- add a new `` in the [EVM](https://github.com/DimensionDev/Maskbook/blob/develop/packages/mask/src/plugins/EVM/UI/SNSAdaptor/index.tsx) plugin to receive events from the background page.
-
-On the background page:
-
-- instantiate a [BridgedProvider](https://github.com/DimensionDev/Maskbook/blob/develop/packages/mask/src/extension/background-script/EthereumServices/providers/Bridged.ts) and add it into the supported list in [getProvider](https://github.com/DimensionDev/Maskbook/blob/develop/packages/mask/src/extension/background-script/EthereumServices/provider.ts).
-
-## A wallet without any UI
-
-If the wallet is totally UI free and can connect/disconnect by calling some APIs. It can send requests to those APIs directly.
-
-On the background page:
-
-- create a provider to extend from the [BaseProvider](https://github.com/DimensionDev/Maskbook/blob/develop/packages/mask/src/extension/background-script/EthereumServices/providers/MaskWallet.ts) interface and add it into the supported list in [getProvider](https://github.com/DimensionDev/Maskbook/blob/develop/packages/mask/src/extension/background-script/EthereumServices/provider.ts).
-
-## Interceptor
-
-The implementation of Ethereum JSON-RPC may very different between wallets. Those JSON-RPC requests will need some preprocessing before sending to the real wallet. Nevertheless, the Mask Network flavors a bunch of self-known RPC methods that were unknown to other wallets. Bypassing a such request will hit an unimplemented error.
-
-
-
-For this sake, the [`composer`](https://github.com/DimensionDev/Maskbook/blob/develop/packages/mask/src/extension/background-script/EthereumServices/composer.ts) creates a middleware for intercepting JSON-RPC requests. Here is a quick example that converts the Mask Network flavored [`mask_requestAccounts`](./mask-flavored-**jsonrpc**-api.md#mask_requestaccounts) into an Ethereum styled [`eth_accounts`](https://eth.wiki/json-rpc/API#eth_accounts).
-
-```ts
-export class Example implements Middleware {
- async fn(context: Context, next: () => Promise) {
- switch (context.method) {
- case EthereumMethodType.MASK_REQUEST_ACCOUNTS:
- context.requestArguments = {
- ...context.requestArguments,
- method: EthereumMethodType.ETH_ACCOUNTS,
- }
- break
- default:
- break
- }
- await next()
- }
-}
-```
-
-## Examples
-
-| Wallet | Implementation |
-| ------------- | -------------- |
-| MetaMask | \- |
-| WalletConnect | \- |
-| Fortmatic | \- |
diff --git a/package.json b/package.json
index 627d5fa00fad..634ec7a4ab43 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,7 @@
"spellcheck": "cspell lint --no-must-find-files"
},
"dependencies": {
- "@dimensiondev/kit": "0.0.0-20220228054820-f2378be",
+ "@dimensiondev/kit": "0.0.0-20220501022859-60d5533",
"@emotion/cache": "^11.7.1",
"@emotion/react": "^11.9.0",
"@emotion/serialize": "^1.0.3",
diff --git a/packages/.eslintrc.json b/packages/.eslintrc.json
index a06fafd88039..7654e02a4c00 100644
--- a/packages/.eslintrc.json
+++ b/packages/.eslintrc.json
@@ -83,6 +83,7 @@
"@dimensiondev/type/no-instanceof-wrapper": "error",
"@dimensiondev/type/no-wrapper-type-reference": "error",
"@dimensiondev/unicode/specific-set": "error",
+ "@typescript-eslint/array-type": ["error", { "default": "array-simple" }],
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/no-base-to-string": "off",
"@typescript-eslint/no-implied-eval": "error",
diff --git a/packages/backup-format/src/utils/hex2buffer.ts b/packages/backup-format/src/utils/hex2buffer.ts
index 4b8f76f2e0c2..b4fa7099a733 100644
--- a/packages/backup-format/src/utils/hex2buffer.ts
+++ b/packages/backup-format/src/utils/hex2buffer.ts
@@ -22,7 +22,7 @@ export function hex2buffer(hexString: string, padded?: boolean) {
}
/** @internal */
-function concat(...buf: (Uint8Array | number[])[]) {
+function concat(...buf: Array) {
const res = new Uint8Array(sum(buf.map((item) => item.length)))
let offset = 0
buf.forEach((item) => {
diff --git a/packages/backup-format/src/version-1/index.ts b/packages/backup-format/src/version-1/index.ts
index 7abf0376c303..4f001c0dc895 100644
--- a/packages/backup-format/src/version-1/index.ts
+++ b/packages/backup-format/src/version-1/index.ts
@@ -89,16 +89,16 @@ interface BackupJSONFileVersion1 {
publicKey: EC_Public_JsonWebKey
privateKey: EC_Private_JsonWebKey
localKey: AESJsonWebKey
- previousIdentifiers?: { network: string; userId: string }[]
+ previousIdentifiers?: Array<{ network: string; userId: string }>
nickname?: string
}>
people?: Array<{
network: string
userId: string
publicKey: EC_Public_JsonWebKey
- previousIdentifiers?: { network: string; userId: string }[]
+ previousIdentifiers?: Array<{ network: string; userId: string }>
nickname?: string
- groups?: { network: string; groupID: string; virtualGroupOwner: string | null }[]
+ groups?: Array<{ network: string; groupID: string; virtualGroupOwner: string | null }>
// Note: those props are not existed in the backup, just to make the code more readable
privateKey?: EC_Private_JsonWebKey
diff --git a/packages/backup-format/src/version-2/index.ts b/packages/backup-format/src/version-2/index.ts
index 2ed7c710d425..7a9da8856975 100644
--- a/packages/backup-format/src/version-2/index.ts
+++ b/packages/backup-format/src/version-2/index.ts
@@ -322,7 +322,7 @@ interface BackupJSONFileVersion2 {
privateKey?: JsonWebKey
localKey?: JsonWebKey
nickname?: string
- linkedProfiles: [/** ProfileIdentifier.toText() */ string, LinkedProfileDetails][]
+ linkedProfiles: Array<[/** ProfileIdentifier.toText() */ string, LinkedProfileDetails]>
createdAt: number // Unix timestamp
updatedAt: number // Unix timestamp
}>
@@ -345,7 +345,7 @@ interface BackupJSONFileVersion2 {
postBy: string // ProfileIdentifier.toText()
identifier: string // PostIVIdentifier.toText()
postCryptoKey?: JsonWebKey
- recipients: 'everyone' | [/** ProfileIdentifier.toText() */ string, { reason: RecipientReasonJSON[] }][]
+ recipients: 'everyone' | Array<[/** ProfileIdentifier.toText() */ string, { reason: RecipientReasonJSON[] }]>
/** @deprecated */
recipientGroups: never[]
foundAt: number // Unix timestamp
diff --git a/packages/dashboard/package.json b/packages/dashboard/package.json
index d2d156cf0f55..b14d4407dc72 100644
--- a/packages/dashboard/package.json
+++ b/packages/dashboard/package.json
@@ -19,6 +19,7 @@
"@masknet/backup-format": "workspace:*",
"@masknet/icons": "workspace:*",
"@masknet/plugin-example": "workspace:*",
+ "@masknet/plugin-evm": "workspace:*",
"@masknet/plugin-flow": "workspace:*",
"@masknet/plugin-infra": "workspace:*",
"@masknet/plugin-solana": "workspace:*",
@@ -32,6 +33,8 @@
"@masknet/web3-providers": "workspace:*",
"@masknet/web3-shared-base": "workspace:*",
"@masknet/web3-shared-evm": "workspace:*",
+ "@masknet/web3-shared-solana": "workspace:*",
+ "@masknet/web3-shared-flow": "workspace:*",
"@msgpack/msgpack": "^2.7.2",
"@servie/events": "^3.0.0",
"@types/color": "^3.0.3",
diff --git a/packages/dashboard/src/components/CreateWalletForm/index.tsx b/packages/dashboard/src/components/CreateWalletForm/index.tsx
index ddb77638de16..2a5df398e1a0 100644
--- a/packages/dashboard/src/components/CreateWalletForm/index.tsx
+++ b/packages/dashboard/src/components/CreateWalletForm/index.tsx
@@ -31,11 +31,11 @@ const useStyles = makeStyles()((theme) => ({
// TODO: actions, and icon may be an img url
export interface CreateWalletFormProps {
- options: {
+ options: Array<{
label: string
icon: React.ReactNode
value: number
- }[]
+ }>
}
export function CreateWalletForm(props: CreateWalletFormProps) {
diff --git a/packages/dashboard/src/components/DashboardFrame/Navigation.tsx b/packages/dashboard/src/components/DashboardFrame/Navigation.tsx
index e6c47ef72ec6..00e45b050a9b 100644
--- a/packages/dashboard/src/components/DashboardFrame/Navigation.tsx
+++ b/packages/dashboard/src/components/DashboardFrame/Navigation.tsx
@@ -30,7 +30,8 @@ import {
import { useDashboardI18N } from '../../locales'
import { MaskColorVar } from '@masknet/theme'
import { DashboardRoutes } from '@masknet/shared-base'
-import { NetworkPluginID, useCurrentWeb3NetworkPluginID } from '@masknet/plugin-infra/web3'
+import { NetworkPluginID } from '@masknet/web3-shared-base'
+import { useCurrentWeb3NetworkPluginID } from '@masknet/plugin-infra/web3'
const ListItemLinkUnStyled = ({ to, ...props }: ListItemProps & { to: string }) => {
const navigate = useNavigate()
diff --git a/packages/dashboard/src/components/PageFrame/FeaturePromotions/index.tsx b/packages/dashboard/src/components/PageFrame/FeaturePromotions/index.tsx
index a2533c89433e..7d44196acfe0 100644
--- a/packages/dashboard/src/components/PageFrame/FeaturePromotions/index.tsx
+++ b/packages/dashboard/src/components/PageFrame/FeaturePromotions/index.tsx
@@ -1,9 +1,10 @@
import { memo, useCallback, useMemo } from 'react'
import { useNavigate } from 'react-router-dom'
import { makeStyles } from '@masknet/theme'
-import { openWindow, useRemoteControlledDialog } from '@masknet/shared-base-ui'
-import { useAccount } from '@masknet/web3-shared-evm'
-import { PluginMessages, Services } from '../../../API'
+import { openWindow } from '@masknet/shared-base-ui'
+import { useAccount } from '@masknet/plugin-infra/web3'
+import { Services } from '../../../API'
+import { NetworkPluginID } from '@masknet/web3-shared-base'
import { PersonaContext } from '../../../pages/Personas/hooks/usePersonaContext'
import { DashboardRoutes, EnhanceableSite } from '@masknet/shared-base'
import { PluginId } from '@masknet/plugin-infra'
@@ -31,10 +32,10 @@ const useStyles = makeStyles()((theme) => ({
export const FeaturePromotions = memo(() => {
const { classes } = useStyles()
const navigate = useNavigate()
- const account = useAccount()
+ const account = useAccount(NetworkPluginID.PLUGIN_EVM)
const { currentPersona, connectPersona } = PersonaContext.useContainer()
- const { setDialog: setBuyDialog } = useRemoteControlledDialog(PluginMessages.Transak.buyTokenDialogUpdated)
+ // const { setDialog: setBuyDialog } = useRemoteControlledDialog(PluginMessages.Transak.buyTokenDialogUpdated)
const isConnectedTwitter = useMemo(() => {
if (!currentPersona) return false
@@ -46,10 +47,10 @@ export const FeaturePromotions = memo(() => {
}, [currentPersona])
const openTransakDialog = useCallback(() => {
- setBuyDialog({
- open: true,
- address: account ?? '',
- })
+ // setBuyDialog({
+ // open: true,
+ // address: account ?? '',
+ // })
}, [])
const openTwitter = (pluginId: string) => async () => {
diff --git a/packages/dashboard/src/hooks/useGasOptions.ts b/packages/dashboard/src/hooks/useGasOptions.ts
deleted file mode 100644
index c9f42b64bb11..000000000000
--- a/packages/dashboard/src/hooks/useGasOptions.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import { GasOption, isEIP1559Supported, useChainId } from '@masknet/web3-shared-evm'
-import { useMemo } from 'react'
-import { useAsync } from 'react-use'
-import { useDashboardI18N } from '../locales'
-import { PluginServices } from '../API'
-
-const { Wallet: WalletRPC } = PluginServices
-export function useGasOptions() {
- const t = useDashboardI18N()
- const chainId = useChainId()
- const is1559Supported = useMemo(() => isEIP1559Supported(chainId), [chainId])
- const { value: gasFromMetaMask, loading: getFromMetaMaskLoading } = useAsync(async () => {
- if (!is1559Supported) return
-
- return WalletRPC.getEstimateGasFees(chainId)
- }, [is1559Supported, chainId])
-
- // #region Get gas options from debank
- const { value: gasFromDebank, loading: getFromDebankLoading } = useAsync(async () => {
- if (is1559Supported) return
- const response = await WalletRPC.getGasPriceDictFromDeBank(chainId)
- if (!response) return null
- return {
- low: response.data.slow.price,
- medium: response.data.normal.price,
- high: response.data.fast.price,
- }
- }, [is1559Supported, chainId])
- // #endregion
-
- const gasOptions = is1559Supported ? gasFromMetaMask : gasFromDebank
-
- const options = useMemo(() => {
- return [
- {
- title: t.wallet_gas_fee_settings_low(),
- gasOption: GasOption.Low,
- gasPrice: gasOptions?.low ?? 0,
- },
- {
- title: t.wallet_gas_fee_settings_medium(),
- gasOption: GasOption.Medium,
- gasPrice: gasOptions?.medium ?? 0,
- },
- {
- title: t.wallet_gas_fee_settings_high(),
- gasOption: GasOption.High,
- gasPrice: gasOptions?.high ?? 0,
- },
- ]
- }, [is1559Supported, gasOptions])
-
- return {
- value: options,
- loading: is1559Supported ? getFromMetaMaskLoading : getFromDebankLoading,
- gasOptions,
- }
-}
diff --git a/packages/dashboard/src/initialization/Dashboard.tsx b/packages/dashboard/src/initialization/Dashboard.tsx
index c16bcb6cc643..83b4c5155b97 100644
--- a/packages/dashboard/src/initialization/Dashboard.tsx
+++ b/packages/dashboard/src/initialization/Dashboard.tsx
@@ -10,19 +10,15 @@ import {
import { I18NextProviderHMR, SharedContextProvider } from '@masknet/shared'
import { ErrorBoundary } from '@masknet/shared-base-ui'
import { createInjectHooksRenderer, useActivatedPluginsDashboard } from '@masknet/plugin-infra/dashboard'
-import { NetworkPluginID, PluginsWeb3ContextProvider, useAllPluginsWeb3State } from '@masknet/plugin-infra/web3'
-import { Web3Provider } from '@masknet/web3-shared-evm'
-
+import { PluginsWeb3ContextProvider, useAllPluginsWeb3State } from '@masknet/plugin-infra/web3'
import { i18NextInstance } from '@masknet/shared-base'
import '../utils/kv-storage'
import './PluginHost'
import { Pages } from '../pages/routes'
-import { Web3Context } from '../web3/context'
import { useAppearance, usePluginID } from '../pages/Personas/api'
import { PersonaContext } from '../pages/Personas/hooks/usePersonaContext'
-import { fixWeb3State } from '../../../mask/src/plugins/EVM/UI/Web3State'
const PluginRender = createInjectHooksRenderer(useActivatedPluginsDashboard, (x) => x.GlobalInjection)
@@ -30,9 +26,6 @@ export default function DashboardRoot() {
const pluginID = usePluginID()
const PluginsWeb3State = useAllPluginsWeb3State()
- // TODO: migrate EVM plugin
- fixWeb3State(PluginsWeb3State[NetworkPluginID.PLUGIN_EVM], Web3Context)
-
// #region theme
const appearance = useAppearance()
const mode = useSystemPreferencePalette()
@@ -47,28 +40,26 @@ export default function DashboardRoot() {
// #endregion
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
)
}
diff --git a/packages/dashboard/src/initialization/PluginHost.ts b/packages/dashboard/src/initialization/PluginHost.ts
index 272c30c82d69..848bb1d4954f 100644
--- a/packages/dashboard/src/initialization/PluginHost.ts
+++ b/packages/dashboard/src/initialization/PluginHost.ts
@@ -2,9 +2,9 @@ import './plugins'
import { Emitter } from '@servie/events'
import { startPluginDashboard, Plugin } from '@masknet/plugin-infra/dashboard'
+import { createI18NBundle, i18NextInstance } from '@masknet/shared-base'
import { Services, Messages } from '../API'
-import { createI18NBundle, createSubscriptionFromAsync, i18NextInstance } from '@masknet/shared-base'
-import { InMemoryStorages, PersistentStorages } from '../utils/kv-storage'
+import { createSharedContext } from '../../../mask/src/plugin-infra/host'
const PluginHost: Plugin.__Host.Host = {
minimalMode: {
@@ -16,23 +16,7 @@ const PluginHost: Plugin.__Host.Host = {
addI18NResource(plugin, resource) {
createI18NBundle(plugin, resource)(i18NextInstance)
},
- createContext: (pluginID, signal) => {
- const currentPersonaSub = createSubscriptionFromAsync(
- Services.Settings.getCurrentPersonaIdentifier,
- undefined,
- Messages.events.currentPersonaIdentifier.on,
- signal,
- )
- return {
- createKVStorage(type, defaultValues) {
- if (type === 'memory') return InMemoryStorages.Plugin.createSubScope(pluginID, defaultValues, signal)
- else return PersistentStorages.Plugin.createSubScope(pluginID, defaultValues, signal)
- },
- personaSign: Services.Identity.signWithPersona,
- walletSign: Services.Ethereum.personalSign,
- currentPersona: currentPersonaSub,
- }
- },
+ createContext: createSharedContext,
}
setTimeout(() => {
Messages.events.pluginMinimalModeChanged.on(([id, status]) => {
diff --git a/packages/dashboard/src/initialization/isolated_bridge.ts b/packages/dashboard/src/initialization/isolated_bridge.ts
index 9e941f0812b0..e7b621e94ac0 100644
--- a/packages/dashboard/src/initialization/isolated_bridge.ts
+++ b/packages/dashboard/src/initialization/isolated_bridge.ts
@@ -24,11 +24,9 @@ function installPluginService() {
const Wallet = channelOf('com.maskbook.wallet')
const Transak = channelOf('com.maskbook.transak')
const Swap = channelOf('com.maskbook.trader')
- const Pets = channelOf('com.maskbook.pets')
- setPluginMessages({ Wallet, Transak, Swap, Pets })
+ setPluginMessages({ Wallet, Transak, Swap })
setPluginServices({
Wallet: initRPCBridge(PluginMessages.Wallet.events.rpc),
- Swap: initRPCBridge(PluginMessages.Swap.rpc),
})
}
diff --git a/packages/dashboard/src/pages/CreateMaskWallet/components/CreateMnemonic/index.tsx b/packages/dashboard/src/pages/CreateMaskWallet/components/CreateMnemonic/index.tsx
index fc44340b5553..d672c8b0df22 100644
--- a/packages/dashboard/src/pages/CreateMaskWallet/components/CreateMnemonic/index.tsx
+++ b/packages/dashboard/src/pages/CreateMaskWallet/components/CreateMnemonic/index.tsx
@@ -3,7 +3,6 @@ import { Alert, Box, Button, Typography } from '@mui/material'
import { makeStyles, MaskColorVar } from '@masknet/theme'
import { InfoIcon, RefreshIcon } from '@masknet/icons'
import { useDashboardI18N } from '../../../../locales'
-import { ChainId, ProviderType } from '@masknet/web3-shared-evm'
import { MnemonicReveal } from '../../../../components/Mnemonic'
import { VerifyMnemonicDialog } from '../VerifyMnemonicDialog'
import { useAsyncFn, useAsyncRetry } from 'react-use'
@@ -115,14 +114,10 @@ const CreateMnemonic = memo(() => {
const account = await Services.Settings.getSelectedWalletAddress()
if (!account) {
- await PluginServices.Wallet.updateAccount({
+ await PluginServices.Wallet.updateMaskAccount({
account: address_,
- providerType: ProviderType.MaskWallet,
})
- const chainId = searchParams.get('chainId')
- if (chainId) {
- await PluginServices.Wallet.selectAccount([address_], Number(chainId) as ChainId)
- }
+ await PluginServices.Wallet.selectMaskAccount([address_])
}
return address_
diff --git a/packages/dashboard/src/pages/Settings/api.ts b/packages/dashboard/src/pages/Settings/api.ts
index 894e2bfbd781..2d922ef5b290 100644
--- a/packages/dashboard/src/pages/Settings/api.ts
+++ b/packages/dashboard/src/pages/Settings/api.ts
@@ -1,15 +1,9 @@
import { createGlobalState } from '@masknet/shared-base-ui'
import { Messages, Services } from '../../API'
-import type { DataProvider } from '@masknet/public-api'
import type { AccountType, BackupFileInfo, Scenario, Locale } from './type'
export const [useLanguage] = createGlobalState(Services.Settings.getLanguage, Messages.events.languageSettings.on)
-export const [useTrendingDataSource] = createGlobalState(
- Services.Settings.getTrendingDataSource,
- Messages.events.currentDataProviderSettings.on,
-)
-
const BASE_RUL = 'https://vaalh28dbi.execute-api.ap-east-1.amazonaws.com/api'
interface BackupBaseRequest {
diff --git a/packages/dashboard/src/pages/Settings/components/DataSourceSetting.tsx b/packages/dashboard/src/pages/Settings/components/DataSourceSetting.tsx
deleted file mode 100644
index b89cd5166e09..000000000000
--- a/packages/dashboard/src/pages/Settings/components/DataSourceSetting.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { MenuItem } from '@mui/material'
-import SettingSelect from './SettingSelect'
-import { useTrendingDataSource } from '../api'
-import { Services } from '../../../API'
-import { MarketTrendProvider } from '../../../type'
-
-export default function DataSourceSetting() {
- const source = useTrendingDataSource()
- const handleChange = (event: any) => {
- const value = event.target.value
- Services.Settings.setTrendingDataSource(value)
- }
-
- return (
-
-
-
-
-
- )
-}
diff --git a/packages/dashboard/src/pages/Wallets/api.ts b/packages/dashboard/src/pages/Wallets/api.ts
deleted file mode 100644
index d16731b30b45..000000000000
--- a/packages/dashboard/src/pages/Wallets/api.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { createGlobalState } from '@masknet/shared-base-ui'
-import { Messages, Services } from '../../API'
-
-export const [useCurrentCollectibleDataProvider] = createGlobalState(
- Services.Settings.getCurrentCollectibleDataProvider,
- (x) => Messages.events.currentNonFungibleAssetDataProviderSettings.on(x),
-)
-
-export const [useCurrentSelectedWalletNetwork] = createGlobalState(
- Services.Settings.getCurrentSelectedWalletNetwork,
- (x) => Messages.events.currentNetworkSettings.on(x),
-)
diff --git a/packages/dashboard/src/pages/Wallets/components/AddCollectibleDialog/index.tsx b/packages/dashboard/src/pages/Wallets/components/AddCollectibleDialog/index.tsx
index 05e0a75d6da2..1037b19e6ec9 100644
--- a/packages/dashboard/src/pages/Wallets/components/AddCollectibleDialog/index.tsx
+++ b/packages/dashboard/src/pages/Wallets/components/AddCollectibleDialog/index.tsx
@@ -1,19 +1,13 @@
-import { FormEvent, memo, useCallback, useEffect, useState } from 'react'
+import { FormEvent, memo, useEffect, useState } from 'react'
import { MaskDialog, MaskTextField } from '@masknet/theme'
import { Box, Button, DialogActions, DialogContent } from '@mui/material'
-import {
- EthereumTokenType,
- isSameAddress,
- useERC721ContractDetailed,
- useERC721TokenDetailedCallback,
- useWallet,
-} from '@masknet/web3-shared-evm'
+import { NetworkPluginID } from '@masknet/web3-shared-base'
import { EthereumAddress } from 'wallet.ts'
import { useDashboardI18N } from '../../../../locales'
import { z } from 'zod'
import { Controller, useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
-import { PluginServices } from '../../../../API'
+import { useWeb3Connection, useWallet, useChainId } from '@masknet/plugin-infra/web3'
export interface AddCollectibleDialogProps {
open: boolean
@@ -31,41 +25,48 @@ enum FormErrorType {
}
export const AddCollectibleDialog = memo(({ open, onClose }) => {
- const wallet = useWallet()
+ const wallet = useWallet(NetworkPluginID.PLUGIN_EVM)
const [address, setAddress] = useState('')
- const { value: contractDetailed, loading: contractDetailLoading } = useERC721ContractDetailed(address)
- const [tokenId, setTokenId, erc721TokenDetailedCallback] = useERC721TokenDetailedCallback(contractDetailed)
-
- const onSubmit = useCallback(async () => {
- if (contractDetailLoading || !wallet) return
-
- const tokenInDB = await PluginServices.Wallet.getToken(EthereumTokenType.ERC721, address, tokenId)
- if (tokenInDB) throw new Error(FormErrorType.Added)
-
- const tokenDetailed = await erc721TokenDetailedCallback()
-
- if (
- (tokenDetailed && !isSameAddress(tokenDetailed.info.owner, wallet.address)) ||
- !tokenDetailed ||
- !tokenDetailed.info.owner
- ) {
- throw new Error(FormErrorType.NotExist)
- } else {
- await PluginServices.Wallet.addToken(tokenDetailed)
- onClose()
- }
- }, [contractDetailLoading, wallet, address, tokenId, erc721TokenDetailedCallback])
-
- return (
-
- )
+ const [tokenId, setTokenId] = useState('')
+ const connection = useWeb3Connection(NetworkPluginID.PLUGIN_EVM)
+ const chainId = useChainId(NetworkPluginID.PLUGIN_EVM)
+
+ return null
+
+ // const [tokenId, setTokenId, erc721TokenDetailedCallback] = useERC721TokenDetailedCallback(contractDetailed)
+
+ // const onSubmit = useCallback(async () => {
+ // if (contractDetailLoading || !wallet) return
+
+ // const tokenInDB = await PluginServices.Wallet.getToken(SchemaType.ERC721, address, tokenId)
+ // if (tokenInDB) throw new Error(FormErrorType.Added)
+
+ // const tokenDetailed = await connection?.getNonFungibleToken(address ?? '', tokenId, {
+ // chainId,
+ // })
+
+ // if (
+ // (tokenDetailed && !isSameAddress(tokenDetailed.info.owner, wallet.address)) ||
+ // !tokenDetailed ||
+ // !tokenDetailed.info.owner
+ // ) {
+ // throw new Error(FormErrorType.NotExist)
+ // } else {
+ // await PluginServices.Wallet.addToken(tokenDetailed)
+ // onClose()
+ // }
+ // }, [contractDetailLoading, wallet, address, tokenId, erc721TokenDetailedCallback])
+
+ // return (
+ //
+ // )
})
export interface AddCollectibleDialogUIProps {
diff --git a/packages/dashboard/src/pages/Wallets/components/AddTokenConfirmUI/index.tsx b/packages/dashboard/src/pages/Wallets/components/AddTokenConfirmUI/index.tsx
index be023076b0c5..3e559f0f5522 100644
--- a/packages/dashboard/src/pages/Wallets/components/AddTokenConfirmUI/index.tsx
+++ b/packages/dashboard/src/pages/Wallets/components/AddTokenConfirmUI/index.tsx
@@ -2,14 +2,15 @@ import { memo } from 'react'
import { useDashboardI18N } from '../../../../locales'
import { Box, Button, DialogActions, DialogContent, Stack, Typography } from '@mui/material'
import { makeStyles } from '@masknet/theme'
-import type { ERC20TokenDetailed } from '@masknet/web3-shared-evm'
import { TokenIcon } from '@masknet/shared'
import { useFormContext } from 'react-hook-form'
+import type { FungibleToken } from '@masknet/web3-shared-base'
+import type { ChainId, SchemaType } from '@masknet/web3-shared-evm'
export interface AddTokenConfirmUIProps {
onBack: () => void
onConfirm: () => void
- token?: ERC20TokenDetailed
+ token?: FungibleToken
balance?: string
}
@@ -58,7 +59,7 @@ export const AddTokenConfirmUI = memo(({ token, balance,
address={token?.address ?? ''}
name={token?.name}
chainId={token?.chainId}
- logoURI={token?.logoURI}
+ logoURI={token?.logoURL}
AvatarProps={{ sx: { width: 48, height: 48 } }}
/>
diff --git a/packages/dashboard/src/pages/Wallets/components/AddTokenFormUI/index.tsx b/packages/dashboard/src/pages/Wallets/components/AddTokenFormUI/index.tsx
index 64a925333c93..aa94b934baac 100644
--- a/packages/dashboard/src/pages/Wallets/components/AddTokenFormUI/index.tsx
+++ b/packages/dashboard/src/pages/Wallets/components/AddTokenFormUI/index.tsx
@@ -2,13 +2,14 @@ import { memo } from 'react'
import { useDashboardI18N } from '../../../../locales'
import { Button, DialogActions, DialogContent, TextField } from '@mui/material'
import { makeStyles } from '@masknet/theme'
-import type { ERC20TokenDetailed } from '@masknet/web3-shared-evm'
import { useFormContext, Controller } from 'react-hook-form'
+import type { ChainId, SchemaType } from '@masknet/web3-shared-evm'
+import type { FungibleToken } from '@masknet/web3-shared-base'
export interface AddTokenFormUIProps {
onNext: () => void
onClose: () => void
- token?: ERC20TokenDetailed
+ token?: FungibleToken
}
const useStyles = makeStyles()((theme) => ({
diff --git a/packages/dashboard/src/pages/Wallets/components/Assets/index.tsx b/packages/dashboard/src/pages/Wallets/components/Assets/index.tsx
index 0dfc10391166..53927168aa98 100644
--- a/packages/dashboard/src/pages/Wallets/components/Assets/index.tsx
+++ b/packages/dashboard/src/pages/Wallets/components/Assets/index.tsx
@@ -1,9 +1,10 @@
-import { type Web3Plugin, NetworkPluginID, useCurrentWeb3NetworkPluginID } from '@masknet/plugin-infra/web3'
+import { memo, useEffect, useState } from 'react'
+import { useCurrentWeb3NetworkPluginID, Web3Helper } from '@masknet/plugin-infra/web3'
import { makeStyles, useTabs } from '@masknet/theme'
import { TabContext, TabList, TabPanel } from '@mui/lab'
import { Box, Button, Tab } from '@mui/material'
-import { memo, useEffect, useState } from 'react'
import { usePickToken } from '@masknet/shared'
+import { NetworkPluginID } from '@masknet/web3-shared-base'
import { ContentContainer } from '../../../../components/ContentContainer'
import { useDashboardI18N } from '../../../../locales'
import { AddCollectibleDialog } from '../AddCollectibleDialog'
@@ -38,7 +39,7 @@ export enum AssetTab {
const assetTabs = [AssetTab.Token, AssetTab.Collectibles] as const
interface TokenAssetsProps {
- network: Web3Plugin.NetworkDescriptor | null
+ network: Web3Helper.NetworkDescriptorAll | null
}
export const Assets = memo(({ network }) => {
diff --git a/packages/dashboard/src/pages/Wallets/components/Balance/index.tsx b/packages/dashboard/src/pages/Wallets/components/Balance/index.tsx
index 88763228ff6d..c631b671625e 100644
--- a/packages/dashboard/src/pages/Wallets/components/Balance/index.tsx
+++ b/packages/dashboard/src/pages/Wallets/components/Balance/index.tsx
@@ -1,13 +1,14 @@
+import { memo } from 'react'
+import { noop } from 'lodash-unified'
import { CardIcon, DownloadIcon, MaskWalletIcon, SendIcon, SwapIcon } from '@masknet/icons'
-import type { Web3Plugin } from '@masknet/plugin-infra/web3'
import { MiniNetworkSelector } from '@masknet/shared'
import { DashboardRoutes } from '@masknet/shared-base'
import { MaskColorVar } from '@masknet/theme'
+import type { NetworkDescriptor, NetworkPluginID } from '@masknet/web3-shared-base'
import { Box, Button, buttonClasses, styled, Typography } from '@mui/material'
-import { noop } from 'lodash-unified'
-import { memo } from 'react'
import { useDashboardI18N } from '../../../../locales'
import { useIsMatched } from '../../hooks'
+import type { Web3Helper } from '@masknet/plugin-infra/web3'
const BalanceContainer = styled('div')(
({ theme }) => `
@@ -75,10 +76,23 @@ export interface BalanceCardProps {
onBuy(): void
onSwap(): void
onReceive(): void
- networks: Web3Plugin.NetworkDescriptor[]
- selectedNetwork: Web3Plugin.NetworkDescriptor | null
+ networks: Array<
+ NetworkDescriptor<
+ Web3Helper.Definition[NetworkPluginID]['ChainId'],
+ Web3Helper.Definition[NetworkPluginID]['NetworkType']
+ >
+ >
+ selectedNetwork: NetworkDescriptor<
+ Web3Helper.Definition[NetworkPluginID]['ChainId'],
+ Web3Helper.Definition[NetworkPluginID]['NetworkType']
+ > | null
showOperations: boolean
- onSelectNetwork(network: Web3Plugin.NetworkDescriptor | null): void
+ onSelectNetwork(
+ network: NetworkDescriptor<
+ Web3Helper.Definition[NetworkPluginID]['ChainId'],
+ Web3Helper.Definition[NetworkPluginID]['NetworkType']
+ > | null,
+ ): void
}
export const Balance = memo(
@@ -114,9 +128,12 @@ export const Balance = memo(
disabledNonCurrentNetwork={isDisabledNonCurrentChainSelect}
selectedNetwork={selectedNetwork}
networks={networks}
- onSelect={(network: Web3Plugin.NetworkDescriptor | null) =>
- networks.length <= 1 ? noop : onSelectNetwork(network)
- }
+ onSelect={(
+ network: NetworkDescriptor<
+ Web3Helper.Definition[NetworkPluginID]['ChainId'],
+ Web3Helper.Definition[NetworkPluginID]['NetworkType']
+ > | null,
+ ) => (networks.length <= 1 ? noop : onSelectNetwork(network))}
/>
diff --git a/packages/dashboard/src/pages/Wallets/components/CollectibleCard/index.tsx b/packages/dashboard/src/pages/Wallets/components/CollectibleCard/index.tsx
index 106b6bf9ad8d..eefdac98ecd6 100644
--- a/packages/dashboard/src/pages/Wallets/components/CollectibleCard/index.tsx
+++ b/packages/dashboard/src/pages/Wallets/components/CollectibleCard/index.tsx
@@ -1,17 +1,18 @@
import { memo, useEffect, useMemo, useRef, useState } from 'react'
+import { useHoverDirty } from 'react-use'
+import { WalletIcon, NFTCardStyledAssetPlayer } from '@masknet/shared'
import { Box, Button, Link, Tooltip, Typography } from '@mui/material'
import { makeStyles, MaskColorVar } from '@masknet/theme'
+import { NetworkPluginID, NonFungibleAsset } from '@masknet/web3-shared-base'
import { CollectiblePlaceholder } from '../CollectiblePlaceHolder'
-import { useHoverDirty } from 'react-use'
import { useDashboardI18N } from '../../../../locales'
-import { WalletIcon, NFTCardStyledAssetPlayer } from '@masknet/shared'
import { ChangeNetworkTip } from '../FungibleTokenTableRow/ChangeNetworkTip'
import {
- NetworkPluginID,
- useNetworkDescriptor,
+ useChainId,
useCurrentWeb3NetworkPluginID,
+ useNetworkDescriptor,
useWeb3State,
- Web3Plugin,
+ Web3Helper,
} from '@masknet/plugin-infra/web3'
const useStyles = makeStyles()((theme) => ({
@@ -94,20 +95,23 @@ const useStyles = makeStyles()((theme) => ({
}))
export interface CollectibleCardProps {
- chainId: number
- token: Web3Plugin.NonFungibleToken
+ token: NonFungibleAsset<
+ Web3Helper.Definition[NetworkPluginID]['ChainId'],
+ Web3Helper.Definition[NetworkPluginID]['SchemaType']
+ >
onSend(): void
renderOrder: number
}
-export const CollectibleCard = memo(({ chainId, token, onSend, renderOrder }) => {
+export const CollectibleCard = memo(({ token, onSend, renderOrder }) => {
const t = useDashboardI18N()
- const { Utils } = useWeb3State()
+ const chainId = useChainId()
const { classes } = useStyles()
const ref = useRef(null)
+ const { Others } = useWeb3State() as Web3Helper.Web3StateAll
const [isHoveringTooltip, setHoveringTooltip] = useState(false)
const isHovering = useHoverDirty(ref)
- const networkDescriptor = useNetworkDescriptor(token.contract?.chainId)
+ const networkDescriptor = useNetworkDescriptor(undefined, token.contract?.chainId)
const isOnCurrentChain = useMemo(() => chainId === token.contract?.chainId, [chainId, token])
const currentPluginId = useCurrentWeb3NetworkPluginID()
@@ -119,10 +123,9 @@ export const CollectibleCard = memo(({ chainId, token, onS
const sendable = currentPluginId === NetworkPluginID.PLUGIN_EVM
const showSendButton = (isHovering || isHoveringTooltip) && sendable
- let nftLink
- if (Utils?.resolveNonFungibleTokenLink && token.contract) {
- nftLink = Utils?.resolveNonFungibleTokenLink?.(token.contract?.chainId, token.contract.address, token.tokenId)
- }
+ const nftLink = useMemo(() => {
+ return Others?.explorerResolver.nonFungibleTokenLink(token.chainId, token.address, token.tokenId)
+ }, [currentPluginId, token.chainId, token.address, token.tokenId])
return (
@@ -130,7 +133,7 @@ export const CollectibleCard = memo(({ chainId, token, onS
- {(token.metadata?.assetURL || token.metadata?.iconURL) && token.contract ? (
+ {(token.metadata?.mediaURL || token.metadata?.imageURL) && token.contract ? (
(({ chainId, token, onS
contractAddress={token.contract.address}
chainId={token.contract.chainId}
renderOrder={renderOrder}
- url={token.metadata.assetURL || token.metadata.iconURL}
+ url={token.metadata.imageURL || token.metadata.mediaURL}
tokenId={token.tokenId}
classes={{
loadingFailImage: classes.loadingFailImage,
@@ -183,7 +186,7 @@ export const CollectibleCard = memo(({ chainId, token, onS
) : (
- {token.name || token.tokenId}
+ {token.metadata?.name || token.tokenId}
)}
diff --git a/packages/dashboard/src/pages/Wallets/components/CollectibleList/index.tsx b/packages/dashboard/src/pages/Wallets/components/CollectibleList/index.tsx
index d41558f5516b..cf03dcd06f4a 100644
--- a/packages/dashboard/src/pages/Wallets/components/CollectibleList/index.tsx
+++ b/packages/dashboard/src/pages/Wallets/components/CollectibleList/index.tsx
@@ -2,22 +2,20 @@ import { Dispatch, memo, SetStateAction, useCallback, useEffect, useRef, useStat
import { useNavigate } from 'react-router-dom'
import { Box, Stack, TablePagination } from '@mui/material'
import { makeStyles } from '@masknet/theme'
+import { NetworkPluginID, NonFungibleToken } from '@masknet/web3-shared-base'
import { LoadingPlaceholder } from '../../../../components/LoadingPlaceholder'
-import { DashboardRoutes, EMPTY_LIST } from '@masknet/shared-base'
+import { DashboardRoutes } from '@masknet/shared-base'
import { EmptyPlaceholder } from '../EmptyPlaceholder'
import { CollectibleCard } from '../CollectibleCard'
import { useDashboardI18N } from '../../../../locales'
-import { PluginMessages } from '../../../../API'
import { TransferTab } from '../Transfer'
import {
- useNetworkDescriptor,
- useWeb3State as useWeb3PluginState,
- Web3Plugin,
useAccount,
useCurrentWeb3NetworkPluginID,
- NetworkPluginID,
+ useNetworkDescriptor,
+ useNonFungibleAssets,
+ Web3Helper,
} from '@masknet/plugin-infra/web3'
-import { useAsyncRetry } from 'react-use'
const useStyles = makeStyles()({
root: {
@@ -37,7 +35,7 @@ const useStyles = makeStyles()({
})
interface CollectibleListProps {
- selectedNetwork: Web3Plugin.NetworkDescriptor | null
+ selectedNetwork: Web3Helper.NetworkDescriptorAll | null
}
const ITEM_SIZE = {
@@ -49,42 +47,45 @@ export const CollectibleList = memo(({ selectedNetwork })
const [page, setPage] = useState(0)
const navigate = useNavigate()
const account = useAccount()
- const { Asset } = useWeb3PluginState()
+ const { value = [], error, retry, loading } = useNonFungibleAssets()
const network = useNetworkDescriptor()
const [loadingSize, setLoadingSize] = useState(0)
- const [renderData, setRenderData] = useState([])
+ const [renderData, setRenderData] = useState<
+ Array<
+ NonFungibleToken<
+ Web3Helper.Definition[NetworkPluginID]['ChainId'],
+ Web3Helper.Definition[NetworkPluginID]['SchemaType']
+ >
+ >
+ >([])
- const {
- value = { data: EMPTY_LIST, hasNextPage: false },
- error: collectiblesError,
- loading: isQuerying,
- retry,
- } = useAsyncRetry(
- async () => Asset?.getNonFungibleAssets?.(account, { page, size: 20 }, undefined, selectedNetwork || undefined),
- [account, Asset?.getNonFungibleAssets, network, selectedNetwork],
- )
useEffect(() => {
- const unsubscribeTokens = PluginMessages.Wallet.events.erc721TokensUpdated.on(() => retry())
- const unsubscribeSocket = PluginMessages.Wallet.events.socketMessageUpdated.on((info) => {
- if (!info.done) {
- retry()
- }
- })
- return () => {
- unsubscribeTokens()
- unsubscribeSocket()
- }
+ // const unsubscribeTokens = PluginMessages.Wallet.events.erc721TokensUpdated.on(() => retry())
+ // const unsubscribeSocket = PluginMessages.Wallet.events.socketMessageUpdated.on((info) => {
+ // if (!info.done) {
+ // retry()
+ // }
+ // })
+ // return () => {
+ // unsubscribeTokens()
+ // unsubscribeSocket()
+ // }
}, [retry])
useEffect(() => {
if (!loadingSize) return
- const render = value.data.slice(page * loadingSize, (page + 1) * loadingSize)
+ const render = value.slice(page * loadingSize, (page + 1) * loadingSize)
setRenderData(render)
- }, [value.data, loadingSize, page])
+ }, [value, loadingSize, page])
const currentPluginId = useCurrentWeb3NetworkPluginID()
const onSend = useCallback(
- (detail: Web3Plugin.NonFungibleToken) => {
+ (
+ detail: NonFungibleToken<
+ Web3Helper.Definition[NetworkPluginID]['ChainId'],
+ Web3Helper.Definition[NetworkPluginID]['SchemaType']
+ >,
+ ) => {
// Sending NFT is only available on EVM currently.
if (currentPluginId !== NetworkPluginID.PLUGIN_EVM) return
navigate(DashboardRoutes.WalletsTransfer, {
@@ -97,19 +98,18 @@ export const CollectibleList = memo(({ selectedNetwork })
[currentPluginId],
)
- const hasNextPage = (page + 1) * loadingSize < value.data.length
- const isLoading = renderData.length === 0 && isQuerying
+ const hasNextPage = (page + 1) * loadingSize < value.length
+ const isLoading = renderData.length === 0 && loading
return (
setLoadingSize(size)}
/>
@@ -118,30 +118,29 @@ export const CollectibleList = memo(({ selectedNetwork })
export interface CollectibleListUIProps {
page: number
- onPageChange: Dispatch>
hasNextPage: boolean
isLoading: boolean
isEmpty: boolean
showPagination: boolean
- chainId: number
- dataSource: Web3Plugin.NonFungibleToken[]
- onSend(detail: Web3Plugin.NonFungibleToken): void
+ chainId?: Web3Helper.ChainIdAll
+ dataSource: Array<
+ NonFungibleToken<
+ Web3Helper.Definition[NetworkPluginID]['ChainId'],
+ Web3Helper.Definition[NetworkPluginID]['SchemaType']
+ >
+ >
+ onSend(
+ detail: NonFungibleToken<
+ Web3Helper.Definition[NetworkPluginID]['ChainId'],
+ Web3Helper.Definition[NetworkPluginID]['SchemaType']
+ >,
+ ): void
+ onPageChange: Dispatch>
setLoadingSize(fn: (pre: number | undefined) => number): void
}
export const CollectibleListUI = memo(
- ({
- page,
- onPageChange,
- isLoading,
- isEmpty,
- hasNextPage,
- showPagination,
- chainId,
- dataSource,
- onSend,
- setLoadingSize,
- }) => {
+ ({ page, onPageChange, isLoading, isEmpty, hasNextPage, showPagination, dataSource, onSend, setLoadingSize }) => {
const t = useDashboardI18N()
const { classes } = useStyles()
const ref = useRef(null)
@@ -167,7 +166,6 @@ export const CollectibleListUI = memo(
{dataSource.map((x, index) => (