@ledgerhq/live-countervalues-react 0.2.45-nightly.0 → 0.2.45-nightly.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +20 -0
- package/lib/CountervaluesMarketcapProvider.d.ts +23 -0
- package/lib/CountervaluesMarketcapProvider.d.ts.map +1 -0
- package/lib/CountervaluesMarketcapProvider.js +89 -0
- package/lib/CountervaluesMarketcapProvider.js.map +1 -0
- package/lib/index.d.ts +44 -18
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +81 -131
- package/lib/index.js.map +1 -1
- package/lib-es/CountervaluesMarketcapProvider.d.ts +23 -0
- package/lib-es/CountervaluesMarketcapProvider.d.ts.map +1 -0
- package/lib-es/CountervaluesMarketcapProvider.js +58 -0
- package/lib-es/CountervaluesMarketcapProvider.js.map +1 -0
- package/lib-es/index.d.ts +44 -18
- package/lib-es/index.d.ts.map +1 -1
- package/lib-es/index.js +78 -124
- package/lib-es/index.js.map +1 -1
- package/package.json +5 -5
- package/src/CountervaluesMarketcapProvider.tsx +94 -0
- package/src/index.tsx +120 -180
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import api from "@ledgerhq/live-countervalues/api/index";
|
|
2
|
+
import { log } from "@ledgerhq/logs";
|
|
3
|
+
import React, { createContext, useContext, useEffect, useReducer } from "react";
|
|
4
|
+
const MARKETCAP_REFRESH = 30 * 60000;
|
|
5
|
+
const MARKETCAP_REFRESH_ON_ERROR = 60000;
|
|
6
|
+
const CountervaluesMarketcapBridgeContext = createContext(null);
|
|
7
|
+
function useCountervaluesMarketcapBridgeContext() {
|
|
8
|
+
const bridge = useContext(CountervaluesMarketcapBridgeContext);
|
|
9
|
+
if (!bridge) {
|
|
10
|
+
throw new Error("'useCountervaluesMarketcapBridgeContext' must be used within a 'CountervaluesMarketcapProvider'");
|
|
11
|
+
}
|
|
12
|
+
return bridge;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Call side effects outside of the primary render tree, avoiding costly child re-renders
|
|
16
|
+
* TODO this could be re-written as a side effect only, to avoid dependency on render state.
|
|
17
|
+
*/
|
|
18
|
+
function Effect({ bridge }) {
|
|
19
|
+
const lastUpdated = bridge.useLastUpdated();
|
|
20
|
+
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
let timeout = null;
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
if (!lastUpdated || now - lastUpdated > MARKETCAP_REFRESH) {
|
|
25
|
+
bridge.setLoading(true);
|
|
26
|
+
api.fetchIdsSortedByMarketcap().then(fetchedIds => {
|
|
27
|
+
bridge.setIds(fetchedIds);
|
|
28
|
+
timeout = setTimeout(() => forceUpdate(), MARKETCAP_REFRESH);
|
|
29
|
+
}, error => {
|
|
30
|
+
log("countervalues", "error fetching marketcap ids " + error);
|
|
31
|
+
bridge.setError(error.message);
|
|
32
|
+
timeout = setTimeout(() => forceUpdate(), MARKETCAP_REFRESH_ON_ERROR);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
timeout = setTimeout(() => forceUpdate(), MARKETCAP_REFRESH - (now - lastUpdated));
|
|
37
|
+
}
|
|
38
|
+
return () => {
|
|
39
|
+
if (timeout)
|
|
40
|
+
clearTimeout(timeout);
|
|
41
|
+
};
|
|
42
|
+
}, [lastUpdated, bridge]);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Provides market-cap ids via the supplied bridge.
|
|
47
|
+
*/
|
|
48
|
+
export function CountervaluesMarketcapProvider({ children, bridge, }) {
|
|
49
|
+
return (React.createElement(CountervaluesMarketcapBridgeContext.Provider, { value: bridge },
|
|
50
|
+
React.createElement(Effect, { bridge: bridge }),
|
|
51
|
+
children));
|
|
52
|
+
}
|
|
53
|
+
/** Returns market-cap ids. */
|
|
54
|
+
export function useMarketcapIds() {
|
|
55
|
+
const bridge = useCountervaluesMarketcapBridgeContext();
|
|
56
|
+
return bridge.useIds();
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=CountervaluesMarketcapProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CountervaluesMarketcapProvider.js","sourceRoot":"","sources":["../src/CountervaluesMarketcapProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,wCAAwC,CAAC;AACzD,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,KAAK,EAAE,EAAgB,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAE9F,MAAM,iBAAiB,GAAG,EAAE,GAAG,KAAK,CAAC;AACrC,MAAM,0BAA0B,GAAG,KAAK,CAAC;AAczC,MAAM,mCAAmC,GAAG,aAAa,CACvD,IAAI,CACL,CAAC;AAEF,SAAS,sCAAsC;IAC7C,MAAM,MAAM,GAAG,UAAU,CAAC,mCAAmC,CAAC,CAAC;IAC/D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,iGAAiG,CAClG,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAS,MAAM,CAAC,EAAE,MAAM,EAA4C;IAClE,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC;IAC5C,MAAM,CAAC,EAAE,WAAW,CAAC,GAAG,UAAU,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,GAAyC,IAAI,CAAC;QACzD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,IAAI,CAAC,WAAW,IAAI,GAAG,GAAG,WAAW,GAAG,iBAAiB,EAAE,CAAC;YAC1D,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACxB,GAAG,CAAC,yBAAyB,EAAE,CAAC,IAAI,CAClC,UAAU,CAAC,EAAE;gBACX,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC1B,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,EAAE,iBAAiB,CAAC,CAAC;YAC/D,CAAC,EACD,KAAK,CAAC,EAAE;gBACN,GAAG,CAAC,eAAe,EAAE,+BAA+B,GAAG,KAAK,CAAC,CAAC;gBAC9D,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC/B,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,EAAE,0BAA0B,CAAC,CAAC;YACxE,CAAC,CACF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,EAAE,iBAAiB,GAAG,CAAC,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC;QACrF,CAAC;QAED,OAAO,GAAG,EAAE;YACV,IAAI,OAAO;gBAAE,YAAY,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IAE1B,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,8BAA8B,CAAC,EAC7C,QAAQ,EACR,MAAM,GAKP;IACC,OAAO,CACL,oBAAC,mCAAmC,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM;QACzD,oBAAC,MAAM,IAAC,MAAM,EAAE,MAAM,GAAI;QACzB,QAAQ,CACoC,CAChD,CAAC;AACJ,CAAC;AAED,8BAA8B;AAC9B,MAAM,UAAU,eAAe;IAC7B,MAAM,MAAM,GAAG,sCAAsC,EAAE,CAAC;IACxD,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC;AACzB,CAAC"}
|
package/lib-es/index.d.ts
CHANGED
|
@@ -3,13 +3,28 @@ import type { Currency, Unit } from "@ledgerhq/types-cryptoassets";
|
|
|
3
3
|
import type { Account, AccountLike } from "@ledgerhq/types-live";
|
|
4
4
|
import { BigNumber } from "bignumber.js";
|
|
5
5
|
import React, { ReactElement } from "react";
|
|
6
|
-
|
|
7
|
-
export interface
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
export { CountervaluesMarketcapProvider, useMarketcapIds } from "./CountervaluesMarketcapProvider";
|
|
7
|
+
export interface PollingState {
|
|
8
|
+
isPolling: boolean;
|
|
9
|
+
triggerRef: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Bridge enabling platform-specific persistence of countervalues state.
|
|
13
|
+
* @note: make sure that the object is memoized to avoid re-renders.
|
|
14
|
+
*/
|
|
15
|
+
export interface CountervaluesBridge {
|
|
16
|
+
setPollingIsPolling(polling: boolean): void;
|
|
17
|
+
setPollingTriggerLoad(triggerLoad: boolean): void;
|
|
18
|
+
setState(state: CounterValuesState): void;
|
|
19
|
+
setStateError(error: Error): void;
|
|
20
|
+
setStatePending(pending: boolean): void;
|
|
21
|
+
usePollingIsPolling(): boolean;
|
|
22
|
+
usePollingTriggerLoad(): boolean;
|
|
23
|
+
useStateError(): Error | null;
|
|
24
|
+
useStatePending(): boolean;
|
|
25
|
+
useState(): CounterValuesState;
|
|
26
|
+
useUserSettings(): CountervaluesSettings;
|
|
27
|
+
wipe(): void;
|
|
13
28
|
}
|
|
14
29
|
export type Polling = {
|
|
15
30
|
wipe: () => void;
|
|
@@ -20,29 +35,35 @@ export type Polling = {
|
|
|
20
35
|
error: Error | null | undefined;
|
|
21
36
|
};
|
|
22
37
|
export type Props = {
|
|
38
|
+
/** Bridge enabling platform-specific persistence of countervalues state. */
|
|
39
|
+
bridge: CountervaluesBridge;
|
|
23
40
|
children: React.ReactNode;
|
|
24
|
-
|
|
41
|
+
/** the time to wait before the first poll when app starts (allow things to render to not do all at boot time) */
|
|
25
42
|
pollInitDelay?: number;
|
|
43
|
+
/** the minimum time to wait before two automatic polls (then one that happen whatever network/appstate events) */
|
|
26
44
|
autopollInterval?: number;
|
|
45
|
+
/** debounce time before actually fetching */
|
|
27
46
|
debounceDelay?: number;
|
|
28
47
|
savedState?: CounterValuesStateRaw;
|
|
29
48
|
};
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}): ReactElement;
|
|
49
|
+
/**
|
|
50
|
+
* Base Countervalues Context to use without polling logic.
|
|
51
|
+
*/
|
|
52
|
+
export declare const CountervaluesContext: React.Context<CountervaluesBridge | null>;
|
|
35
53
|
/**
|
|
36
54
|
* Root countervalues provider (polling + calculation).
|
|
37
55
|
*/
|
|
38
|
-
export declare function CountervaluesProvider({ children,
|
|
39
|
-
/** Returns market-cap ids. */
|
|
40
|
-
export declare function useMarketcapIds(): string[];
|
|
56
|
+
export declare function CountervaluesProvider({ children, bridge, ...rest }: Props): ReactElement;
|
|
41
57
|
/** Returns the full countervalues state. */
|
|
42
58
|
export declare function useCountervaluesState(): CounterValuesState;
|
|
59
|
+
/** Allows consumer to access the countervalues polling control object */
|
|
43
60
|
export declare function useCountervaluesPolling(): Polling;
|
|
44
|
-
|
|
45
|
-
export declare function
|
|
61
|
+
/** Allows consumer to access the user settings that was used to fetch the countervalues */
|
|
62
|
+
export declare function useCountervaluesUserSettings(): CountervaluesSettings;
|
|
63
|
+
/**
|
|
64
|
+
* Provides a way to calculate a countervalue from a value
|
|
65
|
+
* Seems like a major bottleneck, see if it actually needs the full state or we can select only the needed data
|
|
66
|
+
*/
|
|
46
67
|
export declare function useCalculate(query: {
|
|
47
68
|
value: number;
|
|
48
69
|
from: Currency;
|
|
@@ -51,6 +72,7 @@ export declare function useCalculate(query: {
|
|
|
51
72
|
date?: Date | null | undefined;
|
|
52
73
|
reverse?: boolean;
|
|
53
74
|
}): number | null | undefined;
|
|
75
|
+
/** Provides a way to calculate a countervalue from a value using a callback */
|
|
54
76
|
export declare function useCalculateCountervalueCallback({ to, }: {
|
|
55
77
|
to: Currency;
|
|
56
78
|
}): (from: Currency, value: BigNumber) => BigNumber | null | undefined;
|
|
@@ -64,6 +86,10 @@ export declare function useSendAmount({ account, fiatCurrency, cryptoAmount, }:
|
|
|
64
86
|
fiatUnit: Unit;
|
|
65
87
|
calculateCryptoAmount: (fiatAmount: BigNumber) => BigNumber;
|
|
66
88
|
};
|
|
89
|
+
/**
|
|
90
|
+
* Infer the tracking pairs for the top coins that the portfolio needs to display itself
|
|
91
|
+
* if startDate is undefined, the feature is disabled
|
|
92
|
+
*/
|
|
67
93
|
export declare function useTrackingPairsForTopCoins(marketcapIds: string[], countervalue: Currency, size: number, startDate: Date | undefined): {
|
|
68
94
|
from: import("@ledgerhq/types-cryptoassets").CryptoCurrency;
|
|
69
95
|
to: Currency;
|
package/lib-es/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
|
package/lib-es/index.js
CHANGED
|
@@ -1,74 +1,35 @@
|
|
|
1
1
|
import { getAccountCurrency } from "@ledgerhq/coin-framework/account/helpers";
|
|
2
|
-
import
|
|
3
|
-
import { calculate, exportCountervalues, importCountervalues, inferTrackingPairForAccounts, initialState, loadCountervalues, trackingPairForTopCoins, } from "@ledgerhq/live-countervalues/logic";
|
|
2
|
+
import { calculate, importCountervalues, inferTrackingPairForAccounts, loadCountervalues, trackingPairForTopCoins, } from "@ledgerhq/live-countervalues/logic";
|
|
4
3
|
import { useDebounce } from "@ledgerhq/live-hooks/useDebounce";
|
|
5
|
-
import { log } from "@ledgerhq/logs";
|
|
6
4
|
import { BigNumber } from "bignumber.js";
|
|
7
|
-
import React, { createContext, useCallback, useContext, useEffect, useMemo,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
marketCapBatchingAfterRank: 0,
|
|
22
|
-
});
|
|
23
|
-
const CountervaluesContext = createContext(initialState);
|
|
24
|
-
const CountervaluesMarketcapIdsContext = createContext([]);
|
|
5
|
+
import React, { createContext, useCallback, useContext, useEffect, useMemo, } from "react";
|
|
6
|
+
import { useMarketcapIds } from "./CountervaluesMarketcapProvider";
|
|
7
|
+
export { CountervaluesMarketcapProvider, useMarketcapIds } from "./CountervaluesMarketcapProvider";
|
|
8
|
+
/**
|
|
9
|
+
* Base Countervalues Context to use without polling logic.
|
|
10
|
+
*/
|
|
11
|
+
export const CountervaluesContext = createContext(null);
|
|
12
|
+
function useCountervaluesBridgeContext() {
|
|
13
|
+
const bridge = useContext(CountervaluesContext);
|
|
14
|
+
if (!bridge) {
|
|
15
|
+
throw new Error("'useCountervaluesBridgeContext' must be used within a 'CountervaluesProvider'");
|
|
16
|
+
}
|
|
17
|
+
return bridge;
|
|
18
|
+
}
|
|
25
19
|
function trackingPairsHash(a) {
|
|
26
20
|
return a
|
|
27
21
|
.map(p => `${p.from.ticker}:${p.to.ticker}:${p.startDate.toISOString().slice(0, 10) || ""}`)
|
|
28
22
|
.sort()
|
|
29
23
|
.join("|");
|
|
30
24
|
}
|
|
31
|
-
const marketcapRefresh = 30 * 60000;
|
|
32
|
-
const marketcapRefreshOnError = 60000;
|
|
33
|
-
/** Provides market-cap ids via the supplied bridge. */
|
|
34
|
-
export function CountervaluesMarketcapProvider({ children, bridge, }) {
|
|
35
|
-
const ids = bridge.useIds();
|
|
36
|
-
const lastUpdated = bridge.useLastUpdated();
|
|
37
|
-
const [, forceUpdate] = useReducer(x => x + 1, 0);
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
let timeout = null;
|
|
40
|
-
const now = Date.now();
|
|
41
|
-
if (!lastUpdated || now - lastUpdated > marketcapRefresh) {
|
|
42
|
-
bridge.setLoading(true);
|
|
43
|
-
api.fetchIdsSortedByMarketcap().then(fetchedIds => {
|
|
44
|
-
bridge.setIds(fetchedIds);
|
|
45
|
-
timeout = setTimeout(() => forceUpdate(), marketcapRefresh);
|
|
46
|
-
}, error => {
|
|
47
|
-
log("countervalues", "error fetching marketcap ids " + error);
|
|
48
|
-
bridge.setError(error.message);
|
|
49
|
-
timeout = setTimeout(() => forceUpdate(), marketcapRefreshOnError);
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
timeout = setTimeout(() => forceUpdate(), marketcapRefresh - (now - lastUpdated));
|
|
54
|
-
}
|
|
55
|
-
return () => {
|
|
56
|
-
if (timeout)
|
|
57
|
-
clearTimeout(timeout);
|
|
58
|
-
};
|
|
59
|
-
}, [lastUpdated, bridge]);
|
|
60
|
-
return (React.createElement(CountervaluesMarketcapIdsContext.Provider, { value: ids }, children));
|
|
61
|
-
}
|
|
62
25
|
/**
|
|
63
|
-
*
|
|
26
|
+
* Call side effects outside of the primary render tree, avoiding costly child re-renders
|
|
64
27
|
*/
|
|
65
|
-
|
|
66
|
-
const
|
|
28
|
+
function Effect({ bridge, savedState, debounceDelay = 1000, pollInitDelay = 3 * 1000, }) {
|
|
29
|
+
const userSettings = bridge.useUserSettings();
|
|
30
|
+
const { refreshRate, marketCapBatchingAfterRank } = userSettings;
|
|
67
31
|
const debouncedUserSettings = useDebounce(userSettings, debounceDelay);
|
|
68
|
-
const
|
|
69
|
-
// TODO this is always using the initial value, doesn't react to changes.
|
|
70
|
-
const marketcapIds = useContext(CountervaluesMarketcapIdsContext);
|
|
71
|
-
const { marketCapBatchingAfterRank } = userSettings;
|
|
32
|
+
const marketcapIds = useMarketcapIds();
|
|
72
33
|
const batchStrategySolver = useMemo(() => ({
|
|
73
34
|
shouldBatchCurrencyFrom: (currency) => {
|
|
74
35
|
if (currency.type === "FiatCurrency")
|
|
@@ -78,97 +39,88 @@ export function CountervaluesProvider({ children, userSettings, pollInitDelay =
|
|
|
78
39
|
},
|
|
79
40
|
}), [marketCapBatchingAfterRank, marketcapIds]);
|
|
80
41
|
// flag used to trigger a loadCountervalues
|
|
81
|
-
const
|
|
82
|
-
// trigger poll only when userSettings changes
|
|
42
|
+
const triggerLoad = bridge.usePollingTriggerLoad();
|
|
43
|
+
// trigger poll only when userSettings changes in a debounced way
|
|
83
44
|
useEffect(() => {
|
|
84
|
-
|
|
85
|
-
}, [debouncedUserSettings]);
|
|
45
|
+
bridge.setPollingTriggerLoad(true);
|
|
46
|
+
}, [bridge, debouncedUserSettings]);
|
|
86
47
|
// loadCountervalues logic
|
|
48
|
+
const currentState = bridge.useState();
|
|
49
|
+
const pending = bridge.useStatePending();
|
|
50
|
+
// loadCountervalues logic using bridge
|
|
87
51
|
useEffect(() => {
|
|
88
52
|
if (pending || !triggerLoad)
|
|
89
53
|
return;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
loadCountervalues(
|
|
93
|
-
|
|
54
|
+
bridge.setPollingTriggerLoad(false);
|
|
55
|
+
bridge.setStatePending(true);
|
|
56
|
+
loadCountervalues(currentState, userSettings, batchStrategySolver, userSettings.granularitiesRates).then(s => {
|
|
57
|
+
bridge.setState(s);
|
|
58
|
+
bridge.setStatePending(false);
|
|
59
|
+
}, e => {
|
|
60
|
+
bridge.setStateError(e);
|
|
61
|
+
bridge.setStatePending(false);
|
|
62
|
+
});
|
|
63
|
+
}, [pending, currentState, userSettings, triggerLoad, batchStrategySolver, bridge]);
|
|
94
64
|
// save the state when it changes
|
|
95
65
|
useEffect(() => {
|
|
96
66
|
if (!savedState?.status || !Object.keys(savedState.status).length)
|
|
97
67
|
return;
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}, [savedState, userSettings]);
|
|
103
|
-
// manage the auto polling loop and the interface for user land to trigger a reload
|
|
104
|
-
const [isPolling, setIsPolling] = useState(true);
|
|
68
|
+
bridge.setState(importCountervalues(savedState, userSettings));
|
|
69
|
+
}, [bridge, savedState, userSettings]);
|
|
70
|
+
// manage the auto polling loop
|
|
71
|
+
const isPolling = bridge.usePollingIsPolling();
|
|
105
72
|
useEffect(() => {
|
|
106
73
|
if (!isPolling)
|
|
107
74
|
return;
|
|
108
75
|
let pollingTimeout;
|
|
109
76
|
function pollingLoop() {
|
|
110
|
-
|
|
111
|
-
pollingTimeout = setTimeout(pollingLoop,
|
|
77
|
+
bridge.setPollingTriggerLoad(true);
|
|
78
|
+
pollingTimeout = setTimeout(pollingLoop, refreshRate);
|
|
112
79
|
}
|
|
113
80
|
pollingTimeout = setTimeout(pollingLoop, pollInitDelay);
|
|
114
81
|
return () => clearTimeout(pollingTimeout);
|
|
115
|
-
}, [
|
|
116
|
-
|
|
117
|
-
wipe: () => dispatch({ type: "wipe" }),
|
|
118
|
-
poll: () => setTriggerLoad(true),
|
|
119
|
-
start: () => setIsPolling(true),
|
|
120
|
-
stop: () => setIsPolling(false),
|
|
121
|
-
pending,
|
|
122
|
-
error,
|
|
123
|
-
}), [pending, error]);
|
|
124
|
-
return (React.createElement(CountervaluesPollingContext.Provider, { value: polling },
|
|
125
|
-
React.createElement(CountervaluesUserSettingsContext.Provider, { value: userSettings },
|
|
126
|
-
React.createElement(CountervaluesContext.Provider, { value: state }, children))));
|
|
82
|
+
}, [refreshRate, pollInitDelay, isPolling, bridge]);
|
|
83
|
+
return null;
|
|
127
84
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
case "pending":
|
|
136
|
-
return { ...state, pending: true, error: undefined };
|
|
137
|
-
case "wipe":
|
|
138
|
-
return { state: initialState, pending: false, error: undefined };
|
|
139
|
-
case "setCounterValueState":
|
|
140
|
-
return { ...state, state: action.payload };
|
|
141
|
-
default:
|
|
142
|
-
return state;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
/** Returns market-cap ids. */
|
|
146
|
-
export function useMarketcapIds() {
|
|
147
|
-
return useContext(CountervaluesMarketcapIdsContext);
|
|
85
|
+
/**
|
|
86
|
+
* Root countervalues provider (polling + calculation).
|
|
87
|
+
*/
|
|
88
|
+
export function CountervaluesProvider({ children, bridge, ...rest }) {
|
|
89
|
+
return (React.createElement(CountervaluesContext.Provider, { value: bridge },
|
|
90
|
+
React.createElement(Effect, { ...rest, bridge: bridge }),
|
|
91
|
+
children));
|
|
148
92
|
}
|
|
149
93
|
/** Returns the full countervalues state. */
|
|
150
94
|
export function useCountervaluesState() {
|
|
151
|
-
return
|
|
95
|
+
return useCountervaluesBridgeContext().useState();
|
|
152
96
|
}
|
|
153
|
-
|
|
97
|
+
/** Allows consumer to access the countervalues polling control object */
|
|
154
98
|
export function useCountervaluesPolling() {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
99
|
+
const bridge = useCountervaluesBridgeContext();
|
|
100
|
+
const pending = bridge.useStatePending();
|
|
101
|
+
const error = bridge.useStateError();
|
|
102
|
+
return useMemo(() => ({
|
|
103
|
+
poll: () => bridge.setPollingTriggerLoad(true),
|
|
104
|
+
start: () => bridge.setPollingIsPolling(true),
|
|
105
|
+
stop: () => bridge.setPollingIsPolling(false),
|
|
106
|
+
wipe: () => bridge.wipe(),
|
|
107
|
+
pending,
|
|
108
|
+
error,
|
|
109
|
+
}), [bridge, error, pending]);
|
|
160
110
|
}
|
|
161
|
-
|
|
162
|
-
export function
|
|
163
|
-
|
|
164
|
-
return useMemo(() => exportCountervalues(state), [state]);
|
|
111
|
+
/** Allows consumer to access the user settings that was used to fetch the countervalues */
|
|
112
|
+
export function useCountervaluesUserSettings() {
|
|
113
|
+
return useCountervaluesBridgeContext().useUserSettings();
|
|
165
114
|
}
|
|
166
|
-
|
|
115
|
+
/**
|
|
116
|
+
* Provides a way to calculate a countervalue from a value
|
|
117
|
+
* Seems like a major bottleneck, see if it actually needs the full state or we can select only the needed data
|
|
118
|
+
*/
|
|
167
119
|
export function useCalculate(query) {
|
|
168
120
|
const state = useCountervaluesState();
|
|
169
|
-
return calculate(state, query);
|
|
121
|
+
return useMemo(() => calculate(state, query), [state, query]);
|
|
170
122
|
}
|
|
171
|
-
|
|
123
|
+
/** Provides a way to calculate a countervalue from a value using a callback */
|
|
172
124
|
export function useCalculateCountervalueCallback({ to, }) {
|
|
173
125
|
const state = useCountervaluesState();
|
|
174
126
|
return useCallback((from, value) => {
|
|
@@ -201,8 +153,10 @@ export function useSendAmount({ account, fiatCurrency, cryptoAmount, }) {
|
|
|
201
153
|
}) ?? 0), [state, cryptoCurrency, fiatCurrency]);
|
|
202
154
|
return { fiatAmount, fiatUnit, calculateCryptoAmount };
|
|
203
155
|
}
|
|
204
|
-
|
|
205
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Infer the tracking pairs for the top coins that the portfolio needs to display itself
|
|
158
|
+
* if startDate is undefined, the feature is disabled
|
|
159
|
+
*/
|
|
206
160
|
export function useTrackingPairsForTopCoins(marketcapIds, countervalue, size, startDate) {
|
|
207
161
|
const dateTimestamp = startDate?.getTime();
|
|
208
162
|
return useMemo(() => dateTimestamp
|
package/lib-es/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAC9E,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/live-countervalues-react",
|
|
3
|
-
"version": "0.2.45-nightly.
|
|
3
|
+
"version": "0.2.45-nightly.2",
|
|
4
4
|
"description": "Ledger Live countervalues React module",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ledger"
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"bignumber.js": "9",
|
|
28
|
-
"@ledgerhq/types-live": "6.79.0",
|
|
28
|
+
"@ledgerhq/types-live": "6.79.1-nightly.0",
|
|
29
29
|
"@ledgerhq/types-cryptoassets": "7.24.0",
|
|
30
|
-
"@ledgerhq/cryptoassets": "13.
|
|
30
|
+
"@ledgerhq/cryptoassets": "13.24.0-nightly.0",
|
|
31
31
|
"@ledgerhq/logs": "6.13.0",
|
|
32
|
-
"@ledgerhq/live-countervalues": "0.6.0-nightly.
|
|
33
|
-
"@ledgerhq/coin-framework": "5.9.0-nightly.
|
|
32
|
+
"@ledgerhq/live-countervalues": "0.6.0-nightly.2",
|
|
33
|
+
"@ledgerhq/coin-framework": "5.9.0-nightly.2",
|
|
34
34
|
"@ledgerhq/live-hooks": "0.1.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import api from "@ledgerhq/live-countervalues/api/index";
|
|
2
|
+
import { log } from "@ledgerhq/logs";
|
|
3
|
+
import React, { ReactElement, createContext, useContext, useEffect, useReducer } from "react";
|
|
4
|
+
|
|
5
|
+
const MARKETCAP_REFRESH = 30 * 60000;
|
|
6
|
+
const MARKETCAP_REFRESH_ON_ERROR = 60000;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Bridge enabling platform-specific persistence of market-cap ids.
|
|
10
|
+
* NOTE: memoize the object to avoid re-renders.
|
|
11
|
+
*/
|
|
12
|
+
export interface CountervaluesMarketcapBridge {
|
|
13
|
+
setError(message: string): void;
|
|
14
|
+
setIds(ids: string[]): void;
|
|
15
|
+
setLoading(loading: boolean): void;
|
|
16
|
+
useIds(): string[];
|
|
17
|
+
useLastUpdated(): number | undefined;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const CountervaluesMarketcapBridgeContext = createContext<CountervaluesMarketcapBridge | null>(
|
|
21
|
+
null,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
function useCountervaluesMarketcapBridgeContext() {
|
|
25
|
+
const bridge = useContext(CountervaluesMarketcapBridgeContext);
|
|
26
|
+
if (!bridge) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
"'useCountervaluesMarketcapBridgeContext' must be used within a 'CountervaluesMarketcapProvider'",
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return bridge;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Call side effects outside of the primary render tree, avoiding costly child re-renders
|
|
36
|
+
* TODO this could be re-written as a side effect only, to avoid dependency on render state.
|
|
37
|
+
*/
|
|
38
|
+
function Effect({ bridge }: { bridge: CountervaluesMarketcapBridge }) {
|
|
39
|
+
const lastUpdated = bridge.useLastUpdated();
|
|
40
|
+
const [, forceUpdate] = useReducer((x: number) => x + 1, 0);
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
let timeout: ReturnType<typeof setTimeout> | null = null;
|
|
44
|
+
const now = Date.now();
|
|
45
|
+
|
|
46
|
+
if (!lastUpdated || now - lastUpdated > MARKETCAP_REFRESH) {
|
|
47
|
+
bridge.setLoading(true);
|
|
48
|
+
api.fetchIdsSortedByMarketcap().then(
|
|
49
|
+
fetchedIds => {
|
|
50
|
+
bridge.setIds(fetchedIds);
|
|
51
|
+
timeout = setTimeout(() => forceUpdate(), MARKETCAP_REFRESH);
|
|
52
|
+
},
|
|
53
|
+
error => {
|
|
54
|
+
log("countervalues", "error fetching marketcap ids " + error);
|
|
55
|
+
bridge.setError(error.message);
|
|
56
|
+
timeout = setTimeout(() => forceUpdate(), MARKETCAP_REFRESH_ON_ERROR);
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
} else {
|
|
60
|
+
timeout = setTimeout(() => forceUpdate(), MARKETCAP_REFRESH - (now - lastUpdated));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return () => {
|
|
64
|
+
if (timeout) clearTimeout(timeout);
|
|
65
|
+
};
|
|
66
|
+
}, [lastUpdated, bridge]);
|
|
67
|
+
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Provides market-cap ids via the supplied bridge.
|
|
73
|
+
*/
|
|
74
|
+
export function CountervaluesMarketcapProvider({
|
|
75
|
+
children,
|
|
76
|
+
bridge,
|
|
77
|
+
}: {
|
|
78
|
+
children: React.ReactNode;
|
|
79
|
+
/** @param bridge Contains the functions that interact with the apps' state. Reference needs to be stable */
|
|
80
|
+
bridge: CountervaluesMarketcapBridge;
|
|
81
|
+
}): ReactElement {
|
|
82
|
+
return (
|
|
83
|
+
<CountervaluesMarketcapBridgeContext.Provider value={bridge}>
|
|
84
|
+
<Effect bridge={bridge} />
|
|
85
|
+
{children}
|
|
86
|
+
</CountervaluesMarketcapBridgeContext.Provider>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Returns market-cap ids. */
|
|
91
|
+
export function useMarketcapIds(): string[] {
|
|
92
|
+
const bridge = useCountervaluesMarketcapBridgeContext();
|
|
93
|
+
return bridge.useIds();
|
|
94
|
+
}
|