Skip to content

Commit

Permalink
feat: prevent address reuse on Jam page (#433)
Browse files Browse the repository at this point in the history
  • Loading branch information
theborakompanioni committed Aug 1, 2022
1 parent 01515d7 commit 6a8830f
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 18 deletions.
41 changes: 25 additions & 16 deletions src/components/Jam.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -350,25 +350,34 @@ export default function Jam() {
const isValidAddress = (candidate) => {
return typeof candidate !== 'undefined' && candidate !== ''
}
const isAddressReused = (destination, inputAddresses) => {
if (!destination) return false

if (!isValidAddress(values.dest1)) {
errors.dest1 = t('scheduler.error_invalid_destionation_address')
}
if (!isValidAddress(values.dest2)) {
errors.dest2 = t('scheduler.error_invalid_destionation_address')
}
if (!isValidAddress(values.dest3)) {
errors.dest3 = t('scheduler.error_invalid_destionation_address')
const knownAddress = walletInfo?.addressSummary[destination] || false
const alreadyUsed = knownAddress && walletInfo?.addressSummary[destination]?.status !== 'new'
const duplicateEntry = inputAddresses.filter((it) => it === destination).length > 1

return alreadyUsed || duplicateEntry
}

const validAddresses = Array(3)
const addressDict = Array(3)
.fill('')
.map((_, index) => values[`dest${index + 1}`])
.filter((it) => isValidAddress(it))
const uniqueValidAddresses = [...new Set(validAddresses)]
if (validAddresses.length !== uniqueValidAddresses.length) {
errors.addressReuse = t('scheduler.error_address_reuse')
}
.map((_, index) => {
const key = `dest${index + 1}`
return {
key,
address: values[key],
}
})
const addresses = addressDict.map((it) => it.address)

addressDict.forEach((addressEntry) => {
if (!isValidAddress(addressEntry.address)) {
errors[addressEntry.key] = t('scheduler.feedback_invalid_destination_address')
} else if (isAddressReused(addressEntry.address, addresses)) {
errors[addressEntry.key] = t('scheduler.feedback_reused_destination_address')
}
})

return errors
}}
Expand Down Expand Up @@ -457,10 +466,10 @@ export default function Jam() {
isInvalid={touched[`dest${i}`] && !!errors[`dest${i}`]}
className={`${styles.input} slashed-zeroes`}
/>
<rb.Form.Control.Feedback type="invalid">{errors[`dest${i}`]}</rb.Form.Control.Feedback>
</rb.Form.Group>
)
})}
{errors && errors.addressReuse && <rb.Alert variant="danger">{errors.addressReuse}</rb.Alert>}
{!collaborativeOperationRunning && (
<p className="text-secondary mb-4">{t('scheduler.description_fees')}</p>
)}
Expand Down
4 changes: 2 additions & 2 deletions src/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,8 @@
"complete_wallet_title": "Complete Wallet",
"complete_wallet_subtitle": "This will use all of your non-frozen funds.",
"description_destination_addresses": "You can choose to send your funds to an external wallet after completion automatically. However, this feature requires you to provide multiple destination addresses to preserve your privacy.",
"error_invalid_destionation_address": "Please enter valid a destination address.",
"feedback_invalid_destination_address": "Please enter valid a destination address.",
"feedback_reused_destination_address": "This address is already used. To preserve your privacy please choose another one.",
"toggle_internal_destination_title": "Send to external wallet",
"toggle_internal_destination_subtitle": "Specify destination addresses to send funds to an external wallet.",
"label_destination_input": "Destination {{ destination }}",
Expand All @@ -403,7 +404,6 @@
"progress_current_state": "Waiting for transaction <1>{{ current }}</1> of <3>{{ total }}</3> to process...",
"progress_done": "All transactions completed successfully. The scheduler will stop soon.",
"error_loading_schedule_failed": "Loading schedule progress failed.",
"error_address_reuse": "Reusing addresses is prohibited. Make sure to use unique and unused addresses.",
"precondition": {
"hint_missing_utxos": "To run the scheduler you need at least one UTXO with <2>{{ minConfirmations }}</2> confirmations in Jar #0. Fund your wallet and wait for <6>{{ minConfirmations }}</6> blocks.",
"hint_missing_confirmations": "The scheduler requires one of your UTXOs in Jar #0 to have <2>{{ minConfirmations }}</2> or more confirmations. Wait for <6>{{ amountOfMissingConfirmations }}</6> more block(s).",
Expand Down

0 comments on commit 6a8830f

Please sign in to comment.