├── .editorconfig ├── .github ├── issue_template.md └── workflows │ ├── auto-approve.yml │ ├── auto-merge.yml │ ├── lock.yml │ ├── pr-any.yml │ └── push-master.yml ├── .gitignore ├── .mailmap ├── .npmignore ├── .nvmrc ├── .prettierignore ├── .prettierrc.cjs ├── .yarn └── plugins │ └── .keep ├── .yarnrc.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── CONTRIBUTORS ├── LICENSE ├── README.md ├── docs ├── .nojekyll ├── assets │ ├── background_top.svg │ ├── chrome.svg │ ├── firefox.svg │ ├── header_logo.svg │ ├── hero.svg │ └── logo.svg ├── extension-overview.png ├── favicon.ico ├── fonts │ ├── Inter │ │ ├── Inter-Italic-VariableFont_opsz,wght.ttf │ │ ├── Inter-VariableFont_opsz,wght.ttf │ │ ├── OFL.txt │ │ ├── README.txt │ │ └── static │ │ │ ├── Inter_18pt-Black.ttf │ │ │ ├── Inter_18pt-BlackItalic.ttf │ │ │ ├── Inter_18pt-Bold.ttf │ │ │ ├── Inter_18pt-BoldItalic.ttf │ │ │ ├── Inter_18pt-ExtraBold.ttf │ │ │ ├── Inter_18pt-ExtraBoldItalic.ttf │ │ │ ├── Inter_18pt-ExtraLight.ttf │ │ │ ├── Inter_18pt-ExtraLightItalic.ttf │ │ │ ├── Inter_18pt-Italic.ttf │ │ │ ├── Inter_18pt-Light.ttf │ │ │ ├── Inter_18pt-LightItalic.ttf │ │ │ ├── Inter_18pt-Medium.ttf │ │ │ ├── Inter_18pt-MediumItalic.ttf │ │ │ ├── Inter_18pt-Regular.ttf │ │ │ ├── Inter_18pt-SemiBold.ttf │ │ │ ├── Inter_18pt-SemiBoldItalic.ttf │ │ │ ├── Inter_18pt-Thin.ttf │ │ │ ├── Inter_18pt-ThinItalic.ttf │ │ │ ├── Inter_24pt-Black.ttf │ │ │ ├── Inter_24pt-BlackItalic.ttf │ │ │ ├── Inter_24pt-Bold.ttf │ │ │ ├── Inter_24pt-BoldItalic.ttf │ │ │ ├── Inter_24pt-ExtraBold.ttf │ │ │ ├── Inter_24pt-ExtraBoldItalic.ttf │ │ │ ├── Inter_24pt-ExtraLight.ttf │ │ │ ├── Inter_24pt-ExtraLightItalic.ttf │ │ │ ├── Inter_24pt-Italic.ttf │ │ │ ├── Inter_24pt-Light.ttf │ │ │ ├── Inter_24pt-LightItalic.ttf │ │ │ ├── Inter_24pt-Medium.ttf │ │ │ ├── Inter_24pt-MediumItalic.ttf │ │ │ ├── Inter_24pt-Regular.ttf │ │ │ ├── Inter_24pt-SemiBold.ttf │ │ │ ├── Inter_24pt-SemiBoldItalic.ttf │ │ │ ├── Inter_24pt-Thin.ttf │ │ │ ├── Inter_24pt-ThinItalic.ttf │ │ │ ├── Inter_28pt-Black.ttf │ │ │ ├── Inter_28pt-BlackItalic.ttf │ │ │ ├── Inter_28pt-Bold.ttf │ │ │ ├── Inter_28pt-BoldItalic.ttf │ │ │ ├── Inter_28pt-ExtraBold.ttf │ │ │ ├── Inter_28pt-ExtraBoldItalic.ttf │ │ │ ├── Inter_28pt-ExtraLight.ttf │ │ │ ├── Inter_28pt-ExtraLightItalic.ttf │ │ │ ├── Inter_28pt-Italic.ttf │ │ │ ├── Inter_28pt-Light.ttf │ │ │ ├── Inter_28pt-LightItalic.ttf │ │ │ ├── Inter_28pt-Medium.ttf │ │ │ ├── Inter_28pt-MediumItalic.ttf │ │ │ ├── Inter_28pt-Regular.ttf │ │ │ ├── Inter_28pt-SemiBold.ttf │ │ │ ├── Inter_28pt-SemiBoldItalic.ttf │ │ │ ├── Inter_28pt-Thin.ttf │ │ │ └── Inter_28pt-ThinItalic.ttf │ ├── Manrope │ │ ├── Manrope-VariableFont_wght.ttf │ │ ├── OFL.txt │ │ ├── README.txt │ │ └── static │ │ │ ├── Manrope-Bold.ttf │ │ │ ├── Manrope-ExtraBold.ttf │ │ │ ├── Manrope-ExtraLight.ttf │ │ │ ├── Manrope-Light.ttf │ │ │ ├── Manrope-Medium.ttf │ │ │ ├── Manrope-Regular.ttf │ │ │ └── Manrope-SemiBold.ttf │ └── Unbounded │ │ ├── OFL.txt │ │ ├── README.txt │ │ ├── Unbounded-VariableFont_wght.ttf │ │ └── static │ │ ├── Unbounded-Black.ttf │ │ ├── Unbounded-Bold.ttf │ │ ├── Unbounded-ExtraBold.ttf │ │ ├── Unbounded-ExtraLight.ttf │ │ ├── Unbounded-Light.ttf │ │ ├── Unbounded-Medium.ttf │ │ ├── Unbounded-Regular.ttf │ │ └── Unbounded-SemiBold.ttf ├── index.html ├── logo.jpg └── style.css ├── eslint.config.js ├── i18next-scanner.config.cjs ├── package.json ├── packages ├── extension-base │ ├── README.md │ ├── package.json │ ├── src │ │ ├── background │ │ │ ├── RequestBytesSign.ts │ │ │ ├── RequestExtrinsicSign.ts │ │ │ ├── handlers │ │ │ │ ├── Extension.spec.ts │ │ │ │ ├── Extension.ts │ │ │ │ ├── State.ts │ │ │ │ ├── Tabs.ts │ │ │ │ ├── helpers.ts │ │ │ │ ├── index.ts │ │ │ │ └── subscriptions.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── bundle.ts │ │ ├── defaults.ts │ │ ├── index.ts │ │ ├── packageDetect.ts │ │ ├── packageInfo.ts │ │ ├── page │ │ │ ├── Accounts.ts │ │ │ ├── Injected.ts │ │ │ ├── Metadata.ts │ │ │ ├── PostMessageProvider.ts │ │ │ ├── Signer.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── stores │ │ │ ├── Accounts.ts │ │ │ ├── Base.ts │ │ │ ├── Metadata.ts │ │ │ └── index.ts │ │ ├── types.ts │ │ └── utils │ │ │ ├── canDerive.ts │ │ │ ├── getId.ts │ │ │ ├── index.ts │ │ │ └── portUtils.ts │ ├── tsconfig.build.json │ └── tsconfig.spec.json ├── extension-chains │ ├── README.md │ ├── package.json │ ├── src │ │ ├── bundle.ts │ │ ├── index.ts │ │ ├── packageDetect.ts │ │ ├── packageInfo.ts │ │ └── types.ts │ └── tsconfig.build.json ├── extension-compat-metamask │ ├── README.md │ ├── package.json │ ├── src │ │ ├── bundle.ts │ │ ├── index.ts │ │ ├── packageDetect.ts │ │ └── packageInfo.ts │ └── tsconfig.build.json ├── extension-dapp │ ├── README.md │ ├── package.json │ ├── src │ │ ├── bundle.ts │ │ ├── index.ts │ │ ├── packageDetect.ts │ │ ├── packageInfo.ts │ │ ├── util.ts │ │ ├── wrapBytes.spec.ts │ │ └── wrapBytes.ts │ ├── tsconfig.build.json │ └── tsconfig.spec.json ├── extension-inject │ ├── README.md │ ├── package.json │ ├── src │ │ ├── bundle.ts │ │ ├── chrome.ts │ │ ├── crossenv.ts │ │ ├── cyrb53.spec.ts │ │ ├── cyrb53.ts │ │ ├── index.ts │ │ ├── packageDetect.ts │ │ ├── packageInfo.ts │ │ └── types.ts │ ├── tsconfig.build.json │ └── tsconfig.spec.json ├── extension-mocks │ ├── .skip-build │ ├── .skip-npm │ ├── README.md │ ├── package.json │ ├── src │ │ ├── chrome.ts │ │ ├── chromeWrapper.ts │ │ ├── empty.js │ │ ├── fileMock.cjs │ │ ├── loader-empty.js │ │ └── react-i18next.ts │ └── tsconfig.build.json ├── extension-ui │ ├── .skip-build │ ├── .skip-npm │ ├── README.md │ ├── package.json │ ├── src │ │ ├── MetadataCache.ts │ │ ├── Popup │ │ │ ├── Accounts │ │ │ │ ├── Account.spec.tsx │ │ │ │ ├── Account.tsx │ │ │ │ ├── AccountsTree.tsx │ │ │ │ ├── AddAccount.tsx │ │ │ │ ├── AddAccountImage.tsx │ │ │ │ └── index.tsx │ │ │ ├── AuthManagement │ │ │ │ ├── AccountManagement.tsx │ │ │ │ ├── WebsiteEntry.tsx │ │ │ │ └── index.tsx │ │ │ ├── Authorize │ │ │ │ ├── Authorize.spec.tsx │ │ │ │ ├── NoAccount.tsx │ │ │ │ ├── Request.tsx │ │ │ │ └── index.tsx │ │ │ ├── CreateAccount │ │ │ │ ├── CreateAccount.spec.tsx │ │ │ │ ├── Mnemonic.tsx │ │ │ │ └── index.tsx │ │ │ ├── Derive │ │ │ │ ├── AddressDropdown.tsx │ │ │ │ ├── DerivationPath.tsx │ │ │ │ ├── Derive.spec.tsx │ │ │ │ ├── SelectParent.tsx │ │ │ │ └── index.tsx │ │ │ ├── Export.spec.tsx │ │ │ ├── Export.tsx │ │ │ ├── ExportAll.tsx │ │ │ ├── Forget.tsx │ │ │ ├── ImportLedger.tsx │ │ │ ├── ImportQr.spec.tsx │ │ │ ├── ImportQr.tsx │ │ │ ├── ImportSeed │ │ │ │ ├── ImportSeed.spec.tsx │ │ │ │ ├── SeedAndPath.tsx │ │ │ │ └── index.tsx │ │ │ ├── Metadata │ │ │ │ ├── Request.tsx │ │ │ │ └── index.tsx │ │ │ ├── PhishingDetected.tsx │ │ │ ├── RestoreJson.tsx │ │ │ ├── Signing │ │ │ │ ├── Bytes.tsx │ │ │ │ ├── Extrinsic.tsx │ │ │ │ ├── LedgerSign.tsx │ │ │ │ ├── Qr.tsx │ │ │ │ ├── Request │ │ │ │ │ ├── SignArea.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── Signing.spec.tsx │ │ │ │ ├── TransactionIndex.tsx │ │ │ │ ├── Unlock.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── metadataMock.ts │ │ │ ├── Welcome.tsx │ │ │ └── index.tsx │ │ ├── adapter.d.ts │ │ ├── assets │ │ │ ├── arrow-down.svg │ │ │ ├── checkmark.svg │ │ │ ├── details.svg │ │ │ ├── images.d.ts │ │ │ ├── pjs.svg │ │ │ ├── spinner-white.png │ │ │ └── spinner.png │ │ ├── components │ │ │ ├── AccountNamePasswordCreation.spec.tsx │ │ │ ├── AccountNamePasswordCreation.tsx │ │ │ ├── ActionBar.tsx │ │ │ ├── ActionText.tsx │ │ │ ├── Address.spec.tsx │ │ │ ├── Address.tsx │ │ │ ├── BackButton.tsx │ │ │ ├── Box.tsx │ │ │ ├── BoxWithLabel.tsx │ │ │ ├── Button.tsx │ │ │ ├── ButtonArea.tsx │ │ │ ├── ButtonWithSubtitle.tsx │ │ │ ├── Checkbox.tsx │ │ │ ├── Dropdown.tsx │ │ │ ├── ErrorBoundary.tsx │ │ │ ├── Icon.tsx │ │ │ ├── Identicon.tsx │ │ │ ├── InputFileWithLabel.tsx │ │ │ ├── InputFilter.tsx │ │ │ ├── InputWithLabel.tsx │ │ │ ├── Label.tsx │ │ │ ├── Link.tsx │ │ │ ├── List.tsx │ │ │ ├── Loading.tsx │ │ │ ├── Main.tsx │ │ │ ├── Menu.tsx │ │ │ ├── MenuDivider.tsx │ │ │ ├── MenuItem.tsx │ │ │ ├── MnemonicSeed.tsx │ │ │ ├── NextStepButton.tsx │ │ │ ├── RemoveAuth.tsx │ │ │ ├── Spinner.tsx │ │ │ ├── Svg.tsx │ │ │ ├── Switch.tsx │ │ │ ├── Table.tsx │ │ │ ├── TextAreaWithLabel.tsx │ │ │ ├── TextInputs.ts │ │ │ ├── Toast │ │ │ │ ├── Toast.tsx │ │ │ │ └── ToastProvider.tsx │ │ │ ├── ValidatedInput.tsx │ │ │ ├── VerticalSpace.tsx │ │ │ ├── View.tsx │ │ │ ├── Warning.tsx │ │ │ ├── contexts.tsx │ │ │ ├── index.ts │ │ │ ├── themes.ts │ │ │ └── types.ts │ │ ├── createView.tsx │ │ ├── hooks │ │ │ ├── index.js │ │ │ ├── useGenesisHashOptions.ts │ │ │ ├── useIsMounted.ts │ │ │ ├── useIsPopup.ts │ │ │ ├── useLedger.ts │ │ │ ├── useMetadata.ts │ │ │ ├── useOutsideClick.ts │ │ │ ├── useToast.tsx │ │ │ └── useTranslation.ts │ │ ├── i18n │ │ │ ├── Backend.ts │ │ │ ├── cache.ts │ │ │ └── i18n.ts │ │ ├── index.ts │ │ ├── messaging.spec.ts │ │ ├── messaging.ts │ │ ├── partials │ │ │ ├── AccountSelection.tsx │ │ │ ├── Header.spec.tsx │ │ │ ├── Header.tsx │ │ │ ├── HeaderWithSteps.tsx │ │ │ ├── MenuAdd.tsx │ │ │ ├── MenuSettings.tsx │ │ │ ├── Name.tsx │ │ │ ├── Password.tsx │ │ │ └── index.ts │ │ ├── styled.ts │ │ ├── testHelpers.ts │ │ ├── types.ts │ │ └── util │ │ │ ├── buildHierarchy.spec.ts │ │ │ ├── buildHierarchy.ts │ │ │ ├── chains.ts │ │ │ ├── defaultType.ts │ │ │ ├── getLanguageOptions.ts │ │ │ ├── getNetworkMap.ts │ │ │ ├── getParentNameSuri.ts │ │ │ ├── legerChains.ts │ │ │ ├── nextDerivationPath.spec.ts │ │ │ ├── nextDerivationPath.ts │ │ │ ├── typeGuards.ts │ │ │ └── validators.ts │ ├── tsconfig.build.json │ └── tsconfig.spec.json └── extension │ ├── .skip-npm │ ├── README.md │ ├── manifest_chrome.json │ ├── manifest_firefox.json │ ├── package.json │ ├── public │ ├── favicon.ico │ ├── fonts │ │ ├── fonts.css │ │ ├── nunito-sans-v6-vietnamese_latin-ext_latin-regular.eot │ │ ├── nunito-sans-v6-vietnamese_latin-ext_latin-regular.svg │ │ ├── nunito-sans-v6-vietnamese_latin-ext_latin-regular.ttf │ │ ├── nunito-sans-v6-vietnamese_latin-ext_latin-regular.woff │ │ └── nunito-sans-v6-vietnamese_latin-ext_latin-regular.woff2 │ ├── images │ │ ├── icon-128.png │ │ ├── icon-16.png │ │ ├── icon-32.png │ │ ├── icon-48.png │ │ ├── icon-64.png │ │ └── pjs.svg │ ├── index.html │ ├── locales │ │ ├── bn │ │ │ └── translation.json │ │ ├── en │ │ │ └── translation.json │ │ ├── fr │ │ │ └── translation.json │ │ ├── pl │ │ │ └── translation.json │ │ ├── th │ │ │ └── translation.json │ │ ├── tr │ │ │ └── translation.json │ │ ├── ur │ │ │ └── translation.json │ │ └── zh │ │ │ └── translation.json │ ├── notification.html │ └── theme.css │ ├── src │ ├── background.ts │ ├── content.ts │ ├── extension.ts │ ├── packageDetect.ts │ ├── packageInfo.ts │ └── page.ts │ ├── tsconfig.build.json │ ├── tsconfig.spec.json │ ├── webpack.config.cjs │ └── webpack.shared.cjs ├── rollup.config.js ├── scripts └── diff.sh ├── test-bundle.html ├── tsconfig.base.json ├── tsconfig.build.json ├── tsconfig.eslint.json ├── tsconfig.json ├── tsconfig.webpack.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | [*] 3 | indent_style=space 4 | indent_size=2 5 | tab_width=2 6 | end_of_line=lf 7 | charset=utf-8 8 | trim_trailing_whitespace=true 9 | max_line_length=120 10 | insert_final_newline=true 11 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | * **I'm submitting a ...** 24 | 25 | 32 | 33 | - [ ] Bug report 34 | - [ ] Feature request 35 | - [ ] Support request 36 | - [ ] Other 37 | 38 | 39 | * **What is the current behavior and expected behavior?** 40 | 41 | 49 | 50 | 51 | * **What is the motivation for changing the behavior?** 52 | 53 | 61 | 62 | 63 | * **Please tell us about your environment:** 64 | 65 | 74 | 75 | - Version: 76 | - Environment: 77 | 78 | - [ ] Node.js 79 | - [ ] Browser 80 | - [ ] Other (limited support for other environments) 81 | 82 | - Language: 83 | 84 | - [ ] JavaScript 85 | - [ ] TypeScript (include tsc --version) 86 | - [ ] Other 87 | -------------------------------------------------------------------------------- /.github/workflows/auto-approve.yml: -------------------------------------------------------------------------------- 1 | name: bot 2 | 3 | on: 4 | pull_request: 5 | types: [labeled] 6 | 7 | jobs: 8 | approve: 9 | if: "! startsWith(github.event.head_commit.message, '[CI Skip]') && (!github.event.pull_request || github.event.pull_request.head.repo.full_name == github.repository)" 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: jacogr/action-approve@795afd1dd096a2071d7ec98740661af4e853b7da 13 | with: 14 | authors: jacogr, TarikGul 15 | labels: -auto 16 | token: ${{ secrets.GH_PAT_BOT }} 17 | -------------------------------------------------------------------------------- /.github/workflows/auto-merge.yml: -------------------------------------------------------------------------------- 1 | name: bot 2 | 3 | on: 4 | pull_request: 5 | types: [labeled] 6 | 7 | jobs: 8 | merge: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: jacogr/action-merge@d2d64b4545acd93b0a9575177d3d215ae3f92029 12 | with: 13 | checks: pr (build),pr (lint),pr (test) 14 | labels: -auto 15 | strategy: squash 16 | token: ${{ secrets.GH_PAT_BOT }} 17 | -------------------------------------------------------------------------------- /.github/workflows/lock.yml: -------------------------------------------------------------------------------- 1 | name: 'Lock Threads' 2 | 3 | on: 4 | schedule: 5 | - cron: '20 2/3 * * *' 6 | 7 | jobs: 8 | lock: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: dessant/lock-threads@c1b35aecc5cdb1a34539d14196df55838bb2f836 12 | with: 13 | github-token: ${{ secrets.GH_PAT_BOT }} 14 | issue-inactive-days: '7' 15 | issue-comment: > 16 | This thread has been automatically locked since there has not been 17 | any recent activity after it was closed. Please open a new issue 18 | if you think you have a related problem or query. 19 | pr-inactive-days: '2' 20 | pr-comment: > 21 | This pull request has been automatically locked since there 22 | has not been any recent activity after it was closed. 23 | Please open a new issue for related bugs. 24 | -------------------------------------------------------------------------------- /.github/workflows/pr-any.yml: -------------------------------------------------------------------------------- 1 | name: PR 2 | on: [pull_request] 3 | 4 | jobs: 5 | pr: 6 | continue-on-error: true 7 | strategy: 8 | matrix: 9 | step: ['lint', 'test', 'build', diff] 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: actions/setup-node@v4 14 | with: 15 | node-version: 'lts/*' 16 | - name: Set Execute Permissions 17 | run: chmod +x ./scripts/* 18 | - name: ${{ matrix.step }} 19 | run: | 20 | corepack enable 21 | yarn install --immutable 22 | yarn ${{ matrix.step }} 23 | -------------------------------------------------------------------------------- /.github/workflows/push-master.yml: -------------------------------------------------------------------------------- 1 | name: Master 2 | on: 3 | push: 4 | branches: 5 | - master 6 | 7 | jobs: 8 | master: 9 | if: "! startsWith(github.event.head_commit.message, '[CI Skip]')" 10 | strategy: 11 | matrix: 12 | step: ['build:release'] 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | fetch-depth: 0 18 | token: ${{ secrets.GH_PAT_BOT }} 19 | - uses: actions/setup-node@v4 20 | with: 21 | node-version: 'lts/*' 22 | - name: ${{ matrix.step }} 23 | env: 24 | CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} 25 | GH_PAT: ${{ secrets.GH_PAT_BOT }} 26 | GH_RELEASE_GITHUB_API_TOKEN: ${{ secrets.GH_PAT_BOT }} 27 | GH_RELEASE_FILES: master-ff-build.zip,master-ff-src.zip,master-chrome-build.zip,master-chrome-src.zip 28 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 29 | run: | 30 | corepack enable 31 | yarn install --immutable 32 | yarn ${{ matrix.step }} 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | build-*/ 3 | coverage/ 4 | node_modules/ 5 | tmp/ 6 | NOTES.md 7 | .DS_Store 8 | .env.local 9 | .env.development.local 10 | .env.test.local 11 | .env.production.local 12 | .npmrc 13 | .yarn/* 14 | !.yarn/releases 15 | !.yarn/plugins 16 | .pnp.* 17 | cc-test-reporter 18 | lerna-debug.log* 19 | master-chrome-build.zip 20 | master-chrome-src.zip 21 | master-ff-build.zip 22 | master-ff-src.zip 23 | npm-debug.log* 24 | tsconfig.*buildinfo 25 | yarn-debug.log* 26 | yarn-error.log* 27 | package-lock.json 28 | _book 29 | docs/html 30 | .idea 31 | .vscode 32 | packages/extension/manifest.json 33 | 34 | # Diff script generates ff-diff 35 | ff-diff -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Jaco 2 | github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 3 | github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Github Actions 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 18.14 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | build 2 | coverage 3 | packages 4 | -------------------------------------------------------------------------------- /.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | module.exports = require('@polkadot/dev/config/prettier.cjs'); 5 | -------------------------------------------------------------------------------- /.yarn/plugins/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/.yarn/plugins/.keep -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | compressionLevel: mixed 2 | 3 | enableGlobalCache: false 4 | 5 | enableImmutableInstalls: false 6 | 7 | enableProgressBars: false 8 | 9 | logFilters: 10 | - code: YN0013 11 | level: discard 12 | 13 | nodeLinker: node-modules 14 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/.nojekyll -------------------------------------------------------------------------------- /docs/assets/background_top.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/extension-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/extension-overview.png -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/favicon.ico -------------------------------------------------------------------------------- /docs/fonts/Inter/Inter-Italic-VariableFont_opsz,wght.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/Inter-Italic-VariableFont_opsz,wght.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/Inter-VariableFont_opsz,wght.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/Inter-VariableFont_opsz,wght.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-Black.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-BlackItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-Bold.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-BoldItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-ExtraBold.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-ExtraLight.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-Italic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-Light.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-LightItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-Medium.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-MediumItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-Regular.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-SemiBold.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-Thin.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_18pt-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_18pt-ThinItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-Black.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-BlackItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-Bold.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-BoldItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-ExtraBold.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-ExtraLight.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-Italic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-Light.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-LightItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-Medium.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-MediumItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-Regular.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-SemiBold.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-Thin.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_24pt-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_24pt-ThinItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-Black.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-BlackItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-Bold.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-BoldItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-ExtraBold.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-ExtraLight.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-Italic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-Light.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-LightItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-Medium.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-MediumItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-Regular.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-SemiBold.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-Thin.ttf -------------------------------------------------------------------------------- /docs/fonts/Inter/static/Inter_28pt-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Inter/static/Inter_28pt-ThinItalic.ttf -------------------------------------------------------------------------------- /docs/fonts/Manrope/Manrope-VariableFont_wght.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Manrope/Manrope-VariableFont_wght.ttf -------------------------------------------------------------------------------- /docs/fonts/Manrope/static/Manrope-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Manrope/static/Manrope-Bold.ttf -------------------------------------------------------------------------------- /docs/fonts/Manrope/static/Manrope-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Manrope/static/Manrope-ExtraBold.ttf -------------------------------------------------------------------------------- /docs/fonts/Manrope/static/Manrope-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Manrope/static/Manrope-ExtraLight.ttf -------------------------------------------------------------------------------- /docs/fonts/Manrope/static/Manrope-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Manrope/static/Manrope-Light.ttf -------------------------------------------------------------------------------- /docs/fonts/Manrope/static/Manrope-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Manrope/static/Manrope-Medium.ttf -------------------------------------------------------------------------------- /docs/fonts/Manrope/static/Manrope-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Manrope/static/Manrope-Regular.ttf -------------------------------------------------------------------------------- /docs/fonts/Manrope/static/Manrope-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Manrope/static/Manrope-SemiBold.ttf -------------------------------------------------------------------------------- /docs/fonts/Unbounded/Unbounded-VariableFont_wght.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Unbounded/Unbounded-VariableFont_wght.ttf -------------------------------------------------------------------------------- /docs/fonts/Unbounded/static/Unbounded-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Unbounded/static/Unbounded-Black.ttf -------------------------------------------------------------------------------- /docs/fonts/Unbounded/static/Unbounded-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Unbounded/static/Unbounded-Bold.ttf -------------------------------------------------------------------------------- /docs/fonts/Unbounded/static/Unbounded-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Unbounded/static/Unbounded-ExtraBold.ttf -------------------------------------------------------------------------------- /docs/fonts/Unbounded/static/Unbounded-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Unbounded/static/Unbounded-ExtraLight.ttf -------------------------------------------------------------------------------- /docs/fonts/Unbounded/static/Unbounded-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Unbounded/static/Unbounded-Light.ttf -------------------------------------------------------------------------------- /docs/fonts/Unbounded/static/Unbounded-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Unbounded/static/Unbounded-Medium.ttf -------------------------------------------------------------------------------- /docs/fonts/Unbounded/static/Unbounded-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Unbounded/static/Unbounded-Regular.ttf -------------------------------------------------------------------------------- /docs/fonts/Unbounded/static/Unbounded-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/fonts/Unbounded/static/Unbounded-SemiBold.ttf -------------------------------------------------------------------------------- /docs/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/docs/logo.jpg -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2025 @polkadot/extension authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import baseConfig from '@polkadot/dev/config/eslint'; 5 | 6 | export default [ 7 | ...baseConfig, 8 | { 9 | rules: { 10 | 'import/extensions': 'off' 11 | } 12 | } 13 | ]; 14 | -------------------------------------------------------------------------------- /i18next-scanner.config.cjs: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const fs = require('fs'); 5 | const path = require('path'); 6 | const typescript = require('typescript'); 7 | 8 | function transform (file, enc, done) { 9 | const { ext } = path.parse(file.path); 10 | 11 | if (ext === '.tsx') { 12 | const content = fs.readFileSync(file.path, enc); 13 | 14 | const { outputText } = typescript.transpileModule(content, { 15 | compilerOptions: { 16 | target: 'es2018' 17 | }, 18 | fileName: path.basename(file.path) 19 | }); 20 | 21 | this.parser.parseFuncFromString(outputText); 22 | } 23 | 24 | done(); 25 | } 26 | 27 | module.exports = { 28 | input: [ 29 | 'packages/extension-ui/src/**/*.{ts,tsx}', 30 | // Use ! to filter out files or directories 31 | '!packages/*/src/**/*.spec.{ts,tsx}', 32 | '!packages/*/src/i18n/**', 33 | '!**/node_modules/**' 34 | ], 35 | options: { 36 | debug: false, // true to print config 37 | defaultLng: 'en', 38 | func: { 39 | extensions: ['.tsx', '.ts'], 40 | list: ['t', 'i18next.t', 'i18n.t'] 41 | }, 42 | keySeparator: false, // key separator 43 | lngs: ['en'], 44 | nsSeparator: false, // namespace separator 45 | resource: { 46 | jsonIndent: 2, 47 | lineEnding: '\n', 48 | loadPath: 'packages/extension/public/locales/{{lng}}/{{ns}}.json', 49 | savePath: 'packages/extension/public/locales/{{lng}}/{{ns}}.json' 50 | }, 51 | trans: { 52 | component: 'Trans' 53 | } 54 | }, 55 | output: './', 56 | transform 57 | }; 58 | -------------------------------------------------------------------------------- /packages/extension-base/README.md: -------------------------------------------------------------------------------- 1 | # @polkadot/extension-base 2 | 3 | Functions, classes and other utilities used in `@polkadot/extension`. These include: 4 | - background script handlers, 5 | - message passing, 6 | - scripts injected inside pages. 7 | 8 | They are primarily meant to be used in `@polkadot/extension`, and can be broken without any notice to cater for `@polkadot/extension`'s needs. 9 | 10 | They are exported here if you wish to use part of them in the development of your 11 | own extension. Don't forget to add `process.env.EXTENSION_PREFIX` to separate 12 | ports and stores from the current extension's ones. 13 | -------------------------------------------------------------------------------- /packages/extension-base/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Jaco Greeff ", 3 | "bugs": "https://github.com/polkadot-js/extension/issues", 4 | "description": "Functions, classes and other utilities used in @polkadot/extension", 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "homepage": "https://github.com/polkadot-js/extension/tree/master/packages/extension-base#readme", 9 | "license": "Apache-2.0", 10 | "name": "@polkadot/extension-base", 11 | "repository": { 12 | "directory": "packages/extension-base", 13 | "type": "git", 14 | "url": "https://github.com/polkadot-js/extension.git" 15 | }, 16 | "sideEffects": [ 17 | "./packageDetect.js", 18 | "./packageDetect.cjs" 19 | ], 20 | "type": "module", 21 | "version": "0.59.2", 22 | "main": "index.js", 23 | "dependencies": { 24 | "@polkadot/api": "^16.1.2", 25 | "@polkadot/extension-chains": "0.59.2", 26 | "@polkadot/extension-dapp": "0.59.2", 27 | "@polkadot/extension-inject": "0.59.2", 28 | "@polkadot/keyring": "^13.5.1", 29 | "@polkadot/networks": "^13.5.1", 30 | "@polkadot/phishing": "^0.25.12", 31 | "@polkadot/rpc-provider": "^16.1.2", 32 | "@polkadot/types": "^16.1.2", 33 | "@polkadot/ui-keyring": "^3.14.1", 34 | "@polkadot/ui-settings": "^3.14.1", 35 | "@polkadot/util": "^13.5.1", 36 | "@polkadot/util-crypto": "^13.5.1", 37 | "eventemitter3": "^5.0.1", 38 | "rxjs": "^7.8.1", 39 | "tslib": "^2.8.1" 40 | }, 41 | "devDependencies": { 42 | "@polkadot/dev-test": "^0.83.2", 43 | "@polkadot/extension-mocks": "0.59.2" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/extension-base/src/background/RequestBytesSign.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { KeyringPair } from '@polkadot/keyring/types'; 5 | import type { TypeRegistry } from '@polkadot/types'; 6 | import type { SignerPayloadRaw } from '@polkadot/types/types'; 7 | import type { HexString } from '@polkadot/util/types'; 8 | import type { RequestSign } from './types.js'; 9 | 10 | import { u8aToHex, u8aWrapBytes } from '@polkadot/util'; 11 | 12 | export default class RequestBytesSign implements RequestSign { 13 | public readonly payload: SignerPayloadRaw; 14 | 15 | constructor (payload: SignerPayloadRaw) { 16 | this.payload = payload; 17 | } 18 | 19 | sign (_registry: TypeRegistry, pair: KeyringPair): { signature: HexString } { 20 | return { 21 | signature: u8aToHex( 22 | pair.sign( 23 | u8aWrapBytes(this.payload.data) 24 | ) 25 | ) 26 | }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/extension-base/src/background/RequestExtrinsicSign.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { KeyringPair } from '@polkadot/keyring/types'; 5 | import type { TypeRegistry } from '@polkadot/types'; 6 | import type { SignerPayloadJSON } from '@polkadot/types/types'; 7 | import type { HexString } from '@polkadot/util/types'; 8 | import type { RequestSign } from './types.js'; 9 | 10 | export default class RequestExtrinsicSign implements RequestSign { 11 | public readonly payload: SignerPayloadJSON; 12 | 13 | constructor (payload: SignerPayloadJSON) { 14 | this.payload = payload; 15 | } 16 | 17 | sign (registry: TypeRegistry, pair: KeyringPair): { signature: HexString } { 18 | return registry 19 | .createType('ExtrinsicPayload', this.payload, { version: this.payload.version }) 20 | .sign(pair); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/extension-base/src/background/handlers/helpers.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | export function withErrorLog (fn: () => unknown): void { 5 | try { 6 | const p = fn(); 7 | 8 | if (p && typeof p === 'object' && typeof (p as Promise).catch === 'function') { 9 | (p as Promise).catch(console.error); 10 | } 11 | } catch (e) { 12 | console.error(e); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/extension-base/src/background/handlers/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /* global chrome */ 5 | 6 | import type { MessageTypes, TransportRequestMessage } from '../types.js'; 7 | 8 | import { assert } from '@polkadot/util'; 9 | 10 | import { PORT_EXTENSION } from '../../defaults.js'; 11 | import Extension from './Extension.js'; 12 | import State from './State.js'; 13 | import Tabs from './Tabs.js'; 14 | 15 | export { withErrorLog } from './helpers.js'; 16 | 17 | const state = new State(); 18 | 19 | await state.init(); 20 | const extension = new Extension(state); 21 | const tabs = new Tabs(state); 22 | 23 | export default function handler ({ id, message, request }: TransportRequestMessage, port?: chrome.runtime.Port, extensionPortName = PORT_EXTENSION): void { 24 | const isExtension = !port || port?.name === extensionPortName; 25 | const sender = port?.sender; 26 | 27 | if (!isExtension && !sender) { 28 | throw new Error('Unable to extract message sender'); 29 | } 30 | 31 | const from = isExtension 32 | ? 'extension' 33 | : sender?.url || sender?.tab?.url || ''; 34 | const source = `${from}: ${id}: ${message}`; 35 | 36 | console.log(` [in] ${source}`); // :: ${JSON.stringify(request)}`); 37 | 38 | const promise = isExtension 39 | ? extension.handle(id, message, request, port) 40 | : tabs.handle(id, message, request, from, port); 41 | 42 | promise 43 | .then((response: unknown): void => { 44 | console.log(`[out] ${source}`); // :: ${JSON.stringify(response)}`); 45 | 46 | // between the start and the end of the promise, the user may have closed 47 | // the tab, in which case port will be undefined 48 | assert(port, 'Port has been disconnected'); 49 | 50 | port.postMessage({ id, response }); 51 | }) 52 | .catch((error: Error): void => { 53 | console.log(`[err] ${source}:: ${error.message}`); 54 | 55 | // only send message back to port if it's still connected 56 | if (port) { 57 | port.postMessage({ error: error.message, id }); 58 | } 59 | }); 60 | } 61 | -------------------------------------------------------------------------------- /packages/extension-base/src/background/handlers/subscriptions.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /* global chrome */ 5 | 6 | import type { MessageTypesWithSubscriptions, SubscriptionMessageTypes } from '../types.js'; 7 | 8 | type Subscriptions = Record; 9 | 10 | const subscriptions: Subscriptions = {}; 11 | 12 | // return a subscription callback, that will send the data to the caller via the port 13 | export function createSubscription (id: string, port: chrome.runtime.Port): (data: SubscriptionMessageTypes[TMessageType]) => void { 14 | subscriptions[id] = port; 15 | 16 | return (subscription: unknown): void => { 17 | if (subscriptions[id]) { 18 | port.postMessage({ id, subscription }); 19 | } 20 | }; 21 | } 22 | 23 | // clear a previous subscriber 24 | export function unsubscribe (id: string): void { 25 | if (subscriptions[id]) { 26 | console.log(`Unsubscribing from ${id}`); 27 | 28 | delete subscriptions[id]; 29 | } else { 30 | console.error(`Unable to unsubscribe from ${id}`); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/extension-base/src/background/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | export { default as handlers, withErrorLog } from './handlers/index.js'; 5 | -------------------------------------------------------------------------------- /packages/extension-base/src/bundle.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | export { packageInfo } from './packageInfo.js'; 5 | -------------------------------------------------------------------------------- /packages/extension-base/src/defaults.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // this _must_ be changed for each extension 5 | export const EXTENSION_PREFIX = process.env['EXTENSION_PREFIX'] || ''; 6 | 7 | if (!EXTENSION_PREFIX && !process.env['PORT_PREFIX']) { 8 | throw new Error('CRITICAL: The extension does not define an own EXTENSION_PREFIX environment variable as part of the build, this is required to ensure that messages are not shared between extensions. Failure to do so will yield messages sent to multiple extensions.'); 9 | } 10 | 11 | const PORT_PREFIX = `${EXTENSION_PREFIX || 'unknown'}-${process.env['PORT_PREFIX'] || 'unknown'}`; 12 | 13 | export const PORT_CONTENT = `${PORT_PREFIX}-content`; 14 | export const PORT_EXTENSION = `${PORT_PREFIX}-extension`; 15 | 16 | export const MESSAGE_ORIGIN_PAGE = `${PORT_PREFIX}-page`; 17 | export const MESSAGE_ORIGIN_CONTENT = `${PORT_PREFIX}-content`; 18 | 19 | export const ALLOWED_PATH = ['/', '/account/import-ledger', '/account/restore-json'] as const; 20 | 21 | export const PASSWORD_EXPIRY_MIN = 15; 22 | export const PASSWORD_EXPIRY_MS = PASSWORD_EXPIRY_MIN * 60 * 1000; 23 | 24 | export const PHISHING_PAGE_REDIRECT = '/phishing-page-detected'; 25 | 26 | // console.log(`Extension is sending and receiving messages on ${PORT_PREFIX}-*`); 27 | -------------------------------------------------------------------------------- /packages/extension-base/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Since we inject into pages, we skip this 5 | // import './detectPackage'; 6 | 7 | export * from './bundle.js'; 8 | -------------------------------------------------------------------------------- /packages/extension-base/src/packageDetect.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Do not edit, auto-generated by @polkadot/dev 5 | // (packageInfo imports will be kept as-is, user-editable) 6 | 7 | import { packageInfo as chainsInfo } from '@polkadot/extension-chains/packageInfo'; 8 | import { packageInfo as dappInfo } from '@polkadot/extension-dapp/packageInfo'; 9 | import { packageInfo as injectInfo } from '@polkadot/extension-inject/packageInfo'; 10 | import { detectPackage } from '@polkadot/util'; 11 | 12 | import { packageInfo } from './packageInfo.js'; 13 | 14 | detectPackage(packageInfo, null, [chainsInfo, dappInfo, injectInfo]); 15 | -------------------------------------------------------------------------------- /packages/extension-base/src/packageInfo.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Do not edit, auto-generated by @polkadot/dev 5 | 6 | export const packageInfo = { name: '@polkadot/extension-base', path: 'auto', type: 'auto', version: '0.59.2' }; 7 | -------------------------------------------------------------------------------- /packages/extension-base/src/page/Accounts.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { InjectedAccount, InjectedAccounts, Unsubcall } from '@polkadot/extension-inject/types'; 5 | import type { SendRequest } from './types.js'; 6 | 7 | // External to class, this.# is not private enough (yet) 8 | let sendRequest: SendRequest; 9 | 10 | export default class Accounts implements InjectedAccounts { 11 | constructor (_sendRequest: SendRequest) { 12 | sendRequest = _sendRequest; 13 | } 14 | 15 | public get (anyType?: boolean): Promise { 16 | return sendRequest('pub(accounts.list)', { anyType }); 17 | } 18 | 19 | public subscribe (cb: (accounts: InjectedAccount[]) => unknown): Unsubcall { 20 | let id: string | null = null; 21 | 22 | sendRequest('pub(accounts.subscribe)', null, cb) 23 | .then((subId): void => { 24 | id = subId; 25 | }) 26 | .catch(console.error); 27 | 28 | return (): void => { 29 | id && sendRequest('pub(accounts.unsubscribe)', { id }) 30 | .catch(console.error); 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/extension-base/src/page/Injected.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { Injected } from '@polkadot/extension-inject/types'; 5 | import type { SendRequest } from './types.js'; 6 | 7 | import Accounts from './Accounts.js'; 8 | import Metadata from './Metadata.js'; 9 | import PostMessageProvider from './PostMessageProvider.js'; 10 | import Signer from './Signer.js'; 11 | 12 | export default class implements Injected { 13 | public readonly accounts: Accounts; 14 | 15 | public readonly metadata: Metadata; 16 | 17 | public readonly provider: PostMessageProvider; 18 | 19 | public readonly signer: Signer; 20 | 21 | constructor (sendRequest: SendRequest) { 22 | this.accounts = new Accounts(sendRequest); 23 | this.metadata = new Metadata(sendRequest); 24 | this.provider = new PostMessageProvider(sendRequest); 25 | this.signer = new Signer(sendRequest); 26 | 27 | setInterval((): void => { 28 | sendRequest('pub(ping)', null).catch((): void => { 29 | console.error('Extension unavailable, ping failed'); 30 | }); 31 | }, 5_000 + Math.floor(Math.random() * 5_000)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/extension-base/src/page/Metadata.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { InjectedMetadata, InjectedMetadataKnown, MetadataDef } from '@polkadot/extension-inject/types'; 5 | import type { SendRequest } from './types.js'; 6 | 7 | // External to class, this.# is not private enough (yet) 8 | let sendRequest: SendRequest; 9 | 10 | export default class Metadata implements InjectedMetadata { 11 | constructor (_sendRequest: SendRequest) { 12 | sendRequest = _sendRequest; 13 | } 14 | 15 | public get (): Promise { 16 | return sendRequest('pub(metadata.list)'); 17 | } 18 | 19 | public provide (definition: MetadataDef): Promise { 20 | return sendRequest('pub(metadata.provide)', definition); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/extension-base/src/page/Signer.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { Signer as SignerInterface, SignerResult } from '@polkadot/api/types'; 5 | import type { SignerPayloadJSON, SignerPayloadRaw } from '@polkadot/types/types'; 6 | import type { SendRequest } from './types.js'; 7 | 8 | // External to class, this.# is not private enough (yet) 9 | let sendRequest: SendRequest; 10 | let nextId = 0; 11 | 12 | export default class Signer implements SignerInterface { 13 | constructor (_sendRequest: SendRequest) { 14 | sendRequest = _sendRequest; 15 | } 16 | 17 | public async signPayload (payload: SignerPayloadJSON): Promise { 18 | const id = ++nextId; 19 | const result = await sendRequest('pub(extrinsic.sign)', payload); 20 | 21 | // we add an internal id (number) - should have a mapping from the 22 | // extension id (string) -> internal id (number) if we wish to provide 23 | // updated via the update functionality (noop at this point) 24 | return { 25 | ...result, 26 | id 27 | }; 28 | } 29 | 30 | public async signRaw (payload: SignerPayloadRaw): Promise { 31 | const id = ++nextId; 32 | const result = await sendRequest('pub(bytes.sign)', payload); 33 | 34 | return { 35 | ...result, 36 | id 37 | }; 38 | } 39 | 40 | // NOTE We don't listen to updates at all, if we do we can interpret the 41 | // result as provided by the API here 42 | // public update (id: number, status: Hash | SubmittableResult): void { 43 | // // ignore 44 | // } 45 | } 46 | -------------------------------------------------------------------------------- /packages/extension-base/src/page/types.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { MessageTypesWithNoSubscriptions, MessageTypesWithNullRequest, MessageTypesWithSubscriptions, RequestTypes, ResponseTypes, SubscriptionMessageTypes } from '../background/types.js'; 5 | 6 | export interface SendRequest { 7 | (message: TMessageType): Promise; 8 | (message: TMessageType, request: RequestTypes[TMessageType]): Promise; 9 | (message: TMessageType, request: RequestTypes[TMessageType], subscriber: (data: SubscriptionMessageTypes[TMessageType]) => void): Promise; 10 | } 11 | -------------------------------------------------------------------------------- /packages/extension-base/src/stores/Accounts.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { KeyringJson, KeyringStore } from '@polkadot/ui-keyring/types'; 5 | 6 | import { EXTENSION_PREFIX } from '../defaults.js'; 7 | import BaseStore from './Base.js'; 8 | 9 | export default class AccountsStore extends BaseStore implements KeyringStore { 10 | constructor () { 11 | super( 12 | EXTENSION_PREFIX && EXTENSION_PREFIX !== 'polkadot{.js}' 13 | ? `${EXTENSION_PREFIX}accounts` 14 | : null 15 | ); 16 | } 17 | 18 | public override async set (key: string, value: KeyringJson, update?: () => void): Promise { 19 | // shortcut, don't save testing accounts in extension storage 20 | if (key.startsWith('account:') && value.meta && value.meta.isTesting) { 21 | update && update(); 22 | 23 | return; 24 | } 25 | 26 | await super.set(key, value, update); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/extension-base/src/stores/Metadata.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { MetadataDef } from '@polkadot/extension-inject/types'; 5 | 6 | import { EXTENSION_PREFIX } from '../defaults.js'; 7 | import BaseStore from './Base.js'; 8 | 9 | export default class MetadataStore extends BaseStore { 10 | constructor () { 11 | super( 12 | EXTENSION_PREFIX && EXTENSION_PREFIX !== 'polkadot{.js}' 13 | ? `${EXTENSION_PREFIX}metadata` 14 | : 'metadata' 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/extension-base/src/stores/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | export { default as AccountsStore } from './Accounts.js'; 5 | export { default as MetadataStore } from './Metadata.js'; 6 | -------------------------------------------------------------------------------- /packages/extension-base/src/types.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | export interface Message extends MessageEvent { 5 | data: { 6 | error?: string; 7 | id: string; 8 | origin: string; 9 | response?: string; 10 | subscription?: string; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/extension-base/src/utils/canDerive.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { KeypairType } from '@polkadot/util-crypto/types'; 5 | 6 | export function canDerive (type?: KeypairType): boolean { 7 | return !!type && ['ed25519', 'sr25519', 'ecdsa', 'ethereum'].includes(type); 8 | } 9 | -------------------------------------------------------------------------------- /packages/extension-base/src/utils/getId.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { EXTENSION_PREFIX } from '../defaults.js'; 5 | 6 | let counter = 0; 7 | 8 | export function getId (): string { 9 | return `${EXTENSION_PREFIX}.${Date.now()}.${++counter}`; 10 | } 11 | -------------------------------------------------------------------------------- /packages/extension-base/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-base authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | export { canDerive } from './canDerive.js'; 5 | -------------------------------------------------------------------------------- /packages/extension-base/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "baseUrl": "..", 5 | "outDir": "./build", 6 | "rootDir": "./src" 7 | }, 8 | "exclude": [ 9 | "**/*.spec.ts" 10 | ], 11 | "references": [ 12 | { "path": "../extension-chains/tsconfig.build.json" }, 13 | { "path": "../extension-dapp/tsconfig.build.json" }, 14 | { "path": "../extension-inject/tsconfig.build.json" } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/extension-base/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "baseUrl": "..", 5 | "outDir": "./build", 6 | "rootDir": "./src", 7 | "emitDeclarationOnly": false, 8 | "noEmit": true 9 | }, 10 | "include": [ 11 | "**/*.spec.ts" 12 | ], 13 | "references": [ 14 | { "path": "../extension-base/tsconfig.build.json" }, 15 | { "path": "../extension-inject/tsconfig.build.json" }, 16 | { "path": "../extension-mocks/tsconfig.build.json" } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/extension-chains/README.md: -------------------------------------------------------------------------------- 1 | # @polkadot/extension-chains 2 | 3 | Definitions for chains that are supported by this extension. It contains the bare definitions as well as a stripped-down (call-only) metadata format. 4 | -------------------------------------------------------------------------------- /packages/extension-chains/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Jaco Greeff ", 3 | "bugs": "https://github.com/polkadot-js/extension/issues", 4 | "description": "Definitions for all known chains as exposed by the extension.", 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "homepage": "https://github.com/polkadot-js/extension/tree/master/packages/extension-chains#readme", 9 | "license": "Apache-2.0", 10 | "name": "@polkadot/extension-chains", 11 | "repository": { 12 | "directory": "packages/extension-chains", 13 | "type": "git", 14 | "url": "https://github.com/polkadot-js/extension.git" 15 | }, 16 | "sideEffects": [ 17 | "./packageDetect.js", 18 | "./packageDetect.cjs" 19 | ], 20 | "type": "module", 21 | "version": "0.59.2", 22 | "main": "index.js", 23 | "dependencies": { 24 | "@polkadot/extension-inject": "0.59.2", 25 | "@polkadot/networks": "^13.5.1", 26 | "@polkadot/util": "^13.5.1", 27 | "@polkadot/util-crypto": "^13.5.1", 28 | "tslib": "^2.8.1" 29 | }, 30 | "peerDependencies": { 31 | "@polkadot/api": "*", 32 | "@polkadot/types": "*" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/extension-chains/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-chains authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Since we inject into pages, we skip this 5 | // import './packageDetect.js'; 6 | 7 | export * from './bundle.js'; 8 | -------------------------------------------------------------------------------- /packages/extension-chains/src/packageDetect.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2025 @polkadot/extension-chains authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Do not edit, auto-generated by @polkadot/dev 5 | // (packageInfo imports will be kept as-is, user-editable) 6 | 7 | import { packageInfo as injectInfo } from '@polkadot/extension-inject/packageInfo'; 8 | import { detectPackage } from '@polkadot/util'; 9 | 10 | import { packageInfo } from './packageInfo.js'; 11 | 12 | detectPackage(packageInfo, null, [injectInfo]); 13 | -------------------------------------------------------------------------------- /packages/extension-chains/src/packageInfo.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2025 @polkadot/extension-chains authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Do not edit, auto-generated by @polkadot/dev 5 | 6 | export const packageInfo = { name: '@polkadot/extension-chains', path: 'auto', type: 'auto', version: '0.59.2' }; 7 | -------------------------------------------------------------------------------- /packages/extension-chains/src/types.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-chains authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { MetadataDef } from '@polkadot/extension-inject/types'; 5 | import type { Registry } from '@polkadot/types/types'; 6 | 7 | export interface Chain { 8 | definition: MetadataDef; 9 | genesisHash?: string; 10 | hasMetadata: boolean; 11 | icon: string; 12 | isUnknown?: boolean; 13 | name: string; 14 | registry: Registry; 15 | specVersion: number; 16 | ss58Format: number; 17 | tokenDecimals: number; 18 | tokenSymbol: string; 19 | } 20 | -------------------------------------------------------------------------------- /packages/extension-chains/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "baseUrl": "..", 5 | "outDir": "./build", 6 | "rootDir": "./src" 7 | }, 8 | "references": [ 9 | { "path": "../extension-inject/tsconfig.build.json" } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/extension-compat-metamask/README.md: -------------------------------------------------------------------------------- 1 | # @polkadot/extension-metamask-compat 2 | 3 | An optional metamask-compatible layer 4 | -------------------------------------------------------------------------------- /packages/extension-compat-metamask/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Jaco Greeff ", 3 | "bugs": "https://github.com/polkadot-js/extension/issues", 4 | "description": "Metamask compatibility layer", 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "homepage": "https://github.com/polkadot-js/extension/tree/master/packages/extension-compat-metamask#readme", 9 | "license": "Apache-2.0", 10 | "name": "@polkadot/extension-compat-metamask", 11 | "repository": { 12 | "directory": "packages/extension-compat-metamask", 13 | "type": "git", 14 | "url": "https://github.com/polkadot-js/extension.git" 15 | }, 16 | "sideEffects": [ 17 | "./packageDetect.js", 18 | "./packageDetect.cjs" 19 | ], 20 | "type": "module", 21 | "version": "0.59.2", 22 | "main": "index.js", 23 | "dependencies": { 24 | "@metamask/detect-provider": "^2.0.0", 25 | "@polkadot/extension-inject": "0.59.2", 26 | "@polkadot/types": "^16.1.2", 27 | "@polkadot/util": "^13.5.1", 28 | "tslib": "^2.8.1", 29 | "web3": "^4.7.0" 30 | }, 31 | "peerDependencies": { 32 | "@polkadot/api": "*", 33 | "@polkadot/util": "*" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/extension-compat-metamask/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-compat-metamask authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Since we inject into pages, we skip this 5 | // import './detectPackage'; 6 | 7 | export * from './bundle.js'; 8 | -------------------------------------------------------------------------------- /packages/extension-compat-metamask/src/packageDetect.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2025 @polkadot/extension-compat-metamask authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Do not edit, auto-generated by @polkadot/dev 5 | // (packageInfo imports will be kept as-is, user-editable) 6 | 7 | import { packageInfo as injectInfo } from '@polkadot/extension-inject/packageInfo'; 8 | import { detectPackage } from '@polkadot/util'; 9 | 10 | import { packageInfo } from './packageInfo.js'; 11 | 12 | detectPackage(packageInfo, null, [injectInfo]); 13 | -------------------------------------------------------------------------------- /packages/extension-compat-metamask/src/packageInfo.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2025 @polkadot/extension-compat-metamask authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Do not edit, auto-generated by @polkadot/dev 5 | 6 | export const packageInfo = { name: '@polkadot/extension-compat-metamask', path: 'auto', type: 'auto', version: '0.59.2' }; 7 | -------------------------------------------------------------------------------- /packages/extension-compat-metamask/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "baseUrl": "..", 5 | "outDir": "./build", 6 | "rootDir": "./src" 7 | }, 8 | "references": [ 9 | { "path": "../extension-inject/tsconfig.build.json" } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/extension-dapp/README.md: -------------------------------------------------------------------------------- 1 | # @polkadot/extension-dapp 2 | 3 | Documentation available [in the polkadot-js doc](https://polkadot.js.org/docs/extension). 4 | -------------------------------------------------------------------------------- /packages/extension-dapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Jaco Greeff ", 3 | "bugs": "https://github.com/polkadot-js/extension/issues", 4 | "description": "Provides an interfaces around the injected globals for ease of access by dapp developers.", 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "homepage": "https://github.com/polkadot-js/extension/tree/master/packages/extension-dapp#readme", 9 | "license": "Apache-2.0", 10 | "name": "@polkadot/extension-dapp", 11 | "repository": { 12 | "directory": "packages/extension-dapp", 13 | "type": "git", 14 | "url": "https://github.com/polkadot-js/extension.git" 15 | }, 16 | "sideEffects": [ 17 | "./packageDetect.js", 18 | "./packageDetect.cjs" 19 | ], 20 | "type": "module", 21 | "version": "0.59.2", 22 | "main": "index.js", 23 | "dependencies": { 24 | "@polkadot/extension-inject": "0.59.2", 25 | "@polkadot/util": "^13.5.1", 26 | "@polkadot/util-crypto": "^13.5.1", 27 | "tslib": "^2.8.1" 28 | }, 29 | "devDependencies": { 30 | "@polkadot/dev-test": "^0.83.2" 31 | }, 32 | "peerDependencies": { 33 | "@polkadot/api": "*", 34 | "@polkadot/util": "*", 35 | "@polkadot/util-crypto": "*" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/extension-dapp/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-dapp authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Since we inject into pages, we skip this 5 | // import './packageDetect.js'; 6 | 7 | export * from './bundle.js'; 8 | -------------------------------------------------------------------------------- /packages/extension-dapp/src/packageDetect.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2025 @polkadot/extension-dapp authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Do not edit, auto-generated by @polkadot/dev 5 | // (packageInfo imports will be kept as-is, user-editable) 6 | 7 | import { packageInfo as injectInfo } from '@polkadot/extension-inject/packageInfo'; 8 | import { detectPackage } from '@polkadot/util'; 9 | 10 | import { packageInfo } from './packageInfo.js'; 11 | 12 | detectPackage(packageInfo, null, [injectInfo]); 13 | -------------------------------------------------------------------------------- /packages/extension-dapp/src/packageInfo.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2025 @polkadot/extension-dapp authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Do not edit, auto-generated by @polkadot/dev 5 | 6 | export const packageInfo = { name: '@polkadot/extension-dapp', path: 'auto', type: 'auto', version: '0.59.2' }; 7 | -------------------------------------------------------------------------------- /packages/extension-dapp/src/util.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-dapp authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | export function documentReadyPromise (creator: () => Promise): Promise { 5 | return new Promise((resolve): void => { 6 | if (document.readyState === 'complete') { 7 | resolve(creator()); 8 | } else { 9 | window.addEventListener('load', () => resolve(creator())); 10 | } 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /packages/extension-dapp/src/wrapBytes.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { U8A_WRAP_ETHEREUM, U8A_WRAP_POSTFIX, U8A_WRAP_PREFIX, u8aIsWrapped, u8aUnwrapBytes, u8aWrapBytes } from '@polkadot/util'; 5 | 6 | export const ETHEREUM = U8A_WRAP_ETHEREUM; 7 | export const POSTFIX = U8A_WRAP_POSTFIX; 8 | export const PREFIX = U8A_WRAP_PREFIX; 9 | 10 | export const isWrapped = u8aIsWrapped; 11 | export const unwrapBytes = u8aUnwrapBytes; 12 | export const wrapBytes = u8aWrapBytes; 13 | -------------------------------------------------------------------------------- /packages/extension-dapp/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "baseUrl": "..", 5 | "outDir": "./build", 6 | "rootDir": "./src" 7 | }, 8 | "exclude": [ 9 | "**/*.spec.ts" 10 | ], 11 | "references": [ 12 | { "path": "../extension-inject/tsconfig.build.json" } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/extension-dapp/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "baseUrl": "..", 5 | "outDir": "./build", 6 | "rootDir": "./src", 7 | "emitDeclarationOnly": false, 8 | "noEmit": true 9 | }, 10 | "include": [ 11 | "**/*.spec.ts" 12 | ], 13 | "references": [ 14 | { "path": "../extension-dapp/tsconfig.build.json" } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/extension-inject/README.md: -------------------------------------------------------------------------------- 1 | # @polkadot/extension-inject 2 | 3 | This is a basic extension injector that manages access to the global objects available. As an extension developer, you don't need to manage access to the window object manually, by just calling enable here, the global object is setup and managed properly. From here any dapp can access it with the `@polkadot/extension-dapp` package; 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { injectExtension } from '@polkadot/extension-inject'; 9 | 10 | // this a the function that will be exposed to be callable by the dapp. It resolves a promise 11 | // with the injected interface, (see `Injected`) when the dapp at `originName` (url) is allowed 12 | // to access functionality 13 | function enableFn (originName: string): Promise { 14 | ... 15 | } 16 | 17 | // injects the extension into the page 18 | injectExtension(enableFn, { name: 'myExtension', version: '1.0.1' }); 19 | ``` 20 | -------------------------------------------------------------------------------- /packages/extension-inject/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Jaco Greeff ", 3 | "bugs": "https://github.com/polkadot-js/extension/issues", 4 | "description": "A generic injector (usable to any extension), that populates the base exposed interfaces to be used by dapps.", 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "homepage": "https://github.com/polkadot-js/extension/tree/master/packages/extension-inject#readme", 9 | "license": "Apache-2.0", 10 | "name": "@polkadot/extension-inject", 11 | "repository": { 12 | "directory": "packages/extension-inject", 13 | "type": "git", 14 | "url": "https://github.com/polkadot-js/extension.git" 15 | }, 16 | "sideEffects": true, 17 | "type": "module", 18 | "version": "0.59.2", 19 | "main": "index.js", 20 | "dependencies": { 21 | "@polkadot/api": "^16.1.2", 22 | "@polkadot/rpc-provider": "^16.1.2", 23 | "@polkadot/types": "^16.1.2", 24 | "@polkadot/util": "^13.5.1", 25 | "@polkadot/util-crypto": "^13.5.1", 26 | "@polkadot/x-global": "^13.5.1", 27 | "tslib": "^2.8.1" 28 | }, 29 | "devDependencies": { 30 | "@polkadot/dev-test": "^0.83.2", 31 | "@types/chrome": "^0.0.254", 32 | "@types/firefox-webext-browser": "^111.0.5" 33 | }, 34 | "peerDependencies": { 35 | "@polkadot/api": "*", 36 | "@polkadot/util": "*" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/extension-inject/src/bundle.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-inject authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { Injected, InjectedExtension, InjectedWindow, InjectOptions } from './types.js'; 5 | 6 | import { cyrb53 } from './cyrb53.js'; 7 | 8 | export { packageInfo } from './packageInfo.js'; 9 | 10 | // setting for new-style connect (more-secure with no details exposed without 11 | // user acknowledgement, however slightly less-compatible with all dapps, some 12 | // may have not upgraded and don't have access to the latest interfaces) 13 | // 14 | // NOTE: In future versions this will be made the default 15 | const IS_CONNECT_CAPABLE = false; 16 | 17 | // It is recommended to always use the function below to shield the extension and dapp from 18 | // any future changes. The exposed interface will manage access between the 2 environments, 19 | // be it via window (current), postMessage (under consideration) or any other mechanism 20 | export function injectExtension (enable: (origin: string) => Promise, { name, version }: InjectOptions): void { 21 | // small helper with the typescript types, just cast window 22 | const windowInject = window as Window & InjectedWindow; 23 | 24 | // don't clobber the existing object, we will add it (or create as needed) 25 | windowInject.injectedWeb3 = windowInject.injectedWeb3 || {}; 26 | 27 | if (IS_CONNECT_CAPABLE) { 28 | // expose our extension on the window object, new-style with connect(origin) 29 | windowInject.injectedWeb3[cyrb53(`${name}/${version}`)] = { 30 | connect: (origin: string): Promise => 31 | enable(origin).then(({ accounts, metadata, provider, signer }) => ({ 32 | accounts, metadata, name, provider, signer, version 33 | })), 34 | enable: (): Promise => 35 | Promise.reject( 36 | new Error('This extension does not have support for enable(...), rather is only supports the new connect(...) variant (no extension name/version metadata without specific user-approval)') 37 | ) 38 | }; 39 | } else { 40 | // expose our extension on the window object, old-style with enable(origin) 41 | windowInject.injectedWeb3[name] = { 42 | enable: (origin: string): Promise => 43 | enable(origin), 44 | version 45 | }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/extension-inject/src/chrome.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-inject authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { extractGlobal, xglobal } from '@polkadot/x-global'; 5 | 6 | export const chrome = extractGlobal('chrome', xglobal.browser); 7 | -------------------------------------------------------------------------------- /packages/extension-inject/src/crossenv.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-inject authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { exposeGlobal, xglobal } from '@polkadot/x-global'; 5 | 6 | exposeGlobal('chrome', xglobal.browser); 7 | -------------------------------------------------------------------------------- /packages/extension-inject/src/cyrb53.spec.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-inject authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type * as _ from '@polkadot/dev-test/globals.d.ts'; 5 | 6 | import { cyrb53 } from './cyrb53.js'; 7 | 8 | const TESTS = [ 9 | { input: 'a', seed: 0, test: '501c2ba782c97901' }, 10 | { input: 'b', seed: 0, test: '459eda5bc254d2bf' }, 11 | { input: 'revenge', seed: 0, test: 'fbce64cc3b748385' }, 12 | { input: 'revenue', seed: 0, test: 'fb1d85148d13f93a' }, 13 | { input: 'revenue', seed: 1, test: '76fee5e6598ccd5c' }, 14 | { input: 'revenue', seed: 2, test: '1f672e2831253862' }, 15 | { input: 'revenue', seed: 3, test: '2b10de31708e6ab7' } 16 | ] as const; 17 | 18 | describe('cyrb53', (): void => { 19 | for (let i = 0, count = TESTS.length; i < count; i++) { 20 | const { input, seed, test } = TESTS[i]; 21 | 22 | it(`correctly encodes ${input}`, (): void => { 23 | // expected values, known input & seed 24 | expect(cyrb53(input, seed)).toEqual(test); 25 | 26 | // seed set as Date.now(), should not match previous 27 | expect(cyrb53(input)).not.toEqual(test); 28 | }); 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /packages/extension-inject/src/cyrb53.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-inject authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // cyrb53 (c) 2018 bryc (github.com/bryc) 5 | // A fast and simple hash function with decent collision resistance. 6 | // Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity. 7 | // Public domain. Attribution appreciated. 8 | // 9 | // From https://github.com/bryc/code/blob/fed42df9db547493452e32375c93d7854383e480/jshash/experimental/cyrb53.js 10 | // As shared in https://stackoverflow.com/a/52171480 11 | // 12 | // Small changes made to the code as linked above: 13 | // - Seed value is required (set as Date.now() in usage, could change) 14 | // - Return value is a hex string (as per comment in SO answer) 15 | // - TS typings added 16 | // - Non-intrusive coding-style variable declaration changes 17 | export function cyrb53 (input: string, seed = Date.now()): string { 18 | let h1 = 0xdeadbeef ^ seed; 19 | let h2 = 0x41c6ce57 ^ seed; 20 | 21 | for (let i = 0, count = input.length; i < count; i++) { 22 | const ch = input.charCodeAt(i); 23 | 24 | h1 = Math.imul(h1 ^ ch, 2654435761); 25 | h2 = Math.imul(h2 ^ ch, 1597334677); 26 | } 27 | 28 | h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909); 29 | h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909); 30 | 31 | // https://stackoverflow.com/a/52171480 32 | return (h2 >>> 0).toString(16).padStart(8, '0') + (h1 >>> 0).toString(16).padStart(8, '0'); 33 | } 34 | -------------------------------------------------------------------------------- /packages/extension-inject/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-inject authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Since we inject into pages, we skip this 5 | // import './packageDetect.js'; 6 | 7 | export * from './bundle.js'; 8 | -------------------------------------------------------------------------------- /packages/extension-inject/src/packageDetect.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2025 @polkadot/extension-inject authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Do not edit, auto-generated by @polkadot/dev 5 | // (packageInfo imports will be kept as-is, user-editable) 6 | 7 | import { detectPackage } from '@polkadot/util'; 8 | 9 | import { packageInfo } from './packageInfo.js'; 10 | 11 | detectPackage(packageInfo, null, []); 12 | -------------------------------------------------------------------------------- /packages/extension-inject/src/packageInfo.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2025 @polkadot/extension-inject authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Do not edit, auto-generated by @polkadot/dev 5 | 6 | export const packageInfo = { name: '@polkadot/extension-inject', path: 'auto', type: 'auto', version: '0.59.2' }; 7 | -------------------------------------------------------------------------------- /packages/extension-inject/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "baseUrl": "..", 5 | "outDir": "./build", 6 | "rootDir": "./src" 7 | }, 8 | "exclude": [ 9 | "**/*.spec.ts" 10 | ], 11 | "references": [] 12 | } 13 | -------------------------------------------------------------------------------- /packages/extension-inject/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "baseUrl": "..", 5 | "outDir": "./build", 6 | "rootDir": "./src", 7 | "emitDeclarationOnly": false, 8 | "noEmit": true 9 | }, 10 | "include": [ 11 | "**/*.spec.ts" 12 | ], 13 | "references": [ 14 | { "path": "../extension-inject/tsconfig.build.json" } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/extension-mocks/.skip-build: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/packages/extension-mocks/.skip-build -------------------------------------------------------------------------------- /packages/extension-mocks/.skip-npm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/packages/extension-mocks/.skip-npm -------------------------------------------------------------------------------- /packages/extension-mocks/README.md: -------------------------------------------------------------------------------- 1 | # @polkadot/extension-chains 2 | 3 | Definitions for chains that are supported by this extension. It contains the bare definitions as well as a stripped-down (call-only) metadata format. 4 | -------------------------------------------------------------------------------- /packages/extension-mocks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Jaco Greeff ", 3 | "bugs": "https://github.com/polkadot-js/extension/issues", 4 | "description": "Definitions for all known chains as exposed by the extension.", 5 | "engines": { 6 | "node": ">=18" 7 | }, 8 | "homepage": "https://github.com/polkadot-js/extension/tree/master/packages/extension-mocks#readme", 9 | "license": "Apache-2.0", 10 | "name": "@polkadot/extension-mocks", 11 | "repository": { 12 | "directory": "packages/extension-mocks", 13 | "type": "git", 14 | "url": "https://github.com/polkadot-js/extension.git" 15 | }, 16 | "sideEffects": false, 17 | "type": "module", 18 | "version": "0.59.2", 19 | "main": "index.js", 20 | "dependencies": { 21 | "sinon-chrome": "^3.0.1", 22 | "tslib": "^2.8.1" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/extension-mocks/src/chrome.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-mocks authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /* eslint-disable @typescript-eslint/no-explicit-any */ 5 | import chrome from './chromeWrapper'; 6 | 7 | class MessagingFake { 8 | private listeners: ((...params: unknown[]) => unknown)[] = []; 9 | 10 | get onMessage (): any { 11 | return { 12 | addListener: (cb: (...params: unknown[]) => unknown) => this.listeners.push(cb) 13 | }; 14 | } 15 | 16 | get onDisconnect (): any { 17 | return { 18 | addListener: (): any => undefined 19 | }; 20 | } 21 | 22 | postMessage (data: unknown): void { 23 | this.listeners.forEach((cb) => cb.call(this, data)); 24 | } 25 | } 26 | 27 | const messagingFake = new MessagingFake(); 28 | 29 | chrome.runtime.connect.returns(messagingFake); 30 | 31 | chrome.storage.local.get.returns( 32 | new Promise>((resolve, reject) => { 33 | try { 34 | const result = { 35 | authUrls: JSON.stringify({ 36 | 'localhost:3000': { 37 | authorizedAccounts: ['5FbSap4BsWfjyRhCchoVdZHkDnmDm3NEgLZ25mesq4aw2WvX'], 38 | count: 0, 39 | id: '11', 40 | origin: 'example.com', 41 | url: 'http://localhost:3000' 42 | } 43 | }) 44 | }; 45 | 46 | resolve(result); 47 | } catch (error) { 48 | reject(error); 49 | } 50 | })); 51 | 52 | chrome.storage.local.set.returns( 53 | new Promise((resolve, reject) => { 54 | try { 55 | resolve(); 56 | } catch (error) { 57 | reject(error); 58 | } 59 | })); 60 | 61 | // eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-member-access 62 | (window as any).chrome = (globalThis as any).chrome = chrome; 63 | 64 | export default chrome; 65 | -------------------------------------------------------------------------------- /packages/extension-mocks/src/chromeWrapper.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-mocks authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import sinonChrome from 'sinon-chrome'; 5 | 6 | // eslint-disable-next-line @typescript-eslint/no-namespace 7 | namespace ChromeWrapper { 8 | export interface IAction { 9 | setBadgeText: (content: object) => Promise; 10 | } 11 | export const action: IAction = { 12 | setBadgeText: (_: object) => { 13 | return new Promise((resolve, _reject) => { 14 | resolve(); 15 | }); 16 | } 17 | }; 18 | } 19 | const extendedSinonChrome = { 20 | ...sinonChrome, 21 | action: ChromeWrapper.action 22 | }; 23 | 24 | export default extendedSinonChrome; 25 | -------------------------------------------------------------------------------- /packages/extension-mocks/src/empty.js: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-mocks authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | export default ''; 5 | -------------------------------------------------------------------------------- /packages/extension-mocks/src/fileMock.cjs: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-mocks authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // eslint-disable-line 5 | module.exports = ''; 6 | -------------------------------------------------------------------------------- /packages/extension-mocks/src/loader-empty.js: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-mocks authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import path from 'node:path'; 5 | import process from 'node:process'; 6 | import { pathToFileURL } from 'node:url'; 7 | 8 | /** 9 | * Adjusts the resolver to point to empty files for .svg 10 | * 11 | * @param {*} specifier 12 | * @param {*} context 13 | * @param {*} nextResolve 14 | * @returns {*} 15 | */ 16 | export function resolve (specifier, context, nextResolve) { 17 | if (/\.(png|svg)$/.test(specifier)) { 18 | return { 19 | format: 'module', 20 | shortCircuit: true, 21 | url: pathToFileURL( 22 | path.join(process.cwd(), 'packages/extension-mocks/src/empty.js') 23 | ).href 24 | }; 25 | } 26 | 27 | return nextResolve(specifier, context); 28 | } 29 | -------------------------------------------------------------------------------- /packages/extension-mocks/src/react-i18next.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-mocks authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type React from 'react'; 5 | 6 | interface useTranslationReturnObj { 7 | i18n: { changeLanguage: () => Promise; }; 8 | t: (str: string) => string; 9 | } 10 | 11 | export const useTranslation = (): useTranslationReturnObj => { 12 | return { 13 | i18n: { 14 | changeLanguage: () => new Promise(() => { /**/ }) 15 | }, 16 | t: (str: string) => str 17 | }; 18 | }; 19 | 20 | export const withTranslation = () => (component: React.ReactElement): React.ReactElement => component; 21 | 22 | export const Trans = ({ children }: { children: React.ReactElement }): React.ReactElement => children; 23 | 24 | export default withTranslation; 25 | -------------------------------------------------------------------------------- /packages/extension-mocks/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "baseUrl": "..", 5 | "outDir": "./build", 6 | "rootDir": "./src" 7 | }, 8 | "references": [ 9 | { "path": "../extension-inject/tsconfig.build.json" } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/extension-ui/.skip-build: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/packages/extension-ui/.skip-build -------------------------------------------------------------------------------- /packages/extension-ui/.skip-npm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/packages/extension-ui/.skip-npm -------------------------------------------------------------------------------- /packages/extension-ui/README.md: -------------------------------------------------------------------------------- 1 | # @polkadot/extension-ui 2 | 3 | UI for the `@polkadot/extension` 4 | -------------------------------------------------------------------------------- /packages/extension-ui/src/MetadataCache.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { MetadataDef } from '@polkadot/extension-inject/types'; 5 | 6 | const metadataGets = new Map>(); 7 | 8 | export function getSavedMeta (genesisHash: string): Promise | undefined { 9 | return metadataGets.get(genesisHash); 10 | } 11 | 12 | export function setSavedMeta (genesisHash: string, def: Promise): Map> { 13 | return metadataGets.set(genesisHash, def); 14 | } 15 | -------------------------------------------------------------------------------- /packages/extension-ui/src/Popup/Accounts/AccountsTree.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { AccountWithChildren } from '@polkadot/extension-base/background/types'; 5 | 6 | import React from 'react'; 7 | 8 | import { styled } from '../../styled.js'; 9 | import Account from './Account.js'; 10 | 11 | interface Props extends AccountWithChildren { 12 | className?: string 13 | parentName?: string; 14 | withCheckbox?: boolean 15 | withMenu?: boolean 16 | showHidden?: boolean 17 | } 18 | 19 | function AccountsTree ({ className, parentName, showHidden = true, suri, withCheckbox = false, withMenu = true, ...account }: Props): React.ReactElement { 20 | return ( 21 |
22 | { (showHidden || !account.isHidden) && ( 23 | 32 | )} 33 | {account?.children?.map((child, index) => ( 34 | 42 | ))} 43 |
44 | ); 45 | } 46 | 47 | export default styled(AccountsTree)` 48 | .accountWichCheckbox { 49 | display: flex; 50 | align-items: center; 51 | 52 | & .address { 53 | flex: 1; 54 | } 55 | 56 | & .accountTree-checkbox label span { 57 | top: -12px; 58 | } 59 | } 60 | `; 61 | -------------------------------------------------------------------------------- /packages/extension-ui/src/Popup/Accounts/AddAccount.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React, { useCallback, useContext } from 'react'; 5 | 6 | import { ActionContext } from '../../components/index.js'; 7 | import { useTranslation } from '../../hooks/index.js'; 8 | import Header from '../../partials/Header.js'; 9 | import { styled } from '../../styled.js'; 10 | import AddAccountImage from './AddAccountImage.js'; 11 | 12 | interface Props { 13 | className?: string; 14 | } 15 | 16 | function AddAccount ({ className }: Props): React.ReactElement { 17 | const { t } = useTranslation(); 18 | const onAction = useContext(ActionContext); 19 | const _onClick = useCallback( 20 | () => onAction('/account/create'), 21 | [onAction] 22 | ); 23 | 24 | return ( 25 | <> 26 |
31 |
32 |
33 | 34 |
35 |
36 |

{t("You currently don't have any accounts. Create your first account to get started.")}

37 |
38 |
39 | 40 | ); 41 | } 42 | 43 | export default React.memo(styled(AddAccount)` 44 | color: var(--textColor); 45 | height: 100%; 46 | 47 | h3 { 48 | color: var(--textColor); 49 | margin-top: 0; 50 | font-weight: normal; 51 | font-size: 24px; 52 | line-height: 33px; 53 | text-align: center; 54 | } 55 | 56 | > .image { 57 | display: flex; 58 | justify-content: center; 59 | } 60 | 61 | > .no-accounts p { 62 | text-align: center; 63 | font-size: 16px; 64 | line-height: 26px; 65 | margin: 0 30px; 66 | color: var(--subTextColor); 67 | } 68 | `); 69 | -------------------------------------------------------------------------------- /packages/extension-ui/src/Popup/AuthManagement/WebsiteEntry.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { AuthUrlInfo } from '@polkadot/extension-base/background/types'; 5 | 6 | import React, { useCallback } from 'react'; 7 | import { Link } from 'react-router-dom'; 8 | 9 | import RemoveAuth from '../../components/RemoveAuth.js'; 10 | import { useTranslation } from '../../hooks/index.js'; 11 | import { styled } from '../../styled.js'; 12 | 13 | interface Props { 14 | className?: string; 15 | info: AuthUrlInfo; 16 | removeAuth: (url: string) => void; 17 | url: string; 18 | } 19 | 20 | function WebsiteEntry ({ className = '', info: { authorizedAccounts, isAllowed }, removeAuth, url }: Props): React.ReactElement { 21 | const { t } = useTranslation(); 22 | 23 | const _removeAuth = useCallback( 24 | () => removeAuth(url), 25 | [removeAuth, url] 26 | ); 27 | 28 | return ( 29 |
30 | 31 |
32 | {url} 33 |
34 | { 38 | authorizedAccounts?.length 39 | ? t('{{total}} accounts', { 40 | replace: { 41 | total: authorizedAccounts.length 42 | } 43 | }) 44 | : isAllowed 45 | ? t('all accounts') 46 | : t('no accounts') 47 | } 48 |
49 | ); 50 | } 51 | 52 | export default styled(WebsiteEntry)` 53 | display: flex; 54 | align-items: center; 55 | margin-top: .2rem; 56 | 57 | .url{ 58 | flex: 1; 59 | } 60 | 61 | .connectedAccounts{ 62 | margin-left: .5rem; 63 | background-color: var(--primaryColor); 64 | color: white; 65 | cursor: pointer; 66 | padding: 0 0.5rem; 67 | border-radius: 4px; 68 | text-decoration: none; 69 | } 70 | `; 71 | -------------------------------------------------------------------------------- /packages/extension-ui/src/Popup/Authorize/NoAccount.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { t } from 'i18next'; 5 | import React, { useCallback } from 'react'; 6 | import { Trans } from 'react-i18next'; 7 | 8 | import { Button, Warning } from '../../components/index.js'; 9 | import { rejectAuthRequest } from '../../messaging.js'; 10 | import { styled } from '../../styled.js'; 11 | 12 | interface Props { 13 | authId: string; 14 | className?: string; 15 | } 16 | 17 | function NoAccount ({ authId, className }: Props): React.ReactElement { 18 | const _onClick = useCallback(() => { 19 | rejectAuthRequest(authId).catch(console.error); 20 | }, [authId] 21 | ); 22 | 23 | return ( 24 |
25 | 26 | You do not have any account. Please create an account and refresh the application's page. 27 | 28 | 34 |
35 | ); 36 | } 37 | 38 | export default styled(NoAccount)` 39 | .acceptButton { 40 | width: 90%; 41 | margin: 25px auto 0; 42 | } 43 | 44 | .warningMargin { 45 | margin: 1rem 24px 0 1.45rem; 46 | } 47 | `; 48 | -------------------------------------------------------------------------------- /packages/extension-ui/src/Popup/CreateAccount/Mnemonic.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React, { useCallback, useState } from 'react'; 5 | 6 | import { ButtonArea, Checkbox, MnemonicSeed, NextStepButton, VerticalSpace, Warning } from '../../components/index.js'; 7 | import { useToast, useTranslation } from '../../hooks/index.js'; 8 | 9 | interface Props { 10 | onNextStep: () => void; 11 | seed: string; 12 | } 13 | 14 | function Mnemonic ({ onNextStep, seed }: Props): React.ReactElement { 15 | const { t } = useTranslation(); 16 | const [isMnemonicSaved, setIsMnemonicSaved] = useState(false); 17 | const { show } = useToast(); 18 | 19 | const _onCopy = useCallback((): void => { 20 | show(t('Copied')); 21 | }, [show, t]); 22 | 23 | return ( 24 | <> 25 | 29 | 30 | {t("Please write down your wallet's mnemonic seed and keep it in a safe place. The mnemonic can be used to restore your wallet. Keep it carefully to not lose your assets.")} 31 | 32 | 33 | 38 | 39 | 43 | {t('Next step')} 44 | 45 | 46 | 47 | ); 48 | } 49 | 50 | export default React.memo(Mnemonic); 51 | -------------------------------------------------------------------------------- /packages/extension-ui/src/Popup/Metadata/index.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React, { useContext } from 'react'; 5 | 6 | import { Loading, MetadataReqContext } from '../../components/index.js'; 7 | import { useTranslation } from '../../hooks/index.js'; 8 | import { Header } from '../../partials/index.js'; 9 | import Request from './Request.js'; 10 | 11 | export default function Metadata (): React.ReactElement { 12 | const { t } = useTranslation(); 13 | const requests = useContext(MetadataReqContext); 14 | 15 | return ( 16 | <> 17 |
18 | {requests[0] 19 | ? ( 20 | 26 | ) 27 | : 28 | } 29 | 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /packages/extension-ui/src/Popup/PhishingDetected.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | import { Trans } from 'react-i18next'; 6 | import { useParams } from 'react-router'; 7 | 8 | import { useTranslation } from '../hooks/index.js'; 9 | import { Header } from '../partials/index.js'; 10 | import { styled } from '../styled.js'; 11 | 12 | interface Props { 13 | className?: string; 14 | } 15 | 16 | interface WebsiteState { 17 | website: string; 18 | } 19 | 20 | function PhishingDetected ({ className }: Props): React.ReactElement { 21 | const { t } = useTranslation(); 22 | const { website } = useParams(); 23 | const decodedWebsite = decodeURIComponent(website); 24 | 25 | return ( 26 | <> 27 |
28 |
29 |

30 | {t('You have been redirected because the Polkadot{.js} extension believes that this website could compromise the security of your accounts and your tokens.')} 31 |

32 |

33 | {decodedWebsite} 34 |

35 |

36 | 37 | Note that this website was reported on a community-driven, curated list. It might be incomplete or inaccurate. If you think that this website was flagged incorrectly, please open an issue by clicking here. 38 | 39 |

40 |
41 | 42 | ); 43 | } 44 | 45 | export default styled(PhishingDetected)` 46 | p { 47 | color: var(--subTextColor); 48 | margin-bottom: 1rem; 49 | margin-top: 0; 50 | 51 | a { 52 | color: var(--subTextColor); 53 | } 54 | 55 | &.websiteAddress { 56 | font-size: 1.3rem; 57 | text-align: center; 58 | } 59 | } 60 | `; 61 | -------------------------------------------------------------------------------- /packages/extension-ui/src/Popup/Signing/Bytes.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React, { useMemo } from 'react'; 5 | 6 | import { isAscii, u8aToString, u8aUnwrapBytes } from '@polkadot/util'; 7 | 8 | import { useTranslation } from '../../hooks/index.js'; 9 | import { styled } from '../../styled.js'; 10 | 11 | interface Props { 12 | className?: string; 13 | bytes: string; 14 | url: string; 15 | } 16 | 17 | function Bytes ({ bytes, className, url }: Props): React.ReactElement { 18 | const { t } = useTranslation(); 19 | 20 | const text = useMemo( 21 | () => isAscii(bytes) 22 | ? u8aToString(u8aUnwrapBytes(bytes)) 23 | : bytes, 24 | [bytes] 25 | ); 26 | 27 | return ( 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
{t('from')}{url}
{t('bytes')}
{text}
40 | ); 41 | } 42 | 43 | export default styled(Bytes)` 44 | border: 0; 45 | display: block; 46 | font-size: 0.75rem; 47 | margin-top: 0.75rem; 48 | 49 | td.data { 50 | max-width: 0; 51 | overflow: hidden; 52 | text-align: left; 53 | text-overflow: ellipsis; 54 | vertical-align: middle; 55 | width: 100%; 56 | padding: 0.15rem; 57 | 58 | &.pre { 59 | padding: 0px; 60 | 61 | div { 62 | padding: 0.15rem; 63 | font-family: inherit; 64 | font-size: 0.75rem; 65 | margin: 0; 66 | white-space: pre; 67 | overflow: auto; 68 | max-height: calc(100vh - 480px); 69 | min-height: var(--boxLineHeight); 70 | border: 1px solid var(--boxBorderColor); 71 | background: var(--boxBackground); 72 | line-height: var(--boxLineHeight); 73 | } 74 | } 75 | } 76 | 77 | td.label { 78 | opacity: 0.5; 79 | padding: 0 0.5rem; 80 | text-align: right; 81 | vertical-align: middle; 82 | white-space: nowrap; 83 | } 84 | `; 85 | -------------------------------------------------------------------------------- /packages/extension-ui/src/Popup/Signing/Unlock.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React, { useCallback } from 'react'; 5 | 6 | import { InputWithLabel, Warning } from '../../components/index.js'; 7 | import { useTranslation } from '../../hooks/index.js'; 8 | 9 | interface Props { 10 | className?: string; 11 | error?: string | null; 12 | isBusy: boolean; 13 | onSign: () => void; 14 | password: string; 15 | setError: (error: string | null) => void; 16 | setPassword: (password: string) => void; 17 | } 18 | 19 | function Unlock ({ className, error, isBusy, onSign, password, setError, setPassword }: Props): React.ReactElement { 20 | const { t } = useTranslation(); 21 | 22 | const _onChangePassword = useCallback( 23 | (password: string): void => { 24 | setPassword(password); 25 | setError(null); 26 | }, 27 | [setError, setPassword] 28 | ); 29 | 30 | return ( 31 |
32 | 43 | {error && ( 44 | 48 | {error} 49 | 50 | )} 51 |
52 | ); 53 | } 54 | 55 | export default React.memo(Unlock); 56 | -------------------------------------------------------------------------------- /packages/extension-ui/src/Popup/Welcome.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React, { useCallback, useContext } from 'react'; 5 | 6 | import { ActionContext, Box, Button, ButtonArea, List, VerticalSpace } from '../components/index.js'; 7 | import { useTranslation } from '../hooks/index.js'; 8 | import { Header } from '../partials/index.js'; 9 | import { styled } from '../styled.js'; 10 | 11 | interface Props { 12 | className?: string; 13 | } 14 | 15 | function Welcome ({ className }: Props): React.ReactElement { 16 | const { t } = useTranslation(); 17 | const onAction = useContext(ActionContext); 18 | 19 | const _onClick = useCallback( 20 | (): void => { 21 | window.localStorage.setItem('welcome_read', 'ok'); 22 | onAction(); 23 | }, 24 | [onAction] 25 | ); 26 | 27 | return ( 28 | <> 29 |
30 |
31 |

{t('Before we start, just a couple of notes regarding use:')}

32 | 33 | 34 |
  • {t('We do not send any clicks, pageviews or events to a central server')}
  • 35 |
  • {t('We do not use any trackers or analytics')}
  • 36 |
  • {t("We don't collect keys, addresses or any information - your information never leaves this machine")}
  • 37 |
    38 |
    39 |

    {t('... we are not in the information collection business (even anonymized).')}

    40 |
    41 | 42 | 43 | 44 | 45 | 46 | ); 47 | } 48 | 49 | export default styled(Welcome)` 50 | p { 51 | color: var(--subTextColor); 52 | margin-bottom: 6px; 53 | margin-top: 0; 54 | } 55 | `; 56 | -------------------------------------------------------------------------------- /packages/extension-ui/src/adapter.d.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | declare module '@wojtekmaj/enzyme-adapter-react-17'; 5 | -------------------------------------------------------------------------------- /packages/extension-ui/src/assets/arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /packages/extension-ui/src/assets/checkmark.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /packages/extension-ui/src/assets/details.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /packages/extension-ui/src/assets/images.d.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | declare module '*.svg' { 5 | const url: string; 6 | export default url; 7 | } 8 | 9 | declare module '*.png' { 10 | const url: string; 11 | export default url; 12 | } 13 | 14 | declare module '*.woff' { 15 | const url: string; 16 | export default url; 17 | } 18 | 19 | declare module '*.woff2' { 20 | const url: string; 21 | export default url; 22 | } 23 | -------------------------------------------------------------------------------- /packages/extension-ui/src/assets/pjs.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /packages/extension-ui/src/assets/spinner-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/packages/extension-ui/src/assets/spinner-white.png -------------------------------------------------------------------------------- /packages/extension-ui/src/assets/spinner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkadot-js/extension/9f29135a0ac2e2616891b7150fbab7815a45f0a9/packages/extension-ui/src/assets/spinner.png -------------------------------------------------------------------------------- /packages/extension-ui/src/components/ActionBar.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | 8 | interface Props { 9 | children: React.ReactNode; 10 | className?: string; 11 | } 12 | 13 | function ActionBar ({ children, className }: Props): React.ReactElement { 14 | return ( 15 |
    16 | {children} 17 |
    18 | ); 19 | } 20 | 21 | export default styled(ActionBar)` 22 | align-content: flex-end; 23 | display: flex; 24 | justify-content: space-between; 25 | padding: 0.25rem; 26 | text-align: right; 27 | 28 | a { 29 | cursor: pointer; 30 | } 31 | 32 | a+a { 33 | margin-left: 0.75rem; 34 | } 35 | `; 36 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/ActionText.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { IconDefinition } from '@fortawesome/fontawesome-svg-core'; 5 | import type { MouseEventHandler } from 'react'; 6 | 7 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 8 | import React from 'react'; 9 | 10 | import { styled } from '../styled.js'; 11 | 12 | interface Props { 13 | className?: string; 14 | icon?: IconDefinition; 15 | onClick: MouseEventHandler; 16 | text: string; 17 | } 18 | 19 | function ActionText ({ className, icon, onClick, text }: Props): React.ReactElement { 20 | return ( 21 |
    25 | {icon && } 26 | {text} 27 |
    28 | ); 29 | } 30 | 31 | export default styled(ActionText)` 32 | cursor: pointer; 33 | 34 | span { 35 | color: var(--labelColor); 36 | font-size: var(--labelFontSize); 37 | line-height: var(--labelLineHeight); 38 | text-decoration-line: underline; 39 | } 40 | 41 | .svg-inline--fa { 42 | color: var(--iconNeutralColor); 43 | display: inline-block; 44 | margin-right: 0.3rem; 45 | position: relative; 46 | top: 2px; 47 | } 48 | `; 49 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/BackButton.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { faArrowLeft } from '@fortawesome/free-solid-svg-icons'; 5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 6 | import React from 'react'; 7 | 8 | import { styled } from '../styled.js'; 9 | import Button from './Button.js'; 10 | 11 | interface Props { 12 | className?: string; 13 | onClick: () => void; 14 | } 15 | 16 | function BackButton ({ className, onClick }: Props): React.ReactElement { 17 | return ( 18 | 28 | ); 29 | } 30 | 31 | export default styled(BackButton)` 32 | background: var(--backButtonBackground); 33 | margin-right: 11px; 34 | width: 42px; 35 | 36 | .arrowLeft { 37 | color: var(--backButtonTextColor); 38 | display: block; 39 | margin: auto; 40 | } 41 | 42 | &:not(:disabled):hover { 43 | background: var(--backButtonBackgroundHover); 44 | } 45 | `; 46 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/Box.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | 8 | interface Props { 9 | banner?: React.ReactNode; 10 | children: React.ReactNode; 11 | className?: string; 12 | } 13 | 14 | function Box ({ banner, children, className }: Props): React.ReactElement { 15 | return ( 16 |
    17 | {children} 18 | {banner &&
    {banner}
    } 19 |
    20 | ); 21 | } 22 | 23 | export default styled(Box)` 24 | background: var(--readonlyInputBackground); 25 | border: 1px solid var(--inputBorderColor); 26 | border-radius: var(--borderRadius); 27 | color: var(--subTextColor); 28 | font-family: var(--fontFamily); 29 | font-size: var(--fontSize); 30 | margin: 0.75rem 24px; 31 | padding: var(--boxPadding); 32 | position: relative; 33 | 34 | .banner { 35 | background: darkorange; 36 | border-radius: 0 var(--borderRadius) 0 var(--borderRadius); 37 | color: white; 38 | font-size: 0.75rem; 39 | padding: 0.25rem 0.5rem; 40 | position: absolute; 41 | right: 0; 42 | top: 0; 43 | } 44 | `; 45 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/BoxWithLabel.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | import styled from 'styled-components'; 6 | 7 | import Label from './Label.js'; 8 | 9 | interface Props { 10 | className?: string; 11 | label: string; 12 | value?: string; 13 | } 14 | 15 | function BoxWithLabel ({ className, label, value }: Props): React.ReactElement { 16 | return ( 17 | 25 | ); 26 | } 27 | 28 | export default styled(BoxWithLabel)` 29 | .seedBox { 30 | background: var(--readonlyInputBackground); 31 | box-shadow: none; 32 | border-radius: var(--borderRadius); 33 | border: 1px solid var(--inputBorderColor); 34 | border-color: var(--inputBorderColor); 35 | box-sizing: border-box; 36 | display: block; 37 | font-family: var(--fontFamily); 38 | outline: none; 39 | resize: none; 40 | width: 100%; 41 | } 42 | `; 43 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/ButtonArea.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | 8 | interface Props { 9 | className?: string; 10 | children: React.ReactNode; 11 | } 12 | 13 | function ButtonArea ({ children, className }: Props): React.ReactElement { 14 | return ( 15 |
    16 | {children} 17 |
    18 | ); 19 | } 20 | 21 | export default styled(ButtonArea)` 22 | display: flex; 23 | flex-direction: row; 24 | background: var(--highlightedAreaBackground); 25 | border-top: 1px solid var(--inputBorderColor); 26 | padding: 12px 24px; 27 | margin-left: 0; 28 | margin-right: 0; 29 | 30 | & > button:not(:last-of-type) { 31 | margin-right: 8px; 32 | } 33 | `; 34 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/ButtonWithSubtitle.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | import { Button } from './index.js'; 8 | 9 | interface ButtonWithSubtitleProps { 10 | title: string; 11 | subTitle: string; 12 | children?: string; 13 | to: string; 14 | } 15 | 16 | export default function ButtonWithSubtitle ({ children, subTitle, title, to }: ButtonWithSubtitleProps): React.ReactElement { 17 | return ( 18 | 19 |

    {title}

    20 | {subTitle} 21 | {children} 22 |
    23 | ); 24 | } 25 | 26 | const StyledButton = styled(Button)` 27 | button { 28 | padding-top: 0; 29 | padding-bottom: 0; 30 | } 31 | 32 | p { 33 | margin: 0; 34 | font-size: 15px; 35 | line-height: 20px; 36 | } 37 | 38 | span { 39 | display: block; 40 | font-size: 12px; 41 | line-height: 16px; 42 | } 43 | `; 44 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/ErrorBoundary.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributor 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React, { useCallback, useEffect, useState } from 'react'; 5 | import { useTranslation } from 'react-i18next'; 6 | 7 | import Header from '../partials/Header'; 8 | import Button from './Button'; 9 | import ButtonArea from './ButtonArea'; 10 | import VerticalSpace from './VerticalSpace'; 11 | 12 | interface ErrorBoundaryProps { 13 | children: React.ReactNode; 14 | className?: string; 15 | error?: Error | null; 16 | trigger?: string; 17 | } 18 | 19 | const ErrorBoundary: React.FC = ({ children, error: propError, trigger }) => { 20 | const { t } = useTranslation(); 21 | const [error, setError] = useState(null); 22 | 23 | useEffect(() => { 24 | if (error !== null && trigger) { 25 | setError(null); 26 | } 27 | }, [error, trigger]); 28 | 29 | useEffect(() => { 30 | if (propError) { 31 | setError(propError); 32 | } 33 | }, [propError]); 34 | 35 | const goHome = useCallback(() => { 36 | setError(null); 37 | window.location.hash = '/'; 38 | }, [setError]); 39 | 40 | if (error) { 41 | return ( 42 | <> 43 |
    44 |
    45 | {t('Something went wrong with the query and rendering of this component. {{message}}', { 46 | replace: { message: error.message } 47 | })} 48 |
    49 | 50 | 51 | 54 | 55 | 56 | ); 57 | } 58 | 59 | return <>{children}; 60 | }; 61 | 62 | export default ErrorBoundary; 63 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/Icon.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | 8 | interface Props { 9 | className?: string; 10 | icon: string; 11 | onClick?: () => void; 12 | } 13 | 14 | function Icon ({ className = '', icon, onClick }: Props): React.ReactElement { 15 | return ( 16 |
    20 | {icon} 21 |
    22 | ); 23 | } 24 | 25 | export default styled(Icon)(({ onClick }) => ` 26 | background: white; 27 | border-radius: 50%; 28 | box-sizing: border-box; 29 | cursor: ${onClick ? 'pointer' : 'inherit'}; 30 | text-align: center; 31 | `); 32 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/Identicon.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { IconTheme } from '@polkadot/react-identicon/types'; 5 | 6 | import React from 'react'; 7 | 8 | import { Identicon as Icon } from '@polkadot/react-identicon'; 9 | 10 | import { styled } from '../styled.js'; 11 | 12 | interface Props { 13 | className?: string; 14 | iconTheme?: IconTheme; 15 | isExternal?: boolean | null; 16 | onCopy?: () => void; 17 | prefix?: number; 18 | value?: string | null; 19 | } 20 | 21 | function Identicon ({ className, iconTheme, onCopy, prefix, value }: Props): React.ReactElement { 22 | return ( 23 |
    24 | 32 |
    33 | ); 34 | } 35 | 36 | export default styled(Identicon)` 37 | background: rgba(192, 192, 292, 0.25); 38 | border-radius: 50%; 39 | display: flex; 40 | justify-content: center; 41 | 42 | .container:before { 43 | box-shadow: none; 44 | background: var(--identiconBackground); 45 | } 46 | 47 | svg { 48 | circle:first-of-type { 49 | display: none; 50 | } 51 | } 52 | `; 53 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/InputFilter.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { faTimes } from '@fortawesome/free-solid-svg-icons'; 5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 6 | import React, { useCallback, useRef } from 'react'; 7 | 8 | import { styled } from '../styled.js'; 9 | import { Input } from './TextInputs.js'; 10 | 11 | interface Props { 12 | className?: string; 13 | onChange: (filter: string) => void; 14 | placeholder: string; 15 | value: string; 16 | withReset?: boolean; 17 | } 18 | 19 | function InputFilter ({ className, onChange, placeholder, value, withReset = false }: Props) { 20 | const inputRef: React.RefObject | null = useRef(null); 21 | 22 | const onChangeFilter = useCallback((event: React.ChangeEvent) => { 23 | onChange(event.target.value); 24 | }, [onChange]); 25 | 26 | const onResetFilter = useCallback(() => { 27 | onChange(''); 28 | inputRef.current && inputRef.current.select(); 29 | }, [onChange]); 30 | 31 | return ( 32 |
    33 | 44 | {withReset && !!value && ( 45 | 50 | )} 51 |
    52 | ); 53 | } 54 | 55 | export default styled(InputFilter)` 56 | padding-left: 1rem !important; 57 | padding-right: 1rem !important; 58 | position: relative; 59 | 60 | .resetIcon { 61 | position: absolute; 62 | right: 28px; 63 | top: 12px; 64 | color: var(--iconNeutralColor); 65 | cursor: pointer; 66 | } 67 | `; 68 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/Label.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | 8 | interface Props { 9 | children: React.ReactNode; 10 | className?: string; 11 | label: string; 12 | } 13 | 14 | function Label ({ children, className, label }: Props): React.ReactElement { 15 | return ( 16 |
    17 | 18 | {children} 19 |
    20 | ); 21 | } 22 | 23 | export default styled(Label)` 24 | color: var(--textColor); 25 | 26 | label { 27 | font-size: var(--inputLabelFontSize); 28 | line-height: 14px; 29 | letter-spacing: 0.04em; 30 | opacity: 0.65; 31 | margin-bottom: 12px; 32 | text-transform: uppercase; 33 | } 34 | `; 35 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/Link.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | import { Link as RouterLink } from 'react-router-dom'; 6 | 7 | import { styled } from '../styled.js'; 8 | 9 | interface Props { 10 | children?: React.ReactNode; 11 | className?: string; 12 | isDanger?: boolean; 13 | isDisabled?: boolean; 14 | onClick?: () => void; 15 | title?: string; 16 | to?: string; 17 | } 18 | 19 | function Link ({ children, className = '', isDisabled, onClick, title, to }: Props): React.ReactElement { 20 | if (isDisabled) { 21 | return ( 22 |
    26 | {children} 27 |
    28 | ); 29 | } 30 | 31 | return to 32 | ? ( 33 | 39 | {children} 40 | 41 | ) 42 | : ( 43 | 49 | {children} 50 | 51 | ); 52 | } 53 | 54 | export default styled(Link)(({ isDanger }) => ` 55 | align-items: center; 56 | color: var(${isDanger ? '--textColorDanger' : '--textColor'}); 57 | display: flex; 58 | opacity: 0.85; 59 | text-decoration: none; 60 | vertical-align: middle; 61 | 62 | &:hover { 63 | color: var(${isDanger ? '--textColorDanger' : '--textColor'}); 64 | opacity: 1.0; 65 | } 66 | 67 | &:visited { 68 | color: var(${isDanger ? '--textColorDanger' : '--textColor'}); 69 | } 70 | 71 | &.isDisabled { 72 | opacity: 0.4; 73 | } 74 | `); 75 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/List.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | 8 | interface Props { 9 | className?: string; 10 | children: React.ReactNode; 11 | } 12 | 13 | const List = ({ children, className }: Props) => ( 14 |
      15 | {children} 16 |
    17 | ); 18 | 19 | export default styled(List)` 20 | list-style: none; 21 | padding-inline-start: 10px; 22 | padding-inline-end: 10px; 23 | text-indent: -22px; 24 | margin-left: 21px; 25 | 26 | li { 27 | margin-bottom: 8px; 28 | } 29 | 30 | li::before { 31 | content: '\\2022'; 32 | color: var(--primaryColor); 33 | font-size: 30px; 34 | font-weight: bold; 35 | margin-right: 10px; 36 | vertical-align: -20%; 37 | } 38 | `; 39 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/Loading.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { useTranslation } from '../hooks/index.js'; 7 | 8 | interface Props { 9 | children?: React.ReactNode; 10 | } 11 | 12 | export default function Loading ({ children }: Props): React.ReactElement { 13 | const { t } = useTranslation(); 14 | 15 | if (!children) { 16 | return ( 17 |
    {t('... loading ...')}
    18 | ); 19 | } 20 | 21 | return ( 22 | <>{children} 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/Main.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | 8 | interface Props { 9 | children: React.ReactNode; 10 | className?: string; 11 | } 12 | 13 | function Main ({ children, className }: Props): React.ReactElement { 14 | return ( 15 |
    16 | {children} 17 |
    18 | ); 19 | } 20 | 21 | export default styled(Main)` 22 | display: flex; 23 | flex-direction: column; 24 | height: calc(100vh - 2px); 25 | background: var(--background); 26 | color: var(--textColor); 27 | font-size: var(--fontSize); 28 | line-height: var(--lineHeight); 29 | border: 1px solid var(--inputBorderColor); 30 | 31 | * { 32 | font-family: var(--fontFamily); 33 | } 34 | 35 | > * { 36 | padding-left: 24px; 37 | padding-right: 24px; 38 | } 39 | `; 40 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/Menu.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | 8 | interface Props { 9 | children: React.ReactNode; 10 | className?: string; 11 | reference: React.RefObject; 12 | } 13 | 14 | function Menu ({ children, className, reference }: Props): React.ReactElement { 15 | return ( 16 |
    20 | {children} 21 |
    22 | ); 23 | } 24 | 25 | export default styled(Menu)` 26 | background: var(--popupBackground); 27 | border-radius: 4px; 28 | border: 1px solid var(--boxBorderColor); 29 | box-sizing: border-box; 30 | box-shadow: 0 0 10px var(--boxShadow); 31 | margin-top: 60px; 32 | padding: 16px 0; 33 | position: absolute; 34 | right: 0; 35 | z-index: 2; 36 | `; 37 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/MenuDivider.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | 8 | interface Props { 9 | className?: string; 10 | } 11 | 12 | function MenuDivider ({ className }: Props): React.ReactElement { 13 | return ( 14 |
    15 | ); 16 | } 17 | 18 | export default styled(MenuDivider)` 19 | padding-top: 16px; 20 | margin-bottom: 16px; 21 | border-bottom: 1px solid var(--inputBorderColor); 22 | `; 23 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/MenuItem.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | 8 | interface Props { 9 | children: React.ReactNode; 10 | className?: string; 11 | noBorder?: boolean; 12 | title?: React.ReactNode; 13 | } 14 | 15 | function MenuItem ({ children, className = '', title }: Props): React.ReactElement { 16 | return ( 17 |
    18 | {title && ( 19 |
    {title}
    20 | )} 21 | {children} 22 |
    23 | ); 24 | } 25 | 26 | export default styled(MenuItem)` 27 | min-width: 13rem; 28 | padding: 0 16px; 29 | max-width: 100%; 30 | 31 | > .itemTitle { 32 | margin: 0; 33 | width: 100%; 34 | font-size: var(--inputLabelFontSize); 35 | line-height: 14px; 36 | letter-spacing: 0.04em; 37 | text-transform: uppercase; 38 | color: var(--textColor); 39 | opacity: 0.65; 40 | } 41 | 42 | &+&.isTitled { 43 | margin-top: 16px; 44 | } 45 | `; 46 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/MnemonicSeed.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { MouseEventHandler } from 'react'; 5 | 6 | import { faCopy } from '@fortawesome/free-regular-svg-icons'; 7 | import React from 'react'; 8 | import CopyToClipboard from 'react-copy-to-clipboard'; 9 | 10 | import { useTranslation } from '../hooks/index.js'; 11 | import { styled } from '../styled.js'; 12 | import ActionText from './ActionText.js'; 13 | import BoxWithLabel from './BoxWithLabel.js'; 14 | 15 | interface Props { 16 | seed: string; 17 | onCopy: MouseEventHandler; 18 | className?: string; 19 | } 20 | 21 | function MnemonicSeed ({ className, onCopy, seed }: Props): React.ReactElement { 22 | const { t } = useTranslation(); 23 | 24 | return ( 25 |
    26 | 31 |
    32 | 33 | 40 | 41 |
    42 |
    43 | ); 44 | } 45 | 46 | export default styled(MnemonicSeed)` 47 | margin-bottom: 21px; 48 | 49 | .buttonsRow { 50 | display: flex; 51 | flex-direction: row; 52 | 53 | .copyBtn { 54 | margin-right: 32px; 55 | } 56 | } 57 | 58 | .mnemonicDisplay { 59 | .seedBox { 60 | color: var(--primaryColor); 61 | font-size: var(--fontSize); 62 | height: unset; 63 | letter-spacing: -0.01em; 64 | line-height: var(--lineHeight); 65 | margin-bottom: 10px; 66 | padding: 14px; 67 | } 68 | } 69 | `; 70 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/NextStepButton.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { ButtonProps } from './Button.js'; 5 | 6 | import { faArrowRight } from '@fortawesome/free-solid-svg-icons'; 7 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 8 | import React from 'react'; 9 | 10 | import { styled } from '../styled.js'; 11 | import Button from './Button.js'; 12 | 13 | function NextStepButton ({ children, ...props }: ButtonProps): React.ReactElement { 14 | return ( 15 | 23 | ); 24 | } 25 | 26 | export default styled(NextStepButton)` 27 | .arrowRight{ 28 | float: right; 29 | margin-top: 4px; 30 | margin-right: 1px; 31 | color: var(--buttonTextColor); 32 | } 33 | `; 34 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/RemoveAuth.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import { faTrash } from '@fortawesome/free-solid-svg-icons'; 5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 6 | import React from 'react'; 7 | 8 | import { styled } from '../styled.js'; 9 | 10 | interface Props { 11 | className?: string 12 | onRemove: () => void 13 | } 14 | 15 | function RemoveAuth ({ className, onRemove }: Props): React.ReactElement { 16 | return ( 17 | 23 | ); 24 | } 25 | 26 | export default styled(RemoveAuth)` 27 | cursor: pointer; 28 | color: var(--labelColor); 29 | margin-right: 1rem; 30 | 31 | &.selected { 32 | color: var(--primaryColor); 33 | } 34 | `; 35 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/Spinner.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import spinnerSrc from '../assets/spinner.png'; 7 | import { styled } from '../styled.js'; 8 | 9 | interface Props { 10 | className?: string; 11 | size?: 'normal'; 12 | } 13 | 14 | function Spinner ({ className = '', size = 'normal' }: Props): React.ReactElement { 15 | return ( 16 | 20 | ); 21 | } 22 | 23 | export default React.memo(styled(Spinner)` 24 | bottom: 0rem; 25 | height: 3rem; 26 | left: 50%; 27 | margin-left: -1.5rem; 28 | position: absolute; 29 | width: 3rem; 30 | z-index: 31 | `); 32 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/Svg.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | 8 | interface Props { 9 | className?: string; 10 | src: string; 11 | } 12 | 13 | const Svg = ({ className }: Props) => ; 14 | 15 | export default styled(Svg)(({ src }) => ` 16 | background: var(--textColor); 17 | display: inline-block; 18 | mask: url(${src}); 19 | mask-size: cover; 20 | `); 21 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/Switch.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React, { useCallback } from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | 8 | interface Props { 9 | checked: boolean; 10 | onChange: (checked: boolean) => void; 11 | uncheckedLabel: string; 12 | checkedLabel: string; 13 | className?: string; 14 | } 15 | 16 | function Switch ({ checked, checkedLabel, className, onChange, uncheckedLabel }: Props): React.ReactElement { 17 | const _onChange = useCallback( 18 | (event: React.ChangeEvent) => onChange(event.target.checked), 19 | [onChange] 20 | ); 21 | 22 | return ( 23 |
    24 | {uncheckedLabel} 25 | 34 | {checkedLabel} 35 |
    36 | ); 37 | } 38 | 39 | export default styled(Switch)` 40 | label { 41 | position: relative; 42 | display: inline-block; 43 | width: 48px; 44 | height: 24px; 45 | margin: 8px; 46 | } 47 | 48 | .checkbox { 49 | opacity: 0; 50 | width: 0; 51 | height: 0; 52 | 53 | &:checked + .slider:before { 54 | transform: translateX(24px); 55 | } 56 | } 57 | 58 | .slider { 59 | position: absolute; 60 | cursor: pointer; 61 | top: 0; 62 | left: 0; 63 | right: 0; 64 | bottom: 0; 65 | background-color: var(--readonlyInputBackground); 66 | transition: 0.2s; 67 | border-radius: 100px; 68 | border: 1px solid var(--inputBorderColor); 69 | 70 | &:before { 71 | position: absolute; 72 | content: ''; 73 | height: 16px; 74 | width: 16px; 75 | left: 4px; 76 | bottom: 3px; 77 | background-color: var(--primaryColor); 78 | transition: 0.4s; 79 | border-radius: 50%; 80 | } 81 | } 82 | `; 83 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/Table.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React from 'react'; 5 | 6 | import { styled } from '../styled.js'; 7 | 8 | interface Props { 9 | children: React.ReactNode; 10 | className?: string; 11 | isFull?: boolean; 12 | } 13 | 14 | function Table ({ children, className = '', isFull }: Props): React.ReactElement { 15 | return ( 16 | 17 | 18 | {children} 19 | 20 |
    21 | ); 22 | } 23 | 24 | export default React.memo(styled(Table)` 25 | border: 0; 26 | display: block; 27 | font-size: var(--labelFontSize); 28 | line-height: var(--labelLineHeight); 29 | margin-bottom: 1rem; 30 | 31 | &.isFull { 32 | height: 100%; 33 | overflow: auto; 34 | } 35 | 36 | td.data { 37 | max-width: 0; 38 | overflow: hidden; 39 | text-align: left; 40 | text-overflow: ellipsis; 41 | vertical-align: middle; 42 | width: 100%; 43 | 44 | pre { 45 | font-family: inherit; 46 | font-size: 0.75rem; 47 | margin: 0; 48 | } 49 | } 50 | 51 | td.label { 52 | opacity: 0.5; 53 | padding: 0 0.5rem; 54 | text-align: right; 55 | vertical-align: top; 56 | white-space: nowrap; 57 | } 58 | 59 | details { 60 | cursor: pointer; 61 | max-width: 24rem; 62 | 63 | summary { 64 | text-overflow: ellipsis; 65 | outline: 0; 66 | overflow: hidden; 67 | white-space: nowrap; 68 | } 69 | 70 | &[open] summary { 71 | white-space: normal; 72 | } 73 | } 74 | `); 75 | -------------------------------------------------------------------------------- /packages/extension-ui/src/components/TextAreaWithLabel.tsx: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2025 @polkadot/extension-ui authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import React, { useCallback } from 'react'; 5 | 6 | import Label from './Label.js'; 7 | import { TextArea } from './TextInputs.js'; 8 | 9 | interface Props { 10 | className?: string; 11 | isError?: boolean; 12 | isFocused?: boolean; 13 | isReadOnly?: boolean; 14 | rowsCount?: number; 15 | label: string; 16 | onChange?: (value: string) => void; 17 | value?: string; 18 | } 19 | 20 | export default function TextAreaWithLabel ({ className, isError, isFocused, isReadOnly, label, onChange, rowsCount, value }: Props): React.ReactElement { 21 | const _onChange = useCallback( 22 | ({ target: { value } }: React.ChangeEvent): void => { 23 | onChange && onChange(value); 24 | }, 25 | [onChange] 26 | ); 27 | 28 | return ( 29 |