From 185d4a36c61769ea6eb41b4820672c9806584389 Mon Sep 17 00:00:00 2001 From: "@greweb" Date: Tue, 10 May 2022 09:27:30 +0100 Subject: [PATCH 1/3] Simplify a lot "tools" and remove its dep to live-common (#1944) --- tools/package.json | 22 +- tools/src/demos/Currencies/index.js | 190 - tools/src/demos/apps/index.js | 261 - tools/src/demos/assets/index.js | 255 - tools/src/demos/bridgestream/index.js | 157 - tools/src/demos/bridgetest/index.js | 116 - tools/src/demos/countervalues/CurrentRate.js | 30 - tools/src/demos/countervalues/GraphRate.js | 58 - tools/src/demos/countervalues/index.js | 137 - tools/src/demos/derivations/CurrencySelect.js | 57 - tools/src/demos/derivations/index.js | 167 - tools/src/demos/erc20/TokenSelect.js | 52 - tools/src/demos/explorers/index.js | 168 - tools/src/demos/index.js | 24 - tools/src/demos/logsviewer/index.js | 109 +- tools/src/demos/manager/DeviceStorage.js | 94 - tools/src/demos/manager/images/blue.png | Bin 3307 -> 0 bytes tools/src/demos/manager/images/nanoS.png | Bin 14739 -> 0 bytes tools/src/demos/manager/images/nanoX.png | Bin 13057 -> 0 bytes tools/src/demos/manager/index.js | 806 -- tools/src/demos/mcu-repair/index.js | 184 - tools/src/demos/qrledger/index.js | 199 - tools/src/demos/qrstreambenchmark/index.js | 201 - tools/src/index.js | 5 - tools/src/live-common-setup.js | 143 - tools/yarn.lock | 11556 ++++------------ 26 files changed, 2971 insertions(+), 12020 deletions(-) delete mode 100644 tools/src/demos/Currencies/index.js delete mode 100644 tools/src/demos/apps/index.js delete mode 100644 tools/src/demos/assets/index.js delete mode 100644 tools/src/demos/bridgestream/index.js delete mode 100644 tools/src/demos/bridgetest/index.js delete mode 100644 tools/src/demos/countervalues/CurrentRate.js delete mode 100644 tools/src/demos/countervalues/GraphRate.js delete mode 100644 tools/src/demos/countervalues/index.js delete mode 100644 tools/src/demos/derivations/CurrencySelect.js delete mode 100644 tools/src/demos/derivations/index.js delete mode 100644 tools/src/demos/erc20/TokenSelect.js delete mode 100644 tools/src/demos/explorers/index.js delete mode 100644 tools/src/demos/manager/DeviceStorage.js delete mode 100644 tools/src/demos/manager/images/blue.png delete mode 100644 tools/src/demos/manager/images/nanoS.png delete mode 100644 tools/src/demos/manager/images/nanoX.png delete mode 100644 tools/src/demos/manager/index.js delete mode 100644 tools/src/demos/mcu-repair/index.js delete mode 100644 tools/src/demos/qrledger/index.js delete mode 100644 tools/src/demos/qrstreambenchmark/index.js delete mode 100644 tools/src/live-common-setup.js diff --git a/tools/package.json b/tools/package.json index 233fc38337..13a0f21fde 100644 --- a/tools/package.json +++ b/tools/package.json @@ -3,36 +3,18 @@ "version": "0.1.0", "private": true, "dependencies": { - "@ledgerhq/hw-transport": "^6.7.0", - "@ledgerhq/hw-transport-http": "^6.7.0", - "@ledgerhq/hw-transport-u2f": "^5.36.0-deprecated", - "@ledgerhq/hw-transport-web-ble": "^6.7.0", - "@ledgerhq/hw-transport-webhid": "^6.7.0", - "@ledgerhq/hw-transport-webusb": "^6.7.0", - "@ledgerhq/live-common": "^22.0.0", - "@material-ui/core": "^4.11.3", - "babel-polyfill": "^6.26.0", "bignumber.js": "^9.0.1", "flow-bin": "^0.145.0", - "qrcode": "^1.4.2", + "invariant": "^2.2.4", "react": "^17.0.2", "react-dom": "^17.0.2", "react-inspector": "^4.0.1", - "react-redux": "^7.2.4", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", "react-scripts": "3.4.3", - "react-select": "^3.2.0", + "react-select": "^5.3.2", "react-table": "^6.11.4", - "react-tooltip": "^3.11.5", - "redux": "^4.1.0", - "redux-devtools-extension": "^2.13.9", - "redux-thunk": "^2.2.0", - "reselect": "^4.0.0", - "rxjs": "^6.6.7", "styled-components": "^4.4.0", - "timeago.js": "^4.0.2", - "victory": "^34.3.12", "webpack": "4.42" }, "scripts": { diff --git a/tools/src/demos/Currencies/index.js b/tools/src/demos/Currencies/index.js deleted file mode 100644 index 9f16a7a196..0000000000 --- a/tools/src/demos/Currencies/index.js +++ /dev/null @@ -1,190 +0,0 @@ -// @flow -import React, { Component } from "react"; -import styled from "styled-components"; -import { listCryptoCurrencies } from "@ledgerhq/live-common/lib/currencies"; -import { getCryptoCurrencyIcon } from "@ledgerhq/live-common/lib/react"; -import { - blockchainBaseURL, - hasCurrencyExplorer, -} from "@ledgerhq/live-common/lib/api/Ledger"; -import api from "@ledgerhq/live-common/lib/countervalues/api"; - -const Section = styled.div` - padding: 20px 40px; -`; - -const Intro = styled.div` - margin-top: 20px; - padding: 0 40px; - font-size: 16px; -`; - -const SectionHeader = styled.h1``; - -const CryptoList = styled.div` - display: flex; - flex-direction: column; -`; - -const CryptoCell = styled.div` - color: ${(p) => p.color}; - display: flex; - flex-direction: row; - align-items: center; - margin: 10px; -`; - -const Problem = styled.div` - width: 50px; - color: red; - text-decoration: underline; -`; -const NoProblem = styled.div` - width: 50px; - color: green; -`; - -const CryptoName = styled.div` - padding: 6px; - font-size: 14px; -`; - -const CryptoInfo = styled.div` - padding: 6px; - font-size: 14px; - color: #999; - flex: 1; -`; - -const AltIcon = styled.div` - font-size: 24px; -`; - -const IconWrapper = styled.div` - color: ${(p) => p.color}; - background-color: ${(p) => p.bg}; - border-radius: 8px; - display: flex; - overflow: hidden; - flex-direction: column; - justify-content: center; - align-items: center; - width: ${(p) => p.size}px; - height: ${(p) => p.size}px; - margin-right: 10px; -`; - -class Crypto extends Component<*> { - render() { - const { crypto } = this.props; - const Icon = getCryptoCurrencyIcon(crypto); - const validationErrors = [ - Icon ? null : "icon is missing", - crypto.family === "bitcoin" && !crypto.bitcoinLikeInfo - ? "bitcoin family coins must provide bitcoinLikeInfo" - : null, - crypto.family === "ethereum" && !crypto.ethereumLikeInfo - ? "ethereum family coins must provide ethereumLikeInfo" - : null, - crypto.units.length === 0 - ? "at least one unit must be provided in units" - : null, - ].filter((o) => o); - return ( - - {validationErrors.length ? ( - KO - ) : ( - OK - )} - - {Icon ? : {crypto.ticker}} - - - {Icon ? : {crypto.ticker}} - - - {crypto.name} ({crypto.ticker}) - - - {[ - "#" + crypto.id + "(" + crypto.coinType + ")", - "belongs to " + crypto.family + " family", - crypto.isTestnetFor && - "is testnet of '" + crypto.isTestnetFor + "'", - crypto.supportsSegwit && "supports segwit", - crypto.forkedFrom && "forked " + crypto.forkedFrom, - crypto.managerAppName && - "on Manager '" + crypto.managerAppName + "'", - crypto.ledgerExplorerId && - "ledger explorer '" + crypto.ledgerExplorerId + "'", - crypto.blockAvgTime && "blockAvgTime=" + crypto.blockAvgTime, - crypto.scheme && "scheme=" + crypto.scheme, - crypto.bitcoinLikeInfo && - "bitcoinLikeInfo=" + JSON.stringify(crypto.bitcoinLikeInfo), - crypto.ethereumLikeInfo && - "ethereumLikeInfo=" + JSON.stringify(crypto.ethereumLikeInfo), - "units are " + - crypto.units - .map((u) => u.code + "(^" + u.magnitude + ")") - .join(" "), - hasCurrencyExplorer(crypto) - ? "ledger explorer is " + blockchainBaseURL(crypto) - : "doesn't have ledger explorer", - ] - .filter((o) => o) - .join(", ")} - - - ); - } -} - -class Currencies extends Component<*, *> { - static demo = { - title: "Currencies", - url: "/currencies", - }; - - state = { - tickers: [], - }; - - async componentDidMount() { - const tickers = await api.fetchMarketcapTickers(); - this.setState({ tickers }); - } - - render() { - const { tickers } = this.state; - const all = listCryptoCurrencies(true); - const available = tickers - .map((ticker) => all.find((a) => a.ticker === ticker)) - .filter(Boolean); - const unavailable = all.filter((a) => !available.includes(a)); - return ( -
- - This shows @ledgerhq/live-common database (Disclaimer: - regardless if a given crypto-asset is supported) - -
- Crypto assets - - {available.map((a) => ( - - ))} - - no countervalues yet - - {unavailable.map((a) => ( - - ))} - -
-
- ); - } -} - -export default Currencies; diff --git a/tools/src/demos/apps/index.js b/tools/src/demos/apps/index.js deleted file mode 100644 index 029c22c783..0000000000 --- a/tools/src/demos/apps/index.js +++ /dev/null @@ -1,261 +0,0 @@ -// @flow -import React, { useState, useEffect } from "react"; -import styled from "styled-components"; -import Select from "react-select"; -import type { CryptoCurrency } from "@ledgerhq/live-common/lib/types"; -import { listCryptoCurrencies } from "@ledgerhq/live-common/lib/currencies"; -import { setEnv } from "@ledgerhq/live-common/lib/env"; -import { getCryptoCurrencyIcon } from "@ledgerhq/live-common/lib/react"; -import manager from "@ledgerhq/live-common/lib/manager"; - -const coins = listCryptoCurrencies(); - -const Container = styled.div` - width: 600px; - margin: 20px auto; -`; - -const Section = styled.div` - padding: 20px 0; -`; - -const SectionHead = styled.div` - font-size: 18px; - padding: 20px 0; - color: ${(p) => (p.error ? "#ea2e49" : "#6490f1")}; -`; - -const SectionBody = styled.div` - display: flex; - flex-direction: row; - flex-wrap: wrap; -`; - -const CoinContainer = styled.div` - width: 80px; - padding: 4px; -`; - -const IconWrapper = styled.div` - color: ${(p) => p.color}; - background-color: ${(p) => p.bg}; - border-radius: 8px; - display: flex; - overflow: hidden; - flex-direction: column; - justify-content: center; - align-items: center; - width: ${(p) => p.size}px; - height: ${(p) => p.size}px; - margin-right: 10px; -`; - -const CryptoName = styled.div` - padding: 6px; - font-size: 12px; - font-weight: bold; -`; - -const AltIcon = styled.div` - font-size: 24px; -`; - -const CoinPreview = ({ coin }: { coin: CryptoCurrency }) => { - const text = coin.managerAppName; - const Icon = getCryptoCurrencyIcon(coin); - return ( - - - {Icon ? : {coin.ticker}} - - {text} - - ); -}; - -const AppPreview = ({ app }: *) => { - return ( - - - {`${app.name} ${app.version}`} - - ); -}; - -const AppWithCoinPreview = ({ app }: *) => { - return ; -}; - -const choices = [ - { - label: "Nano S 1.6.1", - deviceInfo: { - version: "1.6.1", - mcuVersion: "1.12", - majMin: "1.6", - providerName: null, - targetId: 823132164, - isOSU: false, - isBootloader: false, - managerAllowed: false, - pinValidated: true, - }, - }, - { - label: "Nano S 1.5.5", - deviceInfo: { - version: "1.5.5", - mcuVersion: "1.7", - majMin: "1.5", - providerName: null, - targetId: 823132164, - isOSU: false, - isBootloader: false, - managerAllowed: false, - pinValidated: true, - }, - }, - { - label: "Nano X 1.2.4-5", - deviceInfo: { - version: "1.2.4-5", - mcuVersion: "2.10", - majMin: "1.2", - providerName: null, - targetId: 855638020, - isOSU: false, - isBootloader: false, - managerAllowed: false, - pinValidated: true, - }, - }, -]; - -const providers = [ - { label: "production (provider 1)", value: 1 }, - { label: "beta (provider 4)", value: 4 }, -]; - -const Apps = () => { - const [apps, setApps] = useState([]); - const [choice, setChoice] = useState(choices[0]); - const [provider, setProvider] = useState(providers[0]); - - useEffect(() => { - setApps([]); - setEnv("FORCE_PROVIDER", provider.value); - manager.getAppsList(choice.deviceInfo).then(setApps); - }, [choice, provider]); - - const unknownApps = []; - const knownAppsWithCoin = []; - const deprecatedApps = []; - apps.forEach((app) => { - const coin = coins.find((c) => app.name === c.managerAppName); - if (coin) { - knownAppsWithCoin.push({ - app, - coin, - }); - } else if (!manager.canHandleInstall(app)) { - deprecatedApps.push(app); - } else { - unknownApps.push(app); - } - }); - const notFoundCryptoCurrencies = - apps.length === 0 - ? [] - : coins.filter( - (c) => - c.managerAppName && - !apps.find((app) => app.name === c.managerAppName) - ); - - return ( - -

Manager apps for device

- - c.label} - getOptionValue={(c) => c.label} - /> - - {apps.length === 0 ? ( -
- Loading... -
- ) : null} - - {notFoundCryptoCurrencies.length > 0 ? ( -
- - {"can't find a Manager app for these crypto-currencies"} - - - {notFoundCryptoCurrencies.map((coin) => ( - - ))} - -
- ) : null} - {unknownApps.length > 0 ? ( -
- - {"can't find crypto-currencies corresponding to these Manager apps"} - - - {unknownApps.map((app) => ( - - ))} - -
- ) : null} - {knownAppsWithCoin.length > 0 ? ( -
- Apps correctly recognized by Live - - {knownAppsWithCoin.map((all) => ( - - ))} - -
- ) : null} - {deprecatedApps.length > 0 ? ( -
- - {"Apps recognized as "} - deprecated - {" by Live (no install available)"} - - - {deprecatedApps.map((app) => ( - - ))} - -
- ) : null} -
- ); -}; - -Apps.demo = { - title: "Apps", - url: "/apps", - hidden: true, -}; - -export default Apps; diff --git a/tools/src/demos/assets/index.js b/tools/src/demos/assets/index.js deleted file mode 100644 index b51162f6f7..0000000000 --- a/tools/src/demos/assets/index.js +++ /dev/null @@ -1,255 +0,0 @@ -// @flow -import React, { Component, useCallback, useState, useMemo } from "react"; -import ReactTable from "react-table"; -import { BigNumber } from "bignumber.js"; -import { - listTokens, - listCryptoCurrencies, - isCurrencySupported, - getCryptoCurrencyById, - getFiatCurrencyByTicker, - useCurrenciesByMarketcap, - useMarketcapTickers, - formatCurrencyUnit, -} from "@ledgerhq/live-common/lib/currencies"; - -const usdFiat = getFiatCurrencyByTicker("USD"); -const bitcoin = getCryptoCurrencyById("bitcoin"); -const ethereum = getCryptoCurrencyById("ethereum"); - -const DownloadData = ({ data }) => { - const onClick = useCallback(() => { - const csv = [ - ["id", "name", "ticker", "type", "live", "url", "USD", "magnitude"], - ] - .concat( - data.map((d) => [ - d.id, - d.name, - d.ticker, - d.type, - d.livesupport, - d.type === "TokenCurrency" - ? `https://etherscan.io/address/${d.contractAddress}` - : "", - d.usdValue, - d.units[0].magnitude, - ]) - ) - .map((row) => - row.map((cell) => String(cell).replace(/[,\n\r]/g, "")).join(",") - ) - .join("\n"); - const dataUrl = `data:text/csv,` + encodeURIComponent(csv); - window.open(dataUrl); - }, [data]); - - return ; -}; - -const columns = [ - { - Header: "Live?", - width: 80, - accessor: "livesupport", - }, - { - Header: "Delisted?", - width: 80, - accessor: "delisted", - }, - { - Header: "type", - width: 120, - accessor: "typeText", - }, - { - Header: "id", - width: 120, - accessor: "id", - }, - { - Header: "Name", - accessor: "name", - }, - { - Header: "Ticker", - accessor: "ticker", - width: 100, - }, - { - Header: "Magnitude", - id: "magnitude", - accessor: (o) => o.units[0].magnitude, - width: 100, - }, - { - Header: "extra", - id: "extra", - accessor: (token) => - token.type === "TokenCurrency" ? ( - - {token.contractAddress} - - ) : ( - "coinType=" + token.coinType - ), - }, - { - id: "countervalue", - Header: (p) => { - const data = p.data.map((d) => d._original); - const supported = data.filter((d) => d.countervalueStatus === "yes"); - const withExchange = data.filter((d) => d.exchange); - const percentageSupport = supported.length / data.length; - const realPercentageSupport = withExchange.length / data.length; - return ( -
- countervalue -
- {supported.length} have marketcap ( - {Math.floor(percentageSupport * 1000) / 10}%) -
-
- {withExchange.length} supported ( - {Math.floor(realPercentageSupport * 1000) / 10}%) -
- -
- ); - }, - accessor: "countervalueText", - }, - { - Header: "USD", - accessor: "usdValue", - width: 100, - }, -]; - -const counterpartFor = (c) => - c === bitcoin || c === ethereum - ? usdFiat - : c.type === "CryptoCurrency" - ? bitcoin - : ethereum; - -const Assets = () => { - const tokens = listTokens({ withDelisted: true }); - const currencies = listCryptoCurrencies(); - const all = useMemo(() => currencies.concat(tokens), [tokens, currencies]); - const tickers = useMarketcapTickers() || []; - const [rates] = useState({}); - const byMarketcap = useCurrenciesByMarketcap(all); - const data = byMarketcap.map((t) => { - let countervalueStatus = "no"; - let loading = false; - let exchange; - let formatted = ""; - let usdValue = ""; - if (t.disableCountervalue) { - countervalueStatus = "disabled"; - } else if (tickers.includes(t.ticker)) { - countervalueStatus = "yes"; - const counter = counterpartFor(t); - if (rates[counter.ticker]) { - const ratePerExchange = (rates[counter.ticker] || {})[t.ticker] || {}; - exchange = Object.keys(ratePerExchange)[0]; - if (exchange) { - const latest = ratePerExchange[exchange].latest || 0; - - if (counter !== usdFiat) { - if (rates[usdFiat.ticker]) { - const intermRatePerExchange = - (rates[usdFiat.ticker] || {})[counter.ticker] || {}; - const intermExchange = Object.keys(intermRatePerExchange)[0]; - if (intermExchange) { - const intermLatest = - intermRatePerExchange[intermExchange].latest || 0; - usdValue = formatCurrencyUnit( - usdFiat.units[0], - BigNumber(latest) - .times(intermLatest) - .times(10 ** t.units[0].magnitude) - ); - } - } - } else { - usdValue = formatCurrencyUnit( - counter.units[0], - BigNumber(latest).times(10 ** t.units[0].magnitude) - ); - } - - formatted = formatCurrencyUnit( - counter.units[0], - BigNumber(latest).times(10 ** t.units[0].magnitude), - { - showCode: true, - } - ); - } - } else { - loading = true; - } - } - const countervalueText = - countervalueStatus !== "yes" - ? countervalueStatus - : loading - ? "..." - : exchange - ? exchange + " @ " + formatted - : "no exchange found"; - const livesupport = - t.type === "TokenCurrency" || isCurrencySupported(t) ? "yes" : "no"; - return { - ...t, - typeText: - t.type === "TokenCurrency" - ? "token on " + t.parentCurrency.name - : "coin", - countervalueStatus, - countervalueText, - exchange, - loading, - livesupport, - delisted: t.delisted ? "yes" : "no", - usdValue, - }; - }); - - return ( -
- -
- ); -}; - -export default class Demo extends Component<{}> { - static demo = { - title: "Assets", - url: "/assets", - }; - render() { - return ; - } -} diff --git a/tools/src/demos/bridgestream/index.js b/tools/src/demos/bridgestream/index.js deleted file mode 100644 index fd489ac79b..0000000000 --- a/tools/src/demos/bridgestream/index.js +++ /dev/null @@ -1,157 +0,0 @@ -// @flow -import React, { PureComponent, Component } from "react"; -import qrcode from "qrcode"; - -type Props = { - data: string, - errorCorrectionLevel: string, - size: number, - style?: * -}; - -class QRCode extends PureComponent { - static defaultProps = { - size: 200, - errorCorrectionLevel: "Q" - }; - - componentDidMount() { - this.drawQRCode(); - } - - componentDidUpdate() { - this.drawQRCode(); - } - - _canvas = null; - - drawQRCode() { - const { data, size, errorCorrectionLevel } = this.props; - qrcode.toCanvas(this._canvas, data, { - width: size, - margin: 0, - errorCorrectionLevel, - color: { - light: "#ffffff" - } - }); - } - - render() { - return (this._canvas = n)} />; - } -} - -const checkArrayString = (m: mixed): string[] => { - if (!Array.isArray(m)) throw new Error("JSON is not an array"); - const res = []; - for (const item of m) { - if (typeof item === "string") { - res.push(item); - } - } - return res; -}; - -const parseData = (inputValue: string): string[] => - checkArrayString( - JSON.parse(atob(inputValue.trim().replace("BRIDGESTREAM_DATA=", ""))) - ); - -class BridgeStream extends Component<*, *> { - state = { - data: null, - error: null - }; - - input = React.createRef(); - - gifIt = () => { - const qrcodes = document.getElementById("qrcodes"); - if (!qrcodes) throw new Error("no qrcodes"); - - const gif = new window.GIF({ - workers: 2, - quality: 10 - }); - - const els = [...qrcodes.children]; - - els.forEach(canvas => { - gif.addFrame(canvas, { delay: 200 }); - }); - - gif.on("finished", blob => { - window.open(URL.createObjectURL(blob)); - }); - - gif.render(); - }; - - onSubmit = (evt: *) => { - evt.preventDefault(); - const input = this.input.current; - if (input) { - try { - const data = parseData(input.value); - this.setState({ data, error: null }); - setTimeout(this.gifIt, 1000); - } catch (error) { - this.setState({ data: null, error }); - } - } - }; - - render() { - const { error, data } = this.state; - if (data) { - return ( -
- {data.map((data, i) => ( - - ))} -
- ); - } - return ( -
-
- - -
-
{error ? String(error) : null}
-
- ); - } -} - -// $FlowFixMe -BridgeStream.demo = { - title: "BridgeStream", - url: "/bridgestream", - hidden: true -}; - -export default BridgeStream; diff --git a/tools/src/demos/bridgetest/index.js b/tools/src/demos/bridgetest/index.js deleted file mode 100644 index ba61d7a58a..0000000000 --- a/tools/src/demos/bridgetest/index.js +++ /dev/null @@ -1,116 +0,0 @@ -// @flow -import React, { useState, useEffect } from "react"; -import Eth from "@ledgerhq/hw-app-eth"; -import WebSocketTransport from "@ledgerhq/hw-transport-http/lib/WebSocketTransport"; - -const bridgeURL = "ws://localhost:8435"; - -function check() { - return WebSocketTransport.check(bridgeURL); -} - -function checkLoop(isCancelled) { - return check().catch(async () => { - await delay(500); - if (isCancelled()) return; - return checkLoop(isCancelled); - }); -} - -function delay(ms) { - return new Promise((success) => setTimeout(success, ms)); -} - -async function verifyAddress(onAddress) { - const transport = await WebSocketTransport.open(bridgeURL); - try { - const eth = new Eth(transport); - const { address } = await eth.getAddress("44'/60'/0'/0/0"); - onAddress(address); - // trigger verification - await eth.getAddress("44'/60'/0'/0/0", true); - } finally { - await transport.close(); - } -} - -const initialState = { - opened: false, - available: false, - address: "", -}; - -const BridgeTest = () => { - const [{ opened, address, available }, setState] = useState(initialState); - - useEffect(() => { - if (!opened) return; - let cancelled = false; - - checkLoop(() => cancelled) - .then(() => { - if (cancelled) return; - setState({ - ...initialState, - opened: true, - available: true, - }); - return verifyAddress((address) => - setState({ - opened: true, - available: true, - address, - }) - ).then(() => { - setState(initialState); - }); - }) - .catch((error) => { - alert("" + error); - console.error(error); - setState(initialState); - }); - - return () => { - cancelled = true; - }; - }, [opened]); - - return ( -
- {opened ? ( - !available ? ( -
- Connecting...{" "} - -
- ) : !address ? ( -
Loading...
- ) : ( -
{"Verify on your device the address: " + address}
- ) - ) : ( - - setState({ - ...initialState, - opened: true, - }) - } - href={`ledgerlive://bridge?appName=Ethereum&origin=${window.location.host}`} - > - Open with Ledger Live - - )} -
- ); -}; - -// $FlowFixMe -BridgeTest.demo = { - title: "Bridge test", - url: "/bridgetest", - hidden: true, -}; - -export default BridgeTest; diff --git a/tools/src/demos/countervalues/CurrentRate.js b/tools/src/demos/countervalues/CurrentRate.js deleted file mode 100644 index ab79fb5a25..0000000000 --- a/tools/src/demos/countervalues/CurrentRate.js +++ /dev/null @@ -1,30 +0,0 @@ -// @flow -import React from "react"; -import BigNumber from "bignumber.js"; -import type { Currency } from "@ledgerhq/live-common/lib/types"; -import { formatCurrencyUnit } from "@ledgerhq/live-common/lib/currencies"; -import { useCalculate } from "@ledgerhq/live-common/lib/countervalues/react"; - -const CurrentRate = ({ from, to }: { from: Currency, to: Currency }) => { - const value = 10 ** from.units[0].magnitude; - const countervalue = useCalculate({ from, to, value, disableRounding: true }); - return ( - - - {formatCurrencyUnit(from.units[0], BigNumber(value), { - showCode: true, - })} - - {" = "} - - {countervalue - ? formatCurrencyUnit(to.units[0], BigNumber(countervalue), { - showCode: true, - }) - : "???"} - - - ); -}; - -export default CurrentRate; diff --git a/tools/src/demos/countervalues/GraphRate.js b/tools/src/demos/countervalues/GraphRate.js deleted file mode 100644 index 3ee8822a86..0000000000 --- a/tools/src/demos/countervalues/GraphRate.js +++ /dev/null @@ -1,58 +0,0 @@ -// @flow -import React from "react"; -import { VictoryLine } from "victory"; -import type { Currency } from "@ledgerhq/live-common/lib/types"; -import { useCalculateMany } from "@ledgerhq/live-common/lib/countervalues/react"; - -type Props = { - from: Currency, - to: Currency, - count: number, - increment: number, - width: number, - height: number, -}; - -const GraphRate = ({ from, to, width, height, count, increment }: Props) => { - const inputData = []; - let t = Date.now() - count * increment; - const value = 10 ** from.units[0].magnitude; - for (let i = 0; i < count; i++) { - const date = new Date(t); - inputData.push({ date, value }); - t += increment; - } - const outputData = useCalculateMany(inputData, { - from, - to, - disableRounding: true, - }); - - const data = inputData.map(({ date }, i) => ({ - date, - value: outputData[i] || 0, - })); - - return ( - - - - ); -}; - -export default GraphRate; diff --git a/tools/src/demos/countervalues/index.js b/tools/src/demos/countervalues/index.js deleted file mode 100644 index 2690913fb1..0000000000 --- a/tools/src/demos/countervalues/index.js +++ /dev/null @@ -1,137 +0,0 @@ -// @flow -import React, { useState, useEffect } from "react"; -import { - listSupportedCurrencies, - getFiatCurrencyByTicker, -} from "@ledgerhq/live-common/lib/currencies"; -import type { - CountervaluesSettings, - TrackingPair, -} from "@ledgerhq/live-common/lib/countervalues/types"; -import { importCountervalues } from "@ledgerhq/live-common/lib/countervalues/logic"; -import { - Countervalues, - useCountervaluesPolling, - useCountervaluesExport, -} from "@ledgerhq/live-common/lib/countervalues/react"; -import CurrentRate from "./CurrentRate"; -import GraphRate from "./GraphRate"; - -const Row = ({ pair }: { pair: TrackingPair }) => { - return ( -
- {" 1Y"} - - {" 1M"} - - {" 7D"} - - {" 1D"} - - -
- ); -}; - -const App = ({ userSettings }: { userSettings: CountervaluesSettings }) => { - const polling = useCountervaluesPolling(); - return ( -
-
- {polling.pending ? "loading..." : "loaded."} - - -
-
- {userSettings.trackingPairs.map((pair) => ( - - ))} -
-
- ); -}; - -const initialUserSettings = { - // TODO we could make this dynamic / saved in LocalStorage - trackingPairs: listSupportedCurrencies() - .filter((c) => !c.isTestnetFor) - .map((from) => ({ - from, - // this to be dynamical (actually let user conf the from-to) - to: getFiatCurrencyByTicker("USD"), - // this to be dynamical (we want to challenge change of this over time!) - startDate: new Date(Date.now() - 365 * 24 * 60 * 60 * 1000), - })), - autofillGaps: true, -}; - -const LS_KEY = "countervalues"; -let initialCountervalues; -try { - const json = localStorage.getItem(LS_KEY); - if (json) { - initialCountervalues = importCountervalues( - JSON.parse(json), - initialUserSettings - ); - } -} catch (e) { - console.warn(e); -} - -const HookChanges = () => { - const e = useCountervaluesExport(); - useEffect(() => { - localStorage.setItem(LS_KEY, JSON.stringify(e)); - }, [e]); - return null; -}; - -const Demo = () => { - const [userSettings, setUserSettings] = useState(initialUserSettings); - - return ( - - - - - ); -}; - -Demo.demo = { - title: "Countervalues", - url: "/countervalues", -}; - -export default Demo; diff --git a/tools/src/demos/derivations/CurrencySelect.js b/tools/src/demos/derivations/CurrencySelect.js deleted file mode 100644 index 5ed1a72a1f..0000000000 --- a/tools/src/demos/derivations/CurrencySelect.js +++ /dev/null @@ -1,57 +0,0 @@ -// @flow -import React, { Component } from "react"; -import MenuItem from "@material-ui/core/MenuItem"; -import Select from "@material-ui/core/Select"; -import { getCryptoCurrencyIcon } from "@ledgerhq/live-common/lib/react"; -import type { Currency, CryptoCurrency } from "@ledgerhq/live-common/lib/types"; - -function inferCrypto(currency: Currency): ?CryptoCurrency { - if ("coinType" in currency) { - return currency; - } -} - -class CurrencySelect extends Component<{ - value: ?Currency, - currencies: Currency[], - onChange: (?Currency) => void -}> { - handleChange = (e: *) => { - this.props.onChange(this.props.currencies[e.target.value]); - }; - render() { - const { currencies, value } = this.props; - const i = currencies.indexOf(value); - return ( - - ); - } -} - -export default CurrencySelect; diff --git a/tools/src/demos/derivations/index.js b/tools/src/demos/derivations/index.js deleted file mode 100644 index 64fdcce47d..0000000000 --- a/tools/src/demos/derivations/index.js +++ /dev/null @@ -1,167 +0,0 @@ -// @flow -import React, { Component } from "react"; -import TransportWebUSB from "@ledgerhq/hw-transport-webusb"; -import styled from "styled-components"; -import { listCryptoCurrencies } from "@ledgerhq/live-common/lib/currencies"; -import { getAccountPlaceholderName } from "@ledgerhq/live-common/lib/account"; -import getAddress from "@ledgerhq/live-common/lib/hw/getAddress"; -import { - getDerivationModesForCurrency, - getDerivationScheme, - runDerivationScheme, - isIterableDerivationMode, - derivationModeSupportsIndex -} from "@ledgerhq/live-common/lib/derivation"; -import CurrencySelect from "./CurrencySelect"; - -const Main = styled.div` - padding: 40px; -`; - -let transportGlobalP; -let queue = Promise.resolve(); -const execInQueue = (job: () => Promise) => { - const p = queue.then(job); - queue = p; - return queue; -}; - -class CurrencyDerivation extends Component<*, *> { - state = { - address: "", - path: "", - error: null - }; - - componentDidMount() { - this.getAddress(); - } - - getAddress = (verify: boolean = false) => - execInQueue(async () => { - const { derivationMode, currency, index: account } = this.props; - try { - const p = transportGlobalP || TransportWebUSB.create(); - transportGlobalP = p; - const transport = await p; - const { address, path } = await getAddress(transport, { - currency, - path: runDerivationScheme( - getDerivationScheme({ currency, derivationMode }), - currency, - { account } - ), - derivationMode, - verify - }); - this.setState({ address, path }); - } catch (error) { - this.setState({ error }); - } - }); - - onVerify = () => this.getAddress(true); - - render() { - const { currency, derivationMode, index } = this.props; - const { address, path, error } = this.state; - - return ( -
- - {getAccountPlaceholderName({ currency, derivationMode, index })} - - {error ? ( - - {String(error.message || error)} - - - ) : path ? ( - - - {`${path}: ${address}`} - - - - ) : null} -
- ); - } -} - -class CurrencyDerivations extends Component<*, *> { - state = { - total: 1 - }; - - more = () => this.setState(({ total }) => ({ total: total + 1 })); - - render() { - const { currency } = this.props; - const { total } = this.state; - - return ( -
- {Array(total) - .fill(null) - .map((_, index) => - getDerivationModesForCurrency(currency) - .filter(mode => derivationModeSupportsIndex(mode, index)) - .filter(mode => index === 0 || isIterableDerivationMode(mode)) - .map(derivationMode => ( - - )) - )} - -
- ); - } -} - -class Derivations extends Component<*, *> { - static demo = { - title: "Derivations", - url: "/derivations", - hidden: true - }; - - state = { - currency: null - }; - - onChangeCurrency = (currency: *) => { - this.setState({ currency }); - }; - - render() { - const { currency } = this.state; - const currencies = listCryptoCurrencies(true).sort((a, b) => - a.family === b.family - ? a.name.localeCompare(b.name) - : a.family.localeCompare(b.family) - ); - return ( -
-
- -
- {currency ? ( - - ) : null} -
- ); - } -} - -export default Derivations; diff --git a/tools/src/demos/erc20/TokenSelect.js b/tools/src/demos/erc20/TokenSelect.js deleted file mode 100644 index 10d9fb3284..0000000000 --- a/tools/src/demos/erc20/TokenSelect.js +++ /dev/null @@ -1,52 +0,0 @@ -// @flow -import React, { useState, useEffect } from "react"; -import Select from "react-select"; -import { listTokens } from "@ledgerhq/live-common/lib/currencies"; -import type { TokenCurrency } from "@ledgerhq/live-common/lib/types"; -import api from "@ledgerhq/live-common/lib/countervalues/api"; - -let tickers; -const tickersP = api.fetchMarketcapTickers().then((t) => { - tickers = t; - return t; -}); - -const rank = (token) => { - const i = tickers.indexOf(token.ticker); - if (i === -1) return Infinity; - return i; -}; - -const getSortedTokens = () => { - let tokens = listTokens(); - if (!tickers) return tokens; - return tokens.slice(0).sort((a, b) => rank(a) - rank(b)); -}; - -type Props = { - value: ?TokenCurrency, - onChange: (?TokenCurrency) => void, -}; - -const TokenSelect = ({ value, onChange }: Props) => { - const [tokens, setTokens] = useState(getSortedTokens); - - useEffect(() => { - if (!tickers) { - tickersP.then(() => setTokens(getSortedTokens())); - } - }, []); - - return ( -