From 52a554635085ec9ac176f8151d7df4494e405239 Mon Sep 17 00:00:00 2001 From: devchenyan Date: Sun, 3 Mar 2024 14:04:52 +0800 Subject: [PATCH 1/2] feat: Displaying DAO rewards --- .../DepositDialog/depositDialog.module.scss | 101 +++++++++++------- .../src/components/DepositDialog/hooks.ts | 33 ++++++ .../src/components/DepositDialog/index.tsx | 66 ++++++++++-- .../src/components/NervosDAO/index.tsx | 6 +- packages/neuron-ui/src/locales/en.json | 3 + packages/neuron-ui/src/locales/es.json | 3 + packages/neuron-ui/src/locales/fr.json | 3 + packages/neuron-ui/src/locales/zh-tw.json | 4 + packages/neuron-ui/src/locales/zh.json | 3 + 9 files changed, 173 insertions(+), 49 deletions(-) diff --git a/packages/neuron-ui/src/components/DepositDialog/depositDialog.module.scss b/packages/neuron-ui/src/components/DepositDialog/depositDialog.module.scss index 821546c681..b2fc0b5edf 100644 --- a/packages/neuron-ui/src/components/DepositDialog/depositDialog.module.scss +++ b/packages/neuron-ui/src/components/DepositDialog/depositDialog.module.scss @@ -1,7 +1,11 @@ @import '../../styles/mixin.scss'; +.container { + width: 680px; +} + .slider { - margin-top: 16px; + margin-top: 10px; :global(.ms-Slider-thumb) { top: -8px; @@ -32,10 +36,31 @@ margin-top: 16px; } -.depositValueLabel { - line-height: 20px; - color: var(--secondary-text-color); - font-size: 14px; +.depositValueLabelWrap { + display: flex; + + .depositValueLabel { + line-height: 20px; + color: var(--secondary-text-color); + font-size: 14px; + } + .tooltip { + margin-left: 120px; + } + .tip { + width: 400px; + word-break: normal; + white-space: normal; + line-height: 180%; + } + + svg { + margin: 2px 4px 0; + cursor: pointer; + path { + fill: var(--primary-color); + } + } } .fee { @@ -43,46 +68,49 @@ justify-content: space-between; font-size: 14px; line-height: 20px; + margin-top: 4px; color: var(--main-text-color); + gap: 24px; & > div { - &:nth-last-child(1) { - width: 230px; - text-align: right; + &:first-child { + flex-shrink: 0; } } } -.notice { - $lineHeight: 24px; - display: flex; - box-sizing: border-box; - margin-top: 22px; - border: 1px solid rgba(252, 136, 0, 0.2); - padding: 7px 54px; - border-radius: 4px; - background: #fff6eb; - color: #f68c2a; - font-weight: 500; - font-size: 12px; - line-height: $lineHeight; - text-align: center; - - & > svg { - $size: 14px; - flex-shrink: 0; - margin: calc(($lineHeight - $size) / 2) 4px 0 0; - width: $size; - height: $size; - - g[fill='#D50000'] { - fill: currentColor; +.rewards { + padding: 6px 16px; + background: var(--tag-green-bg-color); + border-radius: 8px; + margin-top: 14px; + div { + display: flex; + justify-content: space-between; + color: var(--primary-color); + p { + margin: 0; + padding: 4px 0; + font-size: 14px; + line-height: 20px; } } +} - @media (prefers-color-scheme: dark) { - border-color: #4b391c; - background: #4b391c; +.acpContent { + display: flex; + .tip { + min-width: 190px; + word-break: normal; + white-space: normal; + line-height: 180%; + } + svg { + margin: 2px 4px 0; + cursor: pointer; + path { + fill: var(--primary-color); + } } } @@ -90,7 +118,7 @@ font-weight: 500; font-size: 12px; background: inherit; - color: #f68c2a; + color: var(--primary-color); border: none; padding: 0; margin: 0; @@ -111,6 +139,7 @@ gap: 8px; & > svg { + flex-shrink: 0; path { fill: #e5e5e5; diff --git a/packages/neuron-ui/src/components/DepositDialog/hooks.ts b/packages/neuron-ui/src/components/DepositDialog/hooks.ts index 2a28144db6..41fa272d06 100644 --- a/packages/neuron-ui/src/components/DepositDialog/hooks.ts +++ b/packages/neuron-ui/src/components/DepositDialog/hooks.ts @@ -275,3 +275,36 @@ export const useOnDepositDialogCancel = ({ clearGeneratedTx() }, [dispatch, onCloseDepositDialog, resetDepositValue, clearGeneratedTx]) } + +export const useDepositRewards = ({ + depositValue, + maxDepositValue, + disabled, + globalAPC, +}: { + depositValue: string + maxDepositValue: string | null + disabled: boolean + globalAPC: number +}) => { + const [annualRewards, monthRewards] = useMemo(() => { + if (disabled) return ['0', '0'] + + const value = CKBToShannonFormatter( + (Number(maxDepositValue || depositValue) - MIN_DEPOSIT_AMOUNT).toFixed(MAX_DECIMAL_DIGITS).toString() + ) + + const dpc = globalAPC / 365 / 100 + + const mRewards = (Number(value) * dpc * 30).toFixed(0).toString() + + const rewerds = (Number(value) * dpc * 360).toFixed(0).toString() + + return [rewerds, mRewards] + }, [depositValue, maxDepositValue, disabled, globalAPC]) + + return { + annualRewards, + monthRewards, + } +} diff --git a/packages/neuron-ui/src/components/DepositDialog/index.tsx b/packages/neuron-ui/src/components/DepositDialog/index.tsx index fd4125033f..abc69ca05f 100644 --- a/packages/neuron-ui/src/components/DepositDialog/index.tsx +++ b/packages/neuron-ui/src/components/DepositDialog/index.tsx @@ -7,6 +7,7 @@ import { openExternal } from 'services/remote' import { localNumberFormatter, shannonToCKBFormatter } from 'utils' import { Attention, Success } from 'widgets/Icons/icon' import Dialog from 'widgets/Dialog' +import Tooltip from 'widgets/Tooltip' import styles from './depositDialog.module.scss' import { useBalanceReserved, @@ -14,6 +15,7 @@ import { useGenerateDaoDepositTx, useOnDepositDialogCancel, useOnDepositDialogSubmit, + useDepositRewards, } from './hooks' const NERVOS_DAO_RFC_URL = @@ -28,6 +30,7 @@ interface DepositDialogProps { isTxGenerated: boolean suggestFeeRate: number walletID: string + globalAPC: number } const RfcLink = React.memo(() => ( @@ -53,8 +56,9 @@ const DepositDialog = ({ isDepositing, isTxGenerated, suggestFeeRate, + globalAPC, }: DepositDialogProps) => { - const [t] = useTranslation() + const [t, { language }] = useTranslation() const disabled = !isTxGenerated const { isBalanceReserved, onIsBalanceReservedChange, setIsBalanceReserved } = useBalanceReserved() const { depositValue, onChangeDepositValue, slidePercent, onSliderChange, resetDepositValue } = useDepositValue( @@ -81,6 +85,14 @@ const DepositDialog = ({ }, [disabled, onConfirm] ) + const { annualRewards, monthRewards } = useDepositRewards({ + depositValue, + maxDepositValue, + disabled, + globalAPC, + }) + + const isChinese = language === 'zh' || language.startsWith('zh-') return ( {isDepositing ? ( ) : (
- +
+ + + ]} /> +
+ } + > + + +
+
+ {t('nervos-dao.fee')} + {`${shannonToCKBFormatter(fee)}`} +
+
+
+
- {t('nervos-dao.fee')} - {`${shannonToCKBFormatter(fee)}`} +

{t(`nervos-dao.estimated-rewards`, { days: 30 })}

+

{shannonToCKBFormatter(monthRewards)} CKB

+
+
+

{t(`nervos-dao.estimated-rewards`, { days: 360 })}

+

{shannonToCKBFormatter(annualRewards)} CKB

-
- -
-
- ]} /> +
+ {t(`nervos-dao.estimated-apc`)} + {isChinese ? null : ( + {t(`nervos-dao.estimated-apc-tooltip`)}

} + > + +
+ )} +
+

{globalAPC}%

diff --git a/packages/neuron-ui/src/components/NervosDAO/index.tsx b/packages/neuron-ui/src/components/NervosDAO/index.tsx index 24fcef51da..c31269a8f0 100644 --- a/packages/neuron-ui/src/components/NervosDAO/index.tsx +++ b/packages/neuron-ui/src/components/NervosDAO/index.tsx @@ -222,6 +222,7 @@ const NervosDAO = () => { isDepositing={sending} isTxGenerated={!!send.generatedTx} suggestFeeRate={suggestFeeRate} + globalAPC={globalAPC} /> ) }, [ @@ -233,6 +234,7 @@ const NervosDAO = () => { sending, send.generatedTx, suggestFeeRate, + globalAPC, ]) const MemoizedWithdrawDialog = useMemo(() => { @@ -260,7 +262,7 @@ const NervosDAO = () => { const onlineAndSynced = ConnectionStatus.Online === connectionStatus && SyncStatus.SyncCompleted === syncStatus - const isEnglish = language === 'en' || language.startsWith('en-') + const isChinese = language === 'zh' || language.startsWith('zh-') return ( {
{t(`nervos-dao.apc`)} - {isEnglish && ( + {isChinese ? null : ( diff --git a/packages/neuron-ui/src/locales/en.json b/packages/neuron-ui/src/locales/en.json index db3b2d4754..895817fa68 100644 --- a/packages/neuron-ui/src/locales/en.json +++ b/packages/neuron-ui/src/locales/en.json @@ -695,6 +695,9 @@ "compensation-accumulated": "{{blockNumber}} blocks compensation accumulated", "withdraw-alert": "Hint: there are only {{epochs}} epochs (~{{hours}} hours) until the end of your current lock period. If you wish to withdraw in current lock period, please send withdraw request in time. There are {{nextLeftEpochs}} epochs(~{{days}} days) until the end of your next lock period.", "balance-not-reserved": "Don't reserve any CKBytes for future DAO operations (Not recommended)", + "estimated-rewards": "Estimated Rewards of {{days}} days", + "estimated-apc": "Estimated APC", + "estimated-apc-tooltip": "Estimated Annual Percentage Compensation", "deposit-amount": "Deposit Amount (CKB)", "deposit-record": { "deposited-at": "Deposited", diff --git a/packages/neuron-ui/src/locales/es.json b/packages/neuron-ui/src/locales/es.json index 9308fdfa2f..48427b46f6 100644 --- a/packages/neuron-ui/src/locales/es.json +++ b/packages/neuron-ui/src/locales/es.json @@ -678,6 +678,9 @@ "compensation-accumulated": "Compensación acumulada en {{blockNumber}} bloques", "withdraw-alert": "Advertencia: solo quedan {{epochs}} epochs ({{hours}} horas) hasta el final de su periodo de bloqueo actual. Si desea retirar en el periodo de bloqueo actual, envíe la solicitud de retiro a tiempo. Solo quedan {{nextLeftEpochs}} epochs ({{days}} días) hasta el final de su próximo periodo de bloqueo.", "balance-not-reserved": "No reservar ningún CKBytes para futuras operaciones de DAO (no se recomienda)", + "estimated-rewards": "Recompensas estimadas de {{días}} días", + "estimated-apc": "Estimación APC", + "estimated-apc-tooltip": "Estimación de Compensación Anual", "deposit-amount": "Cantidad a Depositar (CKB)", "deposit-record": { "deposited-at": "Depositado", diff --git a/packages/neuron-ui/src/locales/fr.json b/packages/neuron-ui/src/locales/fr.json index 873641eea1..743379ad4b 100644 --- a/packages/neuron-ui/src/locales/fr.json +++ b/packages/neuron-ui/src/locales/fr.json @@ -685,6 +685,9 @@ "compensation-accumulated": "{{blockNumber}} blocs de compensation accumulée", "withdraw-alert": "Astuce : il ne reste que {{epochs}} époques (~{{hours}} heures) jusqu'à la fin de votre période de verrouillage actuelle. Si vous souhaitez retirer pendant cette période de verrouillage, veuillez envoyer une demande de retrait à temps. Il reste {{nextLeftEpochs}} époques (~{{days}} jours) jusqu'à la fin de votre prochaine période de verrouillage.", "balance-not-reserved": "Ne pas réserver de CKBytes pour les futures opérations DAO (non recommandé)", + "estimated-rewards": "Récompenses estimées de {{days}} jours", + "estimated-apc": "Estimation de APC", + "estimated-apc-tooltip": "Estimation de Compensation Annuel", "deposit-amount": "Montant du dépôt (CKB)", "deposit-record": { "deposited-at": "Déposé", diff --git a/packages/neuron-ui/src/locales/zh-tw.json b/packages/neuron-ui/src/locales/zh-tw.json index cd7e92d5f4..a4e3e97a1d 100644 --- a/packages/neuron-ui/src/locales/zh-tw.json +++ b/packages/neuron-ui/src/locales/zh-tw.json @@ -689,6 +689,10 @@ "compensation-accumulated": "已累計 {{blockNumber}} 個塊的鎖定補貼", "withdraw-alert": "提示:本補貼申請距離 Nervos DAO 規則允許的最近一個鎖定週期僅剩下 {{epochs}} 個 epoch (約 {{hours}} 小時)。如果您希望在本鎖定週期取出,請及時提交取出申請,以確保取出申請能在本鎖定週期結束之前上鏈。下一個鎖定週期的結束時間預計為 {{nextLeftEpochs}} 個 epochs (約 {{days}} 天)。", "balance-not-reserved": "(不建議)不預留未來操作手續費", + "estimated-rewards": "{{days}}天預計獎勵", + "estimated-apc": "預計年化鎖定補貼率", + "estimated-apc-tooltip": "預計年化鎖定補貼率", + "deposit-amount": "存入金額 (CKB)", "deposit-record": { "deposited-at": "存入於", "completed-at": "已取出", diff --git a/packages/neuron-ui/src/locales/zh.json b/packages/neuron-ui/src/locales/zh.json index 37c2f45e91..d64f3bdf00 100644 --- a/packages/neuron-ui/src/locales/zh.json +++ b/packages/neuron-ui/src/locales/zh.json @@ -688,6 +688,9 @@ "compensation-accumulated": "已累计 {{blockNumber}} 个块的锁定补贴", "withdraw-alert": "提示:本补贴申请距离 Nervos DAO 规则允许的最近一个锁定周期仅剩下 {{epochs}} 个 epoch (约 {{hours}} 小时)。 如果您希望在本锁定周期取出,请及时提交取出申请,以确保取出申请能在本锁定周期结束之前上链。下一个锁定周期的结束时间预计为 {{nextLeftEpochs}} 个 epochs (约 {{days}} 天)。", "balance-not-reserved": "不预留未来操作手续费(不建议)", + "estimated-rewards": "{{days}}天预计奖励", + "estimated-apc": "预计年化锁定补贴率", + "estimated-apc-tooltip": "预计年化锁定补贴率", "deposit-amount": "存入金额 (CKB)", "deposit-record": { "deposited-at": "存入于", From c06fc7ca1eae48cfb656c730a798f2e201504b7f Mon Sep 17 00:00:00 2001 From: devchenyan Date: Thu, 4 Apr 2024 01:44:50 +0800 Subject: [PATCH 2/2] fix: spell error --- _typos.toml | 2 ++ .../src/services/transaction-sender.ts | 16 ++++++++-------- .../neuron-wallet/tests/services/cells.test.ts | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/_typos.toml b/_typos.toml index ae82742a0c..0afbdd74c5 100644 --- a/_typos.toml +++ b/_typos.toml @@ -1,6 +1,8 @@ [default.extend-words] thur = "thur" numer = "numer" +HD = "HD" +hd = "hd" # defined in database schema lastest = "lastest" diff --git a/packages/neuron-wallet/src/services/transaction-sender.ts b/packages/neuron-wallet/src/services/transaction-sender.ts index d91b4e7b74..139e6f8179 100644 --- a/packages/neuron-wallet/src/services/transaction-sender.ts +++ b/packages/neuron-wallet/src/services/transaction-sender.ts @@ -674,8 +674,8 @@ export default class TransactionSender { const currentNetwork = NetworksService.getInstance().getCurrent() const rpcService = new RpcService(currentNetwork.remote, currentNetwork.type) - const depositeOutput = await CellsService.getLiveCell(outPoint) - if (!depositeOutput) { + const depositOutput = await CellsService.getLiveCell(outPoint) + if (!depositOutput) { throw new CellIsNotYetLive() } const prevTx = await rpcService.getTransaction(outPoint.txHash) @@ -690,7 +690,7 @@ export default class TransactionSender { const tx: Transaction = await TransactionGenerator.startWithdrawFromDao( walletID, outPoint, - depositeOutput, + depositOutput, depositBlockHeader!.number, depositBlockHeader!.hash, changeAddress!.address, @@ -736,13 +736,13 @@ export default class TransactionSender { if (!withdrawOutput.depositOutPoint) { throw new Error('DAO has not finish step first withdraw') } - const depositeTx = await rpcService.getTransaction(withdrawOutput.depositOutPoint.txHash) - if (!depositeTx?.txStatus.blockHash) { - throw new Error(`Get deposite block hash failed with tx hash ${withdrawOutput.depositOutPoint.txHash}`) + const depositTx = await rpcService.getTransaction(withdrawOutput.depositOutPoint.txHash) + if (!depositTx?.txStatus.blockHash) { + throw new Error(`Get deposit block hash failed with tx hash ${withdrawOutput.depositOutPoint.txHash}`) } - const depositBlockHeader = await rpcService.getHeader(depositeTx.txStatus.blockHash) + const depositBlockHeader = await rpcService.getHeader(depositTx.txStatus.blockHash) if (!depositBlockHeader) { - throw new Error(`Get Header failed with blockHash ${depositeTx.txStatus.blockHash}`) + throw new Error(`Get Header failed with blockHash ${depositTx.txStatus.blockHash}`) } const depositEpoch = this.parseEpoch(BigInt(depositBlockHeader.epoch)) const depositCapacity: bigint = BigInt(withdrawOutput.capacity) diff --git a/packages/neuron-wallet/tests/services/cells.test.ts b/packages/neuron-wallet/tests/services/cells.test.ts index 3bb81943f1..8d3dcd17d1 100644 --- a/packages/neuron-wallet/tests/services/cells.test.ts +++ b/packages/neuron-wallet/tests/services/cells.test.ts @@ -630,7 +630,7 @@ describe('CellsService', () => { ) ).rejects.toThrow(new LiveCapacityNotEnough()) }) - it('left capcity not enough for a cell throw CapacityNotEnoughForChange', async () => { + it('left capacity not enough for a cell throw CapacityNotEnoughForChange', async () => { await createMultisigCell(toShannon('1000'), OutputStatus.Sent, multisigInfo) await expect( CellsService.gatherInputs( @@ -660,7 +660,7 @@ describe('CellsService', () => { ) ).rejects.toThrow(new LiveCapacityNotEnough()) }) - it('left capcity not enough for a cell throw CapacityNotEnoughForChange', async () => { + it('left capacity not enough for a cell throw CapacityNotEnoughForChange', async () => { await expect( CellsService.gatherInputs( toShannon('990'),