Skip to content

Commit

Permalink
feat: Support use sent cell when send CKB (#2963)
Browse files Browse the repository at this point in the history
  • Loading branch information
yanguoyu authored Dec 21, 2023
1 parent 1402f8b commit 94302cb
Show file tree
Hide file tree
Showing 18 changed files with 454 additions and 273 deletions.
116 changes: 92 additions & 24 deletions packages/neuron-ui/src/components/Send/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const updateTransactionWith =
setErrorMessage,
updateTransactionOutput,
isMainnet,
enableUseSentCell,
dispatch,
t,
consumeOutPoints,
Expand All @@ -61,6 +62,7 @@ const updateTransactionWith =
setErrorMessage: (val: string) => void
updateTransactionOutput?: ReturnType<typeof useUpdateTransactionOutput>
isMainnet: boolean
enableUseSentCell: boolean
dispatch: StateDispatch
t: TFunction
consumeOutPoints?: CKBComponents.OutPoint[]
Expand All @@ -87,6 +89,7 @@ const updateTransactionWith =
})),
feeRate: price,
consumeOutPoints,
enableUseSentCell,
}
return generator(realParams)
.then((res: any) => {
Expand Down Expand Up @@ -155,18 +158,31 @@ const useRemoveTransactionOutput = (dispatch: StateDispatch) =>
[dispatch]
)

const useOnTransactionChange = (
walletID: string,
items: State.Output[],
price: string,
isMainnet: boolean,
dispatch: StateDispatch,
isSendMax: boolean,
setTotalAmount: (val: string) => void,
setErrorMessage: (val: string) => void,
t: TFunction,
const useOnTransactionChange = ({
walletID,
items,
price,
isMainnet,
dispatch,
isSendMax,
setTotalAmount,
setErrorMessage,
t,
consumeOutPoints,
enableUseSentCell,
}: {
walletID: string
items: State.Output[]
price: string
isMainnet: boolean
dispatch: StateDispatch
isSendMax: boolean
setTotalAmount: (val: string) => void
setErrorMessage: (val: string) => void
t: TFunction
consumeOutPoints?: CKBComponents.OutPoint[]
) => {
enableUseSentCell: boolean
}) => {
useEffect(() => {
clearTimeout(generateTxTimer)
setErrorMessage('')
Expand All @@ -189,9 +205,22 @@ const useOnTransactionChange = (
dispatch,
t,
consumeOutPoints,
enableUseSentCell,
})
}, 300)
}, [walletID, items, price, isSendMax, dispatch, setTotalAmount, setErrorMessage, t, isMainnet, consumeOutPoints])
}, [
walletID,
items,
price,
isSendMax,
dispatch,
setTotalAmount,
setErrorMessage,
t,
isMainnet,
consumeOutPoints,
enableUseSentCell,
])
}

const useOnSubmit = (items: Readonly<State.Output[]>, isMainnet: boolean, dispatch: StateDispatch) =>
Expand Down Expand Up @@ -286,11 +315,13 @@ export const useGetBatchGeneratedTx = async ({
priceArray = [],
items,
isSendMax,
enableUseSentCell,
}: {
walletID: string
priceArray?: string[]
items: Readonly<State.Output[]>
isSendMax: boolean
enableUseSentCell?: boolean
}) => {
const getUpdateGeneratedTx = (params: Controller.GenerateTransactionParams) =>
(isSendMax ? generateSendingAllTx : generateTx)(params).then((res: ControllerResponse<State.Transaction>) => {
Expand All @@ -309,7 +340,9 @@ export const useGetBatchGeneratedTx = async ({
})),
}

const requestArray = priceArray.map(itemPrice => getUpdateGeneratedTx({ ...realParams, feeRate: itemPrice }))
const requestArray = priceArray.map(itemPrice =>
getUpdateGeneratedTx({ ...realParams, feeRate: itemPrice, enableUseSentCell })
)
const allPromiseResult = await Promise.allSettled<State.Transaction>(requestArray)

const feeRateValueArray: FeeRateValueArrayItemType[] = allPromiseResult?.map(
Expand All @@ -322,17 +355,29 @@ export const useGetBatchGeneratedTx = async ({
return feeRateValueArray
}

export const useInitialize = (
walletID: string,
items: Readonly<State.Output[]>,
generatedTx: any | null,
price: string,
sending: boolean,
isMainnet: boolean,
dispatch: React.Dispatch<any>,
t: TFunction,
export const useInitialize = ({
walletID,
items,
generatedTx,
price,
sending,
isMainnet,
consumeOutPoints,
enableUseSentCell,
dispatch,
t,
}: {
walletID: string
items: Readonly<State.Output[]>
generatedTx: any | null
price: string
sending: boolean
isMainnet: boolean
consumeOutPoints?: CKBComponents.OutPoint[]
) => {
enableUseSentCell: boolean
dispatch: React.Dispatch<any>
t: TFunction
}) => {
const fee = useMemo(() => calculateFee(generatedTx), [generatedTx])

const [totalAmount, setTotalAmount] = useState('0')
Expand Down Expand Up @@ -382,6 +427,7 @@ export const useInitialize = (
setErrorMessage,
updateTransactionOutput,
isMainnet,
enableUseSentCell,
dispatch,
t,
consumeOutPoints,
Expand All @@ -390,7 +436,18 @@ export const useInitialize = (
updateIsSendMax(false)
}
})
}, [walletID, updateTransactionOutput, price, items, dispatch, t, isMainnet, updateIsSendMax, consumeOutPoints])
}, [
walletID,
updateTransactionOutput,
price,
items,
dispatch,
t,
isMainnet,
updateIsSendMax,
consumeOutPoints,
enableUseSentCell,
])

const onSendMaxClick = useCallback(() => {
if (!isSendMax) {
Expand Down Expand Up @@ -436,6 +493,17 @@ export const useInitialize = (
}
}

export const useSendWithSentCell = () => {
const [enableUseSentCell, setEnableUseSentCell] = useState(false)
const onChangeEnableUseSentCell = useCallback(() => {
setEnableUseSentCell(v => !v)
}, [])
return {
enableUseSentCell,
onChangeEnableUseSentCell,
}
}

export default {
useInitialize,
}
46 changes: 30 additions & 16 deletions packages/neuron-ui/src/components/Send/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { HIDE_BALANCE } from 'utils/const'

import { isErrorWithI18n } from 'exceptions'
import { useSearchParams } from 'react-router-dom'
import { useInitialize } from './hooks'
import { useInitialize, useSendWithSentCell } from './hooks'
import styles from './send.module.scss'

const SendHeader = ({ balance, useConsumeCell }: { balance: string; useConsumeCell: boolean }) => {
Expand Down Expand Up @@ -69,6 +69,7 @@ const Send = () => {

const isMainnet = isMainnetUtil(networks, networkID)
const consumeOutPoints = useMemo(() => consumeCells?.map(v => v.outPoint), [useMemo])
const { enableUseSentCell, onChangeEnableUseSentCell } = useSendWithSentCell()

const {
outputs,
Expand All @@ -89,17 +90,18 @@ const Send = () => {
isSendMax,
onSendMaxClick: handleSendMaxClick,
updateIsSendMax,
} = useInitialize(
} = useInitialize({
walletID,
send.outputs,
send.generatedTx,
send.price,
items: send.outputs,
generatedTx: send.generatedTx,
price: send.price,
sending,
isMainnet,
enableUseSentCell,
consumeOutPoints,
dispatch,
t,
consumeOutPoints
)
})

const [searchParams] = useSearchParams()

Expand Down Expand Up @@ -134,18 +136,19 @@ const Send = () => {
[setLocktimeIndex, updateTransactionOutput]
)

useOnTransactionChange(
useOnTransactionChange({
walletID,
outputs,
send.price,
items: outputs,
price: send.price,
isMainnet,
dispatch,
isSendMax,
setTotalAmount,
setErrorMessage,
t,
consumeOutPoints
)
consumeOutPoints,
enableUseSentCell,
})

let errorMessageUnderTotal = errorMessage
try {
Expand Down Expand Up @@ -265,10 +268,21 @@ const Send = () => {
/>
</div>
<div className={styles.rightFooter}>
<Button type="reset" onClick={handleClear} label={t('send.reset')} />
<Button type="submit" disabled={disabled} label={t('send.send')}>
{sending ? <Spinner /> : (t('send.send') as string)}
</Button>
<label htmlFor="send-with-sent-cell" className={styles.allowUseSent}>
<input
type="checkbox"
id="send-with-sent-cell"
checked={enableUseSentCell}
onChange={onChangeEnableUseSentCell}
/>
<span>{t('send.allow-use-sent-cell')}</span>
</label>
<div className={styles.actions}>
<Button type="reset" onClick={handleClear} label={t('send.reset')} />
<Button type="submit" disabled={disabled} label={t('send.send')}>
{sending ? <Spinner /> : (t(enableUseSentCell ? 'send.submit-transaction' : 'send.send') as string)}
</Button>
</div>
</div>
</div>
</div>
Expand Down
34 changes: 28 additions & 6 deletions packages/neuron-ui/src/components/Send/send.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ $headerHeight: 104px;
position: relative;
border-radius: 16px;
background: var(--secondary-background-color);
min-height: 436px;

.content {
padding: 16px;
Expand All @@ -76,13 +77,34 @@ $headerHeight: 104px;
width: 100%;
bottom: 16px;
left: 0;
display: flex;
justify-content: center;
text-align: center;
.actions {
display: flex;
justify-content: center;

button {
width: 216px;
&:last-child {
margin-left: 12px;
button {
width: 216px;
&:last-child {
margin-left: 12px;
}
}
}
.allowUseSent {
display: inline-block;
margin-bottom: 16px;
color: var(--secondary-text-color);
input[type='checkbox'] {
display: none;
margin-right: 8px;
}
input[type='checkbox'] + span {
display: inline-block;
padding-left: 26px;
background: url('../../widgets/Icons/Radio.svg') no-repeat left top;
user-select: none;
}
input[type='checkbox']:checked + span {
background: url('../../widgets/Icons/RadioSelected.svg') no-repeat left top;
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion packages/neuron-ui/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,9 @@
"remove-receiving-address-msg": "Are you sure you want to remove the selected receiving address?",
"locktime-notice-content": "According to the actual running block height, there may be some time variances in locktime.",
"release-on": "Release on",
"locktime-warning": "Please ensure that receiver's wallet can support expiration unlocking. (Note: 1.Exchanges generally do not support expiration unlocking {{extraNote}})"
"locktime-warning": "Please ensure that receiver's wallet can support expiration unlocking. (Note: 1.Exchanges generally do not support expiration unlocking {{extraNote}})",
"allow-use-sent-cell": "Unconfirmed Outputs are allowed in this transaction.",
"submit-transaction": "Submit the transaction"
},
"receive": {
"title": "Receive",
Expand Down
4 changes: 3 additions & 1 deletion packages/neuron-ui/src/locales/zh-tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,9 @@
"remove-receiving-address-msg": "確定要刪除所選收款地址?",
"locktime-notice-content": "鎖定時間根據區塊鏈實際運行情況會有一定的誤差。",
"release-on": "鎖定至",
"locktime-warning": "請確保對方錢包支持到期解鎖功能。(註:1.交易所壹般不支持到期解鎖功能 {{extraNote}})"
"locktime-warning": "請確保對方錢包支持到期解鎖功能。(註:1.交易所壹般不支持到期解鎖功能 {{extraNote}})",
"allow-use-sent-cell": "允許使用待確認的 Outputs 構建交易",
"submit-transaction": "發起交易"
},
"receive": {
"title": "收款",
Expand Down
4 changes: 3 additions & 1 deletion packages/neuron-ui/src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,9 @@
"remove-receiving-address-msg": "确定要删除所选收款地址?",
"locktime-notice-content": "锁定时间根据区块链实际运行情况会有一定的误差。",
"release-on": "锁定至",
"locktime-warning": "请确保对方钱包支持到期解锁功能。(注:1.交易所一般不支持到期解锁功能 {{extraNote}})"
"locktime-warning": "请确保对方钱包支持到期解锁功能。(注:1.交易所一般不支持到期解锁功能 {{extraNote}})",
"allow-use-sent-cell": "允许使用待确认的 Outputs 构建交易",
"submit-transaction": "发起交易"
},
"receive": {
"title": "收款",
Expand Down
1 change: 1 addition & 0 deletions packages/neuron-ui/src/states/init/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const transactionState: State.DetailedTransaction = {
blockHash: '',
witnesses: [],
nervosDao: false,
size: 0,
}

export const chainState: Readonly<State.Chain> = {
Expand Down
1 change: 1 addition & 0 deletions packages/neuron-ui/src/types/App/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ declare namespace State {
outputs: DetailedOutput[]
outputsCount: string
witnesses: string[]
size: number
}
interface Output {
address: string | undefined
Expand Down
Loading

1 comment on commit 94302cb

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Packaging for test is done in 7286102330

Please sign in to comment.