@ledgerhq/live-countervalues 0.1.0
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/.eslintrc.js +33 -0
- package/.turbo/turbo-build.log +4 -0
- package/.unimportedrc.json +4 -0
- package/CHANGELOG.md +1 -0
- package/LICENSE.txt +21 -0
- package/jest-global-setup.js +9 -0
- package/jest.config.js +14 -0
- package/lib/api/api.d.ts +4 -0
- package/lib/api/api.d.ts.map +1 -0
- package/lib/api/api.js +82 -0
- package/lib/api/api.js.map +1 -0
- package/lib/api/api.mock.d.ts +4 -0
- package/lib/api/api.mock.d.ts.map +1 -0
- package/lib/api/api.mock.js +103 -0
- package/lib/api/api.mock.js.map +1 -0
- package/lib/api/index.d.ts +4 -0
- package/lib/api/index.d.ts.map +1 -0
- package/lib/api/index.js +19 -0
- package/lib/api/index.js.map +1 -0
- package/lib/helpers.d.ts +31 -0
- package/lib/helpers.d.ts.map +1 -0
- package/lib/helpers.js +77 -0
- package/lib/helpers.js.map +1 -0
- package/lib/logic.d.ts +40 -0
- package/lib/logic.d.ts.map +1 -0
- package/lib/logic.integration.test.d.ts +2 -0
- package/lib/logic.integration.test.d.ts.map +1 -0
- package/lib/logic.integration.test.js +191 -0
- package/lib/logic.integration.test.js.map +1 -0
- package/lib/logic.js +422 -0
- package/lib/logic.js.map +1 -0
- package/lib/logic.test.d.ts +2 -0
- package/lib/logic.test.d.ts.map +1 -0
- package/lib/logic.test.js +29 -0
- package/lib/logic.test.js.map +1 -0
- package/lib/mock.d.ts +4 -0
- package/lib/mock.d.ts.map +1 -0
- package/lib/mock.js +10 -0
- package/lib/mock.js.map +1 -0
- package/lib/mock.test.d.ts +2 -0
- package/lib/mock.test.d.ts.map +1 -0
- package/lib/mock.test.js +210 -0
- package/lib/mock.test.js.map +1 -0
- package/lib/types.d.ts +47 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +4 -0
- package/lib/types.js.map +1 -0
- package/lib-es/api/api.d.ts +4 -0
- package/lib-es/api/api.d.ts.map +1 -0
- package/lib-es/api/api.js +77 -0
- package/lib-es/api/api.js.map +1 -0
- package/lib-es/api/api.mock.d.ts +4 -0
- package/lib-es/api/api.mock.d.ts.map +1 -0
- package/lib-es/api/api.mock.js +98 -0
- package/lib-es/api/api.mock.js.map +1 -0
- package/lib-es/api/index.d.ts +4 -0
- package/lib-es/api/index.d.ts.map +1 -0
- package/lib-es/api/index.js +14 -0
- package/lib-es/api/index.js.map +1 -0
- package/lib-es/helpers.d.ts +31 -0
- package/lib-es/helpers.d.ts.map +1 -0
- package/lib-es/helpers.js +67 -0
- package/lib-es/helpers.js.map +1 -0
- package/lib-es/logic.d.ts +40 -0
- package/lib-es/logic.d.ts.map +1 -0
- package/lib-es/logic.integration.test.d.ts +2 -0
- package/lib-es/logic.integration.test.d.ts.map +1 -0
- package/lib-es/logic.integration.test.js +186 -0
- package/lib-es/logic.integration.test.js.map +1 -0
- package/lib-es/logic.js +406 -0
- package/lib-es/logic.js.map +1 -0
- package/lib-es/logic.test.d.ts +2 -0
- package/lib-es/logic.test.d.ts.map +1 -0
- package/lib-es/logic.test.js +27 -0
- package/lib-es/logic.test.js.map +1 -0
- package/lib-es/mock.d.ts +4 -0
- package/lib-es/mock.d.ts.map +1 -0
- package/lib-es/mock.js +6 -0
- package/lib-es/mock.js.map +1 -0
- package/lib-es/mock.test.d.ts +2 -0
- package/lib-es/mock.test.d.ts.map +1 -0
- package/lib-es/mock.test.js +205 -0
- package/lib-es/mock.test.js.map +1 -0
- package/lib-es/types.d.ts +47 -0
- package/lib-es/types.d.ts.map +1 -0
- package/lib-es/types.js +3 -0
- package/lib-es/types.js.map +1 -0
- package/package.json +81 -0
- package/src/api/api.mock.ts +117 -0
- package/src/api/api.ts +79 -0
- package/src/api/index.ts +19 -0
- package/src/helpers.ts +82 -0
- package/src/logic.integration.test.ts +209 -0
- package/src/logic.test.ts +30 -0
- package/src/logic.ts +533 -0
- package/src/mock.test.ts +231 -0
- package/src/mock.ts +8 -0
- package/src/types.ts +70 -0
- package/tsconfig.json +15 -0
package/lib-es/logic.js
ADDED
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
11
|
+
var t = {};
|
|
12
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
13
|
+
t[p] = s[p];
|
|
14
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
15
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
16
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
17
|
+
t[p[i]] = s[p[i]];
|
|
18
|
+
}
|
|
19
|
+
return t;
|
|
20
|
+
};
|
|
21
|
+
import { log } from "@ledgerhq/logs";
|
|
22
|
+
import { flattenAccounts, getAccountCurrency, isAccountEmpty, } from "@ledgerhq/coin-framework/account/helpers";
|
|
23
|
+
import { promiseAllBatched } from "@ledgerhq/live-promise";
|
|
24
|
+
import { pairId, magFromTo, formatPerGranularity, formatCounterValueDay, formatCounterValueHashes, parseFormattedDate, incrementPerGranularity, datapointLimits, } from "./helpers";
|
|
25
|
+
import api from "./api";
|
|
26
|
+
// yield raw version of the countervalues state to be saved in a db
|
|
27
|
+
export function exportCountervalues({ data, status }) {
|
|
28
|
+
const out = { status };
|
|
29
|
+
for (const path in data) {
|
|
30
|
+
const obj = {};
|
|
31
|
+
for (const [k, v] of data[path]) {
|
|
32
|
+
obj[k] = v;
|
|
33
|
+
}
|
|
34
|
+
out[path] = obj;
|
|
35
|
+
}
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
// restore a countervalues state from the raw version
|
|
39
|
+
export function importCountervalues(_a, settings) {
|
|
40
|
+
var { status } = _a, rest = __rest(_a, ["status"]);
|
|
41
|
+
const data = {};
|
|
42
|
+
for (const path in rest) {
|
|
43
|
+
const obj = rest[path];
|
|
44
|
+
const map = new Map();
|
|
45
|
+
for (const k in obj) {
|
|
46
|
+
map.set(k, obj[k]);
|
|
47
|
+
}
|
|
48
|
+
data[path] = map;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
data,
|
|
52
|
+
status,
|
|
53
|
+
cache: Object.entries(data).reduce((prev, [key, val]) => (Object.assign(Object.assign({}, prev), {
|
|
54
|
+
// $FlowFixMe
|
|
55
|
+
[key]: generateCache(key, val, settings) })), {}),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// infer the tracking pair from user accounts to know which pairs are concerned
|
|
59
|
+
export function inferTrackingPairForAccounts(accounts, countervalue) {
|
|
60
|
+
const yearAgo = new Date();
|
|
61
|
+
yearAgo.setFullYear(yearAgo.getFullYear() - 1);
|
|
62
|
+
yearAgo.setHours(0, 0, 0, 0);
|
|
63
|
+
return resolveTrackingPairs(flattenAccounts(accounts)
|
|
64
|
+
.filter(a => !isAccountEmpty(a))
|
|
65
|
+
.map(account => {
|
|
66
|
+
const currency = getAccountCurrency(account);
|
|
67
|
+
return {
|
|
68
|
+
from: currency,
|
|
69
|
+
to: countervalue,
|
|
70
|
+
startDate: account.creationDate < yearAgo ? account.creationDate : yearAgo,
|
|
71
|
+
};
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* yield the ids of the tracking pairs as stored in the database
|
|
76
|
+
*/
|
|
77
|
+
export function trackingPairIds(trackingPairs) {
|
|
78
|
+
return trackingPairs.map(pairId);
|
|
79
|
+
}
|
|
80
|
+
export const initialState = {
|
|
81
|
+
data: {},
|
|
82
|
+
status: {},
|
|
83
|
+
cache: {},
|
|
84
|
+
};
|
|
85
|
+
const MAX_RETRY_DELAY = 7 * incrementPerGranularity.daily;
|
|
86
|
+
// synchronize all countervalues incrementally (async update of the countervalues state)
|
|
87
|
+
export function loadCountervalues(state, settings) {
|
|
88
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
+
const data = Object.assign({}, state.data);
|
|
90
|
+
const cache = Object.assign({}, state.cache);
|
|
91
|
+
const status = Object.assign({}, state.status);
|
|
92
|
+
const nowDate = new Date();
|
|
93
|
+
const latestToFetch = settings.trackingPairs;
|
|
94
|
+
// determines what historical data need to be fetched
|
|
95
|
+
const histoToFetch = [];
|
|
96
|
+
const rateGranularities = ["daily", "hourly"];
|
|
97
|
+
rateGranularities.forEach((granularity) => {
|
|
98
|
+
const format = formatPerGranularity[granularity];
|
|
99
|
+
const earliestHisto = format(nowDate);
|
|
100
|
+
log("countervalues", "earliestHisto=" + earliestHisto);
|
|
101
|
+
const limit = datapointLimits[granularity];
|
|
102
|
+
settings.trackingPairs.forEach(({ from, to, startDate }) => {
|
|
103
|
+
const key = pairId({
|
|
104
|
+
from,
|
|
105
|
+
to,
|
|
106
|
+
});
|
|
107
|
+
const c = cache[key];
|
|
108
|
+
const stats = c === null || c === void 0 ? void 0 : c.stats;
|
|
109
|
+
const s = status[key];
|
|
110
|
+
// when there are too much http failures, slow down the rate to be actually re-fetched
|
|
111
|
+
if ((s === null || s === void 0 ? void 0 : s.failures) && s.timestamp) {
|
|
112
|
+
const { failures, timestamp } = s;
|
|
113
|
+
const secondsBetweenRetries = Math.min(Math.exp(failures * 0.5), MAX_RETRY_DELAY);
|
|
114
|
+
const nextTarget = timestamp + 1000 * secondsBetweenRetries;
|
|
115
|
+
if (nowDate.valueOf() < nextTarget) {
|
|
116
|
+
log("countervalues", `${key}@${granularity} discarded: too much HTTP failures (${failures}) retry in ~${Math.round((nextTarget - nowDate.valueOf()) / 1000)}s`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
let start = startDate;
|
|
121
|
+
const limitDate = Date.now() - limit;
|
|
122
|
+
if (limitDate && start.valueOf() < limitDate) {
|
|
123
|
+
start = new Date(limitDate);
|
|
124
|
+
}
|
|
125
|
+
const needOlderReload = s && s.oldestDateRequested && start < new Date(s.oldestDateRequested);
|
|
126
|
+
if (needOlderReload) {
|
|
127
|
+
log("countervalues", `${key}@${granularity} need older reload (${start.toISOString()} < ${String(s && s.oldestDateRequested)})`);
|
|
128
|
+
}
|
|
129
|
+
if (!needOlderReload) {
|
|
130
|
+
// we do not miss datapoints in the past so we can ask the only remaining part
|
|
131
|
+
if (stats && stats.earliestStableDate && stats.earliestStableDate > start) {
|
|
132
|
+
start = stats.earliestStableDate;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// nothing to fetch for historical
|
|
136
|
+
if (format(start) === earliestHisto)
|
|
137
|
+
return;
|
|
138
|
+
histoToFetch.push([
|
|
139
|
+
granularity,
|
|
140
|
+
{
|
|
141
|
+
from,
|
|
142
|
+
to,
|
|
143
|
+
startDate: start,
|
|
144
|
+
},
|
|
145
|
+
key,
|
|
146
|
+
]);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
log("countervalues", `${histoToFetch.length} historical value to fetch (${settings.trackingPairs.length} pairs)`);
|
|
150
|
+
// Fetch it all
|
|
151
|
+
const [histo, latest] = yield Promise.all([
|
|
152
|
+
promiseAllBatched(10, histoToFetch, ([granularity, pair, key]) => api
|
|
153
|
+
.fetchHistorical(granularity, pair)
|
|
154
|
+
.then(rates => {
|
|
155
|
+
var _a;
|
|
156
|
+
// Update status infos
|
|
157
|
+
const id = pairId(pair);
|
|
158
|
+
let oldestDateRequested = (_a = status[id]) === null || _a === void 0 ? void 0 : _a.oldestDateRequested;
|
|
159
|
+
if (!oldestDateRequested || pair.startDate < new Date(oldestDateRequested)) {
|
|
160
|
+
oldestDateRequested = pair.startDate.toISOString();
|
|
161
|
+
}
|
|
162
|
+
status[id] = {
|
|
163
|
+
timestamp: Date.now(),
|
|
164
|
+
oldestDateRequested,
|
|
165
|
+
};
|
|
166
|
+
return {
|
|
167
|
+
[key]: rates,
|
|
168
|
+
};
|
|
169
|
+
})
|
|
170
|
+
.catch(e => {
|
|
171
|
+
if (settings.disableAutoRecoverErrors)
|
|
172
|
+
throw e;
|
|
173
|
+
// TODO work on the semantic of failure.
|
|
174
|
+
// do we want to opt-in for the 404 cases and make other fails it all?
|
|
175
|
+
// do we want to be resilient on individual pulling / keep error somewhere?
|
|
176
|
+
const id = pairId(pair);
|
|
177
|
+
// only on HTTP error, we count the failures (not network down case)
|
|
178
|
+
if (e && typeof e.status === "number" && e.status) {
|
|
179
|
+
const s = status[id];
|
|
180
|
+
status[id] = {
|
|
181
|
+
timestamp: Date.now(),
|
|
182
|
+
failures: ((s === null || s === void 0 ? void 0 : s.failures) || 0) + 1,
|
|
183
|
+
oldestDateRequested: s === null || s === void 0 ? void 0 : s.oldestDateRequested,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
log("countervalues-error", `Failed to fetch ${granularity} history for ${pair.from.ticker}-${pair.to.ticker} ${String(e)}`);
|
|
187
|
+
return null;
|
|
188
|
+
})),
|
|
189
|
+
api
|
|
190
|
+
.fetchLatest(latestToFetch)
|
|
191
|
+
.then(rates => {
|
|
192
|
+
const out = {};
|
|
193
|
+
let hasData = false;
|
|
194
|
+
latestToFetch.forEach((pair, i) => {
|
|
195
|
+
var _a;
|
|
196
|
+
const key = pairId(pair);
|
|
197
|
+
const latest = rates[i];
|
|
198
|
+
if (((_a = data[key]) === null || _a === void 0 ? void 0 : _a.get("latest")) === latest)
|
|
199
|
+
return;
|
|
200
|
+
out[key] = {
|
|
201
|
+
latest: rates[i],
|
|
202
|
+
};
|
|
203
|
+
hasData = true;
|
|
204
|
+
});
|
|
205
|
+
if (!hasData)
|
|
206
|
+
return null;
|
|
207
|
+
return out;
|
|
208
|
+
})
|
|
209
|
+
.catch(e => {
|
|
210
|
+
if (settings.disableAutoRecoverErrors)
|
|
211
|
+
throw e;
|
|
212
|
+
log("countervalues-error", "Failed to fetch latest for " +
|
|
213
|
+
latestToFetch.map(p => `${p.from.ticker}-${p.to.ticker}`).join(",") +
|
|
214
|
+
" " +
|
|
215
|
+
String(e));
|
|
216
|
+
return null;
|
|
217
|
+
}),
|
|
218
|
+
]);
|
|
219
|
+
const updates = [];
|
|
220
|
+
for (const patch of histo) {
|
|
221
|
+
if (patch) {
|
|
222
|
+
updates.push(patch);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (latest) {
|
|
226
|
+
updates.push(latest);
|
|
227
|
+
}
|
|
228
|
+
log("countervalues", updates.length + " updates to apply");
|
|
229
|
+
const changesKeys = {};
|
|
230
|
+
updates.forEach(patch => {
|
|
231
|
+
Object.keys(patch).forEach(key => {
|
|
232
|
+
changesKeys[key] = 1;
|
|
233
|
+
if (!data[key]) {
|
|
234
|
+
data[key] = new Map();
|
|
235
|
+
}
|
|
236
|
+
Object.entries(patch[key]).forEach(([k, v]) => {
|
|
237
|
+
if (typeof v === "number")
|
|
238
|
+
data[key].set(k, v);
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
// synchronize the cache
|
|
243
|
+
Object.keys(changesKeys).forEach(pair => {
|
|
244
|
+
cache[pair] = generateCache(pair, data[pair], settings);
|
|
245
|
+
});
|
|
246
|
+
return {
|
|
247
|
+
data,
|
|
248
|
+
cache,
|
|
249
|
+
status,
|
|
250
|
+
};
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
export function lenseRateMap(state, pair) {
|
|
254
|
+
const rateId = pairId(pair);
|
|
255
|
+
return state.cache[rateId];
|
|
256
|
+
}
|
|
257
|
+
export function lenseRate({ stats, fallback, map }, query) {
|
|
258
|
+
const { date } = query;
|
|
259
|
+
if (!date)
|
|
260
|
+
return map.get("latest");
|
|
261
|
+
const { iso, hour, day } = formatCounterValueHashes(date);
|
|
262
|
+
if (stats.earliest && iso > stats.earliest)
|
|
263
|
+
return map.get("latest");
|
|
264
|
+
return map.get(hour) || map.get(day) || fallback;
|
|
265
|
+
}
|
|
266
|
+
export function calculate(state, initialQuery) {
|
|
267
|
+
const { from, to } = initialQuery;
|
|
268
|
+
if (from === to)
|
|
269
|
+
return initialQuery.value;
|
|
270
|
+
const { date, value, disableRounding, reverse } = initialQuery;
|
|
271
|
+
const query = {
|
|
272
|
+
date,
|
|
273
|
+
from,
|
|
274
|
+
to,
|
|
275
|
+
};
|
|
276
|
+
const map = lenseRateMap(state, query);
|
|
277
|
+
if (!map)
|
|
278
|
+
return;
|
|
279
|
+
let rate = lenseRate(map, query);
|
|
280
|
+
if (!rate)
|
|
281
|
+
return;
|
|
282
|
+
const mult = reverse
|
|
283
|
+
? magFromTo(initialQuery.to, initialQuery.from)
|
|
284
|
+
: magFromTo(initialQuery.from, initialQuery.to);
|
|
285
|
+
if (reverse && rate) {
|
|
286
|
+
rate = 1 / rate;
|
|
287
|
+
}
|
|
288
|
+
const val = rate ? value * rate * mult : 0;
|
|
289
|
+
return disableRounding ? val : Math.round(val);
|
|
290
|
+
}
|
|
291
|
+
export function calculateMany(state, dataPoints, initialQuery) {
|
|
292
|
+
const { reverse, disableRounding } = initialQuery;
|
|
293
|
+
const { from, to } = initialQuery;
|
|
294
|
+
if (from === to)
|
|
295
|
+
return dataPoints.map(d => d.value);
|
|
296
|
+
const map = lenseRateMap(state, initialQuery);
|
|
297
|
+
if (!map)
|
|
298
|
+
return Array(dataPoints.length).fill(undefined); // undefined array
|
|
299
|
+
const mult = reverse
|
|
300
|
+
? magFromTo(initialQuery.to, initialQuery.from)
|
|
301
|
+
: magFromTo(initialQuery.from, initialQuery.to);
|
|
302
|
+
return dataPoints.map(({ value, date }) => {
|
|
303
|
+
if (from === to)
|
|
304
|
+
return value;
|
|
305
|
+
let rate = lenseRate(map, {
|
|
306
|
+
from,
|
|
307
|
+
to,
|
|
308
|
+
date,
|
|
309
|
+
});
|
|
310
|
+
if (!rate)
|
|
311
|
+
return;
|
|
312
|
+
if (reverse && rate) {
|
|
313
|
+
rate = 1 / rate;
|
|
314
|
+
}
|
|
315
|
+
const val = rate ? value * rate * mult : 0;
|
|
316
|
+
return disableRounding ? val : Math.round(val);
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
function generateCache(pair, rateMap, settings) {
|
|
320
|
+
const map = new Map(rateMap);
|
|
321
|
+
const sorted = Array.from(map.keys())
|
|
322
|
+
.sort()
|
|
323
|
+
.filter(k => k !== "latest");
|
|
324
|
+
const oldest = sorted[0];
|
|
325
|
+
const earliest = sorted[sorted.length - 1];
|
|
326
|
+
const oldestDate = oldest ? parseFormattedDate(oldest) : null;
|
|
327
|
+
const earliestDate = earliest ? parseFormattedDate(earliest) : null;
|
|
328
|
+
let earliestStableDate = earliestDate;
|
|
329
|
+
let fallback = 0;
|
|
330
|
+
let hasHole = false;
|
|
331
|
+
if (oldestDate && oldest) {
|
|
332
|
+
// we find the most recent stable day and we set it in earliestStableDate
|
|
333
|
+
// if autofillGaps is on, shifting daily gaps (hourly don't need to be shifted as it automatically fallback on a day rate)
|
|
334
|
+
const now = Date.now();
|
|
335
|
+
const oldestTime = oldestDate.getTime();
|
|
336
|
+
let shiftingValue = map.get(oldest) || 0;
|
|
337
|
+
if (settings.autofillGaps) {
|
|
338
|
+
fallback = shiftingValue;
|
|
339
|
+
}
|
|
340
|
+
for (let t = oldestTime; t < now; t += incrementPerGranularity.daily) {
|
|
341
|
+
const d = new Date(t);
|
|
342
|
+
const k = formatCounterValueDay(d);
|
|
343
|
+
if (!map.has(k)) {
|
|
344
|
+
if (!hasHole) {
|
|
345
|
+
hasHole = true;
|
|
346
|
+
earliestStableDate = d;
|
|
347
|
+
}
|
|
348
|
+
if (settings.autofillGaps) {
|
|
349
|
+
map.set(k, shiftingValue);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
if (settings.autofillGaps) {
|
|
354
|
+
shiftingValue = map.get(k) || 0;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (!map.get("latest") && settings.autofillGaps) {
|
|
359
|
+
map.set("latest", shiftingValue);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
if (settings.autofillGaps) {
|
|
364
|
+
fallback = map.get("latest") || 0;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const stats = {
|
|
368
|
+
oldest,
|
|
369
|
+
earliest,
|
|
370
|
+
oldestDate,
|
|
371
|
+
earliestDate,
|
|
372
|
+
earliestStableDate,
|
|
373
|
+
};
|
|
374
|
+
return {
|
|
375
|
+
map,
|
|
376
|
+
stats,
|
|
377
|
+
fallback,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
export function resolveTrackingPairs(pairs) {
|
|
381
|
+
const trackingPairs = {};
|
|
382
|
+
for (const pair of pairs) {
|
|
383
|
+
const { from, to } = pair;
|
|
384
|
+
if (from === to)
|
|
385
|
+
continue;
|
|
386
|
+
// dedup and keep oldest date
|
|
387
|
+
let date = pair.startDate;
|
|
388
|
+
const id = pairId(pair);
|
|
389
|
+
if (trackingPairs[id]) {
|
|
390
|
+
const { startDate } = trackingPairs[id];
|
|
391
|
+
if (date) {
|
|
392
|
+
date = date < startDate ? date : startDate;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
trackingPairs[id] = {
|
|
396
|
+
from,
|
|
397
|
+
to,
|
|
398
|
+
startDate: date,
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
// to reach more deterministic order, notably in API calls, we sort by from/to
|
|
402
|
+
return Object.keys(trackingPairs)
|
|
403
|
+
.sort()
|
|
404
|
+
.map(id => trackingPairs[id]);
|
|
405
|
+
}
|
|
406
|
+
//# sourceMappingURL=logic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logic.js","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logic.test.d.ts","sourceRoot":"","sources":["../src/logic.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { genAccount } from "@ledgerhq/coin-framework/mocks/account";
|
|
2
|
+
import { getCryptoCurrencyById, getFiatCurrencyByTicker } from "@ledgerhq/cryptoassets";
|
|
3
|
+
import { inferTrackingPairForAccounts } from "./logic";
|
|
4
|
+
describe("inferTrackingPairForAccounts", () => {
|
|
5
|
+
const accounts = Array(20)
|
|
6
|
+
.fill(null)
|
|
7
|
+
.map((_, i) => genAccount("test" + i));
|
|
8
|
+
const usd = getFiatCurrencyByTicker("USD");
|
|
9
|
+
test("trackingPairs have a deterministic order regardless of accounts order", () => {
|
|
10
|
+
const trackingPairs = inferTrackingPairForAccounts(accounts, usd);
|
|
11
|
+
const accounts2 = accounts.slice(10).concat(accounts.slice(0, 10));
|
|
12
|
+
const trackingPairs2 = inferTrackingPairForAccounts(accounts2, usd);
|
|
13
|
+
expect(trackingPairs).toEqual(trackingPairs2);
|
|
14
|
+
});
|
|
15
|
+
test("trackingPairs with same from and to are filtered out", () => {
|
|
16
|
+
const first = genAccount("test1", { currency: getCryptoCurrencyById("bitcoin") });
|
|
17
|
+
const trackingPairs = inferTrackingPairForAccounts([first], first.currency);
|
|
18
|
+
expect(trackingPairs).toEqual([]);
|
|
19
|
+
});
|
|
20
|
+
test("trackingPairs with 2 accounts of same coin yield one tracking pair", () => {
|
|
21
|
+
const first = genAccount("test1", { currency: getCryptoCurrencyById("bitcoin") });
|
|
22
|
+
const second = genAccount("test2", { currency: getCryptoCurrencyById("bitcoin") });
|
|
23
|
+
const trackingPairs = inferTrackingPairForAccounts([first, second], usd);
|
|
24
|
+
expect(trackingPairs.length).toBe(1);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=logic.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logic.test.js","sourceRoot":"","sources":["../src/logic.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAEvD,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,MAAM,QAAQ,GAAG,KAAK,CAAC,EAAE,CAAC;SACvB,IAAI,CAAC,IAAI,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;IAE3C,IAAI,CAAC,uEAAuE,EAAE,GAAG,EAAE;QACjF,MAAM,aAAa,GAAG,4BAA4B,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAClE,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACnE,MAAM,cAAc,GAAG,4BAA4B,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QACpE,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAChE,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,qBAAqB,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAClF,MAAM,aAAa,GAAG,4BAA4B,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC5E,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC9E,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,qBAAqB,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAClF,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,qBAAqB,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACnF,MAAM,aAAa,GAAG,4BAA4B,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;QACzE,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/lib-es/mock.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,MAA0B,CAAC;AAC7D,eAAO,MAAM,QAAQ,OAAO,CAAC;AAE7B,eAAO,MAAM,YAAY,WAIrB,CAAC"}
|