Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

major: load Network from Context, enable adding Network from QR #681

Merged
merged 11 commits into from
Sep 2, 2020
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Any data transfer from or to the app happens using QR code. By doing so, the mos
- [Manage Accounts on Parity Signer](./docs/tutorials/Hierarchical-Deterministic-Key-Derivation.md)
- [Signing with MyCrypto](./docs/tutorials/MyCrypto-tutorial.md)
- [Signing with Fether](./docs/tutorials/Fether-tutorial.md)
- [Update New Network](./docs/tutorials/New-Network.md)

### Wiki

Expand Down
21 changes: 21 additions & 0 deletions docs/tutorials/New-Network.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Update Network Tutorial

Parity Signer support adding a new Substrate based network or update the existing network via QR code.

This tutorial will walk through how to add a new Rococo Network with Polkadot.js App.

## 1. Get the network metadata as QR Code

Switch to the network you want to play with on Polkadot.js app. Click `Settings` -> `MetaData`

![Network Metadata QR Code](images/Network-Metadata-QR.png)

Here we can see the chain specifications like `Network Name`, `Address Prefix`, and `Genesis Hash` etc. They are all the metaData of the network which is required by Parity Signer. The only item we could change is network color, it is used on Parity Signer to distinguish other networks.

On the right side is the QR Code we need.

Now on the Parity Signer app, click the QR scanner Button anywhere on the app, and scan this QR code, you will have the new Network added to Parity Signer. You can now create accounts under it and sign extrinsic with this network.

![Network Metadata Added on Parity Signer](images/Network-Metadata-Added.png)

Notice since the metadata is generally very big data, and currently, it is hard to sync with Parity Signer, so when signing the transactions on added networks, we cannot interpreter the extrinsic details at the moment. Please check on this [issue](https://github.com/paritytech/parity-signer/issues/457) for the update.
Binary file added docs/tutorials/images/Network-Metadata-Added.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/tutorials/images/Network-Metadata-QR.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/wiki/HDKD.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ In the v4 version, the data schema is significantly refactored in order to suppo

Furthermore, in the new Identity schema, we support hard spoon network in the Substrate network like Kusama, since the Substrate keypairs/accounts generated on Signer will decouple with network's genesisHash, but will use the path as identifier of their networks. From network genesisHash and path's meta data, the `accountId` is generated for signing.
```javascript
const networkParams = getNetwork(meta.path)
const networkParams = getSubstrateNetworkParams(meta.path)
const accountId = getAccountId(meta.address, networkParams.genesisHash)
```
Once the network is hard-spooned, users just need to update network params by scanning QR code, without requring new version of the Signer.
Expand Down
40 changes: 22 additions & 18 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
ScreenStack
} from './screens';

import { useNetworksContext, NetworksContext } from 'stores/NetworkContext';
import { useScannerContext, ScannerContext } from 'stores/ScannerContext';
import { useAccountContext, AccountsContext } from 'stores/AccountsContext';
import CustomAlert from 'components/CustomAlert';
Expand Down Expand Up @@ -62,6 +63,7 @@ export default function App(props: AppProps): React.ReactElement {
const alertContext = useAlertContext();
const globalContext: GlobalState = useGlobalStateContext();
const seedRefContext = useSeedRefStore();
const networkContext = useNetworksContext();
const accountsContext = useAccountContext();
const scannerContext = useScannerContext();

Expand All @@ -87,24 +89,26 @@ export default function App(props: AppProps): React.ReactElement {

return (
<SafeAreaProvider>
<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>
</ScannerContext.Provider>
</AccountsContext.Provider>
<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>
</ScannerContext.Provider>
</AccountsContext.Provider>
</NetworksContext.Provider>
</SafeAreaProvider>
);
}
Expand Down
10 changes: 6 additions & 4 deletions src/components/AccountCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

import React, { ReactElement } from 'react';
import React, { ReactElement, useContext } from 'react';
import { StyleSheet, Text, View, ViewStyle } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';

Expand All @@ -23,7 +23,7 @@ import Address from './Address';
import TouchableItem from './TouchableItem';
import AccountPrefixedTitle from './AccountPrefixedTitle';

import { getNetworkParams } from 'utils/identitiesUtils';
import { NetworksContext } from 'stores/NetworkContext';
import Separator from 'components/Separator';
import fontStyles from 'styles/fontStyles';
import colors from 'styles/colors';
Expand Down Expand Up @@ -66,7 +66,8 @@ export function NetworkCard({
testID?: string;
title: string;
}): ReactElement {
const networkParams = getNetworkParams(networkKey);
const { getNetwork } = useContext(NetworksContext);
const networkParams = getNetwork(networkKey ?? '');
const isDisabled = onPress === undefined;
return (
<TouchableItem testID={testID} disabled={isDisabled} onPress={onPress}>
Expand Down Expand Up @@ -120,10 +121,11 @@ export default function AccountCard({
title,
titlePrefix
}: AccountCardProps): ReactElement {
const { getNetwork } = useContext(NetworksContext);
const defaultTitle = 'No name';
const displayTitle = title.length > 0 ? title : defaultTitle;
const seedTypeDisplay = seedType || '';
const network = getNetworkParams(networkKey);
const network = getNetwork(networkKey ?? '');

return (
<TouchableItem
Expand Down
2 changes: 1 addition & 1 deletion src/components/AccountIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import FontAwesome from 'react-native-vector-icons/FontAwesome';
import colors from 'styles/colors';
import { NetworkProtocols } from 'constants/networkSpecs';
import { blockiesIcon } from 'utils/native';
import { NetworkParams, SubstrateNetworkParams } from 'types/networkSpecsTypes';
import { NetworkParams, SubstrateNetworkParams } from 'types/networkTypes';

export default function AccountIcon(props: {
address: string;
Expand Down
2 changes: 1 addition & 1 deletion src/components/AccountIconChooser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import fonts from 'styles/fonts';
import { debounce } from 'utils/debounce';
import { brainWalletAddress, substrateAddress, words } from 'utils/native';
import { constructSURI } from 'utils/suri';
import { NetworkParams, SubstrateNetworkParams } from 'types/networkSpecsTypes';
import { NetworkParams, SubstrateNetworkParams } from 'types/networkTypes';

interface IconType {
address: string;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Address.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { Text, TextStyle } from 'react-native';

import fontStyles from 'styles/fontStyles';
import { NetworkProtocols } from 'constants/networkSpecs';
import { NetworkProtocol } from 'types/networkSpecsTypes';
import { NetworkProtocol } from 'types/networkTypes';

export default function Address(props: {
address: string;
Expand Down
17 changes: 8 additions & 9 deletions src/components/DerivationNetworkSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

import React from 'react';
import React, { useContext } from 'react';
import {
Image,
Platform,
Expand All @@ -29,10 +29,8 @@ import Icon from 'react-native-vector-icons/MaterialIcons';

import TransparentBackground from './TransparentBackground';

import {
SUBSTRATE_NETWORK_LIST,
SubstrateNetworkKeys
} from 'constants/networkSpecs';
import { NetworksContext } from 'stores/NetworkContext';
import { SubstrateNetworkKeys } from 'constants/networkSpecs';
import fontStyles from 'styles/fontStyles';
import colors from 'styles/colors';

Expand All @@ -53,14 +51,14 @@ export function DerivationNetworkSelector({
networkKey: string;
setVisible: (shouldVisible: boolean) => void;
}): React.ReactElement {
const { getSubstrateNetwork } = useContext(NetworksContext);
const network = getSubstrateNetwork(networkKey);
return (
<View style={styles.body}>
<Text style={styles.label}>{ACCOUNT_NETWORK}</Text>
<Touchable onPress={(): void => setVisible(true)}>
<View style={styles.triggerWrapper}>
<Text style={styles.triggerLabel}>
{SUBSTRATE_NETWORK_LIST[networkKey].title}
</Text>
<Text style={styles.triggerLabel}>{network.title}</Text>
<Icon name="more-vert" size={25} color={colors.text.main} />
</View>
</Touchable>
Expand All @@ -77,12 +75,13 @@ export function NetworkOptions({
visible: boolean;
setVisible: (shouldVisible: boolean) => void;
}): React.ReactElement {
const { networks } = useContext(NetworksContext);
const onNetworkSelected = (networkKey: string): void => {
setNetworkKey(networkKey);
setVisible(false);
};

const menuOptions = Object.entries(SUBSTRATE_NETWORK_LIST)
const menuOptions = Array.from(networks.entries())
.filter(([networkKey]) => !excludedNetworks.includes(networkKey))
.map(([networkKey, networkParams]) => {
return (
Expand Down
28 changes: 16 additions & 12 deletions src/components/PathCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

import React, { useEffect, useState } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import AntIcon from 'react-native-vector-icons/AntDesign';

Expand All @@ -23,6 +23,7 @@ import AccountPrefixedTitle from './AccountPrefixedTitle';
import Address from './Address';
import TouchableItem from './TouchableItem';

import { NetworksContext } from 'stores/NetworkContext';
import Separator from 'components/Separator';
import {
defaultNetworkKey,
Expand All @@ -34,9 +35,8 @@ import fontStyles from 'styles/fontStyles';
import { Identity } from 'types/identityTypes';
import {
isSubstrateNetworkParams,
isUnknownNetworkParams,
SubstrateNetworkParams
} from 'types/networkSpecsTypes';
isUnknownNetworkParams
} from 'types/networkTypes';
import { ButtonListener } from 'types/props';
import {
getAddressWithPath,
Expand Down Expand Up @@ -64,22 +64,23 @@ export default function PathCard({
testID?: string;
titlePrefix?: string;
}): React.ReactElement {
const networksContext = useContext(NetworksContext);
const { networks, allNetworks } = networksContext;
const isNotEmptyName = name && name !== '';
const pathName = isNotEmptyName ? name : getPathName(path, identity);
const { isSeedRefValid, substrateAddress } = useSeedRef(
identity.encryptedSeed
);
const [address, setAddress] = useState('');
const computedNetworkKey =
networkKey || getNetworkKeyByPath(path, identity.meta.get(path)!);
networkKey ||
getNetworkKeyByPath(path, identity.meta.get(path)!, networksContext);
useEffect(() => {
const getAddress = async (): Promise<void> => {
const existedAddress = getAddressWithPath(path, identity);
if (existedAddress !== '') return setAddress(existedAddress);
if (isSeedRefValid && isPathValid) {
const prefix = (NETWORK_LIST[
computedNetworkKey
] as SubstrateNetworkParams).prefix;
if (isSeedRefValid && isPathValid && networks.has(computedNetworkKey)) {
const prefix = networks.get(computedNetworkKey)!.prefix;
const generatedAddress = await substrateAddress(path, prefix);
return setAddress(generatedAddress);
}
Expand All @@ -93,15 +94,18 @@ export default function PathCard({
networkKey,
computedNetworkKey,
isSeedRefValid,
substrateAddress
substrateAddress,
networks
]);

const isUnknownAddress = address === '';
const hasPassword = identity.meta.get(path)?.hasPassword ?? false;
const networkParams =
computedNetworkKey === UnknownNetworkKeys.UNKNOWN && !isUnknownAddress
computedNetworkKey === UnknownNetworkKeys.UNKNOWN &&
!isUnknownAddress &&
!allNetworks.has(computedNetworkKey)
? NETWORK_LIST[defaultNetworkKey]
: NETWORK_LIST[computedNetworkKey];
: allNetworks.get(computedNetworkKey)!;

const nonSubstrateCard = (
<>
Expand Down
4 changes: 2 additions & 2 deletions src/components/PathGroupCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
isUnknownNetworkParams,
SubstrateNetworkParams,
UnknownNetworkParams
} from 'types/networkSpecsTypes';
} from 'types/networkTypes';
import { removeSlash } from 'utils/identitiesUtils';
import { useSeedRef } from 'utils/seedRefHooks';
import { unlockSeedPhrase } from 'utils/navigationHelpers';
Expand Down Expand Up @@ -89,7 +89,7 @@ export default function PathGroupCard({
await accountsStore.deriveNewPath(
nextPath,
substrateAddress,
(networkParams as SubstrateNetworkParams).genesisHash,
networkParams as SubstrateNetworkParams,
name,
''
);
Expand Down
7 changes: 4 additions & 3 deletions src/components/ScreenHeading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

import React, { ReactElement, ReactNode } from 'react';
import React, { ReactElement, ReactNode, useContext } from 'react';
import { View, StyleSheet, Text, ViewStyle, TextStyle } from 'react-native';
import AntIcon from 'react-native-vector-icons/AntDesign';
import { Icon } from 'react-native-elements';

import ButtonIcon from './ButtonIcon';
import AccountIcon from './AccountIcon';

import { NetworksContext } from 'stores/NetworkContext';
import TouchableItem from 'components/TouchableItem';
import testIDs from 'e2e/testIDs';
import { NETWORK_LIST } from 'constants/networkSpecs';
import fontStyles from 'styles/fontStyles';
import fonts from 'styles/fonts';
import colors from 'styles/colors';
Expand Down Expand Up @@ -115,6 +115,7 @@ export function LeftScreenHeading({
...baseStyles.text,
...baseStyles.t_left
};
const { getNetwork } = useContext(NetworksContext);
const isDisabled = onPress === undefined;
return (
<TouchableItem
Expand All @@ -125,7 +126,7 @@ export function LeftScreenHeading({
<View style={{ alignItems: 'center', flexDirection: 'row' }}>
<AccountIcon
address={''}
network={NETWORK_LIST[networkKey]}
network={getNetwork(networkKey)}
style={baseStyles.networkIcon}
/>
<View>
Expand Down
Loading