Skip to content

Commit eb7c83b

Browse files
devchenyanKeith-CY
andauthored
fix: Offline multisig with complex transaction (nervosnetwork#3291)
* fix: complex transaction * fix: check * fix: comment * fix * fix --------- Co-authored-by: Chen Yu <[email protected]>
1 parent a73282e commit eb7c83b

File tree

9 files changed

+104
-2
lines changed

9 files changed

+104
-2
lines changed

packages/neuron-wallet/src/exceptions/multisig.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export class MultisigConfigAddressError extends Error {
2525
}
2626

2727
export class MultisigConfigNeedError extends Error {
28+
public code = 502
2829
constructor() {
2930
super(t('messages.multisig-config-need-error'))
3031
}

packages/neuron-wallet/src/locales/ar.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,13 @@ export default {
221221
cancel: 'إلغاء',
222222
},
223223
},
224+
'unrecognized-lock-script': {
225+
message: 'تم العثور على نص قفل غير معرّف في هذه المعاملة، يرجى التحقق.',
226+
buttons: {
227+
cancel: 'إلغاء',
228+
ignore: 'تجاهل واستمرار',
229+
},
230+
},
224231
},
225232
prompt: {
226233
password: {

packages/neuron-wallet/src/locales/en.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,13 @@ export default {
223223
cancel: 'Cancel',
224224
},
225225
},
226+
'unrecognized-lock-script': {
227+
message: 'An unrecognized lock script was found in this transaction, please check it.',
228+
buttons: {
229+
cancel: 'Cancel',
230+
ignore: 'Ignore and continue',
231+
},
232+
},
226233
},
227234
prompt: {
228235
password: {

packages/neuron-wallet/src/locales/es.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@ export default {
226226
cancel: 'Cancelar',
227227
},
228228
},
229+
'unrecognized-lock-script': {
230+
message: 'Se encontró un script de bloqueo no reconocido en esta transacción, por favor verifíquelo.',
231+
buttons: {
232+
cancel: 'Cancelar',
233+
ignore: 'Ignorar y continuar',
234+
},
235+
},
229236
},
230237
prompt: {
231238
password: {

packages/neuron-wallet/src/locales/fr.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,13 @@ export default {
227227
cancel: 'Annuler',
228228
},
229229
},
230+
'unrecognized-lock-script': {
231+
message: 'Un script de verrouillage non reconnu a été trouvé dans cette transaction, veuillez vérifier.',
232+
buttons: {
233+
cancel: 'Annuler',
234+
ignore: 'Ignorer et continuer',
235+
},
236+
},
230237
},
231238
prompt: {
232239
password: {

packages/neuron-wallet/src/locales/zh-tw.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,13 @@ export default {
209209
cancel: '取消',
210210
},
211211
},
212+
'unrecognized-lock-script': {
213+
message: '在此交易中發現了一個未識別的lock script,請檢查。',
214+
buttons: {
215+
cancel: '取消',
216+
ignore: '忽略並繼續',
217+
},
218+
},
212219
},
213220
prompt: {
214221
password: {

packages/neuron-wallet/src/locales/zh.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,13 @@ export default {
210210
cancel: '取消',
211211
},
212212
},
213+
'unrecognized-lock-script': {
214+
message: '在此交易中发现了一个未识别的lock script,请检查。',
215+
buttons: {
216+
cancel: '取消',
217+
ignore: '忽略并继续',
218+
},
219+
},
213220
},
214221
prompt: {
215222
password: {

packages/neuron-wallet/src/services/transaction-sender.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { t } from 'i18next'
2+
import { dialog } from 'electron'
13
import { serializeWitnessArgs } from '../utils/serialization'
24
import { scriptToAddress } from '../utils/scriptAndAddress'
35
import { TargetOutput, TransactionGenerator, TransactionPersistor } from './tx'
@@ -198,7 +200,27 @@ export default class TransactionSender {
198200
// A 65-byte empty signature used as placeholder
199201
witnessesArgs[0].witnessArgs.setEmptyLock()
200202

201-
const privateKey = findPrivateKey(witnessesArgs[0].lockArgs)
203+
let privateKey = ''
204+
try {
205+
privateKey = findPrivateKey(witnessesArgs[0].lockArgs)
206+
} catch (error) {
207+
const BLOCK_UNRECOGNIZED = 0
208+
const IGNORE_UNRECOGNIZED_AND_CONTINUE = 1
209+
const res = await dialog.showMessageBox({
210+
type: 'warning',
211+
message: t('messageBox.unrecognized-lock-script.message'),
212+
buttons: [
213+
t('messageBox.unrecognized-lock-script.buttons.cancel'),
214+
t('messageBox.unrecognized-lock-script.buttons.ignore'),
215+
],
216+
defaultId: BLOCK_UNRECOGNIZED,
217+
cancelId: IGNORE_UNRECOGNIZED_AND_CONTINUE,
218+
})
219+
if (res.response === IGNORE_UNRECOGNIZED_AND_CONTINUE) {
220+
continue
221+
}
222+
throw error
223+
}
202224

203225
const serializedWitnesses: (WitnessArgs | string)[] = witnessesArgs.map((value: SignInfo, index: number) => {
204226
const args = value.witnessArgs
@@ -330,6 +352,21 @@ export default class TransactionSender {
330352
for (const lockHash of lockHashes) {
331353
const multisigConfig = multisigConfigMap[lockHash]
332354
if (!multisigConfig) {
355+
const BLOCK_UNRECOGNIZED = 0
356+
const IGNORE_UNRECOGNIZED_AND_CONTINUE = 1
357+
const res = await dialog.showMessageBox({
358+
type: 'warning',
359+
message: t('messageBox.unrecognized-lock-script.message'),
360+
buttons: [
361+
t('messageBox.unrecognized-lock-script.buttons.cancel'),
362+
t('messageBox.unrecognized-lock-script.buttons.ignore'),
363+
],
364+
defaultId: BLOCK_UNRECOGNIZED,
365+
cancelId: IGNORE_UNRECOGNIZED_AND_CONTINUE,
366+
})
367+
if (res.response === IGNORE_UNRECOGNIZED_AND_CONTINUE) {
368+
continue
369+
}
333370
throw new MultisigConfigNeedError()
334371
}
335372
const [privateKey, blake160] = findPrivateKeyAndBlake160(multisigConfig.blake160s, tx.signatures?.[lockHash])

packages/neuron-wallet/tests/services/tx/transaction-sender.test.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { dialog } from 'electron'
12
import { CKBComponents } from '@ckb-lumos/lumos/rpc'
23
import { bytes } from '@ckb-lumos/lumos/codec'
34
import 'dotenv/config'
@@ -181,6 +182,12 @@ jest.doMock('services/cells', () => ({
181182
getLiveCell: stubbedGetLiveCell,
182183
}))
183184

185+
jest.mock('electron', () => ({
186+
dialog: {
187+
showMessageBox: jest.fn(),
188+
},
189+
}))
190+
184191
import Transaction from '../../../src/models/chain/transaction'
185192
import TxStatus from '../../../src/models/chain/tx-status'
186193
import CellDep, { DepType } from '../../../src/models/chain/cell-dep'
@@ -1001,13 +1008,28 @@ describe('TransactionSender Test', () => {
10011008
})
10021009
})
10031010

1004-
it('throw exception no matched multisig config', async () => {
1011+
it('no matched multisig config, ignore and continue', async () => {
1012+
const showMessageBoxMock = jest
1013+
.spyOn(dialog, 'showMessageBox')
1014+
.mockImplementation(() => Promise.resolve({ response: 1, checkboxChecked: true }))
1015+
mockGAI.mockReturnValueOnce([{ path: '' }])
1016+
transactionSender.getAddressInfos = mockGAI.bind(transactionSender)
1017+
const tx = Transaction.fromObject(transactionObject)
1018+
await expect(transactionSender.signMultisig(fakeWallet.id, tx, '1234', [])).resolves.not.toThrow()
1019+
expect(showMessageBoxMock).toHaveBeenCalled()
1020+
})
1021+
1022+
it('no matched multisig config, throw exception', async () => {
1023+
const showMessageBoxMock = jest
1024+
.spyOn(dialog, 'showMessageBox')
1025+
.mockImplementation(() => Promise.resolve({ response: 0, checkboxChecked: false }))
10051026
mockGAI.mockReturnValueOnce([{ path: '' }])
10061027
transactionSender.getAddressInfos = mockGAI.bind(transactionSender)
10071028
const tx = Transaction.fromObject(transactionObject)
10081029
await expect(transactionSender.signMultisig(fakeWallet.id, tx, '1234', [])).rejects.toThrowError(
10091030
new MultisigConfigNeedError()
10101031
)
1032+
expect(showMessageBoxMock).toHaveBeenCalled()
10111033
})
10121034

10131035
it('throw exception no matched multisig config addresses', async () => {

0 commit comments

Comments
 (0)