diff --git a/package.json b/package.json index 764e3221b5..0483a843c3 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@polkadot/hw-ledger": "^5.3.2-5", "@polkadot/keyring": "^5.3.2-5", "@polkadot/networks": "^5.3.2-5", + "@polkadot/phishing": "^0.3.22", "@polkadot/types": "^3.5.2-5", "@polkadot/util": "^5.3.2-5", "@polkadot/util-crypto": "^5.3.2-5", diff --git a/packages/page-accounts/package.json b/packages/page-accounts/package.json index bbeac5e83d..7384f0713d 100644 --- a/packages/page-accounts/package.json +++ b/packages/page-accounts/package.json @@ -10,6 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.12.5", + "@polkadot/phishing": "^0.3.22", "@polkadot/react-components": "^0.76.2-17", "@polkadot/vanitygen": "^0.25.2-2", "detect-browser": "^5.2.0", diff --git a/packages/page-accounts/src/modals/Transfer.tsx b/packages/page-accounts/src/modals/Transfer.tsx index 03c3bff3ca..4184bc7107 100644 --- a/packages/page-accounts/src/modals/Transfer.tsx +++ b/packages/page-accounts/src/modals/Transfer.tsx @@ -8,7 +8,8 @@ import BN from 'bn.js'; import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; -import { InputAddress, InputBalance, MarkWarning, Modal, Toggle, TxButton } from '@polkadot/react-components'; +import { checkAddress } from '@polkadot/phishing'; +import { InputAddress, InputBalance, MarkError, MarkWarning, Modal, Toggle, TxButton } from '@polkadot/react-components'; import { useApi, useCall } from '@polkadot/react-hooks'; import { Available } from '@polkadot/react-query'; import { BN_ZERO, isFunction } from '@polkadot/util'; @@ -26,6 +27,17 @@ function isRefcount (accountInfo: AccountInfoWithProviders | AccountInfoWithRefC return !!(accountInfo as AccountInfoWithRefCount).refcount; } +async function checkPhishing (senderId: string | null, recipientId: string | null): Promise<[string | null, string | null]> { + return [ + senderId + ? await checkAddress(senderId) + : null, + recipientId + ? await checkAddress(recipientId) + : null + ]; +} + function Transfer ({ className = '', onClose, recipientId: propRecipientId, senderId: propSenderId }: Props): React.ReactElement { const { t } = useTranslation(); const { api } = useApi(); @@ -36,6 +48,7 @@ function Transfer ({ className = '', onClose, recipientId: propRecipientId, send const [[maxTransfer, noFees], setMaxTransfer] = useState<[BN | null, boolean]>([null, false]); const [recipientId, setRecipientId] = useState(propRecipientId || null); const [senderId, setSenderId] = useState(propSenderId || null); + const [[senderPhish, recipientPhish], setPhishing] = useState<[string | null, string | null]>([null, null]); const balances = useCall(api.derive.balances.all, [senderId]); const accountInfo = useCall(api.query.system.account, [senderId]); @@ -65,6 +78,12 @@ function Transfer ({ className = '', onClose, recipientId: propRecipientId, send } }, [api, balances, recipientId, senderId]); + useEffect((): void => { + checkPhishing(senderId, recipientId) + .then(setPhishing) + .catch(console.error); + }, [recipientId, senderId]); + const noReference = accountInfo ? isRefcount(accountInfo) ? accountInfo.refcount.isZero() @@ -96,6 +115,9 @@ function Transfer ({ className = '', onClose, recipientId: propRecipientId, send onChange={setSenderId} type='account' /> + {senderPhish && ( + ('The sender is associated with a known phishing site, {{url}}', { replace: { url: senderPhish } })} /> + )}

{t('The transferred balance will be subtracted (along with fees) from the sender account.')}

@@ -117,6 +139,9 @@ function Transfer ({ className = '', onClose, recipientId: propRecipientId, send onChange={setRecipientId} type='allPlus' /> + {recipientPhish && ( + ('The recipient is associated with a known phishing site, {{url}}', { replace: { url: recipientPhish } })} /> + )}

{t('The beneficiary will have access to the transferred fees when the transaction is included in a block.')}

@@ -192,7 +217,7 @@ function Transfer ({ className = '', onClose, recipientId: propRecipientId, send ('Make Transfer')} onStart={onClose} params={ diff --git a/yarn.lock b/yarn.lock index ed4b124cfd..f3a3d0d352 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1965,6 +1965,7 @@ __metadata: resolution: "@polkadot/app-accounts@workspace:packages/page-accounts" dependencies: "@babel/runtime": ^7.12.5 + "@polkadot/phishing": ^0.3.22 "@polkadot/react-components": ^0.76.2-17 "@polkadot/test-support": 0.76.2-17 "@polkadot/vanitygen": ^0.25.2-2 @@ -2449,6 +2450,18 @@ __metadata: languageName: node linkType: hard +"@polkadot/phishing@npm:^0.3.22": + version: 0.3.22 + resolution: "@polkadot/phishing@npm:0.3.22" + dependencies: + "@babel/runtime": ^7.12.5 + "@polkadot/util": ^5.3.2-6 + "@polkadot/util-crypto": ^5.3.2-6 + "@polkadot/x-fetch": ^5.3.2-6 + checksum: c5e77c345d9c4b5f3d3cd77f9268f014af3c6ae58549d21eb79594111f1a528f23c0a9e2da991a2f41ace55a1e5ea7931577e8e5410e76b3e5dee0fe990ff8f6 + languageName: node + linkType: hard + "@polkadot/react-api@^0.76.2-17, @polkadot/react-api@workspace:packages/react-api": version: 0.0.0-use.local resolution: "@polkadot/react-api@workspace:packages/react-api" @@ -2811,6 +2824,17 @@ __metadata: languageName: node linkType: hard +"@polkadot/x-fetch@npm:^5.3.2-6": + version: 5.3.2-7 + resolution: "@polkadot/x-fetch@npm:5.3.2-7" + dependencies: + "@babel/runtime": ^7.12.5 + "@types/node-fetch": ^2.5.8 + node-fetch: ^2.6.1 + checksum: 1706b2c7d5c6735c388784774e7194438a37d9e7d0c46bee372e9e90dac7aacebe7b655cf7b061919df27bf01f46e71bdd00aae3dd70e04fc4e89c8f45992f33 + languageName: node + linkType: hard + "@polkadot/x-randomvalues@npm:5.3.2-5": version: 5.3.2-5 resolution: "@polkadot/x-randomvalues@npm:5.3.2-5"