From 17edd52cd4bec20f183d58ae15b79f627d8fd3aa Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Mon, 13 Nov 2023 17:54:09 +0800 Subject: [PATCH 1/5] feat: Enable click max when address is empty. Use placeholder address to generate tx. --- .../neuron-ui/src/components/Send/hooks.ts | 23 +++++++++++++++---- .../neuron-ui/src/components/Send/index.tsx | 20 ++++++++++++++-- packages/neuron-ui/src/utils/const.ts | 2 ++ .../neuron-ui/src/utils/validators/outputs.ts | 4 +++- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/packages/neuron-ui/src/components/Send/hooks.ts b/packages/neuron-ui/src/components/Send/hooks.ts index 00506eb9d7..f933622425 100644 --- a/packages/neuron-ui/src/components/Send/hooks.ts +++ b/packages/neuron-ui/src/components/Send/hooks.ts @@ -10,7 +10,10 @@ import { shannonToCKBFormatter, calculateFee, validateOutputs, + DefaultLockInfo, } from 'utils' +import { scriptToAddress } from '@nervosnetwork/ckb-sdk-utils' +import { PlaceHolderArgs } from 'utils/const' let generateTxTimer: ReturnType @@ -330,10 +333,7 @@ export const useInitialize = ( const [errorMessage, setErrorMessage] = useState('') const [isSendMax, setIsSendMax] = useState(false) - const outputs = useMemo( - () => items.map(item => ({ ...item, disabled: isSendMax || sending })), - [items, isSendMax, sending] - ) + const outputs = useMemo(() => items.map(item => ({ ...item, disabled: sending })), [items, sending]) const updateIsSendMax = useCallback( (payload: boolean) => { @@ -358,7 +358,19 @@ export const useInitialize = ( const updateSendingAllTransaction = useCallback(() => { updateTransactionWith(generateSendingAllTx)({ walletID, - items, + items: items.map(v => ({ + ...v, + address: + v.address || + scriptToAddress( + { + codeHash: DefaultLockInfo.CodeHash, + hashType: DefaultLockInfo.HashType, + args: PlaceHolderArgs, + }, + isMainnet + ), + })), price, setTotalAmount, setErrorMessage, @@ -413,6 +425,7 @@ export const useInitialize = ( setErrorMessage, isSendMax, onSendMaxClick, + updateIsSendMax, } } diff --git a/packages/neuron-ui/src/components/Send/index.tsx b/packages/neuron-ui/src/components/Send/index.tsx index c5e0205607..345374b4cc 100644 --- a/packages/neuron-ui/src/components/Send/index.tsx +++ b/packages/neuron-ui/src/components/Send/index.tsx @@ -1,4 +1,4 @@ -import React, { useState, useCallback } from 'react' +import React, { useState, useCallback, useEffect } from 'react' import { useTranslation } from 'react-i18next' import { List } from 'office-ui-fabric-react' import { useState as useGlobalState, useDispatch, appState } from 'states' @@ -21,6 +21,7 @@ import { import { HIDE_BALANCE } from 'utils/const' import { isErrorWithI18n } from 'exceptions' +import { useSearchParams } from 'react-router-dom' import { useInitialize } from './hooks' import styles from './send.module.scss' @@ -81,8 +82,18 @@ const Send = () => { setErrorMessage, isSendMax, onSendMaxClick: handleSendMaxClick, + updateIsSendMax, } = useInitialize(walletID, send.outputs, send.generatedTx, send.price, sending, isMainnet, dispatch, t) + const [searchParams] = useSearchParams() + + useEffect(() => { + if (searchParams.get('isSendMax')) { + updateIsSendMax(true) + } + // only when router change init send max + }, [searchParams, updateIsSendMax]) + const [locktimeIndex, setLocktimeIndex] = useState(-1) const handleLocktimeClick = useCallback( @@ -128,7 +139,12 @@ const Send = () => { } } - const disabled = connectionStatus === 'offline' || sending || !!errorMessageUnderTotal || !send.generatedTx + const disabled = + connectionStatus === 'offline' || + sending || + !!errorMessageUnderTotal || + !send.generatedTx || + outputs.some(v => !v.address) const outputErrors = useOutputErrors(outputs, isMainnet) diff --git a/packages/neuron-ui/src/utils/const.ts b/packages/neuron-ui/src/utils/const.ts index 238c4be8b8..95db79fe67 100644 --- a/packages/neuron-ui/src/utils/const.ts +++ b/packages/neuron-ui/src/utils/const.ts @@ -81,3 +81,5 @@ export const MILLISECONDS = HOURS_PER_EPOCH * 60 * 60 * 1000 export const ADDRESS_MIN_LENGTH = 86 export const ADDRESS_HEAD_TAIL_LENGTH = 34 + +export const PlaceHolderArgs = `0x${'00'.repeat(21)}` diff --git a/packages/neuron-ui/src/utils/validators/outputs.ts b/packages/neuron-ui/src/utils/validators/outputs.ts index 7e96e2a567..3bed010e7e 100644 --- a/packages/neuron-ui/src/utils/validators/outputs.ts +++ b/packages/neuron-ui/src/utils/validators/outputs.ts @@ -10,7 +10,9 @@ export const validateOutputs = ( ) => { for (let i = 0; i < items.length; i++) { try { - validateAddress(items[i].address || '', isMainnet) + if (items[i].address) { + validateAddress(items[i].address || '', isMainnet) + } if (i !== items.length - 1 || !ignoreLastAmount) { validateAmount(items[i].amount) From e8537d288d949b040d6ad5c0b2cf0ca1f36db0cf Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Tue, 14 Nov 2023 10:43:51 +0800 Subject: [PATCH 2/5] fix: Fix test case --- packages/neuron-ui/src/tests/validators/outputs/fixtures.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/neuron-ui/src/tests/validators/outputs/fixtures.ts b/packages/neuron-ui/src/tests/validators/outputs/fixtures.ts index 5a3edb2fe3..82d160222d 100644 --- a/packages/neuron-ui/src/tests/validators/outputs/fixtures.ts +++ b/packages/neuron-ui/src/tests/validators/outputs/fixtures.ts @@ -21,7 +21,7 @@ const fixtures = { ], ignoreLastAmount: false, }, - exception: true, + exception: false, }, 'Should throw an error when address is invalid': { params: { From a2ea887689f3f4f02b87fc0a13900167ff09d8fc Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Tue, 14 Nov 2023 14:41:38 +0800 Subject: [PATCH 3/5] fix: Add ignore for last address and only ignore address for max send. --- .../neuron-ui/src/components/Send/index.tsx | 2 +- .../src/tests/validators/outputs/fixtures.ts | 22 ++++++++++++++++++- .../tests/validators/outputs/index.test.ts | 12 ++++++---- .../neuron-ui/src/utils/validators/outputs.ts | 5 +++-- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/packages/neuron-ui/src/components/Send/index.tsx b/packages/neuron-ui/src/components/Send/index.tsx index 345374b4cc..e9f253dea6 100644 --- a/packages/neuron-ui/src/components/Send/index.tsx +++ b/packages/neuron-ui/src/components/Send/index.tsx @@ -150,7 +150,7 @@ const Send = () => { const isMaxBtnDisabled = (() => { try { - validateOutputs(outputs, isMainnet, true) + validateOutputs(outputs, isMainnet, true, true) } catch { return true } diff --git a/packages/neuron-ui/src/tests/validators/outputs/fixtures.ts b/packages/neuron-ui/src/tests/validators/outputs/fixtures.ts index 82d160222d..4e02577491 100644 --- a/packages/neuron-ui/src/tests/validators/outputs/fixtures.ts +++ b/packages/neuron-ui/src/tests/validators/outputs/fixtures.ts @@ -8,10 +8,11 @@ const fixtures = { }, ], ignoreLastAmount: false, + ignoreLastAddress: false, }, exception: false, }, - 'Should throw an error when address is not provided': { + 'Should pass when last address is empty and ignore last address': { params: { outputs: [ { @@ -20,9 +21,23 @@ const fixtures = { }, ], ignoreLastAmount: false, + ignoreLastAddress: true, }, exception: false, }, + 'Should throw an error when not the last address is not provided': { + params: { + outputs: [ + { + address: '', + amount: '100', + }, + ], + ignoreLastAmount: false, + ignoreLastAddress: false, + }, + exception: true, + }, 'Should throw an error when address is invalid': { params: { outputs: [ @@ -32,6 +47,7 @@ const fixtures = { }, ], ignoreLastAmount: false, + ignoreLastAddress: false, }, exception: true, }, @@ -44,6 +60,7 @@ const fixtures = { }, ], ignoreLastAmount: false, + ignoreLastAddress: false, }, exception: true, }, @@ -56,6 +73,7 @@ const fixtures = { }, ], ignoreLastAmount: false, + ignoreLastAddress: false, }, exception: true, }, @@ -68,6 +86,7 @@ const fixtures = { }, ], ignoreLastAmount: false, + ignoreLastAddress: false, }, exception: true, }, @@ -80,6 +99,7 @@ const fixtures = { }, ], ignoreLastAmount: true, + ignoreLastAddress: false, }, exception: false, }, diff --git a/packages/neuron-ui/src/tests/validators/outputs/index.test.ts b/packages/neuron-ui/src/tests/validators/outputs/index.test.ts index 90c56798a0..4175e62fad 100644 --- a/packages/neuron-ui/src/tests/validators/outputs/index.test.ts +++ b/packages/neuron-ui/src/tests/validators/outputs/index.test.ts @@ -2,20 +2,24 @@ import { validateOutputs } from 'utils/validators' import fixtures from './fixtures' const fixtureTable: Fixture.Validator[] = Object.entries(fixtures).map( - ([title, { params, exception }]) => [title, [params.outputs, params.ignoreLastAmount], exception] + ([title, { params, exception }]) => [ + title, + [params.outputs, params.ignoreLastAmount, params.ignoreLastAddress], + exception, + ] ) describe(`Test outputs validator`, () => { - test.each(fixtureTable)(`%s`, (_title, [outputs, ignoreLastAmount], exception) => { + test.each(fixtureTable)(`%s`, (_title, [outputs, ignoreLastAmount, ignoreLastAddress], exception) => { expect.assertions(1) if (exception) { try { - validateOutputs(outputs, false, ignoreLastAmount) + validateOutputs(outputs, false, ignoreLastAmount, ignoreLastAddress) } catch (e) { expect(e).not.toBeUndefined() } } else { - expect(validateOutputs()).toBeTruthy() + expect(validateOutputs(outputs, false, ignoreLastAmount, ignoreLastAddress)).toBeTruthy() } }) }) diff --git a/packages/neuron-ui/src/utils/validators/outputs.ts b/packages/neuron-ui/src/utils/validators/outputs.ts index 3bed010e7e..09d6aad7ef 100644 --- a/packages/neuron-ui/src/utils/validators/outputs.ts +++ b/packages/neuron-ui/src/utils/validators/outputs.ts @@ -6,11 +6,12 @@ import validateAmountRange from './amountRange' export const validateOutputs = ( items: Readonly[]> = [], isMainnet: boolean = false, - ignoreLastAmount: boolean = false + ignoreLastAmount: boolean = false, + ignoreLastAddress: boolean = false ) => { for (let i = 0; i < items.length; i++) { try { - if (items[i].address) { + if (!!items[i].address || i !== items.length - 1 || !ignoreLastAddress) { validateAddress(items[i].address || '', isMainnet) } if (i !== items.length - 1 || !ignoreLastAmount) { From 6939a6b5c25a4f2478bc24b7bf2889406e73344f Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Tue, 14 Nov 2023 15:31:09 +0800 Subject: [PATCH 4/5] fix: Ignore last item when check the max button status --- .../neuron-ui/src/components/Send/index.tsx | 2 +- .../src/tests/validators/outputs/fixtures.ts | 22 +------------------ .../tests/validators/outputs/index.test.ts | 12 ++++------ .../neuron-ui/src/utils/validators/outputs.ts | 7 ++---- 4 files changed, 8 insertions(+), 35 deletions(-) diff --git a/packages/neuron-ui/src/components/Send/index.tsx b/packages/neuron-ui/src/components/Send/index.tsx index e9f253dea6..8632bd1209 100644 --- a/packages/neuron-ui/src/components/Send/index.tsx +++ b/packages/neuron-ui/src/components/Send/index.tsx @@ -150,7 +150,7 @@ const Send = () => { const isMaxBtnDisabled = (() => { try { - validateOutputs(outputs, isMainnet, true, true) + validateOutputs(outputs.slice(0, -1), isMainnet) } catch { return true } diff --git a/packages/neuron-ui/src/tests/validators/outputs/fixtures.ts b/packages/neuron-ui/src/tests/validators/outputs/fixtures.ts index 4e02577491..5a3edb2fe3 100644 --- a/packages/neuron-ui/src/tests/validators/outputs/fixtures.ts +++ b/packages/neuron-ui/src/tests/validators/outputs/fixtures.ts @@ -8,11 +8,10 @@ const fixtures = { }, ], ignoreLastAmount: false, - ignoreLastAddress: false, }, exception: false, }, - 'Should pass when last address is empty and ignore last address': { + 'Should throw an error when address is not provided': { params: { outputs: [ { @@ -21,20 +20,6 @@ const fixtures = { }, ], ignoreLastAmount: false, - ignoreLastAddress: true, - }, - exception: false, - }, - 'Should throw an error when not the last address is not provided': { - params: { - outputs: [ - { - address: '', - amount: '100', - }, - ], - ignoreLastAmount: false, - ignoreLastAddress: false, }, exception: true, }, @@ -47,7 +32,6 @@ const fixtures = { }, ], ignoreLastAmount: false, - ignoreLastAddress: false, }, exception: true, }, @@ -60,7 +44,6 @@ const fixtures = { }, ], ignoreLastAmount: false, - ignoreLastAddress: false, }, exception: true, }, @@ -73,7 +56,6 @@ const fixtures = { }, ], ignoreLastAmount: false, - ignoreLastAddress: false, }, exception: true, }, @@ -86,7 +68,6 @@ const fixtures = { }, ], ignoreLastAmount: false, - ignoreLastAddress: false, }, exception: true, }, @@ -99,7 +80,6 @@ const fixtures = { }, ], ignoreLastAmount: true, - ignoreLastAddress: false, }, exception: false, }, diff --git a/packages/neuron-ui/src/tests/validators/outputs/index.test.ts b/packages/neuron-ui/src/tests/validators/outputs/index.test.ts index 4175e62fad..8c9827c364 100644 --- a/packages/neuron-ui/src/tests/validators/outputs/index.test.ts +++ b/packages/neuron-ui/src/tests/validators/outputs/index.test.ts @@ -2,24 +2,20 @@ import { validateOutputs } from 'utils/validators' import fixtures from './fixtures' const fixtureTable: Fixture.Validator[] = Object.entries(fixtures).map( - ([title, { params, exception }]) => [ - title, - [params.outputs, params.ignoreLastAmount, params.ignoreLastAddress], - exception, - ] + ([title, { params, exception }]) => [title, [params.outputs, params.ignoreLastAmount], exception] ) describe(`Test outputs validator`, () => { - test.each(fixtureTable)(`%s`, (_title, [outputs, ignoreLastAmount, ignoreLastAddress], exception) => { + test.each(fixtureTable)(`%s`, (_title, [outputs, ignoreLastAmount], exception) => { expect.assertions(1) if (exception) { try { - validateOutputs(outputs, false, ignoreLastAmount, ignoreLastAddress) + validateOutputs(outputs, false, ignoreLastAmount) } catch (e) { expect(e).not.toBeUndefined() } } else { - expect(validateOutputs(outputs, false, ignoreLastAmount, ignoreLastAddress)).toBeTruthy() + expect(validateOutputs(outputs, false, ignoreLastAmount)).toBeTruthy() } }) }) diff --git a/packages/neuron-ui/src/utils/validators/outputs.ts b/packages/neuron-ui/src/utils/validators/outputs.ts index 09d6aad7ef..7e96e2a567 100644 --- a/packages/neuron-ui/src/utils/validators/outputs.ts +++ b/packages/neuron-ui/src/utils/validators/outputs.ts @@ -6,14 +6,11 @@ import validateAmountRange from './amountRange' export const validateOutputs = ( items: Readonly[]> = [], isMainnet: boolean = false, - ignoreLastAmount: boolean = false, - ignoreLastAddress: boolean = false + ignoreLastAmount: boolean = false ) => { for (let i = 0; i < items.length; i++) { try { - if (!!items[i].address || i !== items.length - 1 || !ignoreLastAddress) { - validateAddress(items[i].address || '', isMainnet) - } + validateAddress(items[i].address || '', isMainnet) if (i !== items.length - 1 || !ignoreLastAmount) { validateAmount(items[i].amount) From d512d50b470ec21e6bb25a8c053bcd8854323fe1 Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Thu, 16 Nov 2023 13:49:38 +0800 Subject: [PATCH 5/5] fix: Change max to reset when is sending max. --- packages/neuron-ui/src/components/SendFieldset/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/neuron-ui/src/components/SendFieldset/index.tsx b/packages/neuron-ui/src/components/SendFieldset/index.tsx index 936097785c..cdbf2b0f23 100644 --- a/packages/neuron-ui/src/components/SendFieldset/index.tsx +++ b/packages/neuron-ui/src/components/SendFieldset/index.tsx @@ -112,11 +112,11 @@ const SendFieldset = ({ value={item.amount ? localNumberFormatter(item.amount) : ''} placeholder={t('send.input-amount')} onChange={onItemChange} - disabled={item.disabled} + disabled={item.disabled || isSendMax} suffix={ isMaxBtnShow && ( ) }