Skip to content

Commit

Permalink
Support "amend a pending transaction" (#3045)
Browse files Browse the repository at this point in the history
Co-authored-by: Chen Yu <[email protected]>
  • Loading branch information
devchenyan and Keith-CY authored Mar 14, 2024
1 parent 4055ab6 commit 57b018e
Show file tree
Hide file tree
Showing 32 changed files with 1,637 additions and 137 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
@import '../../styles/mixin.scss';
$bottomHeight: 24px;
$headerHeight: 72px;
$noticeHeight: 60px;

.layout {
display: flex;

.left {
flex: 1;
position: relative;

.addressCell {
margin-bottom: 10px;
.label {
font-size: 14px;
line-height: 20px;
color: var(--secondary-text-color);
margin-bottom: 8px;
}
.content {
font-family: 'JetBrains Mono';
display: flex;
align-items: center;
color: var(--main-text-color);
border: 1px solid var(--divide-line-color);
background-color: var(--input-disabled-color);
border-radius: 8px;
padding: 10px 16px;
word-break: break-word;
white-space: break-spaces;
}
}

.inputCell {
background: var(--secondary-background-color);
padding: 20px 16px 18px;
border-radius: 16px;
margin-bottom: 16px;
.addresstField {
font-family: 'JetBrains Mono';
}
.textFieldClass {
margin-bottom: 10px;
}
}

.leftFooter {
position: absolute;
width: 100%;
bottom: 0;
left: 0;
height: 80px;
display: flex;
justify-content: center;
align-items: center;

.addButton {
min-width: 216px;
padding: 20px;
box-shadow: 0 0 10px var(--primary-color);
display: flex;
align-items: center;
justify-content: center;
&_icon {
margin-right: 8px;
}
svg {
g,
path {
fill: var(--primary-text-color);
}
}
}
}
}

&.withFullySynced {
.right {
height: calc(100vh - $headerHeight - $bottomHeight - $noticeHeight);
}
}

.right {
margin-left: 16px;
flex: 1;
position: relative;
border-radius: 16px;
background: var(--secondary-background-color);
height: calc(100vh - $headerHeight - $bottomHeight);
$actionHeight: 108px;

.content {
$contentPadding: 16px;
padding: 16px;
/**
These styles are for showing the full tips, because of content needs to scroll on the y-axis.
Then the overflow property that is set as scroll will truncate the tips overflow of the content.
So I need to expand the content's left to show the full tips.
*/
position: relative;
left: -48px;
padding-left: 64px;
width: calc(100% - 32px);
overflow-y: scroll;
height: calc(100% - $actionHeight - 2 * $contentPadding);
}

.rightFooter {
position: absolute;
width: 100%;
bottom: 16px;
left: 0;
text-align: center;
.actions {
display: flex;
justify-content: center;

button {
width: 216px;
&:last-child {
margin-left: 12px;
}
}
}
}
}
}

.headerContainer {
display: flex;
align-items: center;

.goBack {
margin-right: 8px;
cursor: pointer;
g,
path {
stroke: var(--main-text-color);
}
}
.btn {
margin-left: 12px;
min-width: 30px;
height: 16px;
padding: 0 8px;
border-radius: 0;
border-left: 1px solid var(--button-cancel-color);
svg {
g,
path {
fill: var(--main-text-color);
}
}
}

.balance {
font-size: 14px;
}
}
147 changes: 147 additions & 0 deletions packages/neuron-ui/src/components/AmendSUDTSend/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import React, { useState, useCallback, useEffect, useMemo } from 'react'
import { TFunction } from 'i18next'
import { AppActions } from 'states/stateProvider/reducer'
import { getTransaction as getOnChainTransaction } from 'services/chain'
import { getTransaction as getSentTransaction, getTransactionSize, getTransactionList } from 'services/remote'
import { isSuccessResponse } from 'utils'

export const useInitialize = ({
hash,
walletID,
dispatch,
}: {
hash: string
walletID: string
isMainnet: boolean
dispatch: React.Dispatch<any>
t: TFunction
}) => {
const [transaction, setTransaction] = useState<State.GeneratedTx | null>(null)
const [size, setSize] = useState(0)
const [minPrice, setMinPrice] = useState('0')
const [price, setPrice] = useState('0')
const [description, setDescription] = useState('')
const [showConfirmedAlert, setShowConfirmedAlert] = useState(false)
const [sudtInfo, setSudtInfo] = useState<State.Transaction['sudtInfo'] | null>(null)
const [txValue, setTxValue] = useState('0')

const onDescriptionChange = useCallback(
(e: React.SyntheticEvent<HTMLInputElement>) => {
const { value } = e.target as HTMLInputElement
setDescription(value)
},
[dispatch]
)

const fee = useMemo(() => {
const ratio = BigInt(1000)
const base = BigInt(size) * BigInt(price)
const curFee = base / ratio
if (curFee * ratio < base) {
return curFee + BigInt(1)
}
return curFee
}, [price, size])

const fetchInitData = useCallback(async () => {
const {
// @ts-expect-error Replace-By-Fee (RBF)
min_replace_fee: minFee,
transaction: { outputsData },
} = await getOnChainTransaction(hash)
if (!minFee) {
setShowConfirmedAlert(true)
}

const listRes = await getTransactionList({
walletID,
pageNo: 1,
pageSize: 10,
keywords: hash,
})
if (isSuccessResponse(listRes)) {
const list = listRes.result.items
if (list.length) {
const { sudtInfo: info, value } = list[0]
setSudtInfo(info)
setTxValue(value)
}
}

const txRes = await getSentTransaction({ hash, walletID })
if (isSuccessResponse(txRes)) {
const tx = txRes.result

setTransaction({ ...tx, outputsData })

const sizeRes = await getTransactionSize(tx)

if (isSuccessResponse(sizeRes) && typeof sizeRes.result === 'number') {
setSize(sizeRes.result)
if (minFee) {
const mPrice = ((BigInt(minFee) * BigInt(1000)) / BigInt(sizeRes.result)).toString()
setMinPrice(mPrice)
setPrice(mPrice)
}
}
}
}, [hash, setShowConfirmedAlert, setPrice, setTransaction, setSize, setMinPrice])

useEffect(() => {
fetchInitData()
}, [])

const onSubmit = useCallback(
async (e: React.FormEvent) => {
const {
dataset: { walletId, status },
} = e.target as HTMLFormElement
e.preventDefault()
if (status !== 'ready' || !transaction) {
return
}
try {
// @ts-expect-error Replace-By-Fee (RBF)
const { min_replace_fee: minFee } = await getOnChainTransaction(hash)
if (!minFee) {
setShowConfirmedAlert(true)
return
}

const actionType =
transaction.inputs.length > transaction.witnesses.length ? 'send-sudt' : 'send-acp-sudt-to-new-cell'

dispatch({
type: AppActions.RequestPassword,
payload: {
walletID: walletId as string,
amendHash: hash,
actionType,
},
})
} catch {
// ignore
}
},
[dispatch, walletID, hash, setShowConfirmedAlert, transaction]
)

return {
setPrice,
price,
description,
onDescriptionChange,
fee,
transaction,
setTransaction,
minPrice,
showConfirmedAlert,
onSubmit,
sudtInfo,
txValue,
}
}

export default {
useInitialize,
}
Loading

1 comment on commit 57b018e

@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 8276418794

Please sign in to comment.