diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bf031dc5a54..565bc31d6ec2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,36 @@ +# 0.39.1 + +- **Breaking** Drop support for V1 Substrate chains +- Translation into Chinese (Thanks to https://github.com/dushaobindoudou) +- Support for sign-only transactions (Thanks to https://github.com/mzolkiewski) +- Add support for WestEnd testnet +- Add support for social recovery in accounts +- Add counters for all proposal-based apps +- Disable spellcheck on all input fields (privacy) +- Query the paymentInfo API to get weight fee information +- Remove FF warning with https:// -> ws://localhost +- Staking now supports where the controller or stash accounts are not local +- Social app +- Add support for identity setting (via identity module) +- Add support for registrars to hand out identity judgements +- Use both internal and lib hooks as applicable (refactoring) +- Support QR codes (accounts) with optional names +- Cleanup all Modals, simplify +- Adjust balance display formats +- Update to latest libraries (incl. util 2.0 & api 1.0) + +# 0.38.1 + +- Fix summarybar in 123-code (Thanks to https://github.com/anakornk) +- Update Edgeware with correct keys (Thanks to https://github.com/drewstone) +- Add InputAddressMulti inputs, both to council and staking nominators +- Rework all layouts, removing cards for table-ike-layouts +- Technical comittee app +- Allow for external proposal and queued for dispatch in democracy +- Add pre-image support to democracy proposals (including imminent) +- Improved staking page rendering (background) +- Update to latest libraries + # 0.37.1 - Support for Kusama CC3 diff --git a/Dockerfile b/Dockerfile index e728afda0cfd..02bfc440e82e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,19 +7,18 @@ RUN apt-get update && apt-get install -y curl git gnupg RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - RUN apt-get install -y nodejs -WORKDIR /app -RUN git clone https://github.com/polkadot-js/apps +WORKDIR /apps +COPY . . -WORKDIR /app/apps RUN npm install yarn -g RUN yarn -RUN NODE_ENV=production yarn build +RUN NODE_ENV=production yarn build:www FROM ubuntu:18.04 RUN apt-get update && apt-get -y install nginx -COPY --from=builder /app/apps/packages/apps/build /var/www/html +COPY --from=builder /apps/packages/apps/build /var/www/html EXPOSE 80 diff --git a/i18next-scanner.config.js b/i18next-scanner.config.js index eea325d2bcd1..767e240d4756 100644 --- a/i18next-scanner.config.js +++ b/i18next-scanner.config.js @@ -1,7 +1,38 @@ +// Copyright 2017-2020 @polkadot/apps authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + const fs = require('fs'); const path = require('path'); const typescript = require('typescript'); +const findPackages = require('./scripts/findPackages'); + +function transform (file, enc, done) { + const { ext } = path.parse(file.path); + + if (ext === '.tsx') { + const content = fs.readFileSync(file.path, enc); + + const { outputText } = typescript.transpileModule(content, { + compilerOptions: { + target: 'es2018' + }, + fileName: path.basename(file.path) + }); + + const parserHandler = (key, options) => { + options.defaultValue = key; + options.ns = /packages\/(.*?)\/src/g.exec(file.path)[1]; + this.parser.set(key, options); + }; + + this.parser.parseFuncFromString(outputText, parserHandler); + } + + done(); +} + module.exports = { input: [ 'packages/*/src/**/*.{ts,tsx}', @@ -15,44 +46,14 @@ module.exports = { debug: true, func: { list: ['t', 'i18next.t', 'i18n.t'], - extensions: ['.tsx'] + extensions: ['.tsx', '.ts'] }, trans: { component: 'Trans' }, lngs: ['en'], defaultLng: 'en', - ns: [ - 'app-123code', - 'app-accounts', - 'app-address-book', - 'app-claims', - 'app-contracts', - 'app-council', - 'app-dashboard', - 'app-democracy', - 'app-explorer', - 'app-extrinsics', - 'app-generic-asset', - 'app-js', - 'app-parachains', - 'app-settings', - 'app-staking', - 'app-storage', - 'app-sudo', - 'app-tech-comm', - 'app-toolbox', - 'app-transfer', - 'app-treasury', - 'apps', - 'apps-routing', - 'react-api', - 'react-components', - 'react-params', - 'react-query', - 'react-signer', - 'ui' - ], + ns: findPackages().map(({ dir }) => dir), defaultNs: 'ui', resource: { loadPath: 'packages/apps/public/locales/{{lng}}/{{ns}}.json', @@ -63,28 +64,5 @@ module.exports = { nsSeparator: false, // namespace separator keySeparator: false // key separator }, - transform: function transform (file, enc, done) { - const { ext } = path.parse(file.path); - - if (ext === '.tsx') { - const content = fs.readFileSync(file.path, enc); - - const { outputText } = typescript.transpileModule(content, { - compilerOptions: { - target: 'es2018' - }, - fileName: path.basename(file.path) - }); - - const parserHandler = (key, options) => { - options.defaultValue = key; - options.ns = /packages\/(.*?)\/src/g.exec(file.path)[1]; - this.parser.set(key, options); - }; - - this.parser.parseFuncFromString(outputText, parserHandler); - } - - done(); - } + transform }; diff --git a/lerna.json b/lerna.json index 09eaa21766d2..54613fb47579 100644 --- a/lerna.json +++ b/lerna.json @@ -10,5 +10,5 @@ "packages": [ "packages/*" ], - "version": "0.39.0-beta.40" + "version": "0.40.0-beta.11" } diff --git a/package.json b/package.json index a92216d3ae1c..dceaddf8131c 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "0.39.0-beta.40", + "version": "0.40.0-beta.11", "private": true, "engines": { "node": ">=10.13.0", @@ -10,36 +10,37 @@ "packages/*" ], "resolutions": { - "@polkadot/api": "^0.100.0-beta.27", - "@polkadot/api-contract": "^0.100.0-beta.27", - "@polkadot/keyring": "^1.8.1", - "@polkadot/types": "^0.100.0-beta.27", - "@polkadot/util": "^1.8.1", - "@polkadot/util-crypto": "^1.8.1", + "@polkadot/api": "^1.1.0-beta.20", + "@polkadot/api-contract": "^1.1.0-beta.20", + "@polkadot/keyring": "^2.1.1", + "@polkadot/types": "^1.1.0-beta.20", + "@polkadot/util": "^2.1.1", + "@polkadot/util-crypto": "^2.1.1", "babel-core": "^7.0.0-bridge.0", - "typescript": "^3.7.4" + "typescript": "^3.7.5" }, "scripts": { "analyze": "yarn run build && cd packages/apps && yarn run source-map-explorer build/main.*.js", - "build": "yarn run build:code && yarn run build:i18n", + "build": "yarn run build:i18n && yarn run build:code", "build:code": "NODE_ENV=production polkadot-dev-build-ts", "build:i18n": "i18next-scanner --config i18next-scanner.config.js", + "build:www": "rm -rf packages/apps/build && mkdir -p packages/apps/build && yarn run build:i18n && cd packages/apps && NODE_ENV=production webpack --config webpack.config.js", "docs": "echo \"skipping docs\"", "clean": "polkadot-dev-clean-build", "clean:i18n": "rm -rf packages/apps/public/locales/en && mkdir -p packages/apps/public/locales/en", "lint": "eslint --ext .js,.jsx,.ts,.tsx . && tsc --noEmit --pretty", "postinstall": "polkadot-dev-yarn-only", - "test": "echo \"skipping tests\"", + "test": "jest packages/app-claims/src", "vanitygen": "node packages/app-accounts/scripts/vanitygen.js", "start": "cd packages/apps && webpack --config webpack.config.js" }, "devDependencies": { - "@babel/core": "^7.7.7", + "@babel/core": "^7.8.3", "@babel/register": "^7.7.7", - "@babel/runtime": "^7.7.7", - "@polkadot/dev-react": "^0.32.14", - "@polkadot/ts": "^0.1.90", - "autoprefixer": "^9.7.1", + "@babel/runtime": "^7.8.3", + "@polkadot/dev-react": "^0.33.3", + "@polkadot/ts": "^0.2.1", + "autoprefixer": "^9.7.4", "empty": "^0.10.1", "html-loader": "^0.5.5", "i18next-scanner": "^2.10.3", @@ -53,6 +54,6 @@ "postcss-sass": "^0.4.1", "postcss-simple-vars": "^5.0.0", "precss": "^4.0.0", - "source-map-explorer": "^2.1.0" + "source-map-explorer": "^2.2.2" } } diff --git a/packages/app-123code/package.json b/packages/app-123code/package.json index f78c96b5ea42..235bb9b7588c 100644 --- a/packages/app-123code/package.json +++ b/packages/app-123code/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-123code", - "version": "0.39.0-beta.40", + "version": "0.40.0-beta.11", "description": "A basic app that shows the ropes on customisation", "main": "index.js", "scripts": {}, @@ -10,7 +10,7 @@ ], "license": "Apache-2.0", "dependencies": { - "@babel/runtime": "^7.7.7", - "@polkadot/react-components": "^0.39.0-beta.40" + "@babel/runtime": "^7.8.3", + "@polkadot/react-components": "^0.40.0-beta.11" } } diff --git a/packages/app-123code/src/Transfer.tsx b/packages/app-123code/src/Transfer.tsx index 98102378d6c8..7966334832cd 100644 --- a/packages/app-123code/src/Transfer.tsx +++ b/packages/app-123code/src/Transfer.tsx @@ -37,6 +37,7 @@ export default function Transfer ({ accountId }: Props): React.ReactElement diff --git a/packages/app-accounts/package.json b/packages/app-accounts/package.json index f97ad4e966ae..ea28ac40eee3 100644 --- a/packages/app-accounts/package.json +++ b/packages/app-accounts/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-accounts", - "version": "0.39.0-beta.40", + "version": "0.40.0-beta.11", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -10,11 +10,11 @@ "contributors": [], "license": "Apache-2.0", "dependencies": { - "@babel/runtime": "^7.7.7", - "@polkadot/react-components": "^0.39.0-beta.40", - "@polkadot/react-qr": "^0.48.0-beta.8", + "@babel/runtime": "^7.8.3", + "@polkadot/react-components": "^0.40.0-beta.11", + "@polkadot/react-qr": "^0.49.0-beta.2", "@types/file-saver": "^2.0.0", - "@types/yargs": "^13.0.2", + "@types/yargs": "^15.0.2", "detect-browser": "^4.8.0", "file-saver": "^2.0.0", "yargs": "^15.0.2" diff --git a/packages/app-accounts/src/Account.tsx b/packages/app-accounts/src/Account.tsx index ec994c1691dd..d62be808c955 100644 --- a/packages/app-accounts/src/Account.tsx +++ b/packages/app-accounts/src/Account.tsx @@ -4,18 +4,23 @@ import { DeriveAccountInfo } from '@polkadot/api-derive/types'; import { ActionStatus } from '@polkadot/react-components/Status/types'; +import { RecoveryConfig } from '@polkadot/types/interfaces'; import React, { useState, useEffect } from 'react'; import { Label } from 'semantic-ui-react'; import styled from 'styled-components'; -import { AddressInfo, AddressSmall, Button, ChainLock, Forget, Icon, InputTags, LinkPolkascan, Menu, Popup, Input } from '@polkadot/react-components'; +import { AddressInfo, AddressSmall, Badge, Button, ChainLock, Forget, Icon, IdentityIcon, InputTags, LinkPolkascan, Menu, Popup, Input } from '@polkadot/react-components'; import { useApi, useCall, useToggle } from '@polkadot/react-hooks'; +import { Option } from '@polkadot/types'; import keyring from '@polkadot/ui-keyring'; +import { formatBalance, formatNumber } from '@polkadot/util'; import Backup from './modals/Backup'; import ChangePass from './modals/ChangePass'; import Derive from './modals/Derive'; import Identity from './modals/Identity'; +import RecoverAccount from './modals/RecoverAccount'; +import RecoverSetup from './modals/RecoverSetup'; import Transfer from './modals/Transfer'; import { useTranslation } from './translate'; @@ -31,6 +36,10 @@ function Account ({ address, className, filter, isFavorite, toggleFavorite }: Pr const { t } = useTranslation(); const api = useApi(); const info = useCall(api.api.derive.accounts.info as any, [address]); + const recoveryInfo = useCall(api.api.query.recovery?.recoverable, [address], { + transform: (opt: Option): RecoveryConfig | null => + opt.unwrapOr(null) + }); const [tags, setTags] = useState([]); const [accName, setAccName] = useState(''); const [genesisHash, setGenesisHash] = useState(null); @@ -43,6 +52,8 @@ function Account ({ address, className, filter, isFavorite, toggleFavorite }: Pr const [isForgetOpen, toggleForget] = useToggle(); const [isIdentityOpen, toggleIdentity] = useToggle(); const [isPasswordOpen, togglePassword] = useToggle(); + const [isRecoverAccountOpen, toggleRecoverAccount] = useToggle(); + const [isRecoverSetupOpen, toggleRecoverSetup] = useToggle(); const [isSettingsOpen, toggleSettings] = useToggle(); const [isTransferOpen, toggleTransfer] = useToggle(); @@ -51,7 +62,7 @@ function Account ({ address, className, filter, isFavorite, toggleFavorite }: Pr useEffect((): void => { const { identity, nickname } = info || {}; - if (api.api.query.identity?.identityOf) { + if (api.api.query.identity && api.api.query.identity.identityOf) { if (identity?.display) { setAccName(identity.display); } @@ -63,14 +74,14 @@ function Account ({ address, className, filter, isFavorite, toggleFavorite }: Pr useEffect((): void => { const account = keyring.getAccount(address); - setGenesisHash((account && account.meta.genesisHash) || null); + setGenesisHash(account?.meta.genesisHash || null); setFlags({ - isDevelopment: (account && account.meta.isTesting) || false, + isDevelopment: account?.meta.isTesting || false, isEditable: (account && !(account.meta.isInjected || account.meta.isHardware)) || false, - isExternal: (account && account.meta.isExternal) || false + isExternal: account?.meta.isExternal || false }); - _setTags(account?.meta?.tags || []); - setAccName(account?.meta?.name || ''); + _setTags(account?.meta.tags || []); + setAccName(account?.meta.name || ''); }, [address]); useEffect((): void => { @@ -158,6 +169,46 @@ function Account ({ address, className, filter, isFavorite, toggleFavorite }: Pr onClick={_onFavorite} /> + + {recoveryInfo && ( + +

{t('This account is recoverable, with the following friends:')}

+
+ {recoveryInfo.friends.map((friend, index): React.ReactNode => ( + + ))} +
+ + + + + + + + + + + + + + + +
{t('threshold')}{formatNumber(recoveryInfo.threshold)}
{t('delay')}{formatNumber(recoveryInfo.delayPeriod)}
{t('deposit')}{formatBalance(recoveryInfo.deposit)}
+ + } + info={} + isInline + isTooltip + type='online' + /> + )} + )} + {isRecoverAccountOpen && ( + + )} + {isRecoverSetupOpen && ( + + )} {isEditingTags @@ -321,6 +386,19 @@ function Account ({ address, className, filter, isFavorite, toggleFavorite }: Pr > {t('Forget this account')} + {api.api.tx.recovery?.createRecovery && ( + <> + + {!recoveryInfo && ( + + {t('Make recoverable')} + + )} + + {t('Initiate recovery for another')} + + + )} {!api.isDevelopment && ( <> diff --git a/packages/app-accounts/src/Overview.tsx b/packages/app-accounts/src/Overview.tsx index 244bc1a28670..1fc9405c3989 100644 --- a/packages/app-accounts/src/Overview.tsx +++ b/packages/app-accounts/src/Overview.tsx @@ -2,6 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. +import { KeyringAddress } from '@polkadot/ui-keyring/types'; import { ComponentProps as Props } from './types'; import React, { useEffect, useState } from 'react'; @@ -49,6 +50,12 @@ function Overview ({ className, onStatusChange }: Props): React.ReactElement ({ address, isFavorite: favorites.includes(address) })) + .sort((a, b): number => { + const accA = keyring.getAccount(a.address) as KeyringAddress; + const accB = keyring.getAccount(b.address) as KeyringAddress; + + return (accA.meta.whenCreated || 0) - (accB.meta.whenCreated || 0); + }) .sort((a, b): number => a.isFavorite === b.isFavorite ? 0 @@ -122,6 +129,7 @@ function Overview ({ className, onStatusChange }: Props): React.ReactElement
(['vanity']); + const items = useMemo(() => [ + { + isRoot: true, + name: 'overview', + text: t('My accounts') + }, + { + name: 'vanity', + text: t('Vanity address') + } + ], [t]); useEffect((): void => { setHidden( @@ -42,17 +53,7 @@ export default function AccountsApp ({ basePath, onStatusChange }: Props): React
- - -