diff --git a/.changeset/pretty-dingos-sing.md b/.changeset/pretty-dingos-sing.md new file mode 100644 index 000000000000..babb94ab6b51 --- /dev/null +++ b/.changeset/pretty-dingos-sing.md @@ -0,0 +1,5 @@ +--- +"live-mobile": patch +--- + +Feature flags: take into account env variable FEATURE_FLAGS to override feature flags diff --git a/.changeset/quiet-doors-cross.md b/.changeset/quiet-doors-cross.md new file mode 100644 index 000000000000..af547b9dd2f4 --- /dev/null +++ b/.changeset/quiet-doors-cross.md @@ -0,0 +1,5 @@ +--- +"ledger-live-desktop": patch +--- + +Feature flags: take into account env variable FEATURE_FLAGS to override feature flags diff --git a/.changeset/silent-beers-carry.md b/.changeset/silent-beers-carry.md new file mode 100644 index 000000000000..9797daaca265 --- /dev/null +++ b/.changeset/silent-beers-carry.md @@ -0,0 +1,6 @@ +--- +"@ledgerhq/live-common": patch +"@ledgerhq/types-live": patch +--- + +Add FEATURE_FLAGS env variable to override feature flags diff --git a/apps/ledger-live-desktop/src/renderer/components/FirebaseFeatureFlags.tsx b/apps/ledger-live-desktop/src/renderer/components/FirebaseFeatureFlags.tsx index f60e2e2f7396..6531ae273a29 100644 --- a/apps/ledger-live-desktop/src/renderer/components/FirebaseFeatureFlags.tsx +++ b/apps/ledger-live-desktop/src/renderer/components/FirebaseFeatureFlags.tsx @@ -6,6 +6,7 @@ import { Feature, FeatureId } from "@ledgerhq/types-live"; import { getValue } from "firebase/remote-config"; import { formatFeatureId, useFirebaseRemoteConfig } from "./FirebaseRemoteConfig"; +import { getEnv } from "@ledgerhq/live-common/env"; const checkFeatureFlagVersion = (feature: Feature) => { if ( @@ -42,6 +43,17 @@ export const FirebaseFeatureFlagsProvider = ({ children }: Props): JSX.Element = return checkFeatureFlagVersion(localOverrides[key]); } + const envFlags = getEnv("FEATURE_FLAGS") as { [key in FeatureId]?: Feature } | undefined; + if (allowOverride && envFlags) { + const feature = envFlags[key]; + if (feature) + return { + ...feature, + overridesRemote: true, + overriddenByEnv: true, + }; + } + const value = getValue(remoteConfig, formatFeatureId(key)); const feature: Feature = JSON.parse(value.asString()); @@ -58,7 +70,8 @@ export const FirebaseFeatureFlagsProvider = ({ children }: Props): JSX.Element = (key: FeatureId, value: Feature): void => { const actualRemoteValue = getFeature(key, false); if (!isEqual(actualRemoteValue, value)) { - const overridenValue = { ...value, overridesRemote: true }; + const { overriddenByEnv, ...pureValue } = value; // eslint-disable-line + const overridenValue = { ...pureValue, overridesRemote: true }; setLocalOverrides(currentOverrides => ({ ...currentOverrides, [key]: overridenValue })); } else { setLocalOverrides(currentOverrides => ({ ...currentOverrides, [key]: undefined })); diff --git a/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/FeatureFlagsButton.tsx b/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/FeatureFlagsButton.tsx deleted file mode 100644 index ff4c755ba585..000000000000 --- a/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/FeatureFlagsButton.tsx +++ /dev/null @@ -1,248 +0,0 @@ -import React, { useState, useMemo, useCallback } from "react"; -import Button from "~/renderer/components/Button"; -import { useTranslation } from "react-i18next"; -import { defaultFeatures, useFeatureFlags } from "@ledgerhq/live-common/featureFlags/index"; -import { SettingsSectionRow as Row } from "../../SettingsSection"; -import { Text, Input, Icons, Flex, Tag, SearchInput } from "@ledgerhq/react-ui"; -import { - InputRenderLeftContainer, - InputRenderRightContainer, -} from "@ledgerhq/react-ui/components/form/BaseInput/index"; -import { withV3StyleProvider } from "~/renderer/styles/StyleProviderV3"; -import { includes, lowerCase } from "lodash"; -import Box from "~/renderer/components/Box"; -import Switch from "~/renderer/components/Switch"; -import Alert from "~/renderer/components/Alert"; -import { Feature, FeatureId } from "@ledgerhq/types-live"; - -type EditSectionProps = { - error?: Error; - value: string; - disabled?: boolean; - - onOverride: () => void; - onRestore: () => void; - onChange: (_: string) => void; -}; - -const tryParse = (jsonString: string, fallback: any) => { - try { - return JSON.parse(jsonString); - } catch (e) { - return fallback; - } -}; - -const EditSection = ({ - error, - value, - onOverride, - onRestore, - onChange, - disabled, -}: EditSectionProps) => { - const { t } = useTranslation(); - const handleSwitchChange = useCallback( - enabled => { - const prevVal = JSON.parse(value); - onChange(JSON.stringify({ ...prevVal, enabled })); - }, - [value, onChange], - ); - return ( - - {error ? ( - - {error.toString()} - - ) : null} - - ( - - - - )} - /> - - - - - ); -}; - -const FeatureFlagsButton = () => { - const { t } = useTranslation(); - const featureFlagsProvider = useFeatureFlags(); - const [visible, setVisible] = useState(false); - const [error, setError] = useState(); - const [focusedName, setFocusedName] = useState(""); - const [hiddenFlagName, setHiddenFlagName] = useState(null); - const [inputValues, setInputValues] = useState< - { - [key in FeatureId | string]?: string | undefined; - } - >({}); - const [searchInput, setSearchInput] = useState(""); - - const featureFlags = useMemo(() => { - const features: { [key in FeatureId | string]: Feature } = {}; - const featureKeys = Object.keys(defaultFeatures); - if (hiddenFlagName && !featureKeys.includes(hiddenFlagName)) featureKeys.push(hiddenFlagName); - featureKeys.forEach((key: FeatureId | string) => { - const value = featureFlagsProvider.getFeature(key as FeatureId); - if (value) { - features[key] = value; - } - }); - return features; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [focusedName, featureFlagsProvider, hiddenFlagName]); - - const handleInputChange = useCallback( - value => { - setError(); - setInputValues(currentValues => ({ - ...currentValues, - [focusedName]: value, - })); - }, - [focusedName], - ); - - const handleRestoreFeature = useCallback(() => { - setError(); - setInputValues(currentValues => ({ - ...currentValues, - [focusedName]: undefined, - })); - featureFlagsProvider.resetFeature(focusedName); - }, [featureFlagsProvider, focusedName]); - - const handleOverrideFeature = useCallback(() => { - setError(); - try { - // Nb if value is invalid or missing, JSON parse will fail - const newValue = JSON.parse(inputValues[focusedName]); - featureFlagsProvider.overrideFeature(focusedName, newValue); - } catch (e) { - setError(e); - } - }, [inputValues, focusedName, featureFlagsProvider]); - - const handleAddHiddenFlag = useCallback( - value => { - setHiddenFlagName(value); - setSearchInput(value); - }, - [setSearchInput, setHiddenFlagName], - ); - - const filteredFlags = useMemo(() => { - return Object.entries(featureFlags) - .sort((a, b) => a[0].localeCompare(b[0])) - .filter(([name]) => !searchInput || includes(lowerCase(name), lowerCase(searchInput))); - }, [featureFlags, searchInput]); - - return ( - - {t("settings.developer.featureFlagsDesc")} - {!visible ? null : ( - <> - - ( - - - - )} - clearable - placeholder="Add missing flag" - value={hiddenFlagName} - onChange={handleAddHiddenFlag} - /> - - {filteredFlags.map(([flagName, value]) => ( - <> - - {focusedName === flagName ? ( - - - - - {JSON.stringify(featureFlags[flagName], null, 2)} - - - - ) : null} - - ))} - - )} - - } - > - - - ); -}; - -export default withV3StyleProvider(FeatureFlagsButton); diff --git a/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/FeatureFlagsSettings/FeatureFlagDetails.tsx b/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/FeatureFlagsSettings/FeatureFlagDetails.tsx new file mode 100644 index 000000000000..d0b78d6d82c3 --- /dev/null +++ b/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/FeatureFlagsSettings/FeatureFlagDetails.tsx @@ -0,0 +1,74 @@ +import React, { useCallback } from "react"; +import ButtonV2 from "~/renderer/components/Button"; +import { useFeatureFlags } from "@ledgerhq/live-common/featureFlags/index"; +import { Text, Flex, Tag } from "@ledgerhq/react-ui"; +import { FeatureId } from "@ledgerhq/types-live"; +import { withV2StyleProvider } from "~/renderer/styles/StyleProvider"; +import Box from "~/renderer/components/Box"; +import FeatureFlagEdit from "./FeatureFlagEdit"; + +const OldButton = withV2StyleProvider(ButtonV2); + +type Props = { + flagName: FeatureId; + focused?: boolean; + setFocusedName: (arg0: string | undefined) => void; +}; + +const FeatureFlagDetails: React.FC = props => { + const { flagName, focused, setFocusedName } = props; + const { getFeature } = useFeatureFlags(); + const flagValue = getFeature(flagName as FeatureId); + + const { + overriddenByEnv, + overridesRemote, + enabledOverriddenForCurrentLanguage, + enabledOverriddenForCurrentDesktopVersion, + } = flagValue || {}; + + const handleClick = useCallback(() => { + focused ? setFocusedName(undefined) : setFocusedName(flagName); + }, [focused, flagName, setFocusedName]); + + if (!flagValue) return null; + + return ( + <> + + + + {flagName} + {overriddenByEnv ? ( + + overridden by env + + ) : overridesRemote ? ( + + overridden locally + + ) : null} + {enabledOverriddenForCurrentLanguage ? ( + + disabled for current language + + ) : null} + {enabledOverriddenForCurrentDesktopVersion ? ( + + disabled for current version + + ) : null} + + + {focused ? : null} + + ); +}; + +export default FeatureFlagDetails; diff --git a/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/FeatureFlagsSettings/FeatureFlagEdit.tsx b/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/FeatureFlagsSettings/FeatureFlagEdit.tsx new file mode 100644 index 000000000000..4e474d3e34dd --- /dev/null +++ b/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/FeatureFlagsSettings/FeatureFlagEdit.tsx @@ -0,0 +1,113 @@ +import React, { useState, useMemo, useCallback } from "react"; +import Button from "~/renderer/components/ButtonV3"; +import { useTranslation } from "react-i18next"; +import { useFeatureFlags } from "@ledgerhq/live-common/featureFlags/index"; +import { Text, Input, Flex } from "@ledgerhq/react-ui"; +import { Feature, FeatureId } from "@ledgerhq/types-live"; +import { InputRenderRightContainer } from "@ledgerhq/react-ui/components/form/BaseInput/index"; +import { withV2StyleProvider } from "~/renderer/styles/StyleProvider"; +import SwitchV2 from "~/renderer/components/Switch"; +import Alert from "~/renderer/components/Alert"; + +const Switch = withV2StyleProvider(SwitchV2); + +const FeatureFlagEdit: React.FC<{ flagName: FeatureId; flagValue: Feature }> = props => { + const { flagName, flagValue } = props; + const [error, setError] = useState(); + const [inputValue, setInputValue] = useState(undefined); + + /** + * pureValue is the value of the flag without the keys set programmatically + * by Legder Live. + * */ + const { + overriddenByEnv, // eslint-disable-line @typescript-eslint/no-unused-vars + overridesRemote, // eslint-disable-line @typescript-eslint/no-unused-vars + enabledOverriddenForCurrentLanguage, // eslint-disable-line @typescript-eslint/no-unused-vars + enabledOverriddenForCurrentDesktopVersion, // eslint-disable-line @typescript-eslint/no-unused-vars + ...pureValue + } = flagValue || {}; + + const stringifiedPureValue = useMemo(() => (pureValue ? JSON.stringify(pureValue) : undefined), [ + pureValue, + ]); + + const inputValueDefaulted = inputValue || stringifiedPureValue; + + const featureFlagsProvider = useFeatureFlags(); + + const { t } = useTranslation(); + + const handleInputChange = useCallback(value => { + setError(undefined); + setInputValue(value); + }, []); + + const handleRestoreFeature = useCallback(() => { + setError(undefined); + setInputValue(undefined); + featureFlagsProvider.resetFeature(flagName); + }, [featureFlagsProvider, flagName]); + + const handleOverrideFeature = useCallback(() => { + setError(undefined); + try { + // Nb if value is invalid or missing, JSON parse will fail + const newValue = inputValue ? JSON.parse(inputValue) : undefined; + featureFlagsProvider.overrideFeature(flagName, newValue); + } catch (e) { + setError(e); + } + }, [inputValue, flagName, featureFlagsProvider]); + + const isChecked = useMemo(() => { + if (!inputValueDefaulted) return false; + try { + return JSON.parse(inputValueDefaulted)?.enabled; + } catch (e) { + return false; + } + }, [inputValueDefaulted]); + + const handleSwitchChange = useCallback( + enabled => { + featureFlagsProvider.overrideFeature(flagName, { ...flagValue, enabled }); + }, + [featureFlagsProvider, flagName, flagValue], + ); + + return ( + + + {error ? ( + + {error.toString()} + + ) : null} + + ( + + + + )} + /> + + + + + + + {JSON.stringify(pureValue, null, 2)} + + + ); +}; + +export default FeatureFlagEdit; diff --git a/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/FeatureFlagsSettings/index.tsx b/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/FeatureFlagsSettings/index.tsx new file mode 100644 index 000000000000..1cd762341a93 --- /dev/null +++ b/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/FeatureFlagsSettings/index.tsx @@ -0,0 +1,116 @@ +import React, { useState, useMemo, useCallback } from "react"; +import ButtonV2 from "~/renderer/components/Button"; +import { useTranslation } from "react-i18next"; +import { defaultFeatures } from "@ledgerhq/live-common/featureFlags/index"; +import { SettingsSectionRow as Row } from "../../../SettingsSection"; +import { Input, Icons, Flex, SearchInput, Alert } from "@ledgerhq/react-ui"; +import { FeatureId } from "@ledgerhq/types-live"; +import { InputRenderLeftContainer } from "@ledgerhq/react-ui/components/form/BaseInput/index"; +import { includes, lowerCase, trim } from "lodash"; +import { withV3StyleProvider } from "~/renderer/styles/StyleProviderV3"; +import FeatureFlagDetails from "./FeatureFlagDetails"; + +const addFlagHint = `\ +If a feature flag is defined in the targeted Firebase environment \ +but it is missing from the following list, you can type its name in \ +the input field below and it will appear in the list. Type the \ +flag name in camelCase without the "feature" prefix.\ +`; + +const Content = withV3StyleProvider((props: { visible?: boolean }) => { + const { t } = useTranslation(); + const [focusedName, setFocusedName] = useState(); + const [hiddenFlagName, setHiddenFlagName] = useState(""); + const [searchInput, setSearchInput] = useState(""); + + const trimmedHiddenFlagName = trim(hiddenFlagName); + + const featureFlags = useMemo(() => { + const featureKeys = Object.keys(defaultFeatures); + if (trimmedHiddenFlagName && !featureKeys.includes(trimmedHiddenFlagName)) + featureKeys.push(trimmedHiddenFlagName); + return featureKeys; + }, [trimmedHiddenFlagName]); + + const handleAddHiddenFlag = useCallback( + value => { + setHiddenFlagName(value); + setSearchInput(value); + }, + [setSearchInput, setHiddenFlagName], + ); + + const filteredFlags = useMemo(() => { + return featureFlags + .sort((a, b) => a[0].localeCompare(b[0])) + .filter(name => !searchInput || includes(lowerCase(name), lowerCase(searchInput))); + }, [featureFlags, searchInput]); + + const content = useMemo( + () => + filteredFlags.map(flagName => ( + + )), + [filteredFlags, focusedName], + ); + + return ( + + {t("settings.developer.featureFlagsDesc")} + {!props.visible ? null : ( + <> + + + ( + + + + )} + clearable + placeholder={"Add missing flag (instructions above)"} + value={hiddenFlagName} + onChange={handleAddHiddenFlag} + /> + + {content} + + )} + + ); +}); + +const FeatureFlagsSettings = () => { + const { t } = useTranslation(); + const [visible, setVisible] = useState(false); + + const handleClick = useCallback(() => { + setVisible(!visible); + }, [visible]); + + return ( + } + > + + {visible ? "Hide" : "Show"} + + + ); +}; + +export default FeatureFlagsSettings; diff --git a/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/index.jsx b/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/index.jsx index 8cdba548a3d4..96e5eee8ebb5 100644 --- a/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/index.jsx +++ b/apps/ledger-live-desktop/src/renderer/screens/settings/sections/Developer/index.jsx @@ -9,7 +9,7 @@ import AllowDebugAppsToggle from "./AllowDebugAppsToggle"; import EnablePlatformDevToolsToggle from "./EnablePlatformDevToolsToggle"; import CatalogProviderSelect from "./CatalogProviderSelect"; import RunLocalAppButton from "./RunLocalAppButton"; -import FeatureFlagsButton from "./FeatureFlagsButton"; +import FeatureFlagsSettings from "./FeatureFlagsSettings"; import EnableLearnPageStagingUrlToggle from "./EnableLearnPageStagingUrlToggle"; const SectionDeveloper = () => { @@ -44,7 +44,7 @@ const SectionDeveloper = () => { - + { ); }; +export const withV2StyleProvider = (Component: React.ComponentType) => { + const WrappedComponent = props => { + const selectedPalette = useSelector(themeSelector) || "light"; + + return ( + + + + ); + }; + return WrappedComponent; +}; + export default StyleProvider; diff --git a/apps/ledger-live-desktop/tests/fixtures/common.ts b/apps/ledger-live-desktop/tests/fixtures/common.ts index a4f29ac05145..246bd4bff7ee 100644 --- a/apps/ledger-live-desktop/tests/fixtures/common.ts +++ b/apps/ledger-live-desktop/tests/fixtures/common.ts @@ -3,6 +3,7 @@ import { test as base, expect, Page, ElectronApplication } from "@playwright/tes import * as fs from "fs"; import * as path from "path"; import * as crypto from "crypto"; +import { Feature, FeatureId } from "@ledgerhq/types-live"; export function generateUUID(): string { return crypto.randomBytes(16).toString("hex"); @@ -17,6 +18,7 @@ type TestFixtures = { userdataFile: any; env: Record; page: Page; + featureFlags: { [key in FeatureId]?: Feature }; }; const test = base.extend({ @@ -24,6 +26,7 @@ const test = base.extend({ lang: "en-US", theme: "dark", userdata: undefined, + featureFlags: undefined, userdataDestinationPath: async ({}, use) => { use(path.join(__dirname, "../artifacts/userdata", generateUUID())); }, @@ -35,7 +38,15 @@ const test = base.extend({ use(fullFilePath); }, page: async ( - { lang, theme, userdata, userdataDestinationPath, userdataOriginalFile, env }: TestFixtures, + { + lang, + theme, + userdata, + userdataDestinationPath, + userdataOriginalFile, + env, + featureFlags, + }: TestFixtures, use: (page: Page) => void, ) => { // create userdata path @@ -55,6 +66,7 @@ const test = base.extend({ CI: process.env.CI || undefined, PLAYWRIGHT_RUN: true, LEDGER_MIN_HEIGHT: 768, + FEATURE_FLAGS: JSON.stringify(featureFlags), }, env, ); @@ -105,7 +117,7 @@ const test = base.extend({ }); // app is loaded - //expect(await page.title()).toBe("Ledger Live"); + // expect(await page.title()).toBe("Ledger Live"); await page.waitForLoadState("domcontentloaded"); await page.waitForSelector("#loader-container", { state: "hidden" }); diff --git a/apps/ledger-live-mobile/src/components/FirebaseFeatureFlags.tsx b/apps/ledger-live-mobile/src/components/FirebaseFeatureFlags.tsx index f51ef376c405..ccad3a5b0896 100644 --- a/apps/ledger-live-mobile/src/components/FirebaseFeatureFlags.tsx +++ b/apps/ledger-live-mobile/src/components/FirebaseFeatureFlags.tsx @@ -7,6 +7,7 @@ import { defaultFeatures, } from "@ledgerhq/live-common/featureFlags/index"; import { FeatureId, Feature } from "@ledgerhq/types-live"; +import { getEnv } from "@ledgerhq/live-common/env"; import { formatFeatureId } from "./FirebaseRemoteConfig"; @@ -15,17 +16,33 @@ import { languageSelector } from "../reducers/settings"; // eslint-disable-next-line @typescript-eslint/ban-types type Props = PropsWithChildren<{}>; -const getFeature = ( - key: FeatureId, - appLanguage: string, - localOverrides?: { [key in FeatureId]?: Feature }, -) => { +const getFeature = (args: { + key: FeatureId; + appLanguage: string; + localOverrides?: { [key in FeatureId]?: Feature }; + allowOverride?: boolean; +}) => { + const { key, appLanguage, localOverrides, allowOverride = true } = args; try { // Nb prioritize local overrides - if (localOverrides && localOverrides[key]) { + if (allowOverride && localOverrides && localOverrides[key]) { return localOverrides[key]; } + const envFlags = getEnv("FEATURE_FLAGS") as + | { [key in FeatureId]?: Feature } + | undefined; + + if (allowOverride && envFlags) { + const feature = envFlags[key]; + if (feature) + return { + ...feature, + overridesRemote: true, + overriddenByEnv: true, + }; + } + const value = remoteConfig().getValue(formatFeatureId(key)); const feature = JSON.parse(value.asString()); @@ -57,8 +74,8 @@ export const getAllDivergedFlags = ( appLanguage: string, ): { [key in FeatureId]: boolean } => { const res: { [key in FeatureId]: boolean } = {}; - Object.keys(defaultFeatures).forEach(key => { - const value = getFeature(key, appLanguage); + (Object.keys(defaultFeatures) as FeatureId[]).forEach(key => { + const value = getFeature({ key, appLanguage }); if (value && value.enabled !== defaultFeatures[key].enabled) { res[key] = value.enabled; } @@ -73,9 +90,14 @@ export const FirebaseFeatureFlagsProvider: React.FC = ({ children }) => { const overrideFeature = useCallback( (key: FeatureId, value: Feature): void => { - const actualRemoteValue = getFeature(key, appLanguage); + const actualRemoteValue = getFeature({ + key, + appLanguage, + allowOverride: false, + }); if (!isEqual(actualRemoteValue, value)) { - const overridenValue = { ...value, overridesRemote: true }; + const { overriddenByEnv: _, ...pureValue } = value; + const overridenValue = { ...pureValue, overridesRemote: true }; setLocalOverrides(currentOverrides => ({ ...currentOverrides, [key]: overridenValue, @@ -99,7 +121,8 @@ export const FirebaseFeatureFlagsProvider: React.FC = ({ children }) => { // Nb wrapped because the method is also called from outside. const wrappedGetFeature = useCallback( - (key: FeatureId): Feature => getFeature(key, appLanguage, localOverrides), + (key: FeatureId): Feature => + getFeature({ key, appLanguage, localOverrides }), [localOverrides, appLanguage], ); diff --git a/apps/ledger-live-mobile/src/components/RootNavigator/SettingsNavigator.tsx b/apps/ledger-live-mobile/src/components/RootNavigator/SettingsNavigator.tsx index a978314467a0..9500e1c3d4ae 100644 --- a/apps/ledger-live-mobile/src/components/RootNavigator/SettingsNavigator.tsx +++ b/apps/ledger-live-mobile/src/components/RootNavigator/SettingsNavigator.tsx @@ -16,7 +16,7 @@ import DebugBLE from "../../screens/DebugBLE"; import DebugBLEBenchmark from "../../screens/DebugBLEBenchmark"; import DebugCrash from "../../screens/DebugCrash"; import DebugHttpTransport from "../../screens/DebugHttpTransport"; -import DebugFeatureFlags from "../../screens/DebugFeatureFlags"; +import DebugFeatureFlags from "../../screens/FeatureFlagsSettings"; import DebugIcons from "../../screens/DebugIcons"; import DebugLottie from "../../screens/DebugLottie"; import DebugMultiAppInstall from "../../screens/DebugMultiAppInstall"; diff --git a/apps/ledger-live-mobile/src/screens/DebugFeatureFlags.tsx b/apps/ledger-live-mobile/src/screens/DebugFeatureFlags.tsx deleted file mode 100644 index b8dbd9bb11d0..000000000000 --- a/apps/ledger-live-mobile/src/screens/DebugFeatureFlags.tsx +++ /dev/null @@ -1,294 +0,0 @@ -import React, { useCallback, useState, useMemo } from "react"; -import { Pressable, ScrollView, StyleSheet, View } from "react-native"; -import { useTranslation } from "react-i18next"; -import { - defaultFeatures, - useFeatureFlags, -} from "@ledgerhq/live-common/featureFlags/index"; -import type { FeatureId, Feature } from "@ledgerhq/types-live"; - -import { - BaseInput, - Text, - Flex, - Button, - Box, - Tag, - SearchInput, - Switch, - Icons, -} from "@ledgerhq/native-ui"; -import styled from "styled-components/native"; -import { includes, lowerCase } from "lodash"; -import { - InputRenderLeftContainer, - InputRenderRightContainer, -} from "@ledgerhq/native-ui/components/Form/Input/BaseInput"; -import NavigationScrollView from "../components/NavigationScrollView"; -import Alert from "../components/Alert"; - -const Divider = styled(Box).attrs({ - width: "100%", - my: 4, - height: 1, - bg: "neutral.c50", -})``; - -const TagEnabled = styled(Tag).attrs({ - bg: "success.c100", - uppercase: false, - type: "color", - mr: 2, -})``; - -const TagDisabled = styled(Tag).attrs({ - bg: "error.c100", - uppercase: false, - type: "color", - mr: 2, -})``; - -type EditSectionProps = { - error?: Error; - value: string; - disabled?: boolean; - - onOverride: () => void; - onRestore: () => void; - onChange: (_: string) => void; -}; - -const tryParse = (jsonString: string, fallback: any) => { - try { - return JSON.parse(jsonString); - } catch (e) { - return fallback; - } -}; - -const EditSection = ({ - error, - value, - onOverride, - onRestore, - onChange, - disabled, -}: EditSectionProps) => { - const { t } = useTranslation(); - const handleSwitchChange = useCallback( - newVal => { - onChange(JSON.stringify({ ...JSON.parse(value), enabled: newVal })); - }, - [value, onChange], - ); - return ( - - {error ? ( - - {error.toString()} - - ) : null} - ( - - - - )} - /> - - - - - - ); -}; - -export default function DebugFeatureFlags() { - const { t } = useTranslation(); - const featureFlagsProvider = useFeatureFlags(); - const [error, setError] = useState(null); - const [focusedName, setFocusedName] = useState(null); - const [hiddenFlagName, setHiddenFlagName] = useState(null); - const [searchInput, setSearchInput] = useState(""); - const [inputValues, setInputValues] = useState<{ - [key in FeatureId | string]?: string | undefined; - }>({}); - - const featureFlags = useMemo(() => { - const features: { [key in FeatureId | string]: Feature } = {}; - const featureKeys = Object.keys(defaultFeatures); - if (hiddenFlagName && !featureKeys.includes(hiddenFlagName)) - featureKeys.push(hiddenFlagName); - featureKeys.forEach((key: FeatureId | string) => { - const value = featureFlagsProvider.getFeature(key as FeatureId); - if (value) { - features[key] = value; - } - }); - return features; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [focusedName, featureFlagsProvider, hiddenFlagName]); - - const handleInputChange = useCallback( - value => { - setError(null); - if (!focusedName) return; - setInputValues(currentValues => ({ - ...currentValues, - [focusedName]: value, - })); - }, - [focusedName], - ); - - const handleRestoreFeature = useCallback(() => { - setError(null); - if (!focusedName) return; - setInputValues(currentValues => ({ - ...currentValues, - [focusedName]: undefined, - })); - featureFlagsProvider.resetFeature(focusedName); - }, [featureFlagsProvider, focusedName]); - - const handleOverrideFeature = useCallback(() => { - setError(null); - if (!focusedName) return; - try { - // Nb if value is invalid or missing, JSON parse will fail - const newValue = JSON.parse(inputValues[focusedName]); - featureFlagsProvider.overrideFeature(focusedName as FeatureId, newValue); - } catch (e) { - setError(e); - } - }, [inputValues, focusedName, featureFlagsProvider]); - - const handleAddHiddenFlag = useCallback( - value => { - setHiddenFlagName(value); - setSearchInput(value); - }, - [setSearchInput, setHiddenFlagName], - ); - - const handleSearch = useCallback(value => { - setSearchInput(value); - }, []); - - const filteredFlags = useMemo(() => { - return Object.entries(featureFlags) - .sort((a, b) => a[0].localeCompare(b[0])) - .filter( - ([name]) => - !searchInput || includes(lowerCase(name), lowerCase(searchInput)), - ); - }, [featureFlags, searchInput]); - - return ( - - - {t("settings.debug.featureFlagsTitle")} - - Legend: - enabled flag - disabled flag - - - - - ( - - - - )} - placeholder="Add missing flag" - onChange={handleAddHiddenFlag} - autoCapitalize="none" - /> - - {filteredFlags.length === 0 ? ( - {`No flag matching "${searchInput}"`} - ) : null} - {filteredFlags.map(([flagName, value], index, arr) => { - const isFocused = focusedName === flagName; - const isLast = index === arr.length - 1; - return ( - - setFocusedName(isFocused ? null : flagName)} - > - - {value?.enabled ? ( - {flagName} - ) : ( - {flagName} - )} - {value?.overridesRemote && ( - - overridden locally - - )} - {value?.enabledOverriddenForCurrentLanguage && ( - - disabled for current language - - )} - - - {isFocused ? ( - - ) : null} - {isFocused && ( - - - - {JSON.stringify(featureFlags[flagName], null, 2)} - - - - )} - {!isLast && isFocused ? : null} - - ); - })} - - - ); -} - -const styles = StyleSheet.create({ - root: { - padding: 16, - }, -}); diff --git a/apps/ledger-live-mobile/src/screens/FeatureFlagsSettings/FeatureFlagDetails.tsx b/apps/ledger-live-mobile/src/screens/FeatureFlagsSettings/FeatureFlagDetails.tsx new file mode 100644 index 000000000000..4647f48f9a6f --- /dev/null +++ b/apps/ledger-live-mobile/src/screens/FeatureFlagsSettings/FeatureFlagDetails.tsx @@ -0,0 +1,85 @@ +import React from "react"; +import { Pressable, View } from "react-native"; +import { useFeatureFlags } from "@ledgerhq/live-common/featureFlags/index"; +import type { FeatureId } from "@ledgerhq/types-live"; + +import { Flex, Box, Tag } from "@ledgerhq/native-ui"; +import styled from "styled-components/native"; +import FeatureFlagEdit from "./FeatureFlagEdit"; + +export const Divider = styled(Box).attrs({ + width: "100%", + my: 4, + height: 1, + bg: "neutral.c50", +})``; + +export const TagEnabled = styled(Tag).attrs({ + bg: "success.c100", + uppercase: false, + type: "color", + mr: 2, +})``; + +export const TagDisabled = styled(Tag).attrs({ + bg: "error.c100", + uppercase: false, + type: "color", + mr: 2, +})``; + +type Props = { + flagName: FeatureId; + focused?: boolean; + setFocusedName: (arg0: string | undefined) => void; + isLast?: boolean; +}; + +const FeatureFlagDetails: React.FC = props => { + const { flagName, focused, setFocusedName, isLast } = props; + + const { getFeature } = useFeatureFlags(); + const flagValue = getFeature(flagName as FeatureId); + + if (!flagValue) return null; + + const { + overriddenByEnv, + overridesRemote, + enabledOverriddenForCurrentLanguage, + } = flagValue; + + return ( + + setFocusedName(focused ? undefined : flagName)}> + + {flagValue?.enabled ? ( + {flagName} + ) : ( + {flagName} + )} + {overriddenByEnv ? ( + + overridden by env + + ) : overridesRemote ? ( + + overridden locally + + ) : null} + {enabledOverriddenForCurrentLanguage && ( + + disabled for current language + + )} + + + {focused ? ( + + ) : null} + {!isLast && focused ? : null} + + ); +}; + +export default FeatureFlagDetails; diff --git a/apps/ledger-live-mobile/src/screens/FeatureFlagsSettings/FeatureFlagEdit.tsx b/apps/ledger-live-mobile/src/screens/FeatureFlagsSettings/FeatureFlagEdit.tsx new file mode 100644 index 000000000000..f8c0fad6a919 --- /dev/null +++ b/apps/ledger-live-mobile/src/screens/FeatureFlagsSettings/FeatureFlagEdit.tsx @@ -0,0 +1,112 @@ +import React, { useCallback, useState, useMemo } from "react"; +import { ScrollView } from "react-native"; +import { useTranslation } from "react-i18next"; +import { useFeatureFlags } from "@ledgerhq/live-common/featureFlags/index"; +import type { FeatureId, Feature } from "@ledgerhq/types-live"; + +import { BaseInput, Text, Flex, Button, Switch } from "@ledgerhq/native-ui"; +import { InputRenderRightContainer } from "@ledgerhq/native-ui/components/Form/Input/BaseInput"; +import Alert from "../../components/Alert"; + +const FeatureFlagEdit: React.FC<{ + flagName: FeatureId; + flagValue: Feature; +}> = props => { + const { flagName, flagValue } = props; + const [error, setError] = useState(); + const [inputValue, setInputValue] = useState(undefined); + + /** + * pureValue is the value of the flag without the keys set programmatically + * by Legder Live. + * */ + const { overriddenByEnv, overridesRemote, ...pureValue } = flagValue || {}; + + const stringifiedPureValue = useMemo( + () => (pureValue ? JSON.stringify(pureValue) : undefined), + [pureValue], + ); + + const inputValueDefaulted = inputValue || stringifiedPureValue; + + const featureFlagsProvider = useFeatureFlags(); + + const { t } = useTranslation(); + + const handleInputChange = useCallback(value => { + setError(undefined); + setInputValue(value); + }, []); + + const handleRestoreFeature = useCallback(() => { + setError(undefined); + setInputValue(undefined); + featureFlagsProvider.resetFeature(flagName); + }, [featureFlagsProvider, flagName]); + + const handleOverrideFeature = useCallback(() => { + setError(undefined); + try { + // Nb if value is invalid or missing, JSON parse will fail + const newValue = inputValue ? JSON.parse(inputValue) : undefined; + featureFlagsProvider.overrideFeature(flagName, newValue); + } catch (e) { + setError(e); + } + }, [inputValue, flagName, featureFlagsProvider]); + + const isChecked = useMemo(() => { + if (!inputValueDefaulted) return false; + try { + return JSON.parse(inputValueDefaulted)?.enabled; + } catch (e) { + return false; + } + }, [inputValueDefaulted]); + + const handleSwitchChange = useCallback( + enabled => { + featureFlagsProvider.overrideFeature(flagName, { ...flagValue, enabled }); + }, + [featureFlagsProvider, flagName, flagValue], + ); + + return ( + + {error ? ( + + {error.toString()} + + ) : null} + ( + + + + )} + /> + + + + + + + {JSON.stringify(pureValue, null, 2)} + + + + ); +}; + +export default FeatureFlagEdit; diff --git a/apps/ledger-live-mobile/src/screens/FeatureFlagsSettings/index.tsx b/apps/ledger-live-mobile/src/screens/FeatureFlagsSettings/index.tsx new file mode 100644 index 000000000000..f2a2f362c066 --- /dev/null +++ b/apps/ledger-live-mobile/src/screens/FeatureFlagsSettings/index.tsx @@ -0,0 +1,118 @@ +import React, { useCallback, useState, useMemo } from "react"; +import { StyleSheet, View } from "react-native"; +import { useTranslation } from "react-i18next"; +import { defaultFeatures } from "@ledgerhq/live-common/featureFlags/index"; +import type { FeatureId } from "@ledgerhq/types-live"; + +import { BaseInput, Text, Flex, SearchInput, Icons } from "@ledgerhq/native-ui"; +import { includes, lowerCase, trim } from "lodash"; +import { InputRenderLeftContainer } from "@ledgerhq/native-ui/components/Form/Input/BaseInput"; +import NavigationScrollView from "../../components/NavigationScrollView"; +import FeatureFlagDetails, { + Divider, + TagDisabled, + TagEnabled, +} from "./FeatureFlagDetails"; +import Alert from "../../components/Alert"; + +const addFlagHint = `\ +If a feature flag is defined in the targeted Firebase environment \ +but it is missing from the following list, you can type its name in \ +the input field below and it will appear in the list.\nType the \ +flag name in camelCase without the "feature" prefix.\ +`; + +export default function DebugFeatureFlags() { + const { t } = useTranslation(); + const [focusedName, setFocusedName] = useState(); + const [hiddenFlagName, setHiddenFlagName] = useState(""); + const trimmedHiddenFlagName = trim(hiddenFlagName); + const [searchInput, setSearchInput] = useState(""); + + const featureFlags = useMemo(() => { + const featureKeys = Object.keys(defaultFeatures); + if (trimmedHiddenFlagName && !featureKeys.includes(trimmedHiddenFlagName)) + featureKeys.push(trimmedHiddenFlagName); + return featureKeys; + }, [trimmedHiddenFlagName]); + + const handleAddHiddenFlag = useCallback( + value => { + setHiddenFlagName(trim(value)); + setSearchInput(value); + }, + [setSearchInput, setHiddenFlagName], + ); + + const handleSearch = useCallback(value => { + setSearchInput(value); + }, []); + + const filteredFlags = useMemo(() => { + return featureFlags + .sort((a, b) => a[0].localeCompare(b[0])) + .filter( + name => + !searchInput || includes(lowerCase(name), lowerCase(searchInput)), + ); + }, [featureFlags, searchInput]); + + const content = useMemo( + () => + filteredFlags.map((flagName, index, arr) => ( + + )), + [filteredFlags, focusedName], + ); + + return ( + + + {t("settings.debug.featureFlagsTitle")} + + Legend: + enabled flag + disabled flag + + + + + + + ( + + + + )} + placeholder="Add missing flag (instructions above)" + onChange={handleAddHiddenFlag} + autoCapitalize="none" + /> + + {filteredFlags.length === 0 ? ( + {`No flag matching "${searchInput}"`} + ) : null} + {content} + + + ); +} + +const styles = StyleSheet.create({ + root: { + padding: 16, + }, +}); diff --git a/libs/ledger-live-common/src/env.ts b/libs/ledger-live-common/src/env.ts index 96c2c025c660..c143cd18b993 100644 --- a/libs/ledger-live-common/src/env.ts +++ b/libs/ledger-live-common/src/env.ts @@ -29,6 +29,23 @@ const boolParser = (v: unknown): boolean | null | undefined => { const stringParser = (v: unknown): string | null | undefined => typeof v === "string" ? v : undefined; +type JSONValue = + | string + | number + | boolean + | null + | { [x: string]: JSONValue } + | Array; + +const jsonParser = (v: unknown): JSONValue | undefined => { + try { + if (typeof v !== "string") throw new Error(); + return JSON.parse(v); + } catch (e) { + return undefined; + } +}; + const envDefinitions = { ANALYTICS_CONSOLE: { def: false, @@ -644,6 +661,11 @@ const envDefinitions = { parser: boolParser, desc: "use the staging URL for the learn page", }, + FEATURE_FLAGS: { + def: "", + parser: jsonParser, + desc: "key value map for feature flags: {[key in FeatureId]?: Feature]}", + }, }; const getDefinition = (name: string): EnvDef | null | undefined => diff --git a/libs/ledgerjs/packages/types-live/README.md b/libs/ledgerjs/packages/types-live/README.md index 69b66c83dc81..41e4d8f13591 100644 --- a/libs/ledgerjs/packages/types-live/README.md +++ b/libs/ledgerjs/packages/types-live/README.md @@ -60,6 +60,7 @@ Ledger Live main types. * [languages_blacklisted](#languages_blacklisted) * [enabledOverriddenForCurrentLanguage](#enabledoverriddenforcurrentlanguage) * [overridesRemote](#overridesremote) + * [overriddenByEnv](#overriddenbyenv) * [params](#params) * [DefaultFeatures](#defaultfeatures) * [LedgerScriptParams](#ledgerscriptparams) @@ -493,7 +494,7 @@ Type: (`"learn"` | `"pushNotifications"` | `"llmUsbFirmwareUpdate"` | `"ratings" We use objects instead of direct booleans for potential future improvements like feature versioning etc -Type: {enabled: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), desktop_version: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, enabledOverriddenForCurrentDesktopVersion: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, languages_whitelisted: \[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)]?, languages_blacklisted: \[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)]?, enabledOverriddenForCurrentLanguage: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, overridesRemote: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, params: any?} +Type: {enabled: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), desktop_version: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, enabledOverriddenForCurrentDesktopVersion: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, languages_whitelisted: \[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)]?, languages_blacklisted: \[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)]?, enabledOverriddenForCurrentLanguage: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, overridesRemote: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, overriddenByEnv: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, params: any?} #### Properties @@ -504,6 +505,7 @@ Type: {enabled: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Refe * `languages_blacklisted` **\[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)]?** * `enabledOverriddenForCurrentLanguage` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** * `overridesRemote` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `overriddenByEnv` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** * `params` **any?** #### enabled @@ -566,6 +568,12 @@ Whether the remote value of this object was overriden locally Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean) +#### overriddenByEnv + +Whether the remote value of this object was overriden by an environment variable + +Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean) + #### params Additional params @@ -1403,3 +1411,925 @@ Type: {errors: Record<[string](https://developer.mozilla.org/docs/Web/JavaScript * `totalSpent` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** * `useAllAmount` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** * `recipientIsReadOnly` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** + +# <<<<<<< 459e02d258e1aa0e3d946e951b104da7ca6ab275 Type: {enabled: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), desktop_version: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, enabledOverriddenForCurrentDesktopVersion: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, languages_whitelisted: \[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)]?, languages_blacklisted: \[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)]?, enabledOverriddenForCurrentLanguage: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, overridesRemote: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, params: any?} + +Type: {enabled: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), languages_whitelisted: \[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)]?, languages_blacklisted: \[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)]?, enabledOverriddenForCurrentLanguage: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, overridesRemote: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, overriddenByEnv: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, params: any?} + +> > > > > > > Add env variable FEATURE_FLAGS for overriding flags with env + +#### Properties + +* `enabled` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +* `desktop_version` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `enabledOverriddenForCurrentDesktopVersion` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `languages_whitelisted` **\[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)]?** +* `languages_blacklisted` **\[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)]?** +* `enabledOverriddenForCurrentLanguage` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `overridesRemote` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `overriddenByEnv` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `params` **any?** + +#### enabled + +If false, the feature is disabled (for every languages regardless of the languages_whitelisted option) + +Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean) + +#### desktop_version + +The `desktop_version` option is desktop specific, it has no impact on mobile + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### desktop_version + +If set, the feature is disabled when the desktop app version does not satisfies this param + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### desktop_version + +It should respect the semantic versioning specification (https://semver.org/) + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### enabledOverriddenForCurrentDesktopVersion + +Whether the remote value of `enabled` was overriden due to `desktop_version` + +Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean) + +#### languages_whitelisted + +You can optionnally use one of the two following options (languages_whitelisted and languages_blacklisted) (Only implemented on mobile for now) + +Type: \[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)] + +#### languages_whitelisted + +List of languages for which the feature is enabled (it will be disabled by default for all of the others) + +Type: \[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)] + +#### languages_blacklisted + +List of languages for which the feature is disabled + +Type: \[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)] + +#### enabledOverriddenForCurrentLanguage + +Whether the remote value of `enabled` was overriden due to `languages_whitelisted` or `languages_blacklisted` + +Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean) + +#### overridesRemote + +Whether the remote value of this object was overriden locally + +Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean) + +#### overriddenByEnv + +Whether the remote value of this object was overriden by an environment variable + +Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean) + +#### params + +Additional params + +Type: any + +### DefaultFeatures + +Type: any + +### LedgerScriptParams + +Type: {firmware: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), firmwareKey: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), delete: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, deleteKey: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, targetId: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number))?, hash: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), perso: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)} + +#### Properties + +* `firmware` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `firmwareKey` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `delete` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `deleteKey` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `targetId` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number))?** +* `hash` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `perso` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** + +### DeviceInfo + +Type: {mcuVersion: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), version: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), majMin: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), targetId: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)), isBootloader: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), isRecoveryMode: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, isOSU: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), providerName: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), managerAllowed: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), pinValidated: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), seVersion: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, mcuBlVersion: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, mcuTargetId: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?, seTargetId: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?, onboarded: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, hasDevFirmware: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, bootloaderVersion: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, hardwareVersion: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?, languageId: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?} + +#### Properties + +* `mcuVersion` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `version` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `majMin` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `targetId` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number))** +* `isBootloader` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +* `isRecoveryMode` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `isOSU` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +* `providerName` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `managerAllowed` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +* `pinValidated` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +* `seVersion` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `mcuBlVersion` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `mcuTargetId` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** +* `seTargetId` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** +* `onboarded` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `hasDevFirmware` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `bootloaderVersion` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `hardwareVersion` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** +* `languageId` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** + +### DeviceModelInfo + +Type: {modelId: DeviceModelId, deviceInfo: [DeviceInfo](#deviceinfo), apps: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<{name: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), version: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)}>} + +#### Properties + +* `modelId` **DeviceModelId** +* `deviceInfo` **[DeviceInfo](#deviceinfo)** +* `apps` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<{name: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), version: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)}>** + +### DeviceVersion + +Type: {id: Id, name: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), display_name: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), target_id: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), description: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), device: Id, providers: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, mcu_versions: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, se_firmware_final_versions: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, osu_versions: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, application_versions: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, date_creation: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), date_last_modified: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)} + +#### Properties + +* `id` **Id** +* `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `display_name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `target_id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `description` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `device` **Id** +* `providers` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `mcu_versions` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `se_firmware_final_versions` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `osu_versions` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `application_versions` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `date_creation` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `date_last_modified` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** + +### McuVersion + +Type: {id: Id, mcu: Id, name: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), description: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), providers: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, from_bootloader_version: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), device_versions: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, se_firmware_final_versions: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, date_creation: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), date_last_modified: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)} + +#### Properties + +* `id` **Id** +* `mcu` **Id** +* `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `description` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `providers` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `from_bootloader_version` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `device_versions` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `se_firmware_final_versions` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `date_creation` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `date_last_modified` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** + +### SeedPhraseType + +### FirmwareInfo + +Type: {isBootloader: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), rawVersion: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), targetId: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), seVersion: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, mcuVersion: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), mcuBlVersion: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, mcuTargetId: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?, seTargetId: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?, flags: [Buffer](https://nodejs.org/api/buffer.html), bootloaderVersion: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, hardwareVersion: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?, languageId: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?} + +#### Properties + +* `isBootloader` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +* `rawVersion` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `targetId` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** +* `seVersion` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `mcuVersion` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `mcuBlVersion` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `mcuTargetId` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** +* `seTargetId` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** +* `flags` **[Buffer](https://nodejs.org/api/buffer.html)** +* `bootloaderVersion` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `hardwareVersion` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** +* `languageId` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** + +### OsuFirmware + +Type: any + +### FinalFirmware + +Type: any + +### FirmwareUpdateContext + +Type: {osu: [OsuFirmware](#osufirmware), final: [FinalFirmware](#finalfirmware), shouldFlashMCU: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)} + +#### Properties + +* `osu` **[OsuFirmware](#osufirmware)** +* `final` **[FinalFirmware](#finalfirmware)** +* `shouldFlashMCU` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** + +### ApplicationVersion + +Type: {id: Id, name: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), version: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), app: Id, description: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), display_name: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), icon: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), notes: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), perso: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), hash: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), firmware: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), firmware_key: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), delete: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), delete_key: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), device_versions: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, se_firmware_final_versions: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, providers: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, date_creation: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), date_last_modified: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), type: [AppType](#apptype)?, bytes: ([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), warning: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), currency: CryptoCurrency?} + +#### Properties + +* `id` **Id** +* `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `version` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `app` **Id** +* `description` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `display_name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `icon` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `notes` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `perso` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `hash` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `firmware` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `firmware_key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `delete` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `delete_key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `device_versions` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `se_firmware_final_versions` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `providers` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `date_creation` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `date_last_modified` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `type` **[AppType](#apptype)?** +* `bytes` **([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `warning` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `currency` **CryptoCurrency?** + +### Application + +Type: {id: Id, name: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), description: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), application_versions: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[ApplicationVersion](#applicationversion)>, providers: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, category: Id, publisher: (Id | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), date_creation: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), date_last_modified: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), currencyId: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), authorName: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), supportURL: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), contactURL: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), sourceURL: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), compatibleWalletsJSON: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))} + +#### Properties + +* `id` **Id** +* `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `description` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `application_versions` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[ApplicationVersion](#applicationversion)>** +* `providers` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `category` **Id** +* `publisher` **(Id | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `date_creation` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `date_last_modified` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `currencyId` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `authorName` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `supportURL` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `contactURL` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `sourceURL` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `compatibleWalletsJSON` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** + +### AppType + +### App + +App is higher level on top of Application and ApplicationVersion +with all fields Live needs and in normalized form (but still serializable) + +Type: {id: Id, name: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), displayName: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), version: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), currencyId: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), description: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), dateModified: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), icon: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), authorName: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), supportURL: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), contactURL: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), sourceURL: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), compatibleWallets: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<{name: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), url: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))}>, hash: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), perso: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), firmware: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), firmware_key: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), delete: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), delete_key: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), dependencies: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>, bytes: ([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), warning: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), indexOfMarketCap: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), isDevTools: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), type: [AppType](#apptype)} + +#### Properties + +* `id` **Id** +* `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `displayName` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `version` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `currencyId` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `description` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `dateModified` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `icon` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `authorName` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `supportURL` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `contactURL` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `sourceURL` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `compatibleWallets` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<{name: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), url: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))}>** +* `hash` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `perso` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `firmware` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `firmware_key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `delete` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `delete_key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `dependencies` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** +* `bytes` **([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `warning` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `indexOfMarketCap` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** +* `isDevTools` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +* `type` **[AppType](#apptype)** + +### Category + +Type: {id: Id, name: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), description: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), providers: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, applications: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\, date_creation: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), date_last_modified: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)} + +#### Properties + +* `id` **Id** +* `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `description` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `providers` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `applications` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** +* `date_creation` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `date_last_modified` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** + +### SocketEvent + +Type: ({type: `"bulk-progress"`, progress: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), index: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), total: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)} | {type: `"result"`, payload: any} | {type: `"warning"`, message: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)} | {type: `"device-permission-requested"`, wording: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)} | {type: `"device-permission-granted"`} | {type: `"exchange-before"`, nonce: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), apdu: [Buffer](https://nodejs.org/api/buffer.html)} | {type: `"exchange"`, nonce: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), apdu: [Buffer](https://nodejs.org/api/buffer.html), data: [Buffer](https://nodejs.org/api/buffer.html), status: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)} | {type: `"opened"`} | {type: `"closed"`}) + +### NFTStandard + +Type: (`"ERC721"` | `"ERC1155"`) + +### NFTMediaSize + +Type: (`"preview"` | `"big"` | `"original"`) + +### NFTMedias + +Type: Record<[NFTMediaSize](#nftmediasize), {uri: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), mediaType: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)}> + +### NFTMetadata + +Type: {tokenName: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null), nftName: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null), medias: [NFTMedias](#nftmedias), description: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null), properties: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\>, links: Record<[NFTMetadataLinksProviders](#nftmetadatalinksproviders), [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>} + +#### Properties + +* `tokenName` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null)** +* `nftName` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null)** +* `medias` **[NFTMedias](#nftmedias)** +* `description` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null)** +* `properties` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\>** +* `links` **Record<[NFTMetadataLinksProviders](#nftmetadatalinksproviders), [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** + +### NFTCollectionMetadata + +Type: {tokenName: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null)} + +#### Properties + +* `tokenName` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null)** + +### ProtoNFT + +Type: {id: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), tokenId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), amount: BigNumber, contract: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), standard: [NFTStandard](#nftstandard), currencyId: CryptoCurrencyIds, metadata: [NFTMetadata](#nftmetadata)?} + +#### Properties + +* `id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `tokenId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `amount` **BigNumber** +* `contract` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `standard` **[NFTStandard](#nftstandard)** +* `currencyId` **CryptoCurrencyIds** +* `metadata` **[NFTMetadata](#nftmetadata)?** + +### ProtoNFTRaw + +Type: any + +### NFT + +Type: any + +### NFTMetadataLinksProviders + +Type: (`"opensea"` | `"rarible"` | `"explorer"`) + +### NFTMetadataResponse + +Type: {status: (`200` | `404` | `500`), result: ({contract: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), tokenId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), tokenName: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null), nftName: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null), medias: [NFTMedias](#nftmedias), description: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null), properties: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\>, links: Record<[NFTMetadataLinksProviders](#nftmetadatalinksproviders), [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>} | null)?} + +#### Properties + +* `status` **(`200` | `404` | `500`)** +* `result` **({contract: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), tokenId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), tokenName: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null), nftName: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null), medias: [NFTMedias](#nftmedias), description: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null), properties: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\>, links: Record<[NFTMetadataLinksProviders](#nftmetadatalinksproviders), [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>} | null)?** + +### NFTCollectionMetadataResponse + +Type: {status: (`200` | `404` | `500`), result: ({contract: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), tokenName: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null)} | null)?} + +#### Properties + +* `status` **(`200` | `404` | `500`)** +* `result` **({contract: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), tokenName: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null)} | null)?** + +### FloorPrice + +Type: {ticker: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), value: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)} + +#### Properties + +* `ticker` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `value` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** + +### OperationType + +Type: (`"IN"` | `"OUT"` | `"NONE"` | `"CREATE"` | `"REVEAL"` | `"DELEGATE"` | `"UNDELEGATE"` | `"REDELEGATE"` | `"REWARD"` | `"FEES"` | `"FREEZE"` | `"UNFREEZE"` | `"VOTE"` | `"REWARD_PAYOUT"` | `"BOND"` | `"UNBOND"` | `"WITHDRAW_UNBONDED"` | `"SET_CONTROLLER"` | `"SLASH"` | `"NOMINATE"` | `"CHILL"` | `"SUPPLY"` | `"REDEEM"` | `"APPROVE"` | `"OPT_IN"` | `"OPT_OUT"` | `"LOCK"` | `"UNLOCK"` | `"WITHDRAW"` | `"REVOKE"` | `"ACTIVATE"` | `"REGISTER"` | `"NFT_IN"` | `"NFT_OUT"`) + +### Operation + +Type: {id: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), hash: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), type: [OperationType](#operationtype), value: BigNumber, fee: BigNumber, senders: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>, recipients: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>, blockHeight: ([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), blockHash: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), transactionSequenceNumber: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?, accountId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), standard: ([NFTStandard](#nftstandard) | [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))?, operator: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, contract: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, tokenId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, date: [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date), extra: Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), any>, hasFailed: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, subOperations: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Operation](#operation)>?, internalOperations: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Operation](#operation)>?, nftOperations: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Operation](#operation)>?} + +#### Properties + +* `id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `hash` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `type` **[OperationType](#operationtype)** +* `value` **BigNumber** +* `fee` **BigNumber** +* `senders` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** +* `recipients` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** +* `blockHeight` **([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `blockHash` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `transactionSequenceNumber` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** +* `accountId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `standard` **([NFTStandard](#nftstandard) | [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))?** +* `operator` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `contract` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `tokenId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `date` **[Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date)** +* `extra` **Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), any>** +* `hasFailed` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `subOperations` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Operation](#operation)>?** +* `internalOperations` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Operation](#operation)>?** +* `nftOperations` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Operation](#operation)>?** + +### OperationRaw + +Type: {id: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), hash: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), type: [OperationType](#operationtype), value: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), fee: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), senders: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>, recipients: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>, blockHeight: ([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), blockHash: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), transactionSequenceNumber: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?, accountId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), hasFailed: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, standard: ([NFTStandard](#nftstandard) | [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))?, operator: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, contract: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, tokenId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, date: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), extra: Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), any>, subOperations: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[OperationRaw](#operationraw)>?, internalOperations: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[OperationRaw](#operationraw)>?, nftOperations: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[OperationRaw](#operationraw)>?} + +#### Properties + +* `id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `hash` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `type` **[OperationType](#operationtype)** +* `value` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `fee` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `senders` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** +* `recipients` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** +* `blockHeight` **([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `blockHash` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `transactionSequenceNumber` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** +* `accountId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `hasFailed` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `standard` **([NFTStandard](#nftstandard) | [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))?** +* `operator` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `contract` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `tokenId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `date` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `extra` **Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), any>** +* `subOperations` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[OperationRaw](#operationraw)>?** +* `internalOperations` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[OperationRaw](#operationraw)>?** +* `nftOperations` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[OperationRaw](#operationraw)>?** + +### DailyOperationsSection + +Type: {day: [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date), data: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Operation](#operation)>} + +#### Properties + +* `day` **[Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date)** +* `data` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Operation](#operation)>** + +### DailyOperations + +Type: {sections: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[DailyOperationsSection](#dailyoperationssection)>, completed: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)} + +#### Properties + +* `sections` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[DailyOperationsSection](#dailyoperationssection)>** +* `completed` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** + +### PaginationConfig + +A pagination config holds the user's pagination state +this is a state that usually should leave during the app lifecycle, but is not persisted +it drives the number of operations to poll in accounts +when a user paginate more, the number should accordingly be incremented +The UI should manage scrolling ahead of time (e.g. if 30 ops is displayed and UI have pages of 20 ops, the UI can already request to poll 70 ops so it have 2 pages in advance) +The UI must always do max() to keep the increasing the counter and not going back to lower value: that optim the sync to not recompute things too much + +Type: {operationsPerAccountId: Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)>?, operations: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?} + +#### Properties + +* `operationsPerAccountId` **Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)>?** +* `operations` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** + +### SyncConfig + +Type: {paginationConfig: [PaginationConfig](#paginationconfig), withoutSynchronize: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, blacklistedTokenIds: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>?} + +#### Properties + +* `paginationConfig` **[PaginationConfig](#paginationconfig)** +* `withoutSynchronize` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `blacklistedTokenIds` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>?** + +### BalanceHistoryData + +Type: {date: [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date), value: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)} + +#### Properties + +* `date` **[Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date)** +* `value` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** + +### BalanceHistory + +Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[BalanceHistoryData](#balancehistorydata)> + +### BalanceHistoryRaw + +Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<\[[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)]> + +### BalanceHistoryWithCountervalue + +Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\ + +### ValueChange + +Type: {percentage: ([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)), value: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)} + +#### Properties + +* `percentage` **([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** +* `value` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** + +### AccountPortfolio + +Type: {history: [BalanceHistoryWithCountervalue](#balancehistorywithcountervalue), countervalueAvailable: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), countervalueReceiveSum: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), countervalueSendSum: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), cryptoChange: [ValueChange](#valuechange), countervalueChange: [ValueChange](#valuechange)} + +#### Properties + +* `history` **[BalanceHistoryWithCountervalue](#balancehistorywithcountervalue)** +* `countervalueAvailable` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +* `countervalueReceiveSum` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** +* `countervalueSendSum` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** +* `cryptoChange` **[ValueChange](#valuechange)** +* `countervalueChange` **[ValueChange](#valuechange)** + +### CurrencyPortfolio + +Type: {history: [BalanceHistoryWithCountervalue](#balancehistorywithcountervalue), countervalueAvailable: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), histories: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[BalanceHistoryWithCountervalue](#balancehistorywithcountervalue)>, accounts: [AccountLikeArray](#accountlikearray), cryptoChange: [ValueChange](#valuechange), range: [PortfolioRange](#portfoliorange), countervalueChange: [ValueChange](#valuechange)} + +#### Properties + +* `history` **[BalanceHistoryWithCountervalue](#balancehistorywithcountervalue)** +* `countervalueAvailable` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +* `histories` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[BalanceHistoryWithCountervalue](#balancehistorywithcountervalue)>** +* `accounts` **[AccountLikeArray](#accountlikearray)** +* `cryptoChange` **[ValueChange](#valuechange)** +* `range` **[PortfolioRange](#portfoliorange)** +* `countervalueChange` **[ValueChange](#valuechange)** + +### Portfolio + +Type: {balanceHistory: [BalanceHistory](#balancehistory), balanceAvailable: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), availableAccounts: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[AccountLike](#accountlike)>, unavailableCurrencies: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<(CryptoCurrency | TokenCurrency)>, accounts: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[AccountLike](#accountlike)>, range: [PortfolioRange](#portfoliorange), histories: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[BalanceHistoryWithCountervalue](#balancehistorywithcountervalue)>, countervalueReceiveSum: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), countervalueSendSum: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), countervalueChange: [ValueChange](#valuechange)} + +#### Properties + +* `balanceHistory` **[BalanceHistory](#balancehistory)** +* `balanceAvailable` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +* `availableAccounts` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[AccountLike](#accountlike)>** +* `unavailableCurrencies` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<(CryptoCurrency | TokenCurrency)>** +* `accounts` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[AccountLike](#accountlike)>** +* `range` **[PortfolioRange](#portfoliorange)** +* `histories` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[BalanceHistoryWithCountervalue](#balancehistorywithcountervalue)>** +* `countervalueReceiveSum` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** +* `countervalueSendSum` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** +* `countervalueChange` **[ValueChange](#valuechange)** + +### PortfolioRangeConfig + +Type: {count: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?, granularityId: GranularityId, startOf: function (arg0: [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date)): [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date), increment: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)} + +#### Properties + +* `count` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** +* `granularityId` **GranularityId** +* `startOf` **function (arg0: [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date)): [Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date)** +* `increment` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** + +### PortfolioRange + +Type: (`"all"` | `"year"` | `"month"` | `"week"` | `"day"`) + +### AssetsDistribution + +Type: {isAvailable: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), list: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<{currency: (CryptoCurrency | TokenCurrency), accounts: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[AccountLike](#accountlike)>, distribution: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), amount: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), countervalue: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)}>, showFirst: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), sum: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)} + +#### Properties + +* `isAvailable` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +* `list` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<{currency: (CryptoCurrency | TokenCurrency), accounts: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[AccountLike](#accountlike)>, distribution: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), amount: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), countervalue: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)}>** +* `showFirst` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** +* `sum` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** + +### PostOnboardingActionId + +Unique identifier of a post onboarding action. + +### PostOnboardingAction + +All necessary information for complete integration of a post onboarding +action. + +Type: {id: [PostOnboardingActionId](#postonboardingactionid), featureFlagId: [FeatureId](#featureid)?, navigationParams: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\?, Icon: function (props: {size: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), color: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)}): any, title: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), description: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), tagLabel: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, actionCompletedPopupLabel: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), actionCompletedHubTitle: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), startEvent: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, startEventProperties: any?} + +#### Properties + +* `id` **[PostOnboardingActionId](#postonboardingactionid)** +* `featureFlagId` **[FeatureId](#featureid)?** +* `navigationParams` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\?** +* `Icon` **function (props: {size: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), color: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)}): any** +* `title` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `description` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `tagLabel` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `actionCompletedPopupLabel` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `actionCompletedHubTitle` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `startEvent` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `startEventProperties` **any?** + +#### featureFlagId + +If this action is linked to a feature that is enabled by a feature flag, +use this property to identify the feature flag. + +Type: [FeatureId](#featureid) + +#### navigationParams + +Navigation params when the user presses the button for this action + +* In LLM, this will be used like this: + `navigation.navigate(...navigationParams)` +* In LLD, this will be used like this: + `history.push(...navigationParams)` + +Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\ + +#### Icon + +Icon displayed for this action in the post onboarding hub. + +Type: function (props: {size: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), color: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)}): any + +#### title + +Title displayed for this action in the post onboarding hub. + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### description + +Description displayed for this action in the post onboarding hub. + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### tagLabel + +Tag displayed for this action in the post onboarding hub. + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### actionCompletedPopupLabel + +Will appear in an success alert at the bottom of the post-onboarding hub +after completing this action. + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### actionCompletedHubTitle + +Will be used as a title success alert at the bottom of the post-onboarding +hub after completing this action. + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### startEvent + +Event that will be dispatched when starting this action. + +Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) + +#### startEventProperties + +Event properties that will be dispatched when starting this action. + +Type: any + +### PostOnboardingActionState + +State of a post onboarding action. + +Type: {completed: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)} + +#### Properties + +* `completed` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** + +#### completed + +Whether the user has completed this action. This will be reflected in the +UI of the post onboarding hub. + +Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean) + +### PostOnboardingState + +To be used for a redux reducer. +Keeps all necessary information about the state of the post onboarding hub +and can be persisted in storage. + +Type: {deviceModelId: (DeviceModelId | null), walletEntryPointDismissed: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), actionsToComplete: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[PostOnboardingActionId](#postonboardingactionid)>, actionsCompleted: any, lastActionCompleted: ([PostOnboardingActionId](#postonboardingactionid) | null)} + +#### Properties + +* `deviceModelId` **(DeviceModelId | null)** +* `walletEntryPointDismissed` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +* `actionsToComplete` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[PostOnboardingActionId](#postonboardingactionid)>** +* `actionsCompleted` **any** +* `lastActionCompleted` **([PostOnboardingActionId](#postonboardingactionid) | null)** + +#### deviceModelId + +Model Id of the device for which the post onboarding was started. + +Type: (DeviceModelId | null) + +#### walletEntryPointDismissed + +Did the user dismiss the post onboarding entry point on the wallet page. + +Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean) + +#### actionsToComplete + +List of all actions that have to be completed in this post onboarding +(whether they are completed or). +This is used to populate the list of actions in the post onboarding hub UI. + +Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[PostOnboardingActionId](#postonboardingactionid)> + +#### actionsCompleted + +"completed" state for each action. + +Type: any + +#### lastActionCompleted + +Last action that the user has completed. + +This is used to display potentially different content in the post +onboarding hub UI depending on the last action that was completed. + +Type: ([PostOnboardingActionId](#postonboardingactionid) | null) + +### PostOnboardingHubState + +Digest of the store & list of actions into something directly consumable +by UI. (All UI data will be in there). + +Type: {deviceModelId: (DeviceModelId | null), lastActionCompleted: ([PostOnboardingAction](#postonboardingaction) | null), actionsState: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\} + +#### Properties + +* `deviceModelId` **(DeviceModelId | null)** +* `lastActionCompleted` **([PostOnboardingAction](#postonboardingaction) | null)** +* `actionsState` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)\** + +### SwapOperation + +Type: {provider: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), swapId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), status: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), receiverAccountId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), tokenId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, operationId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), fromAmount: BigNumber, toAmount: BigNumber} + +#### Properties + +* `provider` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `swapId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `status` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `receiverAccountId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `tokenId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `operationId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `fromAmount` **BigNumber** +* `toAmount` **BigNumber** + +### SwapOperationRaw + +Type: {provider: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), swapId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), status: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), receiverAccountId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), tokenId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?, operationId: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), fromAmount: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), toAmount: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)} + +#### Properties + +* `provider` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `swapId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `status` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `receiverAccountId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `tokenId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** +* `operationId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `fromAmount` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `toAmount` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** + +### SignedOperation + +Type: {operation: [Operation](#operation), signature: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), signatureRaw: Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), any>?, expirationDate: ([Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))} + +#### Properties + +* `operation` **[Operation](#operation)** +* `signature` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `signatureRaw` **Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), any>?** +* `expirationDate` **([Date](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** + +### SignedOperationRaw + +Type: {operation: [OperationRaw](#operationraw), signature: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), signatureRaw: Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), any>?, expirationDate: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))} + +#### Properties + +* `operation` **[OperationRaw](#operationraw)** +* `signature` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `signatureRaw` **Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), any>?** +* `expirationDate` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** + +### SignOperationEvent + +Type: ({type: `"device-streaming"`, progress: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), index: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), total: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)} | {type: `"device-signature-requested"`} | {type: `"device-signature-granted"`} | {type: `"signed"`, signedOperation: [SignedOperation](#signedoperation)}) + +### SignOperationEventRaw + +Type: ({type: `"device-streaming"`, progress: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), index: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number), total: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)} | {type: `"device-signature-requested"`} | {type: `"device-signature-granted"`} | {type: `"signed"`, signedOperation: [SignedOperationRaw](#signedoperationraw)}) + +### TransactionCommon + +Transaction is a generic object that holds all state for all transactions +there are generic fields and coin specific fields. That's why almost all fields are optionals + +Type: {amount: BigNumber, recipient: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), useAllAmount: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, subAccountId: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))?, feesStrategy: (`"slow"` | `"medium"` | `"fast"` | `"custom"` | null)?} + +#### Properties + +* `amount` **BigNumber** +* `recipient` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `useAllAmount` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `subAccountId` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))?** +* `feesStrategy` **(`"slow"` | `"medium"` | `"fast"` | `"custom"` | null)?** + +### TransactionCommonRaw + +Type: {amount: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), recipient: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), useAllAmount: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, subAccountId: ([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))?, feesStrategy: (`"slow"` | `"medium"` | `"fast"` | `"custom"` | null)?} + +#### Properties + +* `amount` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `recipient` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `useAllAmount` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `subAccountId` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))?** +* `feesStrategy` **(`"slow"` | `"medium"` | `"fast"` | `"custom"` | null)?** + +### FeeStrategy + +User can have 3 differents choice for their fee +Most of the time mid is low \* 1.25 and high is low \* 1.5 +They are some exception as eth that got his own meter + +Type: {amount: BigNumber, displayedAmount: BigNumber?, label: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), unit: Unit?} + +#### Properties + +* `amount` **BigNumber** +* `displayedAmount` **BigNumber?** +* `label` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `unit` **Unit?** + +### TransactionStatusCommon + +TransactionStatus is a view of Transaction with general info to be used on the UI and status info. + +Type: {errors: Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), [Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error)>, warnings: Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), [Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error)>, estimatedFees: BigNumber, amount: BigNumber, totalSpent: BigNumber, recipientIsReadOnly: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?} + +#### Properties + +* `errors` **Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), [Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error)>** +* `warnings` **Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), [Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error)>** +* `estimatedFees` **BigNumber** +* `amount` **BigNumber** +* `totalSpent` **BigNumber** +* `recipientIsReadOnly` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** + +### TransactionStatusCommonRaw + +Type: {errors: Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>, warnings: Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>, estimatedFees: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), amount: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), totalSpent: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), useAllAmount: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?, recipientIsReadOnly: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?} + +#### Properties + +* `errors` **Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** +* `warnings` **Record<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** +* `estimatedFees` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `amount` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `totalSpent` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +* `useAllAmount` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** +* `recipientIsReadOnly` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** diff --git a/libs/ledgerjs/packages/types-live/src/feature.ts b/libs/ledgerjs/packages/types-live/src/feature.ts index 035000286c66..5170a969398b 100644 --- a/libs/ledgerjs/packages/types-live/src/feature.ts +++ b/libs/ledgerjs/packages/types-live/src/feature.ts @@ -49,6 +49,8 @@ export type Feature = { enabledOverriddenForCurrentLanguage?: boolean; /** Whether the remote value of this object was overriden locally */ overridesRemote?: boolean; + /** Whether the remote value of this object was overriden by an environment variable */ + overriddenByEnv?: boolean; /** Additional params */ params?: any; };