Skip to content

Commit

Permalink
A-1207660367546315 (#174)
Browse files Browse the repository at this point in the history
  • Loading branch information
owlsua authored Jul 15, 2024
1 parent dc0a45b commit ba944dd
Show file tree
Hide file tree
Showing 14 changed files with 268 additions and 15 deletions.
3 changes: 2 additions & 1 deletion src/components/composed/Balance/Balance.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

.balance-btc span {
font-weight: 600;
font-size: 1.9rem;
font-size: 1.8rem;
}

.balance-usd {
Expand All @@ -47,6 +47,7 @@
bottom: -25px;
opacity: 0.2;
white-space: nowrap;
cursor: pointer;
}

.balance-locked:hover {
Expand Down
9 changes: 8 additions & 1 deletion src/components/composed/Balance/Balance.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useContext } from 'react'
import { useNavigate, useParams } from 'react-router-dom'

import { ReactComponent as BtcLogo } from '@Assets/images/btc-logo.svg'
import { LogoRound } from '@BasicComponents'
Expand All @@ -12,6 +13,8 @@ import TokenLogoRound from '../../basic/TokenLogoRound/TokenLogoRound'
const Balance = ({ balance, balanceLocked, exchangeRate, walletType }) => {
const { networkType } = useContext(SettingsContext)
const { tokenBalances } = useContext(NetworkContext)
const { coinType } = useParams()
const navigate = useNavigate()
// TODO Consider the correct format for 0,00 that might also be 0.00
const balanceInUSD =
networkType === AppInfo.NETWORK_TYPES.TESTNET
Expand Down Expand Up @@ -44,6 +47,10 @@ const Balance = ({ balance, balanceLocked, exchangeRate, walletType }) => {
)
}

const onLockedClick = () => {
navigate('/wallet/' + coinType + '/locked-balance')
}

return (
<div
className="balance-wrapper"
Expand All @@ -64,7 +71,7 @@ const Balance = ({ balance, balanceLocked, exchangeRate, walletType }) => {
<span>{Format.fiatValue(balanceInUSD)}</span> USD
</p>
{parseFloat(balanceLocked) > 0 ? (
<div className="balance-locked">
<div className="balance-locked" onClick={onLockedClick}>
Locked: {balanceLocked} {symbol()}
</div>
) : (
Expand Down
26 changes: 26 additions & 0 deletions src/components/composed/LockedBalanceList/LockedBalanceList.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.locked-table {
width: 100%;
}

.locked-table-wrapper {
display: flex;
justify-content: center;
align-items: flex-start;
height: 465px;
overflow: auto;
}

.locked-title {
text-align: left;
padding: 10px;
background: rgb(var(--color-green));
width: 50%;
color: rgb(var(--color-white));
}

.locked-loading-wrapper {
display: flex;
justify-content: center;
align-items: center;
height: 465px;
}
122 changes: 122 additions & 0 deletions src/components/composed/LockedBalanceList/LockedBalanceList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import React, { useContext, useState, useEffect, useCallback } from 'react'
import { NetworkContext } from '@Contexts'

import { Loading } from '@ComposedComponents'
import { Mintlayer } from '@APIs'
import { addDays } from 'date-fns'
import LockedBalanceListItem from './LockedBalanceListItem'
import './LockedBalanceList.css'

const LockedBalanceList = () => {
const { lockedUtxos, transactions, fetchingUtxos } =
useContext(NetworkContext)
const [loading, setLoading] = useState(false)
const [updatedUtxosList, setUpdatedUtxosList] = useState([])

const getBlockData = async (blockId) => {
try {
const blockData = await Mintlayer.getBlockDataByHash(blockId)
const parsedData = JSON.parse(blockData)
if (parsedData && parsedData.height) {
return parsedData.height
}
} catch (error) {
console.error('Failed to fetch block data:', error)
}
}

const getUpdatedUtxosWithDate = useCallback(
async (utxos) => {
setLoading(true)
const updatedUtxos = await Promise.all(
utxos.map(async (utxo) => {
if (utxo.utxo.lock.type === 'ForBlockCount') {
const initialTransaction = transactions.find(
(tx) => tx.txid === utxo.outpoint.source_id,
)
if (initialTransaction && !utxo.utxo.lock.content.unlockBlock) {
// Calculating the unlock date
const calculatedUnlockTimestamp =
addDays(
new Date(initialTransaction.date * 1000),
10,
).getTime() / 1000

const blockData = await getBlockData(initialTransaction.blockId)

utxo.utxo.lock.content = {
lockedFor: utxo.utxo.lock.content,
timestamp: calculatedUnlockTimestamp,
unlockBlock: blockData + utxo.utxo.lock.content,
}
}
}
return utxo
}),
)
setLoading(false)
return updatedUtxos
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[lockedUtxos, transactions],
)

useEffect(() => {
const fetchUpdatedUtxos = async () => {
const updatedUtxos = await getUpdatedUtxosWithDate(lockedUtxos)
const sortedUtxos = updatedUtxos.sort(
(a, b) => a.utxo.lock.content.timestamp - b.utxo.lock.content.timestamp,
)
setUpdatedUtxosList(sortedUtxos)
}

fetchUpdatedUtxos()
}, [lockedUtxos, transactions, getUpdatedUtxosWithDate])

return (
<>
<div className="locked-table-wrapper">
{(fetchingUtxos || loading) ? (
<div className="locked-loading-wrapper">
<Loading />
</div>
) : (
<table
className="locked-table"
data-testid="locked-table"
>
<thead>
<tr>
<th
style={{ padding: '10px', textAlign: 'left' }}
className="locked-title"
>
Date
</th>
<th
style={{ padding: '10px', textAlign: 'left' }}
className="locked-title"
>
Amount
</th>
</tr>
</thead>
<tbody>
{lockedUtxos &&
updatedUtxosList.map((utxo, index) => (
<LockedBalanceListItem
key={index}
index={index}
utxo={utxo}
transactions={transactions}
/>
))}
</tbody>
</table>
)}
</div>
</>
)
}

export default LockedBalanceList
Empty file.
34 changes: 34 additions & 0 deletions src/components/composed/LockedBalanceList/LockedBalanceListItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useMemo } from 'react'
import { format } from 'date-fns'

import './LockedBalanceListItem.css'

const LockedBalanceListItem = ({ index, utxo }) => {

const displayDate = useMemo(() => {
if (utxo.utxo.lock.type === 'ForBlockCount') {
return `~ ${format(
new Date(utxo.utxo.lock.content.timestamp * 1000),
'dd/MM/yyyy HH:mm',
)} (Block height: ${utxo.utxo.lock.content.unlockBlock})`
} else if (utxo.utxo.lock.type !== 'ForBlockCount') {
return format(
new Date(utxo.utxo.lock.content.timestamp * 1000),
'dd/MM/yyyy HH:mm',
)
}
}, [utxo])

return (
<tr
style={{
backgroundColor: index % 2 === 0 ? 'white' : 'rgb(247, 250, 250)',
}}
>
<td style={{ padding: '10px' }}>{displayDate}</td>
<td style={{ padding: '10px' }}>{utxo.utxo.value.amount.decimal} ML</td>
</tr>
)
}

export default LockedBalanceListItem
2 changes: 2 additions & 0 deletions src/components/composed/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import CurrentStaking from './CurrentStaking/CurrentStaking'
import HelpTooltip from './HelpTooltip/HelpTooltip'
import RestoreSeedField from './RestoreSeedField/RestoreSeedField'
import UpdateButton from './UpdateButton/UpdateButton'
import LockedBalanceList from './LockedBalanceList/LockedBalanceList'

export {
Balance,
Expand All @@ -44,4 +45,5 @@ export {
HelpTooltip,
RestoreSeedField,
UpdateButton,
LockedBalanceList,
}
37 changes: 25 additions & 12 deletions src/contexts/NetworkProvider/NetworkProvider.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import React, { createContext, useContext, useEffect, useState } from 'react'
import {
getAddressData,
getChainTip,
getTransactionData,
} from '../../services/API/Mintlayer/Mintlayer'

import { AccountContext, SettingsContext } from '@Contexts'
import { AppInfo } from '@Constants'
import { ML_ATOMS_PER_COIN } from '../../utils/Constants/AppInfo/AppInfo'
Expand Down Expand Up @@ -33,6 +29,7 @@ const NetworkProvider = ({ value: propValue, children }) => {
const [lockedBalance, setLockedBalance] = useState(0)
const [unusedAddresses, setUnusedAddresses] = useState({})
const [utxos, setUtxos] = useState([])
const [lockedUtxos, setLockedUtxos] = useState([])
const [transactions, setTransactions] = useState([])
const [feerate, setFeerate] = useState(0)

Expand Down Expand Up @@ -84,12 +81,12 @@ const NetworkProvider = ({ value: propValue, children }) => {

const addresses_data_receive = await Promise.all(
currentMlAddresses.mlReceivingAddresses.map((address) =>
getAddressData(address),
Mintlayer.getAddressData(address),
),
)
const addresses_data_change = await Promise.all(
currentMlAddresses.mlChangeAddresses.map((address) =>
getAddressData(address),
Mintlayer.getAddressData(address),
),
)
const addresses_data = [...addresses_data_receive, ...addresses_data_change]
Expand Down Expand Up @@ -143,7 +140,9 @@ const NetworkProvider = ({ value: propValue, children }) => {
setCurrentAccountId(accountID)

// fetch transactions data
const transactions = transaction_ids.map((txid) => getTransactionData(txid))
const transactions = transaction_ids.map((txid) =>
Mintlayer.getTransactionData(txid),
)
const transactions_data = await Promise.all(transactions)

const parsedTransactions = ML.getParsedTransactions(
Expand All @@ -160,11 +159,19 @@ const NetworkProvider = ({ value: propValue, children }) => {
const unconfirmedTransactions =
LocalStorageService.getItem(unconfirmedTransactionString) || []

const utxos = await Mintlayer.getWalletUtxos(addressList)
const parsedUtxos = utxos
const fetchedUtxos = await Mintlayer.getWalletUtxos(addressList)
const fetchedSpendableUtxos =
await Mintlayer.getWalletSpendableUtxos(addressList)

const parsedUtxos = fetchedUtxos
.map((utxo) => JSON.parse(utxo))
.filter((utxo) => utxo.length > 0)

const parsedSpendableUtxos = fetchedSpendableUtxos
.map((utxo) => JSON.parse(utxo))
.filter((utxo) => utxo.length > 0)
const available = parsedUtxos

const available = parsedSpendableUtxos
.flatMap((utxo) => [...utxo])
.filter((item) => item.utxo.value)
.filter((item) => {
Expand All @@ -189,7 +196,12 @@ const NetworkProvider = ({ value: propValue, children }) => {
setCurrentNetworkType(networkType)

const availableUtxos = available.map((item) => item)
const lockedUtxos = parsedUtxos
.flat()
.filter((obj) => obj.utxo.type === 'LockThenTransfer')

setUtxos(availableUtxos)
setLockedUtxos(lockedUtxos)

setFetchingUtxos(false)

Expand Down Expand Up @@ -305,7 +317,7 @@ const NetworkProvider = ({ value: propValue, children }) => {

useEffect(() => {
const getData = async () => {
const result = await getChainTip()
const result = await Mintlayer.getChainTip()
const { block_height } = JSON.parse(result)
setOnlineHeight(block_height)
}
Expand All @@ -321,6 +333,7 @@ const NetworkProvider = ({ value: propValue, children }) => {
tokenBalances,
// addresses,
utxos,
lockedUtxos,
transactions,
currentHeight,
onlineHeight,
Expand Down
5 changes: 5 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
CreateDelegationPage,
DelegationStakePage,
DelegationWithdrawPage,
LockedBalancePage,
} from '@Pages'

import {
Expand Down Expand Up @@ -232,6 +233,10 @@ const App = () => {
path="/wallet/:coinType/staking/create-delegation"
element={<CreateDelegationPage />}
/>
<Route
path="/wallet/:coinType/locked-balance"
element={<LockedBalancePage />}
/>
<Route
exact
path="/"
Expand Down
5 changes: 5 additions & 0 deletions src/pages/LockedBalance/LockedBalance.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.animate-list-accounts {
overflow: hidden;
transform: translateX(-200%);
transition: transform 1s ease-in-out;
}
14 changes: 14 additions & 0 deletions src/pages/LockedBalance/LockedBalance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { LockedBalanceList } from '@ComposedComponents'

import './LockedBalance.css'

const LockedBalancePage = () => {

return (
<>
<LockedBalanceList />
</>
)
}

export default LockedBalancePage
Loading

0 comments on commit ba944dd

Please sign in to comment.