diff --git a/app/soapbox/features/crypto_donate/components/detailed_crypto_address.js b/app/soapbox/features/crypto_donate/components/detailed_crypto_address.js
deleted file mode 100644
index 40df4909d..000000000
--- a/app/soapbox/features/crypto_donate/components/detailed_crypto_address.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import PropTypes from 'prop-types';
-import QRCode from 'qrcode.react';
-import React from 'react';
-import ImmutablePureComponent from 'react-immutable-pure-component';
-
-import Icon from 'soapbox/components/icon';
-import { CopyableInput } from 'soapbox/features/forms';
-
-import { getExplorerUrl } from '../utils/block_explorer';
-import CoinDB from '../utils/coin_db';
-
-import CryptoIcon from './crypto_icon';
-
-export default class DetailedCryptoAddress extends ImmutablePureComponent {
-
- static propTypes = {
- address: PropTypes.string.isRequired,
- ticker: PropTypes.string.isRequired,
- note: PropTypes.string,
- }
-
- render() {
- const { address, ticker, note } = this.props;
- const title = CoinDB.getIn([ticker, 'name']);
- const explorerUrl = getExplorerUrl(ticker, address);
-
- return (
-
-
-
-
{title || ticker.toUpperCase()}
-
- {explorerUrl &&
-
- }
-
-
- {note &&
{note}
}
-
-
-
-
-
-
-
- );
- }
-
-}
diff --git a/app/soapbox/features/crypto_donate/components/detailed_crypto_address.tsx b/app/soapbox/features/crypto_donate/components/detailed_crypto_address.tsx
new file mode 100644
index 000000000..7d58d4e33
--- /dev/null
+++ b/app/soapbox/features/crypto_donate/components/detailed_crypto_address.tsx
@@ -0,0 +1,53 @@
+import QRCode from 'qrcode.react';
+import React from 'react';
+
+import Icon from 'soapbox/components/icon';
+import { CopyableInput } from 'soapbox/features/forms';
+
+import { getExplorerUrl } from '../utils/block_explorer';
+import CoinDB from '../utils/coin_db';
+
+import CryptoIcon from './crypto_icon';
+
+interface IDetailedCryptoAddress {
+ address: string,
+ ticker: string,
+ note?: string,
+}
+
+const getTitle = (ticker: string): string => {
+ const title = CoinDB.getIn([ticker, 'name']);
+ return typeof title === 'string' ? title : '';
+};
+
+const DetailedCryptoAddress: React.FC = ({ address, ticker, note }): JSX.Element => {
+ const title = getTitle(ticker);
+ const explorerUrl = getExplorerUrl(ticker, address);
+
+ return (
+
+
+
+
{title || ticker.toUpperCase()}
+
+ {explorerUrl &&
+
+ }
+
+
+ {note &&
{note}
}
+
+
+
+
+
+
+
+ );
+};
+
+export default DetailedCryptoAddress;
diff --git a/package.json b/package.json
index 42bc83259..ff9568cd7 100644
--- a/package.json
+++ b/package.json
@@ -70,6 +70,7 @@
"@types/escape-html": "^1.0.1",
"@types/http-link-header": "^1.0.3",
"@types/lodash": "^4.14.180",
+ "@types/qrcode.react": "^1.0.2",
"@types/react-helmet": "^6.1.5",
"@types/react-router-dom": "^5.3.3",
"@types/react-toggle": "^4.0.3",
diff --git a/yarn.lock b/yarn.lock
index 146c677b1..4c7708e0c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2095,6 +2095,13 @@
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.5.tgz#75a2a8e7d8ab4b230414505d92335d1dcb53a6df"
integrity sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==
+"@types/qrcode.react@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.2.tgz#f892432cc41b5dac52e3ca8873b717c8bfea6002"
+ integrity sha512-I9Oq5Cjlkgy3Tw7krCnCXLw2/zMhizkTere49OOcta23tkvH0xBTP0yInimTh0gstLRtb8Ki9NZVujE5UI6ffQ==
+ dependencies:
+ "@types/react" "*"
+
"@types/react-helmet@^6.1.5":
version "6.1.5"
resolved "https://registry.yarnpkg.com/@types/react-helmet/-/react-helmet-6.1.5.tgz#35f89a6b1646ee2bc342a33a9a6c8777933f9083"