diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..1635a51c --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,79 @@ +module.exports = { + env: { + browser: true, + es2021: true, + jest: true + }, + extends: ['eslint:recommended', 'plugin:react/recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaFeatures: { + jsx: true + }, + ecmaVersion: 'latest', + sourceType: 'module' + }, + plugins: ['react', 'react-hooks', '@typescript-eslint', 'import', 'simple-import-sort', 'unused-imports'], + rules: { + /** + * off or 0:Indicates that the rule is not validated. + * warn or 1:Indicates the validation rule, when not satisfied, give a warning + * error or 2 :Indicates that the validation rules are not met, and an error is reported if they are not satisfied. + */ + quotes: [2, 'single'], + // "no-console": process.env.NODE_ENV === 'production' ? 2 : 0, // do not disable the console + 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, // disable debugger + semi: 0, + 'no-control-regex': 2, + 'linebreak-style': [0, 'error', 'windows'], + indent: ['error', 2, { SwitchCase: 1 }], + 'array-bracket-spacing': [2, 'never'], + 'no-irregular-whitespace': 0, + 'no-trailing-spaces': 1, + 'eol-last': 0, + 'no-unused-vars': [1, { vars: 'all', args: 'after-used' }], + 'no-underscore-dangle': 0, + 'no-lone-blocks': 0, + 'no-class-assign': 2, + 'no-floating-decimal': 2, + 'no-loop-func': 1, + 'no-cond-assign': 2, + 'no-delete-var': 2, + 'no-dupe-keys': 2, + 'no-duplicate-case': 2, + 'no-dupe-args': 2, + 'no-empty': 2, + 'no-func-assign': 2, + 'no-invalid-this': 0, + 'no-this-before-super': 0, + 'no-undef': 1, + 'no-use-before-define': 0, + camelcase: 0, + '@typescript-eslint/no-var-requires': 0, + + 'react/display-name': 0, + 'react/react-in-jsx-scope': 0, + 'react/no-unescaped-entities': 0, + 'unused-imports/no-unused-imports': 'warn', + '@typescript-eslint/no-unused-vars': [ + 'warn', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_' + } + ] + }, + settings: { + 'import/resolver': { + typescript: {} + } + }, + overrides: [ + { + files: ['**/*.tsx'], + rules: { + 'react/prop-types': 'off' + } + } + ] +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..fcda8fd1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* +dist/ +.key.config.js \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..3f111fee --- /dev/null +++ b/.prettierrc @@ -0,0 +1,16 @@ +{ + "printWidth": 120, + "tabWidth": 2, + "singleQuote": true, + "useTabs": false, + "semi": true, + "vueIndentScriptAndStyle": true, + "trailingComma": "none", + "bracketSpacing": true, + "jsxBracketSameLine": true, + "arrowParens": "always", + "requirePragma": false, + "insertPragma": false, + "importOrder": ["^@formily/(.*)", "^@(.*)$", "^[./]"], + "importOrderSeparation": true +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..6ab3a543 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + }, + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode" +} diff --git a/README.md b/README.md new file mode 100644 index 00000000..5ef8987e --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# UniSat Wallet + +UniSat Wallet - the first open-source browser extension wallet for Bitcoin NFTs + +## Building locally + +- Install [Node.js](https://nodejs.org) version 14 +- Install [Yarn](https://yarnpkg.com/en/docs/install) +- Install dependencies: `yarn` +- Build the project to the `./dist/` folder with `yarn build:firefox` for Firefox +- Build the project to the `./dist/` folder with `yarn build:chrome` for Chrome +- Develop: `yarn build:chrome:dev` + +## Thanks + +Thanks to the MetaMask team for their contributions to the browser extension wallet community, UniSat Wallet uses (or forks) them to make unisat even better. diff --git a/build/_raw/_locales/en/messages.json b/build/_raw/_locales/en/messages.json new file mode 100644 index 00000000..1520715c --- /dev/null +++ b/build/_raw/_locales/en/messages.json @@ -0,0 +1,112 @@ +{ + "Inscription": { "message": "Inscription" }, + "NFT__list__is__empty": { "message": "NFT list is empty" }, + "This__account__has__no__transactions": { "message": "This account has no transactions" }, + "Very__Long__Account__Name": { "message": "Very Long Account Name" }, + "Login__Success": { "message": "Login Success" }, + "at__least__five__characters": { "message": "at least five characters" }, + "Error": { "message": "Error" }, + "Confirm": { "message": "Confirm" }, + "Cancel": { "message": "Cancel" }, + "YesRemove": { "message": "Yes, Remove" }, + "Are__you__Sure": { "message": "Are you Sure" }, + "New__Password": { "message": "New Password" }, + "Entered__passwords__differ": { "message": "Entered passwords differ" }, + "Receive": { "message": "Receive" }, + "Remove__Account": { "message": "Remove Account" }, + "Swiss__Franc": { "message": "Swiss Franc" }, + "Currency": { "message": "Currency" }, + "PASSWORD__ERROR": { "message": "PASSWORD ERROR" }, + "Continue": { "message": "Continue" }, + "This__phrase__is__the__ONLY__way__to": { "message": "This phrase is the ONLY way to" }, + "click__to__copy": { "message": "click to copy" }, + "You__will__not__be__able__to__recover__this__account__with__your__Secret__Recovery__Phrase": { + "message": "You will not be able to recover this account with your Secret Recovery Phrase" + }, + "Fee": { "message": "Fee" }, + "Your__transaction__has__been__succesfully__sent": { "message": "Your transaction has been succesfully sent" }, + "Invalid__address": { "message": "Invalid address" }, + "Clear__the__inputted": { "message": "Clear the inputted" }, + "Available": { "message": "Available" }, + "Save__it__somewhere__safe__and__secret": { "message": "Save it somewhere safe and secret" }, + "Generate__a__new__address": { "message": "Generate a new address" }, + "I__already__have__a__wallet": { "message": "I already have a wallet" }, + "Create__a__password": { "message": "Create a password" }, + "Type__your__Unisat__password": { "message": "Type your UniSat Wallet password" }, + "Invalid__amount": { "message": "Invalid amount" }, + "Payment__Sent": { "message": "Payment Sent" }, + "Sending": { "message": "Sending" }, + "Euro": { "message": "Euro" }, + "Export__Private__Key": { "message": "Export Private Key" }, + "appName": { "message": "UniSat Wallet" }, + "Payment__Faild": { "message": "Payment Faild" }, + "Change__Password": { "message": "Change Password" }, + "Private__Key": { "message": "Private Key" }, + "Recipients__BTC__address": { "message": "Recipient’s BTC address" }, + "Secret__Recovery__Phrase": { "message": "Secret Recovery Phrase" }, + "Confirm__Password": { "message": "Confirm Password" }, + "Successfully__created": { "message": "Successfully created" }, + "mnemonic__phrase__is__invalid": { "message": "mnemonic phrase is invalid" }, + "Unlock": { "message": "Unlock" }, + "Enter__your__password": { "message": "Enter your password" }, + "Japanese": { "message": "日本" }, + "Add__a__new__account": { "message": "Add a new account" }, + "you__will__need__this__Private__Key__to__access__this__account": { + "message": "you will need this Private Key to access this account" + }, + "recover__your__wallet": { "message": "recover your wallet" }, + "Import__an__existing__wallet__with__your__12__word__secret__recovery__phrase": { + "message": "Import an existing wallet with your 12-word secret recovery phrase" + }, + "US__Dollar": { "message": "US Dollar" }, + "Change__your__lockscreen__password": { "message": "Change your lockscreen password" }, + "copied": { "message": "copied" }, + "Create__Account": { "message": "Create Account" }, + "View__on__Block__Explorer": { "message": "View on Block Explorer" }, + "Do__NOT__share__it__with__anyone": { "message": "Do NOT share it with anyone" }, + "Deposit": { "message": "Deposit" }, + "Show__Secret__Recovery__Phrase": { "message": "Show Secret Recovery Phrase" }, + "Language": { "message": "Language" }, + "Import__Private__Key": { "message": "Import Private Key" }, + "Password": { "message": "Password" }, + "Get__Started": { "message": "Get Started" }, + "Import__wallet": { "message": "Import wallet" }, + "Amount": { "message": "Amount" }, + "Next": { "message": "Next" }, + "Your__transaction__had__not__succesfully__sent": { "message": "Your transaction had not succesfully sent" }, + "Current__Password": { "message": "Current Password" }, + "Create__a__new__account": { "message": "Create a new account" }, + "Create__new__wallet": { "message": "Create new wallet" }, + "Chinese": { "message": "中文" }, + "Add__New__Account": { "message": "Add New Account" }, + "Back": { "message": "Back" }, + "Send": { "message": "Send" }, + "Canadian__Dollar": { "message": "Canadian Dollar" }, + "Successfully__imported": { "message": "Successfully imported" }, + "This__address__can__only__receive__Btc": { "message": "This address can only receive Btc" }, + "This__is__an__imported__account": { "message": "This is an imported account" }, + "Password_must_contain_at_least_5_characters": { "message": "Password must contain at least 5 characters" }, + "appDescription": { + "message": "UniSat Wallet - the first open-source browser extension wallet for Bitcoin NFTs!" + }, + "If__you__ever__change__browsers__or__move__computers": { + "message": "If you ever change browsers or move computers" + }, + "I__saved__My__Secret__Recovery__Phrase": { "message": "I saved My Secret Recovery Phrase" }, + "Confirm__payment": { "message": "Confirm payment" }, + "Recipient": { "message": "Recipient" }, + "Spanish": { "message": "Español" }, + "Show__Private__Key": { "message": "Show Private Key" }, + "You__will__use__this__to__unlock__your__wallet": { "message": "You will use this to unlock your wallet" }, + "Imported__accounts__will__not__be__associated__with__your__originally__created__Unisat__account__Secret__Recovery__Phrase": { + "message": "Imported accounts will not be associated with your originally created UniSat Wallet account Secret Recovery Phrase" + }, + "Login": { "message": "Login" }, + "English": { "message": "English" }, + "Import__an__existing__account": { "message": "Import an existing account" }, + "British__Pound": { "message": "British Pound" }, + "Japanese__Yen": { "message": "Japanese Yen" }, + "Switch__Account": { "message": "Switch Account" }, + "Success": { "message": "Success" }, + "Latest__Transactions": { "message": "Latest Transactions" } +} diff --git a/build/_raw/favicon.ico b/build/_raw/favicon.ico new file mode 100644 index 00000000..4f84b66d Binary files /dev/null and b/build/_raw/favicon.ico differ diff --git a/build/_raw/images/Delete.svg b/build/_raw/images/Delete.svg new file mode 100644 index 00000000..ffd44ea2 --- /dev/null +++ b/build/_raw/images/Delete.svg @@ -0,0 +1,4 @@ + + + + diff --git a/build/_raw/images/Name.svg b/build/_raw/images/Name.svg new file mode 100644 index 00000000..fa606729 --- /dev/null +++ b/build/_raw/images/Name.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/Success.png b/build/_raw/images/Success.png new file mode 100644 index 00000000..9920515b Binary files /dev/null and b/build/_raw/images/Success.png differ diff --git a/build/_raw/images/Success.svg b/build/_raw/images/Success.svg new file mode 100644 index 00000000..c348d3df --- /dev/null +++ b/build/_raw/images/Success.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/build/_raw/images/arrow-left-solid.png b/build/_raw/images/arrow-left-solid.png new file mode 100644 index 00000000..c64e431f Binary files /dev/null and b/build/_raw/images/arrow-left-solid.png differ diff --git a/build/_raw/images/arrow-left.svg b/build/_raw/images/arrow-left.svg new file mode 100644 index 00000000..d3eb2eec --- /dev/null +++ b/build/_raw/images/arrow-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/arrow-right-arrow-left-solid.png b/build/_raw/images/arrow-right-arrow-left-solid.png new file mode 100644 index 00000000..8bbaebf3 Binary files /dev/null and b/build/_raw/images/arrow-right-arrow-left-solid.png differ diff --git a/build/_raw/images/arrow-right-arrow-left-solid.svg b/build/_raw/images/arrow-right-arrow-left-solid.svg new file mode 100644 index 00000000..7d67ee30 --- /dev/null +++ b/build/_raw/images/arrow-right-arrow-left-solid.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/build/_raw/images/arrow-right.svg b/build/_raw/images/arrow-right.svg new file mode 100644 index 00000000..41b4ee3a --- /dev/null +++ b/build/_raw/images/arrow-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/btc.svg b/build/_raw/images/btc.svg new file mode 100644 index 00000000..9cf8dce6 --- /dev/null +++ b/build/_raw/images/btc.svg @@ -0,0 +1,17 @@ + + + btc_main + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/_raw/images/check.svg b/build/_raw/images/check.svg new file mode 100644 index 00000000..a58a2d42 --- /dev/null +++ b/build/_raw/images/check.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/chevron-down-solid.png b/build/_raw/images/chevron-down-solid.png new file mode 100644 index 00000000..31ca4c3c Binary files /dev/null and b/build/_raw/images/chevron-down-solid.png differ diff --git a/build/_raw/images/chevron-down-solid.svg b/build/_raw/images/chevron-down-solid.svg new file mode 100644 index 00000000..fccec59f --- /dev/null +++ b/build/_raw/images/chevron-down-solid.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/build/_raw/images/chevron-right-solid-active.png b/build/_raw/images/chevron-right-solid-active.png new file mode 100644 index 00000000..d561a856 Binary files /dev/null and b/build/_raw/images/chevron-right-solid-active.png differ diff --git a/build/_raw/images/chevron-right-solid.png b/build/_raw/images/chevron-right-solid.png new file mode 100644 index 00000000..99076deb Binary files /dev/null and b/build/_raw/images/chevron-right-solid.png differ diff --git a/build/_raw/images/clock-solid-active.png b/build/_raw/images/clock-solid-active.png new file mode 100644 index 00000000..50c4be30 Binary files /dev/null and b/build/_raw/images/clock-solid-active.png differ diff --git a/build/_raw/images/clock-solid-active.svg b/build/_raw/images/clock-solid-active.svg new file mode 100644 index 00000000..0b04cc35 --- /dev/null +++ b/build/_raw/images/clock-solid-active.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/clock-solid-hover.svg b/build/_raw/images/clock-solid-hover.svg new file mode 100644 index 00000000..58081311 --- /dev/null +++ b/build/_raw/images/clock-solid-hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/clock-solid.png b/build/_raw/images/clock-solid.png new file mode 100644 index 00000000..b54be1b4 Binary files /dev/null and b/build/_raw/images/clock-solid.png differ diff --git a/build/_raw/images/clock-solid.svg b/build/_raw/images/clock-solid.svg new file mode 100644 index 00000000..bdccb1d0 --- /dev/null +++ b/build/_raw/images/clock-solid.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/compass-solid-active.svg b/build/_raw/images/compass-solid-active.svg new file mode 100644 index 00000000..00a68ede --- /dev/null +++ b/build/_raw/images/compass-solid-active.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/build/_raw/images/compass-solid-hover.svg b/build/_raw/images/compass-solid-hover.svg new file mode 100644 index 00000000..92d42645 --- /dev/null +++ b/build/_raw/images/compass-solid-hover.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/build/_raw/images/compass-solid.svg b/build/_raw/images/compass-solid.svg new file mode 100644 index 00000000..5fabf5c1 --- /dev/null +++ b/build/_raw/images/compass-solid.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/build/_raw/images/copy-solid.png b/build/_raw/images/copy-solid.png new file mode 100644 index 00000000..247968fc Binary files /dev/null and b/build/_raw/images/copy-solid.png differ diff --git a/build/_raw/images/copy-solid.svg b/build/_raw/images/copy-solid.svg new file mode 100644 index 00000000..8f44140a --- /dev/null +++ b/build/_raw/images/copy-solid.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/eye.svg b/build/_raw/images/eye.svg new file mode 100644 index 00000000..29c5c401 --- /dev/null +++ b/build/_raw/images/eye.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/gear-solid-active.png b/build/_raw/images/gear-solid-active.png new file mode 100644 index 00000000..7fbbd74f Binary files /dev/null and b/build/_raw/images/gear-solid-active.png differ diff --git a/build/_raw/images/gear-solid-active.svg b/build/_raw/images/gear-solid-active.svg new file mode 100644 index 00000000..aea5ce13 --- /dev/null +++ b/build/_raw/images/gear-solid-active.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/gear-solid-hover.svg b/build/_raw/images/gear-solid-hover.svg new file mode 100644 index 00000000..c1a57b0c --- /dev/null +++ b/build/_raw/images/gear-solid-hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/gear-solid.png b/build/_raw/images/gear-solid.png new file mode 100644 index 00000000..39a7fc86 Binary files /dev/null and b/build/_raw/images/gear-solid.png differ diff --git a/build/_raw/images/gear-solid.svg b/build/_raw/images/gear-solid.svg new file mode 100644 index 00000000..8ba931f8 --- /dev/null +++ b/build/_raw/images/gear-solid.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/grid-solid-active.svg b/build/_raw/images/grid-solid-active.svg new file mode 100644 index 00000000..296799e3 --- /dev/null +++ b/build/_raw/images/grid-solid-active.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/grid-solid-hover.svg b/build/_raw/images/grid-solid-hover.svg new file mode 100644 index 00000000..feb9f415 --- /dev/null +++ b/build/_raw/images/grid-solid-hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/grid-solid.svg b/build/_raw/images/grid-solid.svg new file mode 100644 index 00000000..3caba6f7 --- /dev/null +++ b/build/_raw/images/grid-solid.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/image-default.png b/build/_raw/images/image-default.png new file mode 100644 index 00000000..0be90070 Binary files /dev/null and b/build/_raw/images/image-default.png differ diff --git a/build/_raw/images/list-solid-hover.svg b/build/_raw/images/list-solid-hover.svg new file mode 100644 index 00000000..328d4c00 --- /dev/null +++ b/build/_raw/images/list-solid-hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/list-solid.png b/build/_raw/images/list-solid.png new file mode 100644 index 00000000..b0aab4f8 Binary files /dev/null and b/build/_raw/images/list-solid.png differ diff --git a/build/_raw/images/list-solid.svg b/build/_raw/images/list-solid.svg new file mode 100644 index 00000000..7eeafbde --- /dev/null +++ b/build/_raw/images/list-solid.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/logo@128x.png b/build/_raw/images/logo@128x.png new file mode 100644 index 00000000..2000deed Binary files /dev/null and b/build/_raw/images/logo@128x.png differ diff --git a/build/_raw/images/logo@16x.png b/build/_raw/images/logo@16x.png new file mode 100644 index 00000000..39f22e41 Binary files /dev/null and b/build/_raw/images/logo@16x.png differ diff --git a/build/_raw/images/logo@32x.png b/build/_raw/images/logo@32x.png new file mode 100644 index 00000000..a8ea5348 Binary files /dev/null and b/build/_raw/images/logo@32x.png differ diff --git a/build/_raw/images/logo@48x.png b/build/_raw/images/logo@48x.png new file mode 100644 index 00000000..1f50cdd7 Binary files /dev/null and b/build/_raw/images/logo@48x.png differ diff --git a/build/_raw/images/qrcode-solid.png b/build/_raw/images/qrcode-solid.png new file mode 100644 index 00000000..53bb7632 Binary files /dev/null and b/build/_raw/images/qrcode-solid.png differ diff --git a/build/_raw/images/qrcode-solid.svg b/build/_raw/images/qrcode-solid.svg new file mode 100644 index 00000000..a58ca26c --- /dev/null +++ b/build/_raw/images/qrcode-solid.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/build/_raw/images/stamp-postcard.png b/build/_raw/images/stamp-postcard.png new file mode 100644 index 00000000..e446af7f Binary files /dev/null and b/build/_raw/images/stamp-postcard.png differ diff --git a/build/_raw/images/stamps-famous.png b/build/_raw/images/stamps-famous.png new file mode 100644 index 00000000..27a1355d Binary files /dev/null and b/build/_raw/images/stamps-famous.png differ diff --git a/build/_raw/images/user-solid.png b/build/_raw/images/user-solid.png new file mode 100644 index 00000000..4bae219b Binary files /dev/null and b/build/_raw/images/user-solid.png differ diff --git a/build/_raw/images/user-solid.svg b/build/_raw/images/user-solid.svg new file mode 100644 index 00000000..b4e01dbb --- /dev/null +++ b/build/_raw/images/user-solid.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/build/_raw/images/wallet-logo.png b/build/_raw/images/wallet-logo.png new file mode 100644 index 00000000..202dbe7c Binary files /dev/null and b/build/_raw/images/wallet-logo.png differ diff --git a/build/_raw/images/wallet-solid-active.png b/build/_raw/images/wallet-solid-active.png new file mode 100644 index 00000000..665705dc Binary files /dev/null and b/build/_raw/images/wallet-solid-active.png differ diff --git a/build/_raw/images/wallet-solid-active.svg b/build/_raw/images/wallet-solid-active.svg new file mode 100644 index 00000000..7819ac44 --- /dev/null +++ b/build/_raw/images/wallet-solid-active.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/wallet-solid-hover.svg b/build/_raw/images/wallet-solid-hover.svg new file mode 100644 index 00000000..7b35f374 --- /dev/null +++ b/build/_raw/images/wallet-solid-hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/images/wallet-solid.png b/build/_raw/images/wallet-solid.png new file mode 100644 index 00000000..f934aaa0 Binary files /dev/null and b/build/_raw/images/wallet-solid.png differ diff --git a/build/_raw/images/wallet-solid.svg b/build/_raw/images/wallet-solid.svg new file mode 100644 index 00000000..f6b22ea6 --- /dev/null +++ b/build/_raw/images/wallet-solid.svg @@ -0,0 +1,3 @@ + + + diff --git a/build/_raw/index.html b/build/_raw/index.html new file mode 100644 index 00000000..3a914732 --- /dev/null +++ b/build/_raw/index.html @@ -0,0 +1,27 @@ + + + + + + + + + + + UniSat Wallet + + + +
+ + + diff --git a/build/_raw/manifest/_base_v2.json b/build/_raw/manifest/_base_v2.json new file mode 100644 index 00000000..35641acf --- /dev/null +++ b/build/_raw/manifest/_base_v2.json @@ -0,0 +1,45 @@ +{ + "manifest_version": 2, + "name": "__MSG_appName__", + "version": "1.0", + + "default_locale": "en", + "description": "__MSG_appDescription__", + "icons": { + "16": "/images/logo@16x.png", + "32": "/images/logo@32x.png", + "48": "/images/logo@48x.png", + "128": "/images/logo@128x.png" + }, + + "browser_action": { + "default_popup": "index.html", + "default_icon": { + "16": "/images/logo@16x.png", + "32": "/images/logo@32x.png", + "48": "/images/logo@48x.png", + "128": "/images/logo@128x.png" + }, + "default_title": "__MSG_appName__" + }, + + "author": "https://unisat.io", + "background": { + "page": "background.html", + "persistent": true + }, + "homepage_url": "https://unisat.io", + "permissions": ["storage", "unlimitedStorage", "activeTab", "notifications"], + "short_name": "__MSG_appName__", + + "content_scripts": [ + { + "matches": [""], + "js": ["content-script.js"], + "run_at": "document_start", + "all_frames": true + } + ], + + "web_accessible_resources": ["pageProvider.js"] +} diff --git a/build/_raw/manifest/_base_v3.json b/build/_raw/manifest/_base_v3.json new file mode 100644 index 00000000..c7058192 --- /dev/null +++ b/build/_raw/manifest/_base_v3.json @@ -0,0 +1,52 @@ +{ + "manifest_version": 3, + "name": "__MSG_appName__", + "version": "1.0", + + "default_locale": "en", + "description": "__MSG_appDescription__", + "icons": { + "16": "/images/logo@16x.png", + "32": "/images/logo@32x.png", + "48": "/images/logo@48x.png", + "128": "/images/logo@128x.png" + }, + + "action": { + "default_popup": "index.html", + "default_icon": { + "16": "/images/logo@16x.png", + "32": "/images/logo@32x.png", + "48": "/images/logo@48x.png", + "128": "/images/logo@128x.png" + }, + "default_title": "__MSG_appName__" + }, + + "author": "https://unisat.io", + "background": { + "service_worker": "background.js" + }, + "homepage_url": "https://unisat.io", + "permissions": ["storage", "unlimitedStorage", "activeTab", "notifications"], + "short_name": "__MSG_appName__", + + "content_scripts": [ + { + "matches": [""], + "js": ["content-script.js"], + "run_at": "document_start", + "all_frames": true + } + ], + + "web_accessible_resources": [ + { + "resources": ["pageProvider.js"], + "matches": [""] + } + ], + "content_security_policy": { + "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'" + } +} diff --git a/build/_raw/manifest/brave.json b/build/_raw/manifest/brave.json new file mode 100644 index 00000000..3e2cd527 --- /dev/null +++ b/build/_raw/manifest/brave.json @@ -0,0 +1,7 @@ +{ + "externally_connectable": { + "matches": ["https://unisat.io/*"], + "ids": ["*"] + }, + "minimum_chrome_version": "66" +} diff --git a/build/_raw/manifest/chrome.json b/build/_raw/manifest/chrome.json new file mode 100644 index 00000000..70879b5d --- /dev/null +++ b/build/_raw/manifest/chrome.json @@ -0,0 +1,7 @@ +{ + "externally_connectable": { + "matches": ["https://unisat.io/*"], + "ids": ["*"] + }, + "minimum_chrome_version": "88" +} diff --git a/build/_raw/manifest/edge.json b/build/_raw/manifest/edge.json new file mode 100644 index 00000000..3e2cd527 --- /dev/null +++ b/build/_raw/manifest/edge.json @@ -0,0 +1,7 @@ +{ + "externally_connectable": { + "matches": ["https://unisat.io/*"], + "ids": ["*"] + }, + "minimum_chrome_version": "66" +} diff --git a/build/_raw/manifest/firefox.json b/build/_raw/manifest/firefox.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/build/_raw/manifest/firefox.json @@ -0,0 +1 @@ +{} diff --git a/build/paths.js b/build/paths.js new file mode 100644 index 00000000..a544189e --- /dev/null +++ b/build/paths.js @@ -0,0 +1,36 @@ +const path = require('path'); +const fs = require('fs'); +const appRoot = fs.realpathSync(process.cwd()); +const rootResolve = path.resolve.bind(path, appRoot); +const buildPath = 'dist'; + +function getBrowserPaths(browser) { + let ret = { + root: appRoot, + src: rootResolve('src'), + indexHtml: rootResolve('build/_raw/index.html'), + backgroundHtml: rootResolve('src/background/background.html'), + dist: rootResolve('dist/' + browser), + rootResolve, + dotenv: rootResolve('.env'), + appPath: rootResolve('.'), + appBuild: rootResolve(buildPath), + appPublic: rootResolve('public'), + appHtml: rootResolve('public/index.html'), + appPackageJson: rootResolve('package.json'), + appSrc: rootResolve('src'), + appTsConfig: rootResolve('tsconfig.json'), + appJsConfig: rootResolve('jsconfig.json'), + yarnLockFile: rootResolve('yarn.lock'), + proxySetup: rootResolve('src/setupProxy.js'), + appNodeModules: rootResolve('node_modules'), + appWebpackCache: rootResolve('node_modules/.cache'), + appTsBuildInfoFile: rootResolve('node_modules/.cache/tsconfig.tsbuildinfo') + // publicUrlOrPath, + }; + return ret; +} + +module.exports = { + getBrowserPaths +}; diff --git a/build/plugins/AssetReplacePlugin.js b/build/plugins/AssetReplacePlugin.js new file mode 100644 index 00000000..80f8cc39 --- /dev/null +++ b/build/plugins/AssetReplacePlugin.js @@ -0,0 +1,58 @@ +/** + * replace string with other assets content at "afterProcessAssets" + */ + +class AssetReplacePlugin { + constructor(options) { + this.options = options; + } + apply(compiler) { + const { + webpack: { + sources: { RawSource } + } + } = compiler; + compiler.hooks.make.tapAsync('AssetReplacePlugin', (compilation, callback) => { + compilation.hooks.afterProcessAssets.tap('AssetReplacePlugin', () => { + const replaceArr = Object.entries(this.options) + .map(([k, v]) => { + let assetName; + for (const chunk of compilation.chunks.values()) { + if (chunk.name === v) { + assetName = chunk.files.values().next().value; + + break; + } + } + return [k, assetName]; + }) + .filter(([, assetName]) => assetName); + + const replaceFn = replaceArr + .map(([k, assetName]) => { + // github.com/webpack/webpack-sources/blob/master/lib/ConcatSource.js + const content = compilation.assets[assetName]?.source(); + + return (source) => { + return source.split(new RegExp(`['"]?${k}['"]?`)).join(JSON.stringify(content)); + }; + }) + .reduce((m, n) => (content) => n(m(content))); + + for (const chunk of compilation.chunks.values()) { + const fileName = chunk.files.values().next().value; + if (!replaceArr.includes(([, assetName]) => assetName === fileName)) { + compilation.updateAsset(fileName, (content) => { + const result = replaceFn(content.source()); + + return new RawSource(result); + }); + } + } + }); + callback(); + }); + } +} + +module.exports = AssetReplacePlugin; diff --git a/build/pull_translation.js b/build/pull_translation.js new file mode 100644 index 00000000..16cc8b40 --- /dev/null +++ b/build/pull_translation.js @@ -0,0 +1,44 @@ +const { Client } = require('@notionhq/client'); +const fs = require('fs'); +const { notionKey } = require('../.key.config.js'); +const { token, database_id } = notionKey; +let notion = new Client({ auth: token }); +const Languages = [ + { name: 'English', symbol: 'en', messages: {} }, + { name: 'Chinese', symbol: 'zh_CN', messages: {} }, + { name: 'Japanese', symbol: 'ja', messages: {} }, + { name: 'Spanish', symbol: 'es', messages: {} } +]; + +function getPropertyPlainText(property) { + let arr = property.title || property.rich_text; + if (arr.length == 0) return ''; + return arr[0].plain_text; +} + +let run = async () => { + let langMap = {}; + Languages.forEach((v) => { + langMap[v.name] = v; + }); + let data = await notion.databases.query({ + database_id + }); + data.results.forEach((v) => { + Languages.forEach((lang) => { + let key = getPropertyPlainText(v.properties['Name']); + if (key) { + lang.messages[key] = { + message: getPropertyPlainText(v.properties[lang.name]) + }; + } else { + console.error('Invalid Key!', key); + } + }); + }); + Languages.forEach((lang) => { + fs.mkdirSync(`./build/_raw/_locales/${lang.symbol}/`, { recursive: true }); + fs.writeFileSync(`./build/_raw/_locales/${lang.symbol}/messages.json`, JSON.stringify(lang.messages)); + }); +}; +run(); diff --git a/build/webpack.common.config.js b/build/webpack.common.config.js new file mode 100644 index 00000000..6d51fe2d --- /dev/null +++ b/build/webpack.common.config.js @@ -0,0 +1,543 @@ +/* eslint-disable indent */ +const webpack = require('webpack'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const TSConfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); +const ESLintWebpackPlugin = require('eslint-webpack-plugin'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const path = require('path'); +const fs = require('fs'); +const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent'); +// style files regexes +const cssRegex = /\.css$/; +const cssModuleRegex = /\.module\.css$/; +const sassRegex = /\.(scss|sass)$/; +const sassModuleRegex = /\.module\.(scss|sass)$/; +const lessRegex = /\.less$/; +const lessModuleRegex = /\.module\.less$/; +const stylusRegex = /\.styl$/; +const stylusModuleRegex = /\.module\.styl$/; +const WasmModuleWebpackPlugin = require('wasm-module-webpack-plugin'); +const { getBrowserPaths } = require('./paths'); + +const config = (env) => { + const version = env.version; + const paths = getBrowserPaths(env.browser); + // Check if Tailwind config exists + const useTailwind = fs.existsSync(path.join(paths.appPath, 'tailwind.config.js')); + + const shouldUseSourceMap = false; + const imageInlineSizeLimit = parseInt(process.env.IMAGE_INLINE_SIZE_LIMIT || '10000'); + const isEnvDevelopment = true; + const isEnvProduction = false; + const shouldUseReactRefresh = false; + const hasJsxRuntime = (() => { + if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') { + return false; + } + + try { + require.resolve('react/jsx-runtime'); + return true; + } catch (e) { + return false; + } + })(); + + // common function to get style loaders + const getStyleLoaders = (cssOptions, preProcessor) => { + const loaders = [ + isEnvDevelopment && require.resolve('style-loader'), + isEnvProduction && { + loader: MiniCssExtractPlugin.loader, + // css is located in `static/css`, use '../../' to locate index.html folder + // in production `paths.publicUrlOrPath` can be a relative path + options: paths.publicUrlOrPath.startsWith('.') ? { publicPath: '../../' } : {} + }, + { + loader: require.resolve('css-loader'), + options: cssOptions + }, + { + // Options for PostCSS as we reference these options twice + // Adds vendor prefixing based on your specified browser support in + // package.json + loader: require.resolve('postcss-loader'), + options: { + postcssOptions: { + // Necessary for external CSS imports to work + // https://github.com/facebook/create-react-app/issues/2677 + ident: 'postcss', + config: false, + plugins: !useTailwind + ? [ + 'postcss-flexbugs-fixes', + ['postcss-preset-env', { autoprefixer: { flexbox: 'no-2009' }, stage: 3 }], + // Adds PostCSS Normalize as the reset css with default options, + // so that it honors browserslist config in package.json + // which in turn let's users customize the target behavior as per their needs. + 'postcss-normalize' + ] + : [ + 'tailwindcss', + 'postcss-flexbugs-fixes', + ['postcss-preset-env', { autoprefixer: { flexbox: 'no-2009' }, stage: 3 }] + ] + }, + sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment + } + } + ].filter(Boolean); + if (preProcessor) { + let preProcessorOptions = { + sourceMap: true + }; + if (preProcessor === 'less-loader') { + preProcessorOptions = { + sourceMap: true, + // 自定义主题 + lessOptions: { + modifyVars: { + 'primary-color': 'rgb(234,202,68)', + 'primary-color-active': '#383535', + 'input-icon-hover-color': '#FFFFFF', + 'component-background': '#1C1919', + 'select-dropdown-bg': '#2A2626', + 'select-item-selected-bg': '#332F2F', + 'select-item-active-bg': '#332F2F', + 'input-border-color': 'rgba(255,255,255,0.2)', + borderColor: 'rgba(255,255,255,0.2)', + 'input-hover-border-color': 'rgba(255,255,255,0.4)', + hoverBorderColor: 'rgba(255,255,255,0.4)', + 'border-color-base': 'rgba(255,255,255,0.2)', + 'border-width-base': '0', + 'animation-duration-slow': '0.08s', + 'animation-duration-base': '0.08s', + // "checkbox-border-width": "1px", + 'layout-header-background': '#2A2626', + 'layout-header-padding': '0 1.875rem', + 'layout-header-height': '5.625rem', + 'layout-footer-padding': 'unset', + 'border-radius-base': '0.3rem', + 'checkbox-border-radius': '0.125rem', + // 'checkbox-color': '#2A2626', + // 'checkbox-check-color': '#D7721F', + 'heading-color': '#ffffff', + 'font-size-base': '1.125rem', + 'line-height-base': '1.375rem', + 'text-color': '#ffffff', + 'text-color-secondary': '#AAAAAA', + 'height-lg': '3.875rem', + 'checkbox-size': '1.5rem', + 'btn-text-hover-bg': '#383535', + 'input-disabled-color': 'rgba(255,255,255,0.6)' + }, + javascriptEnabled: true + } + }; + } + loaders.push( + { + loader: require.resolve('resolve-url-loader'), + options: { + sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, + root: paths.appSrc + } + }, + { + loader: require.resolve(preProcessor), + // options: { + // sourceMap: true, + // }, + options: preProcessorOptions + } + ); + } + return loaders; + }; + + const config = { + entry: { + background: paths.rootResolve('src/background/index.ts'), + 'content-script': paths.rootResolve('src/content-script/index.ts'), + pageProvider: paths.rootResolve('src/content-script/pageProvider/index.ts'), + ui: paths.rootResolve('src/ui/index.tsx') + }, + output: { + path: paths.dist, + filename: '[name].js', + publicPath: '/', + globalObject: 'this' + }, + module: { + rules: [ + // Handle node_modules packages that contain sourcemaps + shouldUseSourceMap && { + enforce: 'pre', + exclude: /@babel(?:\/|\\{1,2})runtime/, + test: /\.(js|mjs|jsx|ts|tsx|css)$/, + loader: require.resolve('source-map-loader') + }, + { + // "oneOf" will traverse all following loaders until one will + // match the requirements. When no loader matches it will fall + // back to the "file" loader at the end of the loader list. + oneOf: [ + // TODO: Merge this config once `image/avif` is in the mime-db + // https://github.com/jshttp/mime-db + { + test: [/\.avif$/], + type: 'asset', + mimetype: 'image/avif', + parser: { + dataUrlCondition: { + maxSize: imageInlineSizeLimit + } + } + }, + // "url" loader works like "file" loader except that it embeds assets + // smaller than specified limit in bytes as data URLs to avoid requests. + // A missing `test` is equivalent to a match. + { + test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/], + type: 'asset', + parser: { + dataUrlCondition: { + maxSize: imageInlineSizeLimit + } + } + }, + { + test: /\.svg$/, + use: [ + { + loader: require.resolve('@svgr/webpack'), + options: { + prettier: false, + svgo: false, + svgoConfig: { + plugins: [{ removeViewBox: false }] + }, + titleProp: true, + ref: true + } + }, + { + loader: require.resolve('file-loader'), + options: { + name: 'static/media/[name].[hash].[ext]' + } + } + ], + issuer: { + and: [/\.(ts|tsx|js|jsx|md|mdx)$/] + } + }, + // Process application JS with Babel. + // The preset includes JSX, Flow, TypeScript, and some ESnext features. + { + test: /\.(js|mjs|jsx|ts|tsx)$/, + include: paths.appSrc, + loader: require.resolve('babel-loader'), + options: { + customize: require.resolve('babel-preset-react-app/webpack-overrides'), + presets: [ + [ + require.resolve('babel-preset-react-app'), + { + runtime: hasJsxRuntime ? 'automatic' : 'classic' + } + ] + ], + + plugins: [isEnvDevelopment && shouldUseReactRefresh && require.resolve('react-refresh/babel')].filter( + Boolean + ), + // This is a feature of `babel-loader` for webpack (not Babel itself). + // It enables caching results in ./node_modules/.cache/babel-loader/ + // directory for faster rebuilds. + cacheDirectory: true, + // See #6846 for context on why cacheCompression is disabled + cacheCompression: false, + compact: isEnvProduction + } + }, + // Process any JS outside of the app with Babel. + // Unlike the application JS, we only compile the standard ES features. + { + test: /\.(js|mjs)$/, + exclude: /@babel(?:\/|\\{1,2})runtime/, + loader: require.resolve('babel-loader'), + options: { + babelrc: false, + configFile: false, + compact: false, + presets: [[require.resolve('babel-preset-react-app/dependencies'), { helpers: true }]], + cacheDirectory: true, + // See #6846 for context on why cacheCompression is disabled + cacheCompression: false, + + // Babel sourcemaps are needed for debugging into node_modules + // code. Without the options below, debuggers like VSCode + // show incorrect code and set breakpoints on the wrong lines. + sourceMaps: shouldUseSourceMap, + inputSourceMap: shouldUseSourceMap + } + }, + // "postcss" loader applies autoprefixer to our CSS. + // "css" loader resolves paths in CSS and adds assets as dependencies. + // "style" loader turns CSS into JS modules that inject