ghost-portal/packages/ui-react-rx/src/ApiObservable.ts
Jaco Greeff 4d984d9f72
Introduce higher-level ApiObservables, use stakingBalance displays (#210)
* Move observables to ui-react-rx

* Move observables into ApiObservable

* Allow AddressSummary to render passed-in balance(s)

* Render Balance consistently in summaries

* Style Mini balance

* Use ApiObservable via HOC

* Nominee balances expanded

* Render nominators for account

* Add full balance when intending
2018-08-08 14:57:09 +02:00

89 lines
2.9 KiB
TypeScript

// Copyright 2017-2018 @polkadot/ui-react-rx authors & contributors
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
import { RxApiInterface } from '@polkadot/api-rx/types';
import { ExtendedBalance, ExtendedBalanceMap, ObservableApiInterface } from './types';
import BN from 'bn.js';
import { Observable, combineLatest } from 'rxjs';
import { map, switchMap, toArray } from 'rxjs/operators';
import storage from '@polkadot/storage';
import encodeAddress from '@polkadot/util-keyring/address/encode';
export default class ObservableApi implements ObservableApiInterface {
private api: RxApiInterface;
constructor (api: RxApiInterface) {
this.api = api;
}
validatingBalance = (address: string): Observable<ExtendedBalance> => {
return combineLatest(
this.votingBalance(address),
this.api.state
.getStorage(storage.staking.public.nominatorsFor, address)
.pipe(
switchMap((nominators = []) =>
// FIXME: Will not be needed after https://github.com/polkadot-js/apps/issues/128
this.votingBalances(nominators.map(encodeAddress))
),
toArray()
)
).pipe(
map(([balance, [nominators = []]]: [ExtendedBalance, [Array<ExtendedBalance>]]): ExtendedBalance => {
const nominatedBalance = nominators.reduce((total, nominator: ExtendedBalance) => {
return total.add(nominator.votingBalance);
}, new BN(0));
return {
...balance,
nominators,
nominatedBalance,
stakingBalance: nominatedBalance.add(balance.votingBalance)
};
})
);
}
validatingBalances = (addresses: Array<string>): Observable<ExtendedBalanceMap> => {
return combineLatest(
addresses.map((address) =>
this.validatingBalance(address)
)
).pipe(
map((result: Array<ExtendedBalance>): ExtendedBalanceMap => {
return result.reduce((balances, balance) => {
balances[balance.address] = balance;
return balances;
}, {} as ExtendedBalanceMap);
})
);
}
votingBalance = (address: string): Observable<ExtendedBalance> => {
return combineLatest(
this.api.state.getStorage(storage.staking.public.freeBalanceOf, address),
this.api.state.getStorage(storage.staking.public.reservedBalanceOf, address)
).pipe(
map(([freeBalance = new BN(0), reservedBalance = new BN(0)]): ExtendedBalance => ({
address,
freeBalance,
nominatedBalance: new BN(0),
reservedBalance,
stakingBalance: new BN(0),
votingBalance: freeBalance.add(reservedBalance)
}))
);
}
votingBalances = (addresses: Array<string>): Observable<ExtendedBalance[]> => {
return combineLatest(
addresses.map((address) =>
this.votingBalance(address)
)
);
}
}