From 2eb60bc2255f764801e9ac4626eda84b658c3255 Mon Sep 17 00:00:00 2001 From: amitx13 Date: Thu, 8 Aug 2024 19:16:40 +0530 Subject: [PATCH 1/3] Show considered UTXOs before performing sweep transaction --- src/components/Send/SendForm.tsx | 3 ++- src/components/Send/SourceJarSelector.tsx | 12 +++++++-- src/components/Send/index.tsx | 33 +++++++++++++++++++++-- src/i18n/locales/en/translation.json | 2 +- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/components/Send/SendForm.tsx b/src/components/Send/SendForm.tsx index 7eeaf130b..32142eab3 100644 --- a/src/components/Send/SendForm.tsx +++ b/src/components/Send/SendForm.tsx @@ -26,7 +26,7 @@ import { isValidNumCollaborators, } from './helpers' import { AccountBalanceSummary } from '../../context/BalanceSummary' -import { WalletInfo, CurrentWallet } from '../../context/WalletContext' +import { WalletInfo, CurrentWallet, Utxos } from '../../context/WalletContext' import { useSettings } from '../../context/SettingsContext' import styles from './SendForm.module.css' import { TxFeeInputField, validateTxFee } from '../settings/TxFeeInputField' @@ -214,6 +214,7 @@ export interface SendFormValues { txFee?: TxFee isCoinJoin: boolean numCollaborators?: number + consideredUtxos?: Utxos } interface InnerSendFormProps { diff --git a/src/components/Send/SourceJarSelector.tsx b/src/components/Send/SourceJarSelector.tsx index af6e9ccb5..0977dfd50 100644 --- a/src/components/Send/SourceJarSelector.tsx +++ b/src/components/Send/SourceJarSelector.tsx @@ -3,7 +3,7 @@ import { useField, useFormikContext } from 'formik' import * as rb from 'react-bootstrap' import { jarFillLevel, SelectableJar } from '../jars/Jar' import { noop } from '../../utils' -import { WalletInfo, CurrentWallet, useReloadCurrentWalletInfo, Utxo } from '../../context/WalletContext' +import { WalletInfo, CurrentWallet, useReloadCurrentWalletInfo, Utxo, Utxos } from '../../context/WalletContext' import styles from './SourceJarSelector.module.css' import { ShowUtxos } from './ShowUtxos' import { useTranslation } from 'react-i18next' @@ -38,6 +38,7 @@ export const SourceJarSelector = ({ }: SourceJarSelectorProps) => { const { t } = useTranslation() const [field] = useField(name) + const [consideredUtxos] = useField('consideredUtxos') const form = useFormikContext() const reloadCurrentWalletInfo = useReloadCurrentWalletInfo() @@ -119,8 +120,14 @@ export const SourceJarSelector = ({ } } finally { setIsUtxosLoading(false) + if (walletInfo) { + const selectedUtxos = walletInfo.utxosByJar[field.value].filter((utxo) => { + return !utxo.frozen + }) + form.setFieldValue(consideredUtxos.name, selectedUtxos, true) + } } - }, [frozenUtxos, unFrozenUtxos, wallet, reloadCurrentWalletInfo]) + }, [frozenUtxos, unFrozenUtxos, wallet, reloadCurrentWalletInfo, consideredUtxos, form, field, walletInfo]) return ( <> @@ -165,6 +172,7 @@ export const SourceJarSelector = ({ variant={it.accountIndex === field.value ? variant : undefined} onClick={(jarIndex: number) => { form.setFieldValue(field.name, jarIndex, true) + form.setFieldValue(consideredUtxos.name, undefined, false) if ( it.accountIndex === field.value && !disabled && diff --git a/src/components/Send/index.tsx b/src/components/Send/index.tsx index 7f6dd561d..00032f52f 100644 --- a/src/components/Send/index.tsx +++ b/src/components/Send/index.tsx @@ -12,7 +12,7 @@ import { scrollToTop } from '../../utils' import { PaymentConfirmModal } from '../PaymentConfirmModal' import FeeConfigModal, { FeeConfigSectionKey } from '../settings/FeeConfigModal' import { FeeValues, TxFee, useFeeConfigValues } from '../../hooks/Fees' -import { useReloadCurrentWalletInfo, useCurrentWalletInfo, CurrentWallet } from '../../context/WalletContext' +import { useReloadCurrentWalletInfo, useCurrentWalletInfo, CurrentWallet, Utxos } from '../../context/WalletContext' import { useServiceInfo, useReloadServiceInfo } from '../../context/ServiceInfoContext' import { useLoadConfigValue } from '../../context/ServiceConfigContext' import { useWaitForUtxosToBeSpent } from '../../hooks/WaitForUtxosToBeSpent' @@ -20,6 +20,8 @@ import { routes } from '../../constants/routes' import { JM_MINIMUM_MAKERS_DEFAULT } from '../../constants/config' import { initialNumCollaborators } from './helpers' +import { Divider, UtxoListDisplay } from './ShowUtxos' +import { useSettings } from '../../context/SettingsContext' const INITIAL_DESTINATION = null const INITIAL_SOURCE_JAR_INDEX = null @@ -79,6 +81,29 @@ const createInitialValues = (numCollaborators: number, feeConfigValues: FeeValue } } +type ReviewConsideredUtxosProps = { + utxos: Utxos +} +const ReviewConsideredUtxos = ({ utxos }: ReviewConsideredUtxosProps) => { + const { t } = useTranslation() + const settings = useSettings() + const [isOpen, setIsOpen] = useState(false) + + return ( + + + {t('show_utxos.considered_utxos')} + + + + {isOpen && ( + + )} + + + ) +} + type SendProps = { wallet: CurrentWallet } @@ -516,7 +541,11 @@ export default function Send({ wallet }: SendProps) { numCollaborators: showConfirmSendModal.numCollaborators!, feeConfigValues: { ...feeConfigValues, tx_fees: showConfirmSendModal.txFee }, }} - /> + > + {showConfirmSendModal.amount!.isSweep && showConfirmSendModal.consideredUtxos && ( + + )} + )} ) diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index fcbdf99f4..0693fc6ea 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -703,7 +703,7 @@ }, "show_utxos": { "select_utxos": "Select UTXOs", - "selected_utxos": "Selected UTXOs", + "considered_utxos": "Considered UTXOs", "show_utxo_title": "Select UTXOs to be considered", "show_utxo_subtitle": "The following UTXOs are considered in the transaction. Every unselected UTXO will be frozen and can be unfrozen later on.", "show_utxo_subtitle_when_allutxos_are_frozen": "The following UTXOs are frozen. Please select them to be considered in the transaction.", From 8c8198eff0f952615428882cc2ef352494e6fdeb Mon Sep 17 00:00:00 2001 From: amitx13 Date: Sun, 11 Aug 2024 23:16:59 +0530 Subject: [PATCH 2/3] Refactored consideredUtxo for forward compatibility --- src/components/Send/SendForm.tsx | 4 ++-- src/components/Send/SourceJarSelector.tsx | 22 ++++++++++++++-------- src/components/Send/index.tsx | 14 +++++++++++--- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/components/Send/SendForm.tsx b/src/components/Send/SendForm.tsx index 32142eab3..ed724c19b 100644 --- a/src/components/Send/SendForm.tsx +++ b/src/components/Send/SendForm.tsx @@ -26,7 +26,7 @@ import { isValidNumCollaborators, } from './helpers' import { AccountBalanceSummary } from '../../context/BalanceSummary' -import { WalletInfo, CurrentWallet, Utxos } from '../../context/WalletContext' +import { WalletInfo, CurrentWallet } from '../../context/WalletContext' import { useSettings } from '../../context/SettingsContext' import styles from './SendForm.module.css' import { TxFeeInputField, validateTxFee } from '../settings/TxFeeInputField' @@ -214,7 +214,7 @@ export interface SendFormValues { txFee?: TxFee isCoinJoin: boolean numCollaborators?: number - consideredUtxos?: Utxos + consideredUtxos?: string[] } interface InnerSendFormProps { diff --git a/src/components/Send/SourceJarSelector.tsx b/src/components/Send/SourceJarSelector.tsx index 0977dfd50..92c150e06 100644 --- a/src/components/Send/SourceJarSelector.tsx +++ b/src/components/Send/SourceJarSelector.tsx @@ -110,9 +110,21 @@ export const SourceJarSelector = ({ if (res.length !== 0) { setIsUtxosLoading(true) - await reloadCurrentWalletInfo.reloadUtxos({ signal: abortCtrl.signal }) + const allUtxosData = await reloadCurrentWalletInfo.reloadUtxos({ signal: abortCtrl.signal }) + if (allUtxosData) { + const selectedUtxos = allUtxosData.utxos + .filter((utxo) => utxo.mixdepth === field.value && !utxo.frozen) + .map((utxo) => utxo.utxo) + form.setFieldValue(consideredUtxos.name, selectedUtxos, true) + } + } else { + if (walletInfo) { + const selectedUtxos = walletInfo.utxosByJar[field.value] + .filter((utxo) => !utxo.frozen) + .map((utxo) => utxo.utxo) + form.setFieldValue(consideredUtxos.name, selectedUtxos, true) + } } - setShowUtxos(undefined) } catch (err: any) { if (!abortCtrl.signal.aborted) { @@ -120,12 +132,6 @@ export const SourceJarSelector = ({ } } finally { setIsUtxosLoading(false) - if (walletInfo) { - const selectedUtxos = walletInfo.utxosByJar[field.value].filter((utxo) => { - return !utxo.frozen - }) - form.setFieldValue(consideredUtxos.name, selectedUtxos, true) - } } }, [frozenUtxos, unFrozenUtxos, wallet, reloadCurrentWalletInfo, consideredUtxos, form, field, walletInfo]) diff --git a/src/components/Send/index.tsx b/src/components/Send/index.tsx index 00032f52f..260213865 100644 --- a/src/components/Send/index.tsx +++ b/src/components/Send/index.tsx @@ -542,9 +542,17 @@ export default function Send({ wallet }: SendProps) { feeConfigValues: { ...feeConfigValues, tx_fees: showConfirmSendModal.txFee }, }} > - {showConfirmSendModal.amount!.isSweep && showConfirmSendModal.consideredUtxos && ( - - )} + {showConfirmSendModal.amount?.isSweep && + showConfirmSendModal.consideredUtxos && + walletInfo && + showConfirmSendModal.sourceJarIndex !== undefined && + (() => { + const selectedUtxosList = showConfirmSendModal.consideredUtxos + const utxoList = walletInfo.utxosByJar[showConfirmSendModal.sourceJarIndex].filter((utxo) => + selectedUtxosList.some((selectedUtxos) => selectedUtxos === utxo.utxo), + ) + return + })()} )} From b078dc2938747266f573c4cf4f440652c760bb68 Mon Sep 17 00:00:00 2001 From: amitx13 Date: Sun, 11 Aug 2024 23:44:12 +0530 Subject: [PATCH 3/3] Testing for direct-send RPC-Api which is introduced by amitx13 --- .../joinmarket/latest/Dockerfile | 6 +++--- src/components/Send/index.tsx | 20 +++++++++++++++---- src/libs/JmWalletApi.ts | 1 + 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/docker/regtest/dockerfile-deps/joinmarket/latest/Dockerfile b/docker/regtest/dockerfile-deps/joinmarket/latest/Dockerfile index 871c28759..4c33af052 100644 --- a/docker/regtest/dockerfile-deps/joinmarket/latest/Dockerfile +++ b/docker/regtest/dockerfile-deps/joinmarket/latest/Dockerfile @@ -7,9 +7,9 @@ RUN apt-get update \ tor \ && rm -rf /var/lib/apt/lists/* -ENV REPO https://github.com/JoinMarket-Org/joinmarket-clientserver -ENV REPO_BRANCH master -ENV REPO_REF master +ENV REPO https://github.com/amitx13/joinmarket-clientserver +ENV REPO_BRANCH Updating_Direct-Send_RPC-API_to_accept_UTXOs +ENV REPO_REF Updating_Direct-Send_RPC-API_to_accept_UTXOs WORKDIR /src RUN git clone "$REPO" . --depth=10 --branch "$REPO_BRANCH" && git checkout "$REPO_REF" diff --git a/src/components/Send/index.tsx b/src/components/Send/index.tsx index 260213865..58a1adeff 100644 --- a/src/components/Send/index.tsx +++ b/src/components/Send/index.tsx @@ -263,6 +263,7 @@ export default function Send({ wallet }: SendProps) { destination: Api.BitcoinAddress, amountSats: Api.AmountSats, txFee: TxFee, + consideredUtxos?: string[], ) => { setAlert(undefined) setPaymentSuccessfulInfoAlert(undefined) @@ -272,7 +273,13 @@ export default function Send({ wallet }: SendProps) { try { const res = await Api.postDirectSend( { ...wallet }, - { mixdepth: sourceJarIndex, amount_sats: amountSats, destination, txfee: txFee.value }, + { + mixdepth: sourceJarIndex, + amount_sats: amountSats, + destination, + txfee: txFee.value, + selected_utxos: consideredUtxos, + }, ) if (res.ok) { @@ -420,7 +427,13 @@ export default function Send({ wallet }: SendProps) { values.numCollaborators!, values.txFee!, ) - : await sendPayment(values.sourceJarIndex!, values.destination!.value!, values.amount!.value, values.txFee!) + : await sendPayment( + values.sourceJarIndex!, + values.destination!.value!, + values.amount!.value, + values.txFee!, + values.consideredUtxos, + ) if (success) { formRef.current?.resetForm({ values: initialValues }) @@ -542,8 +555,7 @@ export default function Send({ wallet }: SendProps) { feeConfigValues: { ...feeConfigValues, tx_fees: showConfirmSendModal.txFee }, }} > - {showConfirmSendModal.amount?.isSweep && - showConfirmSendModal.consideredUtxos && + {showConfirmSendModal.consideredUtxos && walletInfo && showConfirmSendModal.sourceJarIndex !== undefined && (() => { diff --git a/src/libs/JmWalletApi.ts b/src/libs/JmWalletApi.ts index 7db9c2184..0f5294745 100644 --- a/src/libs/JmWalletApi.ts +++ b/src/libs/JmWalletApi.ts @@ -113,6 +113,7 @@ interface DirectSendRequest { destination: BitcoinAddress amount_sats: AmountSats txfee?: number + selected_utxos?: string[] } interface DoCoinjoinRequest {