1249c0df71
* chore: initial commit * refactor: remove unnecessary wrappers * style: add missing newline * chore: bump bee-js * chore: ignore any cast in fdp * fix: remove cid import * fix: make TextEncoder and TextDecoder available in jest * refactor: dedupe stamp ttl second conversion * refactor: use convenience methods from bee-js * feat: update to bee-js for restored ens support * fix: bump bee-js to get download fix * fix: resolve feed before downloading reference * fix: fix token displays * fix: fix token input modal error message * refactor: remove wallet balance provider * chore: remove dead code * refactor: upcoming bee js 0.15.0 (#692) * chore: initial commit * fix: do not break page when duration seconds is 0 * ci: remove cache * chore: upgrade bee-js * feat: bee-js and bee v2.6 compatibility * chore: switch upcoming/bee-js to ethersphere/bee-js
116 lines
3.6 KiB
TypeScript
116 lines
3.6 KiB
TypeScript
import { AllSettlements, Bee, BZZ, LastCashoutActionResponse, PeerBalance, Settlements } from '@ethersphere/bee-js'
|
|
import { useEffect, useState } from 'react'
|
|
import { makeRetriablePromise, unwrapPromiseSettlements } from '../utils'
|
|
|
|
interface UseAccountingHook {
|
|
isLoadingUncashed: boolean
|
|
totalUncashed: BZZ
|
|
accounting: Accounting[] | null
|
|
}
|
|
|
|
export interface Accounting {
|
|
peer: string
|
|
uncashedAmount: BZZ
|
|
balance: BZZ
|
|
received: BZZ
|
|
sent: BZZ
|
|
total: BZZ
|
|
}
|
|
|
|
/**
|
|
* Merges the balances, settlements and uncashedAmounts arrays into single array which is sorted by uncashed amounts (if any)
|
|
*
|
|
* @param balances Balances for all peers
|
|
* @param settlements Settlements for all peers which has some settlement
|
|
* @param uncashedAmounts Array of getPeerLastCashout responses which is needed to calculate uncashed amount
|
|
*
|
|
* @returns
|
|
*/
|
|
function mergeAccounting(
|
|
balances: PeerBalance[] | null,
|
|
settlements?: Settlements[],
|
|
uncashedAmounts?: LastCashoutActionResponse[],
|
|
): Accounting[] | null {
|
|
// Settlements or balances are still loading or there is an error -> return null
|
|
if (!balances || !settlements) return null
|
|
|
|
const accounting: Record<string, Accounting> = {}
|
|
|
|
balances.forEach(
|
|
// Some peers may not have settlement but all have balance (therefore initialize sent, received and uncashed to 0)
|
|
({ peer, balance }) =>
|
|
(accounting[peer] = {
|
|
peer,
|
|
balance,
|
|
sent: BZZ.fromPLUR('0'),
|
|
received: BZZ.fromPLUR('0'),
|
|
uncashedAmount: BZZ.fromPLUR('0'),
|
|
total: balance,
|
|
}),
|
|
)
|
|
|
|
settlements.forEach(
|
|
({ peer, sent, received }) =>
|
|
(accounting[peer] = {
|
|
...accounting[peer],
|
|
sent,
|
|
received,
|
|
total: accounting[peer].balance.plus(received).minus(sent),
|
|
}),
|
|
)
|
|
|
|
// If there are no cheques (and hence last cashout actions)
|
|
if (!uncashedAmounts) return Object.values(accounting).sort((a, b) => (a.peer < b.peer ? -1 : 1))
|
|
|
|
uncashedAmounts?.forEach(({ peer, uncashedAmount }) => {
|
|
accounting[peer].uncashedAmount = uncashedAmount
|
|
})
|
|
|
|
// Return sorted by the uncashed amount first and then by the peer id
|
|
return Object.values(accounting).sort((a, b) => {
|
|
const diff = Number(b.uncashedAmount.minus(a.uncashedAmount))
|
|
|
|
if (diff !== 0) {
|
|
return diff
|
|
}
|
|
|
|
return a.peer < b.peer ? -1 : 1
|
|
})
|
|
}
|
|
|
|
export const useAccounting = (
|
|
beeApi: Bee | null,
|
|
settlements: AllSettlements | null,
|
|
balances: PeerBalance[] | null,
|
|
): UseAccountingHook => {
|
|
const [isLoadingUncashed, setIsloadingUncashed] = useState<boolean>(false)
|
|
const [uncashedAmounts, setUncashedAmounts] = useState<LastCashoutActionResponse[] | undefined>(undefined)
|
|
|
|
useEffect(() => {
|
|
// We don't have any settlements loaded yet or we are already loading/have loaded the uncashed amounts
|
|
if (isLoadingUncashed || !beeApi || !settlements || uncashedAmounts) return
|
|
|
|
setIsloadingUncashed(true)
|
|
const promises = settlements.settlements
|
|
.filter(({ received }) => received.gt(BZZ.fromPLUR('0')))
|
|
.map(({ peer }) => makeRetriablePromise(() => beeApi.getLastCashoutAction(peer)))
|
|
|
|
Promise.allSettled(promises).then(settlements => {
|
|
const results = unwrapPromiseSettlements(settlements)
|
|
setUncashedAmounts(results.fulfilled)
|
|
setIsloadingUncashed(false)
|
|
})
|
|
}, [settlements, isLoadingUncashed, uncashedAmounts, beeApi])
|
|
|
|
const accounting = mergeAccounting(balances, settlements?.settlements, uncashedAmounts)
|
|
|
|
let totalUncashed = BZZ.fromPLUR('0')
|
|
accounting?.forEach(({ uncashedAmount }) => (totalUncashed = totalUncashed.plus(uncashedAmount)))
|
|
|
|
return {
|
|
isLoadingUncashed,
|
|
totalUncashed,
|
|
accounting,
|
|
}
|
|
}
|