Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
5e939b9
style: add blurred overlay for recovery phrase reveal
Nick-1979 Sep 24, 2025
46c2811
fix: make the overlay keyboard-accessible and hide unrevealed words f…
Nick-1979 Sep 24, 2025
c656d6f
refactor: minor changes plus using useFormatted inreceive
Nick-1979 Sep 25, 2025
9423181
chore: edit constants
Nick-1979 Sep 25, 2025
5854ba4
chore: remove unused
Nick-1979 Sep 25, 2025
6ea28ac
chore: use demo account for account icons in settings
Nick-1979 Sep 25, 2025
5f7b2a5
refactor: simplify history item destructuring
Nick-1979 Sep 27, 2025
66aadb5
refactor: avoid unnecessary potential decimal overwrite
Nick-1979 Sep 27, 2025
da58429
refactor: simplify response check with optional chaining
Nick-1979 Sep 27, 2025
e17516e
chore: remove duplicate amount utils
Nick-1979 Sep 27, 2025
9afa86d
chore: restore decimal fallback when history item lacks its own decimal
Nick-1979 Sep 27, 2025
40bef4b
chore: avoid possible duplicate keys
Nick-1979 Sep 27, 2025
8effa68
refactor: remove duplicate component
Nick-1979 Sep 27, 2025
142f8f4
refactor: avoid unnecessary API usage
Nick-1979 Sep 27, 2025
94030f3
Merge branch 'main' into useFormattedInReceive
Nick-1979 Sep 27, 2025
7638171
chore: handle boolean condition
Nick-1979 Sep 27, 2025
ab92e11
chore: resolve build issue
Nick-1979 Sep 27, 2025
fc26470
feat: add eth support
Nick-1979 Sep 29, 2025
0700802
Merge branch 'main' into ethSupport00
Nick-1979 Nov 2, 2025
6e3c940
Merge branch 'main' into ethSupport00
Nick-1979 Nov 22, 2025
1af3054
chore: update branch
Nick-1979 Nov 23, 2025
a3d6120
Merge branch 'main' into ethSupport00
Nick-1979 Dec 24, 2025
7a1ae9e
chore: resolve conflicts
Nick-1979 Dec 24, 2025
8b4a355
Merge branch 'main' into ethSupport00
Nick-1979 Jan 2, 2026
a0bf3e9
chore: merge main +
Nick-1979 Jan 6, 2026
3caa583
chore: update package info
Nick-1979 Jan 6, 2026
9d8194c
fix: handle evm address
Nick-1979 Jan 6, 2026
6069ef7
Merge branch 'main' into ethSupport00
Nick-1979 Jan 6, 2026
a8d9e58
chore: resolve conflicts
Nick-1979 Jan 6, 2026
ab4180f
fix: remove extra characters
Nick-1979 Jan 6, 2026
5674527
chore: refactor code
Nick-1979 Jan 7, 2026
73f5c19
Merge branch 'main' into ethSupport00
Nick-1979 Jan 26, 2026
1245143
fix: handle moonbeam transfer as an evm case
Nick-1979 Jan 26, 2026
286fc55
chore: delete unused import
Nick-1979 Jan 26, 2026
b490955
Merge branch 'main' into ethSupport00
Nick-1979 Feb 3, 2026
ba9797c
chore: remove unused
Nick-1979 Feb 3, 2026
d8e8af8
Merge branch 'main' into evmSupport
Nick-1979 Feb 6, 2026
07b6687
Merge branch 'main' into evmSupport
Nick-1979 Feb 6, 2026
f08b668
Merge branch 'main' into evmSupport
Nick-1979 Feb 7, 2026
dde2339
Merge branch 'main' into evmSupport
Nick-1979 Feb 10, 2026
f8597a8
chore: temp merge
Nick-1979 Feb 10, 2026
b321f76
Merge branch 'main' into evmSupport
Nick-1979 Feb 17, 2026
623022a
chore: merge main
Nick-1979 Feb 18, 2026
be5fb01
chore: refactor and use ahAddress
Nick-1979 Feb 18, 2026
6ba2c7a
chore: update apps config
Nick-1979 Feb 18, 2026
5b925a8
Merge branch 'main' into evmSupport
Nick-1979 Feb 25, 2026
18e8a82
Merge branch 'main' into evmSupport
Nick-1979 Mar 1, 2026
1e1dcfa
Merge branch 'main' into evmSupport
Nick-1979 Mar 6, 2026
973f19b
style: set default cursor
Nick-1979 Mar 8, 2026
90467b4
chore: use isEthereum to filter chains
Nick-1979 Mar 8, 2026
602892c
chore: show all accounts in first modal of receive general
Nick-1979 Mar 8, 2026
e7c32e4
chore: get isEvmCompatible on-chain
Nick-1979 Mar 8, 2026
c9e011a
docs: remove logs
Nick-1979 Mar 8, 2026
090965d
fix: use all chains hook
Nick-1979 Mar 8, 2026
d937b6a
refactor: remove useless variable
Nick-1979 Mar 8, 2026
7c4e4f6
fix: use chain tokensymbol
Nick-1979 Mar 8, 2026
6054fe1
fix: apply nft const
Nick-1979 Mar 8, 2026
2e201a0
fix: handle type issue
Nick-1979 Mar 8, 2026
acdf136
chore: update to do
Nick-1979 Mar 10, 2026
94e43c8
chore: update jsdoc
Nick-1979 Mar 10, 2026
003dbdd
feat: add get erc20 balances
Nick-1979 Mar 10, 2026
0edb71d
fix: handle output type
Nick-1979 Mar 10, 2026
8213be5
Merge branch 'main' into evmSupport
Nick-1979 Mar 15, 2026
a24a222
feat: add erc20 tokens support
Nick-1979 Mar 18, 2026
8ea6a4e
refactor: merge rewards tables and rename identity
Nick-1979 Mar 18, 2026
a6ee473
chore: refactor
Nick-1979 Mar 18, 2026
81eb29b
chore: increase sentry sample rate
Nick-1979 Mar 18, 2026
a9dd6ef
chore: handle long token names
Nick-1979 Mar 19, 2026
502ed5b
style: align chain name to left
Nick-1979 Mar 19, 2026
2e319e5
chore: remove default genesis
Nick-1979 Mar 19, 2026
df6f040
chore: use isContract to mitigate console error messages
Nick-1979 Mar 19, 2026
3e906d8
chore: add possible json object pre check
Nick-1979 Mar 19, 2026
ea26f0f
chore: use api to check if proxy is supported
Nick-1979 Mar 19, 2026
b05bc42
feat: get proxy types using api
Nick-1979 Mar 19, 2026
e7390ea
fix: make proxy and chain modals adaptive to EVM addresses
Nick-1979 Mar 20, 2026
694bc4e
chore: remove unused
Nick-1979 Mar 20, 2026
0f19fa0
chore: remove unnecessary type casting
Nick-1979 Mar 20, 2026
2cae291
fix: update goerli genesis hash
Nick-1979 Mar 20, 2026
f6afad9
chore: update goerli genesis
Nick-1979 Mar 20, 2026
781ef60
fix: correct typo
Nick-1979 Mar 20, 2026
58302b4
fix: show evm addresses in address book
Nick-1979 Mar 20, 2026
31a76bc
fix: clear stale setType when input resets or switches away from EVM
Nick-1979 Mar 20, 2026
4a1d61a
fix: add evm support to QR account
Nick-1979 Mar 20, 2026
426736f
chore: update scripts
Nick-1979 Mar 21, 2026
a68edf4
chore: add coin link to the chart
Nick-1979 Mar 21, 2026
b2fa667
fix: show transfer participant name if it is a local account
Nick-1979 Mar 21, 2026
ae49f9a
fix: use storage data while loading new stories
Nick-1979 Mar 22, 2026
33611e9
chore: parse address in getName safely
Nick-1979 Mar 22, 2026
eb0c963
chore: remove unnecessary useMemo
Nick-1979 Mar 22, 2026
d6d48ba
chore: clean logs
Nick-1979 Mar 22, 2026
d51518d
docs: update reviewers count
Nick-1979 Mar 22, 2026
561fd92
chore: update translations
Nick-1979 Mar 22, 2026
ef26c6f
style: adjust switch width
Nick-1979 Mar 22, 2026
28b6afd
fix: update genesis to support evm addresses
Nick-1979 Mar 22, 2026
c2382e0
fix: filter ethereum addresses as reward destination
Nick-1979 Mar 22, 2026
3287eed
fix: adjust display balance width
Nick-1979 Mar 22, 2026
7f04077
style: apply isBlueish to notification icon
Nick-1979 Mar 22, 2026
b14bfe4
chore: remove unused
Nick-1979 Mar 23, 2026
cc4d538
chore: remove unused keys
Nick-1979 Mar 23, 2026
f954f28
chore: hide the derive button if the selected address is ethereum
Nick-1979 Mar 23, 2026
9816fe4
chore: hide derive account for external and 0x accounts
Nick-1979 Mar 23, 2026
6308400
docs: update translations
Nick-1979 Mar 23, 2026
2417423
chore: update todo
Nick-1979 Mar 24, 2026
066ef81
fix: handle fee overwritten issue
Nick-1979 Mar 24, 2026
20a3529
chore: upgrade apps config package
Nick-1979 Mar 24, 2026
139c60c
refactor: utilize new hooks
Nick-1979 Mar 24, 2026
7e60b11
chore: remove unused
Nick-1979 Mar 24, 2026
492eb74
chore: rearrange files
Nick-1979 Mar 24, 2026
49a013e
chore: refactor origin fee
Nick-1979 Mar 24, 2026
613f4bc
chore: add moonbase as test net
Nick-1979 Mar 24, 2026
5a52948
chore: remove unused
Nick-1979 Mar 24, 2026
64f0a92
refactor: handle early return
Nick-1979 Mar 24, 2026
8feacea
fix: navigate to home on import and export completion
Nick-1979 Mar 24, 2026
70fe79a
chore: show 0x address while click on identicon
Nick-1979 Mar 24, 2026
7726ef2
chore: fetch evm address history
Nick-1979 Mar 25, 2026
bb29154
chore: apply build production
Nick-1979 Mar 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
EXTENSION_PREFIX = POLKAGATE
BG_THEME = christmas
EXTENSION_PREFIX = MY_EXTENSION
SUBSCAN_DEFAULT_KEY=''
ALCHEMY_API_KEY= ''
ETHERSCAN_API_KEY= ''
INFURA_PROJECT_ID=''
SENTRY_DSN=''
SENTRY_AUTH_TOKEN=''
SENTRY_ORG=''
SENTRY_PROJECT=''
17 changes: 11 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@
],
"scripts": {
"apply-version": "node -e \"const { execSync } = require('child_process'); const fs = require('fs'); try { const version = execSync('git describe --tags --abbrev=0').toString().trim().replace(/^v/, ''); console.log('Version fetched:', version); const packageJsonPath = './packages/extension/package.json'; const packageJson = JSON.parse(fs.readFileSync(packageJsonPath)); packageJson.version = version; fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); } catch (error) { console.log('No tags found, skipping package.json update'); }\"",
"build": "NODE_ENV=production yarn apply-version && polkadot-dev-build-ts && yarn build:zip && yarn build:rollup",
"build": "NODE_ENV=production yarn copy-prod-manifest && yarn apply-version && polkadot-dev-build-ts && yarn clean-map-build && yarn build:zip && yarn build:rollup",
"build:before": "yarn build:i18n",
"build:clean": "yarn build && find packages/extension/build -name '*.map' -type f -delete",
"build:dev": "NODE_ENV=development polkadot-dev-build-ts",
"build:dev": "NODE_ENV=development yarn copy-dev-manifest && polkadot-dev-build-ts",
"build:i18n": "i18next-scanner --config i18next-scanner.config.cjs",
"build:release": "polkadot-ci-ghact-build",
"build:rollup": "polkadot-exec-rollup --config",
Expand All @@ -36,7 +35,10 @@
"build:zip:dst": "rm -rf ./master-build.zip && cd packages/extension/build && zip -r -FS ../../../master-build.zip .",
"build:zip:src": "rm -rf ./master-src.zip && zip -r -x '*build/*' -x '*node_modules*' -FS ./master-src.zip packages .editorconfig .eslintignore .eslintrc.js babel.config.cjs CHANGELOG.md CONTRIBUTING.md i18next-scanner.config.js jest.config.cjs LICENSE package.json README.md tsconfig.json yarn.lock",
"clean": "polkadot-dev-clean-build",
"clean-map-build": "find packages/extension/build -name '*.map' -type f -delete",
"clean-translations": "node cleanTranslations.cjs",
"copy-dev-manifest": "cp packages/extension/manifest.dev.json packages/extension/manifest.json",
"copy-prod-manifest": "cp packages/extension/manifest.prod.json packages/extension/manifest.json",
"docs": "npx typedoc && (start ./docs/index.html || open ./docs/index.html || xdg-open ./docs/index.html)",
"lint": "polkadot-dev-run-lint",
"postinstall": "polkadot-dev-yarn-only",
Expand All @@ -45,7 +47,7 @@
"start": "NODE_ENV=development yarn watch",
"test": "polkadot-dev-run-test --silent --detectOpenHandles --testPathPattern=packages/extension-polkagate/src --maxWorkers=1",
"test:one": "polkadot-dev-run-test --detectOpenHandles",
"watch": "cd packages/extension && yarn polkadot-exec-webpack --config webpack.watch.cjs --mode development --watch"
"watch": "yarn copy-dev-manifest && cd packages/extension && yarn polkadot-exec-webpack --config webpack.watch.cjs --mode development --watch"
},
"dependencies": {
"@acala-network/api": "^6.2.0",
Expand All @@ -60,7 +62,7 @@
"@mui/icons-material": "^5.15.18",
"@mui/lab": "^5.0.0-alpha.85",
"@mui/material": "^5.8.3",
"@paraspell/sdk-pjs": "^12.6.0",
"@paraspell/sdk-pjs": "12.7.0",
"@polkadot/api": "^16.5.4",
"@polkadot/api-augment": "^16.5.4",
"@polkadot/api-base": "^16.5.4",
Expand All @@ -75,10 +77,11 @@
"@polkadot/types-support": "^16.5.4",
"@polkadot/util": "^13.5.3",
"@polkadot/util-crypto": "^13.5.3",
"@polkagate/apps-config": "^1.3.0",
"@polkagate/apps-config": "2.1.1",
"@sentry/react": "^9.40.0",
"@sentry/webpack-plugin": "^4.0.0",
"@substrate/connect": "^0.7.32",
"@web3icons/react": "^4.0.25",
"babel-plugin-transform-import-meta": "^2.1.1",
"better-react-spinkit": "^2.0.4",
"chance": "^1.1.11",
Expand All @@ -87,6 +90,7 @@
"country-flag-icons": "^1.5.9",
"css-loader": "^6.7.3",
"date-fns": "^4.1.0",
"ethers": "^6.15.0",
"framer-motion": "^11.11.13",
"memoize-one": "^6.0.0",
"polkadot-api": "^1.13.0",
Expand Down Expand Up @@ -128,6 +132,7 @@
"jsdom-worker-fix": "^0.1.8",
"openai": "^4.0.0",
"pinst": "^3.0.0",
"react-devtools-core": "^7.0.1",
"semantic-release": "^24.1.0",
"sinon-chrome": "^3.0.1",
"typedoc": "^0.27.9",
Expand Down
37 changes: 30 additions & 7 deletions packages/extension-base/src/background/handlers/Extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import type { KeyringAddress } from '@polkadot/ui-keyring/types';
import type { HexString } from '@polkadot/util/types';
import type { KeypairType } from '@polkadot/util-crypto/types';
// added for plus to import RequestUpdateMeta
import type { AccountJson, AllowedPath, ApplyAddedTime, AuthorizeRequest, AuthUrls, MessageTypes, MetadataRequest, RequestAccountBatchExport, RequestAccountChangePassword, RequestAccountChangePasswordAll, RequestAccountCreateExternal, RequestAccountCreateHardware, RequestAccountCreateSuri, RequestAccountEdit, RequestAccountExport, RequestAccountForget, RequestAccountShow, RequestAccountsSetUnlockExpiry, RequestAccountTie, RequestAccountValidate, RequestAuthorizeApprove, RequestBatchRestore, RequestCreateAgent, RequestDeriveCreate, RequestDeriveValidate, RequestExplainTx, RequestJsonRestore, RequestMetadataApprove, RequestMetadataReject, RequestSeedCreate, RequestSeedValidate, RequestSigningApprovePassword, RequestSigningApproveSignature, RequestSigningCancel, RequestSigningIsLocked, RequestSigningSignature, RequestTypes, RequestUnlockAllAccounts, RequestUpdateAuthorizedAccounts, RequestUpdateMeta, ResponseAccountExport, ResponseAccountsExport, ResponseAuthorizeList, ResponseDeriveValidate, ResponseJsonGetAccountInfo, ResponseSeedCreate, ResponseSeedValidate, ResponseSigningIsLocked, ResponseType, SigningRequest } from '../types';
import type { AccountJson, AllowedPath, ApplyAddedTime, AuthorizeRequest, AuthUrls, MessageTypes, MetadataRequest, RequestAccountBatchExport, RequestAccountChangePassword, RequestAccountChangePasswordAll, RequestAccountCreateExternal, RequestAccountCreateHardware, RequestAccountCreateSuri, RequestAccountEdit, RequestAccountExport, RequestAccountForget, RequestAccountShow, RequestAccountsSetUnlockExpiry, RequestAccountTie, RequestAccountValidate, RequestAuthorizeApprove, RequestBatchRestore, RequestCreateAgent, RequestDeriveCreate, RequestDeriveValidate, RequestExplainTx, RequestJsonRestore, RequestMetadataApprove, RequestMetadataReject, RequestSeedCreate, RequestSeedValidate, RequestSigningApprovePassword, RequestSigningApproveSignature, RequestSigningCancel, RequestSigningEthereumRawSignature, RequestSigningIsLocked, RequestSigningSignature, RequestTypes, RequestUnlockAllAccounts, RequestUpdateAuthorizedAccounts, RequestUpdateMeta, ResponseAccountExport, ResponseAccountsExport, ResponseAuthorizeList, ResponseDeriveValidate, ResponseJsonGetAccountInfo, ResponseSeedCreate, ResponseSeedValidate, ResponseSigningIsLocked, ResponseType, SigningRequest } from '../types';
import type State from './State';

import { ALLOWED_PATH, START_WITH_PATH } from '@polkadot/extension-base/defaults';
import { metadataExpand } from '@polkadot/extension-chains';
import { TypeRegistry } from '@polkadot/types';
import keyring from '@polkadot/ui-keyring';
import { accounts as accountsObservable } from '@polkadot/ui-keyring/observable/accounts';
import { assert, isHex } from '@polkadot/util';
import { assert, hexToU8a,isHex, u8aToHex } from '@polkadot/util';
import { keyExtractSuri, mnemonicGenerate, mnemonicValidate } from '@polkadot/util-crypto';

import { withErrorLog } from './helpers';
Expand Down Expand Up @@ -110,8 +110,8 @@ export default class Extension {
keyring.saveAccountMeta(pair, { ...pair.meta, addedTime: Date.now() });
}

private accountsCreateExternal({ address, genesisHash, name }: RequestAccountCreateExternal): boolean {
const { pair } = keyring.addExternal(address, { genesisHash, name });
private accountsCreateExternal({ address, genesisHash, name, type }: RequestAccountCreateExternal): boolean {
const { pair } = keyring.addExternal(address, { genesisHash, name, type });
Comment thread
Nick-1979 marked this conversation as resolved.

this.applyAddedTime({ pair });

Expand Down Expand Up @@ -630,9 +630,7 @@ export default class Extension {
throw new Error('Invalid payload: missing required fields.');
}

const { address } = payload;

const pair = keyring.getPair(address);
const pair = keyring.getPair(payload.address);

this.refreshAccountPasswordCache(pair); // check if auto lock duration is expired

Expand All @@ -647,6 +645,28 @@ export default class Extension {
return signature;
}

private signEthereumRaw({ address, data }: RequestSigningEthereumRawSignature): HexString | null {
const pair = keyring.getPair(address);

this.refreshAccountPasswordCache(pair);

if (pair.isLocked) {
return null;
}

const bytes = hexToU8a(data);
const sigBytes = pair.sign(bytes);

const v = (sigBytes[64] & 1) + 27;
const serialized = new Uint8Array(65);

serialized.set(sigBytes.slice(0, 32), 0);
serialized.set(sigBytes.slice(32, 64), 32);
serialized[64] = v;

return u8aToHex(serialized);
}

private signingApproveSignature({ id, signature, signedTransaction }: RequestSigningApproveSignature): boolean {
const queued = this.#state.getSignRequest(id);

Expand Down Expand Up @@ -811,6 +831,9 @@ export default class Extension {
case 'pri(signing.getSignature)':
return this.getSignature(request as RequestSigningSignature);

case 'pri(signing.signEthereumRaw)':
return this.signEthereumRaw(request as RequestSigningEthereumRawSignature);

case 'pri(accounts.unlockAll)':
return this.accountsUnlockAll(request as RequestUnlockAllAccounts);

Expand Down
6 changes: 6 additions & 0 deletions packages/extension-base/src/background/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ export interface RequestSignatures {
'pri(accounts.changePassword)': [RequestAccountChangePassword, boolean];
'pri(accounts.changePasswordAll)': [RequestAccountChangePasswordAll, boolean];
'pri(signing.getSignature)': [RequestSigningSignature, HexString | null];
'pri(signing.signEthereumRaw)': [RequestSigningEthereumRawSignature, HexString | null];
'pri(authorize.approve)': [RequestAuthorizeApprove, boolean];
'pri(authorize.update)': [RequestUpdateAuthorizedAccounts, void];
'pri(authorize.list)': [null, ResponseAuthorizeList];
Expand Down Expand Up @@ -213,6 +214,7 @@ export interface RequestAccountCreateExternal {
address: string;
genesisHash?: HexString | null;
name: string;
type?: KeypairType;
}

export interface RequestAccountCreateSuri {
Expand Down Expand Up @@ -337,6 +339,10 @@ export interface RequestSigningApprovePassword {
export interface RequestSigningSignature {
payload: SignerPayloadJSON;
}
export interface RequestSigningEthereumRawSignature {
address: string;
data: string;
}

export interface RequestSigningApproveSignature {
id: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
// Copyright 2019-2026 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0

import React, { useCallback, useContext, useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';

import { useSelectedAccount } from '../hooks';
import { useAccounts, useSelectedAccount } from '../hooks';
import { setStorage } from '../util';
import { STORAGE_KEY } from '../util/constants';
import { AccountContext, DropSelect } from '.';
import { DropSelect } from '.';

interface Props {
style?: React.CSSProperties;
}

function AccountSelectionDropDown({ style }: Props) {
const selectedAccount = useSelectedAccount();
const { accounts } = useContext(AccountContext);
const accounts = useAccounts();

const onClick = useCallback((address: string | number) => {
setStorage(STORAGE_KEY.SELECTED_ACCOUNT, address).catch(console.error);
Expand Down
6 changes: 3 additions & 3 deletions packages/extension-polkagate/src/components/Address.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import CopyToClipboard from 'react-copy-to-clipboard';
import { noop } from '@polkadot/util';
import { decodeAddress, encodeAddress } from '@polkadot/util-crypto';

import { useAccountName, useIsDark, useTranslation } from '../hooks';
import { useAccountName, useAccounts, useIsDark, useTranslation } from '../hooks';
import useMetadata from '../hooks/useMetadata';
import PolkaGateIdenticon from '../style/PolkaGateIdenticon';
import { DEFAULT_TYPE } from '../util/defaultType';
import { AccountContext, ActionButton, GlowCheckbox, SettingsContext, ShortAddress } from './';
import { ActionButton, GlowCheckbox, SettingsContext, ShortAddress } from './';

export interface Props {
actions?: React.ReactNode;
Expand Down Expand Up @@ -93,7 +93,7 @@ function Address({ address, backgroundColor, check, genesisHash, handleCheck, ma
const { t } = useTranslation();
const isDark = useIsDark();

const { accounts } = useContext(AccountContext);
const accounts = useAccounts();
const accountName = useAccountName(address || '');
const settings = useContext(SettingsContext);
const [{ formatted, genesisHash: recodedGenesis }, setRecoded] = useState<Recoded>(defaultRecoded);
Expand Down
66 changes: 41 additions & 25 deletions packages/extension-polkagate/src/components/AddressInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
// SPDX-License-Identifier: Apache-2.0

import type { Chain } from '@polkadot/extension-chains/types';
import type { KeypairType } from '@polkadot/util-crypto/types';

import { Divider, InputAdornment, Stack, type SxProps, TextField, type Theme, Typography, useTheme } from '@mui/material';
import { ArrowCircleDown, Document, Hashtag, ScanBarcode } from 'iconsax-react';
import React, { useCallback, useEffect, useRef, useState } from 'react';

import { isEthereumAddress } from '@polkadot/util-crypto';

import AccountListModal from '../fullscreen/components/AccountListModal';
import { useIsBlueish, useTranslation } from '../hooks';
import QrScanner from '../popup/import/addWatchOnlyFullScreen/QrScanner';
Expand All @@ -25,10 +28,11 @@ interface Props {
style?: SxProps<Theme>;
withSelect?: boolean;
setIsError?: React.Dispatch<React.SetStateAction<boolean | undefined>>;
setType?: React.Dispatch<React.SetStateAction<KeypairType | undefined>>;
showAddressBook?: boolean;
}

export default function AddressInput({ addWithQr = false, address, chain, disabled = false, label, placeHolder, setAddress, setIsError, showAddressBook, style, withSelect }: Props): React.ReactElement<Props> {
export default function AddressInput({ addWithQr = false, address, chain, disabled = false, label, placeHolder, setAddress, setIsError, setType, showAddressBook, style, withSelect }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const containerRef = useRef<HTMLDivElement>(null);
const isBlueish = useIsBlueish();
Expand All @@ -38,10 +42,10 @@ export default function AddressInput({ addWithQr = false, address, chain, disabl
const [openCamera, setOpenCamera] = useState<boolean>(false);
const [openAccountList, setOpenAccountList] = useState<boolean>(false);
const [invalidAddress, setInvalidAddress] = useState<boolean>(false);
const [enteredAddress, setEnteredAddress] = useState<string | undefined>();
const [enteredAddress, setEnteredAddress] = useState<string | undefined | null>();

useEffect(() => {
if (address) {
if (address || address === null) {
setEnteredAddress(address);
setInvalidAddress(false);
}
Expand All @@ -51,45 +55,57 @@ export default function AddressInput({ addWithQr = false, address, chain, disabl
setIsError && setIsError(invalidAddress);
}, [address, invalidAddress, setIsError]);

const onReset = useCallback((): void => {
setAddress?.(null);
setEnteredAddress(undefined);
setInvalidAddress(false);
setType?.((prev) => (prev === 'ethereum' ? undefined : prev));
}, [setAddress, setType]);

const onSet = useCallback((value: string): void => {
const isEvm = isEthereumAddress(value);

isEvm && setType?.('ethereum');
const isValid = isValidAddress(value);

isValid
? setAddress?.(value)
: setAddress?.(undefined);

setEnteredAddress(value);
setInvalidAddress(!isValid);
}, [setAddress, setType]);
Comment thread
Nick-1979 marked this conversation as resolved.

const handleAddress = useCallback(({ target: { value } }: React.ChangeEvent<HTMLInputElement>): void => {
if (!value) {
setAddress && setAddress(null);
setEnteredAddress(undefined);
setInvalidAddress(false);
onReset();

return;
}

setInvalidAddress(!(isValidAddress(value)));
setEnteredAddress(value);
isValidAddress(value) ? setAddress && setAddress(value) : setAddress && setAddress(undefined);
}, [setAddress]);
onSet(value);
}, [onReset, onSet]);

// @ts-ignore
const _selectAddress = useCallback((newAddr?: string) => handleAddress({ target: { value: newAddr } }), [handleAddress]);

const openQrScanner = useCallback(() => setOpenCamera(true), []);
const onOpenAccountList = useCallback(() => setOpenAccountList(true), []);

const handleInputAddress = useCallback((value: React.ChangeEvent<HTMLInputElement>) => {
handleAddress(value);
}, [handleAddress]);

const pasteAddress = useCallback(() => {
if (enteredAddress || address) {
setAddress && setAddress(null);
setEnteredAddress(undefined);
setInvalidAddress(false);
} else {
navigator.clipboard.readText().then((clipText) => {
const isValid = isValidAddress(clipText);
onReset();

isValid ? setAddress?.(clipText) : setAddress?.(undefined);
setEnteredAddress(clipText);
setInvalidAddress(!isValid);
}).catch(console.error);
return;
}
}, [address, enteredAddress, setAddress]);

navigator.clipboard.readText()
.then((clipText) => {
onSet(clipText);
}).catch(console.error);
}, [address, enteredAddress, onReset, onSet]);

return (
<>
Expand Down Expand Up @@ -134,7 +150,7 @@ export default function AddressInput({ addWithQr = false, address, chain, disabl
size='18'
style={{ cursor: 'pointer', margin: '0 2px 0' }}
variant='Bulk'
/>
/>
}
</InputAdornment>
),
Expand Down Expand Up @@ -205,4 +221,4 @@ export default function AddressInput({ addWithQr = false, address, chain, disabl
}
</>
);
}
}
Loading
Loading