-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement RBF and CPFP with new fees package and add pending transactions view in @caravan/coordinator #116
Closed
Legend101Zz
wants to merge
12
commits into
caravan-bitcoin:main
from
Legend101Zz:coordinator-fee-bumping
Closed
Changes from 4 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
2781e95
Implement RBF and CPFP with new fees package and add pending transact…
Legend101Zz efd947f
Revert "Implement RBF and CPFP with new fees package and add pending …
Legend101Zz 210edc4
feat: add RBF toggle button and functionality to signal RBF with sequ…
Legend101Zz fae5397
feat(coordinator):Introduce 'Pending Transactions' tab for fee bumping
Legend101Zz 193ace1
add fees hook : Code cleaning by taking out the code from pending com…
Legend101Zz 41b3cc3
refactor : hooks index file to export fees hook
Legend101Zz 94df4f1
changes to package.json and UI improvements in pendingTx table
Legend101Zz fd776ad
refactor useGetPendingTransactions to give full tx details including …
Legend101Zz 9f2142e
refactor: Pending Transaction Table ... added additional warning , UI…
Legend101Zz 7237530
Add : CPFP UI and functionality
Legend101Zz 5f3c8f6
refactor: WalletPendingTransactions
Legend101Zz bd4842d
Add : RBF UI and functionality
Legend101Zz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
162 changes: 162 additions & 0 deletions
162
apps/coordinator/src/components/Wallet/WalletPendingTransactions.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
import React, { useEffect, useState } from "react"; | ||
import { useSelector } from "react-redux"; | ||
import { Box, Paper } from "@mui/material"; | ||
import { styled } from "@mui/material/styles"; | ||
import { useGetClient } from "../../hooks"; | ||
// import { TransactionAnalyzer } from "@caravan/bitcoin"; | ||
import { AnalyzedTransaction, RootState, UTXO } from "./fee-bumping/types"; | ||
import { calculateTimeElapsed } from "./fee-bumping/utils"; | ||
import TransactionTable from "./fee-bumping/PendingTransactionTable"; | ||
import RBFOptionsDialog from "./fee-bumping/rbf/RBFOptionsDialog"; | ||
import AccelerateFeeDialog from "./fee-bumping/rbf/AccelerateFeeDialog"; | ||
import CancelTransactionDialog from "./fee-bumping/rbf/CancelTransactionDialog"; | ||
|
||
const StyledPaper = styled(Paper)(({ theme }) => ({ | ||
padding: theme.spacing(3), | ||
marginBottom: theme.spacing(2), | ||
})); | ||
|
||
const WalletPendingTransactions: React.FC = () => { | ||
const [pendingTransactions, setPendingTransactions] = useState< | ||
AnalyzedTransaction[] | ||
>([]); | ||
const [selectedTx, setSelectedTx] = useState<AnalyzedTransaction | null>( | ||
null, | ||
); | ||
const [showRBFOptions, setShowRBFOptions] = useState(false); | ||
const [showIncreaseFees, setShowIncreaseFees] = useState(false); | ||
const [showCancelTx, setShowCancelTx] = useState(false); | ||
const [isLoading, setIsLoading] = useState(true); | ||
const [error, setError] = useState<string | null>(null); | ||
|
||
const network = useSelector((state: RootState) => state.settings.network); | ||
const walletSlices = useSelector((state: RootState) => [ | ||
...Object.values(state.wallet.deposits.nodes), | ||
...Object.values(state.wallet.change.nodes), | ||
]); | ||
const blockchainClient = useGetClient(); | ||
|
||
useEffect(() => { | ||
fetchPendingTransactions(); | ||
}, [network, walletSlices, blockchainClient]); | ||
|
||
const fetchPendingTransactions = async () => { | ||
try { | ||
const pendingTxs = walletSlices | ||
.flatMap((slice) => slice.utxos) | ||
.filter((utxo) => !utxo.confirmed); | ||
|
||
const currentNetworkFeeRate = await getCurrentNetworkFeeRate(); | ||
|
||
const analyzedTransactions = await Promise.all( | ||
pendingTxs.map(async (utxo) => | ||
analyzeTransaction(utxo, currentNetworkFeeRate), | ||
), | ||
); | ||
|
||
setPendingTransactions(analyzedTransactions); | ||
} catch (error) { | ||
console.error("Error fetching pending transactions:", error); | ||
setError("Failed to fetch pending transactions. Please try again later."); | ||
} finally { | ||
setIsLoading(false); | ||
} | ||
}; | ||
|
||
const getCurrentNetworkFeeRate = async (): Promise<number> => { | ||
try { | ||
return await blockchainClient.getFeeEstimate(); | ||
} catch (error) { | ||
console.error("Error fetching network fee rate:", error); | ||
return 1; // Default to 1 sat/vB if unable to fetch | ||
} | ||
}; | ||
|
||
const analyzeTransaction = async ( | ||
utxo: UTXO, | ||
currentNetworkFeeRate: number, | ||
): Promise<AnalyzedTransaction> => { | ||
// const analyzer = new TransactionAnalyzer({ | ||
// txHex: utxo.transactionHex, | ||
// network, | ||
// targetFeeRate: currentNetworkFeeRate, | ||
// // Add other required options for TransactionAnalyzer | ||
// }); | ||
// const analysis = analyzer.analyze(); | ||
|
||
return { | ||
...utxo, | ||
timeElapsed: calculateTimeElapsed(utxo.time), | ||
currentFeeRate: currentNetworkFeeRate, | ||
canRBF: true, | ||
canCPFP: false, | ||
}; | ||
}; | ||
|
||
// const estimateBlocksToMine = (feeRate: number): number => { | ||
// TO DO (MRIGESH) : Implement new methods in client package's BlockchainClient class | ||
// to enable use of this method ... | ||
// }; | ||
|
||
const handleRBF = (tx: AnalyzedTransaction) => { | ||
setSelectedTx(tx); | ||
setShowRBFOptions(true); | ||
}; | ||
|
||
const handleCPFP = (tx: AnalyzedTransaction) => { | ||
console.log("CPFP initiated for transaction:", tx.txid); | ||
//To Implement CPFP logic here | ||
}; | ||
|
||
const handleIncreaseFees = () => { | ||
setShowRBFOptions(false); | ||
setShowIncreaseFees(true); | ||
}; | ||
|
||
const handleCancelTx = () => { | ||
setShowRBFOptions(false); | ||
setShowCancelTx(true); | ||
}; | ||
|
||
const closeAllModals = () => { | ||
setShowRBFOptions(false); | ||
setShowIncreaseFees(false); | ||
setShowCancelTx(false); | ||
setSelectedTx(null); | ||
}; | ||
|
||
return ( | ||
<Box sx={{ width: "100%" }}> | ||
<StyledPaper elevation={3}> | ||
<TransactionTable | ||
transactions={pendingTransactions} | ||
onRBF={handleRBF} | ||
onCPFP={handleCPFP} | ||
isLoading={isLoading} | ||
error={error} | ||
/> | ||
</StyledPaper> | ||
|
||
<RBFOptionsDialog | ||
open={showRBFOptions} | ||
onClose={closeAllModals} | ||
onIncreaseFees={handleIncreaseFees} | ||
onCancelTx={handleCancelTx} | ||
/> | ||
|
||
<AccelerateFeeDialog | ||
open={showIncreaseFees} | ||
onClose={closeAllModals} | ||
onConfirm={closeAllModals} | ||
/> | ||
|
||
<CancelTransactionDialog | ||
open={showCancelTx} | ||
onClose={closeAllModals} | ||
onConfirm={closeAllModals} | ||
/> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default WalletPendingTransactions; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this could all be pulled out as a hook, something like
useGetPendingTransactions
. We'd need some way to set an error from inside the hook though.