on c19b2a8 help sign in
bridge/src/store/lib/useRekeyDateStore.js
79 lines 2.1 kB history raw
1import { useCallback, useState } from 'react';
2import { Just, Nothing } from 'folktale/maybe';
3import Result from 'folktale/result';
5import { useNetwork } from '../network';
7export default function useRekeyDateStore() {
8 const { web3, contracts } = useNetwork();
9 const [rekeyDateCache, _setRekeyDateCache] = useState({});
11 const addToRekeyDateCache = useCallback(
12 entry =>
13 _setRekeyDateCache(cache => ({
14 ...cache,
15 ...entry,
16 })),
17 [_setRekeyDateCache]
18 );
20 /**
21 * @param {number} point
22 * @return {Maybe<Result<Date, String>>}
23 */
24 const getRekeyDate = useCallback(
25 point => rekeyDateCache[point] || Nothing(),
26 [rekeyDateCache]
27 );
29 const syncRekeyDate = useCallback(
30 async point => {
31 const _web3 = web3.getOrElse(null);
32 const _contracts = contracts.getOrElse(null);
33 if (!_web3 || !_contracts) {
34 return;
35 }
37 //TODO tighter search?
38 //TODO maybe move into azimuth-js?
39 const logs = await _contracts.azimuth.getPastEvents('ChangedKeys', {
40 fromBlock: 0,
41 toBlock: 'latest',
42 filter: {
43 point: [point],
44 },
45 });
47 // NB(shrugs) using try-catch here to simplify our error handling
48 try {
49 if (logs.length === 0) {
50 throw new Error('No logs available.');
51 }
53 // last log is most recent
54 const blockNumber = logs[logs.length - 1].blockNumber;
55 if (blockNumber === null) {
56 // the "latest" parameter includes pending blocks,
57 // which won't have a blockNumber just yet
58 throw new Error('Latest rekey is still pending');
59 }
61 const block = await _web3.eth.getBlock(blockNumber);
62 addToRekeyDateCache({
63 [point]: Just(Result.Ok(new Date(block.timestamp * 1000))),
64 });
65 } catch {
66 //TODO: better encoding for "no rekeyDate" state?
67 addToRekeyDateCache({
68 [point]: Just(Result.Error('No rekey date available.')),
69 });
70 }
71 },
72 [web3, contracts, addToRekeyDateCache]
73 );
75 return {
76 getRekeyDate,
77 syncRekeyDate,
78 };