From 556d07b368f512a76873c949e523a26ab12935ff Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Sun, 1 Sep 2019 09:44:27 +0200 Subject: [PATCH] Scan consistency updates (#194) * Scan consistency updates * Default auto height/width * Rework qrcode export * Fix address scanning (as per new format) * Update tests * Bump common * Pass through genesisHash * addExternal via address --- copy-to-extension.sh | 20 ++++++++++ package.json | 2 +- packages/react-identicon/package.json | 4 +- packages/react-qr/src/Display.tsx | 1 - packages/react-qr/src/DisplayAddress.tsx | 8 ++-- packages/react-qr/src/DisplayPayload.tsx | 3 +- packages/react-qr/src/Scan.tsx | 1 - packages/react-qr/src/ScanAddress.tsx | 18 +++++---- packages/react-qr/src/ScanSignature.tsx | 3 +- packages/react-qr/src/constants.ts | 4 +- packages/react-qr/src/qrcode.ts | 5 ++- packages/react-qr/src/types.ts | 1 + packages/react-qr/src/util.spec.ts | 8 +++- packages/react-qr/src/util.ts | 24 +++++++----- packages/ui-keyring/package.json | 4 +- packages/ui-keyring/src/Keyring.ts | 4 +- packages/ui-settings/package.json | 2 +- packages/ui-shared/package.json | 2 +- yarn.lock | 48 ++++++++++++------------ 19 files changed, 100 insertions(+), 62 deletions(-) create mode 100755 copy-to-extension.sh diff --git a/copy-to-extension.sh b/copy-to-extension.sh new file mode 100755 index 00000000..5b97f798 --- /dev/null +++ b/copy-to-extension.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +function copy_folder () { + SRC="packages/$1/build" + DST="extension/node_modules/@polkadot/$1" + + echo "** Copying $SRC to apps/$DST" + + rm -rf ../$DST + cp -r $SRC ../$DST +} + +yarn polkadot-dev-build-ts + +copy_folder "react-identicon" +copy_folder "react-qr" +copy_folder "ui-assets" +copy_folder "ui-keyring" +copy_folder "ui-settings" +copy_folder "ui-shared" diff --git a/package.json b/package.json index d5eb9d3b..1f503e62 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@babel/core": "^7.5.5", "@babel/runtime": "^7.5.5", "@polkadot/dev-react": "^0.31.0-beta.6", - "@polkadot/ts": "^0.1.69", + "@polkadot/ts": "^0.1.70", "babel-plugin-transform-vue-template": "^0.4.2", "empty": "^0.10.1", "gh-pages": "^2.1.1", diff --git a/packages/react-identicon/package.json b/packages/react-identicon/package.json index 5c151295..b5f30334 100644 --- a/packages/react-identicon/package.json +++ b/packages/react-identicon/package.json @@ -25,8 +25,8 @@ "react": "*" }, "devDependencies": { - "@polkadot/keyring": "^1.2.0-beta.3", - "@polkadot/util-crypto": "^1.2.0-beta.3", + "@polkadot/keyring": "^1.2.0-beta.5", + "@polkadot/util-crypto": "^1.2.0-beta.5", "xmlserializer": "^0.6.1" } } diff --git a/packages/react-qr/src/Display.tsx b/packages/react-qr/src/Display.tsx index 6be33dc9..59eb116b 100644 --- a/packages/react-qr/src/Display.tsx +++ b/packages/react-qr/src/Display.tsx @@ -12,7 +12,6 @@ import qrcode from './qrcode'; import { createFrames, createImgSize } from './util'; interface Props extends BaseProps { - size?: number; skipEncoding?: boolean; value: Uint8Array; } diff --git a/packages/react-qr/src/DisplayAddress.tsx b/packages/react-qr/src/DisplayAddress.tsx index e90ae5f9..44848d8e 100644 --- a/packages/react-qr/src/DisplayAddress.tsx +++ b/packages/react-qr/src/DisplayAddress.tsx @@ -12,6 +12,7 @@ import QrDisplay from './Display'; interface Props extends BaseProps { address: string; + genesisHash: string; } interface State { @@ -25,8 +26,8 @@ export default class DisplayExtrinsic extends React.PureComponent dataHash: null }; - public static getDerivedStateFromProps ({ address }: Props, prevState: State): State | null { - const data = createAddressPayload(address); + public static getDerivedStateFromProps ({ address, genesisHash }: Props, prevState: State): State | null { + const data = createAddressPayload(address, genesisHash); const dataHash = xxhashAsHex(data); if (dataHash === prevState.dataHash) { @@ -37,7 +38,7 @@ export default class DisplayExtrinsic extends React.PureComponent } public render (): React.ReactNode { - const { className, style } = this.props; + const { className, size, style } = this.props; const { data } = this.state; if (!data) { @@ -48,6 +49,7 @@ export default class DisplayExtrinsic extends React.PureComponent diff --git a/packages/react-qr/src/DisplayPayload.tsx b/packages/react-qr/src/DisplayPayload.tsx index 4b06f843..945a9899 100644 --- a/packages/react-qr/src/DisplayPayload.tsx +++ b/packages/react-qr/src/DisplayPayload.tsx @@ -39,7 +39,7 @@ export default class DisplayPayload extends React.PureComponent { } public render (): React.ReactNode { - const { className, style } = this.props; + const { className, size, style } = this.props; const { data } = this.state; if (!data) { @@ -49,6 +49,7 @@ export default class DisplayPayload extends React.PureComponent { return ( diff --git a/packages/react-qr/src/Scan.tsx b/packages/react-qr/src/Scan.tsx index 71e0da76..888d61c0 100644 --- a/packages/react-qr/src/Scan.tsx +++ b/packages/react-qr/src/Scan.tsx @@ -14,7 +14,6 @@ interface Props extends BaseProps { delay?: number; onError?: (error: Error) => void; onScan?: (data: string) => void; - size?: number; } const DEFAULT_DELAY = 150; diff --git a/packages/react-qr/src/ScanAddress.tsx b/packages/react-qr/src/ScanAddress.tsx index 6eb126de..9d70cbb9 100644 --- a/packages/react-qr/src/ScanAddress.tsx +++ b/packages/react-qr/src/ScanAddress.tsx @@ -5,6 +5,7 @@ import { BaseProps } from './types'; import React from 'react'; +import { assert } from '@polkadot/util'; import { ADDRESS_PREFIX } from './constants'; import QrScan from './Scan'; @@ -12,18 +13,19 @@ import { decodeAddress } from '@polkadot/util-crypto'; interface Props extends BaseProps { onError?: (error: Error) => void; - onScan?: (data: string) => void; + onScan?: (aqddress: string, genesisHash: string) => void; } export default class ScanAddress extends React.PureComponent { public render (): React.ReactNode { - const { className, onError, style } = this.props; + const { className, onError, size, style } = this.props; return ( ); @@ -32,17 +34,19 @@ export default class ScanAddress extends React.PureComponent { private onScan = (data: string | null): void => { const { onScan } = this.props; - if (!data || !onScan || !data.startsWith(ADDRESS_PREFIX)) { + if (!data || !onScan) { return; } - const address = data.substr(ADDRESS_PREFIX.length); - try { + const [prefix, address, genesisHash] = data.split(':'); + + assert(prefix === ADDRESS_PREFIX, `Invalid address received, expected '${ADDRESS_PREFIX}', found '${prefix}'`); + decodeAddress(address); - onScan(address); + onScan(address, genesisHash); } catch (error) { - console.error('@polkadot/react-qr:QrScanAddress', error.message); + console.error('@polkadot/react-qr:QrScanAddress', error.message, data); } } } diff --git a/packages/react-qr/src/ScanSignature.tsx b/packages/react-qr/src/ScanSignature.tsx index c9b69b3e..aa9db865 100644 --- a/packages/react-qr/src/ScanSignature.tsx +++ b/packages/react-qr/src/ScanSignature.tsx @@ -16,13 +16,14 @@ interface Props extends BaseProps { export default class ScanSignature extends React.PureComponent { public render (): React.ReactNode { - const { className, onError, style } = this.props; + const { className, onError, size, style } = this.props; return ( ); diff --git a/packages/react-qr/src/constants.ts b/packages/react-qr/src/constants.ts index c1dfbe3b..9c314cb7 100644 --- a/packages/react-qr/src/constants.ts +++ b/packages/react-qr/src/constants.ts @@ -2,8 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -const DEFAULT_IMG_SIZE = 300; -const ADDRESS_PREFIX = 'substrate:'; +const ADDRESS_PREFIX = 'substrate'; const FRAME_SIZE = 2048; const SUBSTRATE_ID = new Uint8Array([0x53]); const CRYPTO_SR25519 = new Uint8Array([0x01]); @@ -19,7 +18,6 @@ export { CMD_SIGN_IMMORTAL_TX, CMD_SIGN_MSG, CRYPTO_SR25519, - DEFAULT_IMG_SIZE, FRAME_SIZE, SUBSTRATE_ID }; diff --git a/packages/react-qr/src/qrcode.ts b/packages/react-qr/src/qrcode.ts index ede97637..f5259c3c 100644 --- a/packages/react-qr/src/qrcode.ts +++ b/packages/react-qr/src/qrcode.ts @@ -2,7 +2,10 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import qrcode from 'qrcode-generator'; +import _qrcode from 'qrcode-generator'; + +// A small hurdle to jump through, just to get the default/default correct (as generated) +const qrcode: typeof _qrcode = _qrcode; // HACK The default function take string -> number[], the Uint8array is compatible // with that signature and the use thereof diff --git a/packages/react-qr/src/types.ts b/packages/react-qr/src/types.ts index a8d7131d..e1f80be9 100644 --- a/packages/react-qr/src/types.ts +++ b/packages/react-qr/src/types.ts @@ -4,5 +4,6 @@ export interface BaseProps { className?: string; + size?: string | number; style?: Record; } diff --git a/packages/react-qr/src/util.spec.ts b/packages/react-qr/src/util.spec.ts index 918668dc..3a83e4b6 100644 --- a/packages/react-qr/src/util.spec.ts +++ b/packages/react-qr/src/util.spec.ts @@ -50,9 +50,13 @@ describe('util', (): void => { it('encodes an address properly', (): void => { expect( u8aToString( - createAddressPayload('5GKhfyctwmW5LQdGaHTyU9qq2yDtggdJo719bj5ZUxnVGtmX') + createAddressPayload('5HbgaJEuVN5qGbkhgtuDQANivSWwHXWsC2erP1SQUXgciTVq', '0x') ) - ).toEqual('substrate:5GKhfyctwmW5LQdGaHTyU9qq2yDtggdJo719bj5ZUxnVGtmX'); + ).toEqual( + 'substrate:' + + '5HbgaJEuVN5qGbkhgtuDQANivSWwHXWsC2erP1SQUXgciTVq:' + + '0x' + ); }); }); diff --git a/packages/react-qr/src/util.ts b/packages/react-qr/src/util.ts index e4bc1b86..5195d09e 100644 --- a/packages/react-qr/src/util.ts +++ b/packages/react-qr/src/util.ts @@ -2,10 +2,10 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { u8aConcat, u8aToU8a } from '@polkadot/util'; +import { isString, u8aConcat, u8aToU8a } from '@polkadot/util'; import { decodeAddress } from '@polkadot/util-crypto'; -import { ADDRESS_PREFIX, CRYPTO_SR25519, DEFAULT_IMG_SIZE, FRAME_SIZE, SUBSTRATE_ID } from './constants'; +import { ADDRESS_PREFIX, CRYPTO_SR25519, FRAME_SIZE, SUBSTRATE_ID } from './constants'; const MULTIPART = new Uint8Array([0]); @@ -29,11 +29,8 @@ export function decodeString (value: Uint8Array): string { }, ''); } -export function createAddressPayload (address: string): Uint8Array { - return u8aConcat( - encodeString(ADDRESS_PREFIX), - encodeString(address) - ); +export function createAddressPayload (address: string, genesisHash: string): Uint8Array { + return encodeString(`${ADDRESS_PREFIX}:${address}:${genesisHash}`); } export function createSignPayload (address: string, cmd: number, payload: string | Uint8Array): Uint8Array { @@ -66,8 +63,17 @@ export function createFrames (input: Uint8Array): Uint8Array[] { ); } -export function createImgSize (size: number = DEFAULT_IMG_SIZE): Record { - const height = `${size}px`; +export function createImgSize (size?: string | number): Record { + if (!size) { + return { + height: 'auto', + width: '100%' + }; + } + + const height = isString(size) + ? size + : `${size}px`; return { height, diff --git a/packages/ui-keyring/package.json b/packages/ui-keyring/package.json index 6a563af7..7f89283a 100644 --- a/packages/ui-keyring/package.json +++ b/packages/ui-keyring/package.json @@ -19,9 +19,9 @@ "styled-components": "^4.3.1" }, "devDependencies": { - "@polkadot/keyring": "^1.2.0-beta.3", + "@polkadot/keyring": "^1.2.0-beta.5", "@polkadot/types": "^0.91.0-beta.10", - "@polkadot/util": "^1.2.0-beta.3" + "@polkadot/util": "^1.2.0-beta.5" }, "peerDependencies": { "@polkadot/keyring": "*", diff --git a/packages/ui-keyring/src/Keyring.ts b/packages/ui-keyring/src/Keyring.ts index 88b96dec..579e4831 100644 --- a/packages/ui-keyring/src/Keyring.ts +++ b/packages/ui-keyring/src/Keyring.ts @@ -27,8 +27,8 @@ export class Keyring extends Base implements KeyringStruct { account: (): AddressSubject => this.accounts }; - public addExternal (publicKey: Uint8Array, meta: KeyringPair$Meta = {}): CreateResult { - const pair = this.keyring.addFromAddress(publicKey, { ...meta, isExternal: true }, null); + public addExternal (address: string | Uint8Array, meta: KeyringPair$Meta = {}): CreateResult { + const pair = this.keyring.addFromAddress(address, { ...meta, isExternal: true }, null); return { json: this.saveAccount(pair), diff --git a/packages/ui-settings/package.json b/packages/ui-settings/package.json index b7eac11f..4bf4dbfd 100644 --- a/packages/ui-settings/package.json +++ b/packages/ui-settings/package.json @@ -14,7 +14,7 @@ "store": "^2.0.12" }, "devDependencies": { - "@polkadot/util": "^1.2.0-beta.3" + "@polkadot/util": "^1.2.0-beta.5" }, "peerDependencies": { "@polkadot/util": "*" diff --git a/packages/ui-shared/package.json b/packages/ui-shared/package.json index 9ee3ebd6..fa2c84c8 100644 --- a/packages/ui-shared/package.json +++ b/packages/ui-shared/package.json @@ -17,6 +17,6 @@ "@polkadot/util-crypto": "*" }, "devDependencies": { - "@polkadot/util-crypto": "^1.2.0-beta.3" + "@polkadot/util-crypto": "^1.2.0-beta.5" } } diff --git a/yarn.lock b/yarn.lock index ad878f1c..410b5dbb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2082,19 +2082,19 @@ typescript "^3.6.2" vuepress "^1.0.3" -"@polkadot/keyring@^1.2.0-beta.3": - version "1.2.0-beta.3" - resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-1.2.0-beta.3.tgz#94d7ab481b2d3932b1ae69f28579bbc9a6bc22a8" - integrity sha512-EZVCH/4snM+5rVc9QbD+opQ7rsuxwHf9KCE7+vHGHZKupXbbXv2KTv1X+JVK0Pnxk60vJ5e6idHpNVGZ1AjZag== +"@polkadot/keyring@^1.2.0-beta.5": + version "1.2.0-beta.5" + resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-1.2.0-beta.5.tgz#bac4fe845efdf07e40760c6ff700d7e29c3f6cb8" + integrity sha512-Pmq0kibuRJVGCqqW+w1Xwgd5UOQHrhyfvRx8XaU79iAZVUBzeJFWF8k+IraRJ5795sZfgECNBcCcm+KYJoaHcw== dependencies: "@babel/runtime" "^7.5.5" - "@polkadot/util" "^1.2.0-beta.3" - "@polkadot/util-crypto" "^1.2.0-beta.3" + "@polkadot/util" "^1.2.0-beta.5" + "@polkadot/util-crypto" "^1.2.0-beta.5" -"@polkadot/ts@^0.1.69": - version "0.1.69" - resolved "https://registry.yarnpkg.com/@polkadot/ts/-/ts-0.1.69.tgz#ffc5b4b4c7aedc0a7e61d13b9487ba3bae30cbd5" - integrity sha512-JrzntjqVfEOV/VEMNx8TeW4263bLyvou+ecxNUAW1plAQXEp7PdDtR1wVS1mlhM0/mXt1iYZXet2XchP0po7Fg== +"@polkadot/ts@^0.1.70": + version "0.1.70" + resolved "https://registry.yarnpkg.com/@polkadot/ts/-/ts-0.1.70.tgz#0f6462871c557fc81bf0e0542d5ac4ccd18f134c" + integrity sha512-SREHjU1WHfQeHo8/ieeQuiahHXSvZMyySdP44+G+sySgTDHK5wfOK7zJKv1dFOZBHrWcqtjCptTNMg2B9E2ysQ== dependencies: "@types/chrome" "^0.0.88" @@ -2131,14 +2131,14 @@ tweetnacl "^1.0.1" xxhashjs "^0.2.2" -"@polkadot/util-crypto@^1.2.0-beta.3": - version "1.2.0-beta.3" - resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-1.2.0-beta.3.tgz#fb0df4d48e97e49f7dfd554fe99196bcf5885bff" - integrity sha512-qnlai3+s/q7JJLgcY6nxQUHL/YQx+8k8gRcilxqNlXI40Q/u1O9oYSYSFMBOKCHrXSJJkaBWVU25bMw7FO56XQ== +"@polkadot/util-crypto@^1.2.0-beta.5": + version "1.2.0-beta.5" + resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-1.2.0-beta.5.tgz#c9b5cad0000e4079929bf90fc2e73e15fb77f4c3" + integrity sha512-ffnExVlHedNhR9LfaWKWX0sXxU3BDcVrRqOIgNvPmy0VuwKSaDX/Zr06slz9JNmgMygsUBoLwTGeSrfW3AW5Gg== dependencies: "@babel/runtime" "^7.5.5" - "@polkadot/util" "^1.2.0-beta.3" - "@polkadot/wasm-crypto" "^0.14.0-beta.1" + "@polkadot/util" "^1.2.0-beta.5" + "@polkadot/wasm-crypto" "^0.14.0-beta.2" "@types/bip39" "^2.4.2" "@types/bs58" "^4.0.0" "@types/pbkdf2" "^3.0.0" @@ -2166,10 +2166,10 @@ ip-regex "^4.1.0" moment "^2.24.0" -"@polkadot/util@^1.2.0-beta.3": - version "1.2.0-beta.3" - resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-1.2.0-beta.3.tgz#4f88e22ef5ae31ecf937175572545c65bba66fa0" - integrity sha512-w/Sbs3Bi+rl+TcJKRNFkc9X0yFEPn2i7cH6Y43Pm05UKuMNlJKo3ilKJbGjuwYZJUDWyTqPap2pfSKraH1HDbQ== +"@polkadot/util@^1.2.0-beta.5": + version "1.2.0-beta.5" + resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-1.2.0-beta.5.tgz#546103410f46a805eceb4c220ed396e82ab3725d" + integrity sha512-KnBaQU6QHHuO3UyYUAWAdMkdd3976sVnyFUUk69ATRk8TCF84TI2Zwcjvq9VVyoCTGR8IPIpPOhmQYhUFiFzsQ== dependencies: "@babel/runtime" "^7.5.5" "@types/bn.js" "^4.11.5" @@ -2184,10 +2184,10 @@ resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-0.13.1.tgz#602305b2ca86fc320a35ce820835e0e2dd9e646e" integrity sha512-24a63FynhyBHEGxqoDMZHAcaSxJqnjBPnEcmXXYCN2lI7b4iKaJKF2t+/FUmY7XTST+xNgFTJZ7A/o8jjgC/mA== -"@polkadot/wasm-crypto@^0.14.0-beta.1": - version "0.14.0-beta.2" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-0.14.0-beta.2.tgz#a405cbf019e0213b6d6df7ad0062fc766af3f537" - integrity sha512-QGXgLfeaQDKBASZ70mrSApQ8ROOj2eRDdSUSNu+ApgoRODptkm7NrRtGBWw+5nH5qVOmGG3eZYFHFDZGUrlOag== +"@polkadot/wasm-crypto@^0.14.0-beta.2": + version "0.14.0-beta.3" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-0.14.0-beta.3.tgz#740e576ed07e378b55e7333239da23a44d0a07f3" + integrity sha512-CbPx+ymPkE5TPDH/1cnIi7WhssIRrVY3Ira2qY9YDcc1+L3Gr3yvPvLnNnynaZ+LtYkt57jRSZtUbUgXoT98Dw== "@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0": version "2.9.0"