From ad3592c15bdac3f4726d6667e82ce4be5cef0f9d Mon Sep 17 00:00:00 2001 From: devchenyan Date: Mon, 6 Jan 2025 00:37:58 +0800 Subject: [PATCH 1/5] fix: complex transaction --- .../neuron-wallet/src/exceptions/multisig.ts | 1 + packages/neuron-wallet/src/locales/ar.ts | 7 ++++++ packages/neuron-wallet/src/locales/en.ts | 7 ++++++ packages/neuron-wallet/src/locales/es.ts | 7 ++++++ packages/neuron-wallet/src/locales/fr.ts | 7 ++++++ packages/neuron-wallet/src/locales/zh-tw.ts | 7 ++++++ packages/neuron-wallet/src/locales/zh.ts | 7 ++++++ .../src/services/transaction-sender.ts | 15 ++++++++++++ .../services/tx/transaction-sender.test.ts | 24 ++++++++++++++++++- 9 files changed, 81 insertions(+), 1 deletion(-) diff --git a/packages/neuron-wallet/src/exceptions/multisig.ts b/packages/neuron-wallet/src/exceptions/multisig.ts index 5eef3e0dfd..5afb135b1c 100644 --- a/packages/neuron-wallet/src/exceptions/multisig.ts +++ b/packages/neuron-wallet/src/exceptions/multisig.ts @@ -25,6 +25,7 @@ export class MultisigConfigAddressError extends Error { } export class MultisigConfigNeedError extends Error { + public code = 502 constructor() { super(t('messages.multisig-config-need-error')) } diff --git a/packages/neuron-wallet/src/locales/ar.ts b/packages/neuron-wallet/src/locales/ar.ts index f72a67161d..2f00419a5c 100644 --- a/packages/neuron-wallet/src/locales/ar.ts +++ b/packages/neuron-wallet/src/locales/ar.ts @@ -221,6 +221,13 @@ export default { cancel: 'إلغاء', }, }, + 'unrecognized-lock-script': { + message: 'تم العثور على نص قفل غير معرّف في هذه المعاملة، يرجى التحقق.', + buttons: { + cancel: 'إلغاء', + ignore: 'تجاهل واستمرار', + }, + }, }, prompt: { password: { diff --git a/packages/neuron-wallet/src/locales/en.ts b/packages/neuron-wallet/src/locales/en.ts index fec1bc382c..374f3140ad 100644 --- a/packages/neuron-wallet/src/locales/en.ts +++ b/packages/neuron-wallet/src/locales/en.ts @@ -223,6 +223,13 @@ export default { cancel: 'Cancel', }, }, + 'unrecognized-lock-script': { + message: 'An unrecognized lock script was found in this transaction, please check it.', + buttons: { + cancel: 'Cancel', + ignore: 'Ignpre and continue', + }, + }, }, prompt: { password: { diff --git a/packages/neuron-wallet/src/locales/es.ts b/packages/neuron-wallet/src/locales/es.ts index 9d70452efd..6c6855becd 100644 --- a/packages/neuron-wallet/src/locales/es.ts +++ b/packages/neuron-wallet/src/locales/es.ts @@ -226,6 +226,13 @@ export default { cancel: 'Cancelar', }, }, + 'unrecognized-lock-script': { + message: 'Se encontró un script de bloqueo no reconocido en esta transacción, por favor verifíquelo.', + buttons: { + cancel: 'Cancelar', + ignore: 'Ignorar y continuar', + }, + }, }, prompt: { password: { diff --git a/packages/neuron-wallet/src/locales/fr.ts b/packages/neuron-wallet/src/locales/fr.ts index 58e11e3d3a..c87442f556 100644 --- a/packages/neuron-wallet/src/locales/fr.ts +++ b/packages/neuron-wallet/src/locales/fr.ts @@ -227,6 +227,13 @@ export default { cancel: 'Annuler', }, }, + 'unrecognized-lock-script': { + message: 'Un script de verrouillage non reconnu a été trouvé dans cette transaction, veuillez vérifier.', + buttons: { + cancel: 'Annuler', + ignore: 'Ignorer et continuer', + }, + }, }, prompt: { password: { diff --git a/packages/neuron-wallet/src/locales/zh-tw.ts b/packages/neuron-wallet/src/locales/zh-tw.ts index cc75c175f4..7567c2f8d3 100644 --- a/packages/neuron-wallet/src/locales/zh-tw.ts +++ b/packages/neuron-wallet/src/locales/zh-tw.ts @@ -209,6 +209,13 @@ export default { cancel: '取消', }, }, + 'unrecognized-lock-script': { + message: '在此交易中發現了一個未識別的lock script,請檢查。', + buttons: { + cancel: '取消', + ignore: '忽略並繼續', + }, + }, }, prompt: { password: { diff --git a/packages/neuron-wallet/src/locales/zh.ts b/packages/neuron-wallet/src/locales/zh.ts index 5200e52497..52b09f1210 100644 --- a/packages/neuron-wallet/src/locales/zh.ts +++ b/packages/neuron-wallet/src/locales/zh.ts @@ -210,6 +210,13 @@ export default { cancel: '取消', }, }, + 'unrecognized-lock-script': { + message: '在此交易中发现了一个未识别的lock script,请检查。', + buttons: { + cancel: '取消', + ignore: '忽略并继续', + }, + }, }, prompt: { password: { diff --git a/packages/neuron-wallet/src/services/transaction-sender.ts b/packages/neuron-wallet/src/services/transaction-sender.ts index ebe753e0c1..d413f90fdb 100644 --- a/packages/neuron-wallet/src/services/transaction-sender.ts +++ b/packages/neuron-wallet/src/services/transaction-sender.ts @@ -1,3 +1,5 @@ +import { t } from 'i18next' +import { dialog } from 'electron' import { serializeWitnessArgs } from '../utils/serialization' import { scriptToAddress } from '../utils/scriptAndAddress' import { TargetOutput, TransactionGenerator, TransactionPersistor } from './tx' @@ -330,6 +332,19 @@ export default class TransactionSender { for (const lockHash of lockHashes) { const multisigConfig = multisigConfigMap[lockHash] if (!multisigConfig) { + const res = await dialog.showMessageBox({ + type: 'warning', + message: t('messageBox.unrecognized-lock-script.message'), + buttons: [ + t('messageBox.unrecognized-lock-script.buttons.cancel'), + t('messageBox.unrecognized-lock-script.buttons.ignore'), + ], + defaultId: 0, + cancelId: 1, + }) + if (res.response === 1) { + continue + } throw new MultisigConfigNeedError() } const [privateKey, blake160] = findPrivateKeyAndBlake160(multisigConfig.blake160s, tx.signatures?.[lockHash]) diff --git a/packages/neuron-wallet/tests/services/tx/transaction-sender.test.ts b/packages/neuron-wallet/tests/services/tx/transaction-sender.test.ts index eaf1894650..b73ae330ed 100644 --- a/packages/neuron-wallet/tests/services/tx/transaction-sender.test.ts +++ b/packages/neuron-wallet/tests/services/tx/transaction-sender.test.ts @@ -1,3 +1,4 @@ +import { dialog } from 'electron' import { CKBComponents } from '@ckb-lumos/lumos/rpc' import { bytes } from '@ckb-lumos/lumos/codec' import 'dotenv/config' @@ -181,6 +182,12 @@ jest.doMock('services/cells', () => ({ getLiveCell: stubbedGetLiveCell, })) +jest.mock('electron', () => ({ + dialog: { + showMessageBox: jest.fn(), + }, +})) + import Transaction from '../../../src/models/chain/transaction' import TxStatus from '../../../src/models/chain/tx-status' import CellDep, { DepType } from '../../../src/models/chain/cell-dep' @@ -1001,13 +1008,28 @@ describe('TransactionSender Test', () => { }) }) - it('throw exception no matched multisig config', async () => { + it('no matched multisig config, ignore and continue', async () => { + const showMessageBoxMock = jest + .spyOn(dialog, 'showMessageBox') + .mockImplementation(() => Promise.resolve({ response: 1, checkboxChecked: true })) + mockGAI.mockReturnValueOnce([{ path: '' }]) + transactionSender.getAddressInfos = mockGAI.bind(transactionSender) + const tx = Transaction.fromObject(transactionObject) + await expect(transactionSender.signMultisig(fakeWallet.id, tx, '1234', [])).resolves.not.toThrow() + expect(showMessageBoxMock).toHaveBeenCalled() + }) + + it('no matched multisig config, throw exception', async () => { + const showMessageBoxMock = jest + .spyOn(dialog, 'showMessageBox') + .mockImplementation(() => Promise.resolve({ response: 0, checkboxChecked: false })) mockGAI.mockReturnValueOnce([{ path: '' }]) transactionSender.getAddressInfos = mockGAI.bind(transactionSender) const tx = Transaction.fromObject(transactionObject) await expect(transactionSender.signMultisig(fakeWallet.id, tx, '1234', [])).rejects.toThrowError( new MultisigConfigNeedError() ) + expect(showMessageBoxMock).toHaveBeenCalled() }) it('throw exception no matched multisig config addresses', async () => { From 320729d238c5d360a55d229155e16fdfe0e347f7 Mon Sep 17 00:00:00 2001 From: devchenyan Date: Mon, 6 Jan 2025 00:41:44 +0800 Subject: [PATCH 2/5] fix: check --- .../src/utils/hooks/useGetCountDownAndFeeRateStats.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/neuron-ui/src/utils/hooks/useGetCountDownAndFeeRateStats.ts b/packages/neuron-ui/src/utils/hooks/useGetCountDownAndFeeRateStats.ts index fa6f181910..ac25ab7690 100644 --- a/packages/neuron-ui/src/utils/hooks/useGetCountDownAndFeeRateStats.ts +++ b/packages/neuron-ui/src/utils/hooks/useGetCountDownAndFeeRateStats.ts @@ -15,7 +15,7 @@ const useGetCountDownAndFeeRateStats = ({ seconds = 30, interval = 1000 }: Count suggestFeeRate: number }>({ suggestFeeRate: MEDIUM_FEE_RATE }) - const handleGetFeeRateStatis = useCallback(() => { + const handleGetFeeRateStatistics = useCallback(() => { getFeeRateStatistics() .then(res => { const { median } = res ?? {} @@ -50,7 +50,7 @@ const useGetCountDownAndFeeRateStats = ({ seconds = 30, interval = 1000 }: Count useEffect(() => { if (countDown === seconds) { - handleGetFeeRateStatis() + handleGetFeeRateStatistics() } }, [countDown, seconds]) From 500c21bd894e5ca1e477642447e0fdd9e86cb2c7 Mon Sep 17 00:00:00 2001 From: devchenyan Date: Sat, 11 Jan 2025 21:17:19 +0800 Subject: [PATCH 3/5] fix: comment --- packages/neuron-wallet/src/services/transaction-sender.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/neuron-wallet/src/services/transaction-sender.ts b/packages/neuron-wallet/src/services/transaction-sender.ts index d413f90fdb..458b4c3eba 100644 --- a/packages/neuron-wallet/src/services/transaction-sender.ts +++ b/packages/neuron-wallet/src/services/transaction-sender.ts @@ -332,6 +332,8 @@ export default class TransactionSender { for (const lockHash of lockHashes) { const multisigConfig = multisigConfigMap[lockHash] if (!multisigConfig) { + const BLOCK_UNRECOGNIZED = 0 + const IGNORE_UNRECOGNIZED_AND_CONTINUE = 1 const res = await dialog.showMessageBox({ type: 'warning', message: t('messageBox.unrecognized-lock-script.message'), @@ -339,10 +341,10 @@ export default class TransactionSender { t('messageBox.unrecognized-lock-script.buttons.cancel'), t('messageBox.unrecognized-lock-script.buttons.ignore'), ], - defaultId: 0, - cancelId: 1, + defaultId: BLOCK_UNRECOGNIZED, + cancelId: IGNORE_UNRECOGNIZED_AND_CONTINUE, }) - if (res.response === 1) { + if (res.response === IGNORE_UNRECOGNIZED_AND_CONTINUE) { continue } throw new MultisigConfigNeedError() From a89b0649923c13a185a3a79211d5f2a17ababc17 Mon Sep 17 00:00:00 2001 From: devchenyan Date: Thu, 23 Jan 2025 14:10:35 +0800 Subject: [PATCH 4/5] fix --- .../src/services/transaction-sender.ts | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/neuron-wallet/src/services/transaction-sender.ts b/packages/neuron-wallet/src/services/transaction-sender.ts index 458b4c3eba..df98b06acc 100644 --- a/packages/neuron-wallet/src/services/transaction-sender.ts +++ b/packages/neuron-wallet/src/services/transaction-sender.ts @@ -200,7 +200,27 @@ export default class TransactionSender { // A 65-byte empty signature used as placeholder witnessesArgs[0].witnessArgs.setEmptyLock() - const privateKey = findPrivateKey(witnessesArgs[0].lockArgs) + let privateKey = '' + try { + privateKey = findPrivateKey(witnessesArgs[0].lockArgs) + } catch (error) { + const BLOCK_UNRECOGNIZED = 0 + const IGNORE_UNRECOGNIZED_AND_CONTINUE = 1 + const res = await dialog.showMessageBox({ + type: 'warning', + message: t('messageBox.unrecognized-lock-script.message'), + buttons: [ + t('messageBox.unrecognized-lock-script.buttons.cancel'), + t('messageBox.unrecognized-lock-script.buttons.ignore'), + ], + defaultId: BLOCK_UNRECOGNIZED, + cancelId: IGNORE_UNRECOGNIZED_AND_CONTINUE, + }) + if (res.response === IGNORE_UNRECOGNIZED_AND_CONTINUE) { + continue + } + throw error + } const serializedWitnesses: (WitnessArgs | string)[] = witnessesArgs.map((value: SignInfo, index: number) => { const args = value.witnessArgs From c787f896793611b52c2729809f97ffef88029760 Mon Sep 17 00:00:00 2001 From: devchenyan Date: Sun, 26 Jan 2025 11:08:00 +0800 Subject: [PATCH 5/5] fix --- packages/neuron-wallet/src/locales/en.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/neuron-wallet/src/locales/en.ts b/packages/neuron-wallet/src/locales/en.ts index 374f3140ad..82e3b7d27c 100644 --- a/packages/neuron-wallet/src/locales/en.ts +++ b/packages/neuron-wallet/src/locales/en.ts @@ -227,7 +227,7 @@ export default { message: 'An unrecognized lock script was found in this transaction, please check it.', buttons: { cancel: 'Cancel', - ignore: 'Ignpre and continue', + ignore: 'Ignore and continue', }, }, },