Changeset View
Changeset View
Standalone View
Standalone View
cashtab/src/components/SignVerifyMsg/SignVerifyMsg.tsx
| // Copyright (c) 2024 The Bitcoin developers | // Copyright (c) 2024 The Bitcoin developers | ||||
| // Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
| // file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
| import React, { useState } from 'react'; | import React, { useState } from 'react'; | ||||
| import styled from 'styled-components'; | import styled from 'styled-components'; | ||||
| import { TextArea, Input } from 'components/Common/Inputs'; | import { TextArea, Input } from 'components/Common/Inputs'; | ||||
| import Switch from 'components/Common/Switch'; | import SegmentedControl from 'components/Common/SegmentedControl'; | ||||
| import { WalletContext } from 'wallet/context'; | import { WalletContext } from 'wallet/context'; | ||||
| import CopyToClipboard from 'components/Common/CopyToClipboard'; | import CopyToClipboard from 'components/Common/CopyToClipboard'; | ||||
| import PrimaryButton, { SecondaryButton } from 'components/Common/Buttons'; | import PrimaryButton, { SecondaryButton } from 'components/Common/Buttons'; | ||||
| import { isValidCashAddress } from 'ecashaddrjs'; | import { isValidCashAddress } from 'ecashaddrjs'; | ||||
| import { toast } from 'react-toastify'; | import { toast } from 'react-toastify'; | ||||
| import { theme } from 'assets/styles/theme'; | |||||
| import appConfig from 'config/app'; | import appConfig from 'config/app'; | ||||
| import { PageHeader } from 'components/Common/Atoms'; | import ActionButtonRow from 'components/Common/ActionButtonRow'; | ||||
| import { ThemedSignAndVerifyMsg } from 'components/Common/CustomIcons'; | |||||
| import { signMsg, verifyMsg } from 'ecash-lib'; | import { signMsg, verifyMsg } from 'ecash-lib'; | ||||
| const SignVerifyForm = styled.div` | const SignVerifyForm = styled.div` | ||||
| display: flex; | display: flex; | ||||
| flex-direction: column; | flex-direction: column; | ||||
| gap: 12px; | gap: 12px; | ||||
| width: 100%; | width: 100%; | ||||
| h2 { | h2 { | ||||
| margin-bottom: 20px; | margin-bottom: 20px; | ||||
| } | } | ||||
| `; | `; | ||||
| const Row = styled.div` | const Row = styled.div` | ||||
| width: 100%; | width: 100%; | ||||
| display: flex; | display: flex; | ||||
| flex-direction: row; | flex-direction: row; | ||||
| align-items: center; | align-items: center; | ||||
| justify-content: flex-start; | justify-content: flex-start; | ||||
| gap: 12px; | gap: 12px; | ||||
| `; | `; | ||||
| const FormContainer = styled.div` | |||||
| margin-top: 24px; | |||||
| `; | |||||
| const SignatureLabel = styled.div` | const SignatureLabel = styled.div` | ||||
| font-size: var(--text-lg); | font-size: var(--text-lg); | ||||
| line-height: var(--text-lg--line-height); | line-height: var(--text-lg--line-height); | ||||
| color: ${props => props.theme.primaryText}; | color: ${props => props.theme.primaryText}; | ||||
| text-align: left; | text-align: left; | ||||
| font-weight: bold; | font-weight: bold; | ||||
| width: 100%; | width: 100%; | ||||
| `; | `; | ||||
| ▲ Show 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | const verifyMessage = () => { | ||||
| ); | ); | ||||
| } else { | } else { | ||||
| toast.error('Signature does not match address and message'); | toast.error('Signature does not match address and message'); | ||||
| } | } | ||||
| }; | }; | ||||
| return ( | return ( | ||||
| <SignVerifyForm title="Sign & Verify"> | <SignVerifyForm title="Sign & Verify"> | ||||
| <PageHeader> | <ActionButtonRow variant="tools" activeIndex={2} /> | ||||
| Sign & Verify Msg | |||||
| <ThemedSignAndVerifyMsg /> | |||||
| </PageHeader> | |||||
| <Row> | <Row> | ||||
| <Switch | <SegmentedControl | ||||
| name="Toggle Sign Verify" | name="Toggle Sign Verify" | ||||
| on="✍️ Sign" | aria-label="Sign or verify message" | ||||
| off="✅ Verify" | options={[ | ||||
| bgColorOff={theme.genesisGreen} | { value: 'sign', label: '✍️ Sign' }, | ||||
| width={110} | { value: 'verify', label: '✅ Verify' }, | ||||
| right={76} | ]} | ||||
| checked={signMsgMode} | value={signMsgMode ? 'sign' : 'verify'} | ||||
| handleToggle={() => setSignMsgMode(!signMsgMode)} | onChange={value => setSignMsgMode(value === 'sign')} | ||||
| /> | /> | ||||
| </Row> | </Row> | ||||
| {signMsgMode ? ( | {signMsgMode ? ( | ||||
| <> | <FormContainer> | ||||
| <Row> | <Row> | ||||
| <TextArea | <TextArea | ||||
| placeholder={`Enter message to sign`} | placeholder={`Enter message to sign`} | ||||
| name="msgToSign" | name="msgToSign" | ||||
| label="Message to sign" | |||||
| handleInput={handleInput} | handleInput={handleInput} | ||||
| value={formData.msgToSign} | value={formData.msgToSign} | ||||
| error={formDataError.msgToSign} | error={formDataError.msgToSign} | ||||
| showCount | showCount | ||||
| max={`${CASHTAB_MESSAGE_MAX_LENGTH}`} | max={`${CASHTAB_MESSAGE_MAX_LENGTH}`} | ||||
| /> | /> | ||||
| </Row> | </Row> | ||||
| <Row> | <Row> | ||||
| Show All 16 Lines | return ( | ||||
| > | > | ||||
| <SignatureHolder> | <SignatureHolder> | ||||
| {messageSignature} | {messageSignature} | ||||
| </SignatureHolder> | </SignatureHolder> | ||||
| </CopyToClipboard> | </CopyToClipboard> | ||||
| </Row> | </Row> | ||||
| </> | </> | ||||
| )} | )} | ||||
| </> | </FormContainer> | ||||
| ) : ( | ) : ( | ||||
| <> | <FormContainer> | ||||
| <Row> | <Row> | ||||
| <TextArea | <TextArea | ||||
| placeholder={`Enter message to verify`} | placeholder={`Enter message to verify`} | ||||
| label="Message to verify" | |||||
| name="msgToVerify" | name="msgToVerify" | ||||
| handleInput={handleInput} | handleInput={handleInput} | ||||
| value={formData.msgToVerify} | value={formData.msgToVerify} | ||||
| error={formDataError.msgToVerify} | error={formDataError.msgToVerify} | ||||
| showCount | showCount | ||||
| max={`${CASHTAB_MESSAGE_MAX_LENGTH}`} | max={`${CASHTAB_MESSAGE_MAX_LENGTH}`} | ||||
| /> | /> | ||||
| </Row> | </Row> | ||||
| <Row> | <Row> | ||||
| <Input | <Input | ||||
| label="Address of signature to verify" | |||||
| name="addressToVerify" | name="addressToVerify" | ||||
| placeholder="Enter address of signature to verify" | placeholder="Enter address of signature to verify" | ||||
| value={formData.addressToVerify} | value={formData.addressToVerify} | ||||
| error={formDataError.addressToVerify} | error={formDataError.addressToVerify} | ||||
| handleInput={handleInput} | handleInput={handleInput} | ||||
| /> | /> | ||||
| </Row> | </Row> | ||||
| <Row> | <Row> | ||||
| <TextArea | <TextArea | ||||
| placeholder={`Enter signature to verify`} | placeholder={`Enter signature to verify`} | ||||
| label="Signature to verify" | |||||
| name="signatureToVerify" | name="signatureToVerify" | ||||
| handleInput={handleInput} | handleInput={handleInput} | ||||
| value={formData.signatureToVerify} | value={formData.signatureToVerify} | ||||
| error={formDataError.signatureToVerify} | error={formDataError.signatureToVerify} | ||||
| /> | /> | ||||
| </Row> | </Row> | ||||
| <Row> | <Row> | ||||
| <SecondaryButton | <SecondaryButton | ||||
| onClick={verifyMessage} | onClick={verifyMessage} | ||||
| disabled={ | disabled={ | ||||
| formDataError.msgToVerify !== false || | formDataError.msgToVerify !== false || | ||||
| formDataError.addressToVerify !== false || | formDataError.addressToVerify !== false || | ||||
| formDataError.signatureToVerify !== false | formDataError.signatureToVerify !== false | ||||
| } | } | ||||
| > | > | ||||
| Verify | Verify | ||||
| </SecondaryButton> | </SecondaryButton> | ||||
| </Row> | </Row> | ||||
| </> | </FormContainer> | ||||
| )} | )} | ||||
| </SignVerifyForm> | </SignVerifyForm> | ||||
| ); | ); | ||||
| }; | }; | ||||
| export default SignVerifyMsg; | export default SignVerifyMsg; | ||||