Skip to content

Commit

Permalink
fix: renterd paginate transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
alexfreska committed Nov 28, 2023
1 parent 1f85815 commit 63aef99
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 108 deletions.
5 changes: 5 additions & 0 deletions .changeset/grumpy-bags-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'renterd': minor
---

Wallet transactions are now paginated.
18 changes: 18 additions & 0 deletions apps/renterd/components/Wallet/WalletFilterBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { WalletSyncWarning } from '@siafoundation/design-system'
import { useSyncStatus } from '../../hooks/useSyncStatus'

export function WalletFilterBar() {
const { isSynced, syncPercent, isWalletSynced, walletScanPercent } =
useSyncStatus()
return (
<div className="flex gap-2 w-full">
<WalletSyncWarning
isSynced={isSynced}
isWalletSynced={isWalletSynced}
syncPercent={syncPercent}
walletScanPercent={walletScanPercent}
/>
<div className="flex-1" />
</div>
)
}
113 changes: 17 additions & 96 deletions apps/renterd/components/Wallet/index.tsx
Original file line number Diff line number Diff line change
@@ -1,103 +1,23 @@
import {
EntityList,
EntityListItemProps,
PaginatorUnknownTotal,
WalletLayoutActions,
getTransactionType,
BalanceEvolution,
WalletSyncWarning,
} from '@siafoundation/design-system'
import {
useWallet,
useWalletPending,
useWalletTransactions,
} from '@siafoundation/react-renterd'
import { useMemo } from 'react'
import { useWallet } from '@siafoundation/react-renterd'
import { useDialog } from '../../contexts/dialog'
import { routes } from '../../config/routes'
import BigNumber from 'bignumber.js'
import { RenterdSidenav } from '../RenterdSidenav'
import { RenterdAuthedLayout } from '../RenterdAuthedLayout'
import { useSyncStatus } from '../../hooks/useSyncStatus'
import { EmptyState } from './EmptyState'
import { useTransactions } from '../../contexts/transactions'
import { WalletFilterBar } from './WalletFilterBar'

export function Wallet() {
const transactions = useWalletTransactions({
params: {
// Endpoint currently returns wrong end of txn list
// max: 50,
},
config: {
swr: {
refreshInterval: 60_000,
revalidateOnFocus: false,
},
},
})

const pending = useWalletPending()

const { openDialog } = useDialog()

const entities: EntityListItemProps[] | null = useMemo(() => {
if (!pending.data || !transactions.data) {
return null
}
return [
...(pending.data || []).map((t): EntityListItemProps => {
return {
type: 'transaction',
txType: getTransactionType(t),
// hash: t.ID,
// timestamp: new Date(t.Timestamp).getTime(),
// onClick: () => openDialog('transactionDetails', t.ID),
// sc: totals.sc,
unconfirmed: true,
}
}),
...(transactions.data || [])
.map((t): EntityListItemProps => {
return {
type: 'transaction',
txType: getTransactionType(t.raw),
hash: t.id,
timestamp: new Date(t.timestamp).getTime(),
onClick: () => openDialog('transactionDetails', t.id),
sc: new BigNumber(t.inflow).minus(t.outflow),
}
})
.sort((a, b) => (a.timestamp < b.timestamp ? 1 : -1)),
]
}, [pending.data, transactions.data, openDialog])

// This now works but the visx chart has an issue where the tooltip does not
// find the correct nearest datum when the data is not at a consistent
// interval due to axis scale issues. renterd needs to return clean data
// like hostd or we need to wait for this issue to be fixed:
// https://github.com/airbnb/visx/issues/1533
// until then renterd will use a line graph which does not have the issue.
const balances = useMemo(
() =>
transactions.data
?.sort((a, b) => (a.timestamp > b.timestamp ? 1 : -1))
.reduce((acc, t, i) => {
if (i === 0) {
return acc.concat({
sc: new BigNumber(t.inflow).minus(t.outflow).toNumber(),
timestamp: new Date(t.timestamp).getTime(),
})
}
return acc.concat({
sc: new BigNumber(acc[i - 1].sc)
.plus(t.inflow)
.minus(t.outflow)
.toNumber(),
timestamp: new Date(t.timestamp).getTime(),
})
}, []),
[transactions.data]
)

const wallet = useWallet()
const { dataset, offset, limit, pageCount, dataState } = useTransactions()
const { isSynced, syncPercent, isWalletSynced, walletScanPercent } =
useSyncStatus()

Expand Down Expand Up @@ -126,28 +46,29 @@ export function Wallet() {
sendSiacoin={() => openDialog('sendSiacoin')}
/>
}
stats={
<WalletSyncWarning
isSynced={isSynced}
isWalletSynced={isWalletSynced}
syncPercent={syncPercent}
walletScanPercent={walletScanPercent}
/>
}
stats={<WalletFilterBar />}
>
<div className="p-6 flex flex-col gap-5">
{balances?.length ? (
{/* {balances?.length ? (
<BalanceEvolution
// see comment above
chartType="line"
balances={balances}
isLoading={transactions.isValidating}
/>
) : null}
) : null} */}
<EntityList
title="Transactions"
entities={entities?.slice(0, 100)}
entities={dataset?.slice(0, 100)}
emptyState={<EmptyState />}
actions={
<PaginatorUnknownTotal
offset={offset}
limit={limit}
pageTotal={pageCount}
isLoading={dataState === 'loading'}
/>
}
/>
</div>
</RenterdAuthedLayout>
Expand Down
25 changes: 14 additions & 11 deletions apps/renterd/config/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AppProvider } from '../contexts/app'
import { ConfigProvider } from '../contexts/config'
import { OnboardingBar } from '../components/OnboardingBar'
import { TransfersBar } from '../components/TransfersBar'
import { TransactionsProvider } from '../contexts/transactions'

type Props = {
children: React.ReactNode
Expand All @@ -17,18 +18,20 @@ export function Providers({ children }: Props) {
<AppProvider>
<ConfigProvider>
<DialogProvider>
<ContractsProvider>
<HostsProvider>
<FilesProvider>
{/* this is here so that dialogs can use all the other providers,
<TransactionsProvider>
<ContractsProvider>
<HostsProvider>
<FilesProvider>
{/* this is here so that dialogs can use all the other providers,
and the other providers can trigger dialogs */}
<OnboardingBar />
<TransfersBar />
<Dialogs />
{children}
</FilesProvider>
</HostsProvider>
</ContractsProvider>
<OnboardingBar />
<TransfersBar />
<Dialogs />
{children}
</FilesProvider>
</HostsProvider>
</ContractsProvider>
</TransactionsProvider>
</DialogProvider>
</ConfigProvider>
</AppProvider>
Expand Down
132 changes: 132 additions & 0 deletions apps/renterd/contexts/transactions/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import {
EntityListItemProps,
getTransactionType,
useDatasetEmptyState,
} from '@siafoundation/design-system'
import {
useWalletPending,
useWalletTransactions,
} from '@siafoundation/react-renterd'
import { createContext, useContext, useMemo } from 'react'
import { useDialog } from '../dialog'
import BigNumber from 'bignumber.js'
import { useRouter } from 'next/router'

const defaultLimit = 50
const filters = []

function useTransactionsMain() {
const router = useRouter()
const limit = Number(router.query.limit || defaultLimit)
const offset = Number(router.query.offset || 0)
const transactions = useWalletTransactions({
params: {
// Endpoint currently returns wrong end of txn list
limit,
offset,
},
config: {
swr: {
refreshInterval: 60_000,
revalidateOnFocus: false,
},
},
})

const pending = useWalletPending()

const { openDialog } = useDialog()

const dataset: EntityListItemProps[] | null = useMemo(() => {
if (!pending.data || !transactions.data) {
return null
}
return [
...(pending.data || []).map((t): EntityListItemProps => {
return {
type: 'transaction',
txType: getTransactionType(t),
// hash: t.ID,
// timestamp: new Date(t.Timestamp).getTime(),
// onClick: () => openDialog('transactionDetails', t.ID),
// sc: totals.sc,
unconfirmed: true,
}
}),
...(transactions.data || [])
.map((t): EntityListItemProps => {
return {
type: 'transaction',
txType: getTransactionType(t.raw),
hash: t.id,
timestamp: new Date(t.timestamp).getTime(),
onClick: () => openDialog('transactionDetails', t.id),
sc: new BigNumber(t.inflow).minus(t.outflow),
}
})
.sort((a, b) => (a.timestamp < b.timestamp ? 1 : -1)),
]
}, [pending.data, transactions.data, openDialog])

// // This now works but the visx chart has an issue where the tooltip does not
// // find the correct nearest datum when the data is not at a consistent
// // interval due to axis scale issues. renterd needs to return clean data
// // like hostd or we need to wait for this issue to be fixed:
// // https://github.com/airbnb/visx/issues/1533
// // until then renterd will use a line graph which does not have the issue.
// const balances = useMemo(
// () =>
// transactions.data
// ?.sort((a, b) => (a.timestamp > b.timestamp ? 1 : -1))
// .reduce((acc, t, i) => {
// if (i === 0) {
// return acc.concat({
// sc: new BigNumber(t.inflow).minus(t.outflow).toNumber(),
// timestamp: new Date(t.timestamp).getTime(),
// })
// }
// return acc.concat({
// sc: new BigNumber(acc[i - 1].sc)
// .plus(t.inflow)
// .minus(t.outflow)
// .toNumber(),
// timestamp: new Date(t.timestamp).getTime(),
// })
// }, []),
// [transactions.data]
// )
const error = transactions.error
const dataState = useDatasetEmptyState(
dataset,
transactions.isValidating,
error,
filters
)

return {
dataset,
error,
dataState,
offset,
limit,
pageCount: dataset?.length || 0,
}
}

type State = ReturnType<typeof useTransactionsMain>

const TransactionsContext = createContext({} as State)
export const useTransactions = () => useContext(TransactionsContext)

type Props = {
children: React.ReactNode
}

export function TransactionsProvider({ children }: Props) {
const state = useTransactionsMain()
return (
<TransactionsContext.Provider value={state}>
{children}
</TransactionsContext.Provider>
)
}
4 changes: 3 additions & 1 deletion libs/react-renterd/src/bus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,9 @@ export function useWalletAddresses(args?: HookArgsSwr<void, string[]>) {

type WalletTransactionsParams = {
since?: number
max?: number
before?: number
offset?: number
limit?: number
}

export function useWalletTransactions(
Expand Down

0 comments on commit 63aef99

Please sign in to comment.