@radixdlt/atom-transaction-mapping
Version:
92 lines (85 loc) • 2.74 kB
text/typescript
import {
AnyUpParticle,
isTransferrableTokensParticle,
TransferrableTokensParticleT,
} from '@radixdlt/atom'
import { AddressT } from '@radixdlt/account'
import { mapEquals } from '@radixdlt/util'
import { ok, Result } from 'neverthrow'
import { makeParticleReducer } from './particleReducer'
import {
tokenBalancesForOneAccountReducer,
tokenBalancesForOneAccountFromParticle,
mergeMaps,
emptyTokenBalancesForOneAccount,
} from './tokenBalancesForOneAccountReducer'
import {
ApplicationStateType,
TokenBalancesForOneAccount,
TokenBalancesPerAccount,
TokenBalancesPerAccountReducer,
} from './_types'
export const tokenBalancesPerAccount = (
balances: Map<AddressT, TokenBalancesForOneAccount>,
): TokenBalancesPerAccount => ({
stateType: ApplicationStateType.TOKEN_BALANCES_PER_ACCOUNT,
balances: balances,
size: balances.size,
balancesFor: (owner: AddressT): TokenBalancesForOneAccount =>
balances.get(owner) ?? emptyTokenBalancesForOneAccount(owner),
})
const tokenBalancesPerAccountFromParticle = (
particle: TransferrableTokensParticleT,
): TokenBalancesPerAccount => {
const tokenBalancesForOneAccount_ = tokenBalancesForOneAccountFromParticle(
particle,
)
return tokenBalancesPerAccount(
new Map([[particle.address, tokenBalancesForOneAccount_]]),
)
}
export const emptyTokenBalancesPerAccount = (): TokenBalancesPerAccount =>
tokenBalancesPerAccount(new Map())
export const tokenBalancesPerAccountReducer = (): TokenBalancesPerAccountReducer => {
const combine = (
input: Readonly<{
current: TokenBalancesPerAccount
newState: TokenBalancesPerAccount
}>,
): Result<TokenBalancesPerAccount, Error> => {
const currentBalancesMap = input.current.balances
const newBalancesMap = input.newState.balances
if (mapEquals(currentBalancesMap, newBalancesMap))
return ok(input.current)
return mergeMaps({
first: currentBalancesMap,
second: newBalancesMap,
onDuplicates: (a, b, _) =>
tokenBalancesForOneAccountReducer(a.owner).combine({
current: a,
newState: b,
}),
}).map((balances) => tokenBalancesPerAccount(balances))
}
return makeParticleReducer({
applicationStateType: ApplicationStateType.TOKEN_BALANCES_PER_ACCOUNT,
initialState: emptyTokenBalancesPerAccount(),
reduce: (
input: Readonly<{
state: TokenBalancesPerAccount
upParticle: AnyUpParticle
}>,
): Result<TokenBalancesPerAccount, Error> => {
const particle = input.upParticle.particle
if (!isTransferrableTokensParticle(particle)) return ok(input.state)
const tokenBalancesPerAccount_ = tokenBalancesPerAccountFromParticle(
particle,
)
return combine({
current: input.state,
newState: tokenBalancesPerAccount_,
})
},
combine: combine,
})
}