-
Notifications
You must be signed in to change notification settings - Fork 54
/
UtxoTracker.ts
68 lines (64 loc) · 2.24 KB
/
UtxoTracker.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import { Cardano, WalletProvider } from '@cardano-sdk/core';
import { Observable, combineLatest, map, switchMap } from 'rxjs';
import { RetryBackoffConfig } from 'backoff-rxjs';
import { TrackerSubject, coldObservableProvider, utxoEquals } from './util';
import { TransactionalTracker } from './types';
export interface UtxoTrackerProps {
walletProvider: WalletProvider;
addresses$: Observable<Cardano.Address[]>;
transactionsInFlight$: Observable<Cardano.NewTxAlonzo[]>;
tipBlockHeight$: Observable<number>;
retryBackoffConfig: RetryBackoffConfig;
}
export interface UtxoTrackerInternals {
utxoSource$?: TrackerSubject<Cardano.Utxo[]>;
}
export const createUtxoProvider = (
walletProvider: WalletProvider,
addresses$: Observable<Cardano.Address[]>,
tipBlockHeight$: Observable<number>,
retryBackoffConfig: RetryBackoffConfig
) =>
addresses$.pipe(
switchMap((addresses) =>
coldObservableProvider(
() => walletProvider.utxoDelegationAndRewards(addresses).then(({ utxo }) => utxo),
retryBackoffConfig,
tipBlockHeight$,
utxoEquals
)
)
);
export const createUtxoTracker = (
{ walletProvider, addresses$, transactionsInFlight$, retryBackoffConfig, tipBlockHeight$ }: UtxoTrackerProps,
{
utxoSource$ = new TrackerSubject(
createUtxoProvider(walletProvider, addresses$, tipBlockHeight$, retryBackoffConfig)
)
}: UtxoTrackerInternals = {}
): TransactionalTracker<Cardano.Utxo[]> => {
const available$ = new TrackerSubject<Cardano.Utxo[]>(
combineLatest([utxoSource$, transactionsInFlight$]).pipe(
// filter to utxo that are not included in in-flight transactions
map(([utxo, transactionsInFlight]) =>
utxo.filter(
([utxoTxIn]) =>
!transactionsInFlight.some(({ body: { inputs } }) =>
inputs.some((input) => input.txId === utxoTxIn.txId && input.index === utxoTxIn.index)
)
)
)
)
);
return {
available$,
shutdown: () => {
utxoSource$.complete();
available$.complete();
},
// Currently querying ALL utxo. In the future this will not be utxoSource$,
// as the initial utxo set will be loaded from storage.
// Same pattern in TransactionsTracker.
total$: utxoSource$
};
};