Unverified Commit ea6a0f7a authored by Hanwen Cheng's avatar Hanwen Cheng Committed by GitHub
Browse files

fix: Signing on Polkadot CC1 (#629)

* fix: signing on polkadot, adjust with polkadot js

* add polkadot e2e test

* fix e2e polkadot signing test

* bump version to 4.3

* fix passworded signing problem and add e2e passworded test

* refine message details view
parent d880c815
Pipeline #94382 failed with stages
in 3 minutes and 33 seconds
......@@ -134,8 +134,8 @@ android {
minSdkVersion 18
missingDimensionStrategy 'react-native-camera', 'general'
targetSdkVersion 28
versionCode 4207
versionName "4.2.7"
versionCode 4300
versionName "4.3.0"
ndk {
abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
}
......
......@@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>4.2.7</string>
<string>4.3.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>4207</string>
<string>4300</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
......
{
"name": "NativeSigner",
"version": "4.2.7-beta",
"version": "4.3.0-beta",
"private": true,
"license": "GPL-3.0",
"engines": {
......
......@@ -72,7 +72,7 @@ export const SubstrateNetworkKeys: {
KUSAMA_DEV:
'0x5e9679182f658e148f33d3f760f11179977398bb3da8d1f0bf7b267fe6b3ebb0',
POLKADOT:
'0x0000000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a',
'0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3',
SUBSTRATE_DEV:
'0x0d667fd278ec412cd9fccdb066f09ed5b4cfd9c9afa9eb747213acb02b1e70bc', // substrate --dev commit ac6a2a783f0e1f4a814cf2add40275730cd41be1 hosted on wss://dev-node.substrate.dev .
WESTEND: '0x4a31f96525a77959d97e267c8fc3066ca333d9ade161720e1b7de8d35ccc6bd2'
......@@ -171,7 +171,7 @@ const substrateNetworkBase: {
[SubstrateNetworkKeys.POLKADOT]: {
color: '#e7007a',
decimals: 12,
genesisHash: null,
genesisHash: SubstrateNetworkKeys.POLKADOT,
logo: require('res/img/logos/polkadot.png'),
order: 1,
pathId: 'polkadot',
......
......@@ -34,7 +34,9 @@ export default function MessageDetailsCard({
}): React.ReactElement {
return (
<View style={[styles.messageContainer, style]}>
<Text style={styles.titleText}>{isHash ? 'Hash' : 'Message'}</Text>
<Text style={styles.titleText}>
{isHash ? 'Message Hash' : 'Message'}
</Text>
{isHash ? (
<Text style={styles.hashText}>{message}</Text>
) : (
......
......@@ -84,7 +84,7 @@ export async function processBarCode(
if (seedRef === undefined || !seedRef.isValid()) {
if (sender.hasPassword) {
//need unlock with password
[password] = await unlockSeedPhraseWithPassword(
password = await unlockSeedPhraseWithPassword(
navigation,
false,
senderIdentity
......@@ -93,6 +93,14 @@ export async function processBarCode(
await unlockSeedPhrase(navigation, false, senderIdentity);
}
seedRef = getSeedRef(sender.encryptedSeed, seedRefs)!;
} else {
if (sender.hasPassword) {
password = await unlockSeedPhraseWithPassword(
navigation,
true,
senderIdentity
);
}
}
// 3. sign data
if (isEthereum) {
......@@ -112,6 +120,7 @@ export async function processBarCode(
}
try {
console.log('txrequest raw is', txRequestData.rawData);
await parseQrData();
if (scannerStore.getUnsigned() === null) return;
await scannerStore.setData(accounts);
......
......@@ -37,12 +37,12 @@ function PinUnlockWithPassword({
async function submit(): Promise<void> {
const { pin, password } = state;
const resolvePassword = route.params.resolve;
if (!route.params.isSeedRefValid) {
const resolveWithSeedRef = route.params.resolve;
if (pin.length >= 6 && targetIdentity) {
try {
await createSeedRef(pin);
resolveWithSeedRef(password);
resolvePassword(password);
resetState();
} catch (e) {
updateState({ password: '', pin: '', pinMismatch: true });
......@@ -52,7 +52,6 @@ function PinUnlockWithPassword({
updateState({ pinTooShort: true });
}
} else {
const resolvePassword = route.params.resolve;
resolvePassword(password);
resetState();
}
......
......@@ -15,41 +15,43 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { GenericExtrinsicPayload } from '@polkadot/types';
import {
compactFromU8a,
hexStripPrefix,
hexToU8a,
isU8a,
u8aToHex,
u8aConcat
u8aConcat,
u8aToHex
} from '@polkadot/util';
import { Container } from 'unstated';
import { ExtrinsicPayload } from '@polkadot/types/interfaces';
import AccountsStore from 'stores/AccountsStore';
import { NETWORK_LIST, NetworkProtocols } from 'constants/networkSpecs';
import { TryBrainWalletSignFunc, TrySignFunc } from 'utils/seedRefHooks';
import { isAscii } from 'utils/strings';
import {
brainWalletSign,
decryptData,
keccak,
ethSign,
substrateSign
} from 'utils/native';
import transaction, { Transaction } from 'utils/transaction';
import {
constructDataFromBytes,
asciiToHex,
encodeNumber
} from 'utils/decoders';
import AccountsStore from 'stores/AccountsStore';
import { Account, FoundAccount } from 'types/identityTypes';
import { emptyAccount } from 'utils/account';
import {
CompletedParsedData,
EthereumParsedData,
isEthereumCompletedParsedData,
isMultipartData,
isSubstrateCompletedParsedData,
SubstrateCompletedParsedData
} from 'types/scannerTypes';
import { emptyAccount } from 'utils/account';
import {
asciiToHex,
constructDataFromBytes,
encodeNumber
} from 'utils/decoders';
import {
blake2b,
brainWalletSign,
decryptData,
ethSign,
keccak,
substrateSign
} from 'utils/native';
import { TryBrainWalletSignFunc, TrySignFunc } from 'utils/seedRefHooks';
import { isAscii } from 'utils/strings';
import transaction, { Transaction } from 'utils/transaction';
type TXRequest = Record<string, any>;
......@@ -70,7 +72,6 @@ type ScannerState = {
missedFrames: Array<number>;
multipartData: null | Array<Uint8Array | null>;
multipartComplete: boolean;
prehash: GenericExtrinsicPayload | null;
recipient: FoundAccount | null;
sender: FoundAccount | null;
signedData: string;
......@@ -92,7 +93,6 @@ const DEFAULT_STATE = Object.freeze({
missedFrames: [],
multipartComplete: false,
multipartData: null,
prehash: null,
recipient: null,
sender: null,
signedData: '',
......@@ -144,14 +144,6 @@ export default class ScannerStore extends Container<ScannerState> {
await this.setState({
unsignedData: parsedData
});
// set payload before it got hashed.
// signature will be generated from the hash, but we still want to display it.
if (parsedData.hasOwnProperty('preHash')) {
this.setPrehashPayload(
(parsedData as SubstrateCompletedParsedData).preHash
);
}
}
async integrateMultiPartData(): Promise<void> {
......@@ -274,23 +266,25 @@ export default class ScannerStore extends Container<ScannerState> {
this.setBusy();
const address = signRequest.data.account;
const message = signRequest.data.data;
const crypto = (signRequest as SubstrateCompletedParsedData).data?.crypto;
const isHash =
(signRequest as SubstrateCompletedParsedData)?.isHash || false;
const isOversized =
(signRequest as SubstrateCompletedParsedData)?.oversized || false;
let message = '';
let isHash = false;
let isOversized = false;
let dataToSign = '';
const messageString = message?.toString();
if (messageString === undefined)
throw new Error('No message data to sign.');
if (crypto === 'sr25519' || crypto === 'ed25519') {
if (isSubstrateCompletedParsedData(signRequest)) {
// only Substrate payload has crypto field
dataToSign = message!.toString();
if (signRequest.data.crypto !== 'sr25519')
throw new Error('currently Parity Signer only support sr25519');
isHash = signRequest.isHash;
isOversized = signRequest.oversized;
const rawPayload = signRequest.data.data;
const [offset] = compactFromU8a(rawPayload);
const payload = rawPayload.subarray(offset);
dataToSign = await blake2b(u8aToHex(payload, -1, false));
message = dataToSign;
} else {
dataToSign = await ethSign(message!.toString());
message = signRequest.data.data;
dataToSign = await ethSign(message.toString());
}
const sender = accountsStore.getAccountByAddress(address);
......@@ -342,11 +336,12 @@ export default class ScannerStore extends Container<ScannerState> {
// For Substrate, only sign the blake2 hash if payload bytes length > 256 bytes (handled in decoder.js).
dataToSign = await keccak(txRequest.data.rlp);
} else {
tx = txRequest.data.data;
networkKey = (txRequest.data
.data as ExtrinsicPayload)?.genesisHash.toHex();
const payloadU8a = txRequest.data.data;
const [offset] = compactFromU8a(payloadU8a);
tx = payloadU8a;
networkKey = txRequest.data.genesisHash;
recipientAddress = txRequest.data.account;
dataToSign = txRequest.data.data;
dataToSign = payloadU8a.subarray(offset);
}
const sender = await accountsStore.getById({
......@@ -569,14 +564,4 @@ export default class ScannerStore extends Container<ScannerState> {
getMissedFrames(): number[] {
return this.state.missedFrames;
}
getPrehashPayload(): GenericExtrinsicPayload | null {
return this.state.prehash;
}
setPrehashPayload(prehash: GenericExtrinsicPayload): void {
this.setState({
prehash
});
}
}
import { ExtrinsicPayload } from '@polkadot/types/interfaces';
import { Point, Size } from 'react-native-camera/types';
export interface TxRequestData {
......@@ -40,14 +39,14 @@ export type CompletedParsedData =
export type SubstrateCompletedParsedData = {
data: {
crypto: 'ed25519' | 'sr25519' | null;
data: ExtrinsicPayload | Uint8Array | string;
account: string;
crypto: 'ed25519' | 'sr25519' | null;
data: Uint8Array;
genesisHash: string;
};
action: string; //"signTransaction"
oversized: boolean;
isHash: boolean;
preHash: ExtrinsicPayload;
};
export type SubstrateMultiParsedData = {
......
......@@ -14,22 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { TypeRegistry } from '@polkadot/types';
import {
hexStripPrefix,
hexToU8a,
u8aToHex,
u8aToString
} from '@polkadot/util';
import { hexStripPrefix, hexToU8a, u8aToHex } from '@polkadot/util';
import { encodeAddress } from '@polkadot/util-crypto';
import { blake2b } from './native';
import { ExtrinsicPayloadLatestVersion } from 'constants/chainData';
import {
SUBSTRATE_NETWORK_LIST,
SubstrateNetworkKeys
} from 'constants/networkSpecs';
import { SUBSTRATE_NETWORK_LIST } from 'constants/networkSpecs';
import {
EthereumParsedData,
ParsedData,
......@@ -51,13 +39,12 @@ import {
00 // indicates action: signData
f4cd755672a8f9542ca9da4fbf2182e79135d94304002e6a09ffc96fef6e6c4c // public key
544849532049532053504152544121 // actual payload to sign (should be SCALE or utf8)
91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3 // genesis hash
0 // terminator
--- SQRC Filler Bytes
ec11ec11ec11ec // SQRC filler bytes
*/
const registry = new TypeRegistry();
export function rawDataToU8A(rawData: string): Uint8Array | null {
if (!rawData) {
return null;
......@@ -173,42 +160,24 @@ export async function constructDataFromBytes(
const pubKeyHex = uosAfterFrames.substr(6, 64);
const publicKeyAsBytes = hexToU8a('0x' + pubKeyHex);
const hexEncodedData = '0x' + uosAfterFrames.slice(70);
const rawPayload = hexToU8a(hexEncodedData);
const hexPayload = hexEncodedData.slice(0, -64);
const genesisHash = `0x${hexEncodedData.substr(-64)}`;
const rawPayload = hexToU8a(hexPayload);
data.data.genesisHash = genesisHash;
const isOversized = rawPayload.length > 256;
const defaultPrefix =
SUBSTRATE_NETWORK_LIST[SubstrateNetworkKeys.KUSAMA].prefix;
let extrinsicPayload;
let network;
switch (secondByte) {
case '00': // sign mortal extrinsic
case '02': // sign immortal extrinsic
extrinsicPayload = registry.createType(
'ExtrinsicPayload',
rawPayload,
{
version: ExtrinsicPayloadLatestVersion
}
);
data.action = isOversized ? 'signData' : 'signTransaction';
data.oversized = isOversized;
data.isHash = isOversized;
data.data.data = isOversized
? await blake2b(
u8aToHex(extrinsicPayload.toU8a(true), -1, false)
)
: extrinsicPayload;
// while we are signing a hash, we still have the ability to know what the signing payload is, so we should get that information into the store.
data.preHash = extrinsicPayload;
network =
SUBSTRATE_NETWORK_LIST[extrinsicPayload.genesisHash.toHex()];
data.data.data = rawPayload;
network = SUBSTRATE_NETWORK_LIST[genesisHash];
if (!network) {
throw new Error(
`Signer does not currently support a chain with genesis hash: ${extrinsicPayload.genesisHash.toHex()}`
`Signer does not currently support a chain with genesis hash: ${genesisHash}`
);
}
......@@ -217,31 +186,6 @@ export async function constructDataFromBytes(
network.prefix
); // encode to the prefix;
break;
case '01': // data is a hash
data.action = 'signData';
data.oversized = false;
data.isHash = true;
data.data.data = rawPayload;
data.data.account = encodeAddress(
publicKeyAsBytes,
defaultPrefix
); // default to Kusama
break;
case '03': // Cold Signer should attempt to decode message to utf8
data.action = 'signData';
if (isOversized) {
data.data.data = await blake2b(u8aToHex(rawPayload, -1, false));
data.isHash = isOversized;
data.oversized = isOversized;
} else {
data.data.data = u8aToString(rawPayload);
}
data.data.account = encodeAddress(
publicKeyAsBytes,
defaultPrefix
); // default to Kusama
break;
default:
break;
......
......@@ -15,22 +15,33 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export enum ScanTestRequest {
SetRemarkExtrinsic,
TransferExtrinsic,
SetRemarkMultiPart,
SetRemarkExtrinsicKusama,
TransferExtrinsicKusama,
SetRemarkMultiPartKusama,
SetRemarkExtrinsicPolkadot,
TransferExtrinsicPolkadot,
SetRemarkMultiPartPolkadot,
EthereumTransaction,
EthereumMessage,
passwordedAccountExtrinsic
}
export const scanRequestDataMap = {
[ScanTestRequest.SetRemarkExtrinsic]:
'47500000100005301025a4a03f84a19cf8ebda40e62358c592870691a9cf456138bb4829969d10fe96910000104116503000015040000b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe6f3e4192d8a58ee728ed1f2edf28bb7a78bc62a9b112c190aae5f3eb7de6c5af0ec11ec11ec',
[ScanTestRequest.TransferExtrinsic]:
'49800000100005301025a4a03f84a19cf8ebda40e62358c592870691a9cf456138bb4829969d10fe9699c0400ff3c36776005aec2f32a34c109dc791a82edef980eec3be80da938ac9bcc68217202286bee7503000015040000b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe19d84dae3af90c5c78ff8eaed58b0db1ff8600c4426d4e0969a905ab5fe2d2e50',
[ScanTestRequest.SetRemarkMultiPart]: [
'4040500000200005301025a4a03f84a19cf8ebda40e62358c592870691a9cf456138bb4829969d10fe9695d1100034d113c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d227574662d38223f3e0a3c7376672076657273696f6e3d22312e31222069643d224c617965725f312220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f7376672220786d6c6e733a786c696e6b3d22687474703a2f2f7777772e77332e6f72672f313939392f786c696e6b2220783d223070782220793d22307078222076696577426f783d223135203135203134302031343022207374796c653d22656e61626c652d6261636b67726f756e643a6e65772030203020313730203137303b2220786d6c3a73706163653d227072657365727665223e0a3c7374796c6520747970653d22746578742f637373223e0a092e6267307b66696c6c3a236666663b7d0a092e7374307b66696c6c3a234536303037413b7d0a3c2f7374796c653e0a3c673e0a093c636972636c6520636c6173733d22626730222063783d223835222063793d2238352220723d223730222f3e0a093c673e0a09093c7061746820643d224d38352c33342e37632d32302e382c302d33372e382c31362e392d33372e382c33372e3863302c342e322c302e372c382e332c322c31322e3363302e392c322e372c332e392c342e322c362e372c332e3363322e372d302e392c342e322d332e392c332e332d362e3720632d312e312d332e312d312e362d362e342d312e352d392e374335382e312c35372e362c36392e352c34362c38332e362c34352e336331352e372d302e382c32382e372c31312e372c32382e372c32372e3263302c31342e352d31312e342c32362e342d32352e372c32372e322063302c302d352e332c302e332d372e392c302e37632d312e332c302e322d322e332c302e342d332c302e35632d302e332c302e312d302e362d302e322d302e352d302e356c302e392d342e344c38312c37332e3463302e362d322e382d312e322d352e362d342d362e3220632d322e382d302e362d352e362c312e322d362e322c3463302c302d31312e382c35352d31312e392c35352e36632d302e362c322e382c312e322c352e362c342c362e3263322e382c302e362c352e362d312e322c362e322d3463302e312d302e362c312e372d372e392c312e372d372e392063312e322d352e362c352e382d392e372c31312e322d31302e3463312e322d302e322c352e392d302e352c352e392d302e356331392e352d312e352c33342e392d31372e382c33342e392d33372e37433132322e382c35312e362c3130352e382c33342e372c38352c33342e377a222f3e0a093c2f673e0a3c2f673e0a3c7061746820636c6173733d227374302220643d224d38372e372c310ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11',
'400c9000002000132312e37632d332e342d302e372d362e382c312e342d372e352c342e39632d302e372c332e342c312e342c362e382c342e392c372e3563332e342c302e372c362e382d312e342c372e352d342e39204339332e332c3132352e372c39312e322c3132322e342c38372e372c3132312e377a222f3e0a3c2f7376673e0ae503000015040000b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe89a0d893779d38b2c781bd43be252d3d1e1391dc95025d512d7bb878c368907c0ec11ec11ec11ec11ec11ec11'
[ScanTestRequest.SetRemarkExtrinsicKusama]:
'49500000100005301025a4a03f84a19cf8ebda40e62358c592870691a9cf456138bb4829969d10fe96910000104114501440026040000b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe345f53c073281fc382d20758aee06ceae3014fd53df734d3e94d54642a56dd51b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe0ec11ec',
[ScanTestRequest.TransferExtrinsicKusama]:
'400b900000100005301025a4a03f84a19cf8ebda40e62358c592870691a9cf456138bb4829969d10fe969a00400ba9b70c65836c513128befe1a0b2cafa358c8168cde56a9731f8cab772428a77070010a5d4e8a503440026040000b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe3ea846400c95ce536f8ba122643fad07068b4d0777dc6ec39b6f169681b8121ab0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe0ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11',
[ScanTestRequest.SetRemarkMultiPartKusama]: [
'4040500000200005301025a4a03f84a19cf8ebda40e62358c592870691a9cf456138bb4829969d10fe969ed100001dd10696d706f7274202a2061732052656163742066726f6d20277265616374273b0a696d706f7274207b20506c6174666f726d2c205374796c6553686565742c20546578742c2056696577207d2066726f6d202772656163742d6e6174697665273b0a696d706f7274207b204e61746976654d6f64756c6573207d2066726f6d202772656163742d6e6174697665273b0a0a636f6e737420696e737472756374696f6e73203d20506c6174666f726d2e73656c656374287b0a2020696f733a2060507265737320436d642b5220746f2072656c6f61642c5c6e436d642b44206f72207368616b6520666f7220646576206d656e75602c0a2020616e64726f69643a2060446f75626c65207461702052206f6e20796f7572206b6579626f61726420746f2072656c6f61642c5c6e5368616b65206f72207072657373206d656e7520627574746f6e20666f7220646576206d656e75602c0a7d293b0a0a6578706f72742064656661756c742066756e6374696f6e204170702829207b0a0a2020636f6e7374207b205375627374726174655369676e207d203d204e61746976654d6f64756c6573207c7c207b7d3b0a2020636f6e736f6c652e6c6f672827737562737472617465207369676e206973272c205375627374726174655369676e293b0a0a202072657475726e20280a202020203c56696577207374796c653d7b7374796c65732e636f6e7461696e65727d3e0a2020202020203c54657874207374796c653d7b7374796c65732e77656c636f6d657d3e57656c636f6d6520746f205265616374204e6174697665213c2f546578743e0a2020202020203c54657874207374796c653d7b7374796c65732e696e737472756374696f6e737d3e546f2067657420737461727465642c2065646974204170702e6a733c2f546578743e0a2020202020203c54657874207374796c653d7b7374796c65732e696e737472756374696f6e737d3e7b696e737472756374696f6e737d3c2f546578743e0a202020203c2f566965773e0a2020293b0a7d0a0a636f6e7374207374796c6573203d205374796c6553686565742e637265617465287b0a2020636f6e7461696e65723a207b0a20202020666c65783a20312c0a202020206a757374696679436f6e74656e743a202763656e746572272c0a20202020616c69676e4974656d733a202763656e746572272c0a202020206261636b67726f756e64436f6c6f723a202723463546434646272c0a20207d2c0a202077656c636f6d653a207b0a20202020666f6e7453697a653a2032302c0a2020202074657874416c69676e3a202763656e746572272c0a202020206d617267696e3a2031302c0a20207d2c0ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11',
'400cd00000200010a2020696e737472756374696f6e733a207b0a2020202074657874416c69676e3a202763656e746572272c0a20202020636f6c6f723a202723333333333333272c0a202020206d617267696e426f74746f6d3a20352c0a20207d2c0a7d293b0a5500440026040000b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe5e1efdd919bb098a956954a74f230c9466af21bd3911d2f876c9a0564b1b00e1b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe0ec11ec11ec11ec11'
],
[ScanTestRequest.SetRemarkExtrinsicPolkadot]:
'4990000010000530102ae8673f5391fa714f18f070edfc7db1c6ccd9ee923d0f9b061f28c5d5978162a1000010411d5010000000000000000000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3547562cde4345701ab5ff4721f720c837e2ab7eace195c141c6ff026871fc24f91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c30ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec',
[ScanTestRequest.TransferExtrinsicPolkadot]:
'400bd0000010000530102ae8673f5391fa714f18f070edfc7db1c6ccd9ee923d0f9b061f28c5d5978162aa0050052f375f446eb485845cef8b99f2eac811304bed326e15e7af23585bb81d9752e070010a5d4e825020000000000000000000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c324f94af637ccb3a44abc152a86e02add0989f8a7e1a840c2920b9cd7ba7fe09091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c30ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11',
[ScanTestRequest.SetRemarkMultiPartPolkadot]: [
'404050000020000530102ae8673f5391fa714f18f070edfc7db1c6ccd9ee923d0f9b061f28c5d5978162aed100003dd10696d706f7274202a2061732052656163742066726f6d20277265616374273b0a696d706f7274207b20506c6174666f726d2c205374796c6553686565742c20546578742c2056696577207d2066726f6d202772656163742d6e6174697665273b0a696d706f7274207b204e61746976654d6f64756c6573207d2066726f6d202772656163742d6e6174697665273b0a0a636f6e737420696e737472756374696f6e73203d20506c6174666f726d2e73656c656374287b0a2020696f733a2060507265737320436d642b5220746f2072656c6f61642c5c6e436d642b44206f72207368616b6520666f7220646576206d656e75602c0a2020616e64726f69643a2060446f75626c65207461702052206f6e20796f7572206b6579626f61726420746f2072656c6f61642c5c6e5368616b65206f72207072657373206d656e7520627574746f6e20666f7220646576206d656e75602c0a7d293b0a0a6578706f72742064656661756c742066756e6374696f6e204170702829207b0a0a2020636f6e7374207b205375627374726174655369676e207d203d204e61746976654d6f64756c6573207c7c207b7d3b0a2020636f6e736f6c652e6c6f672827737562737472617465207369676e206973272c205375627374726174655369676e293b0a0a202072657475726e20280a202020203c56696577207374796c653d7b7374796c65732e636f6e7461696e65727d3e0a2020202020203c54657874207374796c653d7b7374796c65732e77656c636f6d657d3e57656c636f6d6520746f205265616374204e6174697665213c2f546578743e0a2020202020203c54657874207374796c653d7b7374796c65732e696e737472756374696f6e737d3e546f2067657420737461727465642c2065646974204170702e6a733c2f546578743e0a2020202020203c54657874207374796c653d7b7374796c65732e696e737472756374696f6e737d3e7b696e737472756374696f6e737d3c2f546578743e0a202020203c2f566965773e0a2020293b0a7d0a0a636f6e7374207374796c6573203d205374796c6553686565742e637265617465287b0a2020636f6e7461696e65723a207b0a20202020666c65783a20312c0a202020206a757374696679436f6e74656e743a202763656e746572272c0a20202020616c69676e4974656d733a202763656e746572272c0a202020206261636b67726f756e64436f6c6f723a202723463546434646272c0a20207d2c0a202077656c636f6d653a207b0a20202020666f6e7453697a653a2032302c0a2020202074657874416c69676e3a202763656e746572272c0a202020206d617267696e3a2031302c0a20207d2c0ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11',
'400d100000200010a2020696e737472756374696f6e733a207b0a2020202074657874416c69676e3a202763656e746572272c0a20202020636f6c6f723a202723333333333333272c0a202020206d617267696e426f74746f6d3a20352c0a20207d2c0a7d293b0a85020000000000000000000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3b70a4c547cfa0e53aae485b9250dbd84d357681a0cc355e5dc3c237bca54439e91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c30ec11ec11'
],
[ScanTestRequest.EthereumTransaction]: {
data:
......@@ -45,5 +56,5 @@ export const scanRequestDataMap = {
'47b7b22616374696f6e223a227369676e44617461222c2264617461223a7b226163636f756e74223a2233313161364430333334313431353937383238393939636338396346656237333864303646646332222c2264617461223a22343236353635373232303639373332303734363836353732363137303739227d7d0ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec'
},
[ScanTestRequest.passwordedAccountExtrinsic]:
'4990000010000530102a225ba2fe8ba7a2a70b6a0801734b20ba9a5d5f6549fc0c9544fc64d9f58a45ea004005a4a03f84a19cf8ebda40e62358c592870691a9cf456138bb4829969d10fe9690700e40b5402850100001f040000b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafed211ef9a2e22676359b8dd5119d182b6bb842a18fc4921e12ed0de47be19848e0ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec'
'400b90000010000530102a225ba2fe8ba7a2a70b6a0801734b20ba9a5d5f6549fc0c9544fc64d9f58a45ea004001e169bcc4cdb062f1c85f971be770b6aea1bd32ac1bf7877aa54ccd73309014a0700e87648175502040026040000b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe1282fc5d493cdd4e1034db77de8e86da65fda3642e8aaa10a6bd31b8a73e7c14b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe0ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11'
};
......@@ -3,6 +3,7 @@ import testIDs from 'e2e/testIDs';
import {
launchWithScanRequest,
pinCode,
tapBack,
testExist,
testInput,
testInputWithDone,
......@@ -40,4 +41,11 @@ describe('Load test', () => {
await testInputWithDone(IdentityPin.passwordInput, password);
await testVisible(SignedTx.qrView);
});
it('does only need password again in the second try', async () => {
await tapBack();
await testTap(SecurityHeader.scanButton);
await testInputWithDone(IdentityPin.passwordInput, password);
await testVisible(SignedTx.qrView);
});
});
......@@ -14,7 +14,11 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { EthereumNetworkKeys } from 'constants/networkSpecs';
import {
EthereumNetworkKeys,
SUBSTRATE_NETWORK_LIST,
SubstrateNetworkKeys
} from 'constants/networkSpecs';
import {
launchWithScanRequest,
pinCode,
......@@ -52,9 +56,9 @@ const testEthereumMessage = async (): Promise<void> => {
describe('Signing test', () => {
testRecoverIdentity();
describe('Substrate Signing Test', () => {
describe('Kusama Signing Test', () => {
it('should sign the set remarks request', async () => {
await launchWithScanRequest(ScanTestRequest.SetRemarkExtrinsic);
await launchWithScanRequest(ScanTestRequest.SetRemarkExtrinsicKusama);
await testSignedTx();
});
......@@ -65,12 +69,42 @@ describe('Signing test', () => {
});
it('should sign transfer request', async () => {
await launchWithScanRequest(ScanTestRequest.TransferExtrinsic);
await launchWithScanRequest(ScanTestRequest.TransferExtrinsicKusama);
await testSignedTx();
});
it('should sign multipart request', async () => {
await launchWithScanRequest(ScanTestRequest.SetRemarkMultiPartKusama);
await testMultiPartExtrinsic();
});
});
describe('Polkadot Signing Test', () => {
it('generate Polkadot account', async () => {
await tapBack();
const PolkadotNetworkButtonIndex =
Main.networkButton +
SUBSTRATE_NETWORK_LIST[SubstrateNetworkKeys.POLKADOT].pathId;
await testTap(testIDs.Main.addNewNetworkButton);
await testScrollAndTap(
PolkadotNetworkButtonIndex,
testIDs.Main.chooserScreen
);
await testVisible(PathDetail.screen);
});
it('should sign the set remarks request', async () => {
await launchWithScanRequest(ScanTestRequest.SetRemarkExtrinsicPolkadot);
await testSignedTx();
});
it('should sign transfer request', async () => {
await launchWithScanRequest(ScanTestRequest.TransferExtrinsicPolkadot);
await testSignedTx();
});
it('should sign multipart request', async () => {
await launchWithScanRequest(ScanTestRequest.SetRemarkMultiPart);
await launchWithScanRequest(ScanTestRequest.SetRemarkMultiPartPolkadot);
await testMultiPartExtrinsic();
});
});
......
......@@ -20,9 +20,8 @@ import {
Metadata,
TypeRegistry
} from '@polkadot/types';
import { ExtrinsicPayload } from '@polkadot/types/interfaces';
import Call from '@polkadot/types/generic/Call';
import { u8aConcat } from '@polkadot/util';
import { hexToU8a, u8aConcat } from '@polkadot/util';
import { checkAddress, decodeAddress } from '@polkadot/util-crypto';
import 'jest';
......@@ -66,17 +65,6 @@ const RN_TX_REQUEST_RAW_DATA =
'5448495320495320535041525441210' + // THIS IS SPARTA!
'ec11ec11ec11ec';
/* eslint-disable prettier/prettier */
const SIGN_MSG_TEST = new Uint8Array([
0, 0, 1, 0, 0,
83, 1, 3, 118, 2, 230, 253, 72, 157, 97,
235, 53, 198, 82, 55, 106, 143, 113, 176, 252,
203, 114, 24, 152, 116, 223, 74, 190, 250, 136,
232, 158, 164, 7, 118, 84, 72, 73, 83, 32,
73, 83, 32, 83, 80, 65, 82, 84, 65, 33
]);
/* eslint-enable prettier/prettier */
const SIGNER_PAYLOAD_TEST = {
address: KUSAMA_ADDRESS,
blockHash:
......@@ -100,7 +88,8 @@ const SIGN_TX_TEST = u8aConcat(
decodeAddress(KUSAMA_ADDRESS),