Compare commits

..
29 Commits
Author SHA1 Message Date
Github Actions cc86e71837 [CI Skip] release/stable 0.56.1
skip-checks: true
2020-07-20 15:31:28 +00:00
Jaco Greeff 00d24f587b 0.56 (#346) 2020-07-20 17:27:23 +02:00
Github Actions c2683d10c6 [CI Skip] release/beta 0.56.0-beta.3
skip-checks: true
2020-07-17 12:30:25 +00:00
Jaco Greeff 11f5607272 Bump dev 2020-07-17 14:26:25 +02:00
Github Actions 259326cb5b [CI Skip] release/beta 0.56.0-beta.2
skip-checks: true
2020-07-17 07:58:51 +00:00
Jaco Greeff dad6590660 Bump deps (#345) 2020-07-17 09:54:43 +02:00
Github Actions b68b4cc374 [CI Skip] release/beta 0.56.0-beta.1
skip-checks: true
2020-07-11 07:35:09 +00:00
Jaco Greeff 7ffa17e372 Flatten Identicon (remove extra wrapper) (#343) 2020-07-11 09:31:22 +02:00
Github Actions c02a4d381c [CI Skip] release/beta 0.56.0-beta.0
skip-checks: true
2020-07-06 17:27:26 +00:00
carumusan ab6e20a0dc Add kulupu (#342) 2020-07-06 19:22:00 +02:00
Github Actions 51dece8b0f [CI Skip] release/stable 0.55.1
skip-checks: true
2020-07-02 11:49:16 +00:00
Jaco Greeff 2452470163 0.55 (#341) 2020-07-02 13:44:36 +02:00
Github Actions edbdb4f239 [CI Skip] release/beta 0.55.0-beta.6
skip-checks: true
2020-07-02 09:54:25 +00:00
Jaco Greeff 43da3b50de Assert of single key 2020-07-02 11:49:54 +02:00
yuhui1208 a3658de7c2 [Stores] make FileStroe read key safely (#338)
* safely readKey

* fix ci

* fix

* fix type error

* Modify judgment

* fix

* fix

* fix lint
2020-07-02 11:44:04 +02:00
Github Actions 74315ec825 [CI Skip] release/beta 0.55.0-beta.5
skip-checks: true
2020-07-02 06:07:03 +00:00
Jaco Greeff 4c58f48645 Bump deps (#340)
* Bump deps

* Adjust for new eslint parser
2020-07-02 08:01:50 +02:00
Github Actions c8f4983946 [CI Skip] release/beta 0.55.0-beta.4
skip-checks: true
2020-07-01 11:44:59 +00:00
Jaco Greeff ea7fad63a6 Ignore .DS_Store (#339)
As per https://github.com/polkadot-js/ui/issues/337#issuecomment-651617556
2020-07-01 13:39:41 +02:00
Github Actions 65352f4253 [CI Skip] release/beta 0.55.0-beta.3
skip-checks: true
2020-06-28 05:40:43 +00:00
Jaco Greeff 11922b1b02 Only apply before on highlight for icons (#336) 2020-06-28 07:35:17 +02:00
Github Actions 47752593b0 [CI Skip] release/beta 0.55.0-beta.2
skip-checks: true
2020-06-25 10:20:37 +00:00
Jaco Greeff 8dfaea2bfc Dep cleanups (#335) 2020-06-25 12:15:27 +02:00
Github Actions b288773d15 [CI Skip] release/beta 0.55.0-beta.1
skip-checks: true
2020-06-24 07:34:57 +00:00
Jaco Greeff 25d9da3144 Bump dependencies (#334)
* Bump dependencies

* QR display component to functional

* Small adjustments
2020-06-24 09:29:43 +02:00
Github Actions 841819d249 [CI Skip] release/beta 0.55.0-beta.0
skip-checks: true
2020-06-22 19:35:29 +00:00
Jaco Greeff 47fa7f9f0e Ledger dependencies bump (#332)
* Bump Ledger deps, adjust interfaces

* Cleanup with correct ledger exports

* Align deps

* 0.10.4
2020-06-22 21:31:17 +02:00
Jaco Greeff ed2c9e5c41 Bumps 2020-06-22 20:42:21 +02:00
Jaco Greeff 985177dd96 Bump deps (#333) 2020-06-22 20:37:44 +02:00
35 changed files with 2250 additions and 2276 deletions
+16
View File
@@ -1,5 +1,21 @@
# CHANGELOG
## 0.56.1 Jul 20, 2020
- Add Kulupu to ss58 options (https://github.com/carumusan)
- Remove CC1 naming for Polkadot (as applicable)
- Flatten React IdentityIcon (no extra wrapping)
- Bump to `@polkadot/api` 1.25.1
- Bump to `@polkadot/util` 2.18.1
## 0.55.1 Jul 2, 2020
- Better error-handling for invalid FileStore accounts (Thanks to https://github.com/yuhui1208)
- Adjust react-qr `Scan*` making `onScan` callbacks required
- Rework the react-qr display to use functional components
- Bump to `@polkadot/api` 1.21.1
- Bump to `@polkadot/util` 2.15.1
## 0.54.1 Jun 16, 2020
- Add genesisHash to signer payload (Thanks to https://github.com/hanwencheng)
+1 -1
View File
@@ -10,5 +10,5 @@
"packages": [
"packages/*"
],
"version": "0.54.1"
"version": "0.56.1"
}
+7 -7
View File
@@ -29,19 +29,19 @@
"test:one": "polkadot-dev-run-test"
},
"devDependencies": {
"@babel/core": "^7.10.2",
"@babel/runtime": "^7.10.2",
"@polkadot/dev": "^0.55.10",
"@polkadot/ts": "^0.3.26",
"@types/jest": "^26.0.0",
"@babel/core": "^7.10.5",
"@babel/runtime": "^7.10.5",
"@polkadot/dev": "^0.55.27",
"@polkadot/ts": "^0.3.29",
"@types/jest": "^26.0.5",
"babel-plugin-transform-vue-template": "^0.4.2",
"empty": "^0.10.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-is": "^16.13.1",
"react-native": "^0.62.2",
"react-native": "^0.63.1",
"vue-template-compiler": "^2.6.11",
"webpack-serve": "^3.2.0"
},
"version": "0.54.1"
"version": "0.56.1"
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/example-react",
"version": "0.54.1",
"version": "0.56.1",
"description": "A very basic example with ui-* & react-* packages",
"main": "index.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
@@ -9,6 +9,6 @@
],
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.10.2"
"@babel/runtime": "^7.10.5"
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/example-vue",
"version": "0.54.1",
"version": "0.56.1",
"description": "A very basic example with ui-* & vue-* packages",
"main": "index.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
@@ -9,6 +9,6 @@
],
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.10.2"
"@babel/runtime": "^7.10.5"
}
}
+13 -13
View File
@@ -1,6 +1,6 @@
{
"name": "exampleReactNative",
"version": "0.54.1",
"version": "0.56.1",
"private": true,
"workspaces": {
"nohoist": [
@@ -23,30 +23,30 @@
"test": "jest"
},
"dependencies": {
"@polkadot/reactnative-identicon": "0.54.1",
"@polkadot/ui-keyring": "0.54.1",
"@polkadot/ui-settings": "0.54.1",
"@polkadot/reactnative-identicon": "0.56.1",
"@polkadot/ui-keyring": "0.56.1",
"@polkadot/ui-settings": "0.56.1",
"@react-native-community/async-storage": "^1.11.0",
"fast-text-encoding": "^1.0.3",
"get-yarn-workspaces": "^1.0.2",
"os-browserify": "^0.3.0",
"process": "^0.11.10",
"react": "16.13.1",
"react-native": "^0.62.2",
"react-native": "^0.63.1",
"react-native-crypto": "^2.2.0",
"react-native-randombytes": "^3.5.3",
"stream-http": "^3.1.1"
},
"devDependencies": {
"@babel/core": "^7.10.2",
"@babel/runtime": "^7.10.2",
"@polkadot/keyring": "^2.14.1",
"@polkadot/util": "^2.14.1",
"@polkadot/util-crypto": "^2.14.1",
"@react-native-community/cli-platform-ios": "^4.10.0",
"@babel/core": "^7.10.5",
"@babel/runtime": "^7.10.5",
"@polkadot/keyring": "^2.18.1",
"@polkadot/util": "^2.18.1",
"@polkadot/util-crypto": "^2.18.1",
"@react-native-community/cli-platform-ios": "^4.10.1",
"@types/react-test-renderer": "16.9.2",
"babel-jest": "^26.0.1",
"metro-react-native-babel-preset": "^0.59.0",
"babel-jest": "^26.1.0",
"metro-react-native-babel-preset": "^0.60.0",
"react-test-renderer": "16.13.1"
},
"peerDependencies": {
+12 -11
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/react-identicon",
"version": "0.54.1",
"version": "0.56.1",
"description": "Renders an SVG picture representing an address",
"main": "index.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
@@ -9,13 +9,12 @@
],
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.10.2",
"@polkadot/ui-settings": "0.54.1",
"@polkadot/ui-shared": "0.54.1",
"@babel/runtime": "^7.10.5",
"@polkadot/ui-settings": "0.56.1",
"@polkadot/ui-shared": "0.56.1",
"color": "^3.1.2",
"jdenticon": "2.2.0",
"react-copy-to-clipboard": "^5.0.2",
"styled-components": "^5.1.1"
"react-copy-to-clipboard": "^5.0.2"
},
"peerDependencies": {
"@polkadot/keyring": "*",
@@ -23,15 +22,17 @@
"@polkadot/util-crypto": "*",
"react": "*",
"react-dom": "*",
"react-is": "*"
"react-is": "*",
"styled-components": "*"
},
"devDependencies": {
"@polkadot/keyring": "^2.14.1",
"@polkadot/util": "^2.14.1",
"@polkadot/util-crypto": "^2.14.1",
"@polkadot/keyring": "^2.18.1",
"@polkadot/util": "^2.18.1",
"@polkadot/util-crypto": "^2.18.1",
"@types/react-copy-to-clipboard": "^4.3.0",
"@types/react-dom": "^16.9.8",
"@types/styled-components": "^5.1.0",
"@types/styled-components": "^5.1.1",
"styled-components": "^5.1.1",
"xmlserializer": "^0.6.1"
}
}
+4 -8
View File
@@ -43,19 +43,15 @@ const Wrapper = styled.div`
position: relative;
}
&:before {
&.highlight:before {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 50%;
box-shadow: 0 0 5px 2px #e0e0e0;
content: '';
}
&.highlight:before {
box-shadow: 0 0 5px 2px #aaa;
content: '';
}
}
`;
@@ -110,14 +106,14 @@ class BaseIcon extends React.PureComponent<Props, State> {
}
private getWrapped ({ address, publicKey }: State): React.ReactNode {
const { className, isAlternative, isHighlight, size = DEFAULT_SIZE, style, theme = settings.icon } = this.props;
const { className = '', isAlternative, isHighlight, size = DEFAULT_SIZE, style, theme = settings.icon } = this.props;
const Component = !address
? Empty
: Components[theme === 'default' ? ICON_DEFAULT_HOST : theme] || Fallback;
return (
<Wrapper
className={`ui--IdentityIcon ${className || ''}`}
className={`ui--IdentityIcon ${className}`}
key={address}
style={style}
>
@@ -19,7 +19,7 @@ function Beachball ({ address, className = '', size, style }: Props): React.Reac
return (
<div
className={`container ${className}`}
className={className}
ref={updateElem}
style={style}
/>
+6 -9
View File
@@ -8,16 +8,13 @@ import React from 'react';
function Empty ({ className = '', size, style }: Props): React.ReactElement<Props> {
return (
<div
className={`container ${className}`}
<svg
className={className}
height={size}
style={style}
>
<svg
height={size}
viewBox='0 0 64 64'
width={size}
/>
</div>
viewBox='0 0 64 64'
width={size}
/>
);
}
@@ -10,7 +10,7 @@ import jdenticon from 'jdenticon';
function Jdenticon ({ className = '', publicKey, size, style }: Props): React.ReactElement<Props> {
return (
<div
className={`container ${className}`}
className={className}
dangerouslySetInnerHTML={{
__html: jdenticon.toSvg(publicKey.substr(2), size)
}}
+10 -17
View File
@@ -17,15 +17,11 @@
// - Overall it is now just a static component, expecting an address as an input value
import { Circle } from '@polkadot/ui-shared/icons/types';
import { Props as BaseProps } from '../types';
import { Props } from '../types';
import React from 'react';
import { polkadotIcon } from '@polkadot/ui-shared';
interface Props extends BaseProps {
isAlternative?: boolean;
}
function renderCircle ({ cx, cy, fill, r }: Circle, key: number): React.ReactNode {
return (
<circle
@@ -40,20 +36,17 @@ function renderCircle ({ cx, cy, fill, r }: Circle, key: number): React.ReactNod
function Identicon ({ address, className = '', isAlternative = false, size, style }: Props): React.ReactElement<Props> {
return (
<div
className={`container ${className}`}
<svg
className={className}
height={size}
id={address}
name={address}
style={style}
viewBox='0 0 64 64'
width={size}
>
<svg
height={size}
id={address}
name={address}
viewBox='0 0 64 64'
width={size}
>
{polkadotIcon(address, { isAlternative }).map(renderCircle)}
</svg>
</div>
{polkadotIcon(address, { isAlternative }).map(renderCircle)}
</svg>
);
}
+4 -1
View File
@@ -3,17 +3,20 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { Prefix } from '@polkadot/util-crypto/address/types';
import React from 'react';
export interface BaseProps {
className?: string;
style?: Record<string, string | number>;
style?: React.CSSProperties;
}
export interface Props extends BaseProps {
address: string;
isAlternative?: boolean;
className?: string;
publicKey: string;
size: number;
style?: React.CSSProperties;
}
export interface IdentityProps extends BaseProps {
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/react-qr",
"version": "0.54.1",
"version": "0.56.1",
"description": "Generates and reads QR codes",
"main": "index.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
@@ -9,13 +9,13 @@
],
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.10.2",
"@babel/runtime": "^7.10.5",
"qrcode-generator": "^1.4.4",
"react-qr-reader": "^2.2.1"
},
"devDependencies": {
"@types/react-qr-reader": "^2.1.3",
"@types/styled-components": "^5.1.0"
"@types/styled-components": "^5.1.1"
},
"peerDependencies": {
"@polkadot/util": "*",
+85 -86
View File
@@ -2,27 +2,31 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { BaseProps } from './types';
import React from 'react';
import React, { useEffect, useRef, useState } from 'react';
import styled from 'styled-components';
import { xxhashAsHex } from '@polkadot/util-crypto';
import qrcode from './qrcode';
import { createFrames, createImgSize } from './util';
interface Props extends BaseProps {
interface Props {
className?: string;
size?: string | number;
skipEncoding?: boolean;
style?: React.CSSProperties;
value: Uint8Array;
}
interface State {
interface FrameState {
frames: Uint8Array[];
frameIdx: number;
image: string | null;
valueHash: string | null;
}
interface TimerState {
timerDelay: number;
timerId: number | null;
valueHash: string | null;
}
const FRAME_DELAY = 2500;
@@ -40,99 +44,94 @@ function getDataUrl (value: Uint8Array): string {
return qr.createDataURL(16, 0);
}
class Display extends React.PureComponent<Props, State> {
public state: State = {
frameIdx: 0,
frames: [],
image: null,
timerDelay: FRAME_DELAY,
timerId: null,
valueHash: null
};
function Display ({ className, size, skipEncoding, style, value }: Props): React.ReactElement<Props> | null {
const [{ image }, setFrameState] = useState<FrameState>({ frameIdx: 0, frames: [], image: null, valueHash: null });
const [containerStyle, setContainerStyle] = useState(createImgSize(size));
const timerRef = useRef<TimerState>({ timerDelay: FRAME_DELAY, timerId: null });
public static getDerivedStateFromProps ({ skipEncoding = false, value }: Props, prevState: State): Pick<State, never> | null {
const valueHash = xxhashAsHex(value);
// run on initial load to setup the global timer and provide and unsubscribe
useEffect((): () => void => {
const nextFrame = () => setFrameState((state): FrameState => {
// when we have a single frame, we only ever fire once
if (state.frames.length <= 1) {
return state;
}
if (valueHash === prevState.valueHash) {
return null;
}
let frameIdx = state.frameIdx + 1;
const frames: Uint8Array[] = skipEncoding
? [value]
: createFrames(value);
// when we overflow, skip to the first and slightly increase the delay between frames
if (frameIdx === state.frames.length) {
frameIdx = 0;
timerRef.current.timerDelay = timerRef.current.timerDelay + TIMER_INC;
}
// encode on demand
return {
frameIdx: 0,
frames,
image: getDataUrl(frames[0]),
valueHash
timerRef.current.timerId = setTimeout(nextFrame, timerRef.current.timerDelay);
// only encode the frames on demand, not above as part of the
// state derivation - in the case of large payloads, this should
// be slightly more responsive on initial load
return {
...state,
frameIdx,
image: getDataUrl(state.frames[frameIdx])
};
});
timerRef.current.timerId = window.setTimeout(nextFrame, FRAME_DELAY);
return (): void => {
// eslint-disable-next-line react-hooks/exhaustive-deps
timerRef.current.timerId && clearTimeout(timerRef.current.timerId);
};
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
public componentDidMount (): void {
this.setState({
timerId: window.setTimeout(this.nextFrame, FRAME_DELAY)
useEffect((): void => {
setContainerStyle(createImgSize(size));
}, [size]);
useEffect((): void => {
setFrameState((state): FrameState => {
const valueHash = xxhashAsHex(value);
if (valueHash === state.valueHash) {
return state;
}
const frames: Uint8Array[] = skipEncoding
? [value]
: createFrames(value);
// encode on demand
return {
frameIdx: 0,
frames,
image: getDataUrl(frames[0]),
valueHash
};
});
}, [skipEncoding, value]);
if (!image) {
return null;
}
public componentWillUnmount (): void {
const { timerId } = this.state;
if (timerId) {
clearTimeout(timerId);
}
}
public render (): React.ReactNode {
const { className, size, style } = this.props;
const { image } = this.state;
if (!image) {
return null;
}
return (
return (
<div
className={className}
style={containerStyle}
>
<div
className={className}
style={createImgSize(size)}
className='ui--qr-Display'
style={style}
>
<div
className='ui--qr-Display'
style={style}
>
<img src={image} />
</div>
<img src={image} />
</div>
);
}
private nextFrame = (): void => {
const { frameIdx, frames, timerDelay } = this.state;
if (!frames || frames.length <= 1) {
return;
}
const nextIdx = frameIdx === frames.length - 1
? 0
: frameIdx + 1;
const nextDelay = timerDelay + ((nextIdx === 0) ? TIMER_INC : 0);
const timerId = setTimeout(this.nextFrame, nextDelay);
// only encode the frames on demand, not above as part of the
// state derivation - in the case of large payloads, this should
// be slightly more responsive on initial load
this.setState({
frameIdx: nextIdx,
image: getDataUrl(frames[nextIdx]),
timerDelay: nextDelay,
timerId
});
}
</div>
);
}
export default styled(Display as React.ComponentClass<Props>)`
export default React.memo(styled(Display)`
.ui--qr-Display {
height: 100%;
width: 100%;
@@ -146,4 +145,4 @@ export default styled(Display as React.ComponentClass<Props>)`
width: auto !important;
}
}
`;
`);
+4 -3
View File
@@ -2,16 +2,17 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { BaseProps } from './types';
import React, { useEffect, useState } from 'react';
import { createAddressPayload } from './util';
import QrDisplay from './Display';
interface Props extends BaseProps {
interface Props {
address: string;
genesisHash: string;
className?: string;
size?: string | number;
style?: React.CSSProperties;
}
function DisplayExtrinsic ({ address, className, genesisHash, size, style }: Props): React.ReactElement<Props> | null {
+4 -3
View File
@@ -2,18 +2,19 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { BaseProps } from './types';
import React, { useEffect, useState } from 'react';
import { createSignPayload } from './util';
import QrDisplay from './Display';
interface Props extends BaseProps {
interface Props {
address: string;
className?: string;
cmd: number;
genesisHash: Uint8Array | string;
payload: Uint8Array;
size?: string | number;
style?: React.CSSProperties;
}
function DisplayPayload ({ address, className, cmd, genesisHash, payload, size, style }: Props): React.ReactElement<Props> | null {
+4 -2
View File
@@ -6,12 +6,14 @@ import { NetworkSpecsStruct } from '@polkadot/ui-settings';
import React, { useEffect, useState } from 'react';
import QrDisplay from './Display';
import { BaseProps } from './types';
import { encodeString } from './util';
interface Props extends BaseProps {
interface Props {
className?: string;
networkSpecs: NetworkSpecsStruct;
size?: string | number;
style?: React.CSSProperties;
}
function DisplayNetworkSpecs ({ className, networkSpecs, size, style }: Props): React.ReactElement<Props> | null {
+15 -14
View File
@@ -2,18 +2,19 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { BaseProps } from './types';
import React, { useCallback } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import Reader from 'react-qr-reader';
import styled from 'styled-components';
import { createImgSize } from './util';
interface Props extends BaseProps {
interface Props {
className?: string;
delay?: number;
onError?: (error: Error) => void;
onScan?: (data: string) => void;
onScan: (data: string) => void;
size?: string | number;
style?: React.CSSProperties;
}
const DEFAULT_DELAY = 150;
@@ -23,26 +24,26 @@ const DEFAULT_ERROR = (error: Error): void => {
};
function Scan ({ className, delay = DEFAULT_DELAY, onError = DEFAULT_ERROR, onScan, size, style }: Props): React.ReactElement<Props> {
const [containerStyle, setContainerStyle] = useState(createImgSize(size));
useEffect((): void => {
setContainerStyle(createImgSize(size));
}, [size]);
const _onError = useCallback(
(error: Error): void => onError(error),
(error: Error) => onError(error),
[onError]
);
const _onScan = useCallback(
(data: string | null): void => {
if (!data || !onScan) {
return;
}
onScan(data);
},
(data: string | null) => data && onScan(data),
[onScan]
);
return (
<div
className={className}
style={createImgSize(size)}
style={containerStyle}
>
<Reader
className='ui--qr-Scan'
+17 -18
View File
@@ -2,8 +2,6 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { BaseProps } from './types';
import React, { useCallback } from 'react';
import { assert } from '@polkadot/util';
import { decodeAddress } from '@polkadot/util-crypto';
@@ -18,33 +16,34 @@ interface ScanType {
name?: string;
}
interface Props extends BaseProps {
interface Props {
className?: string;
onError?: (error: Error) => void;
onScan?: (scanned: ScanType) => void;
onScan: (scanned: ScanType) => void;
size?: string | number;
style?: React.CSSProperties;
}
function ScanAddress ({ className, onError, onScan, size, style }: Props): React.ReactElement<Props> {
const _onScan = useCallback(
(data: string | null): void => {
if (!data || !onScan) {
return;
}
if (data) {
try {
const [prefix, content, genesisHash, name] = data.split(':');
const isValidPrefix = prefix === ADDRESS_PREFIX || prefix === SEED_PREFIX;
try {
const [prefix, content, genesisHash, name] = data.split(':');
const isValidPrefix = prefix === ADDRESS_PREFIX || prefix === SEED_PREFIX;
assert(isValidPrefix, `Invalid prefix received, expected '${ADDRESS_PREFIX}/${SEED_PREFIX}' , found '${prefix}'`);
assert(isValidPrefix, `Invalid prefix received, expected '${ADDRESS_PREFIX}/${SEED_PREFIX}' , found '${prefix}'`);
const isAddress = prefix === ADDRESS_PREFIX;
const isAddress = prefix === ADDRESS_PREFIX;
if (isAddress) {
decodeAddress(content);
}
if (isAddress) {
decodeAddress(content);
onScan({ content, genesisHash, isAddress, name });
} catch (error) {
console.error('@polkadot/react-qr:QrScanAddress', (error as Error).message, data);
}
onScan({ content, genesisHash, isAddress, name });
} catch (error) {
console.error('@polkadot/react-qr:QrScanAddress', (error as Error).message, data);
}
},
[onScan]
+6 -11
View File
@@ -2,8 +2,6 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { BaseProps } from './types';
import React, { useCallback } from 'react';
import QrScan from './Scan';
@@ -12,20 +10,17 @@ interface ScanType {
signature: string;
}
interface Props extends BaseProps {
interface Props {
className?: string;
onError?: (error: Error) => void;
onScan?: (scanned: ScanType) => void;
onScan: (scanned: ScanType) => void;
size?: string | number;
style?: React.CSSProperties;
}
function ScanSignature ({ className, onError, onScan, size, style }: Props): React.ReactElement<Props> {
const _onScan = useCallback(
(signature: string | null): void => {
if (!signature || !onScan) {
return;
}
onScan({ signature: `0x${signature}` });
},
(signature: string | null) => signature && onScan({ signature: `0x${signature}` }),
[onScan]
);
-9
View File
@@ -1,9 +0,0 @@
// Copyright 2017-2020 @polkadot/react-qr authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export interface BaseProps {
className?: string;
size?: string | number;
style?: Record<string, string | number>;
}
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/reactnative-identicon",
"version": "0.54.1",
"version": "0.56.1",
"description": "Renders an SVG picture representing an address",
"main": "index.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
@@ -9,8 +9,8 @@
],
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.10.2",
"@polkadot/ui-shared": "0.54.1",
"@babel/runtime": "^7.10.5",
"@polkadot/ui-shared": "0.56.1",
"react-native-svg": "^12.1.0"
},
"peerDependencies": {
@@ -19,7 +19,7 @@
"react-native": "*"
},
"devDependencies": {
"@polkadot/util-crypto": "^2.14.1",
"@types/react-native": "^0.62.13"
"@polkadot/util-crypto": "^2.18.1",
"@types/react-native": "^0.63.1"
}
}
@@ -3,17 +3,13 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { Circle as CircleType } from '@polkadot/ui-shared/icons/types';
import { Props as BaseProps } from '../types';
import { Props } from '../types';
import React from 'react';
import { View } from 'react-native';
import Svg, { Circle as SvgCircle } from 'react-native-svg';
import { polkadotIcon } from '@polkadot/ui-shared';
interface Props extends BaseProps {
isAlternative?: boolean;
}
function renderCircle ({ cx, cy, fill, r }: CircleType, key: number): React.ReactNode {
return (
<SvgCircle
@@ -4,6 +4,7 @@
export interface Props {
address: string;
isAlternative?: boolean;
publicKey: string;
size: number;
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/ui-assets",
"version": "0.54.1",
"version": "0.56.1",
"description": "Static assets shared accross projects",
"main": "index.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
@@ -9,6 +9,6 @@
],
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.10.2"
"@babel/runtime": "^7.10.5"
}
}
+9 -9
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/ui-keyring",
"version": "0.54.1",
"version": "0.56.1",
"main": "index.js",
"repository": "https://github.com/polkadot-js/apps.git",
"author": "Jaco Greeff <jacogr@gmail.com>",
@@ -17,24 +17,24 @@
"./ledger/transportsWeb": "./ledger/transportsEmpty"
},
"dependencies": {
"@babel/runtime": "^7.10.2",
"@ledgerhq/hw-transport-webusb": "^5.16.0",
"ledger-polkadot": "^0.7.0",
"@babel/runtime": "^7.10.5",
"@ledgerhq/hw-transport-webusb": "^5.19.1",
"@zondax/ledger-polkadot": "^0.11.0",
"mkdirp": "^1.0.4",
"rxjs": "^6.5.5",
"rxjs": "^6.6.0",
"store": "^2.0.12"
},
"devDependencies": {
"@polkadot/keyring": "^2.14.1",
"@polkadot/types": "^1.19.1",
"@polkadot/util": "^2.14.1",
"@polkadot/keyring": "^2.18.1",
"@polkadot/types": "^1.25.1",
"@polkadot/util": "^2.18.1",
"@types/ledgerhq__hw-transport-node-hid": "^4.22.1",
"@types/ledgerhq__hw-transport-webusb": "^4.70.0",
"@types/mkdirp": "^1.0.1",
"@types/store": "^2.0.2"
},
"optionalDependencies": {
"@ledgerhq/hw-transport-node-hid": "^5.16.0"
"@ledgerhq/hw-transport-node-hid": "^5.19.1"
},
"peerDependencies": {
"@polkadot/keyring": "*",
+26 -14
View File
@@ -2,9 +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 Transport from '@ledgerhq/hw-transport';
import { LedgerAddress, LedgerSignature, LedgerTypes, LedgerVersion } from './types';
import LedgerApp, { ResponseBase } from 'ledger-polkadot';
import { ResponseBase, SubstrateApp, newKusamaApp, newPolkadotApp } from '@zondax/ledger-polkadot';
import { assert, bufferToU8a, u8aToBuffer, u8aToHex } from '@polkadot/util';
import allNode from './transportsNode';
@@ -20,36 +21,47 @@ const SUCCESS_CODE = 0x9000;
const transports = allNode.concat(allWeb);
const APPS: Record<string, (transport: Transport) => SubstrateApp> = {
kusama: newKusamaApp,
polkadot: newPolkadotApp
};
type Chain = keyof typeof APPS;
// A very basic wrapper for a ledger app -
// - it connects automatically, creating an app as required
// - Promises return errors (instead of wrapper errors)
export default class Ledger {
#app: LedgerApp | null = null;
#app: SubstrateApp | null = null;
#type: LedgerTypes;
#chain: Chain;
constructor (type: LedgerTypes) {
#transport: LedgerTypes;
constructor (transport: LedgerTypes, chain: Chain) {
// u2f is deprecated
assert(['hid', 'webusb'].includes(type), `Unsupported transport ${type}`);
assert(['hid', 'webusb'].includes(transport), `Unsupported transport ${transport}`);
assert(Object.keys(APPS).includes(chain), `Unsupported chain ${chain}`);
this.#type = type;
this.#chain = chain;
this.#transport = transport;
}
private async _getApp (): Promise<LedgerApp> {
private async _getApp (): Promise<SubstrateApp> {
if (!this.#app) {
const def = transports.find(({ type }) => type === this.#type);
const def = transports.find(({ type }) => type === this.#transport);
assert(def, `Unable to find a transport for ${this.#type}`);
assert(def, `Unable to find a transport for ${this.#transport}`);
const transport = await def.create();
this.#app = new LedgerApp(transport);
this.#app = APPS[this.#chain](transport);
}
return this.#app;
}
private async _withApp <T> (fn: (app: LedgerApp) => Promise<T>): Promise<T> {
private async _withApp <T> (fn: (app: SubstrateApp) => Promise<T>): Promise<T> {
try {
const app = await this._getApp();
@@ -70,7 +82,7 @@ export default class Ledger {
}
public async getAddress (confirm = false, account = LEDGER_DEFAULT_ACCOUNT, change = LEDGER_DEFAULT_CHANGE, addressIndex = LEDGER_DEFAULT_INDEX): Promise<LedgerAddress> {
return this._withApp(async (app: LedgerApp): Promise<LedgerAddress> => {
return this._withApp(async (app: SubstrateApp): Promise<LedgerAddress> => {
const { address, pubKey } = await this._wrapError(app.getAddress(account, change, addressIndex, confirm));
return {
@@ -81,7 +93,7 @@ export default class Ledger {
}
public async getVersion (): Promise<LedgerVersion> {
return this._withApp(async (app: LedgerApp): Promise<LedgerVersion> => {
return this._withApp(async (app: SubstrateApp): Promise<LedgerVersion> => {
const { device_locked: isLocked, major, minor, patch, test_mode: isTestMode } = await this._wrapError(app.getVersion());
return {
@@ -93,7 +105,7 @@ export default class Ledger {
}
public async sign (message: Uint8Array, account = LEDGER_DEFAULT_ACCOUNT, change = LEDGER_DEFAULT_CHANGE, addressIndex = LEDGER_DEFAULT_INDEX): Promise<LedgerSignature> {
return this._withApp(async (app: LedgerApp): Promise<LedgerSignature> => {
return this._withApp(async (app: SubstrateApp): Promise<LedgerSignature> => {
const buffer = u8aToBuffer(message);
const { signature } = await this._wrapError(app.sign(account, change, addressIndex, buffer));
+20 -7
View File
@@ -7,6 +7,7 @@ import { KeyringStore, KeyringJson } from '../types';
import fs from 'fs';
import mkdirp from 'mkdirp';
import path from 'path';
import { assert } from '@polkadot/util';
// NOTE untested and unused by any known apps, probably broken in various mysterious ways
export default class FileStore implements KeyringStore {
@@ -23,14 +24,20 @@ export default class FileStore implements KeyringStore {
public all (cb: (key: string, value: KeyringJson) => void): void {
fs
.readdirSync(this.#path)
.filter((key): boolean => !['.', '..'].includes(key))
.filter((key): boolean => !['.', '..', '.DS_Store'].includes(key))
.forEach((key): void => {
cb(key, this._readKey(key));
const value = this._readKey(key);
value?.address && cb(key, value);
});
}
public get (key: string, cb: (value: KeyringJson) => void): void {
cb(this._readKey(key));
const value = this._readKey(key);
assert(value?.address, `Invalid JSON found for ${key}`);
cb(value);
}
public remove (key: string, cb?: () => void): void {
@@ -47,9 +54,15 @@ export default class FileStore implements KeyringStore {
return path.join(this.#path, key);
}
private _readKey (key: string): KeyringJson {
return JSON.parse(
fs.readFileSync(this._getPath(key)).toString('utf-8')
) as KeyringJson;
private _readKey (key: string): KeyringJson | undefined {
try {
return JSON.parse(
fs.readFileSync(this._getPath(key)).toString('utf-8')
) as KeyringJson;
} catch (error) {
console.error(error);
}
return undefined;
}
}
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/ui-settings",
"version": "0.54.1",
"version": "0.56.1",
"description": "Manages app settings",
"main": "index.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
@@ -9,12 +9,12 @@
],
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.10.2",
"@babel/runtime": "^7.10.5",
"eventemitter3": "^4.0.4",
"store": "^2.0.12"
},
"devDependencies": {
"@polkadot/util": "^2.14.1",
"@polkadot/util": "^2.18.1",
"@types/store": "^2.0.2"
},
"peerDependencies": {
@@ -9,6 +9,9 @@ const chains: Record<string, ChainDef> = {
'0x3fd7b9eb6a00376e5be61f01abb429ffb0b104be05eaff4d458da48fcd425baf', // Kusama CC1
'0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636', // Kusama CC2
'0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe' // Kusama CC3
],
polkadot: [
'0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3' // Polkadot CC1
]
};
@@ -33,5 +33,10 @@ export const PREFIXES: Option[] = [
info: 'edgeware',
text: 'Edgeware (live)',
value: 7
},
{
info: 'kulupu',
text: 'Kulupu (live)',
value: 16
}
];
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/ui-shared",
"version": "0.54.1",
"version": "0.56.1",
"description": "Shared logic that is usable accross all frameworks-specific areas",
"main": "index.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
@@ -9,7 +9,7 @@
],
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.10.2",
"@babel/runtime": "^7.10.5",
"color": "^3.1.2"
},
"peerDependencies": {
@@ -17,8 +17,8 @@
"@polkadot/util-crypto": "*"
},
"devDependencies": {
"@polkadot/util": "^2.14.1",
"@polkadot/util-crypto": "^2.14.1",
"@polkadot/util": "^2.18.1",
"@polkadot/util-crypto": "^2.18.1",
"@types/color": "^3.0.1",
"@types/xmlserializer": "^0.6.0"
}
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/vue-identicon",
"version": "0.54.1",
"version": "0.56.1",
"description": "Renders an SVG picture representing an address",
"author": "Jaco Greeff <jacogr@gmail.com>",
"maintainers": [
@@ -9,8 +9,8 @@
"main": "index.js",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.10.2",
"@polkadot/ui-shared": "0.54.1",
"@babel/runtime": "^7.10.5",
"@polkadot/ui-shared": "0.56.1",
"jdenticon": "2.2.0"
},
"peerDependencies": {
@@ -18,7 +18,7 @@
"vue": "*"
},
"devDependencies": {
"@polkadot/util-crypto": "^2.14.1",
"@polkadot/util-crypto": "^2.18.1",
"vue": "^2.6.11"
}
}
+1950 -2001
View File
File diff suppressed because it is too large Load Diff