@ledgerhq/live-common 34.55.0-nightly.20251215120904 → 34.55.0-nightly.20251217023943
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/lib/apps/listApps.d.ts.map +1 -1
- package/lib/apps/listApps.js +10 -0
- package/lib/apps/listApps.js.map +1 -1
- package/lib/apps/polyfill.d.ts +2 -2
- package/lib/apps/polyfill.d.ts.map +1 -1
- package/lib/apps/types.d.ts +4 -0
- package/lib/apps/types.d.ts.map +1 -1
- package/lib/apps/types.js.map +1 -1
- package/lib/dada-client/hooks/useAssetsData.d.ts +1 -0
- package/lib/dada-client/hooks/useAssetsData.d.ts.map +1 -1
- package/lib/dada-client/hooks/useAssetsData.js +3 -0
- package/lib/dada-client/hooks/useAssetsData.js.map +1 -1
- package/lib/dada-client/hooks/useInterestRatesByCurrencies.d.ts +1 -5
- package/lib/dada-client/hooks/useInterestRatesByCurrencies.d.ts.map +1 -1
- package/lib/dada-client/hooks/useMarketByCurrencies.d.ts +1 -4
- package/lib/dada-client/hooks/useMarketByCurrencies.d.ts.map +1 -1
- package/lib/dada-client/utils/errorUtils.d.ts +28 -0
- package/lib/dada-client/utils/errorUtils.d.ts.map +1 -0
- package/lib/dada-client/utils/errorUtils.js +53 -0
- package/lib/dada-client/utils/errorUtils.js.map +1 -0
- package/lib/e2e/index.d.ts +1 -0
- package/lib/e2e/index.d.ts.map +1 -1
- package/lib/e2e/swap.js +2 -2
- package/lib/e2e/swap.js.map +1 -1
- package/lib/env.react.d.ts +1 -1
- package/lib/env.react.d.ts.map +1 -1
- package/lib/hw/actions/app.d.ts +2 -0
- package/lib/hw/actions/app.d.ts.map +1 -1
- package/lib/hw/actions/app.js +8 -2
- package/lib/hw/actions/app.js.map +1 -1
- package/lib/hw/actions/manager.d.ts +2 -0
- package/lib/hw/actions/manager.d.ts.map +1 -1
- package/lib/hw/actions/manager.js +6 -0
- package/lib/hw/actions/manager.js.map +1 -1
- package/lib/hw/connectApp.d.ts +4 -0
- package/lib/hw/connectApp.d.ts.map +1 -1
- package/lib/hw/connectApp.js.map +1 -1
- package/lib/hw/connectAppEventMapper.d.ts +1 -0
- package/lib/hw/connectAppEventMapper.d.ts.map +1 -1
- package/lib/hw/connectAppEventMapper.js +12 -0
- package/lib/hw/connectAppEventMapper.js.map +1 -1
- package/lib/hw/getOnboardingStatePolling.d.ts.map +1 -1
- package/lib/hw/getOnboardingStatePolling.js +11 -1
- package/lib/hw/getOnboardingStatePolling.js.map +1 -1
- package/lib/modularDrawer/utils/getLoadingStatus.d.ts +1 -1
- package/lib/modularDrawer/utils/getLoadingStatus.d.ts.map +1 -1
- package/lib/socket/index.d.ts.map +1 -1
- package/lib/socket/index.js +28 -0
- package/lib/socket/index.js.map +1 -1
- package/lib/wallet-api/Exchange/server.d.ts.map +1 -1
- package/lib/wallet-api/Exchange/server.js +18 -0
- package/lib/wallet-api/Exchange/server.js.map +1 -1
- package/lib/wallet-api/Exchange/tracking.d.ts +18 -0
- package/lib/wallet-api/Exchange/tracking.d.ts.map +1 -1
- package/lib/wallet-api/Exchange/tracking.js +22 -0
- package/lib/wallet-api/Exchange/tracking.js.map +1 -1
- package/lib-es/apps/listApps.d.ts.map +1 -1
- package/lib-es/apps/listApps.js +10 -0
- package/lib-es/apps/listApps.js.map +1 -1
- package/lib-es/apps/polyfill.d.ts +2 -2
- package/lib-es/apps/polyfill.d.ts.map +1 -1
- package/lib-es/apps/types.d.ts +4 -0
- package/lib-es/apps/types.d.ts.map +1 -1
- package/lib-es/apps/types.js.map +1 -1
- package/lib-es/dada-client/hooks/useAssetsData.d.ts +1 -0
- package/lib-es/dada-client/hooks/useAssetsData.d.ts.map +1 -1
- package/lib-es/dada-client/hooks/useAssetsData.js +3 -0
- package/lib-es/dada-client/hooks/useAssetsData.js.map +1 -1
- package/lib-es/dada-client/hooks/useInterestRatesByCurrencies.d.ts +1 -5
- package/lib-es/dada-client/hooks/useInterestRatesByCurrencies.d.ts.map +1 -1
- package/lib-es/dada-client/hooks/useMarketByCurrencies.d.ts +1 -4
- package/lib-es/dada-client/hooks/useMarketByCurrencies.d.ts.map +1 -1
- package/lib-es/dada-client/utils/errorUtils.d.ts +28 -0
- package/lib-es/dada-client/utils/errorUtils.d.ts.map +1 -0
- package/lib-es/dada-client/utils/errorUtils.js +45 -0
- package/lib-es/dada-client/utils/errorUtils.js.map +1 -0
- package/lib-es/e2e/index.d.ts +1 -0
- package/lib-es/e2e/index.d.ts.map +1 -1
- package/lib-es/e2e/swap.js +2 -2
- package/lib-es/e2e/swap.js.map +1 -1
- package/lib-es/env.react.d.ts +1 -1
- package/lib-es/env.react.d.ts.map +1 -1
- package/lib-es/hw/actions/app.d.ts +2 -0
- package/lib-es/hw/actions/app.d.ts.map +1 -1
- package/lib-es/hw/actions/app.js +8 -2
- package/lib-es/hw/actions/app.js.map +1 -1
- package/lib-es/hw/actions/manager.d.ts +2 -0
- package/lib-es/hw/actions/manager.d.ts.map +1 -1
- package/lib-es/hw/actions/manager.js +6 -0
- package/lib-es/hw/actions/manager.js.map +1 -1
- package/lib-es/hw/connectApp.d.ts +4 -0
- package/lib-es/hw/connectApp.d.ts.map +1 -1
- package/lib-es/hw/connectApp.js.map +1 -1
- package/lib-es/hw/connectAppEventMapper.d.ts +1 -0
- package/lib-es/hw/connectAppEventMapper.d.ts.map +1 -1
- package/lib-es/hw/connectAppEventMapper.js +12 -0
- package/lib-es/hw/connectAppEventMapper.js.map +1 -1
- package/lib-es/hw/getOnboardingStatePolling.d.ts.map +1 -1
- package/lib-es/hw/getOnboardingStatePolling.js +12 -2
- package/lib-es/hw/getOnboardingStatePolling.js.map +1 -1
- package/lib-es/modularDrawer/utils/getLoadingStatus.d.ts +1 -1
- package/lib-es/modularDrawer/utils/getLoadingStatus.d.ts.map +1 -1
- package/lib-es/socket/index.d.ts.map +1 -1
- package/lib-es/socket/index.js +28 -0
- package/lib-es/socket/index.js.map +1 -1
- package/lib-es/wallet-api/Exchange/server.d.ts.map +1 -1
- package/lib-es/wallet-api/Exchange/server.js +18 -0
- package/lib-es/wallet-api/Exchange/server.js.map +1 -1
- package/lib-es/wallet-api/Exchange/tracking.d.ts +18 -0
- package/lib-es/wallet-api/Exchange/tracking.d.ts.map +1 -1
- package/lib-es/wallet-api/Exchange/tracking.js +22 -0
- package/lib-es/wallet-api/Exchange/tracking.js.map +1 -1
- package/package.json +76 -76
- package/src/apps/listApps.ts +11 -0
- package/src/apps/types.ts +5 -0
- package/src/dada-client/hooks/useAssetsData.ts +4 -0
- package/src/dada-client/utils/__test__/errorUtils.test.ts +222 -0
- package/src/dada-client/utils/errorUtils.ts +57 -0
- package/src/e2e/swap.ts +2 -2
- package/src/hw/actions/app.ts +12 -3
- package/src/hw/actions/manager.ts +13 -0
- package/src/hw/connectApp.ts +5 -0
- package/src/hw/connectAppEventMapper.ts +12 -0
- package/src/hw/getOnboardingStatePolling.test.ts +64 -1
- package/src/hw/getOnboardingStatePolling.ts +15 -3
- package/src/modularDrawer/utils/getLoadingStatus.ts +1 -1
- package/src/platform/react.ts +1 -1
- package/src/socket/index.ts +35 -0
- package/src/wallet-api/Exchange/server.test.ts +2 -0
- package/src/wallet-api/Exchange/server.ts +20 -0
- package/src/wallet-api/Exchange/tracking.ts +56 -0
- package/src/wallet-api/react.ts +1 -1
package/src/hw/connectApp.ts
CHANGED
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
} from "@ledgerhq/device-management-kit";
|
|
40
40
|
import { ConnectAppDeviceAction } from "@ledgerhq/live-dmk-shared";
|
|
41
41
|
import { ConnectAppEventMapper } from "./connectAppEventMapper";
|
|
42
|
+
import { DeviceId } from "@ledgerhq/client-ids/ids";
|
|
42
43
|
|
|
43
44
|
export type RequiresDerivation = {
|
|
44
45
|
currencyId: string;
|
|
@@ -84,6 +85,10 @@ export type ConnectAppEvent =
|
|
|
84
85
|
| {
|
|
85
86
|
type: "device-permission-granted";
|
|
86
87
|
}
|
|
88
|
+
| {
|
|
89
|
+
type: "device-id";
|
|
90
|
+
deviceId: DeviceId;
|
|
91
|
+
}
|
|
87
92
|
| {
|
|
88
93
|
type: "app-not-installed";
|
|
89
94
|
appNames: string[];
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
LatestFirmwareVersionRequired,
|
|
29
29
|
UnsupportedFeatureError,
|
|
30
30
|
} from "@ledgerhq/errors";
|
|
31
|
+
import { DeviceId } from "@ledgerhq/client-ids/ids";
|
|
31
32
|
|
|
32
33
|
import type { SkippedAppOp } from "../apps/types";
|
|
33
34
|
import { SkipReason } from "../apps/types";
|
|
@@ -40,6 +41,7 @@ export class ConnectAppEventMapper {
|
|
|
40
41
|
private permissionRequested: boolean = false;
|
|
41
42
|
private lastSeenDeviceSent: boolean = false;
|
|
42
43
|
private installPlan: InstallPlan | null = null;
|
|
44
|
+
private deviceId: string | undefined = undefined;
|
|
43
45
|
private eventSubject = new Subject<ConnectAppEvent>();
|
|
44
46
|
|
|
45
47
|
constructor(
|
|
@@ -162,6 +164,16 @@ export class ConnectAppEventMapper {
|
|
|
162
164
|
if (intermediateValue.installPlan !== null) {
|
|
163
165
|
this.handleInstallPlan(intermediateValue.installPlan);
|
|
164
166
|
}
|
|
167
|
+
if (intermediateValue.deviceId) {
|
|
168
|
+
const deviceIdString = Buffer.from(intermediateValue.deviceId).toString("hex");
|
|
169
|
+
if (deviceIdString !== this.deviceId) {
|
|
170
|
+
this.deviceId = deviceIdString;
|
|
171
|
+
this.eventSubject.next({
|
|
172
|
+
type: "device-id",
|
|
173
|
+
deviceId: DeviceId.fromString(deviceIdString),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
165
177
|
break;
|
|
166
178
|
}
|
|
167
179
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getOnboardingStatePolling } from "./getOnboardingStatePolling";
|
|
2
|
-
import { from, Subscription, TimeoutError } from "rxjs";
|
|
2
|
+
import { from, of, Subscription, TimeoutError } from "rxjs";
|
|
3
3
|
import * as rxjsOperators from "rxjs/operators";
|
|
4
4
|
import { DeviceModelId } from "@ledgerhq/devices";
|
|
5
5
|
import Transport from "@ledgerhq/hw-transport";
|
|
@@ -14,7 +14,13 @@ import { getVersion } from "../device/use-cases/getVersionUseCase";
|
|
|
14
14
|
import { extractOnboardingState, OnboardingState, OnboardingStep } from "./extractOnboardingState";
|
|
15
15
|
import { SeedPhraseType } from "@ledgerhq/types-live";
|
|
16
16
|
import { DeviceDisconnectedWhileSendingError } from "@ledgerhq/device-management-kit";
|
|
17
|
+
import { quitApp } from "../deviceSDK/commands/quitApp";
|
|
17
18
|
|
|
19
|
+
jest.mock("../deviceSDK/commands/quitApp", () => {
|
|
20
|
+
return {
|
|
21
|
+
quitApp: jest.fn(() => of(undefined)), // immediately-completing observable
|
|
22
|
+
};
|
|
23
|
+
});
|
|
18
24
|
jest.mock("./deviceAccess");
|
|
19
25
|
jest.mock("../device/use-cases/getVersionUseCase");
|
|
20
26
|
jest.mock("./extractOnboardingState");
|
|
@@ -42,6 +48,7 @@ const pollingPeriodMs = 1000;
|
|
|
42
48
|
|
|
43
49
|
const mockedGetVersion = jest.mocked(getVersion);
|
|
44
50
|
const mockedWithDevice = jest.mocked(withDevice);
|
|
51
|
+
const mockedQuitApp = jest.mocked(quitApp);
|
|
45
52
|
mockedWithDevice.mockReturnValue(job => from(job(new Transport())));
|
|
46
53
|
|
|
47
54
|
const mockedExtractOnboardingState = jest.mocked(extractOnboardingState);
|
|
@@ -65,6 +72,7 @@ describe("getOnboardingStatePolling", () => {
|
|
|
65
72
|
afterEach(() => {
|
|
66
73
|
mockedGetVersion.mockClear();
|
|
67
74
|
mockedExtractOnboardingState.mockClear();
|
|
75
|
+
mockedQuitApp.mockClear();
|
|
68
76
|
jest.clearAllTimers();
|
|
69
77
|
onboardingStatePollingSubscription?.unsubscribe();
|
|
70
78
|
});
|
|
@@ -308,6 +316,61 @@ describe("getOnboardingStatePolling", () => {
|
|
|
308
316
|
},
|
|
309
317
|
});
|
|
310
318
|
});
|
|
319
|
+
it("should call quitApp before fetching the device version", done => {
|
|
320
|
+
mockedGetVersion.mockResolvedValue(aFirmwareInfo);
|
|
321
|
+
mockedExtractOnboardingState.mockReturnValue(anOnboardingState);
|
|
322
|
+
|
|
323
|
+
const device = aDevice;
|
|
324
|
+
|
|
325
|
+
getOnboardingStatePolling({
|
|
326
|
+
deviceId: device.deviceId,
|
|
327
|
+
deviceName: null,
|
|
328
|
+
pollingPeriodMs,
|
|
329
|
+
}).subscribe({
|
|
330
|
+
next: value => {
|
|
331
|
+
try {
|
|
332
|
+
expect(value.onboardingState).toEqual(anOnboardingState);
|
|
333
|
+
|
|
334
|
+
expect(mockedQuitApp).toHaveBeenCalledTimes(1);
|
|
335
|
+
|
|
336
|
+
const firstCallArgs = (mockedQuitApp as jest.Mock).mock.calls[0];
|
|
337
|
+
expect(firstCallArgs[0]).toBeInstanceOf(Transport);
|
|
338
|
+
|
|
339
|
+
done();
|
|
340
|
+
} catch (err) {
|
|
341
|
+
done(err);
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
error: err => done(err),
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
jest.advanceTimersByTime(pollingPeriodMs - 1);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
it("should call quitApp only once when polling", () => {
|
|
351
|
+
mockedGetVersion.mockResolvedValue(aFirmwareInfo);
|
|
352
|
+
mockedExtractOnboardingState.mockReturnValue(anOnboardingState);
|
|
353
|
+
|
|
354
|
+
const device = aDevice;
|
|
355
|
+
|
|
356
|
+
onboardingStatePollingSubscription = getOnboardingStatePolling({
|
|
357
|
+
deviceId: device.deviceId,
|
|
358
|
+
deviceName: null,
|
|
359
|
+
pollingPeriodMs,
|
|
360
|
+
}).subscribe();
|
|
361
|
+
|
|
362
|
+
jest.advanceTimersByTime(pollingPeriodMs - 1);
|
|
363
|
+
|
|
364
|
+
expect(mockedQuitApp).toHaveBeenCalledTimes(1);
|
|
365
|
+
const firstCallArgs = (mockedQuitApp as jest.Mock).mock.calls[0];
|
|
366
|
+
expect(firstCallArgs[0]).toBeInstanceOf(Transport);
|
|
367
|
+
|
|
368
|
+
jest.advanceTimersByTime(pollingPeriodMs * 5);
|
|
369
|
+
|
|
370
|
+
expect(mockedQuitApp).toHaveBeenCalledTimes(1);
|
|
371
|
+
|
|
372
|
+
expect(mockedGetVersion.mock.calls.length).toBeGreaterThanOrEqual(1);
|
|
373
|
+
});
|
|
311
374
|
});
|
|
312
375
|
|
|
313
376
|
describe("When the device is in bootloader mode", () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { from, of, throwError, Observable, TimeoutError, timer } from "rxjs";
|
|
2
|
-
import { map, catchError, first, timeout, repeat } from "rxjs/operators";
|
|
2
|
+
import { map, catchError, first, timeout, repeat, switchMap } from "rxjs/operators";
|
|
3
3
|
import { getVersion } from "../device/use-cases/getVersionUseCase";
|
|
4
4
|
import { withDevice } from "./deviceAccess";
|
|
5
5
|
import {
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
import { FirmwareInfo } from "@ledgerhq/types-live";
|
|
18
18
|
import { extractOnboardingState, OnboardingState } from "./extractOnboardingState";
|
|
19
19
|
import { DeviceDisconnectedWhileSendingError } from "@ledgerhq/device-management-kit";
|
|
20
|
+
import { quitApp } from "../deviceSDK/commands/quitApp";
|
|
20
21
|
|
|
21
22
|
export type OnboardingStatePollingResult = {
|
|
22
23
|
onboardingState: OnboardingState | null;
|
|
@@ -58,11 +59,23 @@ export const getOnboardingStatePolling = ({
|
|
|
58
59
|
safeGuardTimeoutMs = pollingPeriodMs * 10, // Nb Empirical value
|
|
59
60
|
allowedErrorChecks = [],
|
|
60
61
|
}: GetOnboardingStatePollingArgs): GetOnboardingStatePollingResult => {
|
|
62
|
+
let hasQuitAppAlreadyRun = false;
|
|
63
|
+
|
|
61
64
|
const getOnboardingStateOnce = (): Observable<OnboardingStatePollingResult> => {
|
|
62
65
|
return withDevice(deviceId, {
|
|
63
66
|
openTimeoutMs: transportAbortTimeoutMs,
|
|
64
67
|
matchDeviceByName: deviceName ?? undefined,
|
|
65
|
-
})(t =>
|
|
68
|
+
})(t => {
|
|
69
|
+
const getVersionObs = from(getVersion(t, { abortTimeoutMs: transportAbortTimeoutMs }));
|
|
70
|
+
|
|
71
|
+
// only run quitApp the first time
|
|
72
|
+
if (hasQuitAppAlreadyRun) {
|
|
73
|
+
return getVersionObs;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
hasQuitAppAlreadyRun = true;
|
|
77
|
+
return quitApp(t).pipe(switchMap(() => getVersionObs));
|
|
78
|
+
}).pipe(
|
|
66
79
|
timeout(safeGuardTimeoutMs), // Throws a TimeoutError
|
|
67
80
|
first(),
|
|
68
81
|
catchError((error: unknown) => {
|
|
@@ -73,7 +86,6 @@ export const getOnboardingStatePolling = ({
|
|
|
73
86
|
// Pushes the error to the next step to be processed (no retry from the beginning)
|
|
74
87
|
return of(error as Error);
|
|
75
88
|
}
|
|
76
|
-
|
|
77
89
|
return throwError(() => error);
|
|
78
90
|
}),
|
|
79
91
|
map((event: FirmwareInfo | Error) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LoadingStatus } from "../../deposit/type";
|
|
2
2
|
import { SerializedError } from "@reduxjs/toolkit";
|
|
3
|
-
import { FetchBaseQueryError } from "@reduxjs/toolkit/query";
|
|
3
|
+
import { FetchBaseQueryError } from "@reduxjs/toolkit/query/react";
|
|
4
4
|
|
|
5
5
|
export const getLoadingStatus = ({
|
|
6
6
|
isLoading,
|
package/src/platform/react.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useCallback, useMemo } from "react";
|
|
2
2
|
import { useDispatch } from "react-redux";
|
|
3
3
|
import { ThunkDispatch, UnknownAction } from "@reduxjs/toolkit";
|
|
4
|
-
import { InfiniteData } from "@reduxjs/toolkit/query";
|
|
4
|
+
import { InfiniteData } from "@reduxjs/toolkit/query/react";
|
|
5
5
|
import { AccountLike } from "@ledgerhq/types-live";
|
|
6
6
|
import { makeRe } from "minimatch";
|
|
7
7
|
import type {
|
package/src/socket/index.ts
CHANGED
|
@@ -14,6 +14,8 @@ import {
|
|
|
14
14
|
import { cancelDeviceAction } from "../hw/deviceAccess";
|
|
15
15
|
import { getEnv } from "@ledgerhq/live-env";
|
|
16
16
|
import type { SocketEvent } from "@ledgerhq/types-live";
|
|
17
|
+
import { sha3_256 } from "@noble/hashes/sha3";
|
|
18
|
+
import { DeviceId } from "@ledgerhq/client-ids/ids";
|
|
17
19
|
|
|
18
20
|
const LOG_TYPE = "socket";
|
|
19
21
|
const ALLOW_SECURE_CHANNEL_DELAY = 500;
|
|
@@ -51,6 +53,7 @@ export function createDeviceSocket(
|
|
|
51
53
|
let correctlyFinished = false; // the socket logic reach a normal termination
|
|
52
54
|
let inBulkMode = false; // we have an array of apdus to exchange, without the need of more WS messages.
|
|
53
55
|
let allowSecureChannelTimeout: NodeJS.Timeout | null = null; // allows to delay/cancel the user confirmation event
|
|
56
|
+
let deviceIdCaptured = false; // track if we've already captured the device id
|
|
54
57
|
const ws = new WS(url);
|
|
55
58
|
|
|
56
59
|
ws.onopen = () => {
|
|
@@ -127,6 +130,10 @@ export function createDeviceSocket(
|
|
|
127
130
|
}, ALLOW_SECURE_CHANNEL_DELAY);
|
|
128
131
|
}
|
|
129
132
|
|
|
133
|
+
// Detect GetCertificate APDU to extract device ID
|
|
134
|
+
const shouldCaptureDeviceId =
|
|
135
|
+
!deviceIdCaptured && apdu.slice(0, 2).toString("hex") === "e052";
|
|
136
|
+
|
|
130
137
|
const r = await transport.exchange(apdu);
|
|
131
138
|
|
|
132
139
|
if (allowSecureChannelTimeout) {
|
|
@@ -170,6 +177,34 @@ export function createDeviceSocket(
|
|
|
170
177
|
});
|
|
171
178
|
}
|
|
172
179
|
|
|
180
|
+
// Extract device ID from GetCertificate response
|
|
181
|
+
if (shouldCaptureDeviceId && status === StatusCodes.OK) {
|
|
182
|
+
try {
|
|
183
|
+
const responseData = r.slice(0, r.length - 2);
|
|
184
|
+
const headerLength = responseData[0];
|
|
185
|
+
const publicKeyLengthOffset = 1 + headerLength;
|
|
186
|
+
const publicKeyLength = responseData[publicKeyLengthOffset];
|
|
187
|
+
const publicKeyOffset = publicKeyLengthOffset + 1;
|
|
188
|
+
const publicKey = responseData.slice(
|
|
189
|
+
publicKeyOffset,
|
|
190
|
+
publicKeyOffset + publicKeyLength,
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
// Compute device ID as SHA3-256 hash of the public key
|
|
194
|
+
const deviceIdHash = sha3_256(publicKey);
|
|
195
|
+
const deviceIdString = Buffer.from(deviceIdHash).toString("hex");
|
|
196
|
+
const deviceId = DeviceId.fromString(deviceIdString);
|
|
197
|
+
deviceIdCaptured = true;
|
|
198
|
+
|
|
199
|
+
o.next({
|
|
200
|
+
type: "device-id",
|
|
201
|
+
deviceId,
|
|
202
|
+
});
|
|
203
|
+
} catch (err) {
|
|
204
|
+
tracer.trace("Failed to extract device ID from GetCertificate response", { err });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
173
208
|
const data = r.slice(0, r.length - 2);
|
|
174
209
|
o.next({
|
|
175
210
|
type: "exchange",
|
|
@@ -467,6 +467,17 @@ export const handlers = ({
|
|
|
467
467
|
throw wrappedError;
|
|
468
468
|
}
|
|
469
469
|
|
|
470
|
+
tracking.swapPayloadRequested({
|
|
471
|
+
provider,
|
|
472
|
+
transactionId,
|
|
473
|
+
fromAccountAddress,
|
|
474
|
+
toAccountAddress,
|
|
475
|
+
fromCurrencyId: fromCurrency!.id,
|
|
476
|
+
toCurrencyId: toCurrency?.id,
|
|
477
|
+
fromAmount,
|
|
478
|
+
quoteId,
|
|
479
|
+
});
|
|
480
|
+
|
|
470
481
|
const {
|
|
471
482
|
binaryPayload,
|
|
472
483
|
signature,
|
|
@@ -494,6 +505,15 @@ export const handlers = ({
|
|
|
494
505
|
throw wrappedError;
|
|
495
506
|
});
|
|
496
507
|
|
|
508
|
+
tracking.swapResponseRetrieved({
|
|
509
|
+
binaryPayload,
|
|
510
|
+
signature,
|
|
511
|
+
payinAddress,
|
|
512
|
+
swapId,
|
|
513
|
+
payinExtraId,
|
|
514
|
+
extraTransactionParameters,
|
|
515
|
+
});
|
|
516
|
+
|
|
497
517
|
// Complete Swap
|
|
498
518
|
const trackingCompleteParams = {
|
|
499
519
|
provider: params.provider,
|
|
@@ -119,6 +119,62 @@ export default function trackingWrapper(trackCall: TrackExchange) {
|
|
|
119
119
|
completeExchangeNoParams: (manifest: AppManifest) => {
|
|
120
120
|
track("Completes Exchange no params", getEventData(manifest));
|
|
121
121
|
},
|
|
122
|
+
|
|
123
|
+
swapPayloadRequested: ({
|
|
124
|
+
provider,
|
|
125
|
+
transactionId,
|
|
126
|
+
fromAccountAddress,
|
|
127
|
+
toAccountAddress,
|
|
128
|
+
fromCurrencyId,
|
|
129
|
+
toCurrencyId,
|
|
130
|
+
fromAmount,
|
|
131
|
+
quoteId,
|
|
132
|
+
}: {
|
|
133
|
+
provider: string;
|
|
134
|
+
transactionId: string;
|
|
135
|
+
fromAccountAddress: string;
|
|
136
|
+
toAccountAddress: string;
|
|
137
|
+
fromCurrencyId: string;
|
|
138
|
+
toCurrencyId?: string;
|
|
139
|
+
fromAmount: string | number;
|
|
140
|
+
quoteId?: string;
|
|
141
|
+
}) => {
|
|
142
|
+
track("Swap payload requested", {
|
|
143
|
+
provider,
|
|
144
|
+
transactionId,
|
|
145
|
+
fromAccountAddress,
|
|
146
|
+
toAccountAddress,
|
|
147
|
+
fromCurrencyId,
|
|
148
|
+
toCurrencyId,
|
|
149
|
+
fromAmount: String(fromAmount),
|
|
150
|
+
quoteId,
|
|
151
|
+
});
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
swapResponseRetrieved: ({
|
|
155
|
+
binaryPayload,
|
|
156
|
+
signature,
|
|
157
|
+
payinAddress,
|
|
158
|
+
swapId,
|
|
159
|
+
payinExtraId,
|
|
160
|
+
extraTransactionParameters,
|
|
161
|
+
}: {
|
|
162
|
+
binaryPayload: string;
|
|
163
|
+
signature: string;
|
|
164
|
+
payinAddress: string;
|
|
165
|
+
swapId: string;
|
|
166
|
+
payinExtraId?: string;
|
|
167
|
+
extraTransactionParameters?: string;
|
|
168
|
+
}) => {
|
|
169
|
+
track("Swap response retrieved", {
|
|
170
|
+
binaryPayload,
|
|
171
|
+
signature,
|
|
172
|
+
payinAddress,
|
|
173
|
+
swapId,
|
|
174
|
+
payinExtraId,
|
|
175
|
+
extraTransactionParameters,
|
|
176
|
+
});
|
|
177
|
+
},
|
|
122
178
|
} as const;
|
|
123
179
|
}
|
|
124
180
|
|
package/src/wallet-api/react.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { UserRefusedOnDevice } from "@ledgerhq/errors";
|
|
|
16
16
|
import { WalletState } from "@ledgerhq/live-wallet/store";
|
|
17
17
|
import { endpoints as calEndpoints } from "@ledgerhq/cryptoassets/cal-client/state-manager/api";
|
|
18
18
|
import { ThunkDispatch, UnknownAction } from "@reduxjs/toolkit";
|
|
19
|
-
import { InfiniteData } from "@reduxjs/toolkit/query";
|
|
19
|
+
import { InfiniteData } from "@reduxjs/toolkit/query/react";
|
|
20
20
|
import type {
|
|
21
21
|
TokensDataWithPagination,
|
|
22
22
|
PageParam,
|