Customized Polkadot.js Apps fork for GHOST Mainnet & CASPER Testnet. Pre-configured RPC, GHOST dark theme, and upstream-sync ready.
Go to file
Luke Schoen 0c8e19911c fix: Fixes Issue #144. Extrinsics with high balance restarts webpage (#221)
* fix: Fixes Issue #144. Balance to submit with transaction changed to string

Placeholder indicates acceptable range of values to user in the interim until form validation incorporated.
Max value must be the balance of the account minus one, otherwise the Polkadot Node will give error `Runtime: proposer's balance too low`.
Min value must be above 0.000000000000001, otherwise the Polkadot Node will give error `Runtime: proposer's balance too low`

* fix: Add validations to string input. Add unit tests

Note that entering a large number after all inputs are valid (including code dragged and dropped) causes error `Uncaught Error: byte array longer than desired length`. This is because it only starts encoding after all input fields are valid, but the maximum balance is 64 bits for poc-1 and 128 bits for latest master branch

* fix: Add internationalisation, maxLength to input, validate depending on chain used

- add internationalisation
- add maxLength to input field depending on whether poc-1 (64bit) or latest (128bit) chain used
- pass down api chain data via props
- add unit tests for balance input field, new tests not all passing but don't understand why. since using unsigned 64bit and 128bit
- add balance input field validation to only accept numbers
- when i add `&& maxBN64Bit.gte(inputBN)` or `&& maxBN128Bit.gte(inputBN)` it doesn't appear
to work correctly as in the UI it doesn't allow a length as much as expected

* fix: Must pass in as string as String(xyz) converts to scientific notation x...e+21 for large numbers

* fix: Remove String(xyz) that was converting to scientific notation. Throw on it or non-string input.

* fix: Prop value is BN converted to string with toString(10) according to BN.js docs

* fix: Translate the placeholder

* refactor: Move external dependencies above local. Add missing whitespace

* fix: Scientific value detection on e+ not just letter e

* feat: Add input field validation message notification to extrinsic balance

* refactor: Move expected responses generation into enum in separate file

* WIP - trying with input type number and onKeyDown

* WIP - split into onKeyDown and onKeyUp

* feat: Add scientific notation equivalent in info message. Yet to use converted value when submit

* fix: Allow user to select all that they've entered in input field

* feat: Converts from scientific notation with submit. Need to fix input as crashes on 9e19

* fix: Remove debugging console.log so it doesn't crash

* fix: Calculate size based on actual bitlength before checking BN value against max

* fix: Allow use of decimal point only in scientific notation. Prevent successive decimal point entry

* fix: Update error message with example

* feat: Create InputNumber instead of extending Balance. Requires PR with mods to polkadot-js/apps

* fix: Remove accidently added vscode config

* fix: Remove step and min props since not using input type number

* refactor: Remove debugging console logs from extrinsics

* fix: Remove disused step

* fix: Remove comments and add whitespace

* fix: Remove unnecessary check if balance is defined when it must be

* fix: Fix logic

* fix: Show error when user enters e or e+ without a number afterwards

* test: Update existing tests. Still must add new tests

* test: Fix tests for scientific vs exponential notation

* test: Add remaining tests

* test: Refactor tests in order used

* refactor: clean up comments and duplicate code

* fix: Replace implementation with restrictions on key combos instead of horrible previous approach

* fix: Prevent notification with info from displaying when there are errors. Remove console logs

* fix: Prevent user pasting balance in exponential notation with invalid exponent. Only allow + symbol entry immediately after letter e

- Only allow user to enter + symbol immediately after letter e for exponential input.
- Prevent error when user pastes input with invalid exponent (i.e. when user pastes into the input field for Balance 232e11+ it was crashing with error `error:  RangeError: Invalid array length
    at scientificToDecimal`)

* refactor: Add comment to input cursor and move

* remove todo note

* fix: Prevent user entering 0's at start

* restore: Restore Balance instead of incorrect implementation of InputNumber

* WIP - initially add generic identity function where Balance wraps InputNumber type

* remove generic ident fn

* feat: Add GenericInputNumber

* fix: Add InputNumber generic wrapper of Input and Notification for use in Balance or elsewhere

* fix: Address review comments.

* fix: Fix linting errors and remove useless new line

* fix: Add WarnMessage. Remove UI message for it to be account balance minus 1

* fix: Fix bitLength error when small amount entered. Fix NaN test. Allow input of 0 with warning.

* fix: Allow select all, cut, copy, paste whilst preventing input of a, x, c, v

* fix: Fix linting error that appeared in CI

* fix: Remove conflicting restriction on use of 0

* test: Add enzyme test for default load of Balance component

* test: Add basic enzyme tests to simulate Info, Warning, and Error Notifications

* fix: Address some review comments. See commit details

* Refactor nested condition into `isValidLength` instead of `(values[index].type === 'Balance' ? checkValueBitLength(...`
* Fix alphabetical ordering
* Change to `Between 0 DOT` instead of `Between 1 DOT`
* Add License heaer to chainSpec.ts
* Replace `if (!(typeof input === 'string')) ` with `isString`
* Add blank lines for all blocks in isValidBalanceExpectedResponses.ts

* fix: Remove NaN check since unnecessary. Replace with test for just single e input

* Remove check for NaN since unnecessary. NaN is not string type so will show error associated with the test for string
* Add initial check for input value that contains just 'e' since it should not show same error message as say '1e'

* fix: Revert to just allow integers and decimals without scientific notation

* docs: fix comments

* refactor: Split isValid ternary across multiple lines for readability

* refactor: Remove unnecessary blank line

* fix: Remove nested if condition

* refactor: Split isCopy function definiton from function body implementation similar to in ui-signer

* refactor: Split function definition from function body for all keyboard utils

* fix: Replace event any type with KeyboardEvent type for all keyboard functions

* fix: Remove TranslateFunction with just string as type of messages

* fix: Replace deprecated keyCode and which with key.

* fix: Move isValidLength into isValidBalance

* fix: Split imported packages

* fix: Split imported packages in Balance spec

* fix: Change placeholder to request positive integer input and update messages

* refactor: Split function body onto new line

* fix: Split function body onto new line for readability

* refactor: Split ternary across multiple lines

* fix: Use BN instead of Number for info message

* fix: pass up destructured event properties

* fix: Remove SUIEvent type definition

* fix: Reduce maxLength in digits that user allowed to enter by 1

* merge latest from master

* fix: Remove transfer terminology from Balance placeholder

* Move logic to child

* fix: Remove assignment to optional

* fix: Remove DOT references since number can be anything and substrate chains have own token

* fix: Add missing blank lines and reorder alphabetically

* Non-numeric keys outright without error notification. Use MAX_SAFE_INTEGER built-in

* fix: Reordering

* fix: Remove showing error to user when they enter value over max bitlength

* fix: Restrict user enter value greater than max safe integer

* fix: Do not pass translate down from Balance. Fix tests

* test: Move tests to InputNumber

* Return only value from onChange in InputNumber. Bug since isValid keydowns allowed

* fix: Fixes review comments. See commit message details:

* `onChange` in InputNumber is just `onChange: (value: BN) => void` without an `isValid` property. `isValid` is now set to `true` in Balance as we've taken care of all the invalid cases (i.e. automatically reverting the input if the user pastes an invalid value, or preventing input of non-decimal values in keyDown)

* New input value is reverted to previous valid input field value if the input field value becames invalid (i.e. if they enter a value that's above the maximum allowable). i.e. 0.1111111111111111111111111111111 is allowed, but if any additional 1's are entered (i.e. 0.1111111111111111111111111111111111111) at the end it exceeds max for 128 bit, and we automatically prevent these invalid values from being entered (instead of informing the user through a notification).

* Refer to input as "input" instead of "balance" (i.e. for i18n keys, etc)

* Remove duplicate `KEYS.BACKSPACE`

* Add unit tests for isNonDecimal and isNonInteger

* Remove `KEYS.ZERO` from `KEYS_ALLOWED` and add to isValidDecimal and isValidInteger checks instead

* Split isValidNumber into isValidNumber and isValidKey. Since keyDown has access to the key and can prevent the input (but only has access to the previous input field value before the new key was entered), we check if the the new key entered is valid in isolation of the whole valued by calling isValidKey. Then in onChange where we have access to the new input field value we validate it calling isValidNumber.

* In InputNumber.tsx the Input component accepts `defaultValue={defaultValue || '0'}`, and also we're also overriding the value with the previous valid value with `value={revertedValue}` if the user input is found to be invalid. However React complains with the following errors in the browser Chrome Inspector:

```
Warning: Input contains an input of type text with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://fb.me/react-controlled-components
```

```
Warning: A component is changing a controlled input of type text to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.
```

I have tried as many ways as possible to just use one or the other (i.e. defaultValue or value) to resolve these warnings but so have not being able to replicate the same functionality that works.

* fix: Remove new line

* fix: Remove complexity. See detailed commit comments

Progress update:

* ASSUMPTION: InputNumber may be used in future for useful error, warning, and info messages, so leave the boilerplate props along with Notification.

* ASSUMPTION: Displaying an info message in scientific notation i.e. 3e+7
causes more confusion than benefit since most users are non-techy. In future this when we have Issue #86 Settings App, it could be added as an optional extra that could be toggled by the user along with Issue #224 E-Notation

* ACTIONS:
	* [x] - Remove display of scientific notation equivalent
	* [x] - Remove warning 'number.warn.zero' when user enters 0 value
	* [x] - Remove info notification 'number.info.scientific' when user enters valid value
	* [x] - Remove `toScientificNotation` function, which is incorrectly passed the TranslationFunction `t` anyway.
	* [x] - Remove `IsValidWithMessage` type and replace return value with just a boolean of whether its valid or not
	* [x] - Move `isValidNumber` into React componet, and do not pass the TranslationFunctio to it!
	* [x] - Move `isValidKey` into React componet, and do not pass the TranslationFunctio to it!
	* [x] - Move `isNonDecimal` into React componet, and do not pass the TranslationFunctio to it!
	* [X] - Remove `isNonInteger` and isNonInteger.ts and isNonInteger.spec.js since no longer using
	* [X] - Remove `error`, `warn`, `info` from InputNumber state, since we're filtering out everything not valid. Instead add them as optional props (so Balance or another component can display notifications if required)
	* [X] - Move tests for isValidKey into InputNumber React component, and remove isValidKey.spec.js
	* [X] - Move tests for isValidNumber into InputNumberReact component, and remove isValidNumber.spec.js
	* [X] - Move tests for isNonDecimal into InputNumberReact component, and remove isNonDecimal.spec.js
	* [X] - Update InputNumber.spec.js to remove useless tests that check that the Notification component isn't shown
	* [X] - Make methods `private` as relevant
        * [X] - move chainSpec and keyboard subfolder files into InputNumber. Move contents of constants into InputNumber except for BIT_LENGTH_128
	* [X] - Move all the different files that are only used in the number input into functions inside that input. Then we also get rid of calling external functions (like isNumberValid) with t as a param. Keep it small, keep it together.
        * [X] - Remove `cursorIndexInputField` function since we're not trying to check the current cursor position in the input field anymore
	* [X] - Assume that based on @jacogr's comment: "I'm struggling to see where we are actually now doing errors in the Balance input - it filters everything non-valid.".
          * Action: Change isValid from being true, to being assigned to the value of !isError
        * Note: DO NOT update the Extrinsics component to use the 'fees' observable (as it's used in the Transfer App) so the Balance input field is invalid (appears "red" and Submit Transaction button disabled) when the value entered plus fees exceeds the sender's balance. Reasoning: We cannot determine the size of the tx in there at all - there is a FIXME for the hardcoding of the size (already wrong for poc-3), in the Transfer App. So without the final signed size, it currently cannot be done. `fee = baseTxFee + (tx-size-in-bytes * feePerByte)`. We cannot get the tx-size-in-bytes atm. (hardcoded to 156 in Transfer, which assumes only publicKeys and is not the case when we get to poc-3). There is an issue logged that goes through all the fees. Signer needs to have a method exposed that takes all the params as given, encodes the extrinsic and returns the total fee or size. So nothing stopping us, it just has not been done properly. (Signer does not even know in the modal what the final size would be - that is the first stop, showing the fees in there. Then the apps, then maybe extrinsics if it still has a use)
	* [X] - "Seems SUI docs are currently broken. But in the cases where you absolutely need to point to an input with an attachment, their Label does exactly that and allows attachment with a pointer to an Input. So at most Notification should just warp that. And it really should only be used is completely exceptionally circumstances. (And I really couldn't see any such circumstances from playing with the actual inputs. So at this point seems like a good, although unused in practice idea.)"
          * [X] - Remove Notification component, and all the error, warn, and info props, as we won't be showing notifications
	* [ ] - Integrate into the Transfer App `send a value of` where actual transfers will be done (see @jacogr comment and screenshot). Incorporate the Balance/InputNumber into the Transfer App, which currently just uses an <Input> field and isError={!hasAvailable} to determine highlight the input field "red" and disable the Submit button when they don't have sufficient balance.
         * ACTION: Unable to get this to work. If I change the Input to Balance in Transfer.tsx to the following, then when I modify the value in the Transfer tabs "send a value of" input field, it shows an `Error: Assertion failed` in the console
```
            {/* <Input
              defaultValue='0'
              isError={!hasAvailable}
              label={t('amount', {
                defaultValue: 'send a value of'
              })}
              min={0}
              onChange={this.onChangeAmount}
              type='number'
            /> */}
            <Balance
              defaultValue={{ value: '0' }}
              isError={!hasAvailable}
              label={t('transfer.amount', {
                defaultValue: 'send a value of'
              })}
              onChange={this.onChangeAmount}
            />
```
Error mentioned above:
```
InputNumber.tsx?299c:129 Error: Assertion failed
    at assert (bn.js?cda7:6)
    at BN._initArray (bn.js?cda7:145)
    at BN.init [as _init] (bn.js?cda7:82)
    at new BN (bn.js?cda7:39)
    at Transfer.onChangeAmount.amount (Transfer.tsx?f63a:45)
    at Balance.onChange.value (Balance.tsx?8315:42)
    at InputNumber.onChange.value (InputNumber.tsx?299c:127)
    at Object.Input.onChange.event [as onChange] (Input.tsx?a939:36)
    at apply (_apply.js?59ad:15)
    at baseInvoke (_baseInvoke.js?199b:21)
```

* fix: Move BIT_LENGTH_128 into InputNumber

* refactor: Remove disused keys from constant. Remove useless isShift fn. Use Spread operator.

* refactor: Simplify comments

* refactor: remove useless maxSafeIntegerBN

* refactor: remove useless check for isZero

* refactor: Simplify isNonDecimal function

* refactor: remove maxValue from being maxLength arg. remove useless defaultMaxLength fn

* fix: Use InputNumber in Transfer instead of Balance

* refactor: move non-number specific keyboard functions to Input instead of InputNumber

* refactor: Reorder alphabetically exports

* refactor: Remove disused withApi and translate from Balance and simplify defaultValue

* refactor: spread operator to pass down props before overrides if any

* test: Add more isValidNumber tests. Add maxValue and isValidBitLength tests

* fix: fix maxValue function

* test: Add maxLength test for 128 bit

* refactor: remove unnecessary line in test

* fix: Remove support for decimals since BN.js only supports integers

* refactor: optimise by using isNaN instead of isNonInteger for single character checks

* fix: revert using spread operator to pass down props

* fix: Add bitLength prop to InputNumber. Move maxConservativeLength function. See detailed comments

* bitLength passed down as prop from Transfer and Balance to InputNumber is 128 bit for latest chain specification

* Move maxLength method out of InputNumber class and rename maxConservativeLength also to avoid name conflict with the maxLength prop

* Change argument of maxConservativeLength to the maxValueLength to simplify

* Update InputNumber tests

* Add default bit length for InputNumber is 32 bit for normal numbers

* fix: Add BitLength type and BitLengthOption enum

* fix: prevent user entering value preceded by 0

* refactor: Replace ternary with more readable

* feat: Add 8 and 16 to BitLength for future-proofing and consistency
2018-09-26 16:45:41 +02:00
examples Expand/simplify example: getStorage with keys definitions (#137) 2018-07-12 19:44:00 +02:00
packages fix: Fixes Issue #144. Extrinsics with high balance restarts webpage (#221) 2018-09-26 16:45:41 +02:00
test feat: Fixes Issue #260. Allow use Enter to submit extrinsics (#265) 2018-09-13 11:36:52 +02:00
.babelrc.js Support enumerable accounts (#102) 2018-06-25 18:02:47 +02:00
.codeclimate.yml Initial commit 2018-04-17 17:02:30 +02:00
.dockerignore Add .dockerignore 2018-08-12 17:27:12 +02:00
.editorconfig Initial commit 2018-04-17 17:02:30 +02:00
.eslintignore Initial commit 2018-04-17 17:02:30 +02:00
.eslintrc.json Add utility/toolbox app (#51) 2018-05-15 16:58:32 +02:00
.gitignore Initial commit 2018-04-17 17:02:30 +02:00
.npmignore Initial commit 2018-04-17 17:02:30 +02:00
.nvmrc Add nvmrc (#107) 2018-06-28 07:11:58 +02:00
.stylelintrc.json Add utility/toolbox app (#51) 2018-05-15 16:58:32 +02:00
.travis.yml Add yarn & node to engines (#91) 2018-06-12 10:55:23 +02:00
babel.config.js Use @babel 7 (#52) 2018-05-17 14:51:41 +02:00
Dockerfile Add multistage docker image (11MB) (#164) 2018-07-31 15:29:00 +02:00
jest.config.js feat: Fixes Issue #260. Allow use Enter to submit extrinsics (#265) 2018-09-13 11:36:52 +02:00
lerna.json [CI Skip] 0.20.18 2018-09-26 06:22:25 +00:00
LICENSE Initial commit 2018-04-17 17:02:30 +02:00
package.json [CI Skip] 0.20.18 2018-09-26 06:22:25 +00:00
postcss.config.js Use @babel 7 (#52) 2018-05-17 14:51:41 +02:00
README.md Document UI_MODE & UI_THEME flags (#320) 2018-09-18 10:42:02 +02:00
tsconfig.json Basic transfer app (#293) 2018-09-11 09:08:31 +02:00
tslint.json Add TSLint (#106) 2018-06-27 12:43:07 +02:00
yarn.lock Cleanup app-accounts, align with addresses (#331) 2018-09-21 10:33:39 +02:00

polkadotjs isc style npm travis greenkeeper dependency devDependency

@polkadot/apps

A Portal into the Polkadot network. Provides a view and interaction layer from a browser.

This can be accessed as a hosted application via https://polkadot.js.org/apps/.

overview

The repo is split into a number of packages, each representing an application. These are -

  • apps This is the main entry point. It handles the selection sidebar and routing to the specific application being displayed.
  • app-accounts A basic account management app.
  • app-addresses A basic address management app.
  • app-explorer A simple block explorer. It only shows the most recent blocks, updating as they become available.
  • app-extrinsics Submission of extrinsics to a node.
  • app-rpc Sumission of raw data to RPC endpoints.
  • app-staking A basic staking management app, allowing staking and nominations.
  • app-storage A simple node storage query application. Multiple queries can be queued and updates as new values become available.
  • app-toolbox Utilities to manage data.
  • app-vanitygen A toy that allows you to generate vanity addresses. Running yarn run vanitygen --match <string> runs the generator as a Node CLI app. (Orders of a magnitude faster due to the use of libsoldium bindings)

In addition the following libraries are also included in the repo. These are to be moved to the @polkadot/ui repository once it reaches a base level of stability and usability. (At this point with the framework being tested on the apps above, it makes development easier having it close)

  • ui-app A reactive (using RxJS) application framework with a number of useful shared components.
  • ui-keyring A browser-specific wrapper around the base @polkadot/util-keyring library.
  • ui-signer Signer implementation for apps.
  • ui-identicon Identity icon generator with raw publicKey as input
  • ui-react A collection of base React components
  • ui-react-rx Base components that use the RxJS Observable APIs

development

Contributions are welcome!

To start off, this repo (along with others in the @polkadot family) uses yarn workspaces to organise the code. As such, after cloning dependencies should be installed via yarn, not via npm, the latter will result in broken dependencies.

To get started -

  1. Clone the repo locally, via git clone https://github.com/polkadot-js/apps <optional local path>
  2. Ensure that you have a recent version of Node.js, for development purposes Node 10 is recommended.
  3. Ensure that you have a recent version of Yarn, for development purposes Yarn >=1.3.2 is required.
  4. Install the dependencies by running yarn
  5. Ready! Now you can launch the UI (assuming you have a local Polkadot Node running), via yarn run start
  6. Access the UI via http://localhost:3000

Should you not run a local Node, you can connect to a remote node on the POC-2 network with the WS_URL environment variable. For example - the apps entry point can be launched with a WebSocket connection to Polkadot POC-2 with WS_URL=wss://poc-2.polkadot.io:9944 yarn run start and accessing the application of http://localhost:3000

There are additional environment UI flags that change both the theme and mode -

  • Running with UI_MODE=light|full switches from a full (the default) to a light mode interface that only has specific applications highlighted.
  • Running with UI_THEME=substrate|polkadot switches from a Polkadot theme (the default) to a Substrate-branded UI

demos

Demos for the different libraries can be viewed with yarn run demo:<name> and then browsing to http://localhost:3000. Available demo -

  • yarn run demo:identicon
  • yarn run demo:ui
  • yarn run demo:rx

tutorials

Looking for tutorials to get started? Look at examples for a step-by-step guide to using the API and Components to display some information.

Docker

Run

docker run --rm -it --name polkadot-ui -p 80:80 chevdor/polkadot-ui:latest

Build

docker build -t chevdor/polkadot-ui:latest .