From 6e70c94ce1eccbb0409ead1d787095ba32953a61 Mon Sep 17 00:00:00 2001 From: devchenyan Date: Thu, 13 Mar 2025 21:03:07 +0800 Subject: [PATCH 1/6] fix: Manage Nervos DAO with multisig address --- .../src/components/MultisigAddress/index.tsx | 34 ++++++++++- packages/neuron-ui/src/locales/ar.json | 2 + packages/neuron-ui/src/locales/en.json | 2 + packages/neuron-ui/src/locales/es.json | 2 + packages/neuron-ui/src/locales/fr.json | 2 + packages/neuron-ui/src/locales/zh-tw.json | 2 + packages/neuron-ui/src/locales/zh.json | 2 + packages/neuron-wallet/src/services/cells.ts | 23 +------- .../neuron-wallet/src/services/multisig.ts | 59 ++++++++++++++++--- packages/neuron-wallet/src/utils/const.ts | 1 + 10 files changed, 97 insertions(+), 32 deletions(-) diff --git a/packages/neuron-ui/src/components/MultisigAddress/index.tsx b/packages/neuron-ui/src/components/MultisigAddress/index.tsx index c586003db0..f8defd8bf0 100644 --- a/packages/neuron-ui/src/components/MultisigAddress/index.tsx +++ b/packages/neuron-ui/src/components/MultisigAddress/index.tsx @@ -204,6 +204,25 @@ const MultisigAddress = () => { [listActionOptions] ) + const daoDisabledMessage = useMemo(() => { + if (wallet.device) { + if ( + (daoDepositAction.depositFromMultisig && daoDepositAction.isDialogOpen) || + (daoWithdrawAction.withdrawFromMultisig && daoWithdrawAction.isDialogOpen) + ) { + const multisigConfig = daoDepositAction.depositFromMultisig || daoWithdrawAction.withdrawFromMultisig + if (!multisigConfig) return '' + const { canSign } = getMultisigSignStatus({ + multisigConfig, + addresses, + }) + + return canSign ? 'dao-ledger-notice' : 'dao-hardware-not-match' + } + } + return '' + }, [daoDepositAction, daoWithdrawAction, wallet.device, addresses]) + const { keywords, onChange, onBlur } = useSearch(clearSelected, onFilterConfig) const sendTotalBalance = useMemo(() => { @@ -584,7 +603,7 @@ const MultisigAddress = () => { /> ) : null} - {daoDepositAction.depositFromMultisig && daoDepositAction.isDialogOpen ? ( + {!daoDisabledMessage && daoDepositAction.depositFromMultisig && daoDepositAction.isDialogOpen ? ( { /> ) : null} - {daoWithdrawAction.withdrawFromMultisig && daoWithdrawAction.isDialogOpen ? ( + {!daoDisabledMessage && daoWithdrawAction.withdrawFromMultisig && daoWithdrawAction.isDialogOpen ? ( ) : null} + + { + daoDepositAction.closeDialog() + daoWithdrawAction.closeDialog() + }} + /> ) } diff --git a/packages/neuron-ui/src/locales/ar.json b/packages/neuron-ui/src/locales/ar.json index 6e979ac5df..c0891e05be 100644 --- a/packages/neuron-ui/src/locales/ar.json +++ b/packages/neuron-ui/src/locales/ar.json @@ -1171,6 +1171,8 @@ "daoWithdraw": "سحب من DAO" } }, + "dao-ledger-notice": "تدعم محافظ Ledger حاليًا توقيع معاملات DAO فقط، ولا تدعم بدء الإيداعات أو السحوبات. يرجى التحقق من التحديثات المستقبلية.", + "dao-hardware-not-match": "المحفظة الصلبة المتصلة حاليًا لا تتطابق مع المحفظة الحالية.", "import-dialog": { "actions": { "cancel": "إلغاء", diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json index d943e24dcc..62856f24c0 100644 --- a/packages/neuron-ui/src/locales/en.json +++ b/packages/neuron-ui/src/locales/en.json @@ -1171,6 +1171,8 @@ "daoWithdraw": "DAO Withdraw" } }, + "dao-ledger-notice": "Ledger wallets currently support only signing DAO transactions, not initiating deposits or withdrawals. Please check back for future updates.", + "dao-hardware-not-match": "The hardware wallet currently connected does not match the current wallet.", "import-dialog": { "actions": { "cancel": "Cancel", diff --git a/packages/neuron-ui/src/locales/es.json b/packages/neuron-ui/src/locales/es.json index 38179b3161..a06a1d2c55 100644 --- a/packages/neuron-ui/src/locales/es.json +++ b/packages/neuron-ui/src/locales/es.json @@ -1154,6 +1154,8 @@ "daoWithdraw": "Retirar de DAO" } }, + "dao-ledger-notice": "Las billeteras Ledger actualmente solo admiten la firma de transacciones DAO, no la iniciación de depósitos o retiros. Vuelva a consultar para futuras actualizaciones.", + "dao-hardware-not-match": "La billetera de hardware conectada actualmente no coincide con la billetera actual.", "import-dialog": { "actions": { "cancel": "Cancelar", diff --git a/packages/neuron-ui/src/locales/fr.json b/packages/neuron-ui/src/locales/fr.json index 31e566bc62..02cddfdf75 100644 --- a/packages/neuron-ui/src/locales/fr.json +++ b/packages/neuron-ui/src/locales/fr.json @@ -1161,6 +1161,8 @@ "daoWithdraw": "Retirer de DAO" } }, + "dao-ledger-notice": "Les portefeuilles Ledger prennent actuellement en charge uniquement la signature des transactions DAO, mais pas l’initiation des dépôts ou des retraits. Veuillez vérifier les mises à jour futures.", + "dao-hardware-not-match": "Le portefeuille matériel actuellement connecté ne correspond pas au portefeuille actuel.", "import-dialog": { "actions": { "cancel": "Annuler", diff --git a/packages/neuron-ui/src/locales/zh-tw.json b/packages/neuron-ui/src/locales/zh-tw.json index 8018cb5f86..f254fc07aa 100644 --- a/packages/neuron-ui/src/locales/zh-tw.json +++ b/packages/neuron-ui/src/locales/zh-tw.json @@ -1164,6 +1164,8 @@ "daoWithdraw": "從 DAO 取出" } }, + "dao-ledger-notice": "Ledger 錢包目前僅支援簽署 DAO 交易,無法發起存款或提取。請關注未來的更新。", + "dao-hardware-not-match": "當前連接的硬體錢包與當前錢包不匹配。", "import-dialog": { "actions": { "cancel": "取消", diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json index 9b958cde38..04414759a7 100644 --- a/packages/neuron-ui/src/locales/zh.json +++ b/packages/neuron-ui/src/locales/zh.json @@ -1163,6 +1163,8 @@ "daoWithdraw": "从 DAO 取出" } }, + "dao-ledger-notice": "Ledger 钱包目前仅支持签署 DAO 交易,无法发起存款或提取。请关注未来的更新。", + "dao-hardware-not-match": "当前连接的硬件钱包与当前钱包不匹配。", "import-dialog": { "actions": { "cancel": "取消", diff --git a/packages/neuron-wallet/src/services/cells.ts b/packages/neuron-wallet/src/services/cells.ts index 235648ef46..fae732840e 100644 --- a/packages/neuron-wallet/src/services/cells.ts +++ b/packages/neuron-wallet/src/services/cells.ts @@ -1321,15 +1321,6 @@ export default class CellsService { return {} } const lockHashes = multisigAddresses.map(v => scriptToHash(addressToScript(v))) - - const outputs = await getConnection() - .getRepository(OutputEntity) - .createQueryBuilder('output') - .where('output.lockHash IN (:...lockHashes)', { lockHashes }) - .andWhere('output.hasData = :hasData', { hasData: true }) - .andWhere('output.typeHash IS NOT NULL') - .getMany() - const connection = await getConnection() const [sql, parameters] = connection.driver.escapeQueryWithParameters( ` @@ -1345,7 +1336,7 @@ export default class CellsService { `, { lockHashes, - statuses: [OutputStatus.Live, OutputStatus.Sent], + statuses: [OutputStatus.Live], }, {} ) @@ -1369,18 +1360,6 @@ export default class CellsService { ] = c.balance }) - outputs.forEach(item => { - const key = scriptToAddress( - { - args: item.lockArgs, - codeHash: SystemScriptInfo.MULTI_SIGN_CODE_HASH, - hashType: SystemScriptInfo.MULTI_SIGN_HASH_TYPE, - }, - isMainnet - ) - balances[key] = (BigInt(balances[key]) - BigInt(item.capacity)).toString() - }) - return balances } diff --git a/packages/neuron-wallet/src/services/multisig.ts b/packages/neuron-wallet/src/services/multisig.ts index a2baccd5ee..22bd92ce02 100644 --- a/packages/neuron-wallet/src/services/multisig.ts +++ b/packages/neuron-wallet/src/services/multisig.ts @@ -13,6 +13,12 @@ import Multisig from '../models/multisig' import SyncProgress, { SyncAddressType } from '../database/chain/entities/sync-progress' import { NetworkType } from '../models/network' import logger from '../utils/logger' +import { TransactionPersistor } from './tx' +import { DAO_DATA } from '../utils/const' +import RpcService from '../services/rpc-service' +import TransactionWithStatus from '../models/chain/transaction-with-status' +import TxStatus from '../models/chain/tx-status' +import SystemScriptInfo from '../models/system-script-info' const max64Int = '0x' + 'f'.repeat(16) export default class MultisigService { @@ -107,8 +113,8 @@ export default class MultisigService { }) } - static async getLiveCells(multisigConfigs: MultisigConfig[]) { - const liveCells: MultisigOutput[] = [] + static async getCells(multisigConfigs: MultisigConfig[]) { + const cells: any[] = [] const addressCursorMap: Map = new Map() let currentMultisigConfigs = MultisigService.removeDulpicateConfig(multisigConfigs) const network = NetworksService.getInstance().getCurrent() @@ -144,17 +150,18 @@ export default class MultisigService { const config = currentMultisigConfigs[idx] const script = Multisig.getMultisigScript(config.blake160s, config.r, config.m, config.n) addressCursorMap.set(script.args, v?.result?.last_cursor) - liveCells.push( - ...v.result.objects - .filter((object: any) => !object?.output?.type) - .map((object: any) => MultisigOutput.fromIndexer(object)) - ) + cells.push(...v.result.objects) nextMultisigConfigs.push(currentMultisigConfigs[idx]) } }) currentMultisigConfigs = nextMultisigConfigs } - return liveCells + return cells + } + + static async getLiveCells(multisigConfigs: MultisigConfig[]) { + const cells = await MultisigService.getCells(multisigConfigs) + return cells.filter((object: any) => !object?.output?.type).map((object: any) => MultisigOutput.fromIndexer(object)) } static async saveLiveMultisigOutput() { @@ -166,6 +173,41 @@ export default class MultisigService { } } + static async saveMultisigDaoTx(multisigConfigs: MultisigConfig[]) { + const cells = await MultisigService.getCells(multisigConfigs) + if (cells.length) { + const daoTxHash = new Set() + cells.forEach((cell: any) => { + if (cell?.output?.type?.code_hash === SystemScriptInfo.DAO_CODE_HASH) { + daoTxHash.add(cell.out_point.tx_hash) + } + }) + if (daoTxHash.size > 0) { + const network = NetworksService.getInstance().getCurrent() + const rpcService = new RpcService(network.remote, network.type) + for (const txHash of daoTxHash) { + const txWithStatus: TransactionWithStatus | undefined | { transaction: null; txStatus: TxStatus } = + await rpcService.getTransaction(txHash) + if (txWithStatus?.transaction) { + const tx = Transaction.fromSDK(txWithStatus.transaction) + tx.blockHash = txWithStatus.txStatus.blockHash || undefined + if (tx.blockHash) { + const header = await rpcService.getHeader(tx.blockHash) + tx.timestamp = header?.timestamp + tx.blockNumber = header?.number + } + tx.outputsData.forEach((item, index) => { + if (item === DAO_DATA) { + tx.outputs[index].daoData = DAO_DATA + } + }) + await TransactionPersistor.saveFetchTx(tx) + } + } + } + } + } + static async getMultisigTransactionHashList(multisigConfigs: MultisigConfig[]) { const multisigOutputTxHashList = new Set() const addressCursorMap: Map = new Map() @@ -302,6 +344,7 @@ export default class MultisigService { try { const multisigConfigs = await getConnection().getRepository(MultisigConfig).createQueryBuilder().getMany() await MultisigService.saveLiveMultisigOutput() + await MultisigService.saveMultisigDaoTx(multisigConfigs) await MultisigService.deleteDeadMultisigOutput(multisigConfigs) await MultisigService.saveMultisigSyncBlockNumber(multisigConfigs, lastestBlockNumber) MultisigOutputChangedSubject.getSubject().next('update') diff --git a/packages/neuron-wallet/src/utils/const.ts b/packages/neuron-wallet/src/utils/const.ts index 28ed3e21c6..25b9c5cd31 100644 --- a/packages/neuron-wallet/src/utils/const.ts +++ b/packages/neuron-wallet/src/utils/const.ts @@ -19,6 +19,7 @@ export const DEFAULT_ARGS_LENGTH = 42 export const LOCKTIME_ARGS_LENGTH = 58 export const CHEQUE_ARGS_LENGTH = 82 export const CKB_NODE_DATA_SIZE_BUFFER_RATIO = 1.2 +export const DAO_DATA = '0x0000000000000000' export enum ResponseCode { Fail, From eb20d1907b970a7222ade0af76370fdebe263458 Mon Sep 17 00:00:00 2001 From: chenyan Date: Fri, 14 Mar 2025 19:59:30 +0800 Subject: [PATCH 2/6] fix: comments --- .../src/components/MultisigAddress/index.tsx | 30 ++++++++++--------- .../src/components/WithdrawDialog/index.tsx | 2 +- .../WithdrawDialog/withdrawDialog.module.scss | 2 +- packages/neuron-ui/src/locales/ar.json | 2 +- packages/neuron-ui/src/locales/en.json | 2 +- packages/neuron-ui/src/locales/es.json | 2 +- packages/neuron-ui/src/locales/fr.json | 2 +- packages/neuron-ui/src/locales/zh-tw.json | 2 +- packages/neuron-ui/src/locales/zh.json | 2 +- .../neuron-wallet/src/services/multisig.ts | 8 ++--- 10 files changed, 28 insertions(+), 26 deletions(-) diff --git a/packages/neuron-ui/src/components/MultisigAddress/index.tsx b/packages/neuron-ui/src/components/MultisigAddress/index.tsx index f8defd8bf0..653a0f6d95 100644 --- a/packages/neuron-ui/src/components/MultisigAddress/index.tsx +++ b/packages/neuron-ui/src/components/MultisigAddress/index.tsx @@ -205,21 +205,23 @@ const MultisigAddress = () => { ) const daoDisabledMessage = useMemo(() => { - if (wallet.device) { - if ( - (daoDepositAction.depositFromMultisig && daoDepositAction.isDialogOpen) || - (daoWithdrawAction.withdrawFromMultisig && daoWithdrawAction.isDialogOpen) - ) { - const multisigConfig = daoDepositAction.depositFromMultisig || daoWithdrawAction.withdrawFromMultisig - if (!multisigConfig) return '' - const { canSign } = getMultisigSignStatus({ - multisigConfig, - addresses, - }) - - return canSign ? 'dao-ledger-notice' : 'dao-hardware-not-match' - } + if (!wallet.device) return '' + + const multisigConfig = daoDepositAction.depositFromMultisig || daoWithdrawAction.withdrawFromMultisig + if (!multisigConfig) return '' + + if ( + (daoDepositAction.depositFromMultisig && daoDepositAction.isDialogOpen) || + (daoWithdrawAction.withdrawFromMultisig && daoWithdrawAction.isDialogOpen) + ) { + const { canSign } = getMultisigSignStatus({ + multisigConfig, + addresses, + }) + + return canSign ? 'dao-ledger-notice' : 'dao-hardware-not-match' } + return '' }, [daoDepositAction, daoWithdrawAction, wallet.device, addresses]) diff --git a/packages/neuron-ui/src/components/WithdrawDialog/index.tsx b/packages/neuron-ui/src/components/WithdrawDialog/index.tsx index db6c6035cd..d5d5545d4a 100644 --- a/packages/neuron-ui/src/components/WithdrawDialog/index.tsx +++ b/packages/neuron-ui/src/components/WithdrawDialog/index.tsx @@ -75,7 +75,7 @@ const WithdrawDialog = ({ (Number(currentEpochInfo.number) + Number(currentEpochInfo.index) / Number(currentEpochInfo.length)) ).toFixed(1) const message = - epochs >= 0 ? ( + epochs > 5 ? ( <> {t('nervos-dao.notice-wait-time', { diff --git a/packages/neuron-ui/src/components/WithdrawDialog/withdrawDialog.module.scss b/packages/neuron-ui/src/components/WithdrawDialog/withdrawDialog.module.scss index c406f379ae..c3dcb2feea 100644 --- a/packages/neuron-ui/src/components/WithdrawDialog/withdrawDialog.module.scss +++ b/packages/neuron-ui/src/components/WithdrawDialog/withdrawDialog.module.scss @@ -60,7 +60,7 @@ margin: 44px 0 0 0; border: 1px solid rgba(252, 136, 0, 0.2); padding: 8px 36px; - width: max-content; + max-width: 760px; border-radius: 4px; background: #fff6eb; color: #f68c2a; diff --git a/packages/neuron-ui/src/locales/ar.json b/packages/neuron-ui/src/locales/ar.json index c0891e05be..03433f7d16 100644 --- a/packages/neuron-ui/src/locales/ar.json +++ b/packages/neuron-ui/src/locales/ar.json @@ -1171,7 +1171,7 @@ "daoWithdraw": "سحب من DAO" } }, - "dao-ledger-notice": "تدعم محافظ Ledger حاليًا توقيع معاملات DAO فقط، ولا تدعم بدء الإيداعات أو السحوبات. يرجى التحقق من التحديثات المستقبلية.", + "dao-ledger-notice": "محافظ Ledger لا تدعم حاليًا معاملات DAO لعناوين التوقيع المتعدد. يُرجى استخدام عنوان بتوقيع فردي أو الانتظار للتحديثات المستقبلية.", "dao-hardware-not-match": "المحفظة الصلبة المتصلة حاليًا لا تتطابق مع المحفظة الحالية.", "import-dialog": { "actions": { diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json index 62856f24c0..367b55d3e1 100644 --- a/packages/neuron-ui/src/locales/en.json +++ b/packages/neuron-ui/src/locales/en.json @@ -1171,7 +1171,7 @@ "daoWithdraw": "DAO Withdraw" } }, - "dao-ledger-notice": "Ledger wallets currently support only signing DAO transactions, not initiating deposits or withdrawals. Please check back for future updates.", + "dao-ledger-notice": "Ledger wallets currently do not support DAO transactions for multisig addresses. Please use a single-signature address or await future updates.", "dao-hardware-not-match": "The hardware wallet currently connected does not match the current wallet.", "import-dialog": { "actions": { diff --git a/packages/neuron-ui/src/locales/es.json b/packages/neuron-ui/src/locales/es.json index a06a1d2c55..c960b4e222 100644 --- a/packages/neuron-ui/src/locales/es.json +++ b/packages/neuron-ui/src/locales/es.json @@ -1154,7 +1154,7 @@ "daoWithdraw": "Retirar de DAO" } }, - "dao-ledger-notice": "Las billeteras Ledger actualmente solo admiten la firma de transacciones DAO, no la iniciación de depósitos o retiros. Vuelva a consultar para futuras actualizaciones.", + "dao-ledger-notice": "Las billeteras Ledger actualmente no admiten transacciones DAO para direcciones multifirma. Por favor, use una dirección de firma única o espere futuras actualizaciones.", "dao-hardware-not-match": "La billetera de hardware conectada actualmente no coincide con la billetera actual.", "import-dialog": { "actions": { diff --git a/packages/neuron-ui/src/locales/fr.json b/packages/neuron-ui/src/locales/fr.json index 02cddfdf75..43441d83a7 100644 --- a/packages/neuron-ui/src/locales/fr.json +++ b/packages/neuron-ui/src/locales/fr.json @@ -1161,7 +1161,7 @@ "daoWithdraw": "Retirer de DAO" } }, - "dao-ledger-notice": "Les portefeuilles Ledger prennent actuellement en charge uniquement la signature des transactions DAO, mais pas l’initiation des dépôts ou des retraits. Veuillez vérifier les mises à jour futures.", + "dao-ledger-notice": "Les portefeuilles Ledger ne prennent actuellement pas en charge les transactions DAO pour les adresses multisignatures. Veuillez utiliser une adresse à signature unique ou attendre les futures mises à jour.", "dao-hardware-not-match": "Le portefeuille matériel actuellement connecté ne correspond pas au portefeuille actuel.", "import-dialog": { "actions": { diff --git a/packages/neuron-ui/src/locales/zh-tw.json b/packages/neuron-ui/src/locales/zh-tw.json index f254fc07aa..17c8bd7d3e 100644 --- a/packages/neuron-ui/src/locales/zh-tw.json +++ b/packages/neuron-ui/src/locales/zh-tw.json @@ -1164,7 +1164,7 @@ "daoWithdraw": "從 DAO 取出" } }, - "dao-ledger-notice": "Ledger 錢包目前僅支援簽署 DAO 交易,無法發起存款或提取。請關注未來的更新。", + "dao-ledger-notice": "Ledger 錢包目前不支援多重簽名地址的 DAO 交易。請使用單一簽名地址或等待未來的更新。", "dao-hardware-not-match": "當前連接的硬體錢包與當前錢包不匹配。", "import-dialog": { "actions": { diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json index 04414759a7..dd79782209 100644 --- a/packages/neuron-ui/src/locales/zh.json +++ b/packages/neuron-ui/src/locales/zh.json @@ -1163,7 +1163,7 @@ "daoWithdraw": "从 DAO 取出" } }, - "dao-ledger-notice": "Ledger 钱包目前仅支持签署 DAO 交易,无法发起存款或提取。请关注未来的更新。", + "dao-ledger-notice": "Ledger 钱包目前不支持多签地址的 DAO 交易。请使用单签地址或等待未来的更新。", "dao-hardware-not-match": "当前连接的硬件钱包与当前钱包不匹配。", "import-dialog": { "actions": { diff --git a/packages/neuron-wallet/src/services/multisig.ts b/packages/neuron-wallet/src/services/multisig.ts index 22bd92ce02..1df8ec6e3f 100644 --- a/packages/neuron-wallet/src/services/multisig.ts +++ b/packages/neuron-wallet/src/services/multisig.ts @@ -114,7 +114,7 @@ export default class MultisigService { } static async getCells(multisigConfigs: MultisigConfig[]) { - const cells: any[] = [] + const cells: RPC.IndexerCell[] = [] const addressCursorMap: Map = new Map() let currentMultisigConfigs = MultisigService.removeDulpicateConfig(multisigConfigs) const network = NetworksService.getInstance().getCurrent() @@ -161,7 +161,7 @@ export default class MultisigService { static async getLiveCells(multisigConfigs: MultisigConfig[]) { const cells = await MultisigService.getCells(multisigConfigs) - return cells.filter((object: any) => !object?.output?.type).map((object: any) => MultisigOutput.fromIndexer(object)) + return cells.filter(object => !object?.output?.type).map(object => MultisigOutput.fromIndexer(object)) } static async saveLiveMultisigOutput() { @@ -177,8 +177,8 @@ export default class MultisigService { const cells = await MultisigService.getCells(multisigConfigs) if (cells.length) { const daoTxHash = new Set() - cells.forEach((cell: any) => { - if (cell?.output?.type?.code_hash === SystemScriptInfo.DAO_CODE_HASH) { + cells.forEach(cell => { + if (cell.output?.type?.code_hash === SystemScriptInfo.DAO_CODE_HASH) { daoTxHash.add(cell.out_point.tx_hash) } }) From 80215f48b00518ccd01a2cfc2738bb6ff028220c Mon Sep 17 00:00:00 2001 From: chenyan Date: Sat, 15 Mar 2025 17:15:17 +0800 Subject: [PATCH 3/6] fix: comments --- packages/neuron-ui/src/components/MultisigAddress/index.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/neuron-ui/src/components/MultisigAddress/index.tsx b/packages/neuron-ui/src/components/MultisigAddress/index.tsx index 653a0f6d95..640b548392 100644 --- a/packages/neuron-ui/src/components/MultisigAddress/index.tsx +++ b/packages/neuron-ui/src/components/MultisigAddress/index.tsx @@ -207,15 +207,13 @@ const MultisigAddress = () => { const daoDisabledMessage = useMemo(() => { if (!wallet.device) return '' - const multisigConfig = daoDepositAction.depositFromMultisig || daoWithdrawAction.withdrawFromMultisig - if (!multisigConfig) return '' - if ( (daoDepositAction.depositFromMultisig && daoDepositAction.isDialogOpen) || (daoWithdrawAction.withdrawFromMultisig && daoWithdrawAction.isDialogOpen) ) { + const multisigConfig = daoDepositAction.depositFromMultisig || daoWithdrawAction.withdrawFromMultisig const { canSign } = getMultisigSignStatus({ - multisigConfig, + multisigConfig: multisigConfig!, addresses, }) From 4df15053411357b425b0753c448a60e30c3bf09e Mon Sep 17 00:00:00 2001 From: chenyan Date: Sat, 15 Mar 2025 17:27:04 +0800 Subject: [PATCH 4/6] fix --- .../neuron-wallet/src/services/multisig.ts | 50 +++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/packages/neuron-wallet/src/services/multisig.ts b/packages/neuron-wallet/src/services/multisig.ts index 1df8ec6e3f..c90b995a37 100644 --- a/packages/neuron-wallet/src/services/multisig.ts +++ b/packages/neuron-wallet/src/services/multisig.ts @@ -19,6 +19,7 @@ import RpcService from '../services/rpc-service' import TransactionWithStatus from '../models/chain/transaction-with-status' import TxStatus from '../models/chain/tx-status' import SystemScriptInfo from '../models/system-script-info' +import OutPoint from '../models/chain/out-point' const max64Int = '0x' + 'f'.repeat(16) export default class MultisigService { @@ -182,25 +183,44 @@ export default class MultisigService { daoTxHash.add(cell.out_point.tx_hash) } }) + + const network = NetworksService.getInstance().getCurrent() + const rpcService = new RpcService(network.remote, network.type) + + const getTx = async (txHash: string) => { + const txWithStatus: TransactionWithStatus | undefined | { transaction: null; txStatus: TxStatus } = + await rpcService.getTransaction(txHash) + if (txWithStatus?.transaction) { + const tx = Transaction.fromSDK(txWithStatus.transaction) + tx.blockHash = txWithStatus.txStatus.blockHash || undefined + if (tx.blockHash) { + const header = await rpcService.getHeader(tx.blockHash) + tx.timestamp = header?.timestamp + tx.blockNumber = header?.number + } + return tx + } + } + if (daoTxHash.size > 0) { - const network = NetworksService.getInstance().getCurrent() - const rpcService = new RpcService(network.remote, network.type) for (const txHash of daoTxHash) { - const txWithStatus: TransactionWithStatus | undefined | { transaction: null; txStatus: TxStatus } = - await rpcService.getTransaction(txHash) - if (txWithStatus?.transaction) { - const tx = Transaction.fromSDK(txWithStatus.transaction) - tx.blockHash = txWithStatus.txStatus.blockHash || undefined - if (tx.blockHash) { - const header = await rpcService.getHeader(tx.blockHash) - tx.timestamp = header?.timestamp - tx.blockNumber = header?.number - } - tx.outputsData.forEach((item, index) => { - if (item === DAO_DATA) { - tx.outputs[index].daoData = DAO_DATA + const tx = await getTx(txHash) + if (tx) { + const previousTxHashes: string[] = [] + tx.outputs.forEach((output, index) => { + if (output.type?.codeHash === SystemScriptInfo.DAO_CODE_HASH) { + output.daoData = tx.outputsData[index] + if (tx.outputsData[index] !== DAO_DATA) { + const previousTxHash = tx.inputs[index].previousOutput!.txHash + previousTxHashes.push(previousTxHash) + output.setDepositOutPoint(new OutPoint(previousTxHash, tx.inputs[index].previousOutput!.index)) + } } }) + for (const previousTxHash of previousTxHashes) { + const previousTx = await getTx(previousTxHash) + if (previousTx) await TransactionPersistor.saveFetchTx(previousTx) + } await TransactionPersistor.saveFetchTx(tx) } } From 9df0c7d5547a44e981aad1422f7f3e57ee73bbb8 Mon Sep 17 00:00:00 2001 From: chenyan Date: Sat, 15 Mar 2025 17:33:01 +0800 Subject: [PATCH 5/6] fix --- 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 5ac0ec0ca6..89a6581957 100644 --- a/packages/neuron-wallet/src/services/transaction-sender.ts +++ b/packages/neuron-wallet/src/services/transaction-sender.ts @@ -896,8 +896,7 @@ export default class TransactionSender { multisigConfig.m, multisigConfig.n ) - const multisigAddresses = scriptToAddress(lockScript, NetworksService.getInstance().isMainnet()) - output = new Output(outputCapacity.toString(), AddressParser.parse(multisigAddresses), undefined, '0x') + output = new Output(outputCapacity.toString(), lockScript, undefined, '0x') } else { const wallet = WalletService.getInstance().get(walletID) const address = await wallet.getNextAddress() @@ -919,7 +918,10 @@ export default class TransactionSender { withdrawOutput.lock ) - const withdrawWitnessArgs: WitnessArgs = new WitnessArgs(WitnessArgs.EMPTY_LOCK, '0x0000000000000000') + const withdrawWitnessArgs: WitnessArgs = new WitnessArgs( + multisigConfig ? '' : WitnessArgs.EMPTY_LOCK, + '0x0000000000000000' + ) const tx: Transaction = Transaction.fromObject({ version: '0', cellDeps: [cellDep, daoCellDep], From 4fed46e2470dc8f71ee9fc2273d990653c4c7ef8 Mon Sep 17 00:00:00 2001 From: chenyan Date: Mon, 17 Mar 2025 17:20:33 +0800 Subject: [PATCH 6/6] fix: checkbox is not displaying properly --- packages/neuron-ui/src/styles/mixin.scss | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/neuron-ui/src/styles/mixin.scss b/packages/neuron-ui/src/styles/mixin.scss index 9dfa2f6de3..4d36e5f6f9 100644 --- a/packages/neuron-ui/src/styles/mixin.scss +++ b/packages/neuron-ui/src/styles/mixin.scss @@ -196,23 +196,23 @@ height: 20px; padding-left: 30px; line-height: 20px; - background: url('../widgets/Icons/Checkbox.svg') no-repeat left top; + background: url('widgets/Icons/Checkbox.svg') no-repeat left top; user-select: none; } input[type='checkbox']:checked + span { - background: url('../widgets/Icons/CheckboxSelected.svg') no-repeat left top; + background: url('widgets/Icons/CheckboxSelected.svg') no-repeat left top; } input[type='checkbox']:disabled:checked + span { - background: url('../widgets/Icons/CheckboxSelected.svg') no-repeat left top; + background: url('widgets/Icons/CheckboxSelected.svg') no-repeat left top; opacity: 0.5; } input[type='checkbox']:disabled + span { cursor: not-allowed; - background: url('../widgets/Icons/CheckboxDisabled.svg') no-repeat left top; + background: url('widgets/Icons/CheckboxDisabled.svg') no-repeat left top; @media (prefers-color-scheme: dark) { - background: url('../widgets/Icons/CheckboxDisabledDark.svg') no-repeat left top; + background: url('widgets/Icons/CheckboxDisabledDark.svg') no-repeat left top; } } }