diff --git a/.ckb-version b/.ckb-version index e4f95f2ae6..2b23e8a911 100644 --- a/.ckb-version +++ b/.ckb-version @@ -1 +1 @@ -v0.110.2 +v0.111.0 diff --git a/.github/workflows/update_valid_target.yml b/.github/workflows/update_valid_target.yml index 4b2cd85462..e68d91ee15 100644 --- a/.github/workflows/update_valid_target.yml +++ b/.github/workflows/update_valid_target.yml @@ -1,28 +1,26 @@ name: Update ckb node assume valid target on: - pull_request: - types: [ready_for_review] - branches: - - master + create: jobs: ready-for-release: name: Update ckb node assume valid target runs-on: ubuntu-latest + if: ${{ startsWith(github.ref_name, 'rc/') }} steps: - name: Create Branch uses: peterjgrainger/action-create-branch@v2.2.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - branch: 'chore-update-valid-target/${{github.head_ref}}' - sha: '${{ github.event.pull_request.head.sha }}' + branch: 'chore-update-valid-target/${{github.ref_name}}' + sha: '${{ github.event.create.head.sha }}' - name: Checkout uses: actions/checkout@v3 with: - ref: 'chore-update-valid-target/${{github.head_ref}}' + ref: 'chore-update-valid-target/${{github.ref_name}}' - name: Setup Node uses: actions/setup-node@v3 @@ -37,7 +35,7 @@ jobs: uses: actions/github-script@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BASE: ${{ github.head_ref }} + BASE: ${{ github.ref_name }} with: script: | const fs = require('node:fs') @@ -64,8 +62,8 @@ jobs: uses: actions/github-script@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BASE: ${{github.head_ref}} - HEAD: chore-update-valid-target/${{github.head_ref}} + BASE: ${{github.ref}} + HEAD: chore-update-valid-target/${{github.ref_name}} REPO: ${{github.repository}} with: script: | @@ -83,5 +81,5 @@ jobs: head: HEAD, base: BASE, title: 'chore: Update ckb node assume valid target', - body: `This PR uses to update ckb node assume valid target for PR https://github.com/${REPO}/pull/${context.issue.number}`, + body: `This PR uses to update ckb node assume valid target for ${BASE} branch`, }) diff --git a/CHANGELOG.md b/CHANGELOG.md index 377c2a82ff..56e053b100 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,30 @@ +# 0.111.0 (2023-10-19) + +### CKB Node & Light Client + +- [CKB@v0.111.0](https://github.com/nervosnetwork/ckb/releases/tag/v0.111.0) was released on Sep. 14nd, 2023. This version of CKB node is now bundled and preconfigured in Neuron. +- [CKB Light Client@v0.2.4](https://github.com/nervosnetwork/ckb-light-client/releases/tag/v0.2.4) was released on May. 28th, 2023. This version of CKB Light Client is now bundled and preconfigured in Neuron + +#### Caveat + +◆ **CKB Light Client** is only activated on testnet, thus only `light testnet` is enabled in Neuron. **CKB Light Client on Mainnet** requires an activation on the mainnet, the timetable can be found at https://github.com/nervosnetwork/ckb/releases/tag/v0.110.1. + +### Assumed valid target + +Block before `0xd5e25ad24400f237aa5f72f3738a9ae77fe082a89937e75143fcc8ef5b009383`(at height `11,204,855`) will be skipped in validation.(https://github.com/nervosnetwork/neuron/pull/2881) + +--- + +## Bug fixes + +* #2869: Add a dialog for migration.(@yanguoyu) +* #2870: Fix width of navbar.(@yanguoyu) +* #2873: Fix fallback font on Linux.(@yanguoyu) + + +**Full Changelog**: https://github.com/nervosnetwork/neuron/compare/v0.110.3...v0.111.0 + + # 0.110.3 (2023-10-11) ### CKB Node & Light Client diff --git a/lerna.json b/lerna.json index ce766d7238..a7f5a6383b 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "packages": ["packages/*"], - "version": "0.110.3", + "version": "0.111.0", "npmClient": "yarn", "$schema": "node_modules/lerna/schemas/lerna-schema.json" } diff --git a/package.json b/package.json index 88dc5ef815..c118d23a20 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "neuron", "productName": "Neuron", "description": "CKB Neuron Wallet", - "version": "0.110.3", + "version": "0.111.0", "private": true, "author": { "name": "Nervos Core Dev", diff --git a/packages/neuron-ui/package.json b/packages/neuron-ui/package.json index 93ad46e5ec..0c5ae13189 100644 --- a/packages/neuron-ui/package.json +++ b/packages/neuron-ui/package.json @@ -1,6 +1,6 @@ { "name": "neuron-ui", - "version": "0.110.3", + "version": "0.111.0", "private": true, "author": { "name": "Nervos Core Dev", @@ -86,7 +86,7 @@ "@types/styled-components": "5.1.26", "@wojtekmaj/enzyme-adapter-react-17": "0.8.0", "babel-jest": "25.5.1", - "electron": "24.7.1", + "electron": "24.8.5", "enzyme": "3.11.0", "enzyme-adapter-react-16": "1.15.7", "eslint-config-airbnb": "19.0.4", diff --git a/packages/neuron-ui/public/css/fonts.css b/packages/neuron-ui/public/css/fonts.css index 85b52a469f..d183b3bf33 100644 --- a/packages/neuron-ui/public/css/fonts.css +++ b/packages/neuron-ui/public/css/fonts.css @@ -37,3 +37,13 @@ src: url('../fonts/JetBrainsMonoNL-Regular.otf') format('opentype'), url('../fonts/JetBrainsMonoNL-Regular.ttf') format('opentype'); } + +@font-face { + font-family: 'Inter-Regular'; + src: url('../fonts/Inter-Regular.otf') format('opentype'), url('../fonts/Inter-Regular.ttf') format('opentype'); +} + +@font-face { + font-family: 'Inter-Medium'; + src: url('../fonts/Inter-Medium.otf') format('opentype'), url('../fonts/Inter-Medium.ttf') format('opentype'); +} diff --git a/packages/neuron-ui/public/fonts/Inter-Medium.otf b/packages/neuron-ui/public/fonts/Inter-Medium.otf new file mode 100644 index 0000000000..ca7bfcd434 Binary files /dev/null and b/packages/neuron-ui/public/fonts/Inter-Medium.otf differ diff --git a/packages/neuron-ui/public/fonts/Inter-Medium.ttf b/packages/neuron-ui/public/fonts/Inter-Medium.ttf new file mode 100644 index 0000000000..1d909c10d0 Binary files /dev/null and b/packages/neuron-ui/public/fonts/Inter-Medium.ttf differ diff --git a/packages/neuron-ui/public/fonts/Inter-Regular.otf b/packages/neuron-ui/public/fonts/Inter-Regular.otf new file mode 100644 index 0000000000..84e6a61c3c Binary files /dev/null and b/packages/neuron-ui/public/fonts/Inter-Regular.otf differ diff --git a/packages/neuron-ui/public/fonts/Inter-Regular.ttf b/packages/neuron-ui/public/fonts/Inter-Regular.ttf new file mode 100644 index 0000000000..d7c2eebfc6 Binary files /dev/null and b/packages/neuron-ui/public/fonts/Inter-Regular.ttf differ diff --git a/packages/neuron-ui/src/components/FormattedTokenAmount/index.tsx b/packages/neuron-ui/src/components/FormattedTokenAmount/index.tsx index 1ad311919d..63d82b449b 100644 --- a/packages/neuron-ui/src/components/FormattedTokenAmount/index.tsx +++ b/packages/neuron-ui/src/components/FormattedTokenAmount/index.tsx @@ -8,25 +8,30 @@ import { HIDE_BALANCE } from 'utils/const' import styles from './formattedTokenAmount.module.scss' -type FormattedTokenAmountProps = { item: State.Transaction; show: boolean } +type FormattedTokenAmountProps = { item: State.Transaction; show: boolean; symbolClassName?: string } type AmountProps = Omit & { sudtAmount: string isReceive: boolean amount: string + symbolClassName?: string } -const Amount = ({ sudtAmount, show, item, isReceive, amount }: AmountProps) => { +const Amount = ({ sudtAmount, show, item, isReceive, amount, symbolClassName }: AmountProps) => { return sudtAmount ? (
{show ? `${!sudtAmount.includes('-') ? '+' : ''}${sudtAmount}` : HIDE_BALANCE}  - +
) : ( {amount} ) } -export const FormattedTokenAmount = ({ item, show }: FormattedTokenAmountProps) => { +export const FormattedTokenAmount = ({ item, show, symbolClassName }: FormattedTokenAmountProps) => { let amount = '--' let sudtAmount = '' let copyText = amount @@ -51,7 +56,7 @@ export const FormattedTokenAmount = ({ item, show }: FormattedTokenAmountProps) } } - const props = { sudtAmount, show, item, isReceive, amount } + const props = { sudtAmount, show, item, isReceive, amount, symbolClassName } return show ? ( diff --git a/packages/neuron-ui/src/components/History/history.module.scss b/packages/neuron-ui/src/components/History/history.module.scss index f1ee7cad4f..61438e54d6 100644 --- a/packages/neuron-ui/src/components/History/history.module.scss +++ b/packages/neuron-ui/src/components/History/history.module.scss @@ -236,3 +236,11 @@ body { .isReceive { color: $main-color; } + +.tokenName { + max-width: calc(100px + (100vw - 1300px) / 2); +} + +.symbol { + max-width: calc(180px + (100vw - 1300px) / 2); +} diff --git a/packages/neuron-ui/src/components/History/index.tsx b/packages/neuron-ui/src/components/History/index.tsx index 186039cb10..1329d5281b 100644 --- a/packages/neuron-ui/src/components/History/index.tsx +++ b/packages/neuron-ui/src/components/History/index.tsx @@ -1,6 +1,6 @@ import React, { useState, useCallback } from 'react' import { useNavigate, useLocation } from 'react-router-dom' -import { Trans, useTranslation } from 'react-i18next' +import { useTranslation } from 'react-i18next' import Pagination from 'widgets/Pagination' import SUDTAvatar from 'widgets/SUDTAvatar' import Button from 'widgets/Button' @@ -11,27 +11,16 @@ import { Download, Search, ArrowNext } from 'widgets/Icons/icon' import PageContainer from 'components/PageContainer' import TransactionStatusWrap from 'components/TransactionStatusWrap' import FormattedTokenAmount from 'components/FormattedTokenAmount' -import { UANTokenName, isTonkenInfoStandardUAN } from 'components/UANDisplay' import { useState as useGlobalState, useDispatch } from 'states' import { exportTransactions } from 'services/remote' import { ReactComponent as CKBAvatar } from 'widgets/Icons/Nervos.svg' -import { ReactComponent as Success } from 'widgets/Icons/Success.svg' -import { ReactComponent as Pending } from 'widgets/Icons/Pending.svg' -import { ReactComponent as Failure } from 'widgets/Icons/Failure.svg' -import { - RoutePath, - isMainnet as isMainnetUtil, - uniformTimeFormatter, - nftFormatter, - sUDTAmountFormatter, - sudtValueToAmount, - shannonToCKBFormatter, -} from 'utils' +import { RoutePath, isMainnet as isMainnetUtil, uniformTimeFormatter } from 'utils' import { onEnter } from 'utils/inputDevice' import { CONFIRMATION_THRESHOLD, DEFAULT_SUDT_FIELDS } from 'utils/const' import Tooltip from 'widgets/Tooltip' +import TransactionType from 'components/TransactionType' import RowExtend from './RowExtend' import { useSearch } from './hooks' @@ -73,79 +62,12 @@ const History = () => { const bestBlockNumber = Math.max(cacheTipBlockNumber, bestKnownBlockNumber) - const handleTransactionInfo = (tx: State.Transaction) => { - let name = '--' - let amount = '--' - let typeLabel: React.ReactNode = '--' - let sudtAmount = '' - let showWithUANFormatter = false - - if (tx.nftInfo) { - // NFT - name = walletName - const { type, data } = tx.nftInfo - typeLabel = `${t(`history.${type}`)} m-NFT` - amount = `${type === 'receive' ? '+' : '-'}${nftFormatter(data)}` - } else if (tx.sudtInfo?.sUDT) { + const getTxName = (tx: State.Transaction) => { + if (!tx.nftInfo && tx.sudtInfo?.sUDT) { // Asset Account - name = tx.sudtInfo.sUDT.tokenName || DEFAULT_SUDT_FIELDS.tokenName - if (['create', 'destroy'].includes(tx.type)) { - // create/destroy an account - showWithUANFormatter = isTonkenInfoStandardUAN(tx.sudtInfo.sUDT.tokenName, tx.sudtInfo.sUDT.symbol) - typeLabel = ( - ]} - /> - ) - } else { - // send/receive to/from an account - const type = +tx.sudtInfo.amount <= 0 ? 'send' : 'receive' - typeLabel = `UDT ${t(`history.${type}`)}` - } - - if (tx.sudtInfo.sUDT.decimal) { - sudtAmount = sudtValueToAmount(tx.sudtInfo.amount, tx.sudtInfo.sUDT.decimal, true) - amount = `${sUDTAmountFormatter(sudtAmount)} ${tx.sudtInfo.sUDT.symbol}` - } - } else { - // normal tx - name = walletName - amount = `${shannonToCKBFormatter(tx.value, true)} CKB` - if (tx.type === 'create' || tx.type === 'destroy') { - if (tx.assetAccountType === 'CKB') { - typeLabel = `${t(`history.${tx.type}`, { name: 'CKB' })}` - } else { - typeLabel = `${t(`overview.${tx.type}`, { name: 'Unknown' })}` - } - } else { - typeLabel = tx.nervosDao ? 'Nervos DAO' : t(`history.${tx.type}`) - } - } - - let indicator = - switch (tx.status) { - case 'success': { - indicator = - break - } - case 'failed': { - indicator = - break - } - default: { - // ignore - } - } - - return { - name, - amount, - typeLabel, - sudtAmount, - showWithUANFormatter, - indicator, + return tx.sudtInfo.sUDT.tokenName || DEFAULT_SUDT_FIELDS.tokenName } + return walletName ?? '--' } const handleExpandClick = (idx: number | null) => { @@ -158,7 +80,7 @@ const History = () => { dataIndex: 'name', minWidth: '110px', render(_, __, item) { - const { name } = handleTransactionInfo(item) + const name = getTxName(item) return name.length > 8 ? ( {name}} isTriggerNextToChild showTriangle>
@@ -186,10 +108,16 @@ const History = () => { title: t('history.table.type'), dataIndex: 'type', align: 'left', - minWidth: '100px', + minWidth: '120px', render: (_, __, item) => { - const { typeLabel } = handleTransactionInfo(item) - return typeLabel + return ( + + ) }, }, { @@ -197,9 +125,9 @@ const History = () => { dataIndex: 'amount', align: 'left', isBalance: true, - minWidth: '220px', + minWidth: '200px', render(_, __, item, show) { - return + return }, }, { diff --git a/packages/neuron-ui/src/components/Overview/index.tsx b/packages/neuron-ui/src/components/Overview/index.tsx index ff24b3c12a..f22f45e60d 100644 --- a/packages/neuron-ui/src/components/Overview/index.tsx +++ b/packages/neuron-ui/src/components/Overview/index.tsx @@ -1,11 +1,10 @@ import React, { useCallback, useMemo, useEffect, useState } from 'react' import { Link, useNavigate } from 'react-router-dom' -import { Trans, useTranslation } from 'react-i18next' +import { useTranslation } from 'react-i18next' import { useState as useGlobalState, useDispatch, updateTransactionList } from 'states' import { shannonToCKBFormatter, uniformTimeFormatter, backToTop, CONSTANTS, RoutePath, useFirstLoadWallet } from 'utils' -import { UANTokenName } from 'components/UANDisplay' import PageContainer from 'components/PageContainer' import TransactionStatusWrap from 'components/TransactionStatusWrap' import FormattedTokenAmount from 'components/FormattedTokenAmount' @@ -17,39 +16,11 @@ import { ArrowNext, EyesClose, EyesOpen, OverviewSend, OverviewReceive, Addressb import BalanceSyncIcon from 'components/BalanceSyncingIcon' import CopyZone from 'widgets/CopyZone' import { HIDE_BALANCE } from 'utils/const' +import TransactionType from 'components/TransactionType' import styles from './overview.module.scss' const { PAGE_SIZE, CONFIRMATION_THRESHOLD } = CONSTANTS -const genTypeLabel = ( - type: 'send' | 'receive' | 'create' | 'destroy', - status: 'pending' | 'confirming' | 'success' | 'failed' -) => { - switch (type) { - case 'send': { - if (status === 'failed') { - return 'sent' - } - if (status === 'pending' || status === 'confirming') { - return 'sending' - } - return 'sent' - } - case 'receive': { - if (status === 'failed') { - return 'received' - } - if (status === 'pending' || status === 'confirming') { - return 'receiving' - } - return 'received' - } - default: { - return type - } - } -} - const TransactionStatus = ({ item, cacheTipBlockNumber, @@ -78,72 +49,6 @@ const TransactionStatus = ({ ) } -const TracsactionType = ({ - item, - cacheTipBlockNumber, - bestKnownBlockNumber, -}: { - item: Omit & { status: State.Transaction['status'] | 'confirming' } - cacheTipBlockNumber: number - bestKnownBlockNumber: number -}) => { - const [t] = useTranslation() - let typeLabel: string = '--' - let { status } = item - let typeTransProps: { - i18nKey: string - components: JSX.Element[] - } = { - i18nKey: '', - components: [], - } - - if (item.blockNumber !== undefined) { - const confirmationCount = - item.blockNumber === null || item.status === 'failed' - ? 0 - : 1 + Math.max(cacheTipBlockNumber, bestKnownBlockNumber) - +item.blockNumber - - if (status === 'success' && confirmationCount < CONFIRMATION_THRESHOLD) { - status = 'confirming' - } - if (item.nftInfo) { - // NFT - const { type } = item.nftInfo - typeLabel = `${t(`overview.${genTypeLabel(type, status)}`)}` - } else if (item.sudtInfo?.sUDT) { - // Asset Account - if (['create', 'destroy'].includes(item.type)) { - // create/destroy an account - typeTransProps = { - i18nKey: `overview.${item.type}SUDT`, - components: [ - , - ], - } - } else { - // send/receive to/from an account - const type = +item.sudtInfo.amount <= 0 ? 'send' : 'receive' - typeLabel = `UDT ${t(`overview.${genTypeLabel(type, status)}`)}` - } - } else if (item.type === 'create' || item.type === 'destroy') { - // normal tx - if (item.assetAccountType === 'CKB') { - typeLabel = `${t(`overview.${item.type}`, { name: 'CKB' })}` - } else { - typeLabel = `${t(`overview.${item.type}`, { name: 'Unknown' })}` - } - } else { - typeLabel = item.nervosDao ? 'Nervos DAO' : t(`overview.${genTypeLabel(item.type, status)}`) - } - } - return typeTransProps.i18nKey ? : <>{typeLabel} -} - const Overview = () => { const { app: { pageNotice }, @@ -269,7 +174,7 @@ const Overview = () => { minWidth: '250px', render(_, __, item) { return ( - = props => { return [ bestBlockNumber > 0 && cacheTipBlockNumber > 0 ? `${+((cacheTipBlockNumber * 100) / bestBlockNumber).toFixed(2)}%` - : '0', + : '0.00%', `${cacheTipBlockNumber >= 0 ? localNumberFormatter(cacheTipBlockNumber) : '-'} / ${ bestBlockNumber >= 0 ? localNumberFormatter(bestBlockNumber) : '-' }`, diff --git a/packages/neuron-ui/src/components/TransactionType/index.tsx b/packages/neuron-ui/src/components/TransactionType/index.tsx new file mode 100644 index 0000000000..59ed2b91ab --- /dev/null +++ b/packages/neuron-ui/src/components/TransactionType/index.tsx @@ -0,0 +1,104 @@ +import React from 'react' +import { UANTokenName } from 'components/UANDisplay' +import { Trans, useTranslation } from 'react-i18next' +import { CONFIRMATION_THRESHOLD } from 'utils/const' + +const genTypeLabel = ( + type: 'send' | 'receive' | 'create' | 'destroy', + status: 'pending' | 'confirming' | 'success' | 'failed' +) => { + switch (type) { + case 'send': { + if (status === 'failed') { + return 'sent' + } + if (status === 'pending' || status === 'confirming') { + return 'sending' + } + return 'sent' + } + case 'receive': { + if (status === 'failed') { + return 'received' + } + if (status === 'pending' || status === 'confirming') { + return 'receiving' + } + return 'received' + } + default: + return type + } +} + +const TransactionType = ({ + item, + cacheTipBlockNumber, + bestKnownBlockNumber, + tokenNameClassName, +}: { + item: Omit & { status: State.Transaction['status'] | 'confirming' } + cacheTipBlockNumber: number + bestKnownBlockNumber: number + tokenNameClassName?: string +}) => { + const [t] = useTranslation() + let typeLabel: string = '--' + let { status } = item + let typeTransProps: { + i18nKey: string + components: JSX.Element[] + } = { + i18nKey: '', + components: [], + } + + if (item.blockNumber !== undefined) { + const confirmationCount = + item.blockNumber === null || item.status === 'failed' + ? 0 + : 1 + Math.max(cacheTipBlockNumber, bestKnownBlockNumber) - +item.blockNumber + + if (status === 'success' && confirmationCount < CONFIRMATION_THRESHOLD) { + status = 'confirming' + } + if (item.nftInfo) { + // NFT + const { type } = item.nftInfo + typeLabel = `${t(`overview.${genTypeLabel(type, status)}`)}` + } else if (item.sudtInfo?.sUDT) { + // Asset Account + if (['create', 'destroy'].includes(item.type)) { + // create/destroy an account + typeTransProps = { + i18nKey: `overview.${item.type}SUDT`, + components: [ + , + ], + } + } else { + // send/receive to/from an account + const type = +item.sudtInfo.amount <= 0 ? 'send' : 'receive' + typeLabel = `UDT ${t(`overview.${genTypeLabel(type, status)}`)}` + } + } else if (item.type === 'create' || item.type === 'destroy') { + // normal tx + if (item.assetAccountType === 'CKB') { + typeLabel = `${t(`overview.${item.type}`, { name: 'CKB' })}` + } else { + typeLabel = `${t(`overview.${item.type}`, { name: 'Unknown' })}` + } + } else { + typeLabel = item.nervosDao ? 'Nervos DAO' : t(`overview.${genTypeLabel(item.type, status)}`) + } + } + return typeTransProps.i18nKey ? : <>{typeLabel} +} + +TransactionType.displayName = 'TransactionType' + +export default TransactionType diff --git a/packages/neuron-ui/src/containers/Main/index.tsx b/packages/neuron-ui/src/containers/Main/index.tsx index 0f2175d155..7d77ae8242 100644 --- a/packages/neuron-ui/src/containers/Main/index.tsx +++ b/packages/neuron-ui/src/containers/Main/index.tsx @@ -2,8 +2,10 @@ import React, { useCallback, useMemo } from 'react' import { useNavigate, useLocation, Outlet } from 'react-router-dom' import { useTranslation } from 'react-i18next' import { useState as useGlobalState, useDispatch, dismissGlobalAlertDialog } from 'states' -import { useOnDefaultContextMenu, useOnLocaleChange } from 'utils' +import { useMigrate, useOnDefaultContextMenu, useOnLocaleChange } from 'utils' import AlertDialog from 'widgets/AlertDialog' +import Dialog from 'widgets/Dialog' +import Button from 'widgets/Button' import { useSubscription, useSyncChainData, useOnCurrentWalletChange } from './hooks' const MainContent = () => { @@ -49,6 +51,7 @@ const MainContent = () => { const onCancelGlobalDialog = useCallback(() => { dismissGlobalAlertDialog()(dispatch) }, [dispatch]) + const { isMigrateDialogShow, onCancel, onBackUp, onConfirm } = useMigrate() return (
@@ -61,6 +64,18 @@ const MainContent = () => { type={globalAlertDialog?.type ?? 'success'} onCancel={onCancelGlobalDialog} /> + + {t('messages.rebuild-sync') + .split('\n') + .map((s: string) => ( +

{s}

+ ))} +
+
+
) } diff --git a/packages/neuron-ui/src/containers/Navbar/navbar.module.scss b/packages/neuron-ui/src/containers/Navbar/navbar.module.scss index 09aad05f4f..c2ee9f8021 100644 --- a/packages/neuron-ui/src/containers/Navbar/navbar.module.scss +++ b/packages/neuron-ui/src/containers/Navbar/navbar.module.scss @@ -174,6 +174,7 @@ $hover-bg-color: #3cc68a4d; } a { + padding: 1px 0 1px 5px; &:hover { background-color: transparent; color: #fff; diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json index 4af0e2bc4c..4878419ed2 100644 --- a/packages/neuron-ui/src/locales/en.json +++ b/packages/neuron-ui/src/locales/en.json @@ -568,6 +568,7 @@ "experimental-message": "This is an experimental feature, it could change at any time. Please use with caution.", "rebuild-sync": "For better user experience, Neuron has adopted a new storage, which requires a migrating of data (estimated 20 ~ 60min).\nSorry for the inconvenience.", "migrate-warning": "Warning: The migration process may fail for unknown reasons resulting in resynchronization, please back up manually and start the migration!", + "migrate-ckb-data": "Migrate", "migrate": "Migrate", "secp256k1/blake160-address-required": "Secp256k1/blake160 address is required", "light-client-locktime-warning": "2.Light client mode doesn't support showing lock-time CKBytes.", diff --git a/packages/neuron-ui/src/locales/zh-tw.json b/packages/neuron-ui/src/locales/zh-tw.json index c965ac67f1..a1f2bde2c7 100644 --- a/packages/neuron-ui/src/locales/zh-tw.json +++ b/packages/neuron-ui/src/locales/zh-tw.json @@ -562,6 +562,7 @@ "experimental-message": "本頁面為實驗性功能,可能隨時變更。請謹慎使用。", "rebuild-sync": "為了提供更好的用戶體驗,Neuron 採取了新的存儲方案,該方案需要壹次性遷移數據(預期同步時間為 20~60 分鐘)。\n抱歉給您帶來不便。", "migrate-warning": "註意:遷移過程中可能由於未知原因失敗導致需要重新同步,請備份完成後開始遷移!", + "migrate-ckb-data": "數據遷移", "migrate": "遷移", "secp256k1/blake160-address-required": "請輸入 secp256k1/blake160 地址", "light-client-locktime-warning": "2.輕節點模式不支持展示到期解鎖的 CKBytes。", diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json index d9f7b3f354..67d31df813 100644 --- a/packages/neuron-ui/src/locales/zh.json +++ b/packages/neuron-ui/src/locales/zh.json @@ -305,9 +305,7 @@ "copy-balance": "复制余额", "copy-address": "复制地址", "create": "创建 {{name}} 资产账户", - "destroy": "销毁 {{name}} 资产账户", - "createSUDT": "创建 <0> 资产账户", - "destroySUDT": "销毁 <0> 资产账户" + "destroy": "销毁 {{name}} 资产账户" }, "transaction": { "window-title": "交易: {{hash}}", @@ -563,6 +561,7 @@ "experimental-message": "本页面为实验性功能,可能随时变更。请谨慎使用。", "rebuild-sync": "为了提供更好的用户体验,Neuron 採取了新的存储方案,该方案需要一次性迁移数据(预期同步时间为 20~60 分钟)。\n抱歉给您带来不便。", "migrate-warning": "注意:迁移过程中可能由于未知原因失败导致需要重新同步,请备份完成后开始迁移!", + "migrate-ckb-data": "数据迁移", "migrate": "迁移", "secp256k1/blake160-address-required": "请输入 secp256k1/blake160 地址", "light-client-locktime-warning": "2.轻节点模式不支持展示到期解锁的 CKBytes。", diff --git a/packages/neuron-ui/src/services/subjects.ts b/packages/neuron-ui/src/services/subjects.ts index 9d5e63bcdb..b78aebf9d2 100644 --- a/packages/neuron-ui/src/services/subjects.ts +++ b/packages/neuron-ui/src/services/subjects.ts @@ -37,13 +37,14 @@ const SubjectConstructor = ( return ipcRenderer ? { subscribe: (handler: (data: T) => void) => { - ipcRenderer.on(channel, (_e: Event, data: T) => { + const handlerWrap = (_e: Event, data: T) => { handler(data) - }) + } + ipcRenderer.on(channel, handlerWrap) return { unsubscribe: () => { if (isMulti) { - ipcRenderer.removeListener(channel, handler) + ipcRenderer.removeListener(channel, handlerWrap) } else { ipcRenderer.removeAllListeners(channel) } @@ -67,7 +68,7 @@ export const Navigation = SubjectConstructor('navigation') export const SetLocale = SubjectConstructor<(typeof LOCALES)[number]>('set-locale') export const DeviceSignIndex = SubjectConstructor('device-sign-index') export const MultisigOutputUpdate = SubjectConstructor('multisig-output-update') -export const Migrate = SubjectConstructor<'need-migrate' | 'migrating' | 'failed' | 'finish'>('migrate') +export const Migrate = SubjectConstructor<'need-migrate' | 'migrating' | 'failed' | 'finish'>('migrate', true) export default { DataUpdate, diff --git a/packages/neuron-ui/src/styles/index.scss b/packages/neuron-ui/src/styles/index.scss index d9d814bf82..1ee9bd160c 100755 --- a/packages/neuron-ui/src/styles/index.scss +++ b/packages/neuron-ui/src/styles/index.scss @@ -6,7 +6,7 @@ outline: none !important; -webkit-tap-highlight-color: none !important; user-select: none; - font-family: 'PingFang SC'; + font-family: 'PingFang SC', 'Microsoft YaHei', 'Inter-Regular', 'Inter-Medium'; } [type='button'], @@ -30,7 +30,7 @@ html { } body { - @include regular-text; + font-family: 'Inter-Regular', 'Inter-Medium'; margin: 0; padding: 0; background: #f8f8f8; diff --git a/packages/neuron-ui/src/utils/hooks/index.ts b/packages/neuron-ui/src/utils/hooks/index.ts index 261674a879..8de2d6897d 100644 --- a/packages/neuron-ui/src/utils/hooks/index.ts +++ b/packages/neuron-ui/src/utils/hooks/index.ts @@ -1,7 +1,7 @@ import { useState, useMemo, useCallback, useEffect, useRef } from 'react' -import { useNavigate } from 'react-router-dom' +import { useLocation, useNavigate } from 'react-router-dom' import { TFunction, i18n as i18nType } from 'i18next' -import { openContextMenu, requestPassword, migrateData } from 'services/remote' +import { openContextMenu, requestPassword, migrateData, getCkbNodeDataPath } from 'services/remote' import { loadedWalletIDs, syncRebuildNotification, wallets } from 'services/localCache' import { Migrate, SetLocale as SetLocaleSubject } from 'services/subjects' import { @@ -13,7 +13,7 @@ import { showPageNotice, useDispatch, } from 'states' -import { epochParser, isReadyByVersion, calculateClaimEpochValue, CONSTANTS } from 'utils' +import { epochParser, isReadyByVersion, calculateClaimEpochValue, CONSTANTS, isSuccessResponse } from 'utils' import { validateTokenId, validateAssetAccountName, @@ -24,7 +24,7 @@ import { validateAddress, validateAmountRange, } from 'utils/validators' -import { MenuItemConstructorOptions } from 'electron' +import { MenuItemConstructorOptions, shell } from 'electron' import { ErrorWithI18n, isErrorWithI18n } from 'exceptions' export * from './createSUDTAccount' @@ -405,10 +405,23 @@ export const useToggleChoiceGroupBorder = (containerSelector: string, borderClas } }, [containerSelector, borderClassName]) -export const useGlobalNotifications = ( - dispatch: React.Dispatch<{ type: AppActions.SetGlobalDialog; payload: State.GlobalDialogType }>, - hasDismissMigrate: boolean -) => { +export const useMigrate = () => { + const [isMigrateDialogShow, setIsMigrateDialogShow] = useState(false) + const [hasDismissMigrate, setHasDismissMigrate] = useState(false) + const [ckbDataPath, setCkbDataPath] = useState() + const location = useLocation() + useEffect(() => { + getCkbNodeDataPath().then(res => { + if (isSuccessResponse(res) && res.result) { + setCkbDataPath(res.result) + } + }) + }, [location.pathname]) + const onBackUp = useCallback(() => { + if (ckbDataPath) { + shell.openPath(ckbDataPath) + } + }, [ckbDataPath]) useEffect(() => { const lastVersion = syncRebuildNotification.load() const isVersionUpdate = isReadyByVersion(CONSTANTS.SYNC_REBUILD_SINCE_VERSION, lastVersion) @@ -420,16 +433,34 @@ export const useGlobalNotifications = ( migrateSubscription.unsubscribe() } else if (!hasDismissMigrate) { // means need click ok to migrate - dispatch({ - type: AppActions.SetGlobalDialog, - payload: 'rebuild-sync', - }) + setIsMigrateDialogShow(true) } }) return () => { migrateSubscription.unsubscribe() } - }, [dispatch, hasDismissMigrate]) + }, [hasDismissMigrate]) + const onCancel = useCallback(() => { + setIsMigrateDialogShow(false) + setHasDismissMigrate(true) + }, []) + const onConfirm = useCallback(() => { + migrateData() + .then(res => { + if (isSuccessResponse(res)) { + setIsMigrateDialogShow(false) + } + }) + .finally(() => { + syncRebuildNotification.save() + }) + }, []) + return { + isMigrateDialogShow, + onCancel, + onBackUp, + onConfirm, + } } export const useDidMount = (cb: () => void) => { diff --git a/packages/neuron-wallet/.env b/packages/neuron-wallet/.env index a1ddb2272b..f5fdc8c4f7 100644 --- a/packages/neuron-wallet/.env +++ b/packages/neuron-wallet/.env @@ -117,4 +117,4 @@ DAO_CODE_HASH=0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e MULTISIG_CODE_HASH=0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8 # CKB NODE OPTIONS -CKB_NODE_ASSUME_VALID_TARGET='0x6b6db6bb23e6e98f63b88e6cd38fa49f46980e5b816f620c71c6c9c74633ee54' +CKB_NODE_ASSUME_VALID_TARGET='0xd5e25ad24400f237aa5f72f3738a9ae77fe082a89937e75143fcc8ef5b009383' diff --git a/packages/neuron-wallet/package.json b/packages/neuron-wallet/package.json index b38cc8dd8d..d25caff4cd 100644 --- a/packages/neuron-wallet/package.json +++ b/packages/neuron-wallet/package.json @@ -3,7 +3,7 @@ "productName": "Neuron", "description": "CKB Neuron Wallet", "homepage": "https://www.nervos.org/", - "version": "0.110.3", + "version": "0.111.0", "private": true, "author": { "name": "Nervos Core Dev", @@ -91,12 +91,12 @@ "@types/sqlite3": "3.1.8", "@types/uuid": "8.3.4", "devtron": "1.4.0", - "electron": "24.7.1", + "electron": "24.8.5", "electron-build-env": "0.2.0", "electron-builder": "23.6.0", "electron-devtools-installer": "3.2.0", "jest-when": "3.5.2", - "neuron-ui": "0.110.3", + "neuron-ui": "0.111.0", "typescript": "5.0.4" } } diff --git a/scripts/update-valid-target.js b/scripts/update-valid-target.js index 78d2fbac0f..4ca12b6e55 100644 --- a/scripts/update-valid-target.js +++ b/scripts/update-valid-target.js @@ -26,9 +26,15 @@ const envFilePath = path.resolve(__dirname, '../packages/neuron-wallet/.env') const validTargetReg = /(CKB_NODE_ASSUME_VALID_TARGET=)[\S]*/ ;(async function () { - const tipBlockNumber = (await rpcRequest('get_tip_block_number')).result - const validTargetBlockNumber = `0x${(BigInt(tipBlockNumber) - BigInt(ESTIMATE_BLOCK_COUNT_PER_DAY)).toString(16)}` - const blockHash = (await rpcRequest('get_block_hash', [validTargetBlockNumber])).result - const originEnvContent = fs.readFileSync(envFilePath).toString('utf-8') - fs.writeFileSync(envFilePath, originEnvContent.replace(validTargetReg, `CKB_NODE_ASSUME_VALID_TARGET='${blockHash}'`)) + try { + console.info('start update env file') + const tipBlockNumber = (await rpcRequest('get_tip_block_number')).result + const validTargetBlockNumber = `0x${(BigInt(tipBlockNumber) - BigInt(ESTIMATE_BLOCK_COUNT_PER_DAY)).toString(16)}` + const blockHash = (await rpcRequest('get_block_hash', [validTargetBlockNumber])).result + const originEnvContent = fs.readFileSync(envFilePath).toString('utf-8') + fs.writeFileSync(envFilePath, originEnvContent.replace(validTargetReg, `CKB_NODE_ASSUME_VALID_TARGET='${blockHash}'`)) + console.info('write success') + } catch (error) { + console.error('write failed', error) + } })() diff --git a/yarn.lock b/yarn.lock index 4b975d42c9..5acc5f4844 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1374,9 +1374,9 @@ regenerator-runtime "^0.13.11" "@babel/runtime@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.15.tgz#38f46494ccf6cf020bd4eed7124b425e83e523b8" - integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" + integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== dependencies: regenerator-runtime "^0.14.0" @@ -8194,10 +8194,10 @@ electron-window-state@5.0.3: jsonfile "^4.0.0" mkdirp "^0.5.1" -electron@24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/electron/-/electron-24.7.1.tgz#62b6f7e444f99909e738afae1e3a5a38f9581bba" - integrity sha512-v7nMXqTl5e1sudOMe5P77ofb6WOKCCTOqBrxVwwBRvShm5udFa2EkNrzYpO53w2fdIVlKbfLhD5DdlmYAROGvQ== +electron@24.8.5: + version "24.8.5" + resolved "https://registry.yarnpkg.com/electron/-/electron-24.8.5.tgz#795e13670f89de927bc4e40fd2a64ff7f9f7c3b6" + integrity sha512-CWSF0CrD1XhxyoXUcCcEoJB8orMTHuOrkj2s87XU11vjgVJHhzhCBh9TVqhMQt7U6TtcGYa5kDIiLRekxJRaRA== dependencies: "@electron/get" "^2.0.0" "@types/node" "^18.11.18"