diff --git a/.cert/cert.pem b/.cert/cert.pem new file mode 100644 index 00000000..c0c9d18f --- /dev/null +++ b/.cert/cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEozCCAwugAwIBAgIRALVgQ4iLzJxtipCRuRZ9FWMwDQYJKoZIhvcNAQELBQAw +gbkxHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTFHMEUGA1UECww+YmFy +dG9zei5saXBpbnNraUBCYXJ0b3N6cy1NYWNCb29rLVByby5sb2NhbCAoQmFydG9z +eiBMaXBpbnNraSkxTjBMBgNVBAMMRW1rY2VydCBiYXJ0b3N6LmxpcGluc2tpQEJh +cnRvc3pzLU1hY0Jvb2stUHJvLmxvY2FsIChCYXJ0b3N6IExpcGluc2tpKTAeFw0x +OTA2MDEwMDAwMDBaFw0zMDEwMTgwMjU2MzhaMHIxJzAlBgNVBAoTHm1rY2VydCBk +ZXZlbG9wbWVudCBjZXJ0aWZpY2F0ZTFHMEUGA1UECww+YmFydG9zei5saXBpbnNr +aUBCYXJ0b3N6cy1NYWNCb29rLVByby5sb2NhbCAoQmFydG9zeiBMaXBpbnNraSkw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDOwT5doIalTreoX71W6TLr +V2tijuSHLRmIDcDutPM/cPYNUHgkGthZveMdrcoaDqveHZdGjWY39U+8kzrdcbV2 +7oXNd4ivC5acS8DIJNCO3G1JcNSYnxmZXEaPAHXaVke+SMXVTWbUvA8Rkyor9hPe +KW8gtFqm2IT/klRBfWuYLO24dILrCfYkqJkZ6g++X7pBp1R/8h9SYdHWbHxIDk2d +CWaHNA7v8g1bMw2ZmxICwgbsARplLgIU/ZWRKQik2axOIeHDpoeV9/hj4SXvs1bA +yvO8oNMjYuekkAs117NAfJb9oR6p/iet39IfzY4zQmBqwFDuAu7+nZq1NfFLajor +AgMBAAGjbDBqMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAM +BgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFLRNFQImfwsJQApnvaPukIsWedjpMBQG +A1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAYEAgm1tjv0cRoBR +lBzIajECMHVK1dHYARaaFrG4ll1DpWS38Cyn2FN/YIIdTrzh8vFIkV/Leeozcjp8 +nE84zziw9nYvX86SfKtv8uVaVLPoNm2hl9JQS/19dMrB25vpeDGJqmnF3/n7oVEC +SY6fY2xLMx47tpnT5P9NuXgP6Zz6KVQp+CPEfoIkTo+dU0Kk67K5Q9OR42SyiRG2 +JxSBymbPV/mHwOxAS2M6QMODPt+FpVYeiz+iM6d1lL2NGs2CnyBFaFLNlmxij9yL +rZoU+Om5LrhgY5CL7/DVkU6xZC0VI9AZvV3eV5ouPv4ofH47BSOkxwLj5V4xFGTf ++1YRuvqE12EecBpz5g/33LzrkipA7G6P1Oca38g7Xkv6+XKALXIZ2dtcXUp7s7Ty +Cf6Nydlgeqe6Ik6+OKgWIwCahr2cWWVKC/JFMqOYugD4dYcyvbv+V06YEQvYJP5B +yhVdn4uVAfrGGFUCRm9ZM3EhSPZlNwVcG6l5jaV/48L+Uy32VGvJ +-----END CERTIFICATE----- diff --git a/.cert/key.pem b/.cert/key.pem new file mode 100644 index 00000000..2d61e87b --- /dev/null +++ b/.cert/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDOwT5doIalTreo +X71W6TLrV2tijuSHLRmIDcDutPM/cPYNUHgkGthZveMdrcoaDqveHZdGjWY39U+8 +kzrdcbV27oXNd4ivC5acS8DIJNCO3G1JcNSYnxmZXEaPAHXaVke+SMXVTWbUvA8R +kyor9hPeKW8gtFqm2IT/klRBfWuYLO24dILrCfYkqJkZ6g++X7pBp1R/8h9SYdHW +bHxIDk2dCWaHNA7v8g1bMw2ZmxICwgbsARplLgIU/ZWRKQik2axOIeHDpoeV9/hj +4SXvs1bAyvO8oNMjYuekkAs117NAfJb9oR6p/iet39IfzY4zQmBqwFDuAu7+nZq1 +NfFLajorAgMBAAECggEBAMuSWeW1+N0q9IpEOhko44n1OTaBm2G9djYP1Lc0U41T +m/DgGmryQ7OY09aVFzkw2OiKGjjNYKgYUbpK/Nqs6w9/Kx9zYpF3x4N80wQ9u1vu +jWySO8FKZdoqkQ6cVW31Jg6leKTc4TL1N6EGVa+TS1yjT1fUPK2q4skBOxSAeUAK +t5OvL5eeuumu+Ya3nrwQ1wp1ZBWhkeDIGjED8SDPfT0kU4v8dKTJcXk7ooF5s1OZ +H6HSzEej8eZSfBLDTwPsHylaGTcTi9Tgi8CnjAVdBLaFJlS+bkvv7m5/jnuEpofX +HkyAW5LDnIvHLycE3Ql9BQsR/DF9uzQvn9VRwPGQm4ECgYEA6/eyWhQfl4rDfjQi +fzQgjEYnTbE69R3LUUKulUQQeBYcZO2JAAGZ45G6lZ1zEWFmXuj0aQRYpj798cTg +0ZyH7Dllae8GPZlQ0u/Pxp03DzrvNGbHiTEBYqyVB+gJFn9Robm1eG+kP3QVgaIq +iOXwnUGL74MaJKdwi9ruhzLaQwUCgYEA4E6qJwkBRkGfpjSc0stwTEd+04nSPU1u +V3jFkxS/MNHCF/FUOGBKvrEbbedZ4DRiHjmQ6+zsvl+5jW75bw2rrxxxjkvpNjZe +BOKhac7c+jHXEAm4xuP6lUnPOenBhy/AvOJMm+6wzxdvTzp2gfnfIUOld24bdSXP +29yOzOpYb28CgYAlDn0f0FE1x0D0LNPODi2eWdYKSW7s14T6efJY1puPgEltQDBn +o9i6+EPJAzTy4czl0sevRlN1qCbRNQ3pXR+rZUgb3sGoIs+ikK6cjkv7RFIUdJ+Z +V+zTxi6RU0s6ETyMnVF2XHH61Qwbk5ACd7nVuFl1f603XGQ8UmFrMf080QKBgQDQ +a2eg87YScOGGDvb0ywFib0BCEJqgSXVQo7B5lNp94zmFA8EszRRGkcwZ19DkCeht +izHEdhYYYlvINihg7wPqpvRAsvpUXDoKMganiQY9F9hsV4wwih8JXlbFyhT/pvhg +yalDbostMepEZN8+sE2K3A9ApLewp1y3Pv4VG17m0wKBgB7GIrI2Jx5CG4yFoM8y +kB5rbvNlGAER58AMhzMebs7e2pQg0GxMpaNwqSZyVG0kLq7ayXn9ExA+uQpAG6cR +fnBWVflYf0hKIC1M6U9kOle6lZ/Nbdo80wGa5z3Ieup6w9WB0pbtifvbsnv6RLeA +S7MNQDcNXJxQulqppa+1BOTl +-----END PRIVATE KEY----- diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..f98abe2c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +insert_final_newline = true + +[*.{js}] +charset = utf-8 + +[src/**.js] +indent_style = space +indent_size = 2 + +[{package.json,.travis.yml}] +indent_style = space +indent_size = 2 \ No newline at end of file diff --git a/.env.development b/.env.development new file mode 100644 index 00000000..74cc4ab5 --- /dev/null +++ b/.env.development @@ -0,0 +1,2 @@ +HTTPS=true +SSL_CRT_FILE=./.cert/cert.pem SSL_KEY_FILE=./.cert/key.pem \ No newline at end of file diff --git a/package.json b/package.json index 1e3e88b8..45704040 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@ledgerhq/hw-transport-webusb": "^5.34.0", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "@project-serum/serum": "^0.13.11", diff --git a/src/App.js b/src/App.js index 43f4a3fa..a5a3ea8f 100644 --- a/src/App.js +++ b/src/App.js @@ -38,16 +38,17 @@ export default function App() { }> + - - + + }> - - + + diff --git a/src/components/AddHarwareWalletDialog.js b/src/components/AddHarwareWalletDialog.js new file mode 100644 index 00000000..39bd9914 --- /dev/null +++ b/src/components/AddHarwareWalletDialog.js @@ -0,0 +1,82 @@ +import React, {useEffect, useState} from 'react'; +import DialogActions from '@material-ui/core/DialogActions'; +import Button from '@material-ui/core/Button'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogForm from './DialogForm'; +import {LedgerWalletProvider} from "../utils/walletProvider/ledger"; +import CircularProgress from "@material-ui/core/CircularProgress"; +import {useSnackbar} from "notistack"; + +export default function AddHardwareWalletDialog({ open, onAdd, onClose }) { + const [pubKey, setPubKey] = useState(); + const { enqueueSnackbar } = useSnackbar(); + + useEffect(() => {( async () => { + if (open) { + try { + const provider = new LedgerWalletProvider(); + await provider.init(); + setPubKey(provider.publicKey); + } catch (err) { + console.log(`received error when attempting to connect ledger: ${err}`); + if (err.statusCode === 0x6804) { + enqueueSnackbar('Unlock ledger device', { variant: 'error' }) + } + setPubKey(undefined) + onClose(); + } + } + })();}, [open, onClose]) + + return ( + {}} + onClose={() => { + setPubKey(undefined); + onClose(); + }} + onSubmit={() => { + setPubKey(undefined); + onAdd(pubKey); + onClose(); + }} + fullWidth + > + Add hardware wallet + +
+ {pubKey + ? ( + <> + Hardware wallet detected: +
{pubKey.toString()}
+ + ) + : ( + <> + Connect your ledger and open the Solana application + + + ) + } +
+
+ + + + +
+ ); +} diff --git a/src/components/BalancesList.js b/src/components/BalancesList.js index 0839043b..c4748c48 100644 --- a/src/components/BalancesList.js +++ b/src/components/BalancesList.js @@ -184,6 +184,7 @@ function BalanceListItemDetails({ publicKey, balanceInfo }) { closeTokenAccountDialogOpen, setCloseTokenAccountDialogOpen, ] = useState(false); + const wallet = useWallet() if (!balanceInfo) { return ; @@ -197,10 +198,12 @@ function BalanceListItemDetails({ publicKey, balanceInfo }) { return ( <> - setExportAccDialogOpen(false)} - open={exportAccDialogOpen} - /> + {wallet.allowsExport && + setExportAccDialogOpen(false)} + open={exportAccDialogOpen} + /> + }
{!publicKey.equals(owner) && showTokenInfoDialog ? ( @@ -270,7 +273,7 @@ function BalanceListItemDetails({ publicKey, balanceInfo }) {
- {exportNeedsDisplay && ( + {exportNeedsDisplay && wallet.allowsExport && (
setExportAccDialogOpen(true)}> diff --git a/src/components/DebugButtons.js b/src/components/DebugButtons.js index 1173291e..9e840c4a 100644 --- a/src/components/DebugButtons.js +++ b/src/components/DebugButtons.js @@ -20,7 +20,7 @@ export default function DebugButtons() { const wallet = useWallet(); const updateTokenName = useUpdateTokenName(); const { endpoint } = useConnectionConfig(); - const balanceInfo = useBalanceInfo(wallet.account.publicKey); + const balanceInfo = useBalanceInfo(wallet.publicKey); const [sendTransaction, sending] = useSendTransaction(); const callAsync = useCallAsync(); @@ -29,13 +29,13 @@ export default function DebugButtons() { function requestAirdrop() { callAsync( wallet.connection.requestAirdrop( - wallet.account.publicKey, + wallet.publicKey, LAMPORTS_PER_SOL, ), { onSuccess: async () => { await sleep(5000); - refreshAccountInfo(wallet.connection, wallet.account.publicKey); + refreshAccountInfo(wallet.connection, wallet.publicKey); }, successMessage: 'Success! Please wait up to 30 seconds for the SOL tokens to appear in your wallet.', @@ -53,7 +53,7 @@ export default function DebugButtons() { sendTransaction( createAndInitializeMint({ connection: wallet.connection, - owner: wallet.account, + owner: wallet, mint, amount: 1000, decimals: 2, diff --git a/src/components/ExportAccountDialog.js b/src/components/ExportAccountDialog.js index 7639a329..fe8956e2 100644 --- a/src/components/ExportAccountDialog.js +++ b/src/components/ExportAccountDialog.js @@ -24,7 +24,7 @@ export default function ExportAccountDialog({ open, onClose }) { type={isHidden && 'password'} variant="outlined" margin="normal" - value={bs58.encode(wallet.account.secretKey)} + value={bs58.encode(wallet.provider.account.secretKey)} />