Merge branch 'master' into upload-crates
This commit is contained in:
commit
81212c5031
3
.gitignore
vendored
3
.gitignore
vendored
@ -24,6 +24,9 @@
|
||||
npm-debug.log
|
||||
node_modules
|
||||
|
||||
# js build artifacts
|
||||
.git-release.log
|
||||
|
||||
# gdb files
|
||||
.gdb_history
|
||||
|
||||
|
@ -690,9 +690,10 @@ js-release:
|
||||
script:
|
||||
- rustup default stable
|
||||
- echo $JS_FILES_MODIFIED
|
||||
- if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS rebuild since no JS files modified."; else ./js/scripts/build.sh && ./js/scripts/release.sh; fi
|
||||
- if [ $JS_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS rebuild since no JS files modified."; else ./js/scripts/build.sh && ./js/scripts/push-precompiled.sh; fi
|
||||
- echo $JS_OLD_FILES_MODIFIED
|
||||
- if [ $JS_OLD_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS (old) rebuild since no JS files modified."; else ./js-old/scripts/build.sh && ./js-old/scripts/release.sh; fi
|
||||
- if [ $JS_OLD_FILES_MODIFIED -eq 0 ]; then echo "Skipping JS (old) rebuild since no JS files modified."; else ./js-old/scripts/build.sh && ./js-old/scripts/push-precompiled.sh; fi
|
||||
- if [ $JS_FILES_MODIFIED -eq 0 ] && [ $JS_OLD_FILES_MODIFIED -eq 0 ]; then echo "Skipping Cargo update since no JS files modified."; else ./js/scripts/push-cargo.sh; fi
|
||||
|
||||
tags:
|
||||
- javascript
|
||||
|
43
CHANGELOG.md
43
CHANGELOG.md
@ -1,3 +1,42 @@
|
||||
## Parity [v1.8.3](https://github.com/paritytech/parity/releases/tag/v1.8.3) (2017-11-15)
|
||||
|
||||
Parity 1.8.3 contains several bug-fixes and removes the ability to deploy built-in multi-signature wallets.
|
||||
|
||||
The full list of included changes:
|
||||
|
||||
- Backports to beta ([#7043](https://github.com/paritytech/parity/pull/7043))
|
||||
- pwasm-std update ([#7018](https://github.com/paritytech/parity/pull/7018))
|
||||
- Version 1.8.3
|
||||
- Make CLI arguments parsing more backwards compatible ([#7004](https://github.com/paritytech/parity/pull/7004))
|
||||
- Skip nonce check for gas estimation ([#6997](https://github.com/paritytech/parity/pull/6997))
|
||||
- Events in WASM runtime ([#6967](https://github.com/paritytech/parity/pull/6967))
|
||||
- Return decoded seal fields. ([#6932](https://github.com/paritytech/parity/pull/6932))
|
||||
- Fix serialization of status in transaction receipts. ([#6926](https://github.com/paritytech/parity/pull/6926))
|
||||
- Windows fixes ([#6921](https://github.com/paritytech/parity/pull/6921))
|
||||
- Disallow built-in multi-sig deploy (only watch) ([#7014](https://github.com/paritytech/parity/pull/7014))
|
||||
- Add hint in ActionParams for splitting code/data ([#6968](https://github.com/paritytech/parity/pull/6968))
|
||||
- Action params and embedded params handling
|
||||
- Fix name-spaces
|
||||
|
||||
## Parity [v1.8.2](https://github.com/paritytech/parity/releases/tag/v1.8.2) (2017-10-26)
|
||||
|
||||
Parity 1.8.2 fixes an important potential consensus issue and a few additional minor issues:
|
||||
|
||||
- `blockNumber` transaction field is now returned correctly in RPC calls.
|
||||
- Possible crash when `--force-sealing` option is used.
|
||||
|
||||
The full list of included changes:
|
||||
|
||||
- Beta Backports ([#6891](https://github.com/paritytech/parity/pull/6891))
|
||||
- Bump to v1.8.2
|
||||
- Refactor static context check in CREATE. ([#6886](https://github.com/paritytech/parity/pull/6886))
|
||||
- Refactor static context check in CREATE.
|
||||
- Fix wasm.
|
||||
- Fix serialization of non-localized transactions ([#6868](https://github.com/paritytech/parity/pull/6868))
|
||||
- Fix serialization of non-localized transactions.
|
||||
- Return proper SignedTransactions representation.
|
||||
- Allow force sealing and reseal=0 for non-dev chains. ([#6878](https://github.com/paritytech/parity/pull/6878))
|
||||
|
||||
## Parity [v1.8.1](https://github.com/paritytech/parity/releases/tag/v1.8.1) (2017-10-20)
|
||||
|
||||
Parity 1.8.1 fixes several bugs with token balances, tweaks snapshot-sync, improves the performance of nodes with huge amounts of accounts and changes the Trezor account derivation path.
|
||||
@ -13,7 +52,7 @@ Parity 1.8.1 fixes several bugs with token balances, tweaks snapshot-sync, impro
|
||||
|
||||
If you don't want to downgrade or move your funds off your Trezor-device, you can also use the official Trezor application or other wallets allowing to select the derivation path to access the funds.
|
||||
|
||||
Full list of included changes:
|
||||
The full list of included changes:
|
||||
|
||||
- Add ECIP1017 to Morden config ([#6845](https://github.com/paritytech/parity/pull/6845))
|
||||
- Ethstore optimizations ([#6844](https://github.com/paritytech/parity/pull/6844))
|
||||
@ -45,7 +84,7 @@ Further, users upgrading from 1.7 should acknowledge the following changes:
|
||||
- `trace_filter` RPC method now comes with pagination. [#6312](https://github.com/paritytech/parity/pull/6312)
|
||||
- Added tracing of rewards on closing blocks. [#6194](https://github.com/paritytech/parity/pull/6194)
|
||||
|
||||
Full list of included changes:
|
||||
The full list of included changes:
|
||||
|
||||
- Updated ethabi to fix auto-update ([#6771](https://github.com/paritytech/parity/pull/6771))
|
||||
- Fixed kovan chain validation ([#6760](https://github.com/paritytech/parity/pull/6760))
|
||||
|
135
Cargo.lock
generated
135
Cargo.lock
generated
@ -424,9 +424,6 @@ dependencies = [
|
||||
name = "error-chain"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "eth-secp256k1"
|
||||
@ -586,7 +583,6 @@ dependencies = [
|
||||
"ethcore 1.9.0",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-network 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
@ -610,6 +606,7 @@ dependencies = [
|
||||
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stats 0.1.0",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"triehash 0.1.0",
|
||||
"vm 0.1.0",
|
||||
@ -637,6 +634,7 @@ dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
@ -673,7 +671,6 @@ dependencies = [
|
||||
"ethcore 1.9.0",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethcrypto 0.1.0",
|
||||
@ -692,6 +689,7 @@ dependencies = [
|
||||
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -706,12 +704,11 @@ version = "1.9.0"
|
||||
dependencies = [
|
||||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-tcp-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-tcp-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"keccak-hash 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -847,7 +844,6 @@ dependencies = [
|
||||
"ethcore 1.9.0",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-devtools 1.9.0",
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-light 1.9.0",
|
||||
"ethcore-network 1.9.0",
|
||||
@ -1168,6 +1164,11 @@ name = "integer-encoding"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "interleaved-ordered"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.0"
|
||||
@ -1227,7 +1228,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "jsonrpc-core"
|
||||
version = "8.0.0"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8#cf6f3481760f6ee8fbef7a987954ffc720ff4acf"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9#8f921ed65cda3fba0ce55d31ed62c7f0c3b32966"
|
||||
dependencies = [
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1239,11 +1240,11 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "jsonrpc-http-server"
|
||||
version = "8.0.0"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8#cf6f3481760f6ee8fbef7a987954ffc720ff4acf"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9#8f921ed65cda3fba0ce55d31ed62c7f0c3b32966"
|
||||
dependencies = [
|
||||
"hyper 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1252,10 +1253,10 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "jsonrpc-ipc-server"
|
||||
version = "8.0.0"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8#cf6f3481760f6ee8fbef7a987954ffc720ff4acf"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9#8f921ed65cda3fba0ce55d31ed62c7f0c3b32966"
|
||||
dependencies = [
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)",
|
||||
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1264,19 +1265,19 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "jsonrpc-macros"
|
||||
version = "8.0.0"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8#cf6f3481760f6ee8fbef7a987954ffc720ff4acf"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9#8f921ed65cda3fba0ce55d31ed62c7f0c3b32966"
|
||||
dependencies = [
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc-pubsub"
|
||||
version = "8.0.0"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8#cf6f3481760f6ee8fbef7a987954ffc720ff4acf"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9#8f921ed65cda3fba0ce55d31ed62c7f0c3b32966"
|
||||
dependencies = [
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -1284,11 +1285,11 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "jsonrpc-server-utils"
|
||||
version = "8.0.0"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8#cf6f3481760f6ee8fbef7a987954ffc720ff4acf"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9#8f921ed65cda3fba0ce55d31ed62c7f0c3b32966"
|
||||
dependencies = [
|
||||
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"globset 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1297,10 +1298,10 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "jsonrpc-tcp-server"
|
||||
version = "8.0.0"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8#cf6f3481760f6ee8fbef7a987954ffc720ff4acf"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9#8f921ed65cda3fba0ce55d31ed62c7f0c3b32966"
|
||||
dependencies = [
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1309,10 +1310,11 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "jsonrpc-ws-server"
|
||||
version = "8.0.0"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8#cf6f3481760f6ee8fbef7a987954ffc720ff4acf"
|
||||
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9#8f921ed65cda3fba0ce55d31ed62c7f0c3b32966"
|
||||
dependencies = [
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1362,6 +1364,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvdb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1923,7 +1926,7 @@ dependencies = [
|
||||
"ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"isatty 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"journaldb 0.1.0",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"keccak-hash 0.1.0",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-rocksdb 0.1.0",
|
||||
@ -1977,8 +1980,8 @@ dependencies = [
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"keccak-hash 0.1.0",
|
||||
"linked-hash-map 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2056,9 +2059,8 @@ dependencies = [
|
||||
"ethcore 1.9.0",
|
||||
"ethcore-bigint 0.2.1",
|
||||
"ethcore-bytes 0.1.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"multihash 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.1",
|
||||
"unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2070,7 +2072,6 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"ethcore 1.9.0",
|
||||
"ethcore-io 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"ethkey 0.2.0",
|
||||
"kvdb 0.1.0",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
@ -2124,13 +2125,12 @@ dependencies = [
|
||||
"futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hardware-wallet 1.9.0",
|
||||
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-ipc-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"keccak-hash 0.1.0",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-ipc-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"kvdb-memorydb 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"macros 0.1.0",
|
||||
@ -2151,6 +2151,7 @@ dependencies = [
|
||||
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stats 0.1.0",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vm 0.1.0",
|
||||
@ -2161,8 +2162,8 @@ name = "parity-rpc-client"
|
||||
version = "1.4.0"
|
||||
dependencies = [
|
||||
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"keccak-hash 0.1.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2196,7 +2197,7 @@ version = "1.9.0"
|
||||
dependencies = [
|
||||
"parity-ui-dev 1.9.0",
|
||||
"parity-ui-old-dev 1.9.0",
|
||||
"parity-ui-old-precompiled 1.8.0 (git+https://github.com/paritytech/js-precompiled.git?branch=v1)",
|
||||
"parity-ui-old-precompiled 1.9.0 (git+https://github.com/paritytech/js-precompiled.git?branch=v1)",
|
||||
"parity-ui-precompiled 1.9.0 (git+https://github.com/paritytech/js-precompiled.git)",
|
||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -2217,8 +2218,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity-ui-old-precompiled"
|
||||
version = "1.8.0"
|
||||
source = "git+https://github.com/paritytech/js-precompiled.git?branch=v1#94b0a89aac7eb5ddfdb53cd9bb039da6fdbf7583"
|
||||
version = "1.9.0"
|
||||
source = "git+https://github.com/paritytech/js-precompiled.git?branch=v1#f3fa5e5efb0ed8ada6cd091694fcdaa921e6720f"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -2226,7 +2227,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "parity-ui-precompiled"
|
||||
version = "1.9.0"
|
||||
source = "git+https://github.com/paritytech/js-precompiled.git#1626d64235241e75c531eece004a4923d9d4fcc6"
|
||||
source = "git+https://github.com/paritytech/js-precompiled.git#5b3e31509c369f558c8cb90f6f9918e50cdb2501"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -2253,7 +2254,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity-wasm"
|
||||
version = "0.15.1"
|
||||
version = "0.15.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2272,9 +2273,9 @@ dependencies = [
|
||||
"ethcrypto 0.1.0",
|
||||
"ethkey 0.2.0",
|
||||
"hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)",
|
||||
"jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2939,6 +2940,7 @@ name = "snappy"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rocksdb 0.4.5 (git+https://github.com/paritytech/rust-rocksdb)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3417,7 +3419,7 @@ dependencies = [
|
||||
"ethcore-logger 1.9.0",
|
||||
"ethcore-util 1.9.0",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vm 0.1.0",
|
||||
"wasm-utils 0.1.0 (git+https://github.com/paritytech/wasm-utils)",
|
||||
]
|
||||
@ -3433,7 +3435,7 @@ dependencies = [
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3580,19 +3582,20 @@ dependencies = [
|
||||
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
|
||||
"checksum igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "356a0dc23a4fa0f8ce4777258085d00a01ea4923b2efd93538fc44bf5e1bda76"
|
||||
"checksum integer-encoding 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a053c9c7dcb7db1f2aa012c37dc176c62e4cdf14898dee0eecc606de835b8acb"
|
||||
"checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77"
|
||||
"checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
|
||||
"checksum ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2134e210e2a024b5684f90e1556d5f71a1ce7f8b12e9ac9924c67fb36f63b336"
|
||||
"checksum isatty 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fa500db770a99afe2a0f2229be2a3d09c7ed9d7e4e8440bf71253141994e240f"
|
||||
"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
|
||||
"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
|
||||
"checksum jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)" = "<none>"
|
||||
"checksum jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)" = "<none>"
|
||||
"checksum jsonrpc-ipc-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)" = "<none>"
|
||||
"checksum jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)" = "<none>"
|
||||
"checksum jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)" = "<none>"
|
||||
"checksum jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)" = "<none>"
|
||||
"checksum jsonrpc-tcp-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)" = "<none>"
|
||||
"checksum jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.8)" = "<none>"
|
||||
"checksum jsonrpc-core 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)" = "<none>"
|
||||
"checksum jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)" = "<none>"
|
||||
"checksum jsonrpc-ipc-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)" = "<none>"
|
||||
"checksum jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)" = "<none>"
|
||||
"checksum jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)" = "<none>"
|
||||
"checksum jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)" = "<none>"
|
||||
"checksum jsonrpc-tcp-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)" = "<none>"
|
||||
"checksum jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.9)" = "<none>"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
|
||||
"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
|
||||
@ -3645,9 +3648,9 @@ dependencies = [
|
||||
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
|
||||
"checksum parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "261c025c67ba416e9fe63aa9b3236520ce3c74cfbe43590c9cdcec4ccc8180e4"
|
||||
"checksum parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "<none>"
|
||||
"checksum parity-ui-old-precompiled 1.8.0 (git+https://github.com/paritytech/js-precompiled.git?branch=v1)" = "<none>"
|
||||
"checksum parity-ui-old-precompiled 1.9.0 (git+https://github.com/paritytech/js-precompiled.git?branch=v1)" = "<none>"
|
||||
"checksum parity-ui-precompiled 1.9.0 (git+https://github.com/paritytech/js-precompiled.git)" = "<none>"
|
||||
"checksum parity-wasm 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "95f6243c2d6fadf903b5edfd0011817efc20522ce5f360abf4648c24ea87581a"
|
||||
"checksum parity-wasm 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8431a184ad88cfbcd71a792aaca319cc7203a94300c26b8dce2d0df0681ea87d"
|
||||
"checksum parity-wordlist 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81451bfab101d186f8fc4a0aa13cb5539b31b02c4ed96425a0842e2a413daba6"
|
||||
"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e"
|
||||
"checksum parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f610cb9664da38e417ea3225f23051f589851999535290e077939838ab7a595"
|
||||
|
@ -31,7 +31,7 @@ futures-cpupool = "0.1"
|
||||
fdlimit = "0.1"
|
||||
ws2_32-sys = "0.2"
|
||||
ctrlc = { git = "https://github.com/paritytech/rust-ctrlc.git" }
|
||||
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.8" }
|
||||
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.9" }
|
||||
ethsync = { path = "sync" }
|
||||
ethcore = { path = "ethcore" }
|
||||
ethcore-util = { path = "util" }
|
||||
|
@ -25,8 +25,8 @@ unicase = "1.4"
|
||||
zip = { version = "0.1", default-features = false }
|
||||
itertools = "0.5"
|
||||
|
||||
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.8" }
|
||||
jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.8" }
|
||||
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.9" }
|
||||
jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.9" }
|
||||
|
||||
ethcore-util = { path = "../util" }
|
||||
ethcore-bigint = { path = "../util/bigint" }
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use jsonrpc_core::BoxFuture;
|
||||
use futures::Future;
|
||||
use hyper;
|
||||
|
||||
#[derive(Debug, PartialEq, Default, Clone)]
|
||||
@ -47,7 +47,7 @@ pub struct EndpointInfo {
|
||||
}
|
||||
|
||||
pub type Endpoints = BTreeMap<String, Box<Endpoint>>;
|
||||
pub type Response = BoxFuture<hyper::Response, hyper::Error>;
|
||||
pub type Response = Box<Future<Item=hyper::Response, Error=hyper::Error> + Send>;
|
||||
pub type Request = hyper::Request;
|
||||
|
||||
pub trait Endpoint : Send + Sync {
|
||||
|
@ -24,7 +24,6 @@ use fetch::{self, Fetch};
|
||||
use futures::sync::oneshot;
|
||||
use futures::{self, Future};
|
||||
use hyper::{self, Method, StatusCode};
|
||||
use jsonrpc_core::BoxFuture;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use endpoint::{self, EndpointPath};
|
||||
@ -212,7 +211,7 @@ impl Errors {
|
||||
|
||||
enum FetchState {
|
||||
Error(ContentHandler),
|
||||
InProgress(BoxFuture<FetchState, ()>),
|
||||
InProgress(Box<Future<Item=FetchState, Error=()> + Send>),
|
||||
Streaming(hyper::Response),
|
||||
Done(local::Dapp, endpoint::Response),
|
||||
Empty,
|
||||
@ -289,7 +288,7 @@ impl ContentFetcherHandler {
|
||||
path: EndpointPath,
|
||||
errors: Errors,
|
||||
installer: H,
|
||||
) -> BoxFuture<FetchState, ()> {
|
||||
) -> Box<Future<Item=FetchState, Error=()> + Send> {
|
||||
// Start fetching the content
|
||||
let fetch2 = fetch.clone();
|
||||
let future = fetch.fetch_with_abort(url, abort.into()).then(move |result| {
|
||||
|
@ -32,7 +32,6 @@ extern crate serde_json;
|
||||
extern crate unicase;
|
||||
extern crate zip;
|
||||
|
||||
extern crate jsonrpc_core;
|
||||
extern crate jsonrpc_http_server;
|
||||
|
||||
extern crate ethcore_util as util;
|
||||
@ -52,10 +51,12 @@ extern crate log;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate env_logger;
|
||||
#[cfg(test)]
|
||||
extern crate ethcore_devtools as devtools;
|
||||
#[cfg(test)]
|
||||
extern crate env_logger;
|
||||
extern crate jsonrpc_core;
|
||||
#[cfg(test)]
|
||||
extern crate parity_reactor;
|
||||
|
||||
|
@ -14,8 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::env;
|
||||
use std::str;
|
||||
use std::{env, io, str};
|
||||
use std::net::SocketAddr;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
@ -187,7 +186,7 @@ impl<T: Fetch> ServerBuilder<T> {
|
||||
|
||||
/// Asynchronously start server with no authentication,
|
||||
/// returns result with `Server` handle on success or an error.
|
||||
pub fn start_unsecured_http(self, addr: &SocketAddr, io: IoHandler) -> Result<Server, http::Error> {
|
||||
pub fn start_unsecured_http(self, addr: &SocketAddr, io: IoHandler) -> io::Result<Server> {
|
||||
let fetch = self.fetch_client();
|
||||
Server::start_http(
|
||||
addr,
|
||||
@ -234,7 +233,7 @@ impl Server {
|
||||
remote: Remote,
|
||||
fetch: F,
|
||||
serve_ui: bool,
|
||||
) -> Result<Server, http::Error> {
|
||||
) -> io::Result<Server> {
|
||||
let health = NodeHealth::new(
|
||||
sync_status.clone(),
|
||||
TimeChecker::new::<String>(&[], CpuPool::new(1)),
|
||||
|
@ -1,23 +1,26 @@
|
||||
### Parity [v1.7.8](https://github.com/paritytech/parity/releases/tag/v1.7.8) (2017-10-27)
|
||||
### Parity [v1.7.9](https://github.com/paritytech/parity/releases/tag/v1.7.9) (2017-11-14)
|
||||
|
||||
- [stable] Refactor static context check in CREATE ([#6889](https://github.com/paritytech/parity/pull/6889))
|
||||
- Fix #6228: do not display eth price in cli for etc ([#6877](https://github.com/paritytech/parity/pull/6877))
|
||||
- Fix mining help ([#6885](https://github.com/paritytech/parity/pull/6885))
|
||||
- [stable] v1.7.8 ([#6890](https://github.com/paritytech/parity/pull/6890))
|
||||
- Refactor static context check in CREATE. ([#6886](https://github.com/paritytech/parity/pull/6886))
|
||||
- Cleanup some configuration options ([#6878](https://github.com/paritytech/parity/pull/6878))
|
||||
- Fix serialization of non-localized transactions ([#6868](https://github.com/paritytech/parity/pull/6868))
|
||||
- Updated NTP to version 0.3 ([#6854](https://github.com/paritytech/parity/pull/6854))
|
||||
- Align README with 1.8 and prepare CHANGELOG with 1.8.1 ([#6833](https://github.com/paritytech/parity/pull/6833))
|
||||
- Return error on timed unlock ([#6777](https://github.com/paritytech/parity/pull/6777))
|
||||
- Fix dapps tests in master ([#6866](https://github.com/paritytech/parity/pull/6866))
|
||||
- [Beta] Add ECIP1017 to Morden config (#6810) ([#6845](https://github.com/paritytech/parity/pull/6845))
|
||||
Parity 1.7.9 removes the ability to deploy built-in multi-signature wallets.
|
||||
|
||||
The full list of included changes:
|
||||
|
||||
- Bump to v1.7.9 ([#7047](https://github.com/paritytech/parity/pull/7047))
|
||||
- Disallow built-in multi-sig deploy (only watch) ([#7017](https://github.com/paritytech/parity/pull/7017))
|
||||
|
||||
### Parity [v1.7.8](https://github.com/paritytech/parity/releases/tag/v1.7.8) (2017-10-26)
|
||||
|
||||
Parity 1.7.8 fixes a critical Byzantium consensus issue. Update is highly recommended.
|
||||
|
||||
The full list of included changes:
|
||||
|
||||
- Refactor static context check in CREATE ([#6889](https://github.com/paritytech/parity/pull/6889))
|
||||
- Bump to v1.7.8 ([#6890](https://github.com/paritytech/parity/pull/6890))
|
||||
|
||||
## Parity [v1.7.7](https://github.com/paritytech/parity/releases/tag/v1.7.7) (2017-10-15)
|
||||
|
||||
Parity 1.7.7 Fixes an issue with auto-update system. Updating is recommended, but not required for Byzantium.
|
||||
Parity 1.7.7 fixes an issue with auto-update system. Updating is recommended, but not required for Byzantium.
|
||||
|
||||
Full list of included changes:
|
||||
The full list of included changes:
|
||||
|
||||
- Fix auto-update ([#6769](https://github.com/paritytech/parity/pull/6759))
|
||||
- Bump to v1.7.7
|
||||
@ -28,7 +31,7 @@ Full list of included changes:
|
||||
|
||||
Parity 1.7.6 includes a critical consensus-relevant fix for the Byzantium hard-fork. Please upgrade your Ethereum client before block number `4_370_000`.
|
||||
|
||||
Full list of included changes:
|
||||
The full list of included changes:
|
||||
|
||||
- Fixed modexp gas calculation overflow ([#6746](https://github.com/paritytech/parity/pull/6746))
|
||||
- Fixed modexp gas calculation overflow ([#6741](https://github.com/paritytech/parity/pull/6741))
|
||||
@ -40,7 +43,7 @@ Parity 1.7.5 includes a critical consensus-relevant fix for the Byzantium hard-f
|
||||
|
||||
Parity 1.7.5 is the first stable release of the 1.7 branch. With this release the support for 1.6 releases ends. Please upgrade your stable nodes to 1.7.5.
|
||||
|
||||
Full list of included changes:
|
||||
The full list of included changes:
|
||||
|
||||
- Backport stable - Fixes Badges ([#6731](https://github.com/paritytech/parity/pull/6731))
|
||||
- Fix badges not showing up ([#6730](https://github.com/paritytech/parity/pull/6730))
|
||||
@ -67,7 +70,7 @@ Full list of included changes:
|
||||
|
||||
Parity 1.7.4 includes a critical consensus-relevant fix for the Byzantium hard-fork. Please upgrade your Ethereum client before block number `4_370_000`.
|
||||
|
||||
Full list of included changes:
|
||||
The full list of included changes:
|
||||
|
||||
- Backport ([#6715](https://github.com/paritytech/parity/pull/6715))
|
||||
- Fix estimate gas if from is not provided. ([#6714](https://github.com/paritytech/parity/pull/6714))
|
||||
@ -95,7 +98,7 @@ Parity 1.7.3 enables the Byzantium fork for Ethereum main network on Block 4_370
|
||||
- Revised timeout and batch size constants for bigger blocks.
|
||||
- Renamed RPC receipt `statusCode` field to `status`.
|
||||
|
||||
Full list of included changes:
|
||||
The full list of included changes:
|
||||
|
||||
- Backporting ([#6676](https://github.com/paritytech/parity/pull/6676))
|
||||
- Fix wallet view ([#6597](https://github.com/paritytech/parity/pull/6597))
|
||||
@ -143,7 +146,7 @@ Parity 1.7.2 is a bug-fix release to improve performance and stability. Among ot
|
||||
- Tweaked warp-sync to quickly catch up with chains fallen back more than 10,000 blocks.
|
||||
- Fixes to the Chrome extension and macOS installer upgrades.
|
||||
|
||||
Full list of included changes:
|
||||
The full list of included changes:
|
||||
|
||||
- Fix output from eth_call. ([#6538](https://github.com/paritytech/parity/pull/6538))
|
||||
- Ropsten fork ([#6532](https://github.com/paritytech/parity/pull/6532))
|
||||
@ -294,7 +297,7 @@ Parity 1.7.0 is a major release introducing several important features:
|
||||
- **PubSub API**. https://github.com/paritytech/parity/wiki/JSONRPC-Parity-Pub-Sub-module
|
||||
- **Signer apps for IOS and Android**.
|
||||
|
||||
Full list of included changes:
|
||||
The full list of included changes:
|
||||
|
||||
- Backports [#6163](https://github.com/paritytech/parity/pull/6163)
|
||||
- Light client improvements ([#6156](https://github.com/paritytech/parity/pull/6156))
|
||||
|
@ -16,7 +16,6 @@ memorydb = { path = "../../util/memorydb" }
|
||||
patricia-trie = { path = "../../util/patricia_trie" }
|
||||
ethcore-network = { path = "../../util/network" }
|
||||
ethcore-io = { path = "../../util/io" }
|
||||
ethcore-devtools = { path = "../../devtools" }
|
||||
evm = { path = "../evm" }
|
||||
heapsize = "0.4"
|
||||
vm = { path = "../vm" }
|
||||
@ -39,5 +38,8 @@ kvdb-rocksdb = { path = "../../util/kvdb-rocksdb" }
|
||||
kvdb-memorydb = { path = "../../util/kvdb-memorydb" }
|
||||
memory-cache = { path = "../../util/memory_cache" }
|
||||
|
||||
[dev-dependencies]
|
||||
tempdir = "0.3"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
@ -120,7 +120,6 @@ impl<T: ChainDataFetcher> IoHandler<ClientIoMessage> for ImportBlocks<T> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Service;
|
||||
use devtools::RandomTempPath;
|
||||
use ethcore::spec::Spec;
|
||||
|
||||
use std::sync::Arc;
|
||||
@ -128,13 +127,14 @@ mod tests {
|
||||
use client::fetch;
|
||||
use time::Duration;
|
||||
use parking_lot::Mutex;
|
||||
use tempdir::TempDir;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let tempdir = TempDir::new("").unwrap();
|
||||
let spec = Spec::new_test();
|
||||
let temp_path = RandomTempPath::new();
|
||||
let cache = Arc::new(Mutex::new(Cache::new(Default::default(), Duration::hours(6))));
|
||||
|
||||
Service::start(Default::default(), &spec, fetch::unavailable(), temp_path.as_path(), cache).unwrap();
|
||||
Service::start(Default::default(), &spec, fetch::unavailable(), tempdir.path(), cache).unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -84,4 +84,4 @@ extern crate kvdb_rocksdb;
|
||||
extern crate memory_cache;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate ethcore_devtools as devtools;
|
||||
extern crate tempdir;
|
||||
|
@ -17,10 +17,8 @@
|
||||
//! Defines error types and levels of punishment to use upon
|
||||
//! encountering.
|
||||
|
||||
use rlp::DecoderError;
|
||||
use network::NetworkError;
|
||||
|
||||
use std::fmt;
|
||||
use {rlp, network};
|
||||
|
||||
/// Levels of punishment.
|
||||
///
|
||||
@ -41,9 +39,9 @@ pub enum Punishment {
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// An RLP decoding error.
|
||||
Rlp(DecoderError),
|
||||
Rlp(rlp::DecoderError),
|
||||
/// A network error.
|
||||
Network(NetworkError),
|
||||
Network(network::Error),
|
||||
/// Out of credits.
|
||||
NoCredits,
|
||||
/// Unrecognized packet code.
|
||||
@ -92,14 +90,14 @@ impl Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DecoderError> for Error {
|
||||
fn from(err: DecoderError) -> Self {
|
||||
impl From<rlp::DecoderError> for Error {
|
||||
fn from(err: rlp::DecoderError) -> Self {
|
||||
Error::Rlp(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NetworkError> for Error {
|
||||
fn from(err: NetworkError) -> Self {
|
||||
impl From<network::Error> for Error {
|
||||
fn from(err: network::Error) -> Self {
|
||||
Error::Network(err)
|
||||
}
|
||||
}
|
||||
|
@ -264,8 +264,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn file_store() {
|
||||
let path = ::devtools::RandomTempPath::new();
|
||||
let store = FileStore(path.as_path().clone());
|
||||
let tempdir = ::tempdir::TempDir::new("").unwrap();
|
||||
let path = tempdir.path().join("file");
|
||||
let store = FileStore(path);
|
||||
|
||||
let mut samples = store.load();
|
||||
assert!(samples.is_empty());
|
||||
|
@ -23,7 +23,8 @@
|
||||
]
|
||||
},
|
||||
"validateScoreTransition": 1000000,
|
||||
"validateStepTransition": 1500000
|
||||
"validateStepTransition": 1500000,
|
||||
"maximumUncleCount": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 94b7877b5826a53627b8732ea0feb45869dd04ab
|
||||
Subproject commit 9a1fcbf0d4e73bea437577e807bc38c7ba243d80
|
@ -65,6 +65,8 @@ pub struct AuthorityRoundParams {
|
||||
pub immediate_transitions: bool,
|
||||
/// Block reward in base units.
|
||||
pub block_reward: U256,
|
||||
/// Number of accepted uncles.
|
||||
pub maximum_uncle_count: usize,
|
||||
}
|
||||
|
||||
impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
||||
@ -77,6 +79,7 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
||||
validate_step_transition: p.validate_step_transition.map_or(0, Into::into),
|
||||
immediate_transitions: p.immediate_transitions.unwrap_or(false),
|
||||
block_reward: p.block_reward.map_or_else(Default::default, Into::into),
|
||||
maximum_uncle_count: p.maximum_uncle_count.map_or(0, Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -218,6 +221,7 @@ pub struct AuthorityRound {
|
||||
epoch_manager: Mutex<EpochManager>,
|
||||
immediate_transitions: bool,
|
||||
block_reward: U256,
|
||||
maximum_uncle_count: usize,
|
||||
machine: EthereumMachine,
|
||||
}
|
||||
|
||||
@ -365,6 +369,7 @@ impl AuthorityRound {
|
||||
epoch_manager: Mutex::new(EpochManager::blank()),
|
||||
immediate_transitions: our_params.immediate_transitions,
|
||||
block_reward: our_params.block_reward,
|
||||
maximum_uncle_count: our_params.maximum_uncle_count,
|
||||
machine: machine,
|
||||
});
|
||||
|
||||
@ -436,6 +441,8 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
]
|
||||
}
|
||||
|
||||
fn maximum_uncle_count(&self) -> usize { self.maximum_uncle_count }
|
||||
|
||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
|
||||
// Chain scoring: total weight is sqrt(U256::max_value())*height - step
|
||||
let new_difficulty = U256::from(U128::max_value()) + header_step(parent).expect("Header has been verified; qed").into() - self.step.load().into();
|
||||
@ -949,6 +956,7 @@ mod tests {
|
||||
validate_score_transition: 0,
|
||||
validate_step_transition: 0,
|
||||
immediate_transitions: true,
|
||||
maximum_uncle_count: 0,
|
||||
block_reward: Default::default(),
|
||||
};
|
||||
|
||||
|
@ -192,7 +192,7 @@ pub trait Engine<M: Machine>: Sync + Send {
|
||||
fn extra_info(&self, _header: &M::Header) -> BTreeMap<String, String> { BTreeMap::new() }
|
||||
|
||||
/// Maximum number of uncles a block is allowed to declare.
|
||||
fn maximum_uncle_count(&self) -> usize { 2 }
|
||||
fn maximum_uncle_count(&self) -> usize { 0 }
|
||||
/// The number of generations back that uncles can be.
|
||||
fn maximum_uncle_age(&self) -> usize { 6 }
|
||||
|
||||
|
@ -95,6 +95,8 @@ impl<M: WithBalances> Engine<M> for NullEngine<M> {
|
||||
self.machine.note_rewards(block, &[(author, result_block_reward)], &uncle_rewards)
|
||||
}
|
||||
|
||||
fn maximum_uncle_count(&self) -> usize { 2 }
|
||||
|
||||
fn verify_local_seal(&self, _header: &M::Header) -> Result<(), M::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -181,6 +181,8 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
|
||||
}
|
||||
}
|
||||
|
||||
fn maximum_uncle_count(&self) -> usize { 2 }
|
||||
|
||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
|
||||
let difficulty = self.calculate_difficulty(header, parent);
|
||||
header.set_difficulty(difficulty);
|
||||
|
@ -127,12 +127,14 @@ pub struct WasmCosts {
|
||||
pub mul: u32,
|
||||
/// Memory (load/store) operations multiplier.
|
||||
pub mem: u32,
|
||||
/// Memory copy operation.
|
||||
/// Memory copy operation, per byte.
|
||||
pub mem_copy: u32,
|
||||
/// Memory move operation, per byte.
|
||||
pub mem_move: u32,
|
||||
/// Memory set operation, per byte.
|
||||
pub mem_set: u32,
|
||||
/// Static region charge, per byte.
|
||||
pub static_region: u32,
|
||||
/// General static query of u64 value from env-info
|
||||
pub static_u64: u32,
|
||||
/// General static query of U256 value from env-info
|
||||
pub static_u256: u32,
|
||||
/// General static query of Address value from env-info
|
||||
@ -147,11 +149,9 @@ impl Default for WasmCosts {
|
||||
mul: 4,
|
||||
mem: 2,
|
||||
mem_copy: 1,
|
||||
mem_move: 1,
|
||||
mem_set: 1,
|
||||
static_region: 1,
|
||||
|
||||
// due to runtime issues, this can be slow
|
||||
static_u64: 32,
|
||||
|
||||
static_u256: 64,
|
||||
static_address: 40,
|
||||
}
|
||||
|
@ -38,12 +38,12 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
None,
|
||||
),
|
||||
Static(
|
||||
"_malloc",
|
||||
"_ext_malloc",
|
||||
&[I32],
|
||||
Some(I32),
|
||||
),
|
||||
Static(
|
||||
"_free",
|
||||
"_ext_free",
|
||||
&[I32],
|
||||
None,
|
||||
),
|
||||
@ -92,6 +92,21 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
&[I32; 3],
|
||||
Some(I32),
|
||||
),
|
||||
Static(
|
||||
"_ext_memcpy",
|
||||
&[I32; 3],
|
||||
Some(I32),
|
||||
),
|
||||
Static(
|
||||
"_ext_memset",
|
||||
&[I32; 3],
|
||||
Some(I32),
|
||||
),
|
||||
Static(
|
||||
"_ext_memmove",
|
||||
&[I32; 3],
|
||||
Some(I32),
|
||||
),
|
||||
Static(
|
||||
"_panic",
|
||||
&[I32; 2],
|
||||
@ -99,7 +114,7 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
),
|
||||
Static(
|
||||
"_blockhash",
|
||||
&[I32; 3],
|
||||
&[I64, I32],
|
||||
Some(I32),
|
||||
),
|
||||
Static(
|
||||
@ -130,12 +145,12 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
Static(
|
||||
"_timestamp",
|
||||
&[],
|
||||
Some(I32),
|
||||
Some(I64),
|
||||
),
|
||||
Static(
|
||||
"_blocknumber",
|
||||
&[],
|
||||
Some(I32),
|
||||
Some(I64),
|
||||
),
|
||||
Static(
|
||||
"_difficulty",
|
||||
@ -162,8 +177,8 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
|
||||
Static(
|
||||
"_llvm_bswap_i64",
|
||||
&[I32; 2],
|
||||
Some(I32)
|
||||
&[I64],
|
||||
Some(I64)
|
||||
),
|
||||
];
|
||||
|
||||
|
@ -560,32 +560,67 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
fn mem_copy(&mut self, context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
//
|
||||
// method signature:
|
||||
// fn memcpy(dest: *const u8, src: *const u8, len: u32) -> *mut u8;
|
||||
//
|
||||
|
||||
let len = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let dst = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let src = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let dst = context.value_stack.pop_as::<i32>()? as u32;
|
||||
|
||||
self.charge(|schedule| schedule.wasm.mem_copy as u64 * len as u64)?;
|
||||
|
||||
let mem = self.memory().get(src, len as usize)?;
|
||||
self.memory().set(dst, &mem)?;
|
||||
self.memory().copy_nonoverlapping(src as usize, dst as usize, len as usize)?;
|
||||
|
||||
Ok(Some(0i32.into()))
|
||||
Ok(Some(Into::into(dst as i32)))
|
||||
}
|
||||
|
||||
fn bswap_32(x: u32) -> u32 {
|
||||
x >> 24 | x >> 8 & 0xff00 | x << 8 & 0xff0000 | x << 24
|
||||
fn mem_move(&mut self, context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
//
|
||||
// method signature:
|
||||
// fn memmove(dest: *const u8, src: *const u8, len: u32) -> *mut u8;
|
||||
//
|
||||
|
||||
let len = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let src = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let dst = context.value_stack.pop_as::<i32>()? as u32;
|
||||
|
||||
self.charge(|schedule| schedule.wasm.mem_move as u64 * len as u64)?;
|
||||
|
||||
self.memory().copy(src as usize, dst as usize, len as usize)?;
|
||||
|
||||
Ok(Some(Into::into(dst as i32)))
|
||||
}
|
||||
|
||||
fn mem_set(&mut self, context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
//
|
||||
// method signature:
|
||||
// fn memset(dest: *const u8, c: u32, len: u32) -> *mut u8;
|
||||
//
|
||||
|
||||
let len = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let c = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let dst = context.value_stack.pop_as::<i32>()? as u32;
|
||||
|
||||
self.charge(|schedule| schedule.wasm.mem_set as u64 * len as u64)?;
|
||||
|
||||
self.memory().clear(dst as usize, c as u8, len as usize)?;
|
||||
|
||||
Ok(Some(Into::into(dst as i32)))
|
||||
}
|
||||
|
||||
fn bitswap_i64(&mut self, context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
let x1 = context.value_stack.pop_as::<i32>()?;
|
||||
let x2 = context.value_stack.pop_as::<i32>()?;
|
||||
let x = context.value_stack.pop_as::<i64>()?;
|
||||
let result = x.swap_bytes();
|
||||
|
||||
let result = ((Runtime::bswap_32(x2 as u32) as u64) << 32
|
||||
| Runtime::bswap_32(x1 as u32) as u64) as i64;
|
||||
|
||||
self.return_i64(result)
|
||||
Ok(Some(result.into()))
|
||||
}
|
||||
|
||||
fn user_panic(&mut self, context: InterpreterCallerContext)
|
||||
@ -606,13 +641,10 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
let return_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let block_hi = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let block_lo = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let block_num = context.value_stack.pop_as::<i64>()? as u64;
|
||||
|
||||
self.charge(|schedule| schedule.blockhash_gas as u64)?;
|
||||
|
||||
let block_num = (block_hi as u64) << 32 | block_lo as u64;
|
||||
|
||||
trace!("Requesting block hash for block #{}", block_num);
|
||||
let hash = self.ext.blockhash(&U256::from(block_num));
|
||||
|
||||
@ -694,14 +726,14 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
let timestamp = self.ext.env_info().timestamp as i64;
|
||||
self.return_i64(timestamp)
|
||||
Ok(Some(timestamp.into()))
|
||||
}
|
||||
|
||||
fn block_number(&mut self, _context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
let block_number: u64 = self.ext.env_info().number.into();
|
||||
self.return_i64(block_number as i64)
|
||||
let block_number = self.ext.env_info().number as i64;
|
||||
Ok(Some(block_number.into()))
|
||||
}
|
||||
|
||||
fn difficulty(&mut self, context: InterpreterCallerContext)
|
||||
@ -726,25 +758,6 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn return_i64(&mut self, val: i64) -> Result<Option<interpreter::RuntimeValue>, InterpreterError> {
|
||||
self.charge(|schedule| schedule.wasm.static_u64 as u64)?;
|
||||
|
||||
let uval = val as u64;
|
||||
let hi = (uval >> 32) as i32;
|
||||
let lo = (uval << 32 >> 32) as i32;
|
||||
|
||||
let target = self.instance.module("contract").ok_or(UserTrap::Other)?;
|
||||
target.execute_export(
|
||||
"setTempRet0",
|
||||
self.execution_params().add_argument(
|
||||
interpreter::RuntimeValue::I32(hi).into()
|
||||
),
|
||||
)?;
|
||||
Ok(Some(
|
||||
(lo).into()
|
||||
))
|
||||
}
|
||||
|
||||
pub fn execution_params(&mut self) -> interpreter::ExecutionParams<UserTrap> {
|
||||
use super::env;
|
||||
|
||||
@ -812,10 +825,10 @@ impl<'a, 'b> interpreter::UserFunctionExecutor<UserTrap> for Runtime<'a, 'b> {
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
match name {
|
||||
"_malloc" => {
|
||||
"_ext_malloc" => {
|
||||
self.malloc(context)
|
||||
},
|
||||
"_free" => {
|
||||
"_ext_free" => {
|
||||
// Since it is arena allocator, free does nothing
|
||||
// todo: update if changed
|
||||
self.user_noop(context)
|
||||
@ -853,6 +866,15 @@ impl<'a, 'b> interpreter::UserFunctionExecutor<UserTrap> for Runtime<'a, 'b> {
|
||||
"_emscripten_memcpy_big" => {
|
||||
self.mem_copy(context)
|
||||
},
|
||||
"_ext_memcpy" => {
|
||||
self.mem_copy(context)
|
||||
},
|
||||
"_ext_memmove" => {
|
||||
self.mem_move(context)
|
||||
},
|
||||
"_ext_memset" => {
|
||||
self.mem_set(context)
|
||||
},
|
||||
"_llvm_bswap_i64" => {
|
||||
self.bitswap_i64(context)
|
||||
},
|
||||
|
@ -60,7 +60,7 @@ fn empty() {
|
||||
test_finalize(interpreter.exec(params, &mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(99_976));
|
||||
assert_eq!(gas_left, U256::from(99_982));
|
||||
}
|
||||
|
||||
// This test checks if the contract deserializes payload header properly.
|
||||
@ -89,7 +89,6 @@ fn logger() {
|
||||
test_finalize(interpreter.exec(params, &mut ext)).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(15_177));
|
||||
let address_val: H256 = address.into();
|
||||
assert_eq!(
|
||||
ext.store.get(&"0100000000000000000000000000000000000000000000000000000000000000".parse().unwrap()).expect("storage key to exist"),
|
||||
@ -113,6 +112,7 @@ fn logger() {
|
||||
U256::from(1_000_000_000),
|
||||
"Logger sets 0x04 key to the trasferred value"
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(19_143));
|
||||
}
|
||||
|
||||
// This test checks if the contract can allocate memory and pass pointer to the result stream properly.
|
||||
@ -142,13 +142,12 @@ fn identity() {
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(99_695));
|
||||
|
||||
assert_eq!(
|
||||
Address::from_slice(&result),
|
||||
sender,
|
||||
"Idenity test contract does not return the sender passed"
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(99_844));
|
||||
}
|
||||
|
||||
// Dispersion test sends byte array and expect the contract to 'disperse' the original elements with
|
||||
@ -176,12 +175,12 @@ fn dispersion() {
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(96_543));
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
vec![0u8, 0, 125, 11, 197, 7, 255, 8, 19, 0]
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(99_469));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -205,12 +204,11 @@ fn suicide_not() {
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(96_822));
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
vec![0u8]
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(99_724));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -241,8 +239,8 @@ fn suicide() {
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(96_580));
|
||||
assert!(ext.suicides.contains(&refund));
|
||||
assert_eq!(gas_left, U256::from(99_663));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -272,7 +270,7 @@ fn create() {
|
||||
assert!(ext.calls.contains(
|
||||
&FakeCall {
|
||||
call_type: FakeCallType::Create,
|
||||
gas: U256::from(62_324),
|
||||
gas: U256::from(65_903),
|
||||
sender_address: None,
|
||||
receive_address: None,
|
||||
value: Some(1_000_000_000.into()),
|
||||
@ -280,7 +278,7 @@ fn create() {
|
||||
code_address: None,
|
||||
}
|
||||
));
|
||||
assert_eq!(gas_left, U256::from(62_289));
|
||||
assert_eq!(gas_left, U256::from(65_896));
|
||||
}
|
||||
|
||||
|
||||
@ -314,7 +312,7 @@ fn call_code() {
|
||||
assert!(ext.calls.contains(
|
||||
&FakeCall {
|
||||
call_type: FakeCallType::Call,
|
||||
gas: U256::from(95_585),
|
||||
gas: U256::from(98_709),
|
||||
sender_address: Some(sender),
|
||||
receive_address: Some(receiver),
|
||||
value: None,
|
||||
@ -322,11 +320,11 @@ fn call_code() {
|
||||
code_address: Some("0d13710000000000000000000000000000000000".parse().unwrap()),
|
||||
}
|
||||
));
|
||||
assert_eq!(gas_left, U256::from(90_665));
|
||||
|
||||
// siphash result
|
||||
let res = LittleEndian::read_u32(&result[..]);
|
||||
assert_eq!(res, 4198595614);
|
||||
assert_eq!(gas_left, U256::from(93_851));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -359,7 +357,7 @@ fn call_static() {
|
||||
assert!(ext.calls.contains(
|
||||
&FakeCall {
|
||||
call_type: FakeCallType::Call,
|
||||
gas: U256::from(95_585),
|
||||
gas: U256::from(98_709),
|
||||
sender_address: Some(sender),
|
||||
receive_address: Some(receiver),
|
||||
value: None,
|
||||
@ -367,11 +365,12 @@ fn call_static() {
|
||||
code_address: Some("13077bfb00000000000000000000000000000000".parse().unwrap()),
|
||||
}
|
||||
));
|
||||
assert_eq!(gas_left, U256::from(90_665));
|
||||
|
||||
// siphash result
|
||||
let res = LittleEndian::read_u32(&result[..]);
|
||||
assert_eq!(res, 317632590);
|
||||
|
||||
assert_eq!(gas_left, U256::from(93_851));
|
||||
}
|
||||
|
||||
// Realloc test
|
||||
@ -393,8 +392,8 @@ fn realloc() {
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
}
|
||||
};
|
||||
assert_eq!(gas_left, U256::from(96_811));
|
||||
assert_eq!(result, vec![0u8; 2]);
|
||||
assert_eq!(gas_left, U256::from(99_787));
|
||||
}
|
||||
|
||||
// Tests that contract's ability to read from a storage
|
||||
@ -419,8 +418,8 @@ fn storage_read() {
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(gas_left, U256::from(96_645));
|
||||
assert_eq!(Address::from(&result[12..32]), address);
|
||||
assert_eq!(gas_left, U256::from(99_702));
|
||||
}
|
||||
|
||||
// Tests keccak calculation
|
||||
@ -446,9 +445,97 @@ fn keccak() {
|
||||
};
|
||||
|
||||
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
|
||||
assert_eq!(gas_left, U256::from(80_452));
|
||||
assert_eq!(gas_left, U256::from(84_520));
|
||||
}
|
||||
|
||||
// memcpy test.
|
||||
#[test]
|
||||
fn memcpy() {
|
||||
::ethcore_logger::init_log();
|
||||
let code = load_sample!("mem.wasm");
|
||||
|
||||
let mut test_payload = Vec::with_capacity(8192);
|
||||
for i in 0..8192 {
|
||||
test_payload.push((i % 255) as u8);
|
||||
}
|
||||
let mut data = vec![0u8];
|
||||
data.extend(&test_payload);
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.data = Some(data);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("mem should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(result, test_payload);
|
||||
assert_eq!(gas_left, U256::from(75_324));
|
||||
}
|
||||
|
||||
// memmove test.
|
||||
#[test]
|
||||
fn memmove() {
|
||||
::ethcore_logger::init_log();
|
||||
let code = load_sample!("mem.wasm");
|
||||
|
||||
let mut test_payload = Vec::with_capacity(8192);
|
||||
for i in 0..8192 {
|
||||
test_payload.push((i % 255) as u8);
|
||||
}
|
||||
let mut data = vec![1u8];
|
||||
data.extend(&test_payload);
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.data = Some(data);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("mem should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(result, test_payload);
|
||||
assert_eq!(gas_left, U256::from(75_324));
|
||||
}
|
||||
|
||||
// memset test
|
||||
#[test]
|
||||
fn memset() {
|
||||
::ethcore_logger::init_log();
|
||||
let code = load_sample!("mem.wasm");
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.data = Some(vec![2u8, 228u8]);
|
||||
let mut ext = FakeExt::new();
|
||||
|
||||
let (gas_left, result) = {
|
||||
let mut interpreter = wasm_interpreter();
|
||||
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||
match result {
|
||||
GasLeft::Known(_) => { panic!("mem should return payload"); },
|
||||
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(result, vec![228u8; 8192]);
|
||||
assert_eq!(gas_left, U256::from(75_324));
|
||||
}
|
||||
|
||||
macro_rules! reqrep_test {
|
||||
($name: expr, $input: expr) => {
|
||||
@ -500,11 +587,11 @@ fn math_add() {
|
||||
}
|
||||
).expect("Interpreter to execute without any errors");
|
||||
|
||||
assert_eq!(gas_left, U256::from(94_666));
|
||||
assert_eq!(
|
||||
U256::from_dec_str("1888888888888888888888888888887").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(98_576));
|
||||
}
|
||||
|
||||
// multiplication
|
||||
@ -522,11 +609,11 @@ fn math_mul() {
|
||||
}
|
||||
).expect("Interpreter to execute without any errors");
|
||||
|
||||
assert_eq!(gas_left, U256::from(93_719));
|
||||
assert_eq!(
|
||||
U256::from_dec_str("888888888888888888888888888887111111111111111111111111111112").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(97_726));
|
||||
}
|
||||
|
||||
// subtraction
|
||||
@ -544,11 +631,11 @@ fn math_sub() {
|
||||
}
|
||||
).expect("Interpreter to execute without any errors");
|
||||
|
||||
assert_eq!(gas_left, U256::from(94_718));
|
||||
assert_eq!(
|
||||
U256::from_dec_str("111111111111111111111111111111").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(98_568));
|
||||
}
|
||||
|
||||
// subtraction with overflow
|
||||
@ -566,7 +653,10 @@ fn math_sub_with_overflow() {
|
||||
}
|
||||
);
|
||||
|
||||
assert_eq!(result, Err(vm::Error::Wasm("Wasm runtime error: User(Panic(\"arithmetic operation overflow\"))".into())));
|
||||
match result {
|
||||
Err(vm::Error::Wasm(_)) => {},
|
||||
_ => panic!("Unexpected result {:?}", result),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -583,11 +673,11 @@ fn math_div() {
|
||||
}
|
||||
).expect("Interpreter to execute without any errors");
|
||||
|
||||
assert_eq!(gas_left, U256::from(86_996));
|
||||
assert_eq!(
|
||||
U256::from_dec_str("1125000").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(91_564));
|
||||
}
|
||||
|
||||
// This test checks the ability of wasm contract to invoke
|
||||
@ -675,7 +765,7 @@ fn externs() {
|
||||
"Gas limit requested and returned does not match"
|
||||
);
|
||||
|
||||
assert_eq!(gas_left, U256::from(91_857));
|
||||
assert_eq!(gas_left, U256::from(97_740));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -701,7 +791,7 @@ fn embedded_keccak() {
|
||||
};
|
||||
|
||||
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
|
||||
assert_eq!(gas_left, U256::from(80_452));
|
||||
assert_eq!(gas_left, U256::from(84_520));
|
||||
}
|
||||
|
||||
/// This test checks the correctness of log extern
|
||||
@ -736,5 +826,5 @@ fn events() {
|
||||
assert_eq!(&log_entry.data, b"gnihtemos");
|
||||
|
||||
assert_eq!(&result, b"gnihtemos");
|
||||
assert_eq!(gas_left, U256::from(78039));
|
||||
}
|
||||
assert_eq!(gas_left, U256::from(82_721));
|
||||
}
|
||||
|
@ -209,8 +209,8 @@ fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item
|
||||
let secret = args.arg_secret.parse().map_err(|_| ethstore::Error::InvalidSecret)?;
|
||||
let password = load_password(&args.arg_password)?;
|
||||
let vault_ref = open_args_vault(&store, &args)?;
|
||||
let address = store.insert_account(vault_ref, secret, &password)?;
|
||||
Ok(format!("0x{:?}", address))
|
||||
let account_ref = store.insert_account(vault_ref, secret, &password)?;
|
||||
Ok(format!("0x{:?}", account_ref.address))
|
||||
} else if args.cmd_change_pwd {
|
||||
let address = args.arg_address.parse().map_err(|_| ethstore::Error::InvalidAccount)?;
|
||||
let old_pwd = load_password(&args.arg_old_pwd)?;
|
||||
@ -237,8 +237,8 @@ fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item
|
||||
let password = load_password(&args.arg_password)?;
|
||||
let kp = wallet.decrypt(&password)?;
|
||||
let vault_ref = open_args_vault(&store, &args)?;
|
||||
let address = store.insert_account(vault_ref, kp.secret().clone(), &password)?;
|
||||
Ok(format!("0x{:?}", address))
|
||||
let account_ref = store.insert_account(vault_ref, kp.secret().clone(), &password)?;
|
||||
Ok(format!("0x{:?}", account_ref.address))
|
||||
} else if args.cmd_remove {
|
||||
let address = args.arg_address.parse().map_err(|_| ethstore::Error::InvalidAccount)?;
|
||||
let password = load_password(&args.arg_password)?;
|
||||
|
@ -14,7 +14,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::iter::repeat;
|
||||
use std::str;
|
||||
use ethkey::Secret;
|
||||
use {json, Error, crypto};
|
||||
@ -90,9 +89,7 @@ impl Crypto {
|
||||
// preallocated (on-stack in case of `Secret`) buffer to hold cipher
|
||||
// length = length(plain) as we are using CTR-approach
|
||||
let plain_len = plain.len();
|
||||
let mut ciphertext: SmallVec<[u8; 32]> = SmallVec::new();
|
||||
ciphertext.grow(plain_len);
|
||||
ciphertext.extend(repeat(0).take(plain_len));
|
||||
let mut ciphertext: SmallVec<[u8; 32]> = SmallVec::from_vec(vec![0; plain_len]);
|
||||
|
||||
// aes-128-ctr with initial vector of iv
|
||||
crypto::aes::encrypt(&derived_left_bits, &iv, plain, &mut *ciphertext);
|
||||
@ -143,9 +140,7 @@ impl Crypto {
|
||||
return Err(Error::InvalidPassword);
|
||||
}
|
||||
|
||||
let mut plain: SmallVec<[u8; 32]> = SmallVec::new();
|
||||
plain.grow(expected_len);
|
||||
plain.extend(repeat(0).take(expected_len));
|
||||
let mut plain: SmallVec<[u8; 32]> = SmallVec::from_vec(vec![0; expected_len]);
|
||||
|
||||
match self.cipher {
|
||||
Cipher::Aes128Ctr(ref params) => {
|
||||
|
@ -7,11 +7,10 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
ethcore = { path = "../ethcore" }
|
||||
ethcore-util = { path = "../util" }
|
||||
ethcore-bigint = { path = "../util/bigint" }
|
||||
ethcore-bytes = { path = "../util/bytes" }
|
||||
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.8" }
|
||||
jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.8" }
|
||||
jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.9" }
|
||||
jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.9" }
|
||||
rlp = { path = "../util/rlp" }
|
||||
cid = "0.2"
|
||||
multihash = "0.6"
|
||||
|
@ -20,7 +20,6 @@ extern crate unicase;
|
||||
|
||||
extern crate rlp;
|
||||
extern crate ethcore;
|
||||
extern crate ethcore_util as util;
|
||||
extern crate ethcore_bigint as bigint;
|
||||
extern crate ethcore_bytes as bytes;
|
||||
extern crate jsonrpc_core as core;
|
||||
|
5325
js-old/package-lock.json
generated
5325
js-old/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "parity.js",
|
||||
"version": "1.8.18",
|
||||
"name": "@parity/dapp-v1",
|
||||
"version": "1.9.99",
|
||||
"main": "release/index.js",
|
||||
"jsnext:main": "src/index.js",
|
||||
"author": "Parity Team <admin@parity.io>",
|
||||
@ -27,42 +27,17 @@
|
||||
],
|
||||
"scripts": {
|
||||
"install": "napa",
|
||||
"analize": "npm run analize:lib && npm run analize:dll && npm run analize:app",
|
||||
"analize:app": "WPANALIZE=1 webpack --config webpack/app --json > .build/analize.app.json && cat .build/analize.app.json | webpack-bundle-size-analyzer",
|
||||
"analize:lib": "WPANALIZE=1 webpack --config webpack/libraries --json > .build/analize.lib.json && cat .build/analize.lib.json | webpack-bundle-size-analyzer",
|
||||
"analize:dll": "WPANALIZE=1 webpack --config webpack/vendor --json > .build/analize.dll.json && cat .build/analize.dll.json | webpack-bundle-size-analyzer",
|
||||
"build": "npm run build:lib && npm run build:dll && npm run build:app && npm run build:embed",
|
||||
"build": "npm run build:lib && npm run build:dll && npm run build:app",
|
||||
"build:app": "webpack --config webpack/app",
|
||||
"build:lib": "webpack --config webpack/libraries",
|
||||
"build:dll": "webpack --config webpack/vendor",
|
||||
"build:markdown": "babel-node ./scripts/build-rpc-markdown.js",
|
||||
"build:json": "babel-node ./scripts/build-rpc-json.js",
|
||||
"build:embed": "EMBED=1 node webpack/embed",
|
||||
"build:i18n": "npm run clean && npm run build && babel-node ./scripts/build-i18n.js",
|
||||
"ci:build": "npm run ci:build:lib && npm run ci:build:dll && npm run ci:build:app && npm run ci:build:embed",
|
||||
"ci:build:app": "NODE_ENV=production webpack --config webpack/app",
|
||||
"ci:build:lib": "NODE_ENV=production webpack --config webpack/libraries",
|
||||
"ci:build:dll": "NODE_ENV=production webpack --config webpack/vendor",
|
||||
"ci:build:npm": "NODE_ENV=production webpack --config webpack/npm",
|
||||
"ci:build:jsonrpc": "babel-node ./scripts/build-rpc-json.js --output .npmjs/jsonrpc",
|
||||
"ci:build:embed": "NODE_ENV=production EMBED=1 node webpack/embed",
|
||||
"start": "npm run clean && npm install && npm run build:lib && npm run build:dll && npm run start:app",
|
||||
"start:app": "node webpack/dev.server",
|
||||
"clean": "rm -rf ./.build ./.coverage ./.happypack ./.npmjs ./build ./node_modules/.cache ./node_modules/@parity",
|
||||
"coveralls": "npm run testCoverage && coveralls < coverage/lcov.info",
|
||||
"ci:build": "cross-env NODE_ENV=production npm run build",
|
||||
"clean": "rimraf ./.build ./.coverage ./.happypack ./.npmjs ./build ./node_modules/.cache",
|
||||
"lint": "npm run lint:css && npm run lint:js",
|
||||
"lint:cached": "npm run lint:css && npm run lint:js:cached",
|
||||
"lint:css": "stylelint ./src/**/*.css",
|
||||
"lint:fix": "npm run lint:js:fix",
|
||||
"lint:i18n": "babel-node ./scripts/lint-i18n.js",
|
||||
"lint:js": "eslint --ignore-path .gitignore ./src/",
|
||||
"lint:js:cached": "eslint --cache --ignore-path .gitignore ./src/",
|
||||
"lint:js:fix": "eslint --fix --ignore-path .gitignore ./src/",
|
||||
"test": "NODE_ENV=test mocha --compilers ejs:ejsify 'src/**/*.spec.js'",
|
||||
"test:coverage": "NODE_ENV=test istanbul cover _mocha -- --compilers ejs:ejsify 'src/**/*.spec.js'",
|
||||
"test:e2e": "NODE_ENV=test mocha 'src/**/*.e2e.js'",
|
||||
"test:npm": "(cd .npmjs && npm i) && node test/npmParity && node test/npmJsonRpc && (rm -rf .npmjs/node_modules)",
|
||||
"prepush": "npm run lint:cached"
|
||||
"watch": "webpack --watch --config webpack/app"
|
||||
},
|
||||
"napa": {
|
||||
"qrcode-generator": "kazuhikoarase/qrcode-generator"
|
||||
@ -98,6 +73,7 @@
|
||||
"copy-webpack-plugin": "4.0.1",
|
||||
"core-js": "2.4.1",
|
||||
"coveralls": "2.11.16",
|
||||
"cross-env": "5.1.1",
|
||||
"css-loader": "0.26.1",
|
||||
"ejs-loader": "0.3.0",
|
||||
"ejsify": "1.0.0",
|
||||
@ -118,9 +94,7 @@
|
||||
"html-loader": "0.4.4",
|
||||
"html-webpack-plugin": "2.28.0",
|
||||
"http-proxy-middleware": "0.17.3",
|
||||
"husky": "0.13.1",
|
||||
"ignore-styles": "5.0.1",
|
||||
"image-webpack-loader": "3.2.0",
|
||||
"istanbul": "1.0.0-alpha.2",
|
||||
"jsdom": "9.11.0",
|
||||
"json-loader": "0.5.4",
|
||||
@ -140,6 +114,7 @@
|
||||
"react-addons-test-utils": "15.4.2",
|
||||
"react-hot-loader": "3.0.0-beta.6",
|
||||
"react-intl-aggregate-webpack-plugin": "0.0.1",
|
||||
"rimraf": "2.6.2",
|
||||
"rucksack-css": "0.9.1",
|
||||
"script-ext-html-webpack-plugin": "1.7.1",
|
||||
"serviceworker-webpack-plugin": "0.2.0",
|
||||
@ -160,9 +135,8 @@
|
||||
"yargs": "6.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@parity/wordlist": "1.0.1",
|
||||
"arraybuffer-loader": "0.2.2",
|
||||
"babel-runtime": "6.23.0",
|
||||
"@parity/api": "2.1.x",
|
||||
"@parity/wordlist": "1.1.x",
|
||||
"base32.js": "0.1.0",
|
||||
"bignumber.js": "3.0.1",
|
||||
"blockies": "0.0.2",
|
||||
@ -234,7 +208,6 @@
|
||||
"web3": "0.17.0-beta",
|
||||
"whatwg-fetch": "2.0.1",
|
||||
"worker-loader": "^0.8.0",
|
||||
"yarn": "^0.21.3",
|
||||
"zxcvbn": "4.4.1"
|
||||
}
|
||||
}
|
||||
|
53
js-old/scripts/push-precompiled.sh
Executable file
53
js-old/scripts/push-precompiled.sh
Executable file
@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# variables
|
||||
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
|
||||
PRECOMPILED_BRANCH="v1"
|
||||
GIT_JS_PRECOMPILED="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/js-precompiled.git"
|
||||
BASEDIR=`dirname $0`
|
||||
GITLOG=./.git/.git-release.log
|
||||
|
||||
# setup the git user defaults for the current repo
|
||||
function setup_git_user {
|
||||
git config push.default simple
|
||||
git config merge.ours.driver true
|
||||
git config user.email "$GITHUB_EMAIL"
|
||||
git config user.name "GitLab Build Bot"
|
||||
}
|
||||
|
||||
# change into the build directory
|
||||
pushd $BASEDIR
|
||||
cd ../.dist
|
||||
|
||||
# add local files and send it up
|
||||
echo "*** [v1 precompiled] Setting up GitHub config for js-precompiled"
|
||||
rm -rf ./.git
|
||||
git init
|
||||
setup_git_user
|
||||
|
||||
echo "*** [v1 precompiled] Checking out $PRECOMPILED_BRANCH branch"
|
||||
git remote add origin $GIT_JS_PRECOMPILED
|
||||
git fetch origin 2>$GITLOG
|
||||
git checkout -b $PRECOMPILED_BRANCH
|
||||
|
||||
echo "*** [v1 precompiled] Committing compiled files for $UTCDATE"
|
||||
mv build ../build.new
|
||||
git add .
|
||||
git commit -m "$UTCDATE [update]"
|
||||
git merge origin/$PRECOMPILED_BRANCH -X ours --commit -m "$UTCDATE [merge]"
|
||||
git rm -r build
|
||||
rm -rf build
|
||||
git commit -m "$UTCDATE [cleanup]"
|
||||
mv ../build.new build
|
||||
git add .
|
||||
git commit -m "$UTCDATE [release]"
|
||||
|
||||
echo "*** [v1 precompiled] Merging remote"
|
||||
git push origin HEAD:refs/heads/$PRECOMPILED_BRANCH 2>$GITLOG
|
||||
|
||||
# move to root
|
||||
popd
|
||||
|
||||
# exit with exit code
|
||||
exit 0
|
@ -1,79 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# variables
|
||||
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
|
||||
PACKAGES=( "parity" "etherscan" "shapeshift" "jsonrpc" )
|
||||
BRANCH="v1"
|
||||
GIT_JS_PRECOMPILED="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/js-precompiled.git"
|
||||
GIT_PARITY="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/parity.git"
|
||||
|
||||
# setup the git user defaults for the current repo
|
||||
function setup_git_user {
|
||||
git config push.default simple
|
||||
git config merge.ours.driver true
|
||||
git config user.email "$GITHUB_EMAIL"
|
||||
git config user.name "GitLab Build Bot"
|
||||
}
|
||||
|
||||
# change into the build directory
|
||||
BASEDIR=`dirname $0`
|
||||
GITLOG=./.git/gitcommand.log
|
||||
pushd $BASEDIR
|
||||
cd ../.dist
|
||||
|
||||
# add local files and send it up
|
||||
echo "*** Setting up GitHub config for js-precompiled"
|
||||
rm -rf ./.git
|
||||
git init
|
||||
setup_git_user
|
||||
|
||||
echo "*** Checking out $BRANCH branch"
|
||||
git remote add origin $GIT_JS_PRECOMPILED
|
||||
git fetch origin 2>$GITLOG
|
||||
git checkout -b $BRANCH
|
||||
|
||||
echo "*** Committing compiled files for $UTCDATE"
|
||||
mv build ../build.new
|
||||
git add .
|
||||
git commit -m "$UTCDATE [update]"
|
||||
git merge origin/$BRANCH -X ours --commit -m "$UTCDATE [merge]"
|
||||
git rm -r build
|
||||
rm -rf build
|
||||
git commit -m "$UTCDATE [cleanup]"
|
||||
mv ../build.new build
|
||||
git add .
|
||||
git commit -m "$UTCDATE [release]"
|
||||
|
||||
echo "*** Merging remote"
|
||||
git push origin HEAD:refs/heads/$BRANCH 2>$GITLOG
|
||||
PRECOMPILED_HASH=`git rev-parse HEAD`
|
||||
|
||||
# move to root
|
||||
cd ../..
|
||||
|
||||
echo "*** Setting up GitHub config for parity"
|
||||
setup_git_user
|
||||
git remote set-url origin $GIT_PARITY
|
||||
git reset --hard origin/$BRANCH 2>$GITLOG
|
||||
|
||||
echo "*** Updating cargo parity-ui-old-precompiled#$PRECOMPILED_HASH"
|
||||
git submodule update
|
||||
# Not needed since $BRANCH is hardcoded
|
||||
# sed -i "/^parity-ui-old-precompiled/ { s/branch = \".*\"/branch = \"$BRANCH\"/g; }" dapps/ui/Cargo.toml
|
||||
cargo update -p parity-ui-old-precompiled
|
||||
# --precise "$PRECOMPILED_HASH"
|
||||
|
||||
echo "*** Committing updated files"
|
||||
git add js
|
||||
git add dapps/ui/Cargo.toml
|
||||
git add Cargo.lock
|
||||
git commit -m "[ci skip] js-precompiled $UTCDATE"
|
||||
git push origin HEAD:refs/heads/$BRANCH 2>$GITLOG
|
||||
|
||||
# back to root
|
||||
echo "*** Release completed"
|
||||
popd
|
||||
|
||||
# exit with exit code
|
||||
exit 0
|
@ -1 +1 @@
|
||||
// test script 10
|
||||
// test script 14
|
||||
|
@ -33,6 +33,7 @@
|
||||
<div id="container">
|
||||
<div class="loading">Loading</div>
|
||||
</div>
|
||||
<script src="/parity-utils/inject.js"></script>
|
||||
<script src="vendor.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -25,9 +25,9 @@ import { AppContainer } from 'react-hot-loader';
|
||||
|
||||
import injectTapEventPlugin from 'react-tap-event-plugin';
|
||||
import { hashHistory } from 'react-router';
|
||||
import qs from 'querystring';
|
||||
|
||||
import SecureApi from './secureApi';
|
||||
import Api from '@parity/api';
|
||||
|
||||
import ContractInstances from '~/contracts';
|
||||
|
||||
import { initStore } from './redux';
|
||||
@ -45,23 +45,7 @@ import '../assets/fonts/RobotoMono/font.css';
|
||||
|
||||
injectTapEventPlugin();
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// Expose the React Performance Tools on the`window` object
|
||||
const Perf = require('react-addons-perf');
|
||||
|
||||
window.Perf = Perf;
|
||||
}
|
||||
|
||||
const AUTH_HASH = '#/auth?';
|
||||
|
||||
let token = null;
|
||||
|
||||
if (window.location.hash && window.location.hash.indexOf(AUTH_HASH) === 0) {
|
||||
token = qs.parse(window.location.hash.substr(AUTH_HASH.length)).token;
|
||||
}
|
||||
|
||||
const uiUrl = window.location.host;
|
||||
const api = new SecureApi(uiUrl, token);
|
||||
const api = new Api(window.ethereum);
|
||||
|
||||
patchApi(api);
|
||||
loadSender(api);
|
||||
@ -72,8 +56,6 @@ const store = initStore(api, hashHistory);
|
||||
store.dispatch({ type: 'initAll', api });
|
||||
store.dispatch(setApi(api));
|
||||
|
||||
window.secureApi = api;
|
||||
|
||||
ReactDOM.render(
|
||||
<AppContainer>
|
||||
<ContextProvider api={ api } muiTheme={ muiTheme } store={ store }>
|
||||
|
@ -40,10 +40,10 @@ impl WebApp for App {
|
||||
|
||||
fn info(&self) -> Info {
|
||||
Info {
|
||||
name: "Parity Wallet v1",
|
||||
name: "Parity Wallet",
|
||||
version: env!("CARGO_PKG_VERSION"),
|
||||
author: "Parity <admin@parity.io>",
|
||||
description: "Deprecated version of Parity Wallet.",
|
||||
description: "Parity Wallet and Account management tools",
|
||||
icon_url: "icon.png",
|
||||
}
|
||||
}
|
||||
|
7
js-old/src/manifest.json
Normal file
7
js-old/src/manifest.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "Parity Wallet",
|
||||
"version": "development",
|
||||
"author": "Parity <admin@parity.io>",
|
||||
"description": "Parity Wallet and Account management tools",
|
||||
"icon_url": "icon.png",
|
||||
}
|
@ -17,35 +17,35 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { walletSourceURL } from '~/contracts/code/wallet';
|
||||
// import { walletSourceURL } from '~/contracts/code/wallet';
|
||||
import { RadioButtons } from '~/ui';
|
||||
|
||||
const TYPES = [
|
||||
{
|
||||
label: (
|
||||
<FormattedMessage
|
||||
id='createWallet.type.multisig.label'
|
||||
defaultMessage='Multi-Sig wallet'
|
||||
/>
|
||||
),
|
||||
key: 'MULTISIG',
|
||||
description: (
|
||||
<FormattedMessage
|
||||
id='createWallet.type.multisig.description'
|
||||
defaultMessage='Create/Deploy a {link} Wallet'
|
||||
values={ {
|
||||
link: (
|
||||
<a href={ walletSourceURL } target='_blank'>
|
||||
<FormattedMessage
|
||||
id='createWallet.type.multisig.link'
|
||||
defaultMessage='standard multi-signature'
|
||||
/>
|
||||
</a>
|
||||
)
|
||||
} }
|
||||
/>
|
||||
)
|
||||
},
|
||||
// {
|
||||
// label: (
|
||||
// <FormattedMessage
|
||||
// id='createWallet.type.multisig.label'
|
||||
// defaultMessage='Multi-Sig wallet'
|
||||
// />
|
||||
// ),
|
||||
// key: 'MULTISIG',
|
||||
// description: (
|
||||
// <FormattedMessage
|
||||
// id='createWallet.type.multisig.description'
|
||||
// defaultMessage='Create/Deploy a {link} Wallet'
|
||||
// values={ {
|
||||
// link: (
|
||||
// <a href={ walletSourceURL } target='_blank'>
|
||||
// <FormattedMessage
|
||||
// id='createWallet.type.multisig.link'
|
||||
// defaultMessage='standard multi-signature'
|
||||
// />
|
||||
// </a>
|
||||
// )
|
||||
// } }
|
||||
// />
|
||||
// )
|
||||
// },
|
||||
{
|
||||
label: (
|
||||
<FormattedMessage
|
||||
@ -57,7 +57,7 @@ const TYPES = [
|
||||
description: (
|
||||
<FormattedMessage
|
||||
id='createWallet.type.watch.description'
|
||||
defaultMessage='Add an existing wallet to your accounts'
|
||||
defaultMessage='Add an existing multisig wallet to your accounts'
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ const STEPS = {
|
||||
export default class CreateWalletStore {
|
||||
@observable step = null;
|
||||
@observable txhash = null;
|
||||
@observable walletType = 'MULTISIG';
|
||||
@observable walletType = 'WATCH'; // 'MULTISIG';
|
||||
|
||||
@observable wallet = {
|
||||
account: '',
|
||||
|
@ -133,8 +133,8 @@ export default class TransferStore {
|
||||
}
|
||||
|
||||
@action handleClose = () => {
|
||||
this.stage = 0;
|
||||
this.onClose();
|
||||
this.stage = 0;
|
||||
}
|
||||
|
||||
@action onUpdateDetails = (type, value) => {
|
||||
@ -169,7 +169,6 @@ export default class TransferStore {
|
||||
}
|
||||
|
||||
@action onSend = () => {
|
||||
this.onNext();
|
||||
this.sending = true;
|
||||
|
||||
this
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import { handleActions } from 'redux-actions';
|
||||
|
||||
const initialState = {};
|
||||
const initialState = null;
|
||||
|
||||
export default handleActions({
|
||||
setApi (state, action) {
|
||||
|
@ -16,12 +16,11 @@
|
||||
|
||||
import { throttle } from 'lodash';
|
||||
|
||||
import { fetchBalances, fetchTokensBalances, queryTokensFilter } from './balancesActions';
|
||||
import { loadTokens, fetchTokens } from './tokensActions';
|
||||
import { padRight } from '~/api/util/format';
|
||||
import { LOG_KEYS, getLogger } from '~/config';
|
||||
|
||||
import Contracts from '~/contracts';
|
||||
import { fetchBalances, queryTokensFilter, updateTokensFilter } from './balancesActions';
|
||||
|
||||
const log = getLogger(LOG_KEYS.Balances);
|
||||
let instance = null;
|
||||
|
||||
export default class Balances {
|
||||
@ -29,40 +28,20 @@ export default class Balances {
|
||||
this._api = api;
|
||||
this._store = store;
|
||||
|
||||
this._tokenreg = null;
|
||||
this._tokenregSID = null;
|
||||
this._tokenMetaSID = null;
|
||||
this._apiSubs = [];
|
||||
|
||||
this._blockNumberSID = null;
|
||||
this._accountsInfoSID = null;
|
||||
|
||||
// Throtthled load tokens (no more than once
|
||||
// every minute)
|
||||
this.loadTokens = throttle(
|
||||
this._loadTokens,
|
||||
60 * 1000,
|
||||
{ leading: true, trailing: true }
|
||||
);
|
||||
|
||||
// Throttled `_fetchBalances` function
|
||||
// Throttled `_fetchEthBalances` function
|
||||
// that gets called max once every 40s
|
||||
this.longThrottledFetch = throttle(
|
||||
this._fetchBalances,
|
||||
this._fetchEthBalances,
|
||||
40 * 1000,
|
||||
{ leading: false, trailing: true }
|
||||
{ leading: true, trailing: false }
|
||||
);
|
||||
|
||||
this.shortThrottledFetch = throttle(
|
||||
this._fetchBalances,
|
||||
this._fetchEthBalances,
|
||||
2 * 1000,
|
||||
{ leading: false, trailing: true }
|
||||
);
|
||||
|
||||
// Fetch all tokens every 2 minutes
|
||||
this.throttledTokensFetch = throttle(
|
||||
this._fetchTokens,
|
||||
2 * 60 * 1000,
|
||||
{ leading: false, trailing: true }
|
||||
{ leading: true, trailing: false }
|
||||
);
|
||||
|
||||
// Unsubscribe previous instance if it exists
|
||||
@ -71,17 +50,19 @@ export default class Balances {
|
||||
}
|
||||
}
|
||||
|
||||
static get (store = {}) {
|
||||
static get (store) {
|
||||
if (!instance && store) {
|
||||
const { api } = store.getState();
|
||||
|
||||
return Balances.instantiate(store, api);
|
||||
return Balances.init(store);
|
||||
} else if (!instance) {
|
||||
throw new Error('The Balances Provider has not been initialized yet');
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
static instantiate (store, api) {
|
||||
static init (store) {
|
||||
const { api } = store.getState();
|
||||
|
||||
if (!instance) {
|
||||
instance = new Balances(store, api);
|
||||
}
|
||||
@ -91,15 +72,13 @@ export default class Balances {
|
||||
|
||||
static start () {
|
||||
if (!instance) {
|
||||
return Promise.reject('BalancesProvider has not been intiated yet');
|
||||
return Promise.reject('BalancesProvider has not been initiated yet');
|
||||
}
|
||||
|
||||
const self = instance;
|
||||
|
||||
// Unsubscribe from previous subscriptions
|
||||
return Balances
|
||||
.stop()
|
||||
.then(() => self.loadTokens())
|
||||
return Balances.stop()
|
||||
.then(() => {
|
||||
const promises = [
|
||||
self.subscribeBlockNumber(),
|
||||
@ -107,7 +86,8 @@ export default class Balances {
|
||||
];
|
||||
|
||||
return Promise.all(promises);
|
||||
});
|
||||
})
|
||||
.then(() => self.fetchEthBalances());
|
||||
}
|
||||
|
||||
static stop () {
|
||||
@ -116,71 +96,35 @@ export default class Balances {
|
||||
}
|
||||
|
||||
const self = instance;
|
||||
const promises = [];
|
||||
const promises = self._apiSubs.map((subId) => self._api.unsubscribe(subId));
|
||||
|
||||
if (self._blockNumberSID) {
|
||||
const p = self._api
|
||||
.unsubscribe(self._blockNumberSID)
|
||||
.then(() => {
|
||||
self._blockNumberSID = null;
|
||||
});
|
||||
|
||||
promises.push(p);
|
||||
}
|
||||
|
||||
if (self._accountsInfoSID) {
|
||||
const p = self._api
|
||||
.unsubscribe(self._accountsInfoSID)
|
||||
.then(() => {
|
||||
self._accountsInfoSID = null;
|
||||
});
|
||||
|
||||
promises.push(p);
|
||||
}
|
||||
|
||||
// Unsubscribe without adding the promises
|
||||
// to the result, since it would have to wait for a
|
||||
// reconnection to resolve if the Node is disconnected
|
||||
if (self._tokenreg) {
|
||||
if (self._tokenregSID) {
|
||||
const tokenregSID = self._tokenregSID;
|
||||
|
||||
self._tokenreg
|
||||
.unsubscribe(tokenregSID)
|
||||
.then(() => {
|
||||
if (self._tokenregSID === tokenregSID) {
|
||||
self._tokenregSID = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (self._tokenMetaSID) {
|
||||
const tokenMetaSID = self._tokenMetaSID;
|
||||
|
||||
self._tokenreg
|
||||
.unsubscribe(tokenMetaSID)
|
||||
.then(() => {
|
||||
if (self._tokenMetaSID === tokenMetaSID) {
|
||||
self._tokenMetaSID = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
return Promise.all(promises)
|
||||
.then(() => {
|
||||
self._apiSubs = [];
|
||||
});
|
||||
}
|
||||
|
||||
subscribeAccountsInfo () {
|
||||
// Don't trigger the balances updates on first call (when the
|
||||
// subscriptions are setup)
|
||||
let firstcall = true;
|
||||
|
||||
return this._api
|
||||
.subscribe('parity_allAccountsInfo', (error, accountsInfo) => {
|
||||
if (error) {
|
||||
return console.warn('balances::subscribeAccountsInfo', error);
|
||||
}
|
||||
|
||||
if (firstcall) {
|
||||
firstcall = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.fetchAllBalances();
|
||||
this._store.dispatch(updateTokensFilter());
|
||||
this.fetchEthBalances();
|
||||
})
|
||||
.then((accountsInfoSID) => {
|
||||
this._accountsInfoSID = accountsInfoSID;
|
||||
.then((subId) => {
|
||||
this._apiSubs.push(subId);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('_subscribeAccountsInfo', error);
|
||||
@ -188,161 +132,57 @@ export default class Balances {
|
||||
}
|
||||
|
||||
subscribeBlockNumber () {
|
||||
// Don't trigger the balances updates on first call (when the
|
||||
// subscriptions are setup)
|
||||
let firstcall = true;
|
||||
|
||||
return this._api
|
||||
.subscribe('eth_blockNumber', (error) => {
|
||||
.subscribe('eth_blockNumber', (error, block) => {
|
||||
if (error) {
|
||||
return console.warn('_subscribeBlockNumber', error);
|
||||
return console.warn('balances::subscribeBlockNumber', error);
|
||||
}
|
||||
|
||||
if (firstcall) {
|
||||
firstcall = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this._store.dispatch(queryTokensFilter());
|
||||
return this.fetchAllBalances();
|
||||
return this.fetchEthBalances();
|
||||
})
|
||||
.then((blockNumberSID) => {
|
||||
this._blockNumberSID = blockNumberSID;
|
||||
.then((subId) => {
|
||||
this._apiSubs.push(subId);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('_subscribeBlockNumber', error);
|
||||
});
|
||||
}
|
||||
|
||||
fetchAllBalances (options = {}) {
|
||||
// If it's a network change, reload the tokens
|
||||
// ( and then fetch the tokens balances ) and fetch
|
||||
// the accounts balances
|
||||
if (options.changedNetwork) {
|
||||
this.loadTokens({ skipNotifications: true });
|
||||
this.loadTokens.flush();
|
||||
fetchEthBalances (options = {}) {
|
||||
log.debug('fetching eth balances (throttled)...');
|
||||
|
||||
this.fetchBalances({
|
||||
force: true,
|
||||
skipNotifications: true
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.fetchTokensBalances(options);
|
||||
this.fetchBalances(options);
|
||||
}
|
||||
|
||||
fetchTokensBalances (options) {
|
||||
const { skipNotifications = false, force = false } = options;
|
||||
|
||||
this.throttledTokensFetch(skipNotifications);
|
||||
|
||||
if (force) {
|
||||
this.throttledTokensFetch.flush();
|
||||
}
|
||||
}
|
||||
|
||||
fetchBalances (options) {
|
||||
const { skipNotifications = false, force = false } = options;
|
||||
const { syncing } = this._store.getState().nodeStatus;
|
||||
|
||||
if (options.force) {
|
||||
return this._fetchEthBalances();
|
||||
}
|
||||
|
||||
// If syncing, only retrieve balances once every
|
||||
// few seconds
|
||||
if (syncing || syncing === null) {
|
||||
this.shortThrottledFetch.cancel();
|
||||
this.longThrottledFetch(skipNotifications);
|
||||
|
||||
if (force) {
|
||||
this.longThrottledFetch.flush();
|
||||
}
|
||||
|
||||
return;
|
||||
return this.longThrottledFetch();
|
||||
}
|
||||
|
||||
this.longThrottledFetch.cancel();
|
||||
this.shortThrottledFetch(skipNotifications);
|
||||
|
||||
if (force) {
|
||||
this.shortThrottledFetch.flush();
|
||||
}
|
||||
return this.shortThrottledFetch();
|
||||
}
|
||||
|
||||
_fetchBalances (skipNotifications = false) {
|
||||
this._store.dispatch(fetchBalances(null, skipNotifications));
|
||||
}
|
||||
_fetchEthBalances (skipNotifications = false) {
|
||||
log.debug('fetching eth balances (real)...');
|
||||
|
||||
_fetchTokens (skipNotifications = false) {
|
||||
this._store.dispatch(fetchTokensBalances(null, null, skipNotifications));
|
||||
}
|
||||
const { dispatch, getState } = this._store;
|
||||
|
||||
getTokenRegistry () {
|
||||
return Contracts.get().tokenReg.getContract();
|
||||
}
|
||||
|
||||
_loadTokens (options = {}) {
|
||||
return this
|
||||
.getTokenRegistry()
|
||||
.then((tokenreg) => {
|
||||
this._tokenreg = tokenreg;
|
||||
|
||||
this._store.dispatch(loadTokens(options));
|
||||
|
||||
return this.attachToTokens(tokenreg);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('balances::loadTokens', error);
|
||||
});
|
||||
}
|
||||
|
||||
attachToTokens (tokenreg) {
|
||||
return Promise
|
||||
.all([
|
||||
this.attachToTokenMetaChange(tokenreg),
|
||||
this.attachToNewToken(tokenreg)
|
||||
]);
|
||||
}
|
||||
|
||||
attachToNewToken (tokenreg) {
|
||||
if (this._tokenregSID) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return tokenreg.instance.Registered
|
||||
.subscribe({
|
||||
fromBlock: 0,
|
||||
toBlock: 'latest',
|
||||
skipInitFetch: true
|
||||
}, (error, logs) => {
|
||||
if (error) {
|
||||
return console.error('balances::attachToNewToken', 'failed to attach to tokenreg Registered', error.toString(), error.stack);
|
||||
}
|
||||
|
||||
this.handleTokensLogs(logs);
|
||||
})
|
||||
.then((tokenregSID) => {
|
||||
this._tokenregSID = tokenregSID;
|
||||
});
|
||||
}
|
||||
|
||||
attachToTokenMetaChange (tokenreg) {
|
||||
if (this._tokenMetaSID) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return tokenreg.instance.MetaChanged
|
||||
.subscribe({
|
||||
fromBlock: 0,
|
||||
toBlock: 'latest',
|
||||
topics: [ null, padRight(this._api.util.asciiToHex('IMG'), 32) ],
|
||||
skipInitFetch: true
|
||||
}, (error, logs) => {
|
||||
if (error) {
|
||||
return console.error('balances::attachToTokenMetaChange', 'failed to attach to tokenreg MetaChanged', error.toString(), error.stack);
|
||||
}
|
||||
|
||||
this.handleTokensLogs(logs);
|
||||
})
|
||||
.then((tokenMetaSID) => {
|
||||
this._tokenMetaSID = tokenMetaSID;
|
||||
});
|
||||
}
|
||||
|
||||
handleTokensLogs (logs) {
|
||||
const tokenIds = logs.map((log) => log.params.id.value.toNumber());
|
||||
|
||||
this._store.dispatch(fetchTokens(tokenIds));
|
||||
return fetchBalances(null, skipNotifications)(dispatch, getState);
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { uniq, isEqual } from 'lodash';
|
||||
import { difference, uniq } from 'lodash';
|
||||
import { push } from 'react-router-redux';
|
||||
|
||||
import { notifyTransaction } from '~/util/notifications';
|
||||
@ -22,11 +22,16 @@ import { ETH_TOKEN, fetchAccountsBalances } from '~/util/tokens';
|
||||
import { LOG_KEYS, getLogger } from '~/config';
|
||||
import { sha3 } from '~/api/util/sha3';
|
||||
|
||||
import { fetchTokens } from './tokensActions';
|
||||
|
||||
const TRANSFER_SIGNATURE = sha3('Transfer(address,address,uint256)');
|
||||
|
||||
const log = getLogger(LOG_KEYS.Balances);
|
||||
|
||||
let tokensFilter = {};
|
||||
let tokensFilter = {
|
||||
tokenAddresses: [],
|
||||
addresses: []
|
||||
};
|
||||
|
||||
function _setBalances (balances) {
|
||||
return {
|
||||
@ -63,13 +68,10 @@ function setBalances (updates, skipNotifications = false) {
|
||||
dispatch(notifyBalanceChange(who, prevTokenValue, nextTokenValue, token));
|
||||
}
|
||||
|
||||
// Add the token if it's native ETH or if it has a value
|
||||
if (token.native || nextTokenValue.gt(0)) {
|
||||
nextBalances[who] = {
|
||||
...(nextBalances[who] || {}),
|
||||
[tokenId]: nextTokenValue
|
||||
};
|
||||
}
|
||||
nextBalances[who] = {
|
||||
...(nextBalances[who] || {}),
|
||||
[tokenId]: nextTokenValue
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
@ -100,41 +102,92 @@ function notifyBalanceChange (who, fromValue, toValue, token) {
|
||||
}
|
||||
|
||||
// TODO: fetch txCount when needed
|
||||
export function fetchBalances (_addresses, skipNotifications = false) {
|
||||
return fetchTokensBalances(_addresses, [ ETH_TOKEN ], skipNotifications);
|
||||
export function fetchBalances (addresses, skipNotifications = false) {
|
||||
return (dispatch, getState) => {
|
||||
const { personal } = getState();
|
||||
const { visibleAccounts, accounts } = personal;
|
||||
|
||||
const addressesToFetch = addresses || uniq(visibleAccounts.concat(Object.keys(accounts)));
|
||||
const updates = addressesToFetch.reduce((updates, who) => {
|
||||
updates[who] = [ ETH_TOKEN.id ];
|
||||
|
||||
return updates;
|
||||
}, {});
|
||||
|
||||
return fetchTokensBalances(updates, skipNotifications)(dispatch, getState);
|
||||
};
|
||||
}
|
||||
|
||||
export function updateTokensFilter (_addresses, _tokens, options = {}) {
|
||||
export function updateTokensFilter (options = {}) {
|
||||
return (dispatch, getState) => {
|
||||
const { api, personal, tokens } = getState();
|
||||
const { visibleAccounts, accounts } = personal;
|
||||
|
||||
const addressesToFetch = uniq(visibleAccounts.concat(Object.keys(accounts)));
|
||||
const addresses = uniq(_addresses || addressesToFetch || []).sort();
|
||||
const addresses = uniq(visibleAccounts.concat(Object.keys(accounts)));
|
||||
const tokensToUpdate = Object.values(tokens);
|
||||
const tokensAddressMap = Object.values(tokens).reduce((map, token) => {
|
||||
map[token.address] = token;
|
||||
return map;
|
||||
}, {});
|
||||
|
||||
const tokensToUpdate = _tokens || Object.values(tokens);
|
||||
const tokenAddresses = tokensToUpdate
|
||||
.map((t) => t.address)
|
||||
.filter((address) => address)
|
||||
.sort();
|
||||
.filter((address) => address && !/^(0x)?0*$/.test(address));
|
||||
|
||||
// Token Addresses that are not in the current filter
|
||||
const newTokenAddresses = difference(tokenAddresses, tokensFilter.tokenAddresses);
|
||||
|
||||
// Addresses that are not in the current filter (omit those
|
||||
// that the filter includes)
|
||||
const newAddresses = difference(addresses, tokensFilter.addresses);
|
||||
|
||||
if (tokensFilter.filterFromId || tokensFilter.filterToId) {
|
||||
// Has the tokens addresses changed (eg. a network change)
|
||||
const sameTokens = isEqual(tokenAddresses, tokensFilter.tokenAddresses);
|
||||
|
||||
// Addresses that are not in the current filter (omit those
|
||||
// that the filter includes)
|
||||
const newAddresses = addresses.filter((address) => !tokensFilter.addresses.includes(address));
|
||||
|
||||
// If no new addresses and the same tokens, don't change the filter
|
||||
if (sameTokens && newAddresses.length === 0) {
|
||||
if (newTokenAddresses.length === 0 && newAddresses.length === 0) {
|
||||
log.debug('no need to update token filter', addresses, tokenAddresses, tokensFilter);
|
||||
return queryTokensFilter(tokensFilter)(dispatch, getState);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
log.debug('updating the token filter', addresses, tokenAddresses);
|
||||
const promises = [];
|
||||
const updates = {};
|
||||
|
||||
const allTokenIds = tokensToUpdate.map((token) => token.id);
|
||||
const newTokenIds = newTokenAddresses.map((address) => tokensAddressMap[address].id);
|
||||
|
||||
newAddresses.forEach((newAddress) => {
|
||||
updates[newAddress] = allTokenIds;
|
||||
});
|
||||
|
||||
difference(addresses, newAddresses).forEach((oldAddress) => {
|
||||
updates[oldAddress] = newTokenIds;
|
||||
});
|
||||
|
||||
log.debug('updating the token filter', addresses, tokenAddresses);
|
||||
|
||||
const topicsFrom = [ TRANSFER_SIGNATURE, addresses, null ];
|
||||
const topicsTo = [ TRANSFER_SIGNATURE, null, addresses ];
|
||||
|
||||
const filterOptions = {
|
||||
fromBlock: 'latest',
|
||||
toBlock: 'latest',
|
||||
address: tokenAddresses
|
||||
};
|
||||
|
||||
const optionsFrom = {
|
||||
...filterOptions,
|
||||
topics: topicsFrom
|
||||
};
|
||||
|
||||
const optionsTo = {
|
||||
...filterOptions,
|
||||
topics: topicsTo
|
||||
};
|
||||
|
||||
promises.push(
|
||||
api.eth.newFilter(optionsFrom),
|
||||
api.eth.newFilter(optionsTo)
|
||||
);
|
||||
|
||||
if (tokensFilter.filterFromId) {
|
||||
promises.push(api.eth.uninstallFilter(tokensFilter.filterFromId));
|
||||
@ -144,48 +197,16 @@ export function updateTokensFilter (_addresses, _tokens, options = {}) {
|
||||
promises.push(api.eth.uninstallFilter(tokensFilter.filterToId));
|
||||
}
|
||||
|
||||
Promise
|
||||
.all([
|
||||
api.eth.blockNumber()
|
||||
].concat(promises))
|
||||
.then(([ block ]) => {
|
||||
const topicsFrom = [ TRANSFER_SIGNATURE, addresses, null ];
|
||||
const topicsTo = [ TRANSFER_SIGNATURE, null, addresses ];
|
||||
|
||||
const filterOptions = {
|
||||
fromBlock: block,
|
||||
toBlock: 'pending',
|
||||
address: tokenAddresses
|
||||
};
|
||||
|
||||
const optionsFrom = {
|
||||
...filterOptions,
|
||||
topics: topicsFrom
|
||||
};
|
||||
|
||||
const optionsTo = {
|
||||
...filterOptions,
|
||||
topics: topicsTo
|
||||
};
|
||||
|
||||
const newFilters = Promise.all([
|
||||
api.eth.newFilter(optionsFrom),
|
||||
api.eth.newFilter(optionsTo)
|
||||
]);
|
||||
|
||||
return newFilters;
|
||||
})
|
||||
return Promise.all(promises)
|
||||
.then(([ filterFromId, filterToId ]) => {
|
||||
const nextTokensFilter = {
|
||||
filterFromId, filterToId,
|
||||
addresses, tokenAddresses
|
||||
};
|
||||
|
||||
const { skipNotifications } = options;
|
||||
|
||||
tokensFilter = nextTokensFilter;
|
||||
fetchTokensBalances(addresses, tokensToUpdate, skipNotifications)(dispatch, getState);
|
||||
})
|
||||
.then(() => fetchTokensBalances(updates)(dispatch, getState))
|
||||
.catch((error) => {
|
||||
console.warn('balances::updateTokensFilter', error);
|
||||
});
|
||||
@ -194,12 +215,7 @@ export function updateTokensFilter (_addresses, _tokens, options = {}) {
|
||||
|
||||
export function queryTokensFilter () {
|
||||
return (dispatch, getState) => {
|
||||
const { api, personal, tokens } = getState();
|
||||
const { visibleAccounts, accounts } = personal;
|
||||
|
||||
const allAddresses = visibleAccounts.concat(Object.keys(accounts));
|
||||
const addressesToFetch = uniq(allAddresses);
|
||||
const lcAddresses = addressesToFetch.map((a) => a.toLowerCase());
|
||||
const { api } = getState();
|
||||
|
||||
Promise
|
||||
.all([
|
||||
@ -207,67 +223,107 @@ export function queryTokensFilter () {
|
||||
api.eth.getFilterChanges(tokensFilter.filterToId)
|
||||
])
|
||||
.then(([ logsFrom, logsTo ]) => {
|
||||
const addresses = [];
|
||||
const tokenAddresses = [];
|
||||
const logs = logsFrom.concat(logsTo);
|
||||
const logs = [].concat(logsFrom, logsTo);
|
||||
|
||||
if (logs.length > 0) {
|
||||
if (logs.length === 0) {
|
||||
return;
|
||||
} else {
|
||||
log.debug('got tokens filter logs', logs);
|
||||
}
|
||||
|
||||
const { personal, tokens } = getState();
|
||||
const { visibleAccounts, accounts } = personal;
|
||||
|
||||
const addressesToFetch = uniq(visibleAccounts.concat(Object.keys(accounts)));
|
||||
const lcAddresses = addressesToFetch.map((a) => a.toLowerCase());
|
||||
|
||||
const lcTokensMap = Object.values(tokens).reduce((map, token) => {
|
||||
map[token.address.toLowerCase()] = token;
|
||||
return map;
|
||||
});
|
||||
|
||||
// The keys are the account addresses,
|
||||
// and the value is an Array of the tokens addresses
|
||||
// to update
|
||||
const updates = {};
|
||||
|
||||
logs
|
||||
.forEach((log) => {
|
||||
const tokenAddress = log.address;
|
||||
.forEach((log, index) => {
|
||||
const tokenAddress = log.address.toLowerCase();
|
||||
const token = lcTokensMap[tokenAddress];
|
||||
|
||||
const fromAddress = '0x' + log.topics[1].slice(-40);
|
||||
const toAddress = '0x' + log.topics[2].slice(-40);
|
||||
// logs = [ ...logsFrom, ...logsTo ]
|
||||
const topicIdx = index < logsFrom.length ? 1 : 2;
|
||||
const address = ('0x' + log.topics[topicIdx].slice(-40)).toLowerCase();
|
||||
const addressIndex = lcAddresses.indexOf(address);
|
||||
|
||||
const fromAddressIndex = lcAddresses.indexOf(fromAddress);
|
||||
const toAddressIndex = lcAddresses.indexOf(toAddress);
|
||||
if (addressIndex > -1) {
|
||||
const who = addressesToFetch[addressIndex];
|
||||
|
||||
if (fromAddressIndex > -1) {
|
||||
addresses.push(addressesToFetch[fromAddressIndex]);
|
||||
updates[who] = [].concat(updates[who] || [], token.id);
|
||||
}
|
||||
|
||||
if (toAddressIndex > -1) {
|
||||
addresses.push(addressesToFetch[toAddressIndex]);
|
||||
}
|
||||
|
||||
tokenAddresses.push(tokenAddress);
|
||||
});
|
||||
|
||||
if (addresses.length === 0) {
|
||||
// No accounts to update
|
||||
if (Object.keys(updates).length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tokensToUpdate = Object.values(tokens)
|
||||
.filter((t) => tokenAddresses.includes(t.address));
|
||||
Object.keys(updates).forEach((who) => {
|
||||
// Keep non-empty token addresses
|
||||
updates[who] = uniq(updates[who]);
|
||||
});
|
||||
|
||||
fetchTokensBalances(uniq(addresses), tokensToUpdate)(dispatch, getState);
|
||||
fetchTokensBalances(updates)(dispatch, getState);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchTokensBalances (_addresses = null, _tokens = null, skipNotifications = false) {
|
||||
export function fetchTokensBalances (updates, skipNotifications = false) {
|
||||
return (dispatch, getState) => {
|
||||
const { api, personal, tokens } = getState();
|
||||
const { visibleAccounts, accounts } = personal;
|
||||
const allTokens = Object.values(tokens);
|
||||
|
||||
const addressesToFetch = uniq(visibleAccounts.concat(Object.keys(accounts)));
|
||||
const addresses = _addresses || addressesToFetch;
|
||||
const tokensToUpdate = _tokens || allTokens;
|
||||
if (!updates) {
|
||||
const { visibleAccounts, accounts } = personal;
|
||||
const addressesToFetch = uniq(visibleAccounts.concat(Object.keys(accounts)));
|
||||
|
||||
if (addresses.length === 0) {
|
||||
return Promise.resolve();
|
||||
updates = addressesToFetch.reduce((updates, who) => {
|
||||
updates[who] = allTokens.map((token) => token.id);
|
||||
|
||||
return updates;
|
||||
}, {});
|
||||
}
|
||||
|
||||
const updates = addresses.reduce((updates, who) => {
|
||||
updates[who] = tokensToUpdate.map((token) => token.id);
|
||||
return updates;
|
||||
}, {});
|
||||
let start = Date.now();
|
||||
|
||||
return fetchAccountsBalances(api, allTokens, updates)
|
||||
.then((balances) => {
|
||||
log.debug('got tokens balances', balances, updates, `(took ${Date.now() - start}ms)`);
|
||||
|
||||
// Tokens info might not be fetched yet (to not load
|
||||
// tokens we don't care about)
|
||||
const tokenIdsToFetch = Object.values(balances)
|
||||
.reduce((tokenIds, balance) => {
|
||||
const nextTokenIds = Object.keys(balance)
|
||||
.filter((tokenId) => balance[tokenId].gt(0));
|
||||
|
||||
return tokenIds.concat(nextTokenIds);
|
||||
}, []);
|
||||
|
||||
const tokenIndexesToFetch = uniq(tokenIdsToFetch)
|
||||
.filter((tokenId) => tokens[tokenId] && tokens[tokenId].index && !tokens[tokenId].fetched)
|
||||
.map((tokenId) => tokens[tokenId].index);
|
||||
|
||||
if (tokenIndexesToFetch.length === 0) {
|
||||
return balances;
|
||||
}
|
||||
|
||||
start = Date.now();
|
||||
return fetchTokens(tokenIndexesToFetch)(dispatch, getState)
|
||||
.then(() => log.debug('token indexes fetched', tokenIndexesToFetch, `(took ${Date.now() - start}ms)`))
|
||||
.then(() => balances);
|
||||
})
|
||||
.then((balances) => {
|
||||
dispatch(setBalances(balances, skipNotifications));
|
||||
})
|
||||
|
@ -14,14 +14,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export const fetchCertifiers = () => ({
|
||||
type: 'fetchCertifiers'
|
||||
});
|
||||
|
||||
export const fetchCertifications = (address) => ({
|
||||
type: 'fetchCertifications', address
|
||||
});
|
||||
|
||||
export const addCertification = (address, id, name, title, icon) => ({
|
||||
type: 'addCertification', address, id, name, title, icon
|
||||
});
|
||||
|
343
js-old/src/redux/providers/certifications/certifiers.monitor.js
Normal file
343
js-old/src/redux/providers/certifications/certifiers.monitor.js
Normal file
@ -0,0 +1,343 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { range } from 'lodash';
|
||||
|
||||
import { addCertification, removeCertification } from './actions';
|
||||
|
||||
import { getLogger, LOG_KEYS } from '~/config';
|
||||
import Contract from '~/api/contract';
|
||||
import { bytesToHex, hexToAscii } from '~/api/util/format';
|
||||
import Contracts from '~/contracts';
|
||||
import CertifierABI from '~/contracts/abi/certifier.json';
|
||||
import { querier } from './enhanced-querier';
|
||||
|
||||
const log = getLogger(LOG_KEYS.CertificationsMiddleware);
|
||||
|
||||
let self = null;
|
||||
|
||||
export default class CertifiersMonitor {
|
||||
constructor (api, store) {
|
||||
this._api = api;
|
||||
this._name = 'Certifiers';
|
||||
this._store = store;
|
||||
|
||||
this._contract = new Contract(this.api, CertifierABI);
|
||||
this._contractEvents = [ 'Confirmed', 'Revoked' ]
|
||||
.map((name) => this.contract.events.find((e) => e.name === name));
|
||||
|
||||
this.certifiers = {};
|
||||
this.fetchedAccounts = {};
|
||||
|
||||
this.load();
|
||||
}
|
||||
|
||||
static get () {
|
||||
if (self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
self = new CertifiersMonitor();
|
||||
return self;
|
||||
}
|
||||
|
||||
static init (api, store) {
|
||||
if (!self) {
|
||||
self = new CertifiersMonitor(api, store);
|
||||
}
|
||||
}
|
||||
|
||||
get api () {
|
||||
return this._api;
|
||||
}
|
||||
|
||||
get contract () {
|
||||
return this._contract;
|
||||
}
|
||||
|
||||
get contractEvents () {
|
||||
return this._contractEvents;
|
||||
}
|
||||
|
||||
get name () {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
get store () {
|
||||
return this._store;
|
||||
}
|
||||
|
||||
get registry () {
|
||||
return this._registry;
|
||||
}
|
||||
|
||||
get registryEvents () {
|
||||
return this._registryEvents;
|
||||
}
|
||||
|
||||
checkFilters () {
|
||||
this.checkCertifiersFilter();
|
||||
this.checkRegistryFilter();
|
||||
}
|
||||
|
||||
checkCertifiersFilter () {
|
||||
if (!this.certifiersFilter) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.api.eth.getFilterChanges(this.certifiersFilter)
|
||||
.then((logs) => {
|
||||
if (logs.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parsedLogs = this.contract.parseEventLogs(logs).filter((log) => log.params);
|
||||
|
||||
log.debug('received certifiers logs', parsedLogs);
|
||||
|
||||
const promises = parsedLogs.map((log) => {
|
||||
const account = log.params.who.value;
|
||||
const certifier = Object.values(this.certifiers).find((c) => c.address === log.address);
|
||||
|
||||
if (!certifier) {
|
||||
log.warn('could not find the certifier', { certifiers: this.certifiers, log });
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return this.fetchAccount(account, { ids: [ certifier.id ] });
|
||||
});
|
||||
|
||||
return Promise.all(promises);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
checkRegistryFilter () {
|
||||
if (!this.registryFilter) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.api.eth.getFilterChanges(this.registryFilter)
|
||||
.then((logs) => {
|
||||
if (logs.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parsedLogs = this.contract.parseEventLogs(logs).filter((log) => log.params);
|
||||
const indexes = parsedLogs.map((log) => log.params && log.params.id.value.toNumber());
|
||||
|
||||
log.debug('received registry logs', parsedLogs);
|
||||
return this.fetchElements(indexes);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial load of the Monitor.
|
||||
* Fetch the contract from the Registry, and
|
||||
* load the elements addresses
|
||||
*/
|
||||
load () {
|
||||
const badgeReg = Contracts.get().badgeReg;
|
||||
|
||||
log.debug(`loading the ${this.name} monitor...`);
|
||||
return badgeReg.getContract()
|
||||
.then((registryContract) => {
|
||||
this._registry = registryContract;
|
||||
this._registryEvents = [ 'Registered', 'Unregistered', 'MetaChanged', 'AddressChanged' ]
|
||||
.map((name) => this.registry.events.find((e) => e.name === name));
|
||||
|
||||
return this.registry.instance.badgeCount.call({});
|
||||
})
|
||||
.then((count) => {
|
||||
log.debug(`found ${count.toFormat()} registered contracts for ${this.name}`);
|
||||
return this.fetchElements(range(count.toNumber()));
|
||||
})
|
||||
.then(() => {
|
||||
return this.setRegistryFilter();
|
||||
})
|
||||
.then(() => {
|
||||
// Listen for new blocks
|
||||
return this.api.subscribe('eth_blockNumber', (err) => {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.checkFilters();
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
log.debug(`loaded the ${this.name} monitor!`, this.certifiers);
|
||||
})
|
||||
.catch((error) => {
|
||||
log.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the given registered element
|
||||
*/
|
||||
fetchElements (indexes) {
|
||||
const badgeReg = Contracts.get().badgeReg;
|
||||
const { instance } = this.registry;
|
||||
|
||||
const sorted = indexes.sort();
|
||||
const from = sorted[0];
|
||||
const last = sorted[sorted.length - 1];
|
||||
const limit = last - from + 1;
|
||||
|
||||
// Fetch the address, name and owner in one batch
|
||||
return querier(this.api, { address: instance.address, from, limit }, instance.badge)
|
||||
.then((results) => {
|
||||
const certifiers = results
|
||||
.map(([ address, name, owner ], index) => ({
|
||||
address, owner,
|
||||
id: index + from,
|
||||
name: hexToAscii(bytesToHex(name).replace(/(00)+$/, ''))
|
||||
}))
|
||||
.reduce((certifiers, certifier) => {
|
||||
const { id } = certifier;
|
||||
|
||||
if (!/^(0x)?0+$/.test(certifier.address)) {
|
||||
certifiers[id] = certifier;
|
||||
} else if (certifiers[id]) {
|
||||
delete certifiers[id];
|
||||
}
|
||||
|
||||
return certifiers;
|
||||
}, {});
|
||||
|
||||
// Fetch the meta-data in serie
|
||||
return Object.values(certifiers).reduce((promise, certifier) => {
|
||||
return promise.then(() => badgeReg.fetchMeta(certifier.id))
|
||||
.then((meta) => {
|
||||
this.certifiers[certifier.id] = { ...certifier, ...meta };
|
||||
});
|
||||
}, Promise.resolve());
|
||||
})
|
||||
.then(() => log.debug('fetched certifiers', { certifiers: this.certifiers }))
|
||||
// Fetch the know accounts in case it's an update of the certifiers
|
||||
.then(() => this.fetchAccounts(Object.keys(this.fetchedAccounts), { ids: indexes, force: true }));
|
||||
}
|
||||
|
||||
fetchAccounts (addresses, { ids = null, force = false } = {}) {
|
||||
const newAddresses = force
|
||||
? addresses
|
||||
: addresses.filter((address) => !this.fetchedAccounts[address]);
|
||||
|
||||
if (newAddresses.length === 0) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
log.debug(`fetching values for "${addresses.join(' ; ')}" in ${this.name}...`);
|
||||
return newAddresses
|
||||
.reduce((promise, address) => {
|
||||
return promise.then(() => this.fetchAccount(address, { ids }));
|
||||
}, Promise.resolve())
|
||||
.then(() => {
|
||||
log.debug(`fetched values for "${addresses.join(' ; ')}" in ${this.name}!`);
|
||||
})
|
||||
.then(() => this.setCertifiersFilter());
|
||||
}
|
||||
|
||||
fetchAccount (address, { ids = null } = {}) {
|
||||
let certifiers = Object.values(this.certifiers);
|
||||
|
||||
// Only fetch values for the givens ids, if any
|
||||
if (ids) {
|
||||
certifiers = certifiers.filter((certifier) => ids.includes(certifier.id));
|
||||
}
|
||||
|
||||
certifiers
|
||||
.reduce((promise, certifier) => {
|
||||
return promise
|
||||
.then(() => {
|
||||
return this.contract.at(certifier.address).instance.certified.call({}, [ address ]);
|
||||
})
|
||||
.then((certified) => {
|
||||
const { id, title, icon, name } = certifier;
|
||||
|
||||
if (!certified) {
|
||||
return this.store.dispatch(removeCertification(address, id));
|
||||
}
|
||||
|
||||
log.debug('seen as certified', { address, id, name, icon });
|
||||
this.store.dispatch(addCertification(address, id, name, title, icon));
|
||||
});
|
||||
}, Promise.resolve())
|
||||
.then(() => {
|
||||
this.fetchedAccounts[address] = true;
|
||||
});
|
||||
}
|
||||
|
||||
setCertifiersFilter () {
|
||||
const accounts = Object.keys(this.fetchedAccounts);
|
||||
const addresses = Object.values(this.certifiers).map((c) => c.address);
|
||||
// The events have as first indexed data the account address
|
||||
const topics = [
|
||||
this.contractEvents.map((event) => '0x' + event.signature),
|
||||
accounts
|
||||
];
|
||||
|
||||
if (accounts.length === 0 || addresses.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const promise = this.certifiersFilter
|
||||
? this.api.eth.uninstallFilter(this.certifiersFilter)
|
||||
: Promise.resolve();
|
||||
|
||||
log.debug('setting up registry filter', { topics, accounts, addresses });
|
||||
|
||||
return promise
|
||||
.then(() => this.api.eth.newFilter({
|
||||
fromBlock: 'latest',
|
||||
toBlock: 'latest',
|
||||
address: addresses,
|
||||
topics
|
||||
}))
|
||||
.then((filterId) => {
|
||||
this.certifiersFilter = filterId;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
setRegistryFilter () {
|
||||
const { address } = this.registry.instance;
|
||||
const topics = [ this.registryEvents.map((event) => '0x' + event.signature) ];
|
||||
|
||||
log.debug('setting up registry filter', { topics, address });
|
||||
|
||||
return this.api.eth
|
||||
.newFilter({
|
||||
fromBlock: 'latest',
|
||||
toBlock: 'latest',
|
||||
address, topics
|
||||
})
|
||||
.then((filterId) => {
|
||||
this.registryFilter = filterId;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { padRight, padLeft } from '~/api/util/format';
|
||||
|
||||
/**
|
||||
* Bytecode of this contract:
|
||||
*
|
||||
*
|
||||
pragma solidity ^0.4.10;
|
||||
|
||||
contract Querier {
|
||||
function Querier
|
||||
(address addr, bytes32 sign, uint out_size, uint from, uint limit)
|
||||
public
|
||||
{
|
||||
// The size is 32 bytes for each
|
||||
// value, plus 32 bytes for the count
|
||||
uint m_size = out_size * limit + 32;
|
||||
|
||||
bytes32 p_return;
|
||||
uint p_in;
|
||||
uint p_out;
|
||||
|
||||
assembly {
|
||||
p_return := mload(0x40)
|
||||
mstore(0x40, add(p_return, m_size))
|
||||
|
||||
mstore(p_return, limit)
|
||||
|
||||
p_in := mload(0x40)
|
||||
mstore(0x40, add(p_in, 0x24))
|
||||
|
||||
mstore(p_in, sign)
|
||||
|
||||
p_out := add(p_return, 0x20)
|
||||
}
|
||||
|
||||
for (uint i = from; i < from + limit; i++) {
|
||||
assembly {
|
||||
mstore(add(p_in, 0x4), i)
|
||||
call(gas, addr, 0x0, p_in, 0x24, p_out, out_size)
|
||||
p_out := add(p_out, out_size)
|
||||
pop
|
||||
}
|
||||
}
|
||||
|
||||
assembly {
|
||||
return (p_return, m_size)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
export const bytecode = '0x60606040523415600e57600080fd5b60405160a0806099833981016040528080519190602001805191906020018051919060200180519190602001805191505082810260200160008080806040519350848401604052858452604051602481016040528981529250505060208201855b858701811015609457806004840152878260248560008e5af15090870190600101606f565b8484f300';
|
||||
|
||||
export const querier = (api, { address, from, limit }, method) => {
|
||||
const { outputs, signature } = method;
|
||||
const outLength = 32 * outputs.length;
|
||||
const callargs = [
|
||||
padLeft(address, 32),
|
||||
padRight(signature, 32),
|
||||
padLeft(outLength, 32),
|
||||
padLeft(from, 32),
|
||||
padLeft(limit, 32)
|
||||
].map((v) => v.slice(2)).join('');
|
||||
const calldata = bytecode + callargs;
|
||||
|
||||
return api.eth.call({ data: calldata })
|
||||
.then((result) => {
|
||||
const data = result.slice(2);
|
||||
const results = [];
|
||||
|
||||
for (let i = 0; i < limit; i++) {
|
||||
const datum = data.substr(2 * (32 + i * outLength), 2 * outLength);
|
||||
const decoded = method.decodeOutput('0x' + datum).map((t) => t.value);
|
||||
|
||||
results.push(decoded);
|
||||
}
|
||||
|
||||
return results;
|
||||
});
|
||||
};
|
@ -14,222 +14,22 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { uniq, range, debounce } from 'lodash';
|
||||
|
||||
import { addCertification, removeCertification } from './actions';
|
||||
|
||||
import { getLogger, LOG_KEYS } from '~/config';
|
||||
import Contract from '~/api/contract';
|
||||
import Contracts from '~/contracts';
|
||||
import CertifierABI from '~/contracts/abi/certifier.json';
|
||||
|
||||
const log = getLogger(LOG_KEYS.CertificationsMiddleware);
|
||||
|
||||
// TODO: move this to a more general place
|
||||
const updatableFilter = (api, onFilter) => {
|
||||
let filter = null;
|
||||
|
||||
const update = (address, topics) => {
|
||||
if (filter) {
|
||||
filter = filter.then((filterId) => {
|
||||
api.eth.uninstallFilter(filterId);
|
||||
});
|
||||
}
|
||||
|
||||
filter = (filter || Promise.resolve())
|
||||
.then(() => api.eth.newFilter({
|
||||
fromBlock: 0,
|
||||
toBlock: 'latest',
|
||||
address,
|
||||
topics
|
||||
}))
|
||||
.then((filterId) => {
|
||||
onFilter(filterId);
|
||||
return filterId;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Failed to create certifications filter:', err);
|
||||
});
|
||||
|
||||
return filter;
|
||||
};
|
||||
|
||||
return update;
|
||||
};
|
||||
import Monitor from './certifiers.monitor';
|
||||
|
||||
export default class CertificationsMiddleware {
|
||||
toMiddleware () {
|
||||
const api = Contracts.get()._api;
|
||||
const badgeReg = Contracts.get().badgeReg;
|
||||
|
||||
const contract = new Contract(api, CertifierABI);
|
||||
const Confirmed = contract.events.find((e) => e.name === 'Confirmed');
|
||||
const Revoked = contract.events.find((e) => e.name === 'Revoked');
|
||||
|
||||
return (store) => {
|
||||
let certifiers = [];
|
||||
let addresses = [];
|
||||
let filterChanged = false;
|
||||
let filter = null;
|
||||
let badgeRegFilter = null;
|
||||
let fetchCertifiersPromise = null;
|
||||
|
||||
const updateFilter = updatableFilter(api, (filterId) => {
|
||||
filterChanged = true;
|
||||
filter = filterId;
|
||||
});
|
||||
|
||||
const badgeRegUpdateFilter = updatableFilter(api, (filterId) => {
|
||||
filterChanged = true;
|
||||
badgeRegFilter = filterId;
|
||||
});
|
||||
|
||||
badgeReg
|
||||
.getContract()
|
||||
.then((badgeRegContract) => {
|
||||
return badgeRegUpdateFilter(badgeRegContract.address, [ [
|
||||
badgeRegContract.instance.Registered.signature,
|
||||
badgeRegContract.instance.Unregistered.signature,
|
||||
badgeRegContract.instance.MetaChanged.signature,
|
||||
badgeRegContract.instance.AddressChanged.signature
|
||||
] ]);
|
||||
})
|
||||
.then(() => {
|
||||
shortFetchChanges();
|
||||
|
||||
api.subscribe('eth_blockNumber', (err) => {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetchChanges();
|
||||
});
|
||||
});
|
||||
|
||||
function onLogs (logs) {
|
||||
logs = contract.parseEventLogs(logs);
|
||||
logs.forEach((log) => {
|
||||
const certifier = certifiers.find((c) => c.address === log.address);
|
||||
|
||||
if (!certifier) {
|
||||
throw new Error(`Could not find certifier at ${log.address}.`);
|
||||
}
|
||||
const { id, name, title, icon } = certifier;
|
||||
|
||||
if (log.event === 'Revoked') {
|
||||
store.dispatch(removeCertification(log.params.who.value, id));
|
||||
} else {
|
||||
store.dispatch(addCertification(log.params.who.value, id, name, title, icon));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onBadgeRegLogs (logs) {
|
||||
return badgeReg.getContract()
|
||||
.then((badgeRegContract) => {
|
||||
logs = badgeRegContract.parseEventLogs(logs);
|
||||
|
||||
const ids = logs.map((log) => log.params && log.params.id.value.toNumber());
|
||||
|
||||
return fetchCertifiers(uniq(ids));
|
||||
});
|
||||
}
|
||||
|
||||
function _fetchChanges () {
|
||||
const method = filterChanged
|
||||
? 'getFilterLogs'
|
||||
: 'getFilterChanges';
|
||||
|
||||
filterChanged = false;
|
||||
|
||||
api.eth[method](badgeRegFilter)
|
||||
.then(onBadgeRegLogs)
|
||||
.catch((err) => {
|
||||
console.error('Failed to fetch badge reg events:', err);
|
||||
})
|
||||
.then(() => api.eth[method](filter))
|
||||
.then(onLogs)
|
||||
.catch((err) => {
|
||||
console.error('Failed to fetch new certifier events:', err);
|
||||
});
|
||||
}
|
||||
|
||||
const shortFetchChanges = debounce(_fetchChanges, 0.5 * 1000, { leading: true });
|
||||
const fetchChanges = debounce(shortFetchChanges, 10 * 1000, { leading: true });
|
||||
|
||||
function fetchConfirmedEvents () {
|
||||
return updateFilter(certifiers.map((c) => c.address), [
|
||||
[ Confirmed.signature, Revoked.signature ],
|
||||
addresses
|
||||
]).then(() => shortFetchChanges());
|
||||
}
|
||||
|
||||
function fetchCertifiers (ids = []) {
|
||||
if (fetchCertifiersPromise) {
|
||||
return fetchCertifiersPromise;
|
||||
}
|
||||
|
||||
let fetchEvents = false;
|
||||
|
||||
const idsPromise = (certifiers.length === 0)
|
||||
? badgeReg.certifierCount().then((count) => {
|
||||
return range(count);
|
||||
})
|
||||
: Promise.resolve(ids);
|
||||
|
||||
fetchCertifiersPromise = idsPromise
|
||||
.then((ids) => {
|
||||
const promises = ids.map((id) => {
|
||||
return badgeReg.fetchCertifier(id)
|
||||
.then((cert) => {
|
||||
if (!certifiers.some((c) => c.id === cert.id)) {
|
||||
certifiers = certifiers.concat(cert);
|
||||
fetchEvents = true;
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
if (/does not exist/.test(err.toString())) {
|
||||
return log.info(err.toString());
|
||||
}
|
||||
|
||||
log.warn(`Could not fetch certifier ${id}:`, err);
|
||||
});
|
||||
});
|
||||
|
||||
return Promise
|
||||
.all(promises)
|
||||
.then(() => {
|
||||
fetchCertifiersPromise = null;
|
||||
|
||||
if (fetchEvents) {
|
||||
return fetchConfirmedEvents();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return fetchCertifiersPromise;
|
||||
}
|
||||
Monitor.init(api, store);
|
||||
|
||||
return (next) => (action) => {
|
||||
switch (action.type) {
|
||||
case 'fetchCertifiers':
|
||||
fetchConfirmedEvents();
|
||||
|
||||
break;
|
||||
case 'fetchCertifications':
|
||||
const { address } = action;
|
||||
|
||||
if (!addresses.includes(address)) {
|
||||
addresses = addresses.concat(address);
|
||||
fetchConfirmedEvents();
|
||||
}
|
||||
|
||||
break;
|
||||
case 'setVisibleAccounts':
|
||||
const _addresses = action.addresses || [];
|
||||
const { addresses = [] } = action;
|
||||
|
||||
addresses = uniq(addresses.concat(_addresses));
|
||||
fetchConfirmedEvents();
|
||||
Monitor.get().fetchAccounts(addresses);
|
||||
next(action);
|
||||
|
||||
break;
|
||||
|
@ -20,24 +20,32 @@ export default (state = initialState, action) => {
|
||||
if (action.type === 'addCertification') {
|
||||
const { address, id, name, icon, title } = action;
|
||||
const certifications = state[address] || [];
|
||||
const certifierIndex = certifications.findIndex((c) => c.id === id);
|
||||
const data = { id, name, icon, title };
|
||||
const nextCertifications = certifications.slice();
|
||||
|
||||
if (certifications.some((c) => c.id === id)) {
|
||||
return state;
|
||||
if (certifierIndex >= 0) {
|
||||
nextCertifications[certifierIndex] = data;
|
||||
} else {
|
||||
nextCertifications.push(data);
|
||||
}
|
||||
|
||||
const newCertifications = certifications.concat({
|
||||
id, name, icon, title
|
||||
});
|
||||
|
||||
return { ...state, [address]: newCertifications };
|
||||
return { ...state, [address]: nextCertifications };
|
||||
}
|
||||
|
||||
if (action.type === 'removeCertification') {
|
||||
const { address, id } = action;
|
||||
const certifications = state[address] || [];
|
||||
const certifierIndex = certifications.findIndex((c) => c.id === id);
|
||||
|
||||
const newCertifications = certifications.filter((c) => c.id !== id);
|
||||
// Don't remove if not there
|
||||
if (certifierIndex < 0) {
|
||||
return state;
|
||||
}
|
||||
|
||||
const newCertifications = certifications.slice();
|
||||
|
||||
newCertifications.splice(certifierIndex, 1);
|
||||
return { ...state, [address]: newCertifications };
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ export Balances from './balances';
|
||||
export Personal from './personal';
|
||||
export Signer from './signer';
|
||||
export Status from './status';
|
||||
export Tokens from './tokens';
|
||||
|
||||
export apiReducer from './apiReducer';
|
||||
export balancesReducer from './balancesReducer';
|
||||
|
@ -16,37 +16,117 @@
|
||||
|
||||
import { personalAccountsInfo } from './personalActions';
|
||||
|
||||
let instance;
|
||||
|
||||
export default class Personal {
|
||||
constructor (store, api) {
|
||||
this._api = api;
|
||||
this._store = store;
|
||||
}
|
||||
|
||||
start () {
|
||||
this._removeDeleted();
|
||||
this._subscribeAccountsInfo();
|
||||
static get (store) {
|
||||
if (!instance && store) {
|
||||
return Personal.init(store);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
static init (store) {
|
||||
const { api } = store.getState();
|
||||
|
||||
if (!instance) {
|
||||
instance = new Personal(store, api);
|
||||
} else if (!instance) {
|
||||
throw new Error('The Personal Provider has not been initialized yet');
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
static start () {
|
||||
const self = instance;
|
||||
|
||||
return Personal.stop()
|
||||
.then(() => Promise.all([
|
||||
self._removeDeleted(),
|
||||
self._subscribeAccountsInfo()
|
||||
]));
|
||||
}
|
||||
|
||||
static stop () {
|
||||
if (!instance) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const self = instance;
|
||||
|
||||
return self._unsubscribeAccountsInfo();
|
||||
}
|
||||
|
||||
_subscribeAccountsInfo () {
|
||||
this._api
|
||||
.subscribe('parity_allAccountsInfo', (error, accountsInfo) => {
|
||||
if (error) {
|
||||
console.error('parity_allAccountsInfo', error);
|
||||
return;
|
||||
}
|
||||
let resolved = false;
|
||||
|
||||
// Add the address to each accounts
|
||||
Object.keys(accountsInfo)
|
||||
.forEach((address) => {
|
||||
accountsInfo[address].address = address;
|
||||
});
|
||||
// The Promise will be resolved when the first
|
||||
// accounts are loaded
|
||||
return new Promise((resolve, reject) => {
|
||||
this._api
|
||||
.subscribe('parity_allAccountsInfo', (error, accountsInfo) => {
|
||||
if (error) {
|
||||
console.error('parity_allAccountsInfo', error);
|
||||
|
||||
this._store.dispatch(personalAccountsInfo(accountsInfo));
|
||||
});
|
||||
if (!resolved) {
|
||||
resolved = true;
|
||||
return reject(error);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the address to each accounts
|
||||
Object.keys(accountsInfo)
|
||||
.forEach((address) => {
|
||||
accountsInfo[address].address = address;
|
||||
});
|
||||
|
||||
const { dispatch, getState } = this._store;
|
||||
|
||||
personalAccountsInfo(accountsInfo)(dispatch, getState)
|
||||
.then(() => {
|
||||
if (!resolved) {
|
||||
resolved = true;
|
||||
return resolve();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
if (!resolved) {
|
||||
resolved = true;
|
||||
return reject(error);
|
||||
}
|
||||
});
|
||||
})
|
||||
.then((subId) => {
|
||||
this.subscriptionId = subId;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_unsubscribeAccountsInfo () {
|
||||
// Unsubscribe to any previous
|
||||
// subscriptions
|
||||
if (this.subscriptionId) {
|
||||
return this._api
|
||||
.unsubscribe(this.subscriptionId)
|
||||
.then(() => {
|
||||
this.subscriptionId = null;
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
_removeDeleted () {
|
||||
this._api.parity
|
||||
return this._api.parity
|
||||
.allAccountsInfo()
|
||||
.then((accountsInfo) => {
|
||||
return Promise.all(
|
||||
|
@ -17,6 +17,7 @@
|
||||
import { isEqual, intersection } from 'lodash';
|
||||
|
||||
import BalancesProvider from './balances';
|
||||
import TokensProvider from './tokens';
|
||||
import { updateTokensFilter } from './balancesActions';
|
||||
import { attachWallets } from './walletActions';
|
||||
|
||||
@ -70,7 +71,7 @@ export function personalAccountsInfo (accountsInfo) {
|
||||
return WalletsUtils.fetchOwners(walletContract.at(wallet.address));
|
||||
});
|
||||
|
||||
Promise
|
||||
return Promise
|
||||
.all(_fetchOwners)
|
||||
.then((walletsOwners) => {
|
||||
return Object
|
||||
@ -135,10 +136,6 @@ export function personalAccountsInfo (accountsInfo) {
|
||||
hardware
|
||||
}));
|
||||
dispatch(attachWallets(wallets));
|
||||
|
||||
BalancesProvider.get().fetchAllBalances({
|
||||
force: true
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('personalAccountsInfo', error);
|
||||
@ -176,12 +173,17 @@ export function setVisibleAccounts (addresses) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the Tokens filter to take into account the new
|
||||
// addresses
|
||||
dispatch(updateTokensFilter());
|
||||
const promises = [];
|
||||
|
||||
BalancesProvider.get().fetchBalances({
|
||||
force: true
|
||||
});
|
||||
// Update the Tokens filter to take into account the new
|
||||
// addresses if it is not loading (it fetches the
|
||||
// balances automatically after loading)
|
||||
if (!TokensProvider.get().loading) {
|
||||
promises.push(updateTokensFilter()(dispatch, getState));
|
||||
}
|
||||
|
||||
promises.push(BalancesProvider.get().fetchEthBalances({ force: true }));
|
||||
|
||||
return Promise.all(promises);
|
||||
};
|
||||
}
|
||||
|
@ -23,12 +23,19 @@ import SavedRequests from '~/views/Application/Requests/savedRequests';
|
||||
const savedRequests = new SavedRequests();
|
||||
|
||||
export const init = (api) => (dispatch) => {
|
||||
api.subscribe('parity_postTransaction', (error, request) => {
|
||||
api.subscribe('signer_requestsToConfirm', (error, pending) => {
|
||||
if (error) {
|
||||
return console.error(error);
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(watchRequest(request));
|
||||
const requests = pending
|
||||
.filter((p) => p.payload && p.payload.sendTransaction)
|
||||
.map((p) => ({
|
||||
requestId: '0x' + p.id.toString(16),
|
||||
transaction: p.payload.sendTransaction
|
||||
}));
|
||||
|
||||
requests.forEach((request) => dispatch(watchRequest(request)));
|
||||
});
|
||||
|
||||
api.once('connected', () => {
|
||||
@ -47,13 +54,24 @@ export const watchRequest = (request) => (dispatch, getState) => {
|
||||
dispatch(trackRequest(requestId, request));
|
||||
};
|
||||
|
||||
export const trackRequest = (requestId, { transactionHash = null } = {}) => (dispatch, getState) => {
|
||||
export const trackRequest = (requestId, { transactionHash = null, retries = 0 } = {}) => (dispatch, getState) => {
|
||||
const { api } = getState();
|
||||
|
||||
trackRequestUtil(api, { requestId, transactionHash }, (error, _data = {}) => {
|
||||
const data = { ..._data };
|
||||
|
||||
if (error) {
|
||||
// Retry in 500ms if request not found, max 5 times
|
||||
if (error.type === 'REQUEST_NOT_FOUND') {
|
||||
if (retries > 5) {
|
||||
return dispatch(deleteRequest(requestId));
|
||||
}
|
||||
|
||||
return setTimeout(() => {
|
||||
trackRequest(requestId, { transactionHash, retries: retries + 1 })(dispatch, getState);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
console.error(error);
|
||||
return dispatch(setRequest(requestId, { error }));
|
||||
}
|
||||
@ -65,8 +83,9 @@ export const trackRequest = (requestId, { transactionHash = null } = {}) => (dis
|
||||
const requestData = requests[requestId];
|
||||
let blockSubscriptionId = -1;
|
||||
|
||||
// Set the block height to 0 at the beggining
|
||||
data.blockHeight = new BigNumber(0);
|
||||
// Set the block height to 1 at the beginning (transaction mined,
|
||||
// thus one confirmation)
|
||||
data.blockHeight = new BigNumber(1);
|
||||
|
||||
// If the request was a contract deployment,
|
||||
// then add the contract with the saved metadata to the account
|
||||
|
@ -48,6 +48,12 @@ let store;
|
||||
|
||||
function createApi () {
|
||||
api = {
|
||||
transport: {
|
||||
on: sinon.stub()
|
||||
},
|
||||
pubsub: {
|
||||
subscribeAndGetResult: sinon.stub().returns(Promise.reject(new Error('not connected')))
|
||||
},
|
||||
net: {
|
||||
version: sinon.stub().resolves('2')
|
||||
},
|
||||
|
@ -14,12 +14,11 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { isEqual } from 'lodash';
|
||||
import { isEqual, debounce } from 'lodash';
|
||||
|
||||
import { LOG_KEYS, getLogger } from '~/config';
|
||||
import UpgradeStore from '~/modals/UpgradeParity/store';
|
||||
// import UpgradeStore from '~/modals/UpgradeParity/store';
|
||||
|
||||
import BalancesProvider from './balances';
|
||||
import { statusBlockNumber, statusCollection } from './statusActions';
|
||||
|
||||
const log = getLogger(LOG_KEYS.Signer);
|
||||
@ -31,7 +30,6 @@ const STATUS_BAD = 'bad';
|
||||
|
||||
export default class Status {
|
||||
_apiStatus = {};
|
||||
_status = {};
|
||||
_longStatus = {};
|
||||
_minerSettings = {};
|
||||
_timeoutIds = {};
|
||||
@ -41,21 +39,14 @@ export default class Status {
|
||||
constructor (store, api) {
|
||||
this._api = api;
|
||||
this._store = store;
|
||||
this._upgradeStore = UpgradeStore.get(api);
|
||||
|
||||
// On connecting, stop all subscriptions
|
||||
api.on('connecting', this.stop, this);
|
||||
|
||||
// On connected, start the subscriptions
|
||||
api.on('connected', this.start, this);
|
||||
|
||||
// On disconnected, stop all subscriptions
|
||||
api.on('disconnected', this.stop, this);
|
||||
// this._upgradeStore = UpgradeStore.get(api);
|
||||
|
||||
this.updateApiStatus();
|
||||
}
|
||||
|
||||
static instantiate (store, api) {
|
||||
static init (store) {
|
||||
const { api } = store.getState();
|
||||
|
||||
if (!instance) {
|
||||
instance = new Status(store, api);
|
||||
}
|
||||
@ -63,59 +54,61 @@ export default class Status {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static get () {
|
||||
if (!instance) {
|
||||
static get (store) {
|
||||
if (!instance && store) {
|
||||
return Status.init(store);
|
||||
} else if (!instance) {
|
||||
throw new Error('The Status Provider has not been initialized yet');
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
start () {
|
||||
static start () {
|
||||
const self = instance;
|
||||
|
||||
log.debug('status::start');
|
||||
|
||||
Promise
|
||||
.all([
|
||||
this._subscribeBlockNumber(),
|
||||
const promises = [
|
||||
self._subscribeBlockNumber(),
|
||||
self._subscribeNetPeers(),
|
||||
self._subscribeEthSyncing(),
|
||||
self._subscribeNodeHealth(),
|
||||
self._pollLongStatus(),
|
||||
self._pollApiStatus()
|
||||
];
|
||||
|
||||
this._pollLongStatus(),
|
||||
this._pollStatus()
|
||||
])
|
||||
.then(() => {
|
||||
return BalancesProvider.start();
|
||||
});
|
||||
return Status.stop()
|
||||
.then(() => Promise.all(promises));
|
||||
}
|
||||
|
||||
stop () {
|
||||
log.debug('status::stop');
|
||||
|
||||
const promises = [];
|
||||
|
||||
if (this._blockNumberSubscriptionId) {
|
||||
const promise = this._api
|
||||
.unsubscribe(this._blockNumberSubscriptionId)
|
||||
.then(() => {
|
||||
this._blockNumberSubscriptionId = null;
|
||||
});
|
||||
|
||||
promises.push(promise);
|
||||
static stop () {
|
||||
if (!instance) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
Object.values(this._timeoutIds).forEach((timeoutId) => {
|
||||
clearTimeout(timeoutId);
|
||||
});
|
||||
const self = instance;
|
||||
|
||||
const promise = BalancesProvider.stop();
|
||||
log.debug('status::stop');
|
||||
|
||||
promises.push(promise);
|
||||
self._clearTimeouts();
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(() => true)
|
||||
return self._unsubscribeBlockNumber()
|
||||
.catch((error) => {
|
||||
console.error('status::stop', error);
|
||||
return true;
|
||||
})
|
||||
.then(() => this.updateApiStatus());
|
||||
.then(() => self.updateApiStatus());
|
||||
}
|
||||
|
||||
getApiStatus = () => {
|
||||
const { isConnected, isConnecting, needsToken, secureToken } = this._api;
|
||||
|
||||
return {
|
||||
isConnected,
|
||||
isConnecting,
|
||||
needsToken,
|
||||
secureToken
|
||||
};
|
||||
}
|
||||
|
||||
updateApiStatus () {
|
||||
@ -129,6 +122,33 @@ export default class Status {
|
||||
}
|
||||
}
|
||||
|
||||
_clearTimeouts () {
|
||||
Object.values(this._timeoutIds).forEach((timeoutId) => {
|
||||
clearTimeout(timeoutId);
|
||||
});
|
||||
}
|
||||
|
||||
_overallStatus (health) {
|
||||
const allWithTime = [health.peers, health.sync, health.time].filter(x => x);
|
||||
const all = [health.peers, health.sync].filter(x => x);
|
||||
const statuses = all.map(x => x.status);
|
||||
const bad = statuses.find(x => x === STATUS_BAD);
|
||||
const needsAttention = statuses.find(x => x === STATUS_WARN);
|
||||
const message = allWithTime.map(x => x.message).filter(x => x);
|
||||
|
||||
if (all.length) {
|
||||
return {
|
||||
status: bad || needsAttention || STATUS_OK,
|
||||
message
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: STATUS_BAD,
|
||||
message: ['Unable to fetch node health.']
|
||||
};
|
||||
}
|
||||
|
||||
_subscribeBlockNumber = () => {
|
||||
return this._api
|
||||
.subscribe('eth_blockNumber', (error, blockNumber) => {
|
||||
@ -159,92 +179,81 @@ export default class Status {
|
||||
});
|
||||
}
|
||||
|
||||
_pollTraceMode = () => {
|
||||
return this._api.trace
|
||||
.block()
|
||||
.then(blockTraces => {
|
||||
// Assumes not in Trace Mode if no transactions
|
||||
// in latest block...
|
||||
return blockTraces.length > 0;
|
||||
})
|
||||
.catch(() => false);
|
||||
_updateStatus = debounce(status => {
|
||||
this._store.dispatch(statusCollection(status));
|
||||
}, 2500, {
|
||||
maxWait: 5000
|
||||
});
|
||||
|
||||
_subscribeEthSyncing = () => {
|
||||
return this._api.pubsub
|
||||
.eth
|
||||
.syncing((error, syncing) => {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._updateStatus({ syncing });
|
||||
});
|
||||
}
|
||||
|
||||
getApiStatus = () => {
|
||||
const { isConnected, isConnecting, needsToken, secureToken } = this._api;
|
||||
_subscribeNetPeers = () => {
|
||||
return this._api.pubsub
|
||||
.parity
|
||||
.netPeers((error, netPeers) => {
|
||||
if (error || !netPeers) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
isConnected,
|
||||
isConnecting,
|
||||
needsToken,
|
||||
secureToken
|
||||
};
|
||||
this._store.dispatch(statusCollection({ netPeers }));
|
||||
});
|
||||
}
|
||||
|
||||
_pollStatus = () => {
|
||||
const nextTimeout = (timeout = 1000) => {
|
||||
if (this._timeoutIds.status) {
|
||||
clearTimeout(this._timeoutIds.status);
|
||||
}
|
||||
|
||||
this._timeoutIds.status = setTimeout(() => this._pollStatus(), timeout);
|
||||
};
|
||||
|
||||
this.updateApiStatus();
|
||||
|
||||
if (!this._api.isConnected) {
|
||||
nextTimeout(250);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const statusPromises = [
|
||||
this._api.eth.syncing(),
|
||||
this._api.parity.netPeers(),
|
||||
this._api.parity.nodeHealth()
|
||||
];
|
||||
|
||||
return Promise
|
||||
.all(statusPromises)
|
||||
.then(([ syncing, netPeers, health ]) => {
|
||||
const status = { netPeers, syncing, health };
|
||||
_subscribeNodeHealth = () => {
|
||||
return this._api.pubsub
|
||||
.parity
|
||||
.nodeHealth((error, health) => {
|
||||
if (error || !health) {
|
||||
return;
|
||||
}
|
||||
|
||||
health.overall = this._overallStatus(health);
|
||||
health.peers = health.peers || {};
|
||||
health.sync = health.sync || {};
|
||||
health.time = health.time || {};
|
||||
|
||||
if (!isEqual(status, this._status)) {
|
||||
this._store.dispatch(statusCollection(status));
|
||||
this._status = status;
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('_pollStatus', error);
|
||||
})
|
||||
.then(() => {
|
||||
nextTimeout();
|
||||
this._store.dispatch(statusCollection({ health }));
|
||||
});
|
||||
}
|
||||
|
||||
_overallStatus = (health) => {
|
||||
const allWithTime = [health.peers, health.sync, health.time].filter(x => x);
|
||||
const all = [health.peers, health.sync].filter(x => x);
|
||||
const statuses = all.map(x => x.status);
|
||||
const bad = statuses.find(x => x === STATUS_BAD);
|
||||
const needsAttention = statuses.find(x => x === STATUS_WARN);
|
||||
const message = allWithTime.map(x => x.message).filter(x => x);
|
||||
|
||||
if (all.length) {
|
||||
return {
|
||||
status: bad || needsAttention || STATUS_OK,
|
||||
message
|
||||
};
|
||||
_unsubscribeBlockNumber () {
|
||||
if (this._blockNumberSubscriptionId) {
|
||||
return this._api
|
||||
.unsubscribe(this._blockNumberSubscriptionId)
|
||||
.then(() => {
|
||||
this._blockNumberSubscriptionId = null;
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
status: STATUS_BAD,
|
||||
message: ['Unable to fetch node health.']
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
_pollApiStatus = () => {
|
||||
const nextTimeout = (timeout = 1000) => {
|
||||
if (this._timeoutIds.status) {
|
||||
clearTimeout(this._timeoutIds.status);
|
||||
}
|
||||
|
||||
this._timeoutIds.status = setTimeout(() => this._pollApiStatus(), timeout);
|
||||
};
|
||||
|
||||
this.updateApiStatus();
|
||||
|
||||
if (!this._api.isConnected) {
|
||||
nextTimeout(250);
|
||||
} else {
|
||||
nextTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,7 +268,7 @@ export default class Status {
|
||||
}
|
||||
|
||||
const { nodeKindFull } = this._store.getState().nodeStatus;
|
||||
const defaultTimeout = (nodeKindFull === false ? 240 : 30) * 1000;
|
||||
const defaultTimeout = (nodeKindFull === false ? 240 : 60) * 1000;
|
||||
|
||||
const nextTimeout = (timeout = defaultTimeout) => {
|
||||
if (this._timeoutIds.longStatus) {
|
||||
@ -271,19 +280,18 @@ export default class Status {
|
||||
|
||||
const statusPromises = [
|
||||
this._api.parity.nodeKind(),
|
||||
this._api.parity.netPeers(),
|
||||
this._api.web3.clientVersion(),
|
||||
this._api.net.version(),
|
||||
this._api.parity.netChain()
|
||||
];
|
||||
|
||||
if (nodeKindFull) {
|
||||
statusPromises.push(this._upgradeStore.checkUpgrade());
|
||||
}
|
||||
// if (nodeKindFull) {
|
||||
// statusPromises.push(this._upgradeStore.checkUpgrade());
|
||||
// }
|
||||
|
||||
return Promise
|
||||
.all(statusPromises)
|
||||
.then(([nodeKind, netPeers, clientVersion, netVersion, netChain]) => {
|
||||
.then(([nodeKind, clientVersion, netVersion, netChain]) => {
|
||||
const isTest = [
|
||||
'2', // morden
|
||||
'3', // ropsten,
|
||||
@ -298,7 +306,6 @@ export default class Status {
|
||||
const longStatus = {
|
||||
nodeKind,
|
||||
nodeKindFull,
|
||||
netPeers,
|
||||
clientVersion,
|
||||
netChain,
|
||||
netVersion,
|
||||
@ -310,11 +317,12 @@ export default class Status {
|
||||
this._longStatus = longStatus;
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
nextTimeout();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('_pollLongStatus', error);
|
||||
})
|
||||
.then(() => {
|
||||
nextTimeout(60000);
|
||||
nextTimeout(30000);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
166
js-old/src/redux/providers/tokens.js
Normal file
166
js-old/src/redux/providers/tokens.js
Normal file
@ -0,0 +1,166 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { updateTokensFilter } from './balancesActions';
|
||||
import { loadTokens, fetchTokens } from './tokensActions';
|
||||
import { padRight } from '~/api/util/format';
|
||||
|
||||
import { LOG_KEYS, getLogger } from '~/config';
|
||||
import Contracts from '~/contracts';
|
||||
|
||||
const log = getLogger(LOG_KEYS.Balances);
|
||||
|
||||
let instance = null;
|
||||
|
||||
export default class Tokens {
|
||||
constructor (store, api) {
|
||||
this._api = api;
|
||||
this._store = store;
|
||||
|
||||
this._tokenreg = null;
|
||||
this._tokenregSubs = [];
|
||||
|
||||
this._loading = false;
|
||||
}
|
||||
|
||||
get loading () {
|
||||
return this._loading;
|
||||
}
|
||||
|
||||
static get (store) {
|
||||
if (!instance && store) {
|
||||
return Tokens.init(store);
|
||||
} else if (!instance) {
|
||||
throw new Error('The Tokens Provider has not been initialized yet');
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
static init (store) {
|
||||
const { api } = store.getState();
|
||||
|
||||
if (!instance) {
|
||||
instance = new Tokens(store, api);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
static start () {
|
||||
if (!instance) {
|
||||
return Promise.reject('Tokens Provider has not been initiated yet');
|
||||
}
|
||||
|
||||
const self = instance;
|
||||
|
||||
self._loading = true;
|
||||
|
||||
// Unsubscribe from previous subscriptions
|
||||
return Tokens.stop()
|
||||
.then(() => self.loadTokens())
|
||||
.then(() => {
|
||||
self._loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
static stop () {
|
||||
if (!instance) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const self = instance;
|
||||
|
||||
// Unsubscribe without adding the promises
|
||||
// to the result, since it would have to wait for a
|
||||
// reconnection to resolve if the Node is disconnected
|
||||
if (self._tokenreg) {
|
||||
const tokenregPromises = self._tokenregSubs
|
||||
.map((tokenregSID) => self._tokenreg.unsubscribe(tokenregSID));
|
||||
|
||||
Promise.all(tokenregPromises)
|
||||
.then(() => {
|
||||
self._tokenregSubs = [];
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
attachToTokensEvents (tokenreg) {
|
||||
const metaTopics = [ null, padRight(this._api.util.asciiToHex('IMG'), 32) ];
|
||||
|
||||
return Promise
|
||||
.all([
|
||||
this._attachToTokenregEvents(tokenreg, 'Registered'),
|
||||
this._attachToTokenregEvents(tokenreg, 'MetaChanged', metaTopics)
|
||||
]);
|
||||
}
|
||||
|
||||
getTokenRegistry () {
|
||||
return Contracts.get().tokenReg.getContract();
|
||||
}
|
||||
|
||||
loadTokens (options = {}) {
|
||||
const { dispatch, getState } = this._store;
|
||||
|
||||
return this
|
||||
.getTokenRegistry()
|
||||
.then((tokenreg) => {
|
||||
this._tokenreg = tokenreg;
|
||||
|
||||
return loadTokens(options)(dispatch, getState);
|
||||
})
|
||||
.then(() => updateTokensFilter()(dispatch, getState))
|
||||
.then(() => this.attachToTokensEvents(this._tokenreg))
|
||||
.catch((error) => {
|
||||
console.warn('balances::loadTokens', error);
|
||||
});
|
||||
}
|
||||
|
||||
_attachToTokenregEvents (tokenreg, event, topics = []) {
|
||||
if (this._tokenregSID) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return tokenreg.instance[event]
|
||||
.subscribe({
|
||||
fromBlock: 'latest',
|
||||
toBlock: 'latest',
|
||||
topics: topics,
|
||||
skipInitFetch: true
|
||||
}, (error, logs) => {
|
||||
if (error) {
|
||||
return console.error('balances::attachToNewToken', 'failed to attach to tokenreg Registered', error.toString(), error.stack);
|
||||
}
|
||||
|
||||
this._handleTokensLogs(logs);
|
||||
})
|
||||
.then((tokenregSID) => {
|
||||
this._tokenregSubs.push(tokenregSID);
|
||||
});
|
||||
}
|
||||
|
||||
_handleTokensLogs (logs) {
|
||||
const { dispatch, getState } = this._store;
|
||||
const tokenIds = logs.map((log) => log.params.id.value.toNumber());
|
||||
|
||||
log.debug('got TokenRegistry logs', logs, tokenIds);
|
||||
|
||||
return fetchTokens(tokenIds)(dispatch, getState)
|
||||
.then(() => updateTokensFilter()(dispatch, getState));
|
||||
}
|
||||
}
|
@ -14,56 +14,223 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { uniq } from 'lodash';
|
||||
import { chunk, uniq } from 'lodash';
|
||||
import store from 'store';
|
||||
|
||||
import Contracts from '~/contracts';
|
||||
import { LOG_KEYS, getLogger } from '~/config';
|
||||
import { fetchTokenIds, fetchTokenInfo } from '~/util/tokens';
|
||||
import { fetchTokenIds, fetchTokensBasics, fetchTokensInfo, fetchTokensImages } from '~/util/tokens';
|
||||
|
||||
import { updateTokensFilter } from './balancesActions';
|
||||
import { setAddressImage } from './imagesActions';
|
||||
|
||||
const TOKENS_CACHE_LS_KEY_PREFIX = '_parity::tokens::';
|
||||
const log = getLogger(LOG_KEYS.Balances);
|
||||
|
||||
export function setTokens (tokens) {
|
||||
function _setTokens (tokens) {
|
||||
return {
|
||||
type: 'setTokens',
|
||||
tokens
|
||||
};
|
||||
}
|
||||
|
||||
export function setTokens (nextTokens) {
|
||||
return (dispatch, getState) => {
|
||||
const { nodeStatus, tokens: prevTokens } = getState();
|
||||
const { tokenReg } = Contracts.get();
|
||||
const tokens = {
|
||||
...prevTokens,
|
||||
...nextTokens
|
||||
};
|
||||
|
||||
return tokenReg.getContract()
|
||||
.then((tokenRegContract) => {
|
||||
const lsKey = TOKENS_CACHE_LS_KEY_PREFIX + nodeStatus.netChain;
|
||||
|
||||
store.set(lsKey, {
|
||||
tokenreg: tokenRegContract.address,
|
||||
tokens
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
})
|
||||
.then(() => {
|
||||
dispatch(_setTokens(nextTokens));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function loadCachedTokens (tokenRegContract) {
|
||||
return (dispatch, getState) => {
|
||||
const { nodeStatus } = getState();
|
||||
|
||||
const lsKey = TOKENS_CACHE_LS_KEY_PREFIX + nodeStatus.netChain;
|
||||
const cached = store.get(lsKey);
|
||||
|
||||
if (cached) {
|
||||
// Check if we have data from the right contract
|
||||
if (cached.tokenreg === tokenRegContract.address && cached.tokens) {
|
||||
log.debug('found cached tokens', cached.tokens);
|
||||
|
||||
// Fetch all the tokens images on load
|
||||
// (it's the only thing that might have changed)
|
||||
const tokenIndexes = Object.values(cached.tokens)
|
||||
.filter((t) => t && t.fetched)
|
||||
.map((t) => t.index);
|
||||
|
||||
fetchTokensData(tokenRegContract, tokenIndexes)(dispatch, getState);
|
||||
} else {
|
||||
store.remove(lsKey);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function loadTokens (options = {}) {
|
||||
log.debug('loading tokens', Object.keys(options).length ? options : '');
|
||||
|
||||
return (dispatch, getState) => {
|
||||
const { tokenReg } = Contracts.get();
|
||||
|
||||
tokenReg.getInstance()
|
||||
.then((tokenRegInstance) => {
|
||||
return fetchTokenIds(tokenRegInstance);
|
||||
return tokenReg.getContract()
|
||||
.then((tokenRegContract) => {
|
||||
loadCachedTokens(tokenRegContract)(dispatch, getState);
|
||||
return fetchTokenIds(tokenRegContract.instance);
|
||||
})
|
||||
.then((tokenIndexes) => dispatch(fetchTokens(tokenIndexes, options)))
|
||||
.then((tokenIndexes) => loadTokensBasics(tokenIndexes, options)(dispatch, getState))
|
||||
.catch((error) => {
|
||||
console.warn('tokens::loadTokens', error);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchTokens (_tokenIndexes, options = {}) {
|
||||
const tokenIndexes = uniq(_tokenIndexes || []);
|
||||
export function loadTokensBasics (tokenIndexes, options) {
|
||||
const limit = 64;
|
||||
|
||||
return (dispatch, getState) => {
|
||||
const { api } = getState();
|
||||
const { tokenReg } = Contracts.get();
|
||||
const nextTokens = {};
|
||||
const count = tokenIndexes.length;
|
||||
|
||||
log.debug('loading basic tokens', tokenIndexes);
|
||||
|
||||
if (count === 0) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return tokenReg.getContract()
|
||||
.then((tokenRegContract) => {
|
||||
let promise = Promise.resolve();
|
||||
const first = tokenIndexes[0];
|
||||
const last = tokenIndexes[tokenIndexes.length - 1];
|
||||
|
||||
for (let from = first; from <= last; from += limit) {
|
||||
// No need to fetch `limit` elements
|
||||
const lowerLimit = Math.min(limit, last - from + 1);
|
||||
|
||||
promise = promise
|
||||
.then(() => fetchTokensBasics(api, tokenRegContract, from, lowerLimit))
|
||||
.then((results) => {
|
||||
results
|
||||
.forEach((token) => {
|
||||
nextTokens[token.id] = token;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return promise;
|
||||
})
|
||||
.then(() => {
|
||||
log.debug('fetched tokens basic info', nextTokens);
|
||||
|
||||
dispatch(setTokens(nextTokens));
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('tokens::fetchTokens', error);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchTokens (_tokenIndexes) {
|
||||
const tokenIndexes = uniq(_tokenIndexes || []);
|
||||
const tokenChunks = chunk(tokenIndexes, 64);
|
||||
|
||||
return (dispatch, getState) => {
|
||||
const { api, images } = getState();
|
||||
const { tokenReg } = Contracts.get();
|
||||
|
||||
return tokenReg.getInstance()
|
||||
.then((tokenRegInstance) => {
|
||||
const promises = tokenIndexes.map((id) => fetchTokenInfo(api, tokenRegInstance, id));
|
||||
return tokenReg.getContract()
|
||||
.then((tokenRegContract) => {
|
||||
let promise = Promise.resolve();
|
||||
|
||||
return Promise.all(promises);
|
||||
tokenChunks.forEach((tokenChunk) => {
|
||||
promise = promise
|
||||
.then(() => fetchTokensData(tokenRegContract, tokenChunk)(dispatch, getState));
|
||||
});
|
||||
|
||||
return promise;
|
||||
})
|
||||
.then((results) => {
|
||||
const tokens = results
|
||||
.then(() => {
|
||||
log.debug('fetched token', getState().tokens);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('tokens::fetchTokens', error);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Split the given token indexes between those for whom
|
||||
* we already have some info, and thus just need to fetch
|
||||
* the image, and those for whom we don't have anything and
|
||||
* need to fetch all the info.
|
||||
*/
|
||||
function fetchTokensData (tokenRegContract, tokenIndexes) {
|
||||
return (dispatch, getState) => {
|
||||
const { api, tokens, images } = getState();
|
||||
const allTokens = Object.values(tokens);
|
||||
|
||||
const tokensIndexesMap = allTokens
|
||||
.reduce((map, token) => {
|
||||
map[token.index] = token;
|
||||
return map;
|
||||
}, {});
|
||||
|
||||
const fetchedTokenIndexes = allTokens
|
||||
.filter((token) => token.fetched)
|
||||
.map((token) => token.index);
|
||||
|
||||
const fullIndexes = [];
|
||||
const partialIndexes = [];
|
||||
|
||||
tokenIndexes.forEach((tokenIndex) => {
|
||||
if (fetchedTokenIndexes.includes(tokenIndex)) {
|
||||
partialIndexes.push(tokenIndex);
|
||||
} else {
|
||||
fullIndexes.push(tokenIndex);
|
||||
}
|
||||
});
|
||||
|
||||
log.debug('need to fully fetch', fullIndexes);
|
||||
log.debug('need to partially fetch', partialIndexes);
|
||||
|
||||
const fullPromise = fetchTokensInfo(api, tokenRegContract, fullIndexes);
|
||||
const partialPromise = fetchTokensImages(api, tokenRegContract, partialIndexes)
|
||||
.then((imagesResult) => {
|
||||
return imagesResult.map((image, index) => {
|
||||
const tokenIndex = partialIndexes[index];
|
||||
const token = tokensIndexesMap[tokenIndex];
|
||||
|
||||
return { ...token, image };
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all([ fullPromise, partialPromise ])
|
||||
.then(([ fullResults, partialResults ]) => {
|
||||
log.debug('fetched', { fullResults, partialResults });
|
||||
|
||||
return [].concat(fullResults, partialResults)
|
||||
.filter(({ address }) => !/0x0*$/.test(address))
|
||||
.reduce((tokens, token) => {
|
||||
const { id, image, address } = token;
|
||||
|
||||
@ -75,14 +242,9 @@ export function fetchTokens (_tokenIndexes, options = {}) {
|
||||
tokens[id] = token;
|
||||
return tokens;
|
||||
}, {});
|
||||
|
||||
log.debug('fetched token', tokens);
|
||||
|
||||
dispatch(setTokens(tokens));
|
||||
dispatch(updateTokensFilter(null, null, options));
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('tokens::fetchTokens', error);
|
||||
.then((tokens) => {
|
||||
dispatch(setTokens(tokens));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@ -25,10 +25,15 @@ const initialState = {
|
||||
export default handleActions({
|
||||
setTokens (state, action) {
|
||||
const { tokens } = action;
|
||||
const nextTokens = { ...state };
|
||||
|
||||
return {
|
||||
...state,
|
||||
...tokens
|
||||
};
|
||||
Object.keys(tokens).forEach((tokenId) => {
|
||||
nextTokens[tokenId] = {
|
||||
...(nextTokens[tokenId]),
|
||||
...tokens[tokenId]
|
||||
};
|
||||
});
|
||||
|
||||
return nextTokens;
|
||||
}
|
||||
}, initialState);
|
||||
|
@ -22,12 +22,14 @@ import initReducers from './reducers';
|
||||
import { load as loadWallet } from './providers/walletActions';
|
||||
import { init as initRequests } from './providers/requestsActions';
|
||||
import { setupWorker } from './providers/workerWrapper';
|
||||
import { setApi } from './providers/apiActions';
|
||||
|
||||
import {
|
||||
Balances as BalancesProvider,
|
||||
Personal as PersonalProvider,
|
||||
Signer as SignerProvider,
|
||||
Status as StatusProvider
|
||||
Status as StatusProvider,
|
||||
Tokens as TokensProvider
|
||||
} from './providers';
|
||||
|
||||
const storeCreation = window.devToolsExtension
|
||||
@ -39,14 +41,59 @@ export default function (api, browserHistory, forEmbed = false) {
|
||||
const middleware = initMiddleware(api, browserHistory, forEmbed);
|
||||
const store = applyMiddleware(...middleware)(storeCreation)(reducers);
|
||||
|
||||
BalancesProvider.instantiate(store, api);
|
||||
StatusProvider.instantiate(store, api);
|
||||
new PersonalProvider(store, api).start();
|
||||
// Add the `api` to the Redux Store
|
||||
store.dispatch({ type: 'initAll', api });
|
||||
store.dispatch(setApi(api));
|
||||
|
||||
// Initialise the Store Providers
|
||||
BalancesProvider.init(store);
|
||||
PersonalProvider.init(store);
|
||||
StatusProvider.init(store);
|
||||
TokensProvider.init(store);
|
||||
|
||||
new SignerProvider(store, api).start();
|
||||
|
||||
store.dispatch(loadWallet(api));
|
||||
store.dispatch(initRequests(api));
|
||||
setupWorker(store);
|
||||
|
||||
const start = () => {
|
||||
return Promise
|
||||
.resolve()
|
||||
.then(() => console.log('v1: starting Status Provider...'))
|
||||
.then(() => StatusProvider.start())
|
||||
.then(() => console.log('v1: started Status Provider'))
|
||||
|
||||
.then(() => console.log('v1: starting Personal Provider...'))
|
||||
.then(() => PersonalProvider.start())
|
||||
.then(() => console.log('v1: started Personal Provider'))
|
||||
|
||||
.then(() => console.log('v1: starting Balances Provider...'))
|
||||
.then(() => BalancesProvider.start())
|
||||
.then(() => console.log('v1: started Balances Provider'))
|
||||
|
||||
.then(() => console.log('v1: starting Tokens Provider...'))
|
||||
.then(() => TokensProvider.start())
|
||||
.then(() => console.log('v1: started Tokens Provider'));
|
||||
};
|
||||
|
||||
const stop = () => {
|
||||
return StatusProvider
|
||||
.stop()
|
||||
.then(() => PersonalProvider.stop())
|
||||
.then(() => TokensProvider.stop())
|
||||
.then(() => BalancesProvider.stop());
|
||||
};
|
||||
|
||||
// On connected, start the subscriptions
|
||||
api.on('connected', start);
|
||||
|
||||
// On disconnected, stop all subscriptions
|
||||
api.on('disconnected', stop);
|
||||
|
||||
if (api.isConnected) {
|
||||
start();
|
||||
}
|
||||
|
||||
return store;
|
||||
}
|
||||
|
@ -17,12 +17,12 @@
|
||||
import Push from 'push.js';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
import unkownIcon from '~/../assets/images/contracts/unknown-64x64.png';
|
||||
import unknownIcon from '~/../assets/images/contracts/unknown-64x64.png';
|
||||
|
||||
export function notifyTransaction (account, token, _value, onClick) {
|
||||
const name = account.name || account.address;
|
||||
const value = _value.div(new BigNumber(token.format || 1));
|
||||
const icon = token.image || unkownIcon;
|
||||
const icon = token.image || unknownIcon;
|
||||
|
||||
let _notification = null;
|
||||
|
||||
|
@ -1,133 +0,0 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { range } from 'lodash';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
import { hashToImageUrl } from '~/redux/util';
|
||||
import { sha3 } from '~/api/util/sha3';
|
||||
import imagesEthereum from '~/../assets/images/contracts/ethereum-black-64x64.png';
|
||||
|
||||
const BALANCEOF_SIGNATURE = sha3('balanceOf(address)');
|
||||
const ADDRESS_PADDING = range(24).map(() => '0').join('');
|
||||
|
||||
export const ETH_TOKEN = {
|
||||
address: '',
|
||||
format: new BigNumber(10).pow(18),
|
||||
id: sha3('eth_native_token').slice(0, 10),
|
||||
image: imagesEthereum,
|
||||
name: 'Ethereum',
|
||||
native: true,
|
||||
tag: 'ETH'
|
||||
};
|
||||
|
||||
export function fetchTokenIds (tokenregInstance) {
|
||||
return tokenregInstance.tokenCount
|
||||
.call()
|
||||
.then((numTokens) => {
|
||||
const tokenIndexes = range(numTokens.toNumber());
|
||||
|
||||
return tokenIndexes;
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchTokenInfo (api, tokenregInstace, tokenIndex) {
|
||||
return Promise
|
||||
.all([
|
||||
tokenregInstace.token.call({}, [tokenIndex]),
|
||||
tokenregInstace.meta.call({}, [tokenIndex, 'IMG'])
|
||||
])
|
||||
.then(([ tokenData, image ]) => {
|
||||
const [ address, tag, format, name ] = tokenData;
|
||||
|
||||
const token = {
|
||||
format: format.toString(),
|
||||
index: tokenIndex,
|
||||
image: hashToImageUrl(image),
|
||||
id: sha3(address + tokenIndex).slice(0, 10),
|
||||
address,
|
||||
name,
|
||||
tag
|
||||
};
|
||||
|
||||
return token;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* `updates` should be in the shape:
|
||||
* {
|
||||
* [ who ]: [ tokenId ] // Array of tokens to updates
|
||||
* }
|
||||
*
|
||||
* Returns a Promise resolved witht the balances in the shape:
|
||||
* {
|
||||
* [ who ]: { [ tokenId ]: BigNumber } // The balances of `who`
|
||||
* }
|
||||
*/
|
||||
export function fetchAccountsBalances (api, tokens, updates) {
|
||||
const addresses = Object.keys(updates);
|
||||
const promises = addresses
|
||||
.map((who) => {
|
||||
const tokensIds = updates[who];
|
||||
const tokensToUpdate = tokensIds.map((tokenId) => tokens.find((t) => t.id === tokenId));
|
||||
|
||||
return fetchAccountBalances(api, tokensToUpdate, who);
|
||||
});
|
||||
|
||||
return Promise.all(promises)
|
||||
.then((results) => {
|
||||
return results.reduce((balances, accountBalances, index) => {
|
||||
balances[addresses[index]] = accountBalances;
|
||||
return balances;
|
||||
}, {});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Promise resolved with the balances in the shape:
|
||||
* {
|
||||
* [ tokenId ]: BigNumber // Token balance value
|
||||
* }
|
||||
*/
|
||||
export function fetchAccountBalances (api, tokens, who) {
|
||||
const calldata = '0x' + BALANCEOF_SIGNATURE.slice(2, 10) + ADDRESS_PADDING + who.slice(2);
|
||||
const promises = tokens.map((token) => fetchTokenBalance(api, token, { who, calldata }));
|
||||
|
||||
return Promise.all(promises)
|
||||
.then((results) => {
|
||||
return results.reduce((balances, value, index) => {
|
||||
const token = tokens[index];
|
||||
|
||||
balances[token.id] = value;
|
||||
return balances;
|
||||
}, {});
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchTokenBalance (api, token, { who, calldata }) {
|
||||
if (token.native) {
|
||||
return api.eth.getBalance(who);
|
||||
}
|
||||
|
||||
return api.eth
|
||||
.call({ data: calldata, to: token.address })
|
||||
.then((result) => {
|
||||
const cleanResult = result.replace(/^0x/, '');
|
||||
|
||||
return new BigNumber(`0x${cleanResult || 0}`);
|
||||
});
|
||||
}
|
23
js-old/src/util/tokens/bytecodes.js
Normal file
23
js-old/src/util/tokens/bytecodes.js
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// build from : https://raw.githubusercontent.com/paritytech/contracts/4c8501e908166aab7ff4d2ebb05db61b5d017024/TokenCalls.sol
|
||||
// metadata (include build version and options):
|
||||
// {"compiler":{"version":"0.4.16+commit.d7661dd9"},"language":"Solidity","output":{"abi":[{"inputs":[{"name":"tokenRegAddress","type":"address"},{"name":"start","type":"uint256"},{"name":"limit","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}],"devdoc":{"methods":{}},"userdoc":{"methods":{}}},"settings":{"compilationTarget":{"":"Tokens"},"libraries":{},"optimizer":{"enabled":true,"runs":200},"remappings":[]},"sources":{"":{"keccak256":"0x4790e490f418d1a5884c27ffe9684914dab2d55bd1d23b99cff7aa2ca289e2d3","urls":["bzzr://bb200beae6849f1f5bb97b36c57cd493be52877ec0b55ee9969fa5f8159cf37b"]}},"version":1}
|
||||
// {"compiler":{"version":"0.4.16+commit.d7661dd9"},"language":"Solidity","output":{"abi":[{"inputs":[{"name":"who","type":"address[]"},{"name":"tokens","type":"address[]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}],"devdoc":{"methods":{}},"userdoc":{"methods":{}}},"settings":{"compilationTarget":{"":"TokensBalances"},"libraries":{},"optimizer":{"enabled":true,"runs":200},"remappings":[]},"sources":{"":{"keccak256":"0x4790e490f418d1a5884c27ffe9684914dab2d55bd1d23b99cff7aa2ca289e2d3","urls":["bzzr://bb200beae6849f1f5bb97b36c57cd493be52877ec0b55ee9969fa5f8159cf37b"]}},"version":1}
|
||||
|
||||
export const tokenAddresses = '0x6060604052341561000f57600080fd5b6040516060806102528339810160405280805191906020018051919060200180519150505b6000806000806100426101fc565b600088955085600160a060020a0316639f181b5e6000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156100a657600080fd5b6102c65a03f115156100b757600080fd5b50505060405180519550508688018890116100ce57fe5b8785116100de57600093506100f6565b8487890111156100f25787850393506100f6565b8693505b5b83602002602001925060405191508282016040528382528790505b8388018110156101ea5785600160a060020a031663044215c682600060405160a001526040517c010000000000000000000000000000000000000000000000000000000063ffffffff8416028152600481019190915260240160a060405180830381600087803b151561018457600080fd5b6102c65a03f1151561019557600080fd5b50505060405180519060200180519060200180519060200180519060200180515086935050508a84039050815181106101ca57fe5b600160a060020a039092166020928302909101909101525b600101610112565b8282f35b50505050505050505061020e565b60206040519081016040526000815290565b60368061021c6000396000f30060606040525b600080fd00a165627a7a72305820a9a09f013393cf3c6398ce0f8175073fe363b6f594f9bd569261d0bb94aa84d40029';
|
||||
export const tokensBalances = '0x6060604052341561000f57600080fd5b60405161018b38038061018b8339810160405280805182019190602001805190910190505b6000806000610041610135565b60008060008060008060008c518c51029a506020808c020199507f70a0823100000000000000000000000000000000000000000000000000000000985060405197508988016040528a8852604051965060248701604052888752879550866004019450600093505b8c5184101561011f57600092505b8b51831015610113578c84815181106100cc57fe5b9060200190602002015191508b83815181106100e457fe5b90602001906020020151905060208601955081855260208660248960008561fffff1505b6001909201916100b7565b5b6001909301926100a9565b8988f35b50505050505050505050505050610147565b60206040519081016040526000815290565b6036806101556000396000f30060606040525b600080fd00a165627a7a723058203cfc17c394936aa87b7db79e4f082a7cfdcefef54acd3124d17525b56c92e7950029';
|
@ -81,12 +81,11 @@ export function getTxOptions (api, func, _options, values = []) {
|
||||
options.to = options.to || func.contract.address;
|
||||
}
|
||||
|
||||
if (!address) {
|
||||
return Promise.resolve({ func, options, values });
|
||||
}
|
||||
const promise = (!address)
|
||||
? Promise.resolve(false)
|
||||
: WalletsUtils.isWallet(api, address);
|
||||
|
||||
return WalletsUtils
|
||||
.isWallet(api, address)
|
||||
return promise
|
||||
.then((isWallet) => {
|
||||
if (!isWallet) {
|
||||
return { func, options, values };
|
||||
|
@ -78,13 +78,39 @@ export default class WalletsUtils {
|
||||
.delegateCall(api, walletContract.address, 'fetchTransactions', [ walletContract ])
|
||||
.then((transactions) => {
|
||||
return transactions.sort((txA, txB) => {
|
||||
const comp = txB.blockNumber.comparedTo(txA.blockNumber);
|
||||
const bnA = txA.blockNumber;
|
||||
const bnB = txB.blockNumber;
|
||||
|
||||
if (!bnA) {
|
||||
console.warn('could not find block number in transaction', txA);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!bnB) {
|
||||
console.warn('could not find block number in transaction', txB);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const comp = bnA.comparedTo(bnB);
|
||||
|
||||
if (comp !== 0) {
|
||||
return comp;
|
||||
}
|
||||
|
||||
return txB.transactionIndex.comparedTo(txA.transactionIndex);
|
||||
const txIdxA = txA.transactionIndex;
|
||||
const txIdxB = txB.transactionIndex;
|
||||
|
||||
if (!txIdxA) {
|
||||
console.warn('could not find transaction index in transaction', txA);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!txIdxB) {
|
||||
console.warn('could not find transaction index in transaction', txB);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return txIdxA.comparedTo(txIdxB);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -212,6 +212,7 @@ export default class ConsensysWalletUtils {
|
||||
|
||||
const transaction = {
|
||||
transactionHash: log.transactionHash,
|
||||
transactionIndex: log.transactionIndex,
|
||||
blockNumber: log.blockNumber
|
||||
};
|
||||
|
||||
|
@ -130,27 +130,67 @@ export default class FoundationWalletUtils {
|
||||
.ConfirmationNeeded
|
||||
.getAllLogs()
|
||||
.then((logs) => {
|
||||
return logs.map((log) => ({
|
||||
initiator: log.params.initiator.value,
|
||||
to: log.params.to.value,
|
||||
data: log.params.data.value,
|
||||
value: log.params.value.value,
|
||||
operation: bytesToHex(log.params.operation.value),
|
||||
transactionIndex: log.transactionIndex,
|
||||
transactionHash: log.transactionHash,
|
||||
blockNumber: log.blockNumber,
|
||||
confirmedBy: []
|
||||
}));
|
||||
return logs
|
||||
.filter((log) => {
|
||||
if (!log.blockNumber) {
|
||||
console.warn('got a log without blockNumber', log);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!log.transactionIndex) {
|
||||
console.warn('got a log without transactionIndex', log);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
.map((log) => ({
|
||||
initiator: log.params.initiator.value,
|
||||
to: log.params.to.value,
|
||||
data: log.params.data.value,
|
||||
value: log.params.value.value,
|
||||
operation: bytesToHex(log.params.operation.value),
|
||||
transactionIndex: log.transactionIndex,
|
||||
transactionHash: log.transactionHash,
|
||||
blockNumber: log.blockNumber,
|
||||
confirmedBy: []
|
||||
}));
|
||||
})
|
||||
.then((logs) => {
|
||||
return logs.sort((logA, logB) => {
|
||||
const comp = logA.blockNumber.comparedTo(logB.blockNumber);
|
||||
const bnA = logA.blockNumber;
|
||||
const bnB = logA.blockNumber;
|
||||
|
||||
if (!bnA) {
|
||||
console.warn('could not find block number in log', logA);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!bnB) {
|
||||
console.warn('could not find block number in log', logB);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const comp = bnA.comparedTo(bnB);
|
||||
|
||||
if (comp !== 0) {
|
||||
return comp;
|
||||
}
|
||||
|
||||
return logA.transactionIndex.comparedTo(logB.transactionIndex);
|
||||
const txIdxA = logA.transactionIndex;
|
||||
const txIdxB = logB.transactionIndex;
|
||||
|
||||
if (!txIdxA) {
|
||||
console.warn('could not find transaction index in log', logA);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!txIdxB) {
|
||||
console.warn('could not find transaction index in log', logB);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return txIdxA.comparedTo(txIdxB);
|
||||
});
|
||||
})
|
||||
.then((pendingTxs) => {
|
||||
@ -205,40 +245,48 @@ export default class FoundationWalletUtils {
|
||||
] ]
|
||||
})
|
||||
.then((logs) => {
|
||||
const transactions = logs.map((log) => {
|
||||
const signature = toHex(log.topics[0]);
|
||||
const transactions = logs
|
||||
.map((log) => {
|
||||
const signature = toHex(log.topics[0]);
|
||||
|
||||
const value = log.params.value.value;
|
||||
const from = signature === WalletSignatures.Deposit
|
||||
? log.params['_from'].value
|
||||
: walletContract.address;
|
||||
const value = log.params.value.value;
|
||||
const from = signature === WalletSignatures.Deposit
|
||||
? log.params['_from'].value
|
||||
: walletContract.address;
|
||||
|
||||
const to = signature === WalletSignatures.Deposit
|
||||
? walletContract.address
|
||||
: log.params.to.value;
|
||||
const to = signature === WalletSignatures.Deposit
|
||||
? walletContract.address
|
||||
: log.params.to.value;
|
||||
|
||||
const transaction = {
|
||||
transactionHash: log.transactionHash,
|
||||
blockNumber: log.blockNumber,
|
||||
from, to, value
|
||||
};
|
||||
const transaction = {
|
||||
transactionHash: log.transactionHash,
|
||||
transactionIndex: log.transactionIndex,
|
||||
blockNumber: log.blockNumber,
|
||||
from, to, value
|
||||
};
|
||||
|
||||
if (log.params.created && log.params.created.value && !/^(0x)?0*$/.test(log.params.created.value)) {
|
||||
transaction.creates = log.params.created.value;
|
||||
delete transaction.to;
|
||||
}
|
||||
if (!transaction.blockNumber) {
|
||||
console.warn('log without block number', log);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (log.params.operation) {
|
||||
transaction.operation = bytesToHex(log.params.operation.value);
|
||||
checkPendingOperation(api, log, transaction.operation);
|
||||
}
|
||||
if (log.params.created && log.params.created.value && !/^(0x)?0*$/.test(log.params.created.value)) {
|
||||
transaction.creates = log.params.created.value;
|
||||
delete transaction.to;
|
||||
}
|
||||
|
||||
if (log.params.data) {
|
||||
transaction.data = log.params.data.value;
|
||||
}
|
||||
if (log.params.operation) {
|
||||
transaction.operation = bytesToHex(log.params.operation.value);
|
||||
checkPendingOperation(api, log, transaction.operation);
|
||||
}
|
||||
|
||||
return transaction;
|
||||
});
|
||||
if (log.params.data) {
|
||||
transaction.data = log.params.data.value;
|
||||
}
|
||||
|
||||
return transaction;
|
||||
})
|
||||
.filter((tx) => tx);
|
||||
|
||||
return transactions;
|
||||
});
|
||||
|
@ -26,7 +26,6 @@ import HardwareStore from '~/mobx/hardwareStore';
|
||||
import ExportStore from '~/modals/ExportAccount/exportStore';
|
||||
import { DeleteAccount, EditMeta, Faucet, PasswordManager, Shapeshift, Transfer, Verification } from '~/modals';
|
||||
import { setVisibleAccounts } from '~/redux/providers/personalActions';
|
||||
import { fetchCertifiers, fetchCertifications } from '~/redux/providers/certifications/actions';
|
||||
import { Actionbar, Button, ConfirmDialog, Input, Page, Portal } from '~/ui';
|
||||
import { DeleteIcon, DialIcon, EditIcon, LockedIcon, SendIcon, VerifyIcon, FileDownloadIcon } from '~/ui/Icons';
|
||||
|
||||
@ -45,8 +44,6 @@ class Account extends Component {
|
||||
|
||||
static propTypes = {
|
||||
accounts: PropTypes.object.isRequired,
|
||||
fetchCertifiers: PropTypes.func.isRequired,
|
||||
fetchCertifications: PropTypes.func.isRequired,
|
||||
setVisibleAccounts: PropTypes.func.isRequired,
|
||||
|
||||
account: PropTypes.object,
|
||||
@ -67,7 +64,6 @@ class Account extends Component {
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.props.fetchCertifiers();
|
||||
this.setVisibleAccounts();
|
||||
}
|
||||
|
||||
@ -90,11 +86,10 @@ class Account extends Component {
|
||||
}
|
||||
|
||||
setVisibleAccounts (props = this.props) {
|
||||
const { params, setVisibleAccounts, fetchCertifications } = props;
|
||||
const { params, setVisibleAccounts } = props;
|
||||
const addresses = [params.address];
|
||||
|
||||
setVisibleAccounts(addresses);
|
||||
fetchCertifications(params.address);
|
||||
}
|
||||
|
||||
render () {
|
||||
@ -370,14 +365,14 @@ class Account extends Component {
|
||||
onDeny={ this.exportClose }
|
||||
title={
|
||||
<FormattedMessage
|
||||
id='export.account.title'
|
||||
id='account.export.title'
|
||||
defaultMessage='Export Account'
|
||||
/>
|
||||
}
|
||||
>
|
||||
<div className={ styles.textbox }>
|
||||
<FormattedMessage
|
||||
id='export.account.info'
|
||||
id='account.export.info'
|
||||
defaultMessage='Export your account as a JSON file. Please enter the password linked with this account.'
|
||||
/>
|
||||
</div>
|
||||
@ -388,13 +383,13 @@ class Account extends Component {
|
||||
type='password'
|
||||
hint={
|
||||
<FormattedMessage
|
||||
id='export.account.password.hint'
|
||||
id='account.export.password.hint'
|
||||
defaultMessage='The password specified when creating this account'
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='export.account.password.label'
|
||||
id='account.export.password.label'
|
||||
defaultMessage='Account password'
|
||||
/>
|
||||
}
|
||||
@ -524,8 +519,6 @@ function mapStateToProps (state, props) {
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({
|
||||
fetchCertifiers,
|
||||
fetchCertifications,
|
||||
newError,
|
||||
setVisibleAccounts
|
||||
}, dispatch);
|
||||
|
@ -14,6 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
@ -34,7 +35,15 @@ function render (props) {
|
||||
/>,
|
||||
{
|
||||
context: {
|
||||
store: createRedux()
|
||||
store: createRedux(),
|
||||
api: {
|
||||
transport: {
|
||||
on: sinon.stub()
|
||||
},
|
||||
pubsub: {
|
||||
subscribeAndGetResult: sinon.stub()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
).find('Account').shallow();
|
||||
|
@ -17,10 +17,8 @@
|
||||
import { pick } from 'lodash';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
|
||||
import { Container, SectionList } from '~/ui';
|
||||
import { fetchCertifiers, fetchCertifications } from '~/redux/providers/certifications/actions';
|
||||
import { ETH_TOKEN } from '~/util/tokens';
|
||||
|
||||
import Summary from '../Summary';
|
||||
@ -38,20 +36,9 @@ class List extends Component {
|
||||
orderFallback: PropTypes.string,
|
||||
search: PropTypes.array,
|
||||
|
||||
fetchCertifiers: PropTypes.func.isRequired,
|
||||
fetchCertifications: PropTypes.func.isRequired,
|
||||
handleAddSearchToken: PropTypes.func
|
||||
};
|
||||
|
||||
componentWillMount () {
|
||||
const { accounts, fetchCertifiers, fetchCertifications } = this.props;
|
||||
|
||||
fetchCertifiers();
|
||||
for (let address in accounts) {
|
||||
fetchCertifications(address);
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { accounts, disabled, empty } = this.props;
|
||||
|
||||
@ -264,14 +251,7 @@ function mapStateToProps (state, props) {
|
||||
return { balances, certifications };
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({
|
||||
fetchCertifiers,
|
||||
fetchCertifications
|
||||
}, dispatch);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
null
|
||||
)(List);
|
||||
|
@ -27,7 +27,11 @@ let instance;
|
||||
let redux;
|
||||
|
||||
function createApi () {
|
||||
api = {};
|
||||
api = {
|
||||
pubsub: {
|
||||
subscribeAndGetResult: sinon.stub().returns(Promise.reject(new Error('uninitialized')))
|
||||
}
|
||||
};
|
||||
|
||||
return api;
|
||||
}
|
||||
|
@ -16,8 +16,7 @@
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { FirstRun, UpgradeParity } from '~/modals';
|
||||
import { Errors, ParityBackground, Tooltips } from '~/ui';
|
||||
import { Errors, ParityBackground } from '~/ui';
|
||||
|
||||
import styles from '../application.css';
|
||||
|
||||
@ -25,24 +24,17 @@ export default class Container extends Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
onCloseFirstRun: PropTypes.func,
|
||||
showFirstRun: PropTypes.bool,
|
||||
upgradeStore: PropTypes.object.isRequired
|
||||
showFirstRun: PropTypes.bool
|
||||
};
|
||||
|
||||
render () {
|
||||
const { children, onCloseFirstRun, showFirstRun, upgradeStore } = this.props;
|
||||
const { children } = this.props;
|
||||
|
||||
return (
|
||||
<ParityBackground
|
||||
attachDocument
|
||||
className={ styles.container }
|
||||
>
|
||||
<FirstRun
|
||||
onClose={ onCloseFirstRun }
|
||||
visible={ showFirstRun }
|
||||
/>
|
||||
<Tooltips />
|
||||
<UpgradeParity store={ upgradeStore } />
|
||||
<Errors />
|
||||
{ children }
|
||||
</ParityBackground>
|
||||
|
@ -15,13 +15,12 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import { Link } from 'react-router';
|
||||
import { Toolbar, ToolbarGroup } from 'material-ui/Toolbar';
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
import { Tooltip, StatusIndicator } from '~/ui';
|
||||
import { StatusIndicator } from '~/ui';
|
||||
|
||||
import Tab from './Tab';
|
||||
import styles from './tabBar.css';
|
||||
@ -66,15 +65,6 @@ class TabBar extends Component {
|
||||
</div>
|
||||
</Link>
|
||||
{ this.renderTabItems() }
|
||||
<Tooltip
|
||||
className={ styles.tabbarTooltip }
|
||||
text={
|
||||
<FormattedMessage
|
||||
id='tabBar.tooltip.overview'
|
||||
defaultMessage='navigate between the different parts and views of the application, switching between an account view, token view and decentralized application view'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<ToolbarGroup className={ styles.last }>
|
||||
<div />
|
||||
|
@ -18,27 +18,14 @@ import { observer } from 'mobx-react';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import UpgradeStore from '~/modals/UpgradeParity/store';
|
||||
|
||||
import Connection from '../Connection';
|
||||
import ParityBar from '../ParityBar';
|
||||
import SyncWarning, { showSyncWarning } from '../SyncWarning';
|
||||
|
||||
import Snackbar from './Snackbar';
|
||||
import Container from './Container';
|
||||
import DappContainer from './DappContainer';
|
||||
import Extension from './Extension';
|
||||
import FrameError from './FrameError';
|
||||
import Status from './Status';
|
||||
import Store from './store';
|
||||
import TabBar from './TabBar';
|
||||
import Requests from './Requests';
|
||||
|
||||
import styles from './application.css';
|
||||
|
||||
const inFrame = window.parent !== window && window.parent.frames.length !== 0;
|
||||
const doShowSyncWarning = showSyncWarning();
|
||||
|
||||
@observer
|
||||
class Application extends Component {
|
||||
static contextTypes = {
|
||||
@ -53,11 +40,9 @@ class Application extends Component {
|
||||
}
|
||||
|
||||
store = new Store(this.context.api);
|
||||
upgradeStore = UpgradeStore.get(this.context.api);
|
||||
|
||||
render () {
|
||||
const [root] = (window.location.hash || '').replace('#/', '').split('/');
|
||||
const isMinimized = root === 'app' || root === 'web';
|
||||
|
||||
if (process.env.NODE_ENV !== 'production' && root === 'playground') {
|
||||
return (
|
||||
@ -69,47 +54,20 @@ class Application extends Component {
|
||||
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
inFrame
|
||||
? <FrameError />
|
||||
: null
|
||||
}
|
||||
{
|
||||
isMinimized
|
||||
? this.renderMinimized()
|
||||
: this.renderApp()
|
||||
}
|
||||
{
|
||||
doShowSyncWarning
|
||||
? (<SyncWarning />)
|
||||
: null
|
||||
}
|
||||
<Connection />
|
||||
<Requests />
|
||||
<ParityBar dapp={ isMinimized } />
|
||||
{ this.renderApp() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderApp () {
|
||||
const { blockNumber, children, pending } = this.props;
|
||||
const { children, pending } = this.props;
|
||||
|
||||
return (
|
||||
<Container
|
||||
upgradeStore={ this.upgradeStore }
|
||||
onCloseFirstRun={ this.store.closeFirstrun }
|
||||
showFirstRun={ this.store.firstrunVisible }
|
||||
>
|
||||
<Container>
|
||||
<TabBar pending={ pending } />
|
||||
<div className={ styles.content }>
|
||||
{ children }
|
||||
</div>
|
||||
{
|
||||
blockNumber
|
||||
? <Status upgradeStore={ this.upgradeStore } />
|
||||
: null
|
||||
}
|
||||
<Extension />
|
||||
<Snackbar />
|
||||
</Container>
|
||||
);
|
||||
|
@ -17,7 +17,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import imagesEthcoreBlock from '~/../assets/images/parity-logo-white-no-text.svg';
|
||||
import { AccountsIcon, AddressesIcon, AppsIcon, ContactsIcon, FingerprintIcon, SettingsIcon } from '~/ui/Icons';
|
||||
import { AccountsIcon, AddressesIcon, ContactsIcon, FingerprintIcon, SettingsIcon } from '~/ui/Icons';
|
||||
|
||||
import styles from './views.css';
|
||||
|
||||
@ -50,13 +50,6 @@ const defaultViews = {
|
||||
value: 'address'
|
||||
},
|
||||
|
||||
apps: {
|
||||
active: true,
|
||||
icon: <AppsIcon />,
|
||||
route: '/apps',
|
||||
value: 'app'
|
||||
},
|
||||
|
||||
contracts: {
|
||||
active: false,
|
||||
onlyPersonal: true,
|
||||
|
@ -91,17 +91,6 @@ class Views extends Component {
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
this.renderView('apps',
|
||||
<FormattedMessage
|
||||
id='settings.views.apps.label'
|
||||
/>,
|
||||
<FormattedMessage
|
||||
id='settings.views.apps.description'
|
||||
defaultMessage='Decentralized applications that interact with the underlying network. Add applications, manage you application portfolio and interact with application from around the network.'
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
this.renderView('contracts',
|
||||
<FormattedMessage
|
||||
|
@ -48,8 +48,9 @@ const entry = isEmbed
|
||||
|
||||
module.exports = {
|
||||
cache: !isProd,
|
||||
devtool: isProd ? '#hidden-source-map' : '#source-map',
|
||||
|
||||
devtool: isProd
|
||||
? false
|
||||
: '#source-map',
|
||||
context: path.join(__dirname, '../src'),
|
||||
entry: entry,
|
||||
output: {
|
||||
@ -67,7 +68,7 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
include: /node_modules\/(material-chip-input|ethereumjs-tx|@parity\/wordlist)/,
|
||||
include: /(material-chip-input|ethereumjs-tx)/,
|
||||
use: 'babel-loader'
|
||||
},
|
||||
{
|
||||
@ -214,6 +215,7 @@ module.exports = {
|
||||
|
||||
new CopyWebpackPlugin([
|
||||
{ from: './error_pages.css', to: 'styles.css' },
|
||||
{ from: './manifest.json', to: 'manifest.json' },
|
||||
{ from: 'dapps/static' }
|
||||
], {})
|
||||
);
|
||||
|
@ -62,7 +62,7 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
include: /node_modules\/(ethereumjs-tx|@parity\/wordlist)/,
|
||||
include: /(ethereumjs-tx|wordlist)/,
|
||||
use: 'babel-loader'
|
||||
},
|
||||
{
|
||||
|
@ -65,7 +65,7 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
include: /node_modules\/(ethereumjs-tx|@parity\/wordlist)/,
|
||||
include: /(ethereumjs-tx|wordlist)/,
|
||||
use: 'babel-loader'
|
||||
}
|
||||
]
|
||||
|
8651
js-old/yarn.lock
8651
js-old/yarn.lock
File diff suppressed because it is too large
Load Diff
3466
js/package-lock.json
generated
3466
js/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Parity",
|
||||
"version": "1.9.5",
|
||||
"version": "1.9.10",
|
||||
"main": "src/index.parity.js",
|
||||
"jsnext:main": "src/index.parity.js",
|
||||
"author": "Parity Team <admin@parity.io>",
|
||||
@ -21,13 +21,13 @@
|
||||
"Parity"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "npm run build:lib && npm run build:app && npm run build:embed",
|
||||
"build:app": "webpack --progress --config webpack/app",
|
||||
"build:lib": "webpack --progress --config webpack/libraries",
|
||||
"build": "npm run build:inject && npm run build:app && npm run build:embed",
|
||||
"build:app": "webpack --config webpack/app",
|
||||
"build:inject": "webpack --config webpack/inject",
|
||||
"build:embed": "cross-env EMBED=1 node webpack/embed",
|
||||
"build:i18n": "npm run clean && npm run build && babel-node ./scripts/build-i18n.js",
|
||||
"ci:build": "cross-env NODE_ENV=production npm run build",
|
||||
"clean": "rimraf ./.build ./.coverage ./.happypack ./build ./node_modules/.cache",
|
||||
"clean": "rimraf ./.build ./.coverage ./.happypack ./build",
|
||||
"coveralls": "npm run testCoverage && coveralls < coverage/lcov.info",
|
||||
"lint": "npm run lint:css && npm run lint:js",
|
||||
"lint:cached": "npm run lint:css && npm run lint:js:cached",
|
||||
@ -37,14 +37,11 @@
|
||||
"lint:js": "eslint --ignore-path .gitignore ./src/",
|
||||
"lint:js:cached": "eslint --cache --ignore-path .gitignore ./src/",
|
||||
"lint:js:fix": "eslint --fix --ignore-path .gitignore ./src/",
|
||||
"start": "npm run clean && npm install && npm run build:lib && npm run start:app",
|
||||
"start": "npm run clean && npm install && npm run build:inject && npm run start:app",
|
||||
"start:app": "node webpack/dev.server",
|
||||
"start:electron": "npm run build:app && electron .build/",
|
||||
"test": "cross-env NODE_ENV=test mocha --compilers ejs:ejsify 'src/**/*.spec.js'",
|
||||
"test:coverage": "cross-env NODE_ENV=test istanbul cover _mocha -- --compilers ejs:ejsify 'src/**/*.spec.js'",
|
||||
"test:e2e": "cross-env NODE_ENV=test mocha 'src/**/*.e2e.js'",
|
||||
"test:npm": "(cd .npmjs && npm i) && node test/npmParity && node test/npmJsonRpc && (rimraf .npmjs/node_modules)",
|
||||
"prepush": "npm run lint:cached"
|
||||
"test:coverage": "cross-env NODE_ENV=test istanbul cover _mocha -- --compilers ejs:ejsify 'src/**/*.spec.js'"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "6.26.0",
|
||||
@ -94,9 +91,7 @@
|
||||
"html-loader": "0.4.4",
|
||||
"html-webpack-plugin": "2.30.1",
|
||||
"http-proxy-middleware": "0.17.3",
|
||||
"husky": "0.13.1",
|
||||
"ignore-styles": "5.0.1",
|
||||
"image-webpack-loader": "3.2.0",
|
||||
"istanbul": "1.0.0-alpha.2",
|
||||
"jsdom": "9.11.0",
|
||||
"json-loader": "0.5.4",
|
||||
@ -135,50 +130,33 @@
|
||||
"yargs": "6.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@parity/abi": "^2",
|
||||
"@parity/api": "^2",
|
||||
"@parity/jsonrpc": "^2",
|
||||
"@parity/etherscan": "^2",
|
||||
"@parity/ledger": "^2",
|
||||
"@parity/shapeshift": "^2",
|
||||
"@parity/shared": "^2",
|
||||
"@parity/ui": "^2",
|
||||
"@parity/plugin-signer-account": "paritytech/plugin-signer-account",
|
||||
"@parity/plugin-signer-default": "paritytech/plugin-signer-default",
|
||||
"@parity/plugin-signer-hardware": "paritytech/plugin-signer-hardware",
|
||||
"@parity/plugin-signer-qr": "paritytech/plugin-signer-qr",
|
||||
"@parity/dapp-account": "paritytech/dapp-account",
|
||||
"@parity/api": "2.1.x",
|
||||
"@parity/dapp-accounts": "paritytech/dapp-accounts",
|
||||
"@parity/dapp-address": "paritytech/dapp-address",
|
||||
"@parity/dapp-addresses": "paritytech/dapp-addresses",
|
||||
"@parity/dapp-chaindeploy": "paritytech/dapp-chaindeploy",
|
||||
"@parity/dapp-contract": "paritytech/dapp-contract",
|
||||
"@parity/dapp-contracts": "paritytech/dapp-contracts",
|
||||
"@parity/dapp-console": "paritytech/dapp-console",
|
||||
"@parity/dapp-dapp-accounts": "paritytech/dapp-dapp-accounts",
|
||||
"@parity/dapp-dapp-methods": "paritytech/dapp-dapp-methods",
|
||||
"@parity/dapp-dapp-visible": "paritytech/dapp-dapp-visible",
|
||||
"@parity/dapp-dappreg": "paritytech/dapp-dappreg",
|
||||
"@parity/dapp-develop": "paritytech/dapp-develop",
|
||||
"@parity/dapp-githubhint": "paritytech/dapp-githubhint",
|
||||
"@parity/dapp-home": "paritytech/dapp-home",
|
||||
"@parity/dapp-localtx": "paritytech/dapp-localtx",
|
||||
"@parity/dapp-playground": "paritytech/dapp-playground",
|
||||
"@parity/dapp-registry": "paritytech/dapp-registry",
|
||||
"@parity/dapp-settings": "paritytech/dapp-settings",
|
||||
"@parity/dapp-signaturereg": "paritytech/dapp-signaturereg",
|
||||
"@parity/dapp-signer": "paritytech/dapp-signer",
|
||||
"@parity/dapp-status": "paritytech/dapp-status",
|
||||
"@parity/dapp-tokendeploy": "paritytech/dapp-tokendeploy",
|
||||
"@parity/dapp-tokenreg": "paritytech/dapp-tokenreg",
|
||||
"@parity/dapp-vaults": "paritytech/dapp-vaults",
|
||||
"@parity/dapp-wallet": "paritytech/dapp-wallet",
|
||||
"@parity/dapp-web": "paritytech/dapp-web",
|
||||
"isomorphic-fetch": "2.2.1",
|
||||
"@parity/plugin-signer-account": "paritytech/plugin-signer-account",
|
||||
"@parity/plugin-signer-default": "paritytech/plugin-signer-default",
|
||||
"@parity/plugin-signer-hardware": "paritytech/plugin-signer-hardware",
|
||||
"@parity/plugin-signer-qr": "paritytech/plugin-signer-qr",
|
||||
"@parity/shared": "2.2.x",
|
||||
"@parity/ui": "2.2.x",
|
||||
"keythereum": "1.0.2",
|
||||
"lodash.flatten": "4.4.0",
|
||||
"lodash.omitby": "4.6.0",
|
||||
"lodash.throttle": "4.1.1",
|
||||
"lodash.uniq": "4.5.0",
|
||||
"oo7": "paritytech/oo7#34fdb5991f4e59b2cf84260cab48cec9a57d88c0",
|
||||
"material-ui": "0.16.5",
|
||||
"prop-types": "15.5.10",
|
||||
"react": "15.6.1",
|
||||
"react-dom": "15.6.1",
|
||||
@ -189,7 +167,6 @@
|
||||
"redux": "3.6.0",
|
||||
"solc": "ngotchac/solc-js",
|
||||
"store": "1.3.20",
|
||||
"web3": "0.17.0-beta",
|
||||
"whatwg-fetch": "2.0.1"
|
||||
"web3": "0.17.0-beta"
|
||||
}
|
||||
}
|
||||
|
48
js/scripts/push-cargo.sh
Executable file
48
js/scripts/push-cargo.sh
Executable file
@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# variables
|
||||
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
|
||||
BRANCH=$CI_BUILD_REF_NAME
|
||||
GIT_PARITY="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/parity.git"
|
||||
GITLOG=./.git/.git-release.log
|
||||
|
||||
# setup the git user defaults for the current repo
|
||||
function setup_git_user {
|
||||
git config push.default simple
|
||||
git config merge.ours.driver true
|
||||
git config user.email "$GITHUB_EMAIL"
|
||||
git config user.name "GitLab Build Bot"
|
||||
}
|
||||
|
||||
echo "*** [cargo] Setting up GitHub config for parity"
|
||||
setup_git_user
|
||||
git remote set-url origin $GIT_PARITY
|
||||
git reset --hard origin/$BRANCH 2>$GITLOG
|
||||
git submodule update
|
||||
|
||||
if [ "$BRANCH" == "master" ]; then
|
||||
cd js
|
||||
|
||||
echo "*** [cargo] Bumping package.json patch version"
|
||||
npm --no-git-tag-version version
|
||||
npm version patch
|
||||
|
||||
cd ..
|
||||
|
||||
git add js
|
||||
fi
|
||||
|
||||
echo "*** [cargo] Updating cargo parity-ui-precompiled"
|
||||
sed -i "/^parity-ui-precompiled/ { s/branch = \".*\"/branch = \"$BRANCH\"/g; }" dapps/ui/Cargo.toml
|
||||
cargo update -p parity-ui-precompiled
|
||||
cargo update -p parity-ui-old-precompiled
|
||||
|
||||
echo "*** [cargo] Committing updated files"
|
||||
git add dapps/ui/Cargo.toml
|
||||
git add Cargo.lock
|
||||
git commit -m "[ci skip] js-precompiled $UTCDATE"
|
||||
git push origin HEAD:refs/heads/$BRANCH 2>$GITLOG
|
||||
|
||||
# exit with exit code
|
||||
exit 0
|
52
js/scripts/push-precompiled.sh
Executable file
52
js/scripts/push-precompiled.sh
Executable file
@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# variables
|
||||
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
|
||||
BRANCH=$CI_BUILD_REF_NAME
|
||||
GIT_JS_PRECOMPILED="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/js-precompiled.git"
|
||||
BASEDIR=`dirname $0`
|
||||
GITLOG=./.git/.git-release.log
|
||||
|
||||
# setup the git user defaults for the current repo
|
||||
function setup_git_user {
|
||||
git config push.default simple
|
||||
git config merge.ours.driver true
|
||||
git config user.email "$GITHUB_EMAIL"
|
||||
git config user.name "GitLab Build Bot"
|
||||
}
|
||||
|
||||
# change into the build directory
|
||||
pushd $BASEDIR
|
||||
cd ../.dist
|
||||
|
||||
# add local files and send it up
|
||||
echo "*** [v2 precompiled] Setting up GitHub config"
|
||||
rm -rf ./.git
|
||||
git init
|
||||
setup_git_user
|
||||
|
||||
echo "*** [v2 precompiled] Checking out $BRANCH branch"
|
||||
git remote add origin $GIT_JS_PRECOMPILED
|
||||
git fetch origin 2>$GITLOG
|
||||
git checkout -b $BRANCH
|
||||
|
||||
echo "*** [v2 precompiled] Committing compiled files for $UTCDATE"
|
||||
mv build ../build.new
|
||||
git add .
|
||||
git commit -m "$UTCDATE [update]"
|
||||
git merge origin/$BRANCH -X ours --commit -m "$UTCDATE [merge]"
|
||||
git rm -r build
|
||||
rm -rf build
|
||||
git commit -m "$UTCDATE [cleanup]"
|
||||
mv ../build.new build
|
||||
git add .
|
||||
git commit -m "$UTCDATE [release]"
|
||||
|
||||
echo "*** [v2 precompiled] Merging remote"
|
||||
git push origin HEAD:refs/heads/$BRANCH 2>$GITLOG
|
||||
|
||||
popd
|
||||
|
||||
# exit with exit code
|
||||
exit 0
|
@ -1,103 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# variables
|
||||
UTCDATE=`date -u "+%Y%m%d-%H%M%S"`
|
||||
PACKAGES=()
|
||||
BRANCH=$CI_BUILD_REF_NAME
|
||||
GIT_JS_PRECOMPILED="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/js-precompiled.git"
|
||||
GIT_PARITY="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/parity.git"
|
||||
|
||||
# setup the git user defaults for the current repo
|
||||
function setup_git_user {
|
||||
git config push.default simple
|
||||
git config merge.ours.driver true
|
||||
git config user.email "$GITHUB_EMAIL"
|
||||
git config user.name "GitLab Build Bot"
|
||||
}
|
||||
|
||||
# change into the build directory
|
||||
BASEDIR=`dirname $0`
|
||||
GITLOG=./.git/gitcommand.log
|
||||
pushd $BASEDIR
|
||||
cd ../.dist
|
||||
|
||||
# add local files and send it up
|
||||
echo "*** Setting up GitHub config for js-precompiled"
|
||||
rm -rf ./.git
|
||||
git init
|
||||
setup_git_user
|
||||
|
||||
echo "*** Checking out $BRANCH branch"
|
||||
git remote add origin $GIT_JS_PRECOMPILED
|
||||
git fetch origin 2>$GITLOG
|
||||
git checkout -b $BRANCH
|
||||
|
||||
echo "*** Committing compiled files for $UTCDATE"
|
||||
mv build ../build.new
|
||||
git add .
|
||||
git commit -m "$UTCDATE [update]"
|
||||
git merge origin/$BRANCH -X ours --commit -m "$UTCDATE [merge]"
|
||||
git rm -r build
|
||||
rm -rf build
|
||||
git commit -m "$UTCDATE [cleanup]"
|
||||
mv ../build.new build
|
||||
git add .
|
||||
git commit -m "$UTCDATE [release]"
|
||||
|
||||
echo "*** Merging remote"
|
||||
git push origin HEAD:refs/heads/$BRANCH 2>$GITLOG
|
||||
PRECOMPILED_HASH=`git rev-parse HEAD`
|
||||
|
||||
# move to root
|
||||
cd ../..
|
||||
|
||||
echo "*** Setting up GitHub config for parity"
|
||||
setup_git_user
|
||||
git remote set-url origin $GIT_PARITY
|
||||
git reset --hard origin/$BRANCH 2>$GITLOG
|
||||
|
||||
if [ "$BRANCH" == "master" ]; then
|
||||
cd js
|
||||
|
||||
echo "*** Bumping package.json patch version"
|
||||
npm --no-git-tag-version version
|
||||
npm version patch
|
||||
|
||||
echo "*** Building packages for npmjs"
|
||||
echo "$NPM_TOKEN" >> ~/.npmrc
|
||||
|
||||
for PACKAGE in ${PACKAGES[@]}
|
||||
do
|
||||
echo "*** Building $PACKAGE"
|
||||
LIBRARY=$PACKAGE npm run ci:build:npm
|
||||
DIRECTORY=.npmjs/$PACKAGE
|
||||
|
||||
echo "*** Publishing $PACKAGE from $DIRECTORY"
|
||||
cd $DIRECTORY
|
||||
npm publish --access public || true
|
||||
cd ../..
|
||||
done
|
||||
|
||||
cd ..
|
||||
fi
|
||||
|
||||
echo "*** Updating cargo parity-ui-precompiled#$PRECOMPILED_HASH"
|
||||
git submodule update
|
||||
sed -i "/^parity-ui-precompiled/ { s/branch = \".*\"/branch = \"$BRANCH\"/g; }" dapps/ui/Cargo.toml
|
||||
cargo update -p parity-ui-precompiled
|
||||
# --precise "$PRECOMPILED_HASH"
|
||||
|
||||
echo "*** Committing updated files"
|
||||
git add js
|
||||
git add dapps/ui/Cargo.toml
|
||||
git add Cargo.lock
|
||||
git commit -m "[ci skip] js-precompiled $UTCDATE"
|
||||
git push origin HEAD:refs/heads/$BRANCH 2>$GITLOG
|
||||
|
||||
# back to root
|
||||
echo "*** Release completed"
|
||||
popd
|
||||
|
||||
# exit with exit code
|
||||
exit 0
|
@ -1 +1 @@
|
||||
// test script 14
|
||||
// test script 19
|
||||
|
@ -20,9 +20,9 @@ import { FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import HardwareStore from '@parity/shared/mobx/hardwareStore';
|
||||
import UpgradeStore from '@parity/shared/mobx/upgradeParity';
|
||||
import Errors from '@parity/ui/Errors';
|
||||
import HardwareStore from '@parity/shared/lib/mobx/hardwareStore';
|
||||
import UpgradeStore from '@parity/shared/lib/mobx/upgradeParity';
|
||||
import Errors from '@parity/ui/lib/Errors';
|
||||
|
||||
import Connection from '../Connection';
|
||||
import DappRequests from '../DappRequests';
|
||||
@ -145,11 +145,9 @@ class Application extends Component {
|
||||
|
||||
function mapStateToProps (state) {
|
||||
const { blockNumber } = state.nodeStatus;
|
||||
const { hasAccounts } = state.personal;
|
||||
|
||||
return {
|
||||
blockNumber,
|
||||
hasAccounts
|
||||
blockNumber
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -19,9 +19,9 @@ import { FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import GradientBg from '@parity/ui/GradientBg';
|
||||
import Input from '@parity/ui/Form/Input';
|
||||
import { CompareIcon, ComputerIcon, DashboardIcon, VpnIcon } from '@parity/ui/Icons';
|
||||
import GradientBg from '@parity/ui/lib/GradientBg';
|
||||
import Input from '@parity/ui/lib/Form/Input';
|
||||
import { CompareIcon, ComputerIcon, DashboardIcon, VpnIcon } from '@parity/ui/lib/Icons';
|
||||
|
||||
import styles from './connection.css';
|
||||
|
||||
|
@ -20,11 +20,10 @@ import { FormattedMessage } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Api from '@parity/api';
|
||||
import builtinDapps from '@parity/shared/config/dappsBuiltin.json';
|
||||
import viewsDapps from '@parity/shared/config/dappsViews.json';
|
||||
import DappsStore from '@parity/shared/mobx/dappsStore';
|
||||
import HistoryStore from '@parity/shared/mobx/historyStore';
|
||||
// import { Bond } from 'oo7';
|
||||
import builtinDapps from '@parity/shared/lib/config/dappsBuiltin.json';
|
||||
import viewsDapps from '@parity/shared/lib/config/dappsViews.json';
|
||||
import DappsStore from '@parity/shared/lib/mobx/dappsStore';
|
||||
import HistoryStore from '@parity/shared/lib/mobx/historyStore';
|
||||
|
||||
import styles from './dapp.css';
|
||||
|
||||
@ -163,6 +162,5 @@ export default class Dapp extends Component {
|
||||
const frame = document.getElementById('dappFrame');
|
||||
|
||||
frame.style.opacity = 1;
|
||||
// frame.contentWindow.injectedBondCache = Bond.cache;
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import Button from '@parity/ui/Button';
|
||||
import Button from '@parity/ui/lib/Button';
|
||||
|
||||
import DappsStore from '@parity/shared/mobx/dappsStore';
|
||||
import DappsStore from '@parity/shared/lib/mobx/dappsStore';
|
||||
|
||||
export default function Request ({ appId, className, approveRequest, denyRequest, queueId, request: { from, method } }) {
|
||||
const _onApprove = () => approveRequest(queueId, false);
|
||||
|
@ -23,8 +23,8 @@ $backgroundTwo: #e57a00;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 2.75em;
|
||||
z-index: 760; /* sits above requests */
|
||||
bottom: 0;
|
||||
z-index: 1001; /* sits above sync warning */
|
||||
|
||||
.request {
|
||||
align-items: center;
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { action, computed, observable } from 'mobx';
|
||||
import store from 'store';
|
||||
|
||||
import { sha3 } from '@parity/api/util/sha3';
|
||||
import { sha3 } from '@parity/api/lib/util/sha3';
|
||||
|
||||
import filteredRequests from './filteredRequests';
|
||||
|
||||
|
@ -21,12 +21,12 @@ import { FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import DappCard from '@parity/ui/DappCard';
|
||||
import Checkbox from '@parity/ui/Form/Checkbox';
|
||||
import Page from '@parity/ui/Page';
|
||||
import SectionList from '@parity/ui/SectionList';
|
||||
import DappCard from '@parity/ui/lib/DappCard';
|
||||
import Checkbox from '@parity/ui/lib/Form/Checkbox';
|
||||
import Page from '@parity/ui/lib/Page';
|
||||
import SectionList from '@parity/ui/lib/SectionList';
|
||||
|
||||
import DappsStore from '@parity/shared/mobx/dappsStore';
|
||||
import DappsStore from '@parity/shared/lib/mobx/dappsStore';
|
||||
|
||||
import styles from './dapps.css';
|
||||
|
||||
@ -85,8 +85,8 @@ class Dapps extends Component {
|
||||
/>
|
||||
}
|
||||
>
|
||||
{ this.renderList(this.store.visibleViews) }
|
||||
{ this.renderList(this.store.visibleLocal) }
|
||||
{ this.renderList(this.store.visibleViews) }
|
||||
{ this.renderList(this.store.visibleBuiltin) }
|
||||
{ this.renderList(this.store.visibleNetwork, externalOverlay) }
|
||||
</Page>
|
||||
|
@ -18,10 +18,10 @@ import { observer } from 'mobx-react';
|
||||
import React, { Component } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import Button from '@parity/ui/Button';
|
||||
import { CloseIcon, CheckIcon } from '@parity/ui/Icons';
|
||||
import Button from '@parity/ui/lib/Button';
|
||||
import { CloseIcon, CheckIcon } from '@parity/ui/lib/Icons';
|
||||
|
||||
import Store from '@parity/shared/mobx/extensionStore';
|
||||
import Store from '@parity/shared/lib/mobx/extensionStore';
|
||||
import styles from './extension.css';
|
||||
|
||||
@observer
|
||||
|
@ -19,7 +19,7 @@ import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
|
||||
import Checkbox from '@parity/ui/Form/Checkbox';
|
||||
import Checkbox from '@parity/ui/lib/Form/Checkbox';
|
||||
|
||||
import styles from '../firstRun.css';
|
||||
|
||||
|
@ -21,11 +21,11 @@ import { FormattedMessage } from 'react-intl';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
|
||||
import { createIdentityImg } from '@parity/api/util/identity';
|
||||
import { newError } from '@parity/shared/redux/actions';
|
||||
import Button from '@parity/ui/Button';
|
||||
import Portal from '@parity/ui/Portal';
|
||||
import { CheckIcon, DoneIcon, NextIcon, PrintIcon, ReplayIcon } from '@parity/ui/Icons';
|
||||
import { createIdentityImg } from '@parity/api/lib/util/identity';
|
||||
import { newError } from '@parity/shared/lib/redux/actions';
|
||||
import Button from '@parity/ui/lib/Button';
|
||||
import Portal from '@parity/ui/lib/Portal';
|
||||
import { CheckIcon, DoneIcon, NextIcon, PrintIcon, ReplayIcon } from '@parity/ui/lib/Icons';
|
||||
|
||||
import ParityLogo from '@parity/shared/assets/images/parity-logo-black-no-text.svg';
|
||||
import { NewAccount, AccountDetails } from '@parity/dapp-accounts/src/CreateAccount';
|
||||
|
@ -189,9 +189,9 @@ $modalZ: 10001;
|
||||
}
|
||||
|
||||
.header {
|
||||
/* height: 2em; */
|
||||
padding: 0.5em 1em;
|
||||
border-radius: 4px 4px 0 0;
|
||||
margin-bottom: 0;
|
||||
padding: 0.5em 1em;
|
||||
|
||||
&::after {
|
||||
clear: both;
|
||||
|
@ -24,16 +24,16 @@ import { Link } from 'react-router';
|
||||
import { connect } from 'react-redux';
|
||||
import store from 'store';
|
||||
|
||||
import AccountCard from '@parity/ui/AccountCard';
|
||||
import Button from '@parity/ui/Button';
|
||||
import ContainerTitle from '@parity/ui/Container/Title';
|
||||
import IdentityIcon from '@parity/ui/IdentityIcon';
|
||||
import GradientBg from '@parity/ui/GradientBg';
|
||||
import SelectionList from '@parity/ui/SelectionList';
|
||||
import SignerPending from '@parity/ui/SignerPending';
|
||||
import { CancelIcon } from '@parity/ui/Icons';
|
||||
import AccountCard from '@parity/ui/lib/AccountCard';
|
||||
import Button from '@parity/ui/lib/Button';
|
||||
import ContainerTitle from '@parity/ui/lib/Container/Title';
|
||||
import IdentityIcon from '@parity/ui/lib/IdentityIcon';
|
||||
import GradientBg from '@parity/ui/lib/GradientBg';
|
||||
import SelectionList from '@parity/ui/lib/SelectionList';
|
||||
import SignerPending from '@parity/ui/lib/SignerPending';
|
||||
import { CancelIcon } from '@parity/ui/lib/Icons';
|
||||
|
||||
import DappsStore from '@parity/shared/mobx/dappsStore';
|
||||
import DappsStore from '@parity/shared/lib/mobx/dappsStore';
|
||||
import Signer from '../Signer/Embedded';
|
||||
|
||||
import AccountStore from './accountStore';
|
||||
|
@ -18,7 +18,7 @@ import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import GradientBg from '@parity/ui/GradientBg';
|
||||
import GradientBg from '@parity/ui/lib/GradientBg';
|
||||
|
||||
import styles from './pinMatrix.css';
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user