Changeset View
Changeset View
Standalone View
Standalone View
web/cashtab/src/components/Send/Send.js
Show All 34 Lines | import { | ||||
isValidXecSendAmount, | isValidXecSendAmount, | ||||
} from '@utils/validation'; | } from '@utils/validation'; | ||||
import BalanceHeader from '@components/Common/BalanceHeader'; | import BalanceHeader from '@components/Common/BalanceHeader'; | ||||
import BalanceHeaderFiat from '@components/Common/BalanceHeaderFiat'; | import BalanceHeaderFiat from '@components/Common/BalanceHeaderFiat'; | ||||
import { | import { | ||||
ZeroBalanceHeader, | ZeroBalanceHeader, | ||||
ConvertAmount, | ConvertAmount, | ||||
AlertMsg, | AlertMsg, | ||||
WalletInfoCtn, | |||||
SidePaddingCtn, | |||||
FormLabel, | |||||
} from '@components/Common/Atoms'; | } from '@components/Common/Atoms'; | ||||
import { | import { | ||||
getWalletState, | getWalletState, | ||||
convertToEcashPrefix, | convertToEcashPrefix, | ||||
toLegacyCash, | toLegacyCash, | ||||
toLegacyCashArray, | toLegacyCashArray, | ||||
fromSmallestDenomination, | fromSmallestDenomination, | ||||
} from '@utils/cashMethods'; | } from '@utils/cashMethods'; | ||||
import ApiError from '@components/Common/ApiError'; | import ApiError from '@components/Common/ApiError'; | ||||
import { formatFiatBalance, formatBalance } from '@utils/formatting'; | import { formatFiatBalance, formatBalance } from '@utils/formatting'; | ||||
import { TokenParamLabel } from '@components/Common/Atoms'; | import { TokenParamLabel } from '@components/Common/Atoms'; | ||||
import { PlusSquareOutlined } from '@ant-design/icons'; | import { PlusSquareOutlined } from '@ant-design/icons'; | ||||
import styled from 'styled-components'; | import styled from 'styled-components'; | ||||
import { CopyToClipboard } from 'react-copy-to-clipboard'; | import { CopyToClipboard } from 'react-copy-to-clipboard'; | ||||
import WalletLabel from '@components/Common/WalletLabel.js'; | |||||
const StyledSpacer = styled.div` | |||||
height: 1px; | |||||
width: 100%; | |||||
background-color: ${props => props.theme.wallet.borders.color}; | |||||
margin: 60px 0 50px; | |||||
`; | |||||
const SignMessageLabel = styled.div` | const SignMessageLabel = styled.div` | ||||
text-align: left; | text-align: left; | ||||
color: ${props => props.theme.forms.darkLabel}; | color: ${props => props.theme.forms.text}; | ||||
`; | |||||
const RecipientModeLabel = styled.div` | |||||
color: ${props => props.theme.forms.lightLabel}; | |||||
`; | `; | ||||
const TextAreaLabel = styled.div` | const TextAreaLabel = styled.div` | ||||
text-align: left; | text-align: left; | ||||
color: ${props => props.theme.forms.darkLabel}; | color: ${props => props.theme.forms.text}; | ||||
padding-left: 1px; | padding-left: 1px; | ||||
`; | `; | ||||
const AmountPreviewCtn = styled.div` | |||||
margin-top: -30px; | |||||
`; | |||||
const SendInputCtn = styled.div` | |||||
.ant-form-item-with-help { | |||||
margin-bottom: 32px; | |||||
} | |||||
`; | |||||
const LocaleFormattedValue = styled.h3` | const LocaleFormattedValue = styled.h3` | ||||
color: ${props => props.theme.forms.text}; | color: ${props => props.theme.contrast}; | ||||
font-weight: bold; | |||||
margin-bottom: 0; | |||||
`; | `; | ||||
// Note jestBCH is only used for unit tests; BCHJS must be mocked for jest | // Note jestBCH is only used for unit tests; BCHJS must be mocked for jest | ||||
const SendBCH = ({ jestBCH, passLoadingStatus }) => { | const SendBCH = ({ jestBCH, passLoadingStatus }) => { | ||||
// use balance parameters from wallet.state object and not legacy balances parameter from walletState, if user has migrated wallet | // use balance parameters from wallet.state object and not legacy balances parameter from walletState, if user has migrated wallet | ||||
// this handles edge case of user with old wallet who has not opened latest Cashtab version yet | // this handles edge case of user with old wallet who has not opened latest Cashtab version yet | ||||
// If the wallet object from ContextValue has a `state key`, then check which keys are in the wallet object | // If the wallet object from ContextValue has a `state key`, then check which keys are in the wallet object | ||||
// Else set it as blank | // Else set it as blank | ||||
▲ Show 20 Lines • Show All 530 Lines • ▼ Show 20 Lines | return ( | ||||
onOk={handleOk} | onOk={handleOk} | ||||
onCancel={handleCancel} | onCancel={handleCancel} | ||||
> | > | ||||
<p> | <p> | ||||
Are you sure you want to send {formData.value}{' '} | Are you sure you want to send {formData.value}{' '} | ||||
{currency.ticker} to {formData.address}? | {currency.ticker} to {formData.address}? | ||||
</p> | </p> | ||||
</Modal> | </Modal> | ||||
<WalletInfoCtn> | |||||
<WalletLabel name={wallet.name}></WalletLabel> | |||||
{!balances.totalBalance ? ( | {!balances.totalBalance ? ( | ||||
<ZeroBalanceHeader> | <ZeroBalanceHeader> | ||||
You currently have 0 {currency.ticker} | You currently have 0 {currency.ticker} | ||||
<br /> | <br /> | ||||
Deposit some funds to use this feature | Deposit some funds to use this feature | ||||
</ZeroBalanceHeader> | </ZeroBalanceHeader> | ||||
) : ( | ) : ( | ||||
<> | <> | ||||
<BalanceHeader | <BalanceHeader | ||||
balance={balances.totalBalance} | balance={balances.totalBalance} | ||||
ticker={currency.ticker} | ticker={currency.ticker} | ||||
/> | /> | ||||
{fiatPrice !== null && ( | {fiatPrice !== null && ( | ||||
<BalanceHeaderFiat | <BalanceHeaderFiat | ||||
balance={balances.totalBalance} | balance={balances.totalBalance} | ||||
settings={cashtabSettings} | settings={cashtabSettings} | ||||
fiatPrice={fiatPrice} | fiatPrice={fiatPrice} | ||||
/> | /> | ||||
)} | )} | ||||
</> | </> | ||||
)} | )} | ||||
</WalletInfoCtn> | |||||
<SidePaddingCtn> | |||||
<Row type="flex"> | <Row type="flex"> | ||||
<Col span={24}> | <Col span={24}> | ||||
<Form | <Form | ||||
style={{ | style={{ | ||||
width: 'auto', | width: 'auto', | ||||
marginTop: '40px', | |||||
}} | }} | ||||
> | > | ||||
{!isOneToManyXECSend ? ( | {!isOneToManyXECSend ? ( | ||||
<> | <SendInputCtn> | ||||
<Button | <FormLabel>Send to</FormLabel> | ||||
type="text" | |||||
block | |||||
onClick={() => setIsOneToManyXECSend(true)} | |||||
> | |||||
<RecipientModeLabel> | |||||
Switch to multiple recipients | |||||
</RecipientModeLabel> | |||||
</Button> | |||||
<DestinationAddressSingle | <DestinationAddressSingle | ||||
style={{ marginBottom: '0px' }} | |||||
loadWithCameraOpen={scannerSupported} | loadWithCameraOpen={scannerSupported} | ||||
validateStatus={ | validateStatus={ | ||||
sendBchAddressError ? 'error' : '' | sendBchAddressError ? 'error' : '' | ||||
} | } | ||||
help={ | help={ | ||||
sendBchAddressError | sendBchAddressError | ||||
? sendBchAddressError | ? sendBchAddressError | ||||
: '' | : '' | ||||
} | } | ||||
onScan={result => | onScan={result => | ||||
handleAddressChange({ | handleAddressChange({ | ||||
target: { | target: { | ||||
name: 'address', | name: 'address', | ||||
value: result, | value: result, | ||||
}, | }, | ||||
}) | }) | ||||
} | } | ||||
inputProps={{ | inputProps={{ | ||||
placeholder: `${currency.ticker} Address`, | placeholder: `${currency.ticker} Address`, | ||||
name: 'address', | name: 'address', | ||||
onChange: e => handleAddressChange(e), | onChange: e => | ||||
handleAddressChange(e), | |||||
required: true, | required: true, | ||||
value: formData.address, | value: formData.address, | ||||
}} | }} | ||||
></DestinationAddressSingle> | ></DestinationAddressSingle> | ||||
<FormLabel>Amount</FormLabel> | |||||
<SendBchInput | <SendBchInput | ||||
activeFiatCode={ | activeFiatCode={ | ||||
cashtabSettings && | cashtabSettings && | ||||
cashtabSettings.fiatCurrency | cashtabSettings.fiatCurrency | ||||
? cashtabSettings.fiatCurrency.toUpperCase() | ? cashtabSettings.fiatCurrency.toUpperCase() | ||||
: 'USD' | : 'USD' | ||||
} | } | ||||
validateStatus={ | validateStatus={ | ||||
sendBchAmountError ? 'error' : '' | sendBchAmountError ? 'error' : '' | ||||
} | } | ||||
help={ | help={ | ||||
sendBchAmountError | sendBchAmountError | ||||
? sendBchAmountError | ? sendBchAmountError | ||||
: '' | : '' | ||||
} | } | ||||
onMax={onMax} | onMax={onMax} | ||||
inputProps={{ | inputProps={{ | ||||
name: 'value', | name: 'value', | ||||
dollar: | dollar: | ||||
selectedCurrency === 'USD' ? 1 : 0, | selectedCurrency === 'USD' | ||||
? 1 | |||||
: 0, | |||||
placeholder: 'Amount', | placeholder: 'Amount', | ||||
onChange: e => handleBchAmountChange(e), | onChange: e => | ||||
handleBchAmountChange(e), | |||||
required: true, | required: true, | ||||
value: formData.value, | value: formData.value, | ||||
}} | }} | ||||
selectProps={{ | selectProps={{ | ||||
value: selectedCurrency, | value: selectedCurrency, | ||||
disabled: queryStringText !== null, | disabled: queryStringText !== null, | ||||
onChange: e => | onChange: e => | ||||
handleSelectedCurrencyChange(e), | handleSelectedCurrencyChange(e), | ||||
}} | }} | ||||
></SendBchInput> | ></SendBchInput> | ||||
{priceApiError && ( | {priceApiError && ( | ||||
<AlertMsg> | <AlertMsg> | ||||
Error fetching fiat price. Setting send | Error fetching fiat price. Setting | ||||
by{' '} | send by{' '} | ||||
{currency.fiatCurrencies[ | {currency.fiatCurrencies[ | ||||
cashtabSettings.fiatCurrency | cashtabSettings.fiatCurrency | ||||
].slug.toUpperCase()}{' '} | ].slug.toUpperCase()}{' '} | ||||
disabled | disabled | ||||
</AlertMsg> | </AlertMsg> | ||||
)} | )} | ||||
<LocaleFormattedValue> | </SendInputCtn> | ||||
{formatBalance(formData.value, userLocale)}{' '} | |||||
{selectedCurrency} | |||||
</LocaleFormattedValue> | |||||
<ConvertAmount> | |||||
{fiatPriceString !== '' && '='}{' '} | |||||
{fiatPriceString} | |||||
</ConvertAmount> | |||||
</> | |||||
) : ( | ) : ( | ||||
<> | <> | ||||
<Button | <FormLabel>Send to</FormLabel> | ||||
type="text" | |||||
block | |||||
onClick={() => setIsOneToManyXECSend(false)} | |||||
> | |||||
<RecipientModeLabel> | |||||
Switch to a single recipient | |||||
</RecipientModeLabel> | |||||
</Button> | |||||
<DestinationAddressMulti | <DestinationAddressMulti | ||||
validateStatus={ | validateStatus={ | ||||
sendBchAddressError ? 'error' : '' | sendBchAddressError ? 'error' : '' | ||||
} | } | ||||
help={ | help={ | ||||
sendBchAddressError | sendBchAddressError | ||||
? sendBchAddressError | ? sendBchAddressError | ||||
: '' | : '' | ||||
} | } | ||||
inputProps={{ | inputProps={{ | ||||
placeholder: `One XEC address & value per line, separated by comma \ne.g. \necash:qpatql05s9jfavnu0tv6lkjjk25n6tmj9gkpyrlwu8,500 \necash:qzvydd4n3lm3xv62cx078nu9rg0e3srmqq0knykfed,700`, | placeholder: `One XEC address & value per line, separated by comma \ne.g. \necash:qpatql05s9jfavnu0tv6lkjjk25n6tmj9gkpyrlwu8,500 \necash:qzvydd4n3lm3xv62cx078nu9rg0e3srmqq0knykfed,700`, | ||||
name: 'address', | name: 'address', | ||||
onChange: e => | onChange: e => | ||||
handleMultiAddressChange(e), | handleMultiAddressChange(e), | ||||
required: true, | required: true, | ||||
value: formData.address, | value: formData.address, | ||||
}} | }} | ||||
></DestinationAddressMulti> | ></DestinationAddressMulti> | ||||
</> | </> | ||||
)} | )} | ||||
{!isOneToManyXECSend && ( | |||||
<AmountPreviewCtn> | |||||
<LocaleFormattedValue> | |||||
{formatBalance( | |||||
formData.value, | |||||
userLocale, | |||||
)}{' '} | |||||
{selectedCurrency} | |||||
</LocaleFormattedValue> | |||||
<ConvertAmount> | |||||
{fiatPriceString !== '' && '='}{' '} | |||||
{fiatPriceString} | |||||
</ConvertAmount> | |||||
</AmountPreviewCtn> | |||||
)} | |||||
<div | <div | ||||
style={{ | style={{ | ||||
paddingTop: '32px', | paddingTop: '12px', | ||||
}} | |||||
> | |||||
{!balances.totalBalance || | |||||
apiError || | |||||
sendBchAmountError || | |||||
sendBchAddressError ? ( | |||||
<SecondaryButton>Send</SecondaryButton> | |||||
) : ( | |||||
<> | |||||
{txInfoFromUrl ? ( | |||||
<PrimaryButton | |||||
onClick={() => showModal()} | |||||
> | |||||
Send | |||||
</PrimaryButton> | |||||
) : ( | |||||
<PrimaryButton | |||||
onClick={() => { | |||||
send(); | |||||
}} | }} | ||||
> | > | ||||
Send | |||||
</PrimaryButton> | |||||
)} | |||||
</> | |||||
)} | |||||
</div> | |||||
<div> | |||||
<AdvancedCollapse | <AdvancedCollapse | ||||
style={{ | style={{ | ||||
marginBottom: '24px', | marginBottom: '12px', | ||||
}} | }} | ||||
defaultActiveKey={ | defaultActiveKey={ | ||||
location && | location && | ||||
location.state && | location.state && | ||||
location.state.replyAddress | location.state.replyAddress | ||||
? ['1'] | ? ['1'] | ||||
: ['0'] | : ['0'] | ||||
} | } | ||||
> | > | ||||
<Panel header="Advanced" key="1"> | <Panel header="Advanced" key="1"> | ||||
<AntdFormWrapper | <AntdFormWrapper | ||||
style={{ | style={{ | ||||
marginBottom: '20px', | marginBottom: '20px', | ||||
}} | }} | ||||
> | > | ||||
<TextAreaLabel> | <TextAreaLabel> | ||||
Multiple Recipients: | |||||
<Switch | |||||
defaultunchecked="true" | |||||
checked={isOneToManyXECSend} | |||||
onChange={() => { | |||||
setIsOneToManyXECSend( | |||||
!isOneToManyXECSend, | |||||
); | |||||
setIsEncryptedOptionalOpReturnMsg( | |||||
false, | |||||
); | |||||
}} | |||||
style={{ | |||||
marginBottom: '7px', | |||||
}} | |||||
/> | |||||
</TextAreaLabel> | |||||
<TextAreaLabel> | |||||
Message: | Message: | ||||
{!isOneToManyXECSend ? ( | |||||
<Switch | <Switch | ||||
disabled={ | |||||
isOneToManyXECSend | |||||
} | |||||
style={{ | |||||
marginBottom: '7px', | |||||
}} | |||||
checkedChildren="Private" | checkedChildren="Private" | ||||
unCheckedChildren="Public" | unCheckedChildren="Public" | ||||
defaultunchecked="true" | defaultunchecked="true" | ||||
checked={ | checked={ | ||||
isEncryptedOptionalOpReturnMsg | isEncryptedOptionalOpReturnMsg | ||||
} | } | ||||
onChange={() => | onChange={() => { | ||||
setIsEncryptedOptionalOpReturnMsg( | setIsEncryptedOptionalOpReturnMsg( | ||||
prev => !prev, | prev => !prev, | ||||
) | ); | ||||
} | setIsOneToManyXECSend( | ||||
style={{ | false, | ||||
marginBottom: '7px', | ); | ||||
}} | }} | ||||
/> | /> | ||||
) : ( | |||||
'' | |||||
)} | |||||
</TextAreaLabel> | </TextAreaLabel> | ||||
{isEncryptedOptionalOpReturnMsg ? ( | {isEncryptedOptionalOpReturnMsg ? ( | ||||
<Alert | <Alert | ||||
style={{ | style={{ | ||||
marginBottom: '10px', | marginBottom: '10px', | ||||
}} | }} | ||||
description="Please note encrypted messages can only be sent to wallets with at least 1 outgoing transaction." | description="Please note encrypted messages can only be sent to wallets with at least 1 outgoing transaction." | ||||
type="warning" | type="warning" | ||||
showIcon | showIcon | ||||
/> | /> | ||||
) : ( | ) : ( | ||||
<Alert | <Alert | ||||
style={{ | style={{ | ||||
marginBottom: '10px', | marginBottom: '10px', | ||||
}} | }} | ||||
description="Please note this message will be public." | description="Please note this message will be public." | ||||
type="warning" | type="warning" | ||||
showIcon | showIcon | ||||
/> | /> | ||||
)} | )} | ||||
<TextArea | <TextArea | ||||
name="opReturnMsg" | name="opReturnMsg" | ||||
placeholder={ | placeholder={ | ||||
isEncryptedOptionalOpReturnMsg | isEncryptedOptionalOpReturnMsg | ||||
? `(max ${currency.opReturn.encryptedMsgCharLimit} characters)` | ? `(max ${currency.opReturn.encryptedMsgCharLimit} characters)` | ||||
: `(max ${currency.opReturn.unencryptedMsgCharLimit} characters)` | : `(max ${currency.opReturn.unencryptedMsgCharLimit} characters)` | ||||
} | } | ||||
value={ | value={ | ||||
opReturnMsg | opReturnMsg | ||||
? isEncryptedOptionalOpReturnMsg | ? isEncryptedOptionalOpReturnMsg | ||||
? opReturnMsg.substring( | ? opReturnMsg.substring( | ||||
0, | 0, | ||||
currency.opReturn | currency | ||||
.opReturn | |||||
.encryptedMsgCharLimit + | .encryptedMsgCharLimit + | ||||
1, | 1, | ||||
) | ) | ||||
: opReturnMsg | : opReturnMsg | ||||
: '' | : '' | ||||
} | } | ||||
onChange={e => | onChange={e => | ||||
setOpReturnMsg(e.target.value) | setOpReturnMsg( | ||||
e.target.value, | |||||
) | |||||
} | } | ||||
showCount | showCount | ||||
maxLength={ | maxLength={ | ||||
isEncryptedOptionalOpReturnMsg | isEncryptedOptionalOpReturnMsg | ||||
? currency.opReturn | ? currency.opReturn | ||||
.encryptedMsgCharLimit | .encryptedMsgCharLimit | ||||
: currency.opReturn | : currency.opReturn | ||||
.unencryptedMsgCharLimit | .unencryptedMsgCharLimit | ||||
} | } | ||||
onKeyDown={e => | onKeyDown={e => | ||||
e.keyCode == 13 | e.keyCode == 13 | ||||
? e.preventDefault() | ? e.preventDefault() | ||||
: '' | : '' | ||||
} | } | ||||
/> | /> | ||||
</AntdFormWrapper> | </AntdFormWrapper> | ||||
</Panel> | </Panel> | ||||
</AdvancedCollapse> | </AdvancedCollapse> | ||||
</div> | </div> | ||||
<div | |||||
style={{ | |||||
paddingTop: '12px', | |||||
}} | |||||
> | |||||
{!balances.totalBalance || | |||||
apiError || | |||||
sendBchAmountError || | |||||
sendBchAddressError ? ( | |||||
<SecondaryButton>Send</SecondaryButton> | |||||
) : ( | |||||
<> | |||||
{txInfoFromUrl ? ( | |||||
<PrimaryButton | |||||
onClick={() => showModal()} | |||||
> | |||||
Send | |||||
</PrimaryButton> | |||||
) : ( | |||||
<PrimaryButton | |||||
onClick={() => { | |||||
send(); | |||||
}} | |||||
> | |||||
Send | |||||
</PrimaryButton> | |||||
)} | |||||
</> | |||||
)} | |||||
</div> | |||||
{queryStringText && ( | {queryStringText && ( | ||||
<Alert | <Alert | ||||
message={`You are sending a transaction to an address including query parameters "${queryStringText}." Only the "amount" parameter, in units of ${currency.ticker} satoshis, is currently supported.`} | message={`You are sending a transaction to an address including query parameters "${queryStringText}." Only the "amount" parameter, in units of ${currency.ticker} satoshis, is currently supported.`} | ||||
type="warning" | type="warning" | ||||
/> | /> | ||||
)} | )} | ||||
{apiError && <ApiError />} | {apiError && <ApiError />} | ||||
</Form> | </Form> | ||||
</Col> | </Col> | ||||
</Row> | </Row> | ||||
<StyledSpacer>Signatures</StyledSpacer> | |||||
<Modal | <Modal | ||||
title={`Please review and confirm your message to be signed using this wallet.`} | title={`Please review and confirm your message to be signed using this wallet.`} | ||||
visible={showConfirmMsgToSign} | visible={showConfirmMsgToSign} | ||||
onOk={signMessageByPk} | onOk={signMessageByPk} | ||||
onCancel={() => setShowConfirmMsgToSign(false)} | onCancel={() => setShowConfirmMsgToSign(false)} | ||||
> | > | ||||
<TokenParamLabel>Message:</TokenParamLabel> {msgToSign} | <TokenParamLabel>Message:</TokenParamLabel> {msgToSign} | ||||
<br /> | <br /> | ||||
</Modal> | </Modal> | ||||
<AdvancedCollapse | <AdvancedCollapse | ||||
style={{ | style={{ | ||||
marginBottom: '24px', | marginBottom: '24px', | ||||
}} | }} | ||||
> | > | ||||
<Panel header="Sign Message" key="1"> | <Panel header="Sign Message" key="1"> | ||||
<AntdFormWrapper> | <AntdFormWrapper> | ||||
<Form | <Form | ||||
size="small" | size="small" | ||||
style={{ | style={{ | ||||
width: 'auto', | width: 'auto', | ||||
}} | }} | ||||
> | > | ||||
<Form.Item> | <Form.Item> | ||||
<SignMessageLabel>Message:</SignMessageLabel> | <SignMessageLabel> | ||||
Message: | |||||
</SignMessageLabel> | |||||
<TextArea | <TextArea | ||||
name="signMessage" | name="signMessage" | ||||
onChange={e => handleSignMsgChange(e)} | onChange={e => handleSignMsgChange(e)} | ||||
showCount | showCount | ||||
maxLength={150} | maxLength={150} | ||||
/> | /> | ||||
</Form.Item> | </Form.Item> | ||||
<Form.Item> | <Form.Item> | ||||
<SignMessageLabel>Address:</SignMessageLabel> | <SignMessageLabel> | ||||
Address: | |||||
</SignMessageLabel> | |||||
<Input | <Input | ||||
name="signMessageAddress" | name="signMessageAddress" | ||||
disabled={true} | disabled={true} | ||||
value={ | value={ | ||||
wallet && | wallet && | ||||
wallet.Path1899 && | wallet.Path1899 && | ||||
wallet.Path1899.cashAddress | wallet.Path1899.cashAddress | ||||
? convertToEcashPrefix( | ? convertToEcashPrefix( | ||||
wallet.Path1899.cashAddress, | wallet.Path1899 | ||||
.cashAddress, | |||||
) | ) | ||||
: '' | : '' | ||||
} | } | ||||
/> | /> | ||||
</Form.Item> | </Form.Item> | ||||
<SmartButton | <SmartButton | ||||
onClick={() => setShowConfirmMsgToSign(true)} | onClick={() => | ||||
setShowConfirmMsgToSign(true) | |||||
} | |||||
disabled={!signMessageIsValid} | disabled={!signMessageIsValid} | ||||
> | > | ||||
<PlusSquareOutlined /> | <PlusSquareOutlined /> | ||||
Sign Message | Sign Message | ||||
</SmartButton> | </SmartButton> | ||||
<CopyToClipboard | <CopyToClipboard | ||||
style={{ | style={{ | ||||
display: 'inline-block', | display: 'inline-block', | ||||
width: '100%', | width: '100%', | ||||
position: 'relative', | position: 'relative', | ||||
}} | }} | ||||
text={messageSignature} | text={messageSignature} | ||||
> | > | ||||
<Form.Item> | <Form.Item> | ||||
<SignMessageLabel> | <SignMessageLabel> | ||||
Signature: | Signature: | ||||
</SignMessageLabel> | </SignMessageLabel> | ||||
<TextArea | <TextArea | ||||
name="signMessageSignature" | name="signMessageSignature" | ||||
placeholder="The signature will be generated upon signing of the message" | placeholder="The signature will be generated upon signing of the message" | ||||
readOnly={true} | readOnly={true} | ||||
value={messageSignature} | value={messageSignature} | ||||
onClick={() => handleOnSigCopy()} | onClick={() => handleOnSigCopy()} | ||||
/> | /> | ||||
</Form.Item> | </Form.Item> | ||||
</CopyToClipboard> | </CopyToClipboard> | ||||
{sigCopySuccess} | {sigCopySuccess} | ||||
</Form> | </Form> | ||||
</AntdFormWrapper> | </AntdFormWrapper> | ||||
</Panel> | </Panel> | ||||
</AdvancedCollapse> | </AdvancedCollapse> | ||||
</SidePaddingCtn> | |||||
</> | </> | ||||
); | ); | ||||
}; | }; | ||||
/* | /* | ||||
passLoadingStatus must receive a default prop that is a function | passLoadingStatus must receive a default prop that is a function | ||||
in order to pass the rendering unit test in Send.test.js | in order to pass the rendering unit test in Send.test.js | ||||
Show All 15 Lines |