diff --git a/jest.config.js b/jest.config.js index 65d8ea1d37..077344691d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,7 +2,7 @@ const config = require('@polkadot/dev-react/config/jest'); module.exports = Object.assign({}, config, { moduleNameMapper: { - '@polkadot/app-(accounts|addresses|democracy|example|explorer|extrinsics|rpc|staking|storage|toolbox|vanitygen)(.*)$': '/packages/ui-$1/src/$2', + '@polkadot/app-(accounts|addresses|democracy|example|explorer|extrinsics|rpc|staking|storage|toolbox|transfer|vanitygen)(.*)$': '/packages/ui-$1/src/$2', '@polkadot/ui-(app|identicon|keyring|react-rx|react|signer)(.*)$': '/packages/ui-$1/src/$2', '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': 'empty/object', '\\.(css|less)$': 'empty/object' diff --git a/lerna.json b/lerna.json index 4a160603fc..0b4f2092ee 100644 --- a/lerna.json +++ b/lerna.json @@ -10,5 +10,5 @@ "packages": [ "packages/*" ], - "version": "0.19.61" + "version": "0.20.0" } diff --git a/package.json b/package.json index 7438b3a8f8..7475439665 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ }, "devDependencies": { "@polkadot/dev-react": "^0.20.19", - "@polkadot/ts": "^0.1.25", + "@polkadot/ts": "^0.1.27", "autoprefixer": "^9.1.5", "babel-loader": "^8.0.2", "css-loader": "^1.0.0", diff --git a/packages/app-accounts/package.json b/packages/app-accounts/package.json index 25a7248303..06abed6d33 100644 --- a/packages/app-accounts/package.json +++ b/packages/app-accounts/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-accounts", - "version": "0.19.61", + "version": "0.20.0", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -11,6 +11,6 @@ "license": "ISC", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/ui-app": "^0.19.61" + "@polkadot/ui-app": "^0.20.0" } } diff --git a/packages/app-addresses/package.json b/packages/app-addresses/package.json index b2236a2396..1547395fd2 100644 --- a/packages/app-addresses/package.json +++ b/packages/app-addresses/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-addresses", - "version": "0.19.61", + "version": "0.20.0", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -11,6 +11,6 @@ "license": "ISC", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/ui-app": "^0.19.61" + "@polkadot/ui-app": "^0.20.0" } } diff --git a/packages/app-democracy/package.json b/packages/app-democracy/package.json index 2205af1e3c..88d7659a92 100644 --- a/packages/app-democracy/package.json +++ b/packages/app-democracy/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-democracy", - "version": "0.19.61", + "version": "0.20.0", "description": "A referendum & proposal app", "main": "index.js", "scripts": {}, @@ -11,9 +11,9 @@ "license": "ISC", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/storage": "^0.28.28", - "@polkadot/ui-react": "^0.19.61", - "@polkadot/ui-react-rx": "^0.19.61", - "@polkadot/util-keyring": "^0.29.32" + "@polkadot/storage": "^0.28.29", + "@polkadot/ui-react": "^0.20.0", + "@polkadot/ui-react-rx": "^0.20.0", + "@polkadot/util-keyring": "^0.29.33" } } diff --git a/packages/app-example/package.json b/packages/app-example/package.json index 1d95c26615..42a58702af 100644 --- a/packages/app-example/package.json +++ b/packages/app-example/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-example", - "version": "0.19.61", + "version": "0.20.0", "description": "A basic example app", "main": "index.js", "scripts": {}, @@ -11,9 +11,9 @@ "license": "ISC", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/storage": "^0.28.28", - "@polkadot/ui-react": "^0.19.61", - "@polkadot/ui-react-rx": "^0.19.61", - "@polkadot/util-keyring": "^0.29.32" + "@polkadot/storage": "^0.28.29", + "@polkadot/ui-react": "^0.20.0", + "@polkadot/ui-react-rx": "^0.20.0", + "@polkadot/util-keyring": "^0.29.33" } } diff --git a/packages/app-explorer/package.json b/packages/app-explorer/package.json index 2a667fd452..e40500edf1 100644 --- a/packages/app-explorer/package.json +++ b/packages/app-explorer/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-explorer", - "version": "0.19.61", + "version": "0.20.0", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -11,8 +11,8 @@ "license": "ISC", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/primitives": "^0.28.28", - "@polkadot/ui-app": "^0.19.61", - "@polkadot/util-crypto": "^0.29.32" + "@polkadot/primitives": "^0.28.29", + "@polkadot/ui-app": "^0.20.0", + "@polkadot/util-crypto": "^0.29.33" } } diff --git a/packages/app-extrinsics/package.json b/packages/app-extrinsics/package.json index 7e7298067d..6493b2789e 100644 --- a/packages/app-extrinsics/package.json +++ b/packages/app-extrinsics/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-extrinsics", - "version": "0.19.61", + "version": "0.20.0", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -11,8 +11,8 @@ "license": "ISC", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/extrinsics": "^0.28.28", - "@polkadot/ui-app": "^0.19.61", - "@polkadot/ui-signer": "^0.19.61" + "@polkadot/extrinsics": "^0.28.29", + "@polkadot/ui-app": "^0.20.0", + "@polkadot/ui-signer": "^0.20.0" } } diff --git a/packages/app-rpc/package.json b/packages/app-rpc/package.json index 0b5524d1e4..12d81f16c2 100644 --- a/packages/app-rpc/package.json +++ b/packages/app-rpc/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-rpc", - "version": "0.19.61", + "version": "0.20.0", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -11,8 +11,8 @@ "license": "ISC", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/ui-app": "^0.19.61", - "@polkadot/ui-keyring": "^0.19.61", - "@polkadot/ui-signer": "^0.19.61" + "@polkadot/ui-app": "^0.20.0", + "@polkadot/ui-keyring": "^0.20.0", + "@polkadot/ui-signer": "^0.20.0" } } diff --git a/packages/app-staking/package.json b/packages/app-staking/package.json index 4f43bf3f39..8d74fa0f2c 100644 --- a/packages/app-staking/package.json +++ b/packages/app-staking/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-staking", - "version": "0.19.61", + "version": "0.20.0", "description": "A basic staking app", "main": "index.js", "scripts": {}, @@ -11,12 +11,12 @@ "license": "ISC", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/app-extrinsics": "^0.19.61", - "@polkadot/storage": "^0.28.28", - "@polkadot/ui-app": "^0.19.61", - "@polkadot/ui-keyring": "^0.19.61", - "@polkadot/ui-react": "^0.19.61", - "@polkadot/ui-react-rx": "^0.19.61", - "@polkadot/util-keyring": "^0.29.32" + "@polkadot/app-extrinsics": "^0.20.0", + "@polkadot/storage": "^0.28.29", + "@polkadot/ui-app": "^0.20.0", + "@polkadot/ui-keyring": "^0.20.0", + "@polkadot/ui-react": "^0.20.0", + "@polkadot/ui-react-rx": "^0.20.0", + "@polkadot/util-keyring": "^0.29.33" } } diff --git a/packages/app-storage/package.json b/packages/app-storage/package.json index f1d3f1faaa..0cbd6f2904 100644 --- a/packages/app-storage/package.json +++ b/packages/app-storage/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-storage", - "version": "0.19.61", + "version": "0.20.0", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -11,6 +11,6 @@ "license": "ISC", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/ui-app": "^0.19.61" + "@polkadot/ui-app": "^0.20.0" } } diff --git a/packages/app-toolbox/package.json b/packages/app-toolbox/package.json index 049cbf8f44..e63a9084b5 100644 --- a/packages/app-toolbox/package.json +++ b/packages/app-toolbox/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-toolbox", - "version": "0.19.61", + "version": "0.20.0", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -11,7 +11,7 @@ "license": "ISC", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/ui-app": "^0.19.61", - "@polkadot/ui-keyring": "^0.19.61" + "@polkadot/ui-app": "^0.20.0", + "@polkadot/ui-keyring": "^0.20.0" } } diff --git a/packages/app-transfer/LICENSE b/packages/app-transfer/LICENSE new file mode 100644 index 0000000000..a24e25df8b --- /dev/null +++ b/packages/app-transfer/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017-2018 @polkadot/app-transfer authors & contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/app-transfer/README.md b/packages/app-transfer/README.md new file mode 100644 index 0000000000..2823a5a361 --- /dev/null +++ b/packages/app-transfer/README.md @@ -0,0 +1,3 @@ +# @polkadot/app-transfer + +A basic DOT transfer application, allowing the movement of funds from one account to another. diff --git a/packages/app-transfer/package.json b/packages/app-transfer/package.json new file mode 100644 index 0000000000..63bd22dcb2 --- /dev/null +++ b/packages/app-transfer/package.json @@ -0,0 +1,18 @@ +{ + "name": "@polkadot/app-transfer", + "version": "0.20.0", + "description": "A basic transfer app", + "main": "index.js", + "scripts": {}, + "author": "Jaco Greeff ", + "maintainers": [ + "Jaco Greeff " + ], + "license": "ISC", + "dependencies": { + "@babel/runtime": "^7.0.0", + "@polkadot/ui-app": "^0.20.0", + "@polkadot/ui-keyring": "^0.20.0", + "@polkadot/ui-react-rx": "^0.20.0" + } +} diff --git a/packages/app-transfer/src/Fees.tsx b/packages/app-transfer/src/Fees.tsx new file mode 100644 index 0000000000..1541d41531 --- /dev/null +++ b/packages/app-transfer/src/Fees.tsx @@ -0,0 +1,166 @@ +// Copyright 2017-2018 @polkadot/app-transfer authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { I18nProps } from '@polkadot/ui-app/types'; +import { RxBalance, RxFees } from '@polkadot/ui-react-rx/ApiObservable/types'; +import { Fees } from './types'; + +import BN from 'bn.js'; +import React from 'react'; +import Static from '@polkadot/ui-app/Static'; +import withMulti from '@polkadot/ui-react-rx/with/multi'; +import withObservable from '@polkadot/ui-react-rx/with/observable'; + +import translate from './translate'; + +type State = Fees; + +type Props = I18nProps & { + amount: BN, + balanceFrom?: RxBalance, + balanceTo?: RxBalance, + fees: RxFees, + from?: Uint8Array | null, + to?: Uint8Array | null, + onChange: (fees: Fees) => void +}; + +const ZERO = new BN(0); +const ZERO_BALANCE = { + freeBalance: ZERO, + votingBalance: ZERO +} as RxBalance; + +// FIXME Ok, this is really not cool. Based on the actual transaction we should calculate the size. However currently bacause of the "fully distant" nature of the signer component, we cannot really properly calculate the final size. So count it... and then fix it. (This needs to be sorted) +const TRANSFER_SIZE = 156; + +class FeeDisplay extends React.PureComponent { + constructor (props: Props) { + super(props); + + this.state = { + hasAvailable: false, + isCreation: false, + isNoEffect: false, + isRemovable: false, + isReserved: false, + txfees: ZERO, + txtotal: ZERO + }; + } + + static getDerivedStateFromProps ({ amount, to, from, fees, balanceTo = ZERO_BALANCE, balanceFrom = ZERO_BALANCE }: Props): State | null { + if (!from || !to) { + return null; + } + + let txfees = fees.baseFee + .add(fees.transferFee) + .add(fees.byteFee.muln(TRANSFER_SIZE)); + + if (balanceTo.votingBalance.isZero()) { + txfees = txfees.add(fees.creationFee); + } + + const txtotal = amount.add(txfees); + const hasAvailable = balanceFrom.freeBalance.gte(txtotal); + const isCreation = balanceTo.votingBalance.isZero(); + const isNoEffect = amount.add(balanceTo.votingBalance).lte(fees.existentialDeposit); + const isRemovable = balanceFrom.votingBalance.sub(txtotal).lte(fees.existentialDeposit); + const isReserved = balanceFrom.freeBalance.isZero() && balanceFrom.reservedBalance.gtn(0); + + return { + hasAvailable, + isCreation, + isNoEffect, + isRemovable, + isReserved, + txfees, + txtotal + }; + } + + componentDidUpdate () { + const { onChange } = this.props; + + onChange(this.state); + } + + render () { + const { className, fees, from, to, t } = this.props; + const { hasAvailable, isCreation, isNoEffect, isRemovable, isReserved, txfees, txtotal } = this.state; + + if (!from || !to) { + return null; + } + + return [ + , +
+ { + isRemovable && hasAvailable + ? t('fees.remove', { + defaultValue: 'Submitting this transaction will drop the account balance to below the existential amount, removing the account from the chain state and burning associated funds. ' + }) + : undefined + }{ + isNoEffect && hasAvailable + ? t('fees.noeffect', { + defaultValue: 'The final recipient amount is less than the existential amount, hence the total will be deducted from the sender, however the recipient account will not reflect the amount sent. ' + }) + : undefined + }{ + hasAvailable + ? undefined + : t('fees.available', { + defaultValue: 'The account does not have the required funds available for this transaction with the current values. ' + }) + }{ + isReserved + ? t('fees.reserved', { + defaultValue: '(This account does have a reserved/locked balance, staking locks up the available funds) ' + }) + : undefined + }{ + t('fees.explain', { + defaultValue: 'Fees includes the transaction fee and the per-byte fee. ' + }) + }{ + isCreation && fees.creationFee.gtn(0) + ? t('fees.create', { + defaultValue: 'A fee of {{creationFee}} will be deducted from the sender since the destination account does not exist.', + replace: { + creationFee: fees.creationFee.toString() + } + }) + : undefined + } +
, + + ]; + } +} + +export default withMulti( + translate(FeeDisplay), + withObservable('votingBalance', { paramProp: 'from', propName: 'balanceFrom' }), + withObservable('votingBalance', { paramProp: 'to', propName: 'balanceTo' }) +); diff --git a/packages/app-transfer/src/Submit.tsx b/packages/app-transfer/src/Submit.tsx new file mode 100644 index 0000000000..ca593affb0 --- /dev/null +++ b/packages/app-transfer/src/Submit.tsx @@ -0,0 +1,59 @@ +// Copyright 2017-2018 @polkadot/app-transfer authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { I18nProps } from '@polkadot/ui-app/types'; +import { QueueTx$ExtrinsicAdd } from '@polkadot/ui-signer/types'; + +import BN from 'bn.js'; +import React from 'react'; +import extrinsics from '@polkadot/extrinsics'; +import Button from '@polkadot/ui-app/Button'; +import withMulti from '@polkadot/ui-react-rx/with/multi'; +import withObservable from '@polkadot/ui-react-rx/with/observable'; + +import translate from './translate'; + +type Props = I18nProps & { + isDisabled: boolean, + accountIndex?: BN, + amount: BN, + from: Uint8Array, + to: Uint8Array, + queueExtrinsic: QueueTx$ExtrinsicAdd +}; + +class Submit extends React.PureComponent { + render () { + const { isDisabled, t } = this.props; + + return ( + +