diff --git a/.flowconfig b/.flowconfig
index 4a2c3416b8..8477494a7a 100644
--- a/.flowconfig
+++ b/.flowconfig
@@ -35,6 +35,7 @@ node_modules/warning/.*
; Creates weird flow erros, ignoring for now
.*/node_modules/@ledgerhq/react-native-hw-transport-ble/lib/BleTransport.js
+.*/node_modules/@ledgerhq/live-common/src/families/tezos/bridge/js.ts
[include]
@@ -52,6 +53,7 @@ esproposal.nullish_coalescing=enable
module.file_ext=.js
module.file_ext=.tsx
+module.file_ext=.ts
module.file_ext=.json
module.file_ext=.ios.js
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 711a13a2f6..ec4516782c 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -10,8 +10,6 @@ project.ext.envConfigFiles = [
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
-import com.android.build.OutputFile
-
/**
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
* and bundleReleaseJsAndAssets).
@@ -257,3 +255,5 @@ task copyDownloadableDepsToLibs(type: Copy) {
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 33c5fa42a4..782736f69e 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -6,6 +6,7 @@
+
@@ -30,11 +31,11 @@
android:allowBackup="false"
android:theme="@style/AppTheme"
android:networkSecurityConfig="@xml/network_security_config">
+
> {
+ return emptyList()
+ }
+
+ override fun createNativeModules(reactContext: ReactApplicationContext): List {
+ val modules: MutableList = ArrayList()
+ modules.add(BackgroundRunner(reactContext))
+ return modules
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/java/com/ledger/live/BackgroundService.kt b/android/app/src/main/java/com/ledger/live/BackgroundService.kt
new file mode 100644
index 0000000000..cf41e9098b
--- /dev/null
+++ b/android/app/src/main/java/com/ledger/live/BackgroundService.kt
@@ -0,0 +1,22 @@
+package com.ledger.live;
+
+import android.content.Intent
+import com.facebook.react.HeadlessJsTaskService
+import com.facebook.react.bridge.Arguments
+import com.facebook.react.jstasks.HeadlessJsTaskConfig
+
+class BackgroundService : HeadlessJsTaskService() {
+ override fun getTaskConfig(intent: Intent): HeadlessJsTaskConfig? {
+ val extras = intent.extras
+ return if (extras != null) {
+ HeadlessJsTaskConfig(
+ "BackgroundRunnerService",
+ Arguments.fromBundle(extras),
+ 600000, // timeout for the task
+ true // optional: defines whether or not the task is allowed in foreground. Default is false
+ )
+ } else {
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/java/com/ledger/live/MainActivity.java b/android/app/src/main/java/com/ledger/live/MainActivity.java
index 790b32aef6..59649e15e2 100644
--- a/android/app/src/main/java/com/ledger/live/MainActivity.java
+++ b/android/app/src/main/java/com/ledger/live/MainActivity.java
@@ -1,14 +1,19 @@
package com.ledger.live;
import expo.modules.ReactActivityDelegateWrapper;
+import android.app.PendingIntent;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
+import androidx.core.app.NotificationCompat;
+import androidx.core.app.NotificationManagerCompat;
+
import com.facebook.react.ReactActivity;
import org.devio.rn.splashscreen.SplashScreen;
@@ -45,7 +50,6 @@ protected void onCreate(Bundle savedInstanceState) {
}
}
super.onCreate(null);
-
/**
* Addresses an inconvenient side-effect of using `password-visible`, that
* allowed styled texts to be pasted (receiver's address for instance) retaining
diff --git a/android/app/src/main/java/com/ledger/live/MainApplication.java b/android/app/src/main/java/com/ledger/live/MainApplication.java
index 7587bb7a74..315fc33f9d 100644
--- a/android/app/src/main/java/com/ledger/live/MainApplication.java
+++ b/android/app/src/main/java/com/ledger/live/MainApplication.java
@@ -1,10 +1,14 @@
package com.ledger.live;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
import android.content.res.Configuration;
import expo.modules.ApplicationLifecycleDispatcher;
import expo.modules.ReactNativeHostWrapper;
import android.app.Application;
import android.content.Context;
+import android.os.Build;
+
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import co.airbitz.fastcrypto.RNFastCryptoPackage;
@@ -22,6 +26,24 @@
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
+ public static String LO_NOTIFICATION_CHANNEL = "lo-llm";
+ public static String HI_NOTIFICATION_CHANNEL = "hi-llm";
+ public static int FW_UPDATE_NOTIFICATION_PROGRESS = 1;
+ public static int FW_UPDATE_NOTIFICATION_USER = 2;
+
+ private void createNotificationChannel() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ String description = "Notification channel for background running tasks";
+ NotificationChannel loChannel = new NotificationChannel(LO_NOTIFICATION_CHANNEL, LO_NOTIFICATION_CHANNEL, NotificationManager.IMPORTANCE_DEFAULT);
+ loChannel.setDescription(description);
+ NotificationChannel hiChannel = new NotificationChannel(HI_NOTIFICATION_CHANNEL, HI_NOTIFICATION_CHANNEL, NotificationManager.IMPORTANCE_HIGH);
+ hiChannel.setDescription(description);
+
+ NotificationManager notificationManager = getSystemService(NotificationManager.class);
+ notificationManager.createNotificationChannel(loChannel);
+ notificationManager.createNotificationChannel(hiChannel);
+ }
+ }
private final ReactNativeHost mReactNativeHost =
new ReactNativeHostWrapper(this, new ReactNativeHost(this) {
@@ -36,6 +58,7 @@ protected List getPackages() {
List packages = new PackageList(this).getPackages();
packages.add(new BluetoothHelperPackage());
packages.add(new ReactVideoPackage());
+ packages.add(new BackgroundRunnerPackager());
return packages;
}
@@ -61,6 +84,7 @@ public void onCreate() {
SoLoader.init(this, /* native exopackage */ false);
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
ApplicationLifecycleDispatcher.onApplicationCreate(this);
+ createNotificationChannel();
}
/**
diff --git a/android/app/src/main/res/drawable-hdpi-v11/ic_stat_group.png b/android/app/src/main/res/drawable-hdpi-v11/ic_stat_group.png
new file mode 100644
index 0000000000..033c29baf4
Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi-v11/ic_stat_group.png differ
diff --git a/android/app/src/main/res/drawable-hdpi/ic_stat_group.png b/android/app/src/main/res/drawable-hdpi/ic_stat_group.png
new file mode 100644
index 0000000000..5f74d50ec6
Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/ic_stat_group.png differ
diff --git a/android/app/src/main/res/drawable-mdpi-v11/ic_stat_group.png b/android/app/src/main/res/drawable-mdpi-v11/ic_stat_group.png
new file mode 100644
index 0000000000..b7ecc47bd5
Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi-v11/ic_stat_group.png differ
diff --git a/android/app/src/main/res/drawable-mdpi/ic_stat_group.png b/android/app/src/main/res/drawable-mdpi/ic_stat_group.png
new file mode 100644
index 0000000000..6c6470055f
Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/ic_stat_group.png differ
diff --git a/android/app/src/main/res/drawable-xhdpi-v11/ic_stat_group.png b/android/app/src/main/res/drawable-xhdpi-v11/ic_stat_group.png
new file mode 100644
index 0000000000..c3888a0853
Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi-v11/ic_stat_group.png differ
diff --git a/android/app/src/main/res/drawable-xhdpi/ic_stat_group.png b/android/app/src/main/res/drawable-xhdpi/ic_stat_group.png
new file mode 100644
index 0000000000..7433a79931
Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/ic_stat_group.png differ
diff --git a/android/app/src/main/res/drawable-xxhdpi-v11/ic_stat_group.png b/android/app/src/main/res/drawable-xxhdpi-v11/ic_stat_group.png
new file mode 100644
index 0000000000..308d822861
Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi-v11/ic_stat_group.png differ
diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_stat_group.png b/android/app/src/main/res/drawable-xxhdpi/ic_stat_group.png
new file mode 100644
index 0000000000..6a875c9dc2
Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/ic_stat_group.png differ
diff --git a/android/app/src/main/res/drawable-xxxhdpi-v11/ic_stat_group.png b/android/app/src/main/res/drawable-xxxhdpi-v11/ic_stat_group.png
new file mode 100644
index 0000000000..650f62bd87
Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi-v11/ic_stat_group.png differ
diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_stat_group.png b/android/app/src/main/res/drawable-xxxhdpi/ic_stat_group.png
new file mode 100644
index 0000000000..d22c7f25e5
Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/ic_stat_group.png differ
diff --git a/android/app/src/main/res/mipmap-ldpi/smallicon.png b/android/app/src/main/res/mipmap-ldpi/smallicon.png
new file mode 100644
index 0000000000..d661c0e867
Binary files /dev/null and b/android/app/src/main/res/mipmap-ldpi/smallicon.png differ
diff --git a/android/build.gradle b/android/build.gradle
index d04621d0b7..0cd44daec8 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -19,6 +19,7 @@ buildscript {
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
+ classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlinVersion"
classpath 'com.google.gms:google-services:4.3.10'
}
gradle.projectsEvaluated {
diff --git a/index.js b/index.js
index 7483dc9881..f83ecf5392 100644
--- a/index.js
+++ b/index.js
@@ -17,6 +17,7 @@ import * as Sentry from "@sentry/react-native";
import Config from "react-native-config";
import VersionNumber from "react-native-version-number";
+import BackgroundRunnerService from "./services/BackgroundRunnerService";
import App, { routingInstrumentation } from "./src";
import { getEnabled } from "./src/components/HookSentry";
import logReport from "./src/log-report";
@@ -107,3 +108,7 @@ logReport.logReportInit();
const AppWithSentry = Sentry.wrap(App);
AppRegistry.registerComponent("ledgerlivemobile", () => AppWithSentry);
+AppRegistry.registerHeadlessTask(
+ "BackgroundRunnerService",
+ () => BackgroundRunnerService,
+);
diff --git a/package.json b/package.json
index 613279826f..5486761a86 100644
--- a/package.json
+++ b/package.json
@@ -70,14 +70,14 @@
"@formatjs/intl-locale": "^2.4.46",
"@formatjs/intl-numberformat": "^7.4.2",
"@formatjs/intl-pluralrules": "^4.3.2",
- "@ledgerhq/devices": "6.24.1",
+ "@ledgerhq/devices": "6.27.1",
"@ledgerhq/errors": "6.10.0",
- "@ledgerhq/hw-transport": "6.24.1",
+ "@ledgerhq/hw-transport": "6.27.1",
"@ledgerhq/hw-transport-http": "6.27.0",
- "@ledgerhq/live-common": "22.0.2",
+ "@ledgerhq/live-common": "https://github.com/LedgerHQ/ledger-live-common.git#release/22.1.x",
"@ledgerhq/logs": "6.10.0",
"@ledgerhq/native-ui": "^0.7.16",
- "@ledgerhq/react-native-hid": "6.24.1",
+ "@ledgerhq/react-native-hid": "6.27.1",
"@ledgerhq/react-native-hw-transport-ble": "6.25.1",
"@ledgerhq/react-native-passcode-auth": "^2.1.0",
"@polkadot/reactnative-identicon": "0.87.5",
@@ -189,6 +189,7 @@
"rn-snoopy": "^2.0.2",
"rxjs": "^6.6.6",
"rxjs-compat": "^6.6.6",
+ "semver": "^7.3.7",
"stream-browserify": "^3.0.0",
"string_decoder": "~1.3.0",
"styled-components": "^5.3.3",
@@ -210,6 +211,8 @@
"@types/react-native": "^0.65.21",
"@types/react-native-video": "^5.0.13",
"@types/react-test-renderer": "^17.0.1",
+ "@types/redux-actions": "^2.6.2",
+ "@types/semver": "^7.3.9",
"babel-jest": "^26.6.3",
"babel-plugin-module-resolver": "^4.1.0",
"detox": "^18.2.1",
diff --git a/services/BackgroundRunnerService.ts b/services/BackgroundRunnerService.ts
new file mode 100644
index 0000000000..11e2fedd4e
--- /dev/null
+++ b/services/BackgroundRunnerService.ts
@@ -0,0 +1,110 @@
+import { log } from "@ledgerhq/logs";
+import { withDevicePolling } from "@ledgerhq/live-common/lib/hw/deviceAccess";
+import getDeviceInfo from "@ledgerhq/live-common/lib/hw/getDeviceInfo";
+import { from } from "rxjs";
+import { timeout } from "rxjs/operators";
+import { NativeModules } from "react-native";
+import { hasFinalFirmware } from "@ledgerhq/live-common/lib/hw/hasFinalFirmware";
+import { FirmwareUpdateContext } from "@ledgerhq/live-common/lib/types/manager";
+import prepareFirmwareUpdate from "@ledgerhq/live-common/lib/hw/firmwareUpdate-prepare";
+import mainFirmwareUpdate from "@ledgerhq/live-common/lib/hw/firmwareUpdate-main";
+
+import { addBackgroundEvent } from "../src/actions/appstate";
+import { store } from "../src/context/LedgerStore";
+import { BackgroundEvent } from "../src/reducers/appstate";
+
+/**
+ * This task is not able to touch UI, but it will allow us to complete tasks
+ * even when the device goes to the background. We don't have access to hooks
+ * because we are not inside a component but we can read/write the store so we'll
+ * use that as the common-ground.
+ */
+const TAG = "headlessJS";
+const BackgroundRunnerService = async ({
+ deviceId,
+ firmwareSerializedJson,
+}: {
+ deviceId: string;
+ firmwareSerializedJson: string;
+}) => {
+ const emitEvent = (e: BackgroundEvent) =>
+ store.dispatch(addBackgroundEvent(e));
+ const latestFirmware = JSON.parse(firmwareSerializedJson) as
+ | FirmwareUpdateContext
+ | null
+ | undefined;
+
+ if (!latestFirmware) {
+ log(TAG, "no need to update");
+ return 0;
+ }
+
+ const onError = (error: any) => {
+ emitEvent({ type: "error", error });
+ NativeModules.BackgroundRunner.stop();
+ };
+
+ const onFirmwareUpdated = () => {
+ emitEvent({ type: "firmwareUpdated" });
+ NativeModules.BackgroundRunner.stop();
+ };
+
+ const waitForOnlineDevice = (maxWait: number) => {
+ return withDevicePolling(deviceId)(
+ transport => from(getDeviceInfo(transport)),
+ () => true,
+ ).pipe(timeout(maxWait));
+ };
+
+ prepareFirmwareUpdate(deviceId, latestFirmware).subscribe({
+ next: ({ progress, displayedOnDevice }) => {
+ if (displayedOnDevice) {
+ emitEvent({ type: "confirmUpdate" });
+ } else {
+ emitEvent({ type: "downloadingUpdate", progress });
+ }
+ },
+ error: onError,
+ complete: () => {
+ // Depending on the update path, we might need to run the firmwareMain or simply wait until
+ // the device is online.
+ if (
+ latestFirmware.shouldFlashMCU ||
+ hasFinalFirmware(latestFirmware.final)
+ ) {
+ emitEvent({ type: "flashingMcu" });
+ mainFirmwareUpdate(deviceId, latestFirmware).subscribe({
+ next: ({ progress, installing }) => {
+ if (progress === 1 && installing === "flash-mcu") {
+ // this is the point where we lose communication with the device until the update
+ // is finished and the user has entered their PIN. Therefore the message here should
+ // be generic about waiting for the firmware to finish and then entering the pin
+ emitEvent({ type: "confirmPin" });
+ } else {
+ emitEvent({ type: "flashingMcu", progress, installing });
+ }
+ },
+ error: onError,
+ complete: () => {
+ emitEvent({ type: "confirmPin" });
+ waitForOnlineDevice(5 * 60 * 1000).subscribe({
+ error: onError,
+ complete: onFirmwareUpdated,
+ });
+ },
+ });
+ } else {
+ emitEvent({ type: "confirmPin" });
+ // We're waiting forever condition that make getDeviceInfo work
+ waitForOnlineDevice(5 * 60 * 1000).subscribe({
+ error: onError,
+ complete: onFirmwareUpdated,
+ });
+ }
+ },
+ });
+
+ return null;
+};
+
+export default BackgroundRunnerService;
diff --git a/src/actions/appstate.js b/src/actions/appstate.js
index 5f9d808554..d70f22e02a 100644
--- a/src/actions/appstate.js
+++ b/src/actions/appstate.js
@@ -21,3 +21,21 @@ export const setHasConnectedDevice = (hasConnectedDevice: boolean) => (
export const setModalLock = (modalLock: boolean) => (dispatch: *) =>
dispatch({ type: "SET_MODAL_LOCK", modalLock });
+
+export const addBackgroundEvent = (event: *) => (dispatch: *) =>
+ dispatch({
+ type: "QUEUE_BACKGROUND_EVENT",
+ event,
+ });
+
+export const dequeueBackgroundEvent = () => (dispatch: *) =>
+ dispatch({
+ type: "DEQUEUE_BACKGROUND_EVENT",
+ });
+
+export const clearBackgroundEvents = () => (dispatch: *) =>
+ dispatch({
+ type: "CLEAR_BACKGROUND_EVENTS",
+ });
+
+// TODO: migrate to TS
diff --git a/src/analytics/Track.tsx b/src/analytics/Track.tsx
new file mode 100644
index 0000000000..bd448c53a7
--- /dev/null
+++ b/src/analytics/Track.tsx
@@ -0,0 +1,40 @@
+import { PureComponent } from "react";
+import { track } from "./segment";
+
+class Track extends PureComponent<{
+ onMount?: boolean;
+ onUnmount?: boolean;
+ onUpdate?: boolean;
+ event: string;
+ mandatory?: boolean;
+}> {
+ componentDidMount() {
+ if (this.props.onMount) this.track();
+ }
+
+ componentDidUpdate() {
+ if (this.props.onUpdate) this.track();
+ }
+
+ componentWillUnmount() {
+ if (this.props.onUnmount) this.track();
+ }
+
+ track = () => {
+ const {
+ event,
+ onMount,
+ onUnmount,
+ onUpdate,
+ mandatory,
+ ...properties
+ } = this.props;
+ track(event, properties, mandatory ?? null);
+ };
+
+ render() {
+ return null;
+ }
+}
+
+export default Track;
diff --git a/src/components/BottomModal.tsx b/src/components/BottomModal.tsx
index 8259ea2fc9..51d9cf6bcf 100644
--- a/src/components/BottomModal.tsx
+++ b/src/components/BottomModal.tsx
@@ -14,6 +14,7 @@ export type Props = {
children?: React.ReactNode;
style?: StyleProp;
preventBackdropClick?: boolean;
+ noCloseButton?: boolean;
containerStyle?: StyleProp;
};
@@ -25,6 +26,7 @@ const BottomModal = ({
preventBackdropClick,
onModalHide,
containerStyle,
+ noCloseButton,
...rest
}: Props) => {
const [open, setIsOpen] = useState(false);
@@ -59,7 +61,7 @@ const BottomModal = ({
preventBackdropClick={modalLock || preventBackdropClick}
isOpen={open}
onClose={handleClose}
- noCloseButton={modalLock}
+ noCloseButton={modalLock || noCloseButton}
modalStyle={style}
containerStyle={containerStyle}
{...rest}
diff --git a/src/components/DeviceAction/index.js b/src/components/DeviceAction/index.js
index 11d573d3d7..66c7be0212 100644
--- a/src/components/DeviceAction/index.js
+++ b/src/components/DeviceAction/index.js
@@ -6,9 +6,10 @@ import type {
Device,
} from "@ledgerhq/live-common/lib/hw/actions/types";
import { DeviceNotOnboarded } from "@ledgerhq/live-common/lib/errors";
-import { TransportStatusError } from "@ledgerhq/errors";
+import { TransportStatusError, DisconnectedDevice } from "@ledgerhq/errors";
import { useTranslation } from "react-i18next";
import { useNavigation, useTheme } from "@react-navigation/native";
+import { track } from "../../analytics";
import { setLastSeenDeviceInfo } from "../../actions/settings";
import ValidateOnDevice from "../ValidateOnDevice";
import ValidateMessageOnDevice from "../ValidateMessageOnDevice";
@@ -26,6 +27,7 @@ import {
renderConfirmSwap,
renderConfirmSell,
LoadingAppInstall,
+ AutoRepair,
} from "./rendering";
import PreventNativeBack from "../PreventNativeBack";
import SkipLock from "../behaviour/SkipLock";
@@ -72,6 +74,9 @@ export default function DeviceAction({
requiresAppInstallation,
inWrongDeviceForAccount,
onRetry,
+ repairModalOpened,
+ onAutoRepair,
+ closeRepairModal,
deviceSignatureRequested,
deviceStreamingProgress,
displayUpgradeWarning,
@@ -111,6 +116,19 @@ export default function DeviceAction({
});
}
+ if (repairModalOpened && repairModalOpened.auto) {
+ return (
+
+ );
+ }
+
if (requestQuitApp) {
return renderRequestQuitApp({
t,
@@ -205,6 +223,7 @@ export default function DeviceAction({
}
if (!isLoading && error) {
+ track("DeviceActionError", error);
onError && onError(error);
// NB Until we find a better way, remap the error if it's 6d06 and we haven't fallen
@@ -224,6 +243,16 @@ export default function DeviceAction({
});
}
+ if (error.message === "Invalid channel") {
+ return renderError({
+ t,
+ navigation,
+ error: new DisconnectedDevice(),
+ colors,
+ theme,
+ });
+ }
+
return renderError({
t,
navigation,
@@ -252,7 +281,7 @@ export default function DeviceAction({
}
if (deviceInfo && deviceInfo.isBootloader) {
- return renderBootloaderStep({ t, colors, theme });
+ return renderBootloaderStep({ onAutoRepair, t });
}
if (request && device && deviceSignatureRequested) {
diff --git a/src/components/DeviceAction/rendering.tsx b/src/components/DeviceAction/rendering.tsx
index 8cbd1ae949..04a718112e 100644
--- a/src/components/DeviceAction/rendering.tsx
+++ b/src/components/DeviceAction/rendering.tsx
@@ -1,10 +1,11 @@
-import React, { useEffect } from "react";
+import React, { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import styled from "styled-components/native";
import { WrongDeviceForAccount, UnexpectedBootloader } from "@ledgerhq/errors";
import { TokenCurrency } from "@ledgerhq/live-common/lib/types";
import { Device } from "@ledgerhq/live-common/lib/hw/actions/types";
import { AppRequest } from "@ledgerhq/live-common/lib/hw/actions/app";
+import firmwareUpdateRepair from "@ledgerhq/live-common/lib/hw/firmwareUpdate-repair";
import {
InfiniteLoader,
Text,
@@ -18,6 +19,7 @@ import { urls } from "../../config/urls";
import Alert from "../Alert";
import { lighten } from "../../colors";
import Button from "../Button";
+import FirmwareProgress from "../FirmwareProgress";
import { NavigatorName, ScreenName } from "../../const";
import Animation from "../Animation";
import getDeviceAnimation from "./getDeviceAnimation";
@@ -553,11 +555,76 @@ export function renderWarningOutdated({
);
}
-export function renderBootloaderStep({ t, colors, theme }: RawProps) {
- return renderError({
- t,
- error: new UnexpectedBootloader(),
- colors,
- theme,
- });
-}
+export const renderBootloaderStep = ({
+ onAutoRepair,
+ t,
+}: RawProps & { onAutoRepair: () => void }) => (
+
+ {t("DeviceAction.deviceInBootloader.title")}
+
+ {t("DeviceAction.deviceInBootloader.description")}
+
+
+
+);
+
+export const AutoRepair = ({
+ onDone,
+ t,
+ device,
+ navigation,
+ colors,
+ theme,
+}: RawProps & {
+ onDone: () => void;
+ device: Device;
+ navigation: StackNavigationProp;
+}) => {
+ const [error, setError] = useState(null);
+ const [progress, setProgress] = useState(0);
+
+ useEffect(() => {
+ const sub = firmwareUpdateRepair(device.deviceId, undefined).subscribe({
+ next: ({ progress }) => {
+ setProgress(progress);
+ },
+ error: err => {
+ setError(err);
+ },
+ complete: () => {
+ onDone();
+ navigation.replace(ScreenName.Manager, {});
+ // we re-navigate to the manager to reset the selected device for the action
+ // if we don't do that, we get an "Invalid Channel" error once the device is back online
+ // since the manager still thinks it's connected to a bootloader device and not a normal one
+ },
+ });
+
+ return () => sub.unsubscribe();
+ }, [onDone, setProgress, device, navigation]);
+
+ if (error) {
+ return renderError({
+ t,
+ error,
+ colors,
+ theme,
+ });
+ }
+
+ return (
+
+ {t("FirmwareUpdate.preparingDevice")}
+
+ {t("FirmwareUpdate.pleaseWaitUpdate")}
+
+ );
+};
diff --git a/src/components/FirmwareProgress.tsx b/src/components/FirmwareProgress.tsx
new file mode 100644
index 0000000000..ef651364c4
--- /dev/null
+++ b/src/components/FirmwareProgress.tsx
@@ -0,0 +1,24 @@
+import React, { memo } from "react";
+import { ProgressLoader, Text } from "@ledgerhq/native-ui";
+
+type Props = {
+ progress?: number,
+};
+
+function FirmwareProgress({ progress }: Props) {
+ return (
+
+
+ {progress && progress < 1 ? `${Math.round(progress * 100)}%`: ""}
+
+
+ );
+}
+
+
+export default memo(FirmwareProgress);
diff --git a/src/components/FirmwareUpdate/ConfirmPinStep.tsx b/src/components/FirmwareUpdate/ConfirmPinStep.tsx
new file mode 100644
index 0000000000..2adb52bc72
--- /dev/null
+++ b/src/components/FirmwareUpdate/ConfirmPinStep.tsx
@@ -0,0 +1,63 @@
+import { Flex, Text, Log, NumberedList } from "@ledgerhq/native-ui";
+import React from "react";
+import Animation from "../Animation";
+import getDeviceAnimation from "../DeviceAction/getDeviceAnimation";
+import { useTranslation } from "react-i18next";
+import { Device } from "@ledgerhq/live-common/lib/hw/actions/types";
+import { useTheme } from "styled-components/native";
+import Track from "../../analytics/Track";
+
+type Props = {
+ device: Device;
+};
+
+const ConfirmPinStep = ({ device }: Props) => {
+ const { t } = useTranslation();
+ const { theme } = useTheme();
+
+ return (
+
+
+
+
+
+ {device.deviceName}
+
+
+
+
+ {t("FirmwareUpdate.finishUpdate", { deviceName: device.deviceName })}
+
+
+
+
+
+
+ );
+};
+
+export default ConfirmPinStep;
diff --git a/src/components/FirmwareUpdate/ConfirmRecoveryStep.tsx b/src/components/FirmwareUpdate/ConfirmRecoveryStep.tsx
new file mode 100644
index 0000000000..f29425a7dd
--- /dev/null
+++ b/src/components/FirmwareUpdate/ConfirmRecoveryStep.tsx
@@ -0,0 +1,108 @@
+import {
+ Flex,
+ Text,
+ Link,
+ Icons,
+ Button,
+ Checkbox,
+ Alert,
+} from "@ledgerhq/native-ui";
+import React, { useCallback, useState } from "react";
+import { useTranslation } from "react-i18next";
+import { Device } from "@ledgerhq/live-common/lib/hw/actions/types";
+import { Linking, ScrollView } from "react-native";
+import { track } from "../../analytics";
+import Track from "../../analytics/Track";
+import { urls } from "../../config/urls";
+import SafeMarkdown from "../SafeMarkdown";
+
+type Props = {
+ firmwareVersion: string;
+ firmwareNotes?: string | null;
+ onContinue: () => void;
+ device: Device;
+};
+
+const ConfirmRecoveryStep = ({
+ firmwareVersion,
+ firmwareNotes,
+ onContinue,
+ device,
+}: Props) => {
+ const { t } = useTranslation();
+ const [
+ confirmRecoveryPhraseBackup,
+ setConfirmRecoveryPhraseBackup,
+ ] = useState(false);
+
+ const toggleConfirmRecoveryPhraseBackup = useCallback(() => {
+ track("FirmwareUpdateSeedDisclaimerChecked");
+ setConfirmRecoveryPhraseBackup(!confirmRecoveryPhraseBackup);
+ }, [confirmRecoveryPhraseBackup]);
+
+ const openRecoveryPhraseInfo = React.useCallback(async () => {
+ // Checking if the link is supported for links with custom URL scheme.
+ const supported = await Linking.canOpenURL(urls.recoveryPhraseInfo);
+ if (!supported) return;
+
+ // Opening the link with some app, if the URL scheme is "http" the web link should be opened
+ // by some browser in the mobile
+ await Linking.openURL(urls.recoveryPhraseInfo);
+ }, [urls.recoveryPhraseInfo]);
+
+ return (
+
+
+
+
+
+ {t("FirmwareUpdateReleaseNotes.introTitle", {
+ version: firmwareVersion,
+ deviceName: device.deviceName?.replace(/\u00a0/g, ' '),
+ })}
+
+
+
+
+ {t(
+ "onboarding.stepSetupDevice.recoveryPhraseSetup.infoModal.link",
+ )}
+
+
+
+
+
+
+
+ {/** TODO: replace by divider component when we have one */}
+
+
+
+
+
+ );
+};
+
+export default ConfirmRecoveryStep;
diff --git a/src/components/FirmwareUpdate/ConfirmUpdateStep.tsx b/src/components/FirmwareUpdate/ConfirmUpdateStep.tsx
new file mode 100644
index 0000000000..05c7835e06
--- /dev/null
+++ b/src/components/FirmwareUpdate/ConfirmUpdateStep.tsx
@@ -0,0 +1,96 @@
+import { Flex, Text, Log } from "@ledgerhq/native-ui";
+import React from "react";
+import Animation from "../Animation";
+import getDeviceAnimation from "../DeviceAction/getDeviceAnimation";
+import manager from "@ledgerhq/live-common/lib/manager";
+import { useTranslation } from "react-i18next";
+import { Device } from "@ledgerhq/live-common/lib/hw/actions/types";
+import {
+ DeviceInfo,
+ FirmwareUpdateContext,
+} from "@ledgerhq/live-common/lib/types/manager";
+import { useTheme } from "styled-components/native";
+import Track from "../../analytics/Track";
+
+type Props = {
+ device: Device;
+ deviceInfo: DeviceInfo;
+ latestFirmware?: FirmwareUpdateContext | null;
+};
+
+const ConfirmUpdateStep = ({ device, deviceInfo, latestFirmware }: Props) => {
+ const { t } = useTranslation();
+ const { theme } = useTheme();
+
+ return (
+
+
+
+
+
+ {device.deviceName}
+
+
+
+ {t("FirmwareUpdate.pleaseConfirmUpdate")}
+
+ {latestFirmware?.osu?.hash ? (
+
+ {t("FirmwareUpdate.identifierTitle")}
+
+ {manager
+ .formatHashName(
+ latestFirmware.osu.hash,
+ device.modelId,
+ deviceInfo,
+ )
+ .map((hash, i) => (
+ {hash}
+ ))}
+
+
+ ) : null}
+
+
+ {t("FirmwareUpdate.currentVersionNumber")}
+
+ {deviceInfo.version}
+
+
+
+ {t("FirmwareUpdate.newVersionNumber")}
+
+ {latestFirmware?.final?.name}
+
+
+ );
+};
+
+export default ConfirmUpdateStep;
diff --git a/src/components/FirmwareUpdate/DownloadingUpdateStep.tsx b/src/components/FirmwareUpdate/DownloadingUpdateStep.tsx
new file mode 100644
index 0000000000..fb034f4301
--- /dev/null
+++ b/src/components/FirmwareUpdate/DownloadingUpdateStep.tsx
@@ -0,0 +1,29 @@
+import { Flex, Text } from "@ledgerhq/native-ui";
+import React from "react";
+import { useTranslation } from "react-i18next";
+import FirmwareProgress from "../FirmwareProgress";
+import Track from "../../analytics/Track";
+
+type Props = {
+ progress?: number;
+};
+const DownloadingUpdateStep = ({ progress }: Props) => {
+ const { t } = useTranslation();
+
+ return (
+
+
+
+
+ {progress
+ ? t("FirmwareUpdate.steps.firmware")
+ : t("FirmwareUpdate.steps.preparing")}
+
+
+ {t("FirmwareUpdate.pleaseWaitDownload")}
+
+
+ );
+};
+
+export default DownloadingUpdateStep;
diff --git a/src/components/FirmwareUpdate/FirmwareUpdatedStep.tsx b/src/components/FirmwareUpdate/FirmwareUpdatedStep.tsx
new file mode 100644
index 0000000000..34c4b33366
--- /dev/null
+++ b/src/components/FirmwareUpdate/FirmwareUpdatedStep.tsx
@@ -0,0 +1,27 @@
+import { Flex, Text, Icons, Log, Button } from "@ledgerhq/native-ui";
+import React from "react";
+import { useTranslation } from "react-i18next";
+import Track from "../../analytics/Track";
+
+type Props = {
+ onReinstallApps: () => void;
+};
+const FirmwareUpdatedStep = ({ onReinstallApps }: Props) => {
+ const { t } = useTranslation();
+
+ return (
+
+
+
+
+ {t("FirmwareUpdate.success")}
+
+ {t("FirmwareUpdate.pleaseReinstallApps")}
+
+
+ );
+};
+
+export default FirmwareUpdatedStep;
diff --git a/src/components/FirmwareUpdate/FlashMcuStep.tsx b/src/components/FirmwareUpdate/FlashMcuStep.tsx
new file mode 100644
index 0000000000..68aae1c8e0
--- /dev/null
+++ b/src/components/FirmwareUpdate/FlashMcuStep.tsx
@@ -0,0 +1,30 @@
+import { Flex, Text } from "@ledgerhq/native-ui";
+import React from "react";
+import { useTranslation } from "react-i18next";
+import Track from "../../analytics/Track";
+import FirmwareProgress from "../FirmwareProgress";
+
+type Props = {
+ progress?: number;
+ installing?: string | null;
+};
+const FlashMcuStep = ({ progress, installing }: Props) => {
+ const { t } = useTranslation();
+
+ return (
+
+
+
+
+ {progress && installing
+ ? t(`FirmwareUpdate.steps.${installing}`)
+ : t("FirmwareUpdate.steps.preparing")}
+
+
+ {t("FirmwareUpdate.pleaseWaitUpdate")}
+
+
+ );
+};
+
+export default FlashMcuStep;
diff --git a/src/components/FirmwareUpdate/index.tsx b/src/components/FirmwareUpdate/index.tsx
new file mode 100644
index 0000000000..0c2594b55a
--- /dev/null
+++ b/src/components/FirmwareUpdate/index.tsx
@@ -0,0 +1,265 @@
+import React, { useEffect, useCallback, useReducer } from "react";
+import { useTranslation } from "react-i18next";
+import { NativeModules } from "react-native";
+import { useSelector, useDispatch } from "react-redux";
+import { Device } from "@ledgerhq/live-common/lib/hw/actions/types";
+import { Button, Icons } from "@ledgerhq/native-ui";
+import {
+ BackgroundEvent,
+ nextBackgroundEventSelector,
+} from "../../reducers/appstate";
+import {
+ clearBackgroundEvents,
+ dequeueBackgroundEvent,
+} from "../../actions/appstate";
+import BottomModal from "../BottomModal";
+import GenericErrorView from "../GenericErrorView";
+import { DeviceInfo } from "@ledgerhq/live-common/lib/types/manager";
+import useLatestFirmware from "../../hooks/useLatestFirmware";
+import ConfirmRecoveryStep from "./ConfirmRecoveryStep";
+import FlashMcuStep from "./FlashMcuStep";
+import FirmwareUpdatedStep from "./FirmwareUpdatedStep";
+import ConfirmPinStep from "./ConfirmPinStep";
+import ConfirmUpdateStep from "./ConfirmUpdateStep";
+import DownloadingUpdateStep from "./DownloadingUpdateStep";
+import { track } from "../../analytics";
+import { BluetoothNotSupportedError } from "@ledgerhq/live-common/lib/errors";
+import {
+ DisconnectedDevice,
+ DisconnectedDeviceDuringOperation,
+ WebsocketConnectionError,
+} from "@ledgerhq/errors";
+
+type Props = {
+ device: Device;
+ deviceInfo: DeviceInfo;
+ isOpen: boolean;
+ onClose: (restoreApps?: boolean) => void;
+ hasAppsToRestore: boolean;
+};
+
+type FwUpdateStep =
+ | "confirmRecoveryBackup"
+ | "downloadingUpdate"
+ | "error"
+ | "flashingMcu"
+ | "confirmPin"
+ | "confirmUpdate"
+ | "firmwareUpdated";
+type FwUpdateState = {
+ step: FwUpdateStep;
+ progress?: number;
+ error?: Error;
+ installing?: string | null;
+};
+
+export default function FirmwareUpdate({
+ device,
+ deviceInfo,
+ onClose,
+ isOpen,
+ hasAppsToRestore,
+}: Props) {
+ const nextBackgroundEvent = useSelector(nextBackgroundEventSelector);
+ const dispatch = useDispatch();
+ const latestFirmware = useLatestFirmware(deviceInfo);
+
+ const { t } = useTranslation();
+
+ // reducer for the firmware update state machine
+ const fwUpdateStateReducer = useCallback(
+ (
+ state: FwUpdateState,
+ event: BackgroundEvent | { type: "reset"; wired: boolean },
+ ): FwUpdateState => {
+ switch (event.type) {
+ case "confirmPin":
+ return { step: "confirmPin" };
+ case "downloadingUpdate":
+ if (event.progress) {
+ NativeModules.BackgroundRunner.update(
+ Math.round(event.progress * 100),
+ t("FirmwareUpdate.Notifications.installing", {
+ progress: Math.round(event.progress * 100),
+ }),
+ );
+ }
+ return { step: "downloadingUpdate", progress: event.progress };
+ case "confirmUpdate":
+ NativeModules.BackgroundRunner.requireUserAction(
+ t("FirmwareUpdate.Notifications.confirmOnDevice"),
+ );
+ return { step: "confirmUpdate" };
+ case "flashingMcu":
+ return {
+ step: "flashingMcu",
+ progress: event.progress,
+ installing: event.installing,
+ };
+ case "firmwareUpdated":
+ return { step: "firmwareUpdated" };
+ case "error":
+ if (event.error.message === "Invalid channel") {
+ // this error comes from an uncaught exception on @ledgerhq/react-native-hid
+ // in this specific context, it almost always means the device was disconnected
+ // TODO: we should probably move this mapping to @ledgerhq/react-native-hid itself
+ // if this does mean a disconnected device in all contexts
+ event.error = new (DisconnectedDevice as ErrorConstructor)();
+ }
+ return { step: "error", error: event.error };
+ case "reset":
+ return {
+ step: event.wired ? "confirmRecoveryBackup" : "error",
+ progress: undefined,
+ error: event.wired
+ ? undefined
+ : new (BluetoothNotSupportedError as ErrorConstructor)(),
+ installing: undefined,
+ };
+ default:
+ return { ...state };
+ }
+ },
+ [t],
+ );
+
+ const [state, dispatchEvent] = useReducer(fwUpdateStateReducer, {
+ step: device.wired ? "confirmRecoveryBackup" : "error",
+ progress: undefined,
+ error: device.wired
+ ? undefined
+ : new (BluetoothNotSupportedError as ErrorConstructor)(),
+ installing: undefined,
+ });
+
+ const { step, progress, error, installing } = state;
+
+ const onReset = useCallback(() => {
+ dispatchEvent({ type: "reset", wired: device.wired });
+ dispatch(clearBackgroundEvents());
+ NativeModules.BackgroundRunner.stop();
+ }, [dispatch]);
+
+ // only allow closing of the modal when the update is not in an intermediate step
+ const canClose =
+ step === "confirmRecoveryBackup" ||
+ step === "firmwareUpdated" ||
+ step === "error" ||
+ step === "confirmPin";
+
+ const onTryClose = useCallback(
+ (restoreApps: boolean) => {
+ if (canClose) {
+ onClose(restoreApps);
+ }
+ },
+ [canClose],
+ );
+
+ const onCloseAndReinstall = useCallback(() => onTryClose(true), [onTryClose]);
+ const onCloseSilently = useCallback(() => onTryClose(false), [onTryClose]);
+
+ useEffect(() => {
+ // reset the state whenever we re-open the modal
+ if (isOpen) {
+ onReset();
+ }
+ }, [isOpen, onReset]);
+
+ useEffect(() => {
+ if (!nextBackgroundEvent) return;
+ dispatchEvent(nextBackgroundEvent);
+ dispatch(dequeueBackgroundEvent());
+ }, [nextBackgroundEvent, dispatch, dispatchEvent]);
+
+ useEffect(() => {
+ if (step === "error") {
+ track("FirmwareUpdateError", error ?? null);
+ }
+ }, [step]);
+
+ const launchUpdate = useCallback(() => {
+ if (latestFirmware) {
+ NativeModules.BackgroundRunner.start(
+ device.deviceId,
+ JSON.stringify(latestFirmware),
+ t("FirmwareUpdate.Notifications.preparingUpdate"),
+ );
+ dispatchEvent({ type: "downloadingUpdate", progress: 0 });
+ }
+ }, [latestFirmware]);
+
+ const firmwareVersion = latestFirmware?.final?.name ?? "";
+
+ return (
+
+ {step === "confirmRecoveryBackup" && (
+
+ )}
+ {step === "flashingMcu" && (
+
+ )}
+ {step === "firmwareUpdated" && (
+
+ )}
+ {step === "error" && (
+ <>
+
+ {!(
+ error instanceof BluetoothNotSupportedError ||
+ error instanceof WebsocketConnectionError
+ ) &&
+ hasAppsToRestore && (
+
+ )}
+ >
+ )}
+ {step === "confirmPin" && }
+ {step === "confirmUpdate" && (
+
+ )}
+ {step === "downloadingUpdate" && (
+
+ )}
+
+ );
+}
diff --git a/src/components/FirmwareUpdateBanner.tsx b/src/components/FirmwareUpdateBanner.tsx
index 4c995914e2..1e38dfc68f 100644
--- a/src/components/FirmwareUpdateBanner.tsx
+++ b/src/components/FirmwareUpdateBanner.tsx
@@ -1,59 +1,58 @@
-import React, { useState, useEffect, useContext } from "react";
-
-import { StyleSheet, TouchableOpacity } from "react-native";
-import manager from "@ledgerhq/live-common/lib/manager";
-import * as Animatable from "react-native-animatable";
-import { useTheme } from "@react-navigation/native";
-import {
- DeviceModelInfo,
- FirmwareUpdateContext,
-} from "@ledgerhq/live-common/lib/types/manager";
+import React, { useState, useCallback } from "react";
+import { Platform } from "react-native";
+import { useNavigation, useRoute } from "@react-navigation/native";
+import { DeviceModelInfo } from "@ledgerhq/live-common/lib/types/manager";
import { useTranslation } from "react-i18next";
import { useSelector } from "react-redux";
-import { BottomDrawer, Notification } from "@ledgerhq/native-ui";
-import {
- DownloadMedium,
- NanoFirmwareUpdateMedium,
-} from "@ledgerhq/native-ui/assets/icons";
-import ButtonUseTouchable from "../context/ButtonUseTouchable";
+import { ScreenName, NavigatorName } from "../const";
+import { Alert, BottomDrawer, Text } from "@ledgerhq/native-ui";
+import { DownloadMedium } from "@ledgerhq/native-ui/assets/icons";
import {
lastSeenDeviceSelector,
hasCompletedOnboardingSelector,
+ lastConnectedDeviceSelector,
} from "../reducers/settings";
import { hasConnectedDeviceSelector } from "../reducers/appstate";
-import { BaseButton as Button } from "./Button";
+import Button from "./Button";
+import { useFeature } from "@ledgerhq/live-common/lib/featureFlags";
+import useLatestFirmware from "../hooks/useLatestFirmware";
+import { StackNavigationProp } from "@react-navigation/stack";
+import { isFirmwareUpdateVersionSupported } from "../logic/firmwareUpdate";
const FirmwareUpdateBanner = () => {
const lastSeenDevice: DeviceModelInfo | null = useSelector(
lastSeenDeviceSelector,
);
+ const lastConnectedDevice = useSelector(lastConnectedDeviceSelector);
const hasConnectedDevice = useSelector(hasConnectedDeviceSelector);
const hasCompletedOnboarding: boolean = useSelector(
hasCompletedOnboardingSelector,
);
+
const [showDrawer, setShowDrawer] = useState(false);
- const [showBanner, setShowBanner] = useState(false);
- const [version, setVersion] = useState("");
- const { colors } = useTheme();
const { t } = useTranslation();
- const useTouchable = useContext(ButtonUseTouchable);
- useEffect(() => {
- async function getLatestFirmwareForDevice() {
- const fw:
- | FirmwareUpdateContext
- | null
- | undefined = await manager.getLatestFirmwareForDevice(
- lastSeenDevice?.deviceInfo,
- );
+ const route = useRoute();
+ const navigation = useNavigation>();
- setShowBanner(Boolean(fw));
- setVersion(fw?.final?.name ?? "");
+ const onExperimentalFirmwareUpdate = useCallback(() => {
+ // if we're already in the manager page, only update the params
+ if (route.name === ScreenName.ManagerMain) {
+ navigation.setParams({ firmwareUpdate: true });
+ } else {
+ navigation.navigate(NavigatorName.Manager, {
+ screen: ScreenName.Manager,
+ params: { firmwareUpdate: true },
+ });
}
- getLatestFirmwareForDevice();
- }, [lastSeenDevice, setShowBanner, setVersion]);
+ setShowDrawer(false);
+ }, [navigation]);
+
+ const latestFirmware = useLatestFirmware(lastSeenDevice?.deviceInfo);
+ const showBanner = Boolean(latestFirmware);
+ const version = latestFirmware?.final?.name ?? "";
const onPress = () => {
setShowDrawer(true);
@@ -61,26 +60,40 @@ const FirmwareUpdateBanner = () => {
const onCloseDrawer = () => {
setShowDrawer(false);
};
- const onDismissBanner = () => {
- setShowBanner(false);
- };
- return showBanner && hasConnectedDevice && hasCompletedOnboarding ? (
+ const usbFwUpdateFeatureFlag = { enabled: true }; // TODO: do NOT merge this
+ const isUsbFwVersionUpdateSupported =
+ lastSeenDevice &&
+ isFirmwareUpdateVersionSupported(
+ lastSeenDevice.deviceInfo,
+ lastSeenDevice.modelId,
+ );
+ const usbFwUpdateActivated =
+ usbFwUpdateFeatureFlag?.enabled &&
+ Platform.OS === "android" &&
+ lastConnectedDevice?.wired &&
+ isUsbFwVersionUpdateSupported;
+
+ return showBanner && hasCompletedOnboarding && hasConnectedDevice ? (
<>
-
-
-
-
-
+
+
+ {t("FirmwareUpdate.newVersion", {
+ version,
+ deviceName: lastConnectedDevice?.deviceName,
+ })}
+
+
+
{
@@ -103,19 +113,4 @@ const FirmwareUpdateBanner = () => {
) : null;
};
-const styles = {
- banner: StyleSheet.create({
- root: {
- position: "absolute",
- width: "100%",
- top: 30,
- left: 0,
- zIndex: 100,
- padding: 16,
- },
- }),
-};
-// remove this while we dont have a proper way to handle the banner
-export default function FirmwareUpdateBannerWrapper() {
- return null;
-}
+export default FirmwareUpdateBanner;
diff --git a/src/components/GenericErrorView.tsx b/src/components/GenericErrorView.tsx
index 223667068b..62fd69e32c 100644
--- a/src/components/GenericErrorView.tsx
+++ b/src/components/GenericErrorView.tsx
@@ -8,6 +8,8 @@ import { BluetoothRequired } from "@ledgerhq/errors";
import useExportLogs from "./useExportLogs";
import TranslatedError from "./TranslatedError";
import SupportLinkError from "./SupportLinkError";
+import { IconOrElementType } from "@ledgerhq/native-ui/components/Icon/type";
+
type Props = {
error: Error;
@@ -18,6 +20,8 @@ type Props = {
withDescription?: boolean;
withIcon?: boolean;
hasExportLogButton?: boolean;
+ Icon?: IconOrElementType;
+ iconColor?: string;
children?: React.ReactNode;
};
@@ -35,6 +39,8 @@ const GenericErrorView = ({
withIcon = true,
hasExportLogButton = true,
children,
+ Icon = CloseMedium,
+ iconColor = "error.c100"
}: Props) => {
useEffect(() => {
if (error instanceof BluetoothRequired) {
@@ -56,10 +62,10 @@ const GenericErrorView = ({
{withIcon ? (
) : null}
diff --git a/src/components/RootNavigator/BaseNavigator.tsx b/src/components/RootNavigator/BaseNavigator.tsx
index 1269c1a076..ce193e4f09 100644
--- a/src/components/RootNavigator/BaseNavigator.tsx
+++ b/src/components/RootNavigator/BaseNavigator.tsx
@@ -77,7 +77,6 @@ import SwapOperationDetails from "../../screens/Swap/OperationDetails";
import BuyDeviceScreen from "../../screens/BuyDeviceScreen";
import { readOnlyModeEnabledSelector } from "../../reducers/settings";
import Learn from "../../screens/Learn";
-import ManagerMain from "../../screens/Manager/Manager";
export default function BaseNavigator() {
const { t } = useTranslation();
@@ -556,11 +555,6 @@ export default function BaseNavigator() {
component={AccountsNavigator}
options={{ headerShown: false }}
/>
-
{Object.keys(families).map(name => {
const { component, options } = families[name];
return (
diff --git a/src/components/RootNavigator/ManagerNavigator.tsx b/src/components/RootNavigator/ManagerNavigator.tsx
index f83775a7bc..f6a1607847 100644
--- a/src/components/RootNavigator/ManagerNavigator.tsx
+++ b/src/components/RootNavigator/ManagerNavigator.tsx
@@ -15,6 +15,7 @@ import styles from "../../navigation/styles";
import ReadOnlyTab from "../ReadOnlyTab";
import NanoXIcon from "../../icons/TabNanoX";
import { useIsNavLocked } from "./CustomBlockRouterNavigator";
+import ManagerMain from "../../screens/Manager/Manager";
const BadgeContainer = styled(Flex).attrs({
position: "absolute",
@@ -76,6 +77,11 @@ export default function ManagerNavigator() {
headerRight: null,
gestureEnabled: false,
}}
+ />
+
);
diff --git a/src/components/SelectDevice/index.tsx b/src/components/SelectDevice/index.tsx
index 062a5b9d7b..55dc032de6 100644
--- a/src/components/SelectDevice/index.tsx
+++ b/src/components/SelectDevice/index.tsx
@@ -20,6 +20,7 @@ import USBEmpty from "./USBEmpty";
import LText from "../LText";
import Animation from "../Animation";
import { track } from "../../analytics";
+import { setLastConnectedDevice } from "../../actions/settings";
import PairLight from "../../screens/Onboarding/assets/nanoX/pairDevice/light.json";
import PairDark from "../../screens/Onboarding/assets/nanoX/pairDevice/dark.json";
@@ -60,6 +61,7 @@ export default function SelectDevice({
});
// Nb consider a device selection enough to show the fw update banner in portfolio
dispatch(setHasConnectedDevice(true));
+ dispatch(setLastConnectedDevice(deviceInfo));
onSelect(deviceInfo);
} else {
NativeModules.BluetoothHelperModule.prompt()
@@ -152,7 +154,7 @@ export default function SelectDevice({
<>
{usbOnly && withArrows && !hideAnimation ? (
- ) : ble.length === 0 ? (
+ ) : usbOnly ? null : ble.length === 0 ? (
{
+ try {
+ const maybeData = await AsyncStorage.getItem(storageKey);
+ return maybeData ? JSON.parse(maybeData) : {};
+ } catch (error) {
+ logger.critical(error as Error);
+ return {};
+ }
+};
+
+export const setStorageEnvs = async (key: EnvName, val: string) => {
+ try {
+ const envs = await getStorageEnv();
+ envs[key] = val;
+ await AsyncStorage.setItem(storageKey, JSON.stringify(envs));
+ } catch (error) {
+ logger.critical(error as Error);
+ }
+};
+
+export const isReadOnly = (key: EnvName) => key in Config;
+
+export const enabledExperimentalFeatures = (): string[] =>
+ // $FlowFixMe
+ [...experimentalFeatures, ...developerFeatures]
+ .map(e => e.name)
+ .filter(k => !isEnvDefault(k));
+
+(async () => {
+ const envs = await getStorageEnv();
+
+ /* eslint-disable guard-for-in */
+ for (const k in envs) {
+ setEnvUnsafe(k as EnvName, envs[k]);
+ }
+
+ for (const k in Config) {
+ setEnvUnsafe(k as EnvName, Config[k]);
+ }
+ /* eslint-enable guard-for-in */
+
+ const saveEnvs = async (name: EnvName, value: string) => {
+ if (
+ [...experimentalFeatures, ...developerFeatures].find(
+ f => f.name === name,
+ ) &&
+ !isReadOnly(name)
+ ) {
+ await setStorageEnvs(name, value);
+ }
+ };
+
+ changes
+ .pipe(concatMap(({ name, value }) => saveEnvs(name, value)))
+ .subscribe();
+})();
+
+export function useExperimental(): boolean {
+ const [state, setState] = useState(
+ () => enabledExperimentalFeatures().length > 0,
+ );
+
+ useEffect(() => {
+ const sub = changes.subscribe(() => {
+ const newExperimental = enabledExperimentalFeatures().length > 0;
+ setState(newExperimental);
+ });
+
+ return () => sub.unsubscribe();
+ }, []);
+
+ return state;
+}
+
diff --git a/src/hooks/useLatestFirmware.ts b/src/hooks/useLatestFirmware.ts
new file mode 100644
index 0000000000..3fe23b8515
--- /dev/null
+++ b/src/hooks/useLatestFirmware.ts
@@ -0,0 +1,31 @@
+import { useEffect, useState } from "react";
+import {
+ DeviceInfo,
+ FirmwareUpdateContext,
+} from "@ledgerhq/live-common/lib/types/manager";
+import manager from "@ledgerhq/live-common/lib/manager";
+
+const useLatestFirmware: (
+ deviceInfo?: DeviceInfo,
+) => FirmwareUpdateContext | null | undefined = deviceInfo => {
+ if (!deviceInfo) return null;
+
+ const [latestFirmware, setLatestFirmware] = useState<
+ FirmwareUpdateContext | null | undefined
+ >(null);
+
+ useEffect(() => {
+ const getLatestFirmwareForDevice = async () => {
+ if (deviceInfo) {
+ const fw = await manager.getLatestFirmwareForDevice(deviceInfo);
+ setLatestFirmware(fw);
+ }
+ };
+
+ getLatestFirmwareForDevice();
+ }, [deviceInfo, setLatestFirmware]);
+
+ return latestFirmware;
+};
+
+export default useLatestFirmware;
diff --git a/src/locales/en/common.json b/src/locales/en/common.json
index 5f220f4c6a..899e35e0cc 100644
--- a/src/locales/en/common.json
+++ b/src/locales/en/common.json
@@ -105,6 +105,9 @@
"title": "Sorry, Bluetooth is disabled",
"description": "Please enable Bluetooth in your phone settings. ({{state}} state)"
},
+ "FwUpdateBluetoothNotSupported": {
+ "title": "Firmware updates are only supported for wired connections"
+ },
"BtcUnmatchedApp": {
"title": "That's the wrong app",
"description": "Please open the {{managerAppName}} app on your device."
@@ -257,12 +260,12 @@
"description": "Please try again."
},
"DisconnectedDevice": {
- "title": "Sorry, it looks like your device was disconnected",
- "description": "Please reconnect and try again."
+ "title": "Device disconnected",
+ "description": "Ledger Live could not connect to your device. Please try selecting it again."
},
"DisconnectedDeviceDuringOperation": {
- "title": "Sorry, it looks like your device was disconnected",
- "description": "Please reconnect and try again."
+ "title": "Device disconnected",
+ "description": "Ledger Live could not connect to your device. Please try selecting it again."
},
"ETHAddressNonEIP": {
"title": "Auto-verification not available: carefully verify the address.",
@@ -2777,6 +2780,10 @@
"appNotInstalled": "Please install the {{appName}} app",
"appNotInstalled_plural": "Please install the {{appName}} apps",
"useAnotherDevice": "Use another device",
+ "deviceInBootloader": {
+ "title": "Device in Bootloader mode.",
+ "description": "Click on \"Continue\" to update it."
+ },
"verifyAddress": {
"title": "Verify address on device",
"description": "Please verify that the {{currencyName}} address to be shown in Ledger Live matches the one on your Ledger device."
@@ -3072,6 +3079,27 @@
},
"FirmwareUpdate": {
"title": "Update firmware",
+ "preparing": "Preparing the firmware update, please keep your device awake and connected. We will notify you of the progress",
+ "confirmIdentifierText": "Verify that the identifier on your device is the same as the identifier below. Confirm and enter your PIN code if requested.",
+ "pleaseReinstallApps": "Please re-install the apps on your device.",
+ "pleaseConfirmUpdate": "Confirm the update on your device",
+ "finishUpdate": "Finish the update on your {{deviceName}}",
+ "identifierTitle": "Identifier:",
+ "pleaseWaitDownload": "Please wait for the installer to be downloaded",
+ "preparingDevice": "Preparing your device",
+ "pleaseWaitUpdate": "Please wait for the update to finish",
+ "waitForFirmwareUpdate": "Wait for the firmware update to finish on your device",
+ "unlockDeviceWithPin": "Unlock your device with your PIN",
+ "reinstallApps": "Re-install apps.",
+ "currentVersionNumber": "Current version",
+ "newVersionNumber": "New version",
+ "success": "Firmware updated",
+ "update": "Update",
+ "Notifications": {
+ "confirmOnDevice": "We require your confirmation on the device",
+ "preparingUpdate": "Transferring update, we will notify you when we're done",
+ "installing": "Installing {{progress}}%"
+ },
"Installing": {
"title": "{{stepName}}...",
"subtitle": "If requested on your device, please enter your PIN to finish the process."
@@ -3081,16 +3109,19 @@
"flash-mcu": "MCU updating",
"flash-bootloader": "Bootloader updating",
"flash": "Flashing your device",
- "firmware": "Firmware updating"
+ "preparing": "Preparing update",
+ "firmware": "Downloading update"
},
- "newVersion": "Update Firmware to {{version}} is available",
+ "newVersion": "Update {{version}} available for your {{deviceName}}",
"drawerUpdate": {
"title": "Firmware Update",
"description": "Update your Ledger Nano firmware by connecting it to the Ledger Live application on desktop"
}
},
"FirmwareUpdateReleaseNotes": {
- "introTitle": "You are about to install <1><0>firmware version {{version}}.0>1>",
+ "introTitle": "Update {{deviceName}} to version {{version}}",
+ "recoveryPhraseBackupInstructions": "Ensure your 24-word recovery phrase is written down on the Recovery sheet and it is available, as a precaution.",
+ "confirmRecoveryPhrase": "I have my recovery phrase",
"introDescription1": "Please note that all the apps on your device will be deleted. You can reinstall your apps after the firmware update.",
"introDescription2": "This has no impact on your crypto assets.",
"action": "Continue update"
diff --git a/src/logic/firmwareUpdate.tsx b/src/logic/firmwareUpdate.tsx
new file mode 100644
index 0000000000..917e387439
--- /dev/null
+++ b/src/logic/firmwareUpdate.tsx
@@ -0,0 +1,16 @@
+import { DeviceModelId } from "@ledgerhq/devices";
+import { DeviceInfo } from "@ledgerhq/live-common/lib/types/manager";
+import { satisfies as versionSatisfies } from "semver";
+
+const deviceVersionRangesForUpdate: { [key in DeviceModelId]?: string } = {
+ nanoS: ">=1.6.1",
+ nanoX: ">=1.2.4-6",
+ nanoSP: ">=1.0.0-0",
+};
+
+export const isFirmwareUpdateVersionSupported = (deviceInfo: DeviceInfo, modelId: DeviceModelId) =>
+ deviceVersionRangesForUpdate[modelId] &&
+ versionSatisfies(
+ deviceInfo.version,
+ deviceVersionRangesForUpdate[modelId] as string,
+ );
diff --git a/src/reducers/appstate.ts b/src/reducers/appstate.ts
new file mode 100644
index 0000000000..c8b61f2d70
--- /dev/null
+++ b/src/reducers/appstate.ts
@@ -0,0 +1,96 @@
+import { handleActions } from "redux-actions";
+import { createSelector } from "reselect";
+import { NetworkDown } from "@ledgerhq/errors";
+import type { State } from ".";
+
+export type AsyncState = {
+ isConnected: boolean | null,
+};
+
+export type BackgroundEvent = {
+ type: "confirmPin"
+} | {
+ type: "downloadingUpdate",
+ progress?: number
+} | {
+ type: "confirmUpdate"
+} | {
+ type: "flashingMcu",
+ progress?: number,
+ installing?: string | null,
+} | {
+ type: "firmwareUpdated"
+} | {
+ type: "error",
+ error: any
+};
+
+export type AppState = {
+ isConnected: boolean | null,
+ hasConnectedDevice: boolean,
+ modalLock: boolean,
+ backgroundEvents: Array,
+};
+
+const initialState: AppState = {
+ isConnected: true,
+ hasConnectedDevice: false, // NB for this current session, have we done a device action with a device.
+ modalLock: false,
+ backgroundEvents: [],
+};
+
+const handlers: Object = {
+ SYNC_IS_CONNECTED: (
+ state: AppState,
+ { isConnected }: { isConnected: boolean | null },
+ ) => ({
+ ...state,
+ isConnected,
+ }),
+ HAS_CONNECTED_DEVICE: (
+ state: AppState,
+ { hasConnectedDevice }: { hasConnectedDevice: boolean },
+ ) => ({ ...state, hasConnectedDevice }),
+ SET_MODAL_LOCK: (state: AppState, { modalLock }: { modalLock: boolean }) => ({
+ ...state,
+ modalLock,
+ }),
+ QUEUE_BACKGROUND_EVENT: (state: AppState, { event }: any) => ({
+ ...state,
+ backgroundEvents: [...state.backgroundEvents, event],
+ }),
+ DEQUEUE_BACKGROUND_EVENT: (state: AppState) => {
+ const [_, ...tail] = state.backgroundEvents;
+ return ({
+ ...state,
+ backgroundEvents: tail,
+ });
+ },
+ CLEAR_BACKGROUND_EVENTS: (state: AppState) => ({
+ ...state,
+ backgroundEvents: [],
+ }),
+};
+
+// Selectors
+
+export const isConnectedSelector = (state: State) => state.appstate.isConnected;
+export const isModalLockedSelector = (state: State) => state.appstate.modalLock;
+export const hasConnectedDeviceSelector = (state: State) =>
+ state.appstate.hasConnectedDevice;
+
+ export const backgroundEventsSelector = (state: State) =>
+ state.appstate.backgroundEvents;
+
+ export const nextBackgroundEventSelector = (state: State) =>
+ state.appstate.backgroundEvents[0];
+
+const globalNetworkDown = new NetworkDown();
+
+// $FlowFixMe
+export const networkErrorSelector = createSelector(
+ isConnectedSelector,
+ (isConnected: boolean) => (!isConnected ? globalNetworkDown : null),
+);
+
+export default handleActions(handlers, initialState);
diff --git a/src/screens/Manager/AppsScreen.tsx b/src/screens/Manager/AppsScreen.tsx
index 95868d5502..066929ee17 100644
--- a/src/screens/Manager/AppsScreen.tsx
+++ b/src/screens/Manager/AppsScreen.tsx
@@ -29,6 +29,7 @@ import NoResultsFound from "../../icons/NoResultsFound";
import AppIcon from "./AppsList/AppIcon";
import AppUpdateAll from "./AppsList/AppUpdateAll";
import Search from "../../components/Search";
+import FirmwareUpdateBanner from "../../components/FirmwareUpdateBanner";
type Props = {
state: State;
@@ -266,8 +267,8 @@ const AppsScreen = ({
dispatch={dispatch}
appList={device}
/>
-
-
+
+
;
+export type ManagerTab = keyof typeof MANAGER_TABS;
type Props = {
- navigation: any,
+ navigation: StackNavigationProp,
route: {
params: {
device: Device,
deviceInfo: DeviceInfo,
result: ListAppsResult,
searchQuery?: string,
+ firmwareUpdate?: boolean,
+ appsToRestore?: string[],
updateModalOpened?: boolean,
tab: ManagerTab,
},
@@ -39,30 +47,39 @@ type Props = {
const Manager = ({
navigation,
- route: {
- params: {
+ route,
+}: Props) => {
+ const {
device,
deviceInfo,
result,
searchQuery,
+ firmwareUpdate,
+ appsToRestore,
updateModalOpened,
- tab = MANAGER_TABS.CATALOG,
- },
- },
-}: Props) => {
+ tab = "CATALOG",
+ } = route.params;
+
const { deviceId, deviceName, modelId } = device;
- const [state, dispatch] = useApps(result, deviceId);
+ const [state, dispatch] = useApps(result, deviceId, appsToRestore);
const reduxDispatch = useDispatch();
const { apps, currentError, installQueue, uninstallQueue } = state;
const blockNavigation = installQueue.length + uninstallQueue.length > 0;
const optimisticState = useMemo(() => predictOptimisticState(state), [state]);
+ const latestFirmware = useLatestFirmware(deviceInfo);
- const [quitManagerAction, setQuitManagerAction] = useState(false);
+ const [quitManagerAction, setQuitManagerAction] = useState(null);
+ const [isFirmwareUpdateOpen, setIsFirmwareUpdateOpen] = useState(false);
+ useEffect(() => {
+ if(latestFirmware && firmwareUpdate && isFirmwareUpdateVersionSupported(deviceInfo, device.modelId)) {
+ setIsFirmwareUpdateOpen(true);
+ }
+ }, [firmwareUpdate, latestFirmware]);
/** general error state */
- const [error, setError] = useState(null);
+ const [error, setError] = useState(null);
/** storage warning modal state */
const [storageWarning, setStorageWarning] = useState(null);
/** install app with dependencies modal state */
@@ -90,7 +107,7 @@ const Manager = ({
const dmi = {
modelId: device.modelId,
deviceInfo,
- appsInstalled: state.installed.map(({ name, version }) => ({
+ apps: state.installed.map(({ name, version }) => ({
name,
version,
})),
@@ -98,6 +115,8 @@ const Manager = ({
reduxDispatch(setLastSeenDeviceInfo(dmi));
}, [device, state.installed, deviceInfo, reduxDispatch]);
+ const installedApps = useMemo(() => state.installed.map(({ name }) => name), [state.installed]);
+
/**
* Resets the navigation params in order to unlock navigation
* then trigger caught navigation action
@@ -125,6 +144,25 @@ const Manager = ({
setStorageWarning,
]);
+ const onCloseFirmwareUpdate = useCallback((restoreApps?: boolean) => {
+ setIsFirmwareUpdateOpen(false);
+
+ // removes the firmwareUpdate param from the stack navigation so we don't open the modal again
+ // if the user comes back to this page within the stack
+ navigation.dispatch(state => {
+ const routes = state.routes.map(route => ({ ...route, params: { ...route.params, firmwareUpdate: false }}));
+ return CommonActions.reset({ ...state, routes });
+ });
+ if(restoreApps) {
+ // we renavigate to the manager to force redetection of the apps and restore apps if needed
+ navigation.replace(ScreenName.Manager, {
+ device,
+ appsToRestore: installedApps,
+ firmwareUpdate: false
+ });
+ }
+ }, [installedApps, navigation]);
+
return (
<>
+
>
);
};
diff --git a/src/screens/Manager/index.tsx b/src/screens/Manager/index.tsx
index c363f2a4b8..247349e6b8 100644
--- a/src/screens/Manager/index.tsx
+++ b/src/screens/Manager/index.tsx
@@ -1,4 +1,3 @@
-/* @flow */
import React, { Component } from "react";
import { StyleSheet } from "react-native";
import { useIsFocused } from "@react-navigation/native";
@@ -68,6 +67,9 @@ type RouteParams = {
searchQuery?: string;
tab?: ManagerTab;
installApp?: string;
+ firmwareUpdate?: boolean;
+ device?: Device;
+ appsToRestore?: string[];
};
type Props = {
@@ -152,11 +154,14 @@ class ChooseDevice extends Component<
};
componentDidMount() {
- this.setState(state => ({ ...state, device: undefined }));
+ this.setState(state => ({ ...state, device: this.props.route.params.device }));
}
render() {
- const { isFocused } = this.props;
+ const {
+ isFocused,
+ route: { params = {} },
+ } = this.props;
const { showMenu, device } = this.state;
if (!isFocused) return null;
@@ -171,6 +176,7 @@ class ChooseDevice extends Component<
- withDevice(deviceId)(transport => execWithTransport(transport)(...a)),
+export function useApps(
+ listAppsRes: ListAppsResult,
+ deviceId: string,
+ appsToRestore?: string[],
+) {
+ const exec: Exec = useCallback(
+ (...args) =>
+ withDevice(deviceId)(transport => execWithTransport(transport)(...args)),
[deviceId],
);
- return useAppsRunner(listAppsRes, exec);
+ return useAppsRunner(listAppsRes, exec, appsToRestore);
}
diff --git a/src/screens/Portfolio/index.tsx b/src/screens/Portfolio/index.tsx
index ae26cb7d80..0a5a1f51a8 100644
--- a/src/screens/Portfolio/index.tsx
+++ b/src/screens/Portfolio/index.tsx
@@ -284,7 +284,6 @@ function PortfolioScreen({ navigation }: Props) {
return (
<>
-
@@ -303,6 +302,9 @@ function PortfolioScreen({ navigation }: Props) {
hidePortfolio={areAccountsEmpty}
/>
+
+
+
{
+ const featureFlag = useFeature(featureFlagId);
+
+ return !featureFlag?.enabled ? : null;
+};
+
const FeatureRow = ({ feature }: Props) => {
const { type, ...rest } = feature;
const Children = experimentalTypesMap[type];
+
+ // we only display a feature as experimental if it is not enabled already via feature flag
return (
{
);
};
-export default FeatureRow;
+const FeatureRowCommon = ({ feature }: Props) => {
+ return feature.rolloutFeatureFlag ? (
+
+ ) : (
+
+ );
+};
+
+export default FeatureRowCommon;
diff --git a/yarn.lock b/yarn.lock
index ead99f601d..ca4dced8da 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1066,10 +1066,10 @@
core-js-pure "^3.19.0"
regenerator-runtime "^0.13.4"
-"@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.14.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
- version "7.17.2"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941"
- integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==
+"@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.14.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.9", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
+ version "7.17.9"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72"
+ integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==
dependencies:
regenerator-runtime "^0.13.4"
@@ -1283,6 +1283,16 @@
"@cosmjs/math" "^0.25.6"
"@cosmjs/utils" "^0.25.6"
+"@cosmjs/amino@^0.28.4":
+ version "0.28.4"
+ resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.28.4.tgz#9315f6876dba80148cf715ced44d1dc7a9b68b94"
+ integrity sha512-b8y5gFC0eGrH0IoYSNtDmTdsTgeQ1KFZ5YVOeIiKmzF91MeiciYO/MNqc027kctacZ+UbnVWGEUGyRBPi9ta/g==
+ dependencies:
+ "@cosmjs/crypto" "0.28.4"
+ "@cosmjs/encoding" "0.28.4"
+ "@cosmjs/math" "0.28.4"
+ "@cosmjs/utils" "0.28.4"
+
"@cosmjs/crypto@0.26.6", "@cosmjs/crypto@^0.26.5":
version "0.26.6"
resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.26.6.tgz#4ee84e8707406a951a43eac34ffc83ff6c6030f3"
@@ -1299,6 +1309,19 @@
ripemd160 "^2.0.2"
sha.js "^2.4.11"
+"@cosmjs/crypto@0.28.4":
+ version "0.28.4"
+ resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.28.4.tgz#b2f1ccb9edee7d357ed1dcd92bdb61f6a1ca06d3"
+ integrity sha512-JRxNLlED3DDh9d04A0RcRw3mYkoobN7q7wafUFy3vI1TjoyWx33v0gqqaYE6/hoo9ghUrJSVOfzVihl8fZajJA==
+ dependencies:
+ "@cosmjs/encoding" "0.28.4"
+ "@cosmjs/math" "0.28.4"
+ "@cosmjs/utils" "0.28.4"
+ "@noble/hashes" "^1"
+ bn.js "^5.2.0"
+ elliptic "^6.5.3"
+ libsodium-wrappers "^0.7.6"
+
"@cosmjs/crypto@^0.24.1":
version "0.24.1"
resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.24.1.tgz#62da59c32b26344f26b10dd31a02b93655586d04"
@@ -1351,6 +1374,15 @@
bech32 "^1.1.4"
readonly-date "^1.0.0"
+"@cosmjs/encoding@0.28.4":
+ version "0.28.4"
+ resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.28.4.tgz#ea39eb4c27ebf7b35e62e9898adae189b86d0da7"
+ integrity sha512-N6Qnjs4dd8KwjW5m9t3L+rWYYGW2wyS+iLtJJ9DD8DiTTxpW9h7/AmUVO/dsRe5H2tV8/DzH/B9pFfpsgro22A==
+ dependencies:
+ base64-js "^1.3.0"
+ bech32 "^1.1.4"
+ readonly-date "^1.0.0"
+
"@cosmjs/encoding@^0.24.1":
version "0.24.1"
resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.24.1.tgz#b30e92cdb70fc200a163b8c7aa5254606c8a09ab"
@@ -1397,19 +1429,6 @@
axios "^0.21.1"
fast-deep-equal "^3.1.3"
-"@cosmjs/ledger-amino@^0.26.5":
- version "0.26.6"
- resolved "https://registry.yarnpkg.com/@cosmjs/ledger-amino/-/ledger-amino-0.26.6.tgz#4fd342229f3de3059e193f8db3f88877074aabe0"
- integrity sha512-L5KDfEq7EswV4ku2SbWlozfKVv9WJWtap4/7SMXKH0XrYWOIz0AYeBfM0OGtJQjuHAiD/1QJ8pam/kjUL3+quQ==
- dependencies:
- "@cosmjs/amino" "0.26.6"
- "@cosmjs/crypto" "0.26.6"
- "@cosmjs/encoding" "0.26.6"
- "@cosmjs/math" "0.26.6"
- "@cosmjs/utils" "0.26.6"
- ledger-cosmos-js "^2.1.8"
- semver "^7.3.2"
-
"@cosmjs/math@0.23.1":
version "0.23.1"
resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.23.1.tgz#706f38742a9a1f6561cf2c4510f8e5ab001fc5e6"
@@ -1424,6 +1443,13 @@
dependencies:
bn.js "^4.11.8"
+"@cosmjs/math@0.28.4":
+ version "0.28.4"
+ resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.28.4.tgz#ddc35b69fa1ffeaf5928f70d4c2faf9284627d84"
+ integrity sha512-wsWjbxFXvk46Dsx8jQ5vsBZOIQuiUIyaaZbUvxsgIhAMpuuBnV5O/drK87+B+4cL+umTelFqTbWnkqueVCIFxQ==
+ dependencies:
+ bn.js "^5.2.0"
+
"@cosmjs/math@^0.24.1":
version "0.24.1"
resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.24.1.tgz#9eed507885aacc9b269441fc9ecb00fb5876883a"
@@ -1586,6 +1612,11 @@
resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.26.6.tgz#134ef1ea0675580c2cc7524589d09f3d42c678a7"
integrity sha512-Zx60MMI1vffX8c2UbUMlszrGIug3TWa25bD7NF3blJ5k/MVCZFsPafEZ+jEi7kcqoxdhMhgJTI6AmUhnMfq9SQ==
+"@cosmjs/utils@0.28.4":
+ version "0.28.4"
+ resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.28.4.tgz#ecbc72458cdaffa6eeef572bc691502b3151330f"
+ integrity sha512-lb3TU6833arPoPZF8HTeG9V418CpurvqH5Aa/ls0I0wYdPDEMO6622+PQNQhQ8Vw8Az2MXoSyc8jsqrgawT84Q==
+
"@cosmjs/utils@^0.24.1":
version "0.24.1"
resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.24.1.tgz#0adfefe63b7f17222bc2bc12f71296f35e7ad378"
@@ -2367,17 +2398,17 @@
dependencies:
commander "^2.20.0"
-"@ledgerhq/cryptoassets@6.28.0", "@ledgerhq/cryptoassets@^6.27.0":
- version "6.28.0"
- resolved "https://registry.yarnpkg.com/@ledgerhq/cryptoassets/-/cryptoassets-6.28.0.tgz#218a41c5184a176ceb3ec16dc21b37589f673c08"
- integrity sha512-j3fBnjsOi2qijWO7p/PNoiEHdzjxP849pO02Q4YWW4Ms4lByv7ysmNLMwrset91We2yyVrdHsjdWY8X5JE97qQ==
+"@ledgerhq/cryptoassets@6.28.2", "@ledgerhq/cryptoassets@^6.28.2":
+ version "6.28.2"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/cryptoassets/-/cryptoassets-6.28.2.tgz#fabc77c46830348d121452976cdcc19908e0acb2"
+ integrity sha512-i+33VVNE+54HrC0mHly6JXWO6Th+/7n7vNpxjhUQq+1IL3K/ex1HUCwB61O/siDInjq7OZ1Roq9CEx7tAsED2Q==
dependencies:
invariant "2"
-"@ledgerhq/devices@6.24.1", "@ledgerhq/devices@^6.24.1":
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-6.24.1.tgz#9696d7831aa1a1a8204cdfa55df13f892b7da162"
- integrity sha512-6SNXWXxojUF6WKXMVIbRs15Mveg+9k0RKJK/PKlwZh929Lnr/NcbONWdwPjWKZAp1g82eEPT4jIkG6qc4QXlcA==
+"@ledgerhq/devices@6.27.1", "@ledgerhq/devices@^6.24.1", "@ledgerhq/devices@^6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-6.27.1.tgz#3b13ab1d1ba8201e9e74a08f390560483978c962"
+ integrity sha512-jX++oy89jtv7Dp2X6gwt3MMkoajel80JFWcdc0HCouwDsV1mVJ3SQdwl/bQU0zd8HI6KebvUP95QTwbQLLK/RQ==
dependencies:
"@ledgerhq/errors" "^6.10.0"
"@ledgerhq/logs" "^6.10.0"
@@ -2404,24 +2435,24 @@
resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-5.50.0.tgz#e3a6834cb8c19346efca214c1af84ed28e69dad9"
integrity sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow==
-"@ledgerhq/hw-app-algorand@6.24.1":
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-algorand/-/hw-app-algorand-6.24.1.tgz#f2eb5a39bfc188a1ef02186b1c41dca18e2a2755"
- integrity sha512-1HpUJM67kmDRuPpHg1BeoX5pFWaowpm6BrAqbTsXT0n5vyxGWN/7YVL2Gn7lhFxkssICptnjNcOHN5Eb1XEEBA==
+"@ledgerhq/hw-app-algorand@6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-algorand/-/hw-app-algorand-6.27.1.tgz#e8c0b0b7864f1372d24f487bcd8a17af496a248d"
+ integrity sha512-bYXn1wBm0muDrCGOG+9ofrDQZ7MUkvZY+pcPGPthg/CwuGR9m9rwid934yEy+IwW5BUzvGvs6aorgL2reyKyDg==
dependencies:
"@ledgerhq/errors" "^6.10.0"
- "@ledgerhq/hw-transport" "^6.24.1"
+ "@ledgerhq/hw-transport" "^6.27.1"
bip32-path "^0.4.2"
hi-base32 "^0.5.1"
js-sha512 "^0.8.0"
tweetnacl "^1.0.3"
-"@ledgerhq/hw-app-btc@6.24.1":
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-btc/-/hw-app-btc-6.24.1.tgz#50591ec34c9c2c73fe6a03975cde64b6c4d24af7"
- integrity sha512-01LlJemkOBoHA0LxZb/NNlw7EIAja27kbUZ5zIC7KgtTuxXgteVxoZWUb4RaX2AuczR2Y/FBvz1HBEwa67hUvA==
+"@ledgerhq/hw-app-btc@6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-btc/-/hw-app-btc-6.27.1.tgz#5f7258f8a61532e14d6720678a80133320fc5666"
+ integrity sha512-2XOH5jtso4QsPYjXldwdcXw6amb8kCyiHtXw1NySA1QP/xBjxN8JLEXEPFsaK6l2zz55I8kKUtVoEGz7bpg0lg==
dependencies:
- "@ledgerhq/hw-transport" "^6.24.1"
+ "@ledgerhq/hw-transport" "^6.27.1"
"@ledgerhq/logs" "^6.10.0"
bip32-path "^0.4.2"
bitcoinjs-lib "^5.2.0"
@@ -2433,25 +2464,25 @@
tiny-secp256k1 "1.1.6"
varuint-bitcoin "1.1.2"
-"@ledgerhq/hw-app-cosmos@6.24.1":
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-cosmos/-/hw-app-cosmos-6.24.1.tgz#00b31c446e2902f5cca68a62e812164864e0ffe7"
- integrity sha512-rIqPuHVL0AAeW3cmXZdcEALf91cGLLCxUnz5DE55TDhE3BMj/ej2H+RaYq+2ahlLERXlZCJ4cJhRjoSfKbbRQw==
+"@ledgerhq/hw-app-cosmos@6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-cosmos/-/hw-app-cosmos-6.27.1.tgz#834df28568dfd59304103c7d4222a16c554a1d10"
+ integrity sha512-UJDQmsv5Fb3Owyem/d5mLJLAVIr3yKJjuYArZ3ui6n7zsx+MGtJgUIXUhpEVIk+FrDKnZGa0sqcbvoXW09NIXQ==
dependencies:
"@ledgerhq/errors" "^6.10.0"
- "@ledgerhq/hw-transport" "^6.24.1"
+ "@ledgerhq/hw-transport" "^6.27.1"
bip32-path "^0.4.2"
-"@ledgerhq/hw-app-eth@6.27.0":
- version "6.27.0"
- resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-6.27.0.tgz#944f901a95ed3d82759e3fb011859b1b357620a9"
- integrity sha512-7uyXu7dCsFmgGWSaXqasxb9Cegrw54HtCeMcZIkq1yqR9ik0ipQIPG1/qW+TqWfS6VYNkorUSsnKc67Cc+0MwA==
+"@ledgerhq/hw-app-eth@6.28.2":
+ version "6.28.2"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-6.28.2.tgz#06fd19b9277442f4eb58ed76f4bc8299acd15a81"
+ integrity sha512-/pGJW5QKsci5mkjcUeP8RvDw4sV9gldp7RWKTKlkldqeRh2kV75bAdStL2p99fGdDfGkfYotpTfm3oOXQpOwiQ==
dependencies:
"@ethersproject/abi" "^5.5.0"
"@ethersproject/rlp" "^5.5.0"
- "@ledgerhq/cryptoassets" "^6.27.0"
+ "@ledgerhq/cryptoassets" "^6.28.2"
"@ledgerhq/errors" "^6.10.0"
- "@ledgerhq/hw-transport" "^6.24.1"
+ "@ledgerhq/hw-transport" "^6.27.1"
"@ledgerhq/logs" "^6.10.0"
axios "^0.26.1"
bignumber.js "^9.0.2"
@@ -2464,59 +2495,59 @@
"@ledgerhq/errors" "^5.11.0"
"@ledgerhq/hw-transport" "^5.11.0"
-"@ledgerhq/hw-app-polkadot@6.24.1":
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-polkadot/-/hw-app-polkadot-6.24.1.tgz#43d2c8149d42186ec1466caebd143d3ed102f57a"
- integrity sha512-u5ZTLud2w3BP10t7rYpW/W7Ar3jDzeKrpwKsaWPk9vbuvc38puuj899iAoqRBjcM5T12y2KuoVcQ17n3cxe3Sg==
+"@ledgerhq/hw-app-polkadot@6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-polkadot/-/hw-app-polkadot-6.27.1.tgz#bf253a6c58a44c97c406087dfce70438c3d213e1"
+ integrity sha512-LkRIDITOv3FNfGB4xldaGz62wgZHLlWA6zd/neE3FxqsCogZia28ieRYdSuin7J4LtDU+GahuyJ9tBXAxuUWKw==
dependencies:
"@ledgerhq/errors" "^6.10.0"
- "@ledgerhq/hw-transport" "^6.24.1"
+ "@ledgerhq/hw-transport" "^6.27.1"
bip32-path "^0.4.2"
-"@ledgerhq/hw-app-solana@^6.27.0":
- version "6.27.0"
- resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-solana/-/hw-app-solana-6.27.0.tgz#6d6b52d04919d2725b402f4d3f5ffe2dfe7b3aef"
- integrity sha512-DFaoJU/2y4RIivLeqlG1L0LhtcDulFcFKuwrw6M2+b6BO5y3bxjRoLMDjBrmAHaZmkUDRZYxqnTLvOeYRLIU2A==
+"@ledgerhq/hw-app-solana@^6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-solana/-/hw-app-solana-6.27.1.tgz#9df40918f4175b597bf7f144732615da076f6375"
+ integrity sha512-mibdrbqW8cnu+cWBpdsfbVM0GOn5sundzlVyQ9Aydddkr45NtnjHsz7Yf+/S3idLxXRE64Kat1Jkb0XYnXPHwA==
dependencies:
"@ledgerhq/errors" "^6.10.0"
- "@ledgerhq/hw-transport" "^6.24.1"
+ "@ledgerhq/hw-transport" "^6.27.1"
"@ledgerhq/logs" "^6.10.0"
bip32-path "^0.4.2"
-"@ledgerhq/hw-app-str@6.24.1":
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-str/-/hw-app-str-6.24.1.tgz#aaecc30132831886b6a0eb30fe1e05143ecfaf2a"
- integrity sha512-Xe/7b2xIerY5fQ/soE9mp+drbcWxF486xpmjZaX4w55NWwf7BR7mQ/HqcXvHqIiIvX1DrQhU31Iip926b/8k3g==
+"@ledgerhq/hw-app-str@6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-str/-/hw-app-str-6.27.1.tgz#274aef6627b323e2f0bd630c69cd57bddd11c908"
+ integrity sha512-cAtl6UKdD/KThcEnsCDn99XZtNxMNcMc6Wcbk7L7h/lmF8zgl6b8fjaA9yPvEZZgOfu6CQ8NTjf4Mp6BHMx4lQ==
dependencies:
- "@ledgerhq/hw-transport" "^6.24.1"
+ "@ledgerhq/hw-transport" "^6.27.1"
base32.js "^0.1.0"
sha.js "^2.3.6"
tweetnacl "^1.0.3"
-"@ledgerhq/hw-app-tezos@6.24.1":
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-tezos/-/hw-app-tezos-6.24.1.tgz#891abd61d075f5b86d47fdb3e88adf6bfc4e7ac8"
- integrity sha512-avGyuiWIIPm3bUY1C3xAMD90qQu7jlw7zv62hYtFnhgdo6uL/7yn1OmbU/uQsbA8QTrBYV6LyaXmhZMo7X7bHQ==
+"@ledgerhq/hw-app-tezos@6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-tezos/-/hw-app-tezos-6.27.1.tgz#9150433b6aa5abb9bca4490bfd323a8b1217b730"
+ integrity sha512-rSR2fF3jrezbbCLprOxyfQwJ2A14d5VI4KpOsTsNY3RRrDUwtXwPXIlQ0lqQM6suNbJ9L9Z/QRGrubWZcPt4Yg==
dependencies:
- "@ledgerhq/hw-transport" "^6.24.1"
+ "@ledgerhq/hw-transport" "^6.27.1"
blake2b "^2.1.4"
bs58check "^2.1.2"
invariant "^2.2.4"
-"@ledgerhq/hw-app-trx@6.24.1":
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-trx/-/hw-app-trx-6.24.1.tgz#3b39a538e8bdd8ee193f0469d85384b344411101"
- integrity sha512-5afQ05qYfNwFmYwluEwOP4qFMsuk/RJmFQ6UuQj1bweu1SKbHNHbPYXaKVk0Ba6YH6P7dwjuBLq5BZeqlgMxUg==
+"@ledgerhq/hw-app-trx@6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-trx/-/hw-app-trx-6.27.1.tgz#ad804ff9e17b0867fc618ec8e32fe79f80afc06b"
+ integrity sha512-n4J5EO2a09bJVPEUWM1mzl+zbl9wZyEuX/yto/u8i64CFYT+nqF2Hf/XjkCMxIZ0Fvhh8/vh8jc/vyyYHR6dMg==
dependencies:
"@ledgerhq/errors" "^6.10.0"
- "@ledgerhq/hw-transport" "^6.24.1"
+ "@ledgerhq/hw-transport" "^6.27.1"
-"@ledgerhq/hw-app-xrp@6.24.1":
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-xrp/-/hw-app-xrp-6.24.1.tgz#875a31d46cb14c306ee630a3a54384e904f8be85"
- integrity sha512-+WCzG7oUdUhO8EK1VOoW5oqMIvgsAS/o8mtZUvYroFaHF2wLiGrFAS/3qnj6f2r6WXGktgsz57HqkxmeysLN8w==
+"@ledgerhq/hw-app-xrp@6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-xrp/-/hw-app-xrp-6.27.1.tgz#b89d6906f448438ad9c2df97c7bc69a7c90c7f41"
+ integrity sha512-A3pe31Uu7VXfXPy2nha9uhB1d6RJFPeuqAF1I8YCXXz8JRxExhFcWTUEAbZ5tXAE1L/KJeleFSuCO62U7obHqQ==
dependencies:
- "@ledgerhq/hw-transport" "^6.24.1"
+ "@ledgerhq/hw-transport" "^6.27.1"
bip32-path "0.4.2"
"@ledgerhq/hw-transport-http@6.27.0":
@@ -2530,34 +2561,34 @@
axios "^0.26.1"
ws "8.5.0"
-"@ledgerhq/hw-transport-mocker@6.24.1":
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-mocker/-/hw-transport-mocker-6.24.1.tgz#68091a98bea9f6a790253fb2256bf9407e2f4de8"
- integrity sha512-4bv1nkdv1ZOXnudwIMub9A+2nRX7mwUgb1Na+E8GiaqssLUpqOEZdekM/VURszku75BKp0so+5k7yfIZdECUNQ==
+"@ledgerhq/hw-transport-mocker@6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-mocker/-/hw-transport-mocker-6.27.1.tgz#2ace1f2decba6c3d3d98c47795d0fa136b5a3f73"
+ integrity sha512-rCpI8RUBMSO/JFGAZ2JTkBaL0sXN1qBREvSmZLprRxNaZU0Sd2cHZhxL9rzAEHBRLrDx83Z1Lov8SDDZqSVFVQ==
dependencies:
- "@ledgerhq/hw-transport" "^6.24.1"
+ "@ledgerhq/hw-transport" "^6.27.1"
"@ledgerhq/logs" "^6.10.0"
-"@ledgerhq/hw-transport-node-speculos@6.24.1":
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-speculos/-/hw-transport-node-speculos-6.24.1.tgz#735617a70ec162fb7bb9401ebdcd95e74e7c0cfe"
- integrity sha512-xkOqK7m1HOALqnwxMTxrBU8N54/PnQJpGx9Xg9RRUpLVEU7m84LAI9uXemx4AKfs6CEL8D5EP51WIRlQlnhdCQ==
+"@ledgerhq/hw-transport-node-speculos@6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-speculos/-/hw-transport-node-speculos-6.27.1.tgz#46539775a3a871aed1ee9dc4314afb8c6fbb7889"
+ integrity sha512-HOf1Oy6DBaoFdr0HkRAgyICILfL1rNUoy3v17ui+W5ftIKoRivxw8OhvFSWN8SnflqKlVfRU5hQmH26fpmVh0w==
dependencies:
"@ledgerhq/errors" "^6.10.0"
- "@ledgerhq/hw-transport" "^6.24.1"
+ "@ledgerhq/hw-transport" "^6.27.1"
"@ledgerhq/logs" "^6.10.0"
rxjs "6"
-"@ledgerhq/hw-transport@6.24.1", "@ledgerhq/hw-transport@^6.24.1":
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-6.24.1.tgz#5e787268e6d5ce4f9f0d53b0d520c1f071c2d1ae"
- integrity sha512-cOhxkQJrN7DvPFLLXAS2nqAZ7NIDaFqnbgu9ugTccgbJm2/z7ClRZX/uQoI4FscswZ47MuJQdXqz4nK48phteQ==
+"@ledgerhq/hw-transport@6.27.1", "@ledgerhq/hw-transport@^6.24.1", "@ledgerhq/hw-transport@^6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-6.27.1.tgz#88072278f69c279cb6569352acd4ae2fec33ace3"
+ integrity sha512-hnE4/Fq1YzQI4PA1W0H8tCkI99R3UWDb3pJeZd6/Xs4Qw/q1uiQO+vNLC6KIPPhK0IajUfuI/P2jk0qWcMsuAQ==
dependencies:
- "@ledgerhq/devices" "^6.24.1"
+ "@ledgerhq/devices" "^6.27.1"
"@ledgerhq/errors" "^6.10.0"
events "^3.3.0"
-"@ledgerhq/hw-transport@^5.11.0", "@ledgerhq/hw-transport@^5.19.1", "@ledgerhq/hw-transport@^5.25.0", "@ledgerhq/hw-transport@^5.51.1":
+"@ledgerhq/hw-transport@^5.11.0", "@ledgerhq/hw-transport@^5.19.1", "@ledgerhq/hw-transport@^5.51.1":
version "5.51.1"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-5.51.1.tgz#8dd14a8e58cbee4df0c29eaeef983a79f5f22578"
integrity sha512-6wDYdbWrw9VwHIcoDnqWBaDFyviyjZWv6H9vz9Vyhe4Qd7TIFmbTl/eWs6hZvtZBza9K8y7zD8ChHwRI4s9tSw==
@@ -2590,51 +2621,50 @@
dependencies:
bignumber.js "^9.0.1"
-"@ledgerhq/live-app-sdk@^0.2.0":
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/@ledgerhq/live-app-sdk/-/live-app-sdk-0.2.0.tgz#d50ca7ddd07eeeb564728a1998bf0fb154533315"
- integrity sha512-OwyEu/Ue/D/mw/Fgc4HrXm4jlzD43r7nfLXC913U+YprPapUcT9e6cc28xIEYXnJqY0GVV/ISdP7ODGfJC21Xg==
+"@ledgerhq/live-app-sdk@^0.6.1":
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/live-app-sdk/-/live-app-sdk-0.6.1.tgz#e5841668cb0c7092ec0f0cc8d3fa662b153754ae"
+ integrity sha512-pGSNsTIg/K3P5xrj9n50Lmb6/sILh/7XrZjMsJA5HDTOYfbhWuYNOXtmDgaSjEO5vkI2YrU2I49VoE2XbwpEwg==
dependencies:
- bignumber.js "^9.0.1"
- json-rpc-2.0 "^0.2.16"
+ bignumber.js "^9.0.2"
+ json-rpc-2.0 "^1.0.0"
-"@ledgerhq/live-common@22.0.2":
- version "22.0.2"
- resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-22.0.2.tgz#e93a283788b9da50c03c16969be9459f730a48e9"
- integrity sha512-/ZMgcVI1UqhwteCUeWuN/Gshw+A43NeHrVoVUUHYbP/sw50/Tg4oiOVJ3M/efviKAb3nhLsj4xBBEwraEdzCfQ==
+"@ledgerhq/live-common@https://github.com/LedgerHQ/ledger-live-common.git#release/22.1.x":
+ version "22.1.0"
+ resolved "https://github.com/LedgerHQ/ledger-live-common.git#9308d1ff29839b53cb426588bc7f289160207cf2"
dependencies:
"@celo/contractkit" "^1.5.2"
"@celo/wallet-base" "^1.5.2"
"@celo/wallet-ledger" "^1.5.2"
+ "@cosmjs/amino" "^0.28.4"
"@cosmjs/crypto" "^0.26.5"
- "@cosmjs/ledger-amino" "^0.26.5"
"@cosmjs/proto-signing" "^0.26.5"
"@cosmjs/stargate" "^0.26.5"
"@crypto-com/chain-jslib" "0.0.19"
"@ethereumjs/common" "^2.6.2"
"@ethereumjs/tx" "^3.5.0"
"@ledgerhq/compressjs" "1.3.2"
- "@ledgerhq/cryptoassets" "6.28.0"
- "@ledgerhq/devices" "6.24.1"
+ "@ledgerhq/cryptoassets" "6.28.2"
+ "@ledgerhq/devices" "6.27.1"
"@ledgerhq/errors" "6.10.0"
- "@ledgerhq/hw-app-algorand" "6.24.1"
- "@ledgerhq/hw-app-btc" "6.24.1"
- "@ledgerhq/hw-app-cosmos" "6.24.1"
- "@ledgerhq/hw-app-eth" "6.27.0"
- "@ledgerhq/hw-app-polkadot" "6.24.1"
- "@ledgerhq/hw-app-solana" "^6.27.0"
- "@ledgerhq/hw-app-str" "6.24.1"
- "@ledgerhq/hw-app-tezos" "6.24.1"
- "@ledgerhq/hw-app-trx" "6.24.1"
- "@ledgerhq/hw-app-xrp" "6.24.1"
- "@ledgerhq/hw-transport" "6.24.1"
- "@ledgerhq/hw-transport-mocker" "6.24.1"
- "@ledgerhq/hw-transport-node-speculos" "6.24.1"
+ "@ledgerhq/hw-app-algorand" "6.27.1"
+ "@ledgerhq/hw-app-btc" "6.27.1"
+ "@ledgerhq/hw-app-cosmos" "6.27.1"
+ "@ledgerhq/hw-app-eth" "6.28.2"
+ "@ledgerhq/hw-app-polkadot" "6.27.1"
+ "@ledgerhq/hw-app-solana" "^6.27.1"
+ "@ledgerhq/hw-app-str" "6.27.1"
+ "@ledgerhq/hw-app-tezos" "6.27.1"
+ "@ledgerhq/hw-app-trx" "6.27.1"
+ "@ledgerhq/hw-app-xrp" "6.27.1"
+ "@ledgerhq/hw-transport" "6.27.1"
+ "@ledgerhq/hw-transport-mocker" "6.27.1"
+ "@ledgerhq/hw-transport-node-speculos" "6.27.1"
"@ledgerhq/json-bignumber" "^1.1.0"
- "@ledgerhq/live-app-sdk" "^0.2.0"
+ "@ledgerhq/live-app-sdk" "^0.6.1"
"@ledgerhq/logs" "6.10.0"
- "@polkadot/types" "7.8.1"
- "@polkadot/types-known" "7.8.1"
+ "@polkadot/types" "8.1.1"
+ "@polkadot/types-known" "8.1.1"
"@solana/spl-token" "^0.1.8"
"@solana/web3.js" "^1.32.0"
"@taquito/ledger-signer" stablelib
@@ -2685,7 +2715,6 @@
ripemd160 "^2.0.2"
ripple-binary-codec "^1.3.0"
ripple-bs58check "^2.0.2"
- ripple-lib "1.10.0"
rlp "^3.0.0"
rxjs "6"
rxjs-compat "^6.6.7"
@@ -2695,6 +2724,7 @@
stellar-sdk "^10.0.1"
superstruct "^0.14.2"
triple-beam "^1.3.0"
+ varuint-bitcoin "1.1.2"
winston "^3.4.0"
xstate "^4.28.1"
@@ -2727,14 +2757,14 @@
styled-system "^5.1.5"
victory-native "^35.5.5"
-"@ledgerhq/react-native-hid@6.24.1":
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/@ledgerhq/react-native-hid/-/react-native-hid-6.24.1.tgz#6a5cf8ed513db6430105be3491e71b3a0250c2a0"
- integrity sha512-xTwWr7q/kWUNVfMIiLEybSzEdRseWopNeV7X91vfhqvlkoESfU9SvuhvTKh41qrt+TrTfExAkgbML3uVlwRUXg==
+"@ledgerhq/react-native-hid@6.27.1":
+ version "6.27.1"
+ resolved "https://registry.yarnpkg.com/@ledgerhq/react-native-hid/-/react-native-hid-6.27.1.tgz#e22c8d66c38143d28ccb4b254a177c166282b5f5"
+ integrity sha512-eeFvRjd3n7JBYBJDA2LYiCi31GUEhdAypg1mChSBeMDZvq3erKEPbMA/BLwFSN9+h5QeBmQb0E6oZncB/qr8WA==
dependencies:
- "@ledgerhq/devices" "^6.24.1"
+ "@ledgerhq/devices" "^6.27.1"
"@ledgerhq/errors" "^6.10.0"
- "@ledgerhq/hw-transport" "^6.24.1"
+ "@ledgerhq/hw-transport" "^6.27.1"
"@ledgerhq/logs" "^6.10.0"
rxjs "6"
@@ -2767,6 +2797,11 @@
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-0.4.1.tgz#ef8ef347cfb3a03692f16ed31fda717f8e78d392"
integrity sha512-Qxy9mZoDf5SyFrQ8hpWHeMZ2Scmb9BAz/lt23sKdr/QHnACW9dD6S+/WVJHd3R/BPoNHcUYWXoXXe74cxSEYoA==
+"@noble/hashes@^1":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.0.0.tgz#d5e38bfbdaba174805a4e649f13be9a9ed3351ae"
+ integrity sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg==
+
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@@ -2895,14 +2930,14 @@
dependencies:
"@octokit/openapi-types" "^11.2.0"
-"@polkadot/keyring@^8.4.1":
- version "8.4.1"
- resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-8.4.1.tgz#71098121c60a05e1ad33653fcc521c52f22ad1b8"
- integrity sha512-0qfS7qikUxhe6LEdCOcMRdCxEa26inJ5aSUWaf5dXy+dgy9VJiov6uXAbXdAd1UHpDvr9hvw94FX+hXsJ7Vsyw==
+"@polkadot/keyring@^9.0.1":
+ version "9.1.1"
+ resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-9.1.1.tgz#d4bf244d6dd23d06fed9334e79c0d46a8fdb5988"
+ integrity sha512-qjnO1795v7wDvU2hW0H+z7bMPNV3xcVnIjozt3/+Y5Lphu3Tohh3WNgf9uNKIUTwbWxTF4wWsiUM1ajY4CRuMA==
dependencies:
- "@babel/runtime" "^7.17.2"
- "@polkadot/util" "8.4.1"
- "@polkadot/util-crypto" "8.4.1"
+ "@babel/runtime" "^7.17.9"
+ "@polkadot/util" "9.1.1"
+ "@polkadot/util-crypto" "9.1.1"
"@polkadot/networks@8.0.6-8":
version "8.0.6-8"
@@ -2911,14 +2946,14 @@
dependencies:
"@babel/runtime" "^7.16.3"
-"@polkadot/networks@^8.4.1":
- version "8.4.1"
- resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-8.4.1.tgz#c22585edb38f5ae0a329a1f471577d8b35bf64e4"
- integrity sha512-YFY3fPLbc1Uz9zsX4TOzjY/FF09nABMgrMkvqddrVbSgo71NvoBv3Gqw3mKV/7bX1Gzk1ODfvTzamdpsKEWSnA==
+"@polkadot/networks@^9.0.1":
+ version "9.1.1"
+ resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-9.1.1.tgz#3b99dcedd1ed626f6efecc642e1dcebca64978e3"
+ integrity sha512-L/jk8vDr4shzGEVOqOimmXySLpbrN8+qlk+BR3A6rFa4N+XjtcGvnnt+so+rXwJOu7U4/ir6qPU2Iq63XbQTMA==
dependencies:
- "@babel/runtime" "^7.17.2"
- "@polkadot/util" "8.4.1"
- "@substrate/ss58-registry" "^1.14.0"
+ "@babel/runtime" "^7.17.9"
+ "@polkadot/util" "9.1.1"
+ "@substrate/ss58-registry" "^1.17.0"
"@polkadot/reactnative-identicon@0.87.5":
version "0.87.5"
@@ -2931,58 +2966,58 @@
"@polkadot/util-crypto" "^8.1.2"
react-native-svg "^12.2.0"
-"@polkadot/types-augment@7.8.1":
- version "7.8.1"
- resolved "https://registry.yarnpkg.com/@polkadot/types-augment/-/types-augment-7.8.1.tgz#f790f3874384e3bd3a4850affb775c6d125f2ff3"
- integrity sha512-uKDOlU6arH/Oz/faHq315tCA5vjIJTO/zQt0Iuz9woEbmXd6ga0vkCr3gXWfPvjg+QnMQuRpNG8rxtiX5w0vCw==
- dependencies:
- "@babel/runtime" "^7.17.2"
- "@polkadot/types" "7.8.1"
- "@polkadot/types-codec" "7.8.1"
- "@polkadot/util" "^8.4.1"
-
-"@polkadot/types-codec@7.8.1":
- version "7.8.1"
- resolved "https://registry.yarnpkg.com/@polkadot/types-codec/-/types-codec-7.8.1.tgz#b42df0baeac7d424c4e5216752f7a630d95381fa"
- integrity sha512-4et1ZiXXK/KsveKcXd0p1FwAYq8rwHmf1pyf1tOH9JglA/Ip6mArrIjivnfofxY5WFWgeuAv7b2+Rk5vGq/0Xw==
- dependencies:
- "@babel/runtime" "^7.17.2"
- "@polkadot/util" "^8.4.1"
-
-"@polkadot/types-create@7.8.1":
- version "7.8.1"
- resolved "https://registry.yarnpkg.com/@polkadot/types-create/-/types-create-7.8.1.tgz#9b68e1f4bb3d71e4ed1eaa03119940e3e3952396"
- integrity sha512-TxUFc3/WAzFHT1DIgzIssBKxtbjrSDe3GzHbOlJcIcLI17rLHFCVi53uDYvR9kMxterJ9MFMxXc76iqwnnXCgQ==
- dependencies:
- "@babel/runtime" "^7.17.2"
- "@polkadot/types-codec" "7.8.1"
- "@polkadot/util" "^8.4.1"
-
-"@polkadot/types-known@7.8.1":
- version "7.8.1"
- resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-7.8.1.tgz#1ed7ed5f5bdd5eb8816258753c1f0fa881a0c38f"
- integrity sha512-qUTZq6B4tm+Gt3G/CvivZVHTD3NueTyNpv9/nEUWwOAmKgrZyJy7uLgGwHoqEjcXn+F86B3raIgp6WP+v8PibQ==
- dependencies:
- "@babel/runtime" "^7.17.2"
- "@polkadot/networks" "^8.4.1"
- "@polkadot/types" "7.8.1"
- "@polkadot/types-codec" "7.8.1"
- "@polkadot/types-create" "7.8.1"
- "@polkadot/util" "^8.4.1"
-
-"@polkadot/types@7.8.1":
- version "7.8.1"
- resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-7.8.1.tgz#67ccf5f10fde4e47f007391f7c39c942cc12bdd8"
- integrity sha512-B+b3q5qprJb6PJGiJ1r6FiXW6LxH2SOFXkTpcFpJeM2wBkJmeQoiEQ7M/r8kkrqtORptfsrxmhbjMr0xvUHZHA==
- dependencies:
- "@babel/runtime" "^7.17.2"
- "@polkadot/keyring" "^8.4.1"
- "@polkadot/types-augment" "7.8.1"
- "@polkadot/types-codec" "7.8.1"
- "@polkadot/types-create" "7.8.1"
- "@polkadot/util" "^8.4.1"
- "@polkadot/util-crypto" "^8.4.1"
- rxjs "^7.5.4"
+"@polkadot/types-augment@8.1.1":
+ version "8.1.1"
+ resolved "https://registry.yarnpkg.com/@polkadot/types-augment/-/types-augment-8.1.1.tgz#f62107ca46080b9ddfc55f4acda30265dcf033ff"
+ integrity sha512-JyJigD/rH33uDKPRF8u2rMRmxkh/brM/AkD+pOH5ZO6AfcQ3mNsFEvM5OZ+Wx2vq6+vX3oH922wjK3d3/ILkpQ==
+ dependencies:
+ "@babel/runtime" "^7.17.9"
+ "@polkadot/types" "8.1.1"
+ "@polkadot/types-codec" "8.1.1"
+ "@polkadot/util" "^9.0.1"
+
+"@polkadot/types-codec@8.1.1":
+ version "8.1.1"
+ resolved "https://registry.yarnpkg.com/@polkadot/types-codec/-/types-codec-8.1.1.tgz#f45c40953169c28e406fbdb0b7306f90b858861a"
+ integrity sha512-JJkSYJrkSjNZYIWAqpihgtMKbTfk2r9J6eHeESiWFYhce61o2x1ylyzedaZkvoxD9hVhb7l94ulrHZKtlJKBFQ==
+ dependencies:
+ "@babel/runtime" "^7.17.9"
+ "@polkadot/util" "^9.0.1"
+
+"@polkadot/types-create@8.1.1":
+ version "8.1.1"
+ resolved "https://registry.yarnpkg.com/@polkadot/types-create/-/types-create-8.1.1.tgz#7e9663b1d8abf8caedb71482c1370e4438eee858"
+ integrity sha512-cL+CpLkHiTxRH67oHiCeunant9JpVvmtJZh+t/NZZypjRkH7YVOpKj643vkiP2m02259N2BzYTR6CEQP8QZGGQ==
+ dependencies:
+ "@babel/runtime" "^7.17.9"
+ "@polkadot/types-codec" "8.1.1"
+ "@polkadot/util" "^9.0.1"
+
+"@polkadot/types-known@8.1.1":
+ version "8.1.1"
+ resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-8.1.1.tgz#f956b5e0f282cabc32416c81e1a47f6dcda92e06"
+ integrity sha512-aOuHf/vTFrScipGx9DOcD83ki1jBLHg3549SAkMwyz0K+RnIlt2nat32/M60eUWJgyHHITl4G0QCZrtFY2D2OA==
+ dependencies:
+ "@babel/runtime" "^7.17.9"
+ "@polkadot/networks" "^9.0.1"
+ "@polkadot/types" "8.1.1"
+ "@polkadot/types-codec" "8.1.1"
+ "@polkadot/types-create" "8.1.1"
+ "@polkadot/util" "^9.0.1"
+
+"@polkadot/types@8.1.1":
+ version "8.1.1"
+ resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-8.1.1.tgz#43e5fb78e6214e6af7c5edbdb6ac69d5b919421d"
+ integrity sha512-x9WDx9XcaSkQGlnk2MNu+49oK80s8Js7lr0mmCinV12m8+3si+GvIOvnuV3ydmWgWtpTt2ERfN+T8a/6f50EpA==
+ dependencies:
+ "@babel/runtime" "^7.17.9"
+ "@polkadot/keyring" "^9.0.1"
+ "@polkadot/types-augment" "8.1.1"
+ "@polkadot/types-codec" "8.1.1"
+ "@polkadot/types-create" "8.1.1"
+ "@polkadot/util" "^9.0.1"
+ "@polkadot/util-crypto" "^9.0.1"
+ rxjs "^7.5.5"
"@polkadot/ui-shared@0.87.5":
version "0.87.5"
@@ -2992,7 +3027,7 @@
"@babel/runtime" "^7.16.3"
color "^3.2.1"
-"@polkadot/util-crypto@8.0.6-8", "@polkadot/util-crypto@8.4.1", "@polkadot/util-crypto@^8.1.2", "@polkadot/util-crypto@^8.4.1":
+"@polkadot/util-crypto@8.0.6-8", "@polkadot/util-crypto@9.1.1", "@polkadot/util-crypto@^8.1.2", "@polkadot/util-crypto@^9.0.1":
version "8.0.6-8"
resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-8.0.6-8.tgz#47735fcf409819f3eaeaf9a7099ff170e501adda"
integrity sha512-ssITWN1mRwvzM0wexDaGAfHWWbqOys4D3vg8mY8WYUZ8NKbdGoOSirnOY/0LlsKDUSQ/kRCtWDiPHZs7UC3Y1A==
@@ -3010,7 +3045,7 @@
micro-base "^0.9.0"
tweetnacl "^1.0.3"
-"@polkadot/util@8.0.6-8", "@polkadot/util@8.4.1", "@polkadot/util@^8.1.2", "@polkadot/util@^8.4.1":
+"@polkadot/util@8.0.6-8", "@polkadot/util@9.1.1", "@polkadot/util@^8.1.2", "@polkadot/util@^9.0.1":
version "8.0.6-8"
resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-8.0.6-8.tgz#83e18960abc49d7dc523bd5375923064742d12bf"
integrity sha512-ZH3Yb7tFaatBjiurK8sDcK+jupmgSK5NEB0j89Jwyv/R+wwTjkyeUlRg0wo7srvRQGfazIQMyryD4pFVRaQx3g==
@@ -3817,10 +3852,10 @@
"@styled-system/core" "^5.1.2"
"@styled-system/css" "^5.1.5"
-"@substrate/ss58-registry@^1.14.0":
- version "1.15.0"
- resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.15.0.tgz#211c7c9e5cbcbfb6ee9c300efd719a038af38c36"
- integrity sha512-UU5uN8HEp0NM22od6kHWLltX0McQPgPX6O3gj7fSf1mMExsCS5fzW88gv1WaVaT8Q+umvGgnIAF7+Tvp8fqTFw==
+"@substrate/ss58-registry@^1.17.0":
+ version "1.18.0"
+ resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.18.0.tgz#0744480e880ae8e557327557a2a7fc95577292ec"
+ integrity sha512-nAA1qsorxgdDnx5ie/FL90nM2riTNn72wIq8jtWsR8trsk1uTIHJgQQjEgviFCtMg4Ws9bEjo8DkWBgVGdPFmw==
"@szmarczak/http-timer@^1.1.2":
version "1.1.2"
@@ -4131,7 +4166,7 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
-"@types/lodash@^4.14.136", "@types/lodash@^4.14.159", "@types/lodash@^4.14.170":
+"@types/lodash@^4.14.159", "@types/lodash@^4.14.170":
version "4.14.178"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8"
integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==
@@ -4230,14 +4265,7 @@
dependencies:
"@types/react" "*"
-"@types/react-native@^0.65", "@types/react-native@^0.65.9":
- version "0.65.17"
- resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.65.17.tgz#6bdb4cb7e60bbc7eda880120e2a78a080373dd97"
- integrity sha512-a1yykkqrnrTQJAteu0lt8gqv0PubdNzQvHH1kUOOl3y6JsK5AuqyvBaDmuw6xAYOL3vSXa43Wt+n47VTZRJd7w==
- dependencies:
- "@types/react" "*"
-
-"@types/react-native@^0.65.21":
+"@types/react-native@^0.65", "@types/react-native@^0.65.21", "@types/react-native@^0.65.9":
version "0.65.21"
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.65.21.tgz#f731b172765f17e4866473de41e1d3a4890ae536"
integrity sha512-6TmhHLEBH7xMOBG+MIExOILOEI+nq/VHmlAJZ7SynJ+/ezG318EFrrxDPge46WPqWT25ZbnhSR6uxzBn7TDRbQ==
@@ -4270,6 +4298,11 @@
"@types/scheduler" "*"
csstype "^3.0.2"
+"@types/redux-actions@^2.6.2":
+ version "2.6.2"
+ resolved "https://registry.yarnpkg.com/@types/redux-actions/-/redux-actions-2.6.2.tgz#5956d9e7b9a644358e2c0610f47b1fa3060edc21"
+ integrity sha512-TvcINy8rWFANcpc3EiEQX9Yv3owM3d3KIrqr2ryUIOhYIYzXA/bhDZeGSSSuai62iVR2qMZUgz9tQ5kr0Kl+Tg==
+
"@types/scheduler@*":
version "0.16.2"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
@@ -4282,6 +4315,11 @@
dependencies:
"@types/node" "*"
+"@types/semver@^7.3.9":
+ version "7.3.9"
+ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc"
+ integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==
+
"@types/stack-utils@^2.0.0":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
@@ -4322,7 +4360,7 @@
resolved "https://registry.yarnpkg.com/@types/utf8/-/utf8-2.1.6.tgz#430cabb71a42d0a3613cce5621324fe4f5a25753"
integrity sha512-pRs2gYF5yoKYrgSaira0DJqVg2tFuF+Qjp838xS7K+mJyY2jJzjsrl6y17GbIa4uMRogMbxs+ghNCvKg6XyNrA==
-"@types/ws@^7.2.0", "@types/ws@^7.4.4":
+"@types/ws@^7.4.4":
version "7.4.7"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702"
integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==
@@ -5105,7 +5143,7 @@ axios@0.25.0:
dependencies:
follow-redirects "^1.14.7"
-axios@0.26.1, axios@^0.26.1:
+axios@0.26.1, axios@^0.26.0, axios@^0.26.1:
version "0.26.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9"
integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==
@@ -5119,13 +5157,6 @@ axios@^0.21.1, axios@^0.21.2:
dependencies:
follow-redirects "^1.14.0"
-axios@^0.26.0:
- version "0.26.0"
- resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.0.tgz#9a318f1c69ec108f8cd5f3c3d390366635e13928"
- integrity sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==
- dependencies:
- follow-redirects "^1.14.8"
-
axobject-query@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-0.1.0.tgz#62f59dbc59c9f9242759ca349960e7a2fe3c36c0"
@@ -5720,7 +5751,7 @@ braces@^3.0.1:
dependencies:
fill-range "^7.0.1"
-brorand@^1.0.1, brorand@^1.0.5, brorand@^1.1.0:
+brorand@^1.0.1, brorand@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
@@ -10932,11 +10963,16 @@ json-parse-even-better-errors@^2.3.0:
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
-json-rpc-2.0@^0.2.16, json-rpc-2.0@^0.2.19:
+json-rpc-2.0@^0.2.19:
version "0.2.19"
resolved "https://registry.yarnpkg.com/json-rpc-2.0/-/json-rpc-2.0-0.2.19.tgz#082957f0d22d22f03473dbf5ffeeb20dcdeb1faa"
integrity sha512-tegZKneDQjWintJS5Zlw8xNvJK0/xq4sct2M5AgfFmcCJFMjvrLgk1noH7OPfFgEQ+ScueuWdaGfikCPr+qBtg==
+json-rpc-2.0@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/json-rpc-2.0/-/json-rpc-2.0-1.1.0.tgz#891eb5fd89de6a909444a2d81ae804655b757c29"
+ integrity sha512-A4v62rLgwC2U+G3hA1PKRgAXKS55ItTtjUJVbIq68yccD+AUJZSdjayxd0PLQD8i3ustyLvvaYKW6+DglScrjA==
+
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
@@ -11019,11 +11055,6 @@ jsonparse@^1.2.0:
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=
-jsonschema@1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.2.tgz#83ab9c63d65bf4d596f91d81195e78772f6452bc"
- integrity sha512-iX5OFQ6yx9NgbHCwse51ohhKgLuLL7Z5cNOeZOPIlDUtAMrxlruHLzVZxbltdHE5mEDXN+75oFOwq6Gn0MZwsA==
-
jsprim@^1.2.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb"
@@ -11324,16 +11355,6 @@ leb128@^0.0.5:
bn.js "^5.0.0"
buffer-pipe "0.0.3"
-ledger-cosmos-js@^2.1.8:
- version "2.1.8"
- resolved "https://registry.yarnpkg.com/ledger-cosmos-js/-/ledger-cosmos-js-2.1.8.tgz#b409ecd1e77f630e6fb212a9f602fe5c6e8f054b"
- integrity sha512-Gl7SWMq+3R9OTkF1hLlg5+1geGOmcHX9OdS+INDsGNxSiKRWlsWCvQipGoDnRIQ6CPo2i/Ze58Dw0Mt/l3UYyA==
- dependencies:
- "@babel/runtime" "^7.11.2"
- "@ledgerhq/hw-transport" "^5.25.0"
- bech32 "^1.1.4"
- ripemd160 "^2.0.2"
-
level-blobs@^0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/level-blobs/-/level-blobs-0.1.7.tgz#9ab9b97bb99f1edbf9f78a3433e21ed56386bdaf"
@@ -11624,7 +11645,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
-lodash@4.17.21, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.7.0:
+lodash@4.17.21, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -14933,7 +14954,7 @@ ripemd160@2, ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2:
hash-base "^3.0.0"
inherits "^2.0.1"
-ripple-address-codec@^4.1.1, ripple-address-codec@^4.2.3:
+ripple-address-codec@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/ripple-address-codec/-/ripple-address-codec-4.2.3.tgz#516675715cd43b71d2fd76c59bd92d0f623c152d"
integrity sha512-9Nd0hQmKoJEhSTzYR9kYjKmSWlH6HaVosNVAM7mIIVlzcNlQCPfKXj7CfvXcRiHl3C6XUZj7RFLqzVaPjq2ufA==
@@ -14941,7 +14962,7 @@ ripple-address-codec@^4.1.1, ripple-address-codec@^4.2.3:
base-x "3.0.9"
create-hash "^1.1.2"
-ripple-binary-codec@^1.1.3, ripple-binary-codec@^1.3.0:
+ripple-binary-codec@^1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/ripple-binary-codec/-/ripple-binary-codec-1.3.2.tgz#dfea9daea2a2b9efc871dfcb56eeacc606135ba8"
integrity sha512-8VG1vfb3EM1J7ZdPXo9E57Zv2hF4cxT64gP6rGSQzODVgMjiBCWozhN3729qNTGtHItz0e82Oix8v95vWYBQ3A==
@@ -14968,42 +14989,6 @@ ripple-bs58check@^2.0.2:
create-hash "^1.1.0"
ripple-bs58 "^4.0.0"
-ripple-keypairs@^1.0.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/ripple-keypairs/-/ripple-keypairs-1.1.3.tgz#3af825ffe85c1777b0aa78d832e9fc5750d4529d"
- integrity sha512-y74Y3c0g652BgpDhWsf0x98GnUyY2D9eO2ay2exienUfbIe00TeIiFhYXQhCGVnliGsxeV9WTpU+YuEWuIxuhw==
- dependencies:
- bn.js "^5.1.1"
- brorand "^1.0.5"
- elliptic "^6.5.4"
- hash.js "^1.0.3"
- ripple-address-codec "^4.2.3"
-
-ripple-lib-transactionparser@0.8.2:
- version "0.8.2"
- resolved "https://registry.yarnpkg.com/ripple-lib-transactionparser/-/ripple-lib-transactionparser-0.8.2.tgz#7aaad3ba1e1aeee1d5bcff32334a7a838f834dce"
- integrity sha512-1teosQLjYHLyOQrKUQfYyMjDR3MAq/Ga+MJuLUfpBMypl4LZB4bEoMcmG99/+WVTEiZOezJmH9iCSvm/MyxD+g==
- dependencies:
- bignumber.js "^9.0.0"
- lodash "^4.17.15"
-
-ripple-lib@1.10.0:
- version "1.10.0"
- resolved "https://registry.yarnpkg.com/ripple-lib/-/ripple-lib-1.10.0.tgz#e41aaf17d5c6e6f8bcc8116736ac108ff3d6b810"
- integrity sha512-Cg2u73UybfM1PnzcuLt5flvLKZn35ovdIp+1eLrReVB4swuRuUF/SskJG9hf5wMosbvh+E+jZu8A6IbYJoyFIA==
- dependencies:
- "@types/lodash" "^4.14.136"
- "@types/ws" "^7.2.0"
- bignumber.js "^9.0.0"
- https-proxy-agent "^5.0.0"
- jsonschema "1.2.2"
- lodash "^4.17.4"
- ripple-address-codec "^4.1.1"
- ripple-binary-codec "^1.1.3"
- ripple-keypairs "^1.0.3"
- ripple-lib-transactionparser "0.8.2"
- ws "^7.2.0"
-
rlp@^2.0.0, rlp@^2.2.3, rlp@^2.2.4:
version "2.2.7"
resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf"
@@ -15095,10 +15080,10 @@ rxjs@6, rxjs@^6.4.0, rxjs@^6.6.3, rxjs@^6.6.6:
dependencies:
tslib "^1.9.0"
-rxjs@^7.5.4:
- version "7.5.4"
- resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.4.tgz#3d6bd407e6b7ce9a123e76b1e770dc5761aa368d"
- integrity sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==
+rxjs@^7.5.5:
+ version "7.5.5"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f"
+ integrity sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==
dependencies:
tslib "^2.1.0"
@@ -15224,10 +15209,10 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
-semver@^7.0.0, semver@^7.2.1, semver@^7.3.2, semver@^7.3.5:
- version "7.3.5"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
- integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
+semver@^7.0.0, semver@^7.2.1, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7:
+ version "7.3.7"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
+ integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
dependencies:
lru-cache "^6.0.0"
@@ -17890,7 +17875,7 @@ ws@^6.1.4:
dependencies:
async-limiter "~1.0.0"
-ws@^7, ws@^7.0.0, ws@^7.2.0, ws@^7.4.5, ws@^7.4.6, ws@^7.5.2:
+ws@^7, ws@^7.0.0, ws@^7.4.5, ws@^7.4.6, ws@^7.5.2:
version "7.5.6"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b"
integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==