| undefined
+ if (isLightClient) {
+ interval = setInterval(() => {
+ getAndSaveMultisigSyncProgress()
+ }, 10000)
+ getAndSaveMultisigSyncProgress()
+ }
+ return () => {
+ clearInterval(interval)
+ }
+ }, [isLightClient, getAndSaveMultisigSyncProgress])
+ return { multisigBanlances, multisigSyncProgress }
}
diff --git a/packages/neuron-ui/src/components/MultisigAddress/index.tsx b/packages/neuron-ui/src/components/MultisigAddress/index.tsx
index 68e95209ea..65eced4cc8 100644
--- a/packages/neuron-ui/src/components/MultisigAddress/index.tsx
+++ b/packages/neuron-ui/src/components/MultisigAddress/index.tsx
@@ -20,6 +20,7 @@ import { EditTextField } from 'widgets/TextField'
import { MultisigConfig } from 'services/remote'
import PasswordRequest from 'components/PasswordRequest'
import ApproveMultisigTx from 'components/ApproveMultisigTx'
+import { LIGHT_NETWORK_TYPE } from 'utils/const'
import { useSearch, useConfigManage, useExportConfig, useActions, useSubscription } from './hooks'
import styles from './multisigAddress.module.scss'
@@ -52,6 +53,10 @@ const MultisigAddress = () => {
// eslint-disable-next-line
}, [i18n.language])
const isMainnet = isMainnetUtil(networks, networkID)
+ const isLightClient = useMemo(() => networks.find(n => n.id === networkID)?.type === LIGHT_NETWORK_TYPE, [
+ networks,
+ networkID,
+ ])
const { openDialog, closeDialog, dialogRef, isDialogOpen } = useDialogWrapper()
const {
allConfigs,
@@ -65,7 +70,12 @@ const MultisigAddress = () => {
walletId,
isMainnet,
})
- const multisigBanlances = useSubscription({ walletId, isMainnet, configs: allConfigs })
+ const { multisigBanlances, multisigSyncProgress } = useSubscription({
+ walletId,
+ isMainnet,
+ configs: allConfigs,
+ isLightClient,
+ })
const { deleteAction, infoAction, sendAction, approveAction } = useActions({ deleteConfigById })
const onClickItem = useCallback(
(multisigConfig: MultisigConfig) => (option: { key: string }) => {
@@ -138,8 +148,10 @@ const MultisigAddress = () => {
|
- {['address', 'alias', 'type', 'balance'].map(field => (
- {t(`multisig-address.table.${field}`)} |
+ {['address', 'alias', 'type', ...(isLightClient ? ['sync-block'] : []), 'balance'].map(field => (
+
+ {t(`multisig-address.table.${field}`)}
+ |
))}
@@ -173,6 +185,7 @@ const MultisigAddress = () => {
of
{v.n}
+ {isLightClient ? {multisigSyncProgress?.[v.fullPayload] ?? 0} | : null}
{shannonToCKBFormatter(multisigBanlances[v.fullPayload])}
CKB
diff --git a/packages/neuron-ui/src/components/MultisigAddress/multisigAddress.module.scss b/packages/neuron-ui/src/components/MultisigAddress/multisigAddress.module.scss
index adc8839afe..f3a0a2baa9 100644
--- a/packages/neuron-ui/src/components/MultisigAddress/multisigAddress.module.scss
+++ b/packages/neuron-ui/src/components/MultisigAddress/multisigAddress.module.scss
@@ -55,6 +55,10 @@
padding: 8px;
min-width: 40px;
text-align: left;
+
+ &[data-field="sync-block"] {
+ min-width: 70px;
+ }
}
.checkBoxTh {
diff --git a/packages/neuron-ui/src/components/NervosDAO/hooks.ts b/packages/neuron-ui/src/components/NervosDAO/hooks.ts
index 23a32d989d..4db179fa68 100644
--- a/packages/neuron-ui/src/components/NervosDAO/hooks.ts
+++ b/packages/neuron-ui/src/components/NervosDAO/hooks.ts
@@ -20,7 +20,7 @@ import {
generateDaoDepositTx,
generateDaoClaimTx,
} from 'services/remote'
-import { ckbCore, getHeaderByNumber } from 'services/chain'
+import { ckbCore, getHeader } from 'services/chain'
import { isErrorWithI18n } from 'exceptions'
import { calculateMaximumWithdraw } from '@nervosnetwork/ckb-sdk-utils'
@@ -84,12 +84,14 @@ export const useInitData = ({
updateDepositValue,
wallet,
setGenesisBlockTimestamp,
+ genesisBlockHash,
}: {
clearGeneratedTx: () => void
dispatch: React.Dispatch
updateDepositValue: (value: string) => void
wallet: State.Wallet
setGenesisBlockTimestamp: React.Dispatch>
+ genesisBlockHash?: string
}) =>
useEffect(() => {
updateNervosDaoData({ walletID: wallet.id })(dispatch)
@@ -103,9 +105,11 @@ export const useInitData = ({
: BigInt(0)
}`
)
- getHeaderByNumber('0x0')
- .then(header => setGenesisBlockTimestamp(+header.timestamp))
- .catch(err => console.error(err))
+ if (genesisBlockHash) {
+ getHeader(genesisBlockHash)
+ .then(header => setGenesisBlockTimestamp(+header.timestamp))
+ .catch(err => console.error(err))
+ }
return () => {
clearInterval(intervalId)
clearNervosDaoData()(dispatch)
@@ -450,15 +454,15 @@ export const useOnSlide = ({
export const useUpdateWithdrawList = ({
records,
- tipBlockHash,
+ tipDao,
setWithdrawList,
}: {
records: Readonly
- tipBlockHash: string
+ tipDao?: string
setWithdrawList: React.Dispatch>>
}) =>
useEffect(() => {
- if (!tipBlockHash) {
+ if (!tipDao) {
setWithdrawList(new Map())
return
}
@@ -473,7 +477,6 @@ export const useUpdateWithdrawList = ({
const blockHashes = [
...(committedTx.map(v => v.txStatus.blockHash).filter(v => !!v) as string[]),
...(records.map(v => (v.depositOutPoint ? v.blockHash : null)).filter(v => !!v) as string[]),
- tipBlockHash,
]
return ckbCore.rpc
.createBatchRequest<'getHeader', string[], CKBComponents.BlockHeader[]>(
@@ -494,7 +497,7 @@ export const useUpdateWithdrawList = ({
const withdrawList = new Map()
records.forEach(record => {
const key = getRecordKey(record)
- const withdrawBlockHash = record.depositOutPoint ? record.blockHash : tipBlockHash
+ const withdrawBlockHash = record.depositOutPoint ? record.blockHash : undefined
const formattedDepositOutPoint = record.depositOutPoint
? {
txHash: record.depositOutPoint.txHash,
@@ -509,7 +512,7 @@ export const useUpdateWithdrawList = ({
return
}
const depositDAO = hashHeaderMap.get(tx.txStatus.blockHash!)
- const withdrawDAO = hashHeaderMap.get(withdrawBlockHash)
+ const withdrawDAO = withdrawBlockHash ? hashHeaderMap.get(withdrawBlockHash) : tipDao
if (!depositDAO || !withdrawDAO) {
return
}
@@ -529,7 +532,23 @@ export const useUpdateWithdrawList = ({
.catch(() => {
setWithdrawList(new Map())
})
- }, [records, tipBlockHash, setWithdrawList])
+ }, [records, tipDao, setWithdrawList])
+
+const getBlockHashes = (txHashes: string[]) => {
+ const batchParams: ['getTransaction', string][] = txHashes.map(v => ['getTransaction', v])
+ return ckbCore.rpc
+ .createBatchRequest<'getTransaction', [string], CKBComponents.TransactionWithStatus[]>(batchParams)
+ .exec()
+ .then(res => {
+ return res.map((v, idx) => ({
+ txHash: txHashes[idx],
+ blockHash: v.txStatus.blockHash,
+ }))
+ })
+ .catch(() => {
+ return []
+ })
+}
export const useUpdateDepositEpochList = ({
records,
@@ -542,28 +561,35 @@ export const useUpdateDepositEpochList = ({
}) =>
useEffect(() => {
if (connectionStatus === 'online') {
- const recordKeyIdxMap = new Map()
- const batchParams: ['getHeaderByNumber', bigint][] = []
- records.forEach((record, idx) => {
- const depositBlockNumber = record.depositOutPoint
- ? ckbCore.utils.toUint64Le(record.daoData)
- : record.blockNumber
- if (depositBlockNumber) {
- batchParams.push(['getHeaderByNumber', BigInt(depositBlockNumber)])
- recordKeyIdxMap.set(getRecordKey(record), idx)
- }
- })
- ckbCore.rpc
- .createBatchRequest<'getHeaderByNumber', any, CKBComponents.BlockHeader[]>(batchParams)
- .exec()
- .then(res => {
- const epochList = new Map()
- records.forEach(record => {
- const key = getRecordKey(record)
- epochList.set(key, recordKeyIdxMap.get(key) !== undefined ? res[recordKeyIdxMap.get(key)!]?.epoch : null)
+ getBlockHashes(records.map(v => v.depositOutPoint?.txHash).filter(v => !!v) as string[]).then(
+ depositBlockHashes => {
+ const recordKeyIdx: string[] = []
+ const batchParams: ['getHeader', string][] = []
+ records.forEach((record) => {
+ if (!record.depositOutPoint && record.blockHash) {
+ batchParams.push(['getHeader', record.blockHash])
+ recordKeyIdx.push(record.outPoint.txHash)
+ }
})
- setDepositEpochList(epochList)
- })
+ depositBlockHashes.forEach((v) => {
+ if (v.blockHash) {
+ batchParams.push(['getHeader', v.blockHash])
+ recordKeyIdx.push(v.txHash)
+ }
+ })
+ ckbCore.rpc
+ .createBatchRequest<'getHeader', any, CKBComponents.BlockHeader[]>(batchParams)
+ .exec()
+ .then(res => {
+ const epochList = new Map()
+ records.forEach(record => {
+ const key = record.depositOutPoint ? record.depositOutPoint.txHash : record.outPoint.txHash
+ epochList.set(key, res[recordKeyIdx.indexOf(key)]?.epoch)
+ })
+ setDepositEpochList(epochList)
+ })
+ }
+ )
}
}, [records, setDepositEpochList, connectionStatus])
diff --git a/packages/neuron-ui/src/components/NervosDAO/index.tsx b/packages/neuron-ui/src/components/NervosDAO/index.tsx
index 170d941fa2..18d43d2014 100644
--- a/packages/neuron-ui/src/components/NervosDAO/index.tsx
+++ b/packages/neuron-ui/src/components/NervosDAO/index.tsx
@@ -41,7 +41,7 @@ const NervosDAO = () => {
app: {
send = appState.send,
loadings: { sending = false },
- tipBlockHash,
+ tipDao,
tipBlockTimestamp,
epoch,
},
@@ -108,7 +108,15 @@ const NervosDAO = () => {
isBalanceReserved,
suggestFeeRate,
})
- hooks.useInitData({ clearGeneratedTx, dispatch, updateDepositValue, wallet, setGenesisBlockTimestamp })
+ const genesisBlockHash = useMemo(() => networks.find(v => v.id === networkID)?.genesisHash, [networkID, networks])
+ hooks.useInitData({
+ clearGeneratedTx,
+ dispatch,
+ updateDepositValue,
+ wallet,
+ setGenesisBlockTimestamp,
+ genesisBlockHash,
+ })
hooks.useUpdateGlobalAPC({ bestKnownBlockTimestamp, genesisBlockTimestamp, setGlobalAPC })
const onWithdrawDialogSubmit = hooks.useOnWithdrawDialogSubmit({
activeRecord,
@@ -144,7 +152,7 @@ const NervosDAO = () => {
)} CKB`
hooks.useUpdateWithdrawList({
records,
- tipBlockHash,
+ tipDao,
setWithdrawList,
})
@@ -201,13 +209,14 @@ const NervosDAO = () => {
const key = record.depositOutPoint
? `${record.depositOutPoint.txHash}-${record.depositOutPoint.index}`
: `${record.outPoint.txHash}-${record.outPoint.index}`
+ const txHash = record.depositOutPoint ? record.depositOutPoint.txHash : record.outPoint.txHash
const props: DAORecordProps = {
...record,
tipBlockTimestamp,
withdrawCapacity: withdrawList.get(key) || null,
onClick: onActionClick,
- depositEpoch: depositEpochList.get(key) || '',
+ depositEpoch: depositEpochList.get(txHash) || '',
currentEpoch: epoch,
genesisBlockTimestamp,
connectionStatus,
@@ -303,11 +312,11 @@ const NervosDAO = () => {
record={activeRecord}
onDismiss={onWithdrawDialogDismiss}
onSubmit={onWithdrawDialogSubmit}
- tipBlockHash={tipBlockHash}
+ tipDao={tipDao}
currentEpoch={epoch}
/>
) : null
- }, [activeRecord, onWithdrawDialogDismiss, onWithdrawDialogSubmit, tipBlockHash, epoch])
+ }, [activeRecord, onWithdrawDialogDismiss, onWithdrawDialogSubmit, tipDao, epoch])
const free = BigInt(wallet.balance)
const locked = records
diff --git a/packages/neuron-ui/src/components/NervosDAORecord/hooks.ts b/packages/neuron-ui/src/components/NervosDAORecord/hooks.ts
index d57ef27cf0..b28b447836 100644
--- a/packages/neuron-ui/src/components/NervosDAORecord/hooks.ts
+++ b/packages/neuron-ui/src/components/NervosDAORecord/hooks.ts
@@ -1,24 +1,24 @@
import { useEffect, useCallback } from 'react'
+import { getHeader } from 'services/chain'
import { showTransactionDetails } from 'services/remote'
-import { getHeaderByNumber } from 'services/chain'
import { calculateAPC, CONSTANTS } from 'utils'
const { MILLISECONDS_IN_YEAR } = CONSTANTS
export const useUpdateWithdrawEpochs = ({
isWithdrawn,
- blockNumber,
+ blockHash,
setWithdrawEpoch,
setWithdrawTimestamp,
}: {
isWithdrawn: boolean
- blockNumber: CKBComponents.BlockNumber | null
+ blockHash: CKBComponents.BlockHeader['hash'] | null
setWithdrawEpoch: React.Dispatch
setWithdrawTimestamp: React.Dispatch
}) => {
useEffect(() => {
- if (isWithdrawn && blockNumber) {
- getHeaderByNumber(BigInt(blockNumber))
+ if (isWithdrawn && blockHash) {
+ getHeader(blockHash)
.then(header => {
setWithdrawEpoch(header.epoch)
setWithdrawTimestamp(header.timestamp)
@@ -27,7 +27,7 @@ export const useUpdateWithdrawEpochs = ({
console.error(err)
})
}
- }, [isWithdrawn, blockNumber, setWithdrawEpoch, setWithdrawTimestamp])
+ }, [isWithdrawn, blockHash, setWithdrawEpoch, setWithdrawTimestamp])
}
export const useUpdateApc = ({
diff --git a/packages/neuron-ui/src/components/NervosDAORecord/index.tsx b/packages/neuron-ui/src/components/NervosDAORecord/index.tsx
index 10e77c709a..09b3059ff7 100644
--- a/packages/neuron-ui/src/components/NervosDAORecord/index.tsx
+++ b/packages/neuron-ui/src/components/NervosDAORecord/index.tsx
@@ -41,7 +41,7 @@ export interface DAORecordProps extends State.NervosDAORecord {
}
export const DAORecord = ({
- blockNumber,
+ blockHash,
tipBlockTimestamp,
capacity,
outPoint: { txHash, index },
@@ -73,7 +73,7 @@ export const DAORecord = ({
setApc,
})
- hooks.useUpdateWithdrawEpochs({ isWithdrawn, blockNumber, setWithdrawEpoch, setWithdrawTimestamp })
+ hooks.useUpdateWithdrawEpochs({ isWithdrawn, blockHash, setWithdrawEpoch, setWithdrawTimestamp })
const onTxRecordClick = hooks.useOnTxRecordClick()
const currentEpochValue = epochParser(currentEpoch).value
diff --git a/packages/neuron-ui/src/components/NetworkSetting/index.tsx b/packages/neuron-ui/src/components/NetworkSetting/index.tsx
index 34ed75a005..c0dcfc12df 100644
--- a/packages/neuron-ui/src/components/NetworkSetting/index.tsx
+++ b/packages/neuron-ui/src/components/NetworkSetting/index.tsx
@@ -11,6 +11,7 @@ import { chainState } from 'states'
import { setCurrentNetowrk } from 'services/remote'
import { backToTop, RoutePath, useOnHandleNetwork, useOnWindowResize, useToggleChoiceGroupBorder } from 'utils'
+import { LIGHT_CLIENT_TESTNET } from 'utils/const'
import styles from './networkSetting.module.scss'
const NetworkSetting = ({ chain = chainState, settings: { networks = [] } }: State.AppWithNeuronWallet) => {
@@ -71,11 +72,12 @@ const NetworkSetting = ({ chain = chainState, settings: { networks = [] } }: Sta
{`(${network.remote}`}
-
-
- {isDefault ? null : (
+ {network.chain === LIGHT_CLIENT_TESTNET ? null : (
+
+ )}
+ {isDefault || network.chain === LIGHT_CLIENT_TESTNET ? null : (
|