diff --git a/src/components/Jam.jsx b/src/components/Jam.jsx
index 5cd7b9186..1f815e957 100644
--- a/src/components/Jam.jsx
+++ b/src/components/Jam.jsx
@@ -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
}}
@@ -457,10 +466,10 @@ export default function Jam() {
isInvalid={touched[`dest${i}`] && !!errors[`dest${i}`]}
className={`${styles.input} slashed-zeroes`}
/>
+
{t('scheduler.description_fees')}
)} diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index 3ee7bef49..02cee55a3 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -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 }}", @@ -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).",