Unverified Commit 0d1e1ffb authored by Hanwen Cheng's avatar Hanwen Cheng Committed by GitHub

fix: add PayloadDetailsCards back (#682)

* update dependencies

* make lint happy

* Update networkMetadata.ts

* debug (ci): run the CI

* debug (ci): run the CI w PR trigger

* debug (ci): run the CI w PR trigger to check if it skips previous builds

* complete first integration

* stash

* remove debug

* add error handling functions if there is a parsing error

* fix: update metadata

* fix: add Buffer

* fix: decoding

* fix: update polkadot packages

* fix: update tests

* Update unit.spec.ts to use DOT methods

* Use updated method for decoders.spec

* fix: lint

* test CI test by removing testVisible for qr out of view

* fix: revert qr visibilty, update jest packages

* fix: update babel-jest, remove gensis-hash, block-hash

* fix: fix visibility to exists in detox

* fix: comment in previously failing tests

* fix: pass CI e2e tests

* fix: potential folly mismatch in versions fixed

* fix: currentFocusedField fixed

* fix: LogBox for intest

* style: legibility

makes
- address in PathCard to not look as if it's cut in the end
- payload label text to contrast with its background

* Update src/constants/logo.ts
Co-authored-by: David's avatarDavid <dvdplm@gmail.com>

* fix: Cannot update component bug

* fix: lint, component refresh bug, recomment passing tests

* fix: revert changes

* fix: transaction is previewed before the key is unlocked and invoked (#732)

* fix: preview transaction before signing

* test: fix tests to pass extra screen

* fix: lint types

* test: substrate-nets transfer tests reloaded with modern valid payload

* fix: remove animation causing obscure memory leak on infinite alert state
Co-authored-by: Denis_P's avatarDenis P <denis.pisarev@parity.io>
Co-authored-by: default avatartarikgul <tarik@parity.io>
Co-authored-by: default avataremostov <32168567+emostov@users.noreply.github.com>
Co-authored-by: default avatargoldsteinsveta <sveta@parity.io>
Co-authored-by: default avatarTarik Gul <47201679+TarikGul@users.noreply.github.com>
Co-authored-by: David's avatarDavid <dvdplm@gmail.com>
Co-authored-by: default avatarSlesarew <33295157+Slesarew@users.noreply.github.com>
parent 00528910
Pipeline #127599 failed with stages
in 2 minutes and 42 seconds
This diff is collapsed.
......@@ -5,7 +5,7 @@ require_relative '../node_modules/react-native/scripts/react_native_pods'
def add_flipper_pods!(versions = {})
versions['Flipper'] ||= '~> 0.37.0'
versions['DoubleConversion'] ||= '1.1.7'
versions['Flipper-Folly'] ||= '~> 2.2'
versions['Flipper-Folly'] ||= '~> 2.3.0'
versions['Flipper-Glog'] ||= '0.3.6'
versions['Flipper-PeerTalk'] ||= '~> 0.0.4'
versions['Flipper-RSocket'] ||= '~> 1.1'
......
......@@ -536,6 +536,6 @@ SPEC CHECKSUMS:
Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: 149a5676f06c73884009cb0b361d542a25248470
PODFILE CHECKSUM: 472c8493cf6b01acd584d56fed7308384514150a
COCOAPODS: 1.10.1
This diff is collapsed.
......@@ -36,12 +36,11 @@
"e2e": "yarn e2e:ios && yarn e2e:android"
},
"dependencies": {
"@polkadot/api": "1.26.1",
"@polkadot/api": "3.9.3",
"@polkadot/metadata": "^3.9.3",
"@polkadot/reactnative-identicon": "0.53.1",
"@polkadot/types": "1.26.1",
"@polkadot/types-known": "1.26.1",
"@polkadot/util": "2.11.1",
"@polkadot/util-crypto": "2.11.1",
"@polkadot/util": "5.4.4",
"@polkadot/util-crypto": "5.4.4",
"@react-native-community/async-storage": "^1.11.0",
"@react-native-community/masked-view": "^0.1.6",
"@react-native-community/netinfo": "^5.9.3",
......@@ -49,13 +48,16 @@
"@react-navigation/stack": "^5.7.1",
"bignumber.js": "^9.0.0",
"hoist-non-react-statics": "^3.3.0",
"jest-circus": "26.5.2",
"jest-environment-node": "26.6.2",
"mocha": "6.0.0",
"node-libs-react-native": "^1.0.3",
"react": "^16.11.0",
"react-native": "0.63.4",
"react-native-camera": "^3.21.0",
"react-native-elements": "^1.2.6",
"react-native-gesture-handler": "^1.6.0",
"react-native-keyboard-aware-scroll-view": "^0.9.1",
"react-native-keyboard-aware-scroll-view": "0.9.3",
"react-native-markdown-renderer": "^3.2.8",
"react-native-navbar-color": "^1.0.3",
"react-native-popup-menu": "^0.15.6",
......@@ -85,18 +87,18 @@
"@typescript-eslint/eslint-plugin": "^2.26.0",
"@typescript-eslint/parser": "^2.28.0",
"babel-eslint": "10.1.0",
"babel-jest": "^25.5.1",
"babel-jest": "26.6.3",
"babel-plugin-module-resolver": "^4.0.0",
"babel-plugin-rewrite-require": "^1.14.5",
"babel-plugin-tester": "^9.0.1",
"detox": "18.6.0",
"detox": "17.14.9",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.1",
"eslint-import-resolver-typescript": "^2.0.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-react-hooks": "^3.0.0",
"jest": "^25.4.0",
"jest": "26.6.3",
"jetifier": "^1.6.5",
"metro-react-native-babel-preset": "^0.59.0",
"prettier": "2.0.2",
......@@ -104,7 +106,7 @@
"react-native-typescript-transformer": "^1.2.13",
"react-test-renderer": "16.13.1",
"reactotron-react-native": "5.0.0",
"ts-jest": "^25.4.0",
"ts-jest": "^26.5.1",
"typescript": "^3.9.7"
},
"resolutions": {
......@@ -133,7 +135,7 @@
"build": "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..",
"type": "android.emulator",
"device": {
"avdName": "Nexus_5_API_28"
"avdName": "Pixel_3a_API_30_x86"
}
},
"android.emu.release": {
......@@ -141,7 +143,7 @@
"build": "cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..",
"type": "android.emulator",
"device": {
"avdName": "Nexus_5_API_28"
"avdName": "Pixel_3a_API_30_x86"
}
}
},
......
import { Buffer } from 'buffer';
global.Buffer = Buffer;
process.browser = true;
......@@ -29,6 +29,10 @@ import {
ScreenStack
} from './screens';
import {
useRegistriesStore,
RegistriesContext
} from 'stores/RegistriesContext';
import { useNetworksContext, NetworksContext } from 'stores/NetworkContext';
import { useScannerContext, ScannerContext } from 'stores/ScannerContext';
import { useAccountContext, AccountsContext } from 'stores/AccountsContext';
......@@ -48,7 +52,7 @@ export default function App(props: AppProps): React.ReactElement {
getLaunchArgs(props);
NavigationBar.setColor(colors.background.os);
if (global.inTest) {
console.disableYellowBox = true;
LogBox.ignoreAllLogs(true);
} else if (__DEV__) {
LogBox.ignoreLogs([
'Warning: componentWillReceiveProps',
......@@ -66,6 +70,7 @@ export default function App(props: AppProps): React.ReactElement {
const networkContext = useNetworksContext();
const accountsContext = useAccountContext();
const scannerContext = useScannerContext();
const registriesContext = useRegistriesStore();
const renderStacks = (): React.ReactElement => {
if (globalContext.dataLoaded) {
......@@ -92,20 +97,24 @@ export default function App(props: AppProps): React.ReactElement {
<NetworksContext.Provider value={networkContext}>
<AccountsContext.Provider value={accountsContext}>
<ScannerContext.Provider value={scannerContext}>
<GlobalStateContext.Provider value={globalContext}>
<AlertStateContext.Provider value={alertContext}>
<SeedRefsContext.Provider value={seedRefContext}>
<MenuProvider backHandler={true}>
<StatusBar
barStyle="light-content"
backgroundColor={colors.background.app}
/>
<CustomAlert />
<NavigationContainer>{renderStacks()}</NavigationContainer>
</MenuProvider>
</SeedRefsContext.Provider>
</AlertStateContext.Provider>
</GlobalStateContext.Provider>
<RegistriesContext.Provider value={registriesContext}>
<GlobalStateContext.Provider value={globalContext}>
<AlertStateContext.Provider value={alertContext}>
<SeedRefsContext.Provider value={seedRefContext}>
<MenuProvider backHandler={true}>
<StatusBar
barStyle="light-content"
backgroundColor={colors.background.app}
/>
<CustomAlert />
<NavigationContainer>
{renderStacks()}
</NavigationContainer>
</MenuProvider>
</SeedRefsContext.Provider>
</AlertStateContext.Provider>
</GlobalStateContext.Provider>
</RegistriesContext.Provider>
</ScannerContext.Provider>
</AccountsContext.Provider>
</NetworksContext.Provider>
......
......@@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { useContext, useEffect, useMemo, useState } from 'react';
import { StyleSheet, View, Animated, Text, Easing } from 'react-native';
import { StyleSheet, View, Animated, Text } from 'react-native';
import Button from 'components/Button';
import { Action, AlertStateContext } from 'stores/alertContext';
......@@ -33,14 +33,7 @@ export default function CustomAlert(): React.ReactElement {
if (alertIndex === 0) return;
setAlertDisplay(true);
if (actions.length === 0) {
Animated.timing(animatedValue, {
duration: 1000,
easing: Easing.poly(8),
toValue: 0,
useNativeDriver: false
}).start(() => {
setAlertDisplay(false);
});
setAlertDisplay(false);
}
/* eslint-disable-next-line react-hooks/exhaustive-deps */
}, [alertIndex]);
......
......@@ -234,7 +234,7 @@ const styles = StyleSheet.create({
},
desc: {
flex: 1,
paddingLeft: 16
paddingHorizontal: 16
},
footer: {
height: 80,
......
......@@ -14,6 +14,9 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
// this file includes logos of the supported networks encoded as base64 strings. Can be used to replace requiring the `file` module in
// React Native.
export default {
ethClassic:
'data:image/png;base64,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',
......
This diff is collapsed.
......@@ -15,22 +15,24 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { GenericExtrinsicPayload } from '@polkadot/types';
import Call from '@polkadot/types/generic/Call';
import type { Call, ExtrinsicEra } from '@polkadot/types/interfaces';
import { AnyJson, AnyU8a, IExtrinsicEra, IMethod } from '@polkadot/types/types';
import { formatBalance } from '@polkadot/util';
import { decodeAddress, encodeAddress } from '@polkadot/util-crypto';
import React, { useContext, useEffect, useState } from 'react';
import { StyleSheet, Text, View, ViewStyle } from 'react-native';
import { AnyU8a, IExtrinsicEra, IMethod } from '@polkadot/types/types';
import { ExtrinsicEra } from '@polkadot/types/interfaces';
import { AlertStateContext } from 'stores/alertContext';
import { NetworksContext } from 'stores/NetworkContext';
import { RegistriesStoreState } from 'stores/RegistriesContext';
import {
RegistriesContext,
RegistriesStoreState
} from 'stores/RegistriesContext';
import colors from 'styles/colors';
import { withRegistriesStore } from 'utils/HOC';
import { shortString } from 'utils/strings';
import fontStyles from 'styles/fontStyles';
import { alertDecodeError } from 'utils/alertUtils';
import { withRegistriesStore } from 'utils/HOC';
import { shortString } from 'utils/strings';
const recodeAddress = (encodedAddress: string, prefix: number): string =>
encodeAddress(decodeAddress(encodedAddress), prefix);
......@@ -40,7 +42,7 @@ type ExtrinsicPartProps = {
label: string;
networkKey: string;
registriesStore: RegistriesStoreState;
value: AnyU8a | IMethod | IExtrinsicEra;
value: AnyJson | AnyU8a | IMethod | IExtrinsicEra;
};
const ExtrinsicPart = withRegistriesStore<ExtrinsicPartProps>(
......@@ -56,17 +58,17 @@ const ExtrinsicPart = withRegistriesStore<ExtrinsicPartProps>(
const [formattedCallArgs, setFormattedCallArgs] = useState<any>();
const [tip, setTip] = useState<string>();
const [useFallback, setUseFallBack] = useState(false);
const { getTypeRegistry } = useContext(RegistriesContext);
const { setAlert } = useContext(AlertStateContext);
const { networks, getSubstrateNetwork } = useContext(NetworksContext);
const networkParams = getSubstrateNetwork(networkKey);
const prefix = networkParams.prefix;
const typeRegistry = getTypeRegistry(networks, networkKey)!;
useEffect(() => {
if (label === 'Method' && !fallback) {
try {
const registry = registriesStore.get(networks, networkKey);
const call = registry.createType('Call', value);
const call = typeRegistry.createType('Call', value);
const methodArgs = {};
function formatArgs(
......@@ -74,10 +76,10 @@ const ExtrinsicPart = withRegistriesStore<ExtrinsicPartProps>(
callMethodArgs: any,
depth: number
): void {
const { args, meta, methodName, sectionName } = callInstance;
const { args, meta } = callInstance;
const paramArgKvArray = [];
if (!meta.args.length) {
const sectionMethod = `${sectionName}.${methodName}`;
const sectionMethod = `${call.method}.${call.section}`;
callMethodArgs[sectionMethod] = null;
return;
}
......@@ -95,7 +97,7 @@ const ExtrinsicPart = withRegistriesStore<ExtrinsicPartProps>(
) {
// encode Address and AccountId to the appropriate prefix
argument = recodeAddress(args[i].toString(), prefix);
} else if (args[i] instanceof Call) {
} else if ((args[i] as Call).section) {
argument = formatArgs(args[i] as Call, callMethodArgs, depth++); // go deeper into the nested calls
} else if (
args[i].toRawType() === 'Vec<AccountId>' ||
......@@ -108,7 +110,7 @@ const ExtrinsicPart = withRegistriesStore<ExtrinsicPartProps>(
argument = args[i].toString();
}
const param = meta.args[i].name.toString();
const sectionMethod = `${sectionName}.${methodName}`;
const sectionMethod = `${call.method}.${call.section}`;
paramArgKvArray.push([param, argument]);
callMethodArgs[sectionMethod] = paramArgKvArray;
}
......@@ -140,6 +142,7 @@ const ExtrinsicPart = withRegistriesStore<ExtrinsicPartProps>(
networkKey,
registriesStore,
setAlert,
typeRegistry,
networks
]);
......@@ -168,7 +171,7 @@ const ExtrinsicPart = withRegistriesStore<ExtrinsicPartProps>(
Immortal Era
</Text>
<Text style={{ ...styles.secondaryText, flex: 3 }}>
{value.toString()}
{value?.toString()}
</Text>
</View>
);
......@@ -249,7 +252,7 @@ const ExtrinsicPart = withRegistriesStore<ExtrinsicPartProps>(
renderTipDetails()
) : (
<Text style={styles.secondaryText}>
{useFallback ? value.toString() : value}
{useFallback ? value?.toString() : value}
</Text>
)}
</View>
......@@ -290,12 +293,7 @@ export default function PayloadDetailsCard(
<ExtrinsicPart
label="Method"
networkKey={networkKey}
value={fallback ? payload.method.toString() : payload.method}
/>
<ExtrinsicPart
label="Block Hash"
networkKey={networkKey}
value={payload.blockHash.toString()}
value={fallback ? payload.method.toHuman() : payload.method}
/>
<ExtrinsicPart
label="Era"
......@@ -312,11 +310,6 @@ export default function PayloadDetailsCard(
networkKey={networkKey}
value={payload.tip.toString()}
/>
<ExtrinsicPart
label="Genesis Hash"
networkKey={networkKey}
value={payload.genesisHash.toString()}
/>
</View>
)}
{!!signature && (
......@@ -345,6 +338,7 @@ const styles = StyleSheet.create({
label: {
...fontStyles.t_label,
backgroundColor: colors.signal.main,
color: colors.background.app,
marginBottom: 10,
paddingLeft: 8,
textAlign: 'left'
......@@ -357,6 +351,7 @@ const styles = StyleSheet.create({
},
titleText: {
...fontStyles.t_codeS,
color: colors.text.main
color: colors.text.main,
paddingHorizontal: 16
}
});
import { useContext, useEffect, useState } from 'react';
import { GenericExtrinsicPayload } from '@polkadot/types';
import { ExtrinsicPayloadLatestVersion } from 'constants/chainData';
import { NetworksContext } from 'stores/NetworkContext';
import { RegistriesContext } from 'stores/RegistriesContext';
export function usePayloadDetails(
rawPayload: Uint8Array | string | null,
networkKey: string
): [boolean, GenericExtrinsicPayload | null] {
const [payload, setPayload] = useState<GenericExtrinsicPayload | null>(null);
const [isProcessing, setIsProcessing] = useState<boolean>(false);
const { networks } = useContext(NetworksContext);
const { getTypeRegistry } = useContext(RegistriesContext);
useEffect(() => {
setIsProcessing(true);
if (getTypeRegistry === null) return;
const typeRegistry = getTypeRegistry(networks, networkKey);
if (typeRegistry === null || typeof rawPayload === 'string') {
setIsProcessing(false);
return;
} else {
try {
const extrinsicPayload = typeRegistry.createType(
'ExtrinsicPayload',
rawPayload,
{
version: ExtrinsicPayloadLatestVersion
}
);
setPayload(extrinsicPayload);
setIsProcessing(false);
} catch (e) {
//can't generate extrinsic payload, don't display.
console.log('error', e);
}
}
}, [rawPayload, networkKey, getTypeRegistry, networks]);
return [isProcessing, payload];
}
// Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { isU8a, u8aToHex } from '@polkadot/util';
import React, { useContext, useEffect, useRef } from 'react';
import { Text, View } from 'react-native';
import PayloadDetailsCard from 'modules/sign/components/PayloadDetailsCard';
import strings from 'modules/sign/strings';
import CompatibleCard from 'components/CompatibleCard';
import { SafeAreaScrollViewContainer } from 'components/SafeAreaContainer';
import testIDs from 'e2e/testIDs';
import { AccountsContext } from 'stores/AccountsContext';
import { NetworksContext } from 'stores/NetworkContext';
import { ScannerContext } from 'stores/ScannerContext';
import { FoundAccount } from 'types/identityTypes';
import { isEthereumNetworkParams } from 'types/networkTypes';
import { NavigationProps, NavigationScannerProps } from 'types/props';
import QrView from 'components/QrView';
import styles from 'modules/sign/styles';
import MessageDetailsCard from 'modules/sign/components/MessageDetailsCard';
import Separator from 'components/Separator';
import fontStyles from 'styles/fontStyles';
interface Props extends NavigationScannerProps<'SignedMessage'> {
sender: FoundAccount;
message: string;
}
export default function SignedMessage(
props: NavigationProps<'SignedMessage'>
): React.ReactElement {
const scannerStore = useContext(ScannerContext);
const { sender, message } = scannerStore.state;
const cleanup = useRef(scannerStore.cleanup);
useEffect(() => cleanup.current, [cleanup]);
if (sender === null || message === null) return <View />;
return (
<SignedMessageView
sender={sender}
message={message}
scannerStore={scannerStore}
{...props}
/>
);
}
function SignedMessageView({
sender,
message,
scannerStore
}: Props): React.ReactElement {
const accountsStore = useContext(AccountsContext);
const { signedData, isHash, dataToSign } = scannerStore.state;
const { getNetwork } = useContext(NetworksContext);
const senderNetworkParams = getNetwork(sender.networkKey);
const isEthereum = isEthereumNetworkParams(senderNetworkParams);
return (
<SafeAreaScrollViewContainer>
<Text style={styles.topTitle}>Signed Message</Text>
<Separator
shadow={true}
style={{
height: 0,
marginVertical: 20
}}
/>
<Text style={[fontStyles.h_subheading, { paddingHorizontal: 16 }]}>
{'Scan to publish'}
</Text>
<View testID={testIDs.SignedMessage.qrView}>
<QrView data={signedData} />
</View>
<CompatibleCard
titlePrefix={'from:'}
account={sender}
accountsStore={accountsStore}
/>
{!isEthereum && dataToSign ? (
<PayloadDetailsCard
description={strings.INFO_MULTI_PART}
signature={signedData.toString()}
networkKey={sender.networkKey}
/>
) : null}
<MessageDetailsCard
isHash={isHash ?? false}
message={message}
data={isU8a(dataToSign) ? u8aToHex(dataToSign) : dataToSign.toString()}
style={styles.bodyContent}
/>
</SafeAreaScrollViewContainer>
);
}
// Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
// This screen shows Tx-type payload details and asks for signing confirmation
import React, { useContext, useEffect, useRef } from 'react';
import { Text, View } from 'react-native';
import { usePayloadDetails } from 'modules/sign/hooks';
import PayloadDetailsCard from 'modules/sign/components/PayloadDetailsCard';
import strings from 'modules/sign/strings';
import { SafeAreaScrollViewContainer } from 'components/SafeAreaContainer';
import testIDs from 'e2e/testIDs';
import { AccountsContext } from 'stores/AccountsContext';
import { NetworksContext } from 'stores/NetworkContext';
import { ScannerContext } from 'stores/ScannerContext';
import { FoundAccount } from 'types/identityTypes';
import { isEthereumNetworkParams } from 'types/networkTypes';
import { NavigationProps, NavigationScannerProps } from 'types/props';
import TxDetailsCard from 'modules/sign/components/TxDetailsCard';
import CompatibleCard from 'components/CompatibleCard';
import { Transaction } from 'utils/transaction';
import styles from 'modules/sign/styles';
import Separator from 'components/Separator';
import Button from 'components/Button';
function DetailsTx({
route,
navigation
}: NavigationProps<'DetailsTx'>): React.ReactElement {
const scannerStore = useContext(ScannerContext);