Compare commits

...

25 Commits

Author SHA1 Message Date
pierre 0f795feaef feat(wallet): add generic dialog component 2022-07-04 19:45:36 +02:00
pierre 8f18af232d feat(wallet): add generic dialog component 2022-07-04 19:35:56 +02:00
pierre be6172d622 feat(wallet): add generic dialog component 2022-07-04 19:33:02 +02:00
pierre 2e7d773128 feat(wallet): add generic dialog component 2022-07-04 19:25:03 +02:00
Jon Häggblad 06b823f4c1 connect: catch panics during init 2022-07-04 17:19:41 +02:00
Jon Häggblad 1c0ce9a420 Merge pull request #1429 from nymtech/jon/feat/nym-connect-disconnect-signalling
nym-connect: disconnect signalling
2022-07-04 16:46:37 +02:00
Jon Häggblad dede8899cf cargo: exclude nym-connect from top-level workspace 2022-07-04 15:51:09 +02:00
Jon Häggblad 70f6059ceb connect: handle disconnect signalling 2022-07-04 15:51:09 +02:00
Jon Häggblad fefd2dd267 Merge pull request #1427 from nymtech/feature/nym-connect-directory
nym-connect: add ability to select service provider and gateway
2022-07-04 15:50:17 +02:00
Jon Häggblad 0fbe77d934 connect: clippy 2022-07-04 15:23:14 +02:00
Tommy Verrall 8a267cfe3d Merge pull request #1426 from nymtech/tommy/add-placeholder-qa
Add placeholders to service
2022-07-04 14:10:06 +01:00
Jon Häggblad 5ebb2a3efe changelog: add note 2022-07-04 15:06:23 +02:00
Jon Häggblad de605dc3b9 connect: append gateway to id 2022-07-04 15:00:31 +02:00
Mark Sinclair 6a01edf5fe Nym Connect: fetch list of services from wellknown location and let the user choose 2022-07-04 15:00:31 +02:00
tommy 806b37bd83 Add placeholders to service
Update the all.rs to allow all envs
Placing placeholder addresses only
2022-07-04 13:40:22 +02:00
Jędrzej Stuczyński ffff596d45 Removed redundant lock file on explorer api (#1424) 2022-07-04 09:47:38 +01:00
dependabot[bot] ad826da782 build(deps): bump got from 11.8.2 to 11.8.5 in /nym-wallet/webdriver (#1394)
Bumps [got](https://github.com/sindresorhus/got) from 11.8.2 to 11.8.5.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v11.8.2...v11.8.5)

---
updated-dependencies:
- dependency-name: got
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-04 09:45:31 +01:00
dependabot[bot] 3414eeea7a build(deps): bump protobufjs from 6.10.2 to 6.10.3 in /clients/validator (#1407)
Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 6.10.2 to 6.10.3.
- [Release notes](https://github.com/protobufjs/protobuf.js/releases)
- [Changelog](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/protobufjs/protobuf.js/commits)

---
updated-dependencies:
- dependency-name: protobufjs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-04 09:45:10 +01:00
dependabot[bot] 3a32d34fb4 build(deps): bump protobufjs (#1408)
Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 6.10.2 to 6.10.3.
- [Release notes](https://github.com/protobufjs/protobuf.js/releases)
- [Changelog](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/protobufjs/protobuf.js/commits)

---
updated-dependencies:
- dependency-name: protobufjs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-04 09:45:04 +01:00
dependabot[bot] 248052aec7 build(deps): bump protobufjs from 6.10.2 to 6.10.3 in /testnet-faucet (#1409)
Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 6.10.2 to 6.10.3.
- [Release notes](https://github.com/protobufjs/protobuf.js/releases)
- [Changelog](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/protobufjs/protobuf.js/commits)

---
updated-dependencies:
- dependency-name: protobufjs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-04 09:44:58 +01:00
dependabot[bot] 90c00fc343 build(deps): bump protobufjs from 6.10.2 to 6.10.3 (#1410)
Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 6.10.2 to 6.10.3.
- [Release notes](https://github.com/protobufjs/protobuf.js/releases)
- [Changelog](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/protobufjs/protobuf.js/commits)

---
updated-dependencies:
- dependency-name: protobufjs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-04 09:44:51 +01:00
Tommy Verrall 7bdfbfdcc5 Merge pull request #1384 from Tonycrypto44/Tonycrypto44-patch-1
Update README.md
2022-07-04 09:15:06 +01:00
Jon Häggblad 44e22b74a5 all: fix more clippy::derive-partial-eq-without-eq (#1423) 2022-07-03 23:37:25 +02:00
Jon Häggblad 7920c27648 nym-connect: Cargo.lock (#1422) 2022-07-03 19:34:13 +02:00
Tonycrypto44 f02f914ae2 Update README.md 2022-06-19 19:10:27 -04:00
48 changed files with 775 additions and 2652 deletions
+2
View File
@@ -9,6 +9,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- socks5 client/websocket client: add `--force-register-gateway` flag, useful when rerunning init ([#1353])
- nym-connect: initial proof-of-concept of a UI around the socks5 client was added
- nym-connect: add ability to select network requester and gateway ([#1427]).
- all: added network compilation target to `--help` (or `--version`) commands ([#1256]).
- explorer-api: learned how to sum the delegations by owner in a new endpoint.
- explorer-api: add apy values to `mix_nodes` endpoint
@@ -63,6 +64,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
[#1388]: https://github.com/nymtech/nym/pull/1388
[#1393]: https://github.com/nymtech/nym/pull/1393
[#1404]: https://github.com/nymtech/nym/pull/1404
[#1427]: https://github.com/nymtech/nym/pull/1427
## [nym-contracts-v1.0.1](https://github.com/nymtech/nym/tree/nym-contracts-v1.0.1) (2022-06-22)
+1 -1
View File
@@ -81,4 +81,4 @@ default-members = [
"explorer-api",
]
exclude = ["explorer", "contracts", "tokenomics-py", "clients/webassembly", "nym-wallet"]
exclude = ["explorer", "contracts", "tokenomics-py", "clients/webassembly", "nym-wallet", "nym-connect"]
+2 -2
View File
@@ -9,8 +9,8 @@ The platform is composed of multiple Rust crates. Top-level executable binary cr
* nym-mixnode - shuffles [Sphinx](https://github.com/nymtech/sphinx) packets together to provide privacy against network-level attackers.
* nym-client - an executable which you can build into your own applications. Use it for interacting with Nym nodes.
* nym-socks5-client - a Socks5 proxy you can run on your machine, and use with existing applications
* nym-gateway - acts sort of like a mailbox for mixnet messages, removing the need for directly delivery to potentially offline or firewalled devices.
* nym-socks5-client - a Socks5 proxy you can run on your machine and use with existing applications.
* nym-gateway - acts sort of like a mailbox for mixnet messages, which removes the need for direct delivery to potentially offline or firewalled devices.
* nym-network-monitor - sends packets through the full system to check that they are working as expected, and stores node uptime histories as the basis of a rewards system ("mixmining" or "proof-of-mixing").
* nym-explorer - a (projected) block explorer and (existing) mixnet viewer.
* nym-wallet - a desktop wallet implemented using the [Tauri](https://tauri.studio/en/docs/about/intro) framework.
+14 -14
View File
@@ -221,7 +221,7 @@
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78=
integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==
"@protobufjs/base64@^1.1.2":
version "1.1.2"
@@ -236,12 +236,12 @@
"@protobufjs/eventemitter@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A=
integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==
"@protobufjs/fetch@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=
integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==
dependencies:
"@protobufjs/aspromise" "^1.1.1"
"@protobufjs/inquire" "^1.1.0"
@@ -249,27 +249,27 @@
"@protobufjs/float@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=
integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==
"@protobufjs/inquire@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=
integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==
"@protobufjs/path@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=
integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==
"@protobufjs/pool@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=
integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==
"@protobufjs/utf8@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
"@types/json-schema@^7.0.9":
version "7.0.11"
@@ -282,9 +282,9 @@
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
"@types/long@^4.0.1":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
version "4.0.2"
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a"
integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==
"@types/node@>=13.7.0":
version "17.0.23"
@@ -1642,9 +1642,9 @@ protobufjs@^6.8.8, protobufjs@~6.11.2:
long "^4.0.0"
protobufjs@~6.10.2:
version "6.10.2"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.2.tgz#b9cb6bd8ec8f87514592ba3fdfd28e93f33a469b"
integrity sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==
version "6.10.3"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.3.tgz#11ed1dd02acbfcb330becf1611461d4b407f9eef"
integrity sha512-yvAslS0hNdBhlSKckI4R1l7wunVilX66uvrjzE4MimiAt7/qw1nLpMhZrn/ObuUTM/c3Xnfl01LYMdcSJe6dwg==
dependencies:
"@protobufjs/aspromise" "^1.1.2"
"@protobufjs/base64" "^1.1.2"
+1 -1
View File
@@ -15,7 +15,7 @@ use std::ops::Neg;
use zeroize::Zeroize;
#[derive(Debug)]
#[cfg_attr(test, derive(Clone, PartialEq))]
#[cfg_attr(test, derive(Clone, PartialEq, Eq))]
pub struct Ciphertexts {
pub rr: [G1Projective; NUM_CHUNKS],
pub ss: [G1Projective; NUM_CHUNKS],
+1 -1
View File
@@ -345,7 +345,7 @@ impl PublicKey {
}
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq))]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct PublicKeyWithProof {
pub(crate) key: PublicKey,
pub(crate) proof: ProofOfDiscreteLog,
+1 -1
View File
@@ -68,7 +68,7 @@ impl<'a> Instance<'a> {
}
#[derive(Debug)]
#[cfg_attr(test, derive(Clone, PartialEq))]
#[cfg_attr(test, derive(Clone, PartialEq, Eq))]
pub struct ProofOfChunking {
y0: G1Projective,
bb: Vec<G1Projective>,
@@ -14,7 +14,7 @@ const DISCRETE_LOG_DOMAIN: &[u8] =
b"NYM_COCONUT_NIDKG_V01_CS01_WITH_BLS12381_XMD:SHA-256_SSWU_RO_PROOF_DISCRETE_LOG";
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq))]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct ProofOfDiscreteLog {
pub(crate) rand_commitment: G1Projective,
pub(crate) response: Scalar,
+1 -1
View File
@@ -77,7 +77,7 @@ impl<'a> Instance<'a> {
}
#[derive(Debug)]
#[cfg_attr(test, derive(Clone, PartialEq))]
#[cfg_attr(test, derive(Clone, PartialEq, Eq))]
pub struct ProofOfSecretSharing {
ff: G1Projective,
aa: G2Projective,
+1 -1
View File
@@ -18,7 +18,7 @@ use std::collections::BTreeMap;
use zeroize::Zeroize;
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq))]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct Dealing {
pub public_coefficients: PublicCoefficients,
pub ciphertexts: Ciphertexts,
+4 -2
View File
@@ -100,8 +100,10 @@ impl Network {
pub fn statistics_service_url(&self) -> &str {
match self {
Network::MAINNET => crate::mainnet::STATISTICS_SERVICE_DOMAIN_ADDRESS,
_ => {
panic!("statistics service url is only available for mainnet!")
Network::SANDBOX => crate::mainnet::STATISTICS_SERVICE_DOMAIN_ADDRESS,
Network::QA => crate::mainnet::STATISTICS_SERVICE_DOMAIN_ADDRESS,
Network::CUSTOM { .. } => {
panic!("statistics service url is unavailable for a custom network")
}
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ pub(crate) const _ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] =
hex_literal::hex!("0000000000000000000000000000000000000000");
pub(crate) const REWARDING_VALIDATOR_ADDRESS: &str = "n1tfzd4qz3a45u8p4mr5zmzv66457uwjgcl05jdq";
pub(crate) const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "";
pub(crate) const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "http://0.0.0.0";
pub(crate) fn validators() -> Vec<ValidatorDetails> {
vec![ValidatorDetails::new(
"https://qa-validator.nymtech.net",
+1 -1
View File
@@ -21,7 +21,7 @@ pub(crate) const _ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] =
hex_literal::hex!("E8883BAeF3869e14E4823F46662e81D4F7d2A81F");
pub(crate) const REWARDING_VALIDATOR_ADDRESS: &str = "nymt1jh0s6qu6tuw9ut438836mmn7f3f2wencrnmdj4";
pub(crate) const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "";
pub(crate) const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "http://0.0.0.0";
pub(crate) fn validators() -> Vec<ValidatorDetails> {
vec![ValidatorDetails::new(
"https://sandbox-validator.nymtech.net",
+3 -3
View File
@@ -20,7 +20,7 @@ pub type EphemeralKey = Scalar;
/// Two G1 points representing ElGamal ciphertext
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq))]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct Ciphertext(pub(crate) G1Projective, pub(crate) G1Projective);
impl TryFrom<&[u8]> for Ciphertext {
@@ -73,7 +73,7 @@ impl Ciphertext {
/// PrivateKey used in the ElGamal encryption scheme to recover the plaintext
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq))]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct PrivateKey(pub(crate) Scalar);
impl PrivateKey {
@@ -121,7 +121,7 @@ impl Base58 for PrivateKey {}
// TODO: perhaps be more explicit and apart from gamma also store generator and group order?
/// PublicKey used in the ElGamal encryption scheme to produce the ciphertext
#[derive(Debug, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct PublicKey(G1Projective);
impl PublicKey {
+1 -1
View File
@@ -23,7 +23,7 @@ use crate::Attribute;
type ChallengeDigest = Sha256;
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq))]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct ProofCmCs {
challenge: Scalar,
response_opening: Scalar,
+1 -1
View File
@@ -25,7 +25,7 @@ use crate::utils::{hash_g1, try_deserialize_g1_projective};
// TODO NAMING: double check this one
// Lambda
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq))]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct BlindSignRequest {
// cm
commitment: G1Projective,
+2 -2
View File
@@ -23,7 +23,7 @@ use crate::utils::{
use crate::Base58;
#[derive(Debug, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct SecretKey {
pub(crate) x: Scalar,
pub(crate) ys: Vec<Scalar>,
@@ -351,7 +351,7 @@ impl Bytable for VerificationKey {
impl Base58 for VerificationKey {}
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(test, derive(PartialEq))]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct KeyPair {
secret_key: SecretKey,
verification_key: VerificationKey,
+1 -1
View File
@@ -103,7 +103,7 @@ impl Bytable for Signature {
impl Base58 for Signature {}
#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq))]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub struct BlindedSignature(G1Projective, G1Projective);
impl Bytable for BlindedSignature {
+6 -6
View File
@@ -1480,9 +1480,9 @@
}
},
"node_modules/protobufjs": {
"version": "6.10.2",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz",
"integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==",
"version": "6.10.3",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.3.tgz",
"integrity": "sha512-yvAslS0hNdBhlSKckI4R1l7wunVilX66uvrjzE4MimiAt7/qw1nLpMhZrn/ObuUTM/c3Xnfl01LYMdcSJe6dwg==",
"hasInstallScript": true,
"dependencies": {
"@protobufjs/aspromise": "^1.1.2",
@@ -3162,9 +3162,9 @@
"dev": true
},
"protobufjs": {
"version": "6.10.2",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz",
"integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==",
"version": "6.10.3",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.3.tgz",
"integrity": "sha512-yvAslS0hNdBhlSKckI4R1l7wunVilX66uvrjzE4MimiAt7/qw1nLpMhZrn/ObuUTM/c3Xnfl01LYMdcSJe6dwg==",
"requires": {
"@protobufjs/aspromise": "^1.1.2",
"@protobufjs/base64": "^1.1.2",
-2438
View File
File diff suppressed because it is too large Load Diff
+4 -12
View File
@@ -590,7 +590,7 @@ version = "1.0.1"
dependencies = [
"config",
"crypto",
"dirs 3.0.2",
"dirs",
"futures",
"gateway-client",
"gateway-requests",
@@ -1295,15 +1295,6 @@ dependencies = [
"subtle 2.4.1",
]
[[package]]
name = "dirs"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs"
version = "4.0.0"
@@ -3386,7 +3377,7 @@ dependencies = [
"bip39",
"client-core",
"config",
"dirs 4.0.0",
"dirs",
"eyre",
"fix-path-env",
"futures",
@@ -3394,6 +3385,7 @@ dependencies = [
"nym-socks5-client",
"pretty_env_logger",
"rand 0.7.3",
"reqwest",
"serde",
"serde_json",
"tauri",
@@ -3418,7 +3410,7 @@ dependencies = [
"config",
"credential-storage",
"crypto",
"dirs 3.0.2",
"dirs",
"dotenv",
"futures",
"gateway-client",
+2 -1
View File
@@ -30,11 +30,12 @@ serde_json = "1.0"
tauri = { version = "=1.0.0-rc.8", features = ["ayatana-tray", "shell-open", "system-tray"] }
tendermint-rpc = "0.23.0"
thiserror = "1.0"
tokio = { version = "1.19.1", features = ["sync"] }
tokio = { version = "1.19.1", features = ["sync", "time"] }
url = "2.2"
log = "0.4"
pretty_env_logger = "0.4.0"
fix-path-env = { git = "https://github.com/tauri-apps/fix-path-env-rs", branch = "release"}
reqwest = { version = "0.11", features = ["json"] }
client-core = { path = "../../clients/client-core" }
config = { path = "../../common/config" }
+60 -22
View File
@@ -2,31 +2,52 @@ use std::path::PathBuf;
use client_core::config::GatewayEndpoint;
use log::info;
use std::sync::Arc;
use tokio::sync::RwLock;
use client_core::config::Config as BaseConfig;
use config::NymConfig;
use nym_socks5::client::config::Config as Socks5Config;
pub static SOCKS5_CONFIG_ID: &str = "nym-connect";
use crate::{error::BackendError, state::State};
// This is an open-proxy network-requester for testing
// TODO: make this configurable from the UI
// TODO: once we can set this is the UI, consider just removing it, and put in guards to halt if
// user hasn't chosen the provider
pub static PROVIDER_ADDRESS: &str = "8CrdmK4mYgZ5caMxGU4AvNeT1dXL8VSbgMYAjSFvnfut.2GLdZ1Jn9vkTBMf858evGNGDsPoeivUPw7zFNceLiLX3@BNjYZPxzcJwczXHHgBxCAyVJKxN6LPteDRrKapxWmexv";
pub static SOCKS5_CONFIG_ID: &str = "nym-connect";
const DEFAULT_ETH_ENDPOINT: &str = "https://rinkeby.infura.io/v3/00000000000000000000000000000000";
const DEFAULT_ETH_PRIVATE_KEY: &str =
"0000000000000000000000000000000000000000000000000000000000000001";
#[tauri::command]
pub fn get_config_file_location() -> String {
let id: &str = SOCKS5_CONFIG_ID;
Config::config_file_location(id)
.to_string_lossy()
.to_string()
pub fn append_config_id(gateway_id: &str) -> String {
use std::fmt::Write as _;
let mut id = SOCKS5_CONFIG_ID.to_string();
write!(id, "-{}", gateway_id).expect("Failed to set config id");
id
}
#[tauri::command]
pub async fn get_config_id(
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<String, BackendError> {
let guard = state.read().await;
// TODO: return error instead
let gateway_id = guard
.get_gateway()
.as_ref()
.expect("The config id can not be determined before setting the gateway");
Ok(append_config_id(gateway_id))
}
#[tauri::command]
pub async fn get_config_file_location(
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<String, BackendError> {
let id = get_config_id(state).await?;
Ok(Config::config_file_location(&id)
.to_string_lossy()
.to_string())
}
#[derive(Debug)]
pub struct Config {
socks5: Socks5Config,
}
@@ -55,12 +76,22 @@ impl Config {
self.socks5.get_base_mut()
}
pub async fn init(service_provider: Option<&String>, chosen_gateway_id: Option<&String>) {
let service_provider = service_provider.map_or(PROVIDER_ADDRESS, String::as_str);
let chosen_gateway_id = chosen_gateway_id.map(String::as_str);
pub async fn init(service_provider: &str, chosen_gateway_id: &str) -> Result<(), BackendError> {
info!("Initialising...");
init_socks5(service_provider, chosen_gateway_id).await;
let service_provider = service_provider.to_owned();
let chosen_gateway_id = chosen_gateway_id.to_owned();
// The client initialization was originally not written for this use case, so there are
// lots of ways it can panic. Until we have proper error handling in the init code for the
// clients we'll catch any panics here.
std::panic::catch_unwind(move || {
futures::executor::block_on(init_socks5(service_provider, chosen_gateway_id));
})
.map_err(|_| BackendError::InitializationPanic)?;
info!("Configuration saved 🚀");
Ok(())
}
pub fn config_file_location(id: &str) -> PathBuf {
@@ -68,16 +99,17 @@ impl Config {
}
}
pub async fn init_socks5(provider_address: &str, chosen_gateway_id: Option<&str>) {
pub async fn init_socks5(provider_address: String, chosen_gateway_id: String) {
log::info!("Initialising client...");
let id: &str = SOCKS5_CONFIG_ID;
// Append the gateway id to the name id that we store the config under
let id = append_config_id(&chosen_gateway_id);
log::debug!(
"Attempting to use config file location: {}",
Config::config_file_location(id).to_string_lossy(),
Config::config_file_location(&id).to_string_lossy(),
);
let already_init = Config::config_file_location(id).exists();
let already_init = Config::config_file_location(&id).exists();
if already_init {
log::info!(
"SOCKS5 client \"{}\" was already initialised before! \
@@ -92,7 +124,7 @@ pub async fn init_socks5(provider_address: &str, chosen_gateway_id: Option<&str>
let register_gateway = !already_init || user_wants_force_register;
log::trace!("Creating config for id: {}", id);
let mut config = Config::new(id, provider_address);
let mut config = Config::new(id.as_str(), &provider_address);
// As far as I'm aware, these two are not used, they are only set because the socks5 init code
// requires them for initialising the bandwidth controller.
@@ -103,7 +135,13 @@ pub async fn init_socks5(provider_address: &str, chosen_gateway_id: Option<&str>
.get_base_mut()
.with_eth_private_key(DEFAULT_ETH_PRIVATE_KEY);
let gateway = setup_gateway(id, register_gateway, chosen_gateway_id, config.get_socks5()).await;
let gateway = setup_gateway(
&id,
register_gateway,
Some(&chosen_gateway_id),
config.get_socks5(),
)
.await;
config.get_base_mut().with_gateway_endpoint(gateway);
let config_save_location = config.get_socks5().get_config_file_save_location();
+7
View File
@@ -14,6 +14,13 @@ pub enum BackendError {
NoServiceProviderSet,
#[error("No gateway provider set")]
NoGatewaySet,
#[error("{source}")]
ReqwestError {
#[from]
source: reqwest::Error,
},
#[error("Initialization failed with a panic")]
InitializationPanic,
}
impl Serialize for BackendError {
+8
View File
@@ -19,6 +19,7 @@ mod menu;
mod models;
mod operations;
mod state;
mod tasks;
mod window;
fn main() {
@@ -35,6 +36,7 @@ fn main() {
.manage(Arc::new(RwLock::new(State::new())))
.invoke_handler(tauri::generate_handler![
crate::config::get_config_file_location,
crate::config::get_config_id,
crate::operations::connection::connect::get_gateway,
crate::operations::connection::connect::get_service_provider,
crate::operations::connection::connect::set_gateway,
@@ -42,6 +44,7 @@ fn main() {
crate::operations::connection::connect::start_connecting,
crate::operations::connection::disconnect::start_disconnecting,
crate::operations::window::hide_window,
crate::operations::directory::get_services,
])
.menu(Menu::new().add_default_app_submenu_if_macos())
.system_tray(create_tray_menu())
@@ -61,5 +64,10 @@ fn setup_logging() {
log_builder
.filter_module("handlebars", log::LevelFilter::Warn)
.filter_module("mio", log::LevelFilter::Warn)
.filter_module("sled", log::LevelFilter::Warn)
.filter_module("tokio_tungstenite", log::LevelFilter::Warn)
.filter_module("tungstenite", log::LevelFilter::Warn)
.filter_module("want", log::LevelFilter::Warn)
.init();
}
+20
View File
@@ -30,3 +30,23 @@ pub const APP_EVENT_CONNECTION_STATUS_CHANGED: &str = "app:connection-status-cha
pub struct AppEventConnectionStatusChangedPayload {
pub status: ConnectionStatusKind,
}
#[cfg_attr(test, derive(ts_rs::TS))]
#[derive(Clone, serde::Serialize, serde::Deserialize)]
pub struct DirectoryService {
pub id: String,
pub description: String,
pub items: Vec<DirectoryServiceProvider>,
}
#[cfg_attr(test, derive(ts_rs::TS))]
#[derive(Clone, serde::Serialize, serde::Deserialize)]
pub struct DirectoryServiceProvider {
pub id: String,
pub description: String,
/// Address of the network requester in the form "<gateway_id>.<service_provider_id>"
/// e.g. DpB3cHAchJiNBQi5FrZx2csXb1mrHkpYh9Wzf8Rjsuko.ANNWrvHqMYuertHGHUrZdBntQhpzfbWekB39qez9U2Vx@2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh
pub address: String,
/// Address of the gateway, e.g. 2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh
pub gateway: String,
}
@@ -1,6 +1,4 @@
use crate::error::BackendError;
use crate::models::ConnectResult;
use crate::State;
use crate::{error::BackendError, models::ConnectResult, tasks::start_disconnect_listener, State};
use std::sync::Arc;
use tokio::sync::RwLock;
@@ -9,9 +7,18 @@ pub async fn start_connecting(
state: tauri::State<'_, Arc<RwLock<State>>>,
window: tauri::Window<tauri::Wry>,
) -> Result<ConnectResult, BackendError> {
let mut guard = state.write().await;
let status_receiver = {
let mut guard = state.write().await;
guard.start_connecting(&window).await;
log::trace!("Start connecting with:");
log::trace!(" service_provider: {:?}", guard.get_service_provider());
log::trace!(" gateway: {:?}", guard.get_gateway());
guard.start_connecting(&window).await?
};
// Setup task for checking status
let state = state.inner().clone();
start_disconnect_listener(state, window, status_receiver);
Ok(ConnectResult {
// WIP(JON): fixme
@@ -35,6 +42,7 @@ pub async fn set_service_provider(
service_provider: String,
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<(), BackendError> {
log::trace!("Setting service_provider: {service_provider}");
let mut guard = state.write().await;
guard.set_service_provider(service_provider);
Ok(())
@@ -56,6 +64,7 @@ pub async fn set_gateway(
gateway: String,
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<(), BackendError> {
log::trace!("Setting gateway: {gateway}");
let mut guard = state.write().await;
guard.set_gateway(gateway);
Ok(())
@@ -0,0 +1,14 @@
use crate::error::BackendError;
use crate::models::DirectoryService;
static SERVICE_PROVIDER_WELLKNOWN_URL: &str =
"https://nymtech.net/.wellknown/connect/service-providers.json";
#[tauri::command]
pub async fn get_services() -> Result<Vec<DirectoryService>, BackendError> {
let res = reqwest::get(SERVICE_PROVIDER_WELLKNOWN_URL)
.await?
.json::<Vec<DirectoryService>>()
.await?;
Ok(res)
}
@@ -1,2 +1,3 @@
pub mod connection;
pub mod directory;
pub mod window;
+50 -44
View File
@@ -1,19 +1,19 @@
use client_core::config::GatewayEndpoint;
use futures::channel::mpsc;
use futures::SinkExt;
use log::info;
use std::time::Duration;
use futures::SinkExt;
use tauri::Manager;
use config::NymConfig;
#[cfg(not(feature = "coconut"))]
use nym_socks5::client::NymClient as Socks5NymClient;
use nym_socks5::client::{Socks5ControlMessage, Socks5ControlMessageSender};
use crate::config::SOCKS5_CONFIG_ID;
use crate::models::{
AppEventConnectionStatusChangedPayload, ConnectionStatusKind,
APP_EVENT_CONNECTION_STATUS_CHANGED,
use crate::{
config::append_config_id,
error::BackendError,
models::{
AppEventConnectionStatusChangedPayload, ConnectionStatusKind,
APP_EVENT_CONNECTION_STATUS_CHANGED,
},
tasks::{start_nym_socks5_client, StatusReceiver},
};
use tauri::Manager;
pub struct State {
status: ConnectionStatusKind,
@@ -63,29 +63,56 @@ impl State {
self.gateway = Some(gateway);
}
pub async fn init_config(&self) {
crate::config::Config::init(self.service_provider.as_ref(), self.gateway.as_ref()).await;
pub async fn init_config(&self) -> Result<(), BackendError> {
let service_provider = self
.service_provider
.as_ref()
.expect("Attempting to init without service provider");
let gateway = self
.gateway
.as_ref()
.expect("Attempting to init without gateway");
crate::config::Config::init(service_provider, gateway).await
}
pub async fn start_connecting(&mut self, window: &tauri::Window<tauri::Wry>) {
info!("Connecting");
pub async fn start_connecting(
&mut self,
window: &tauri::Window<tauri::Wry>,
) -> Result<StatusReceiver, BackendError> {
log::info!("Connecting");
self.set_state(ConnectionStatusKind::Connecting, window);
self.status = ConnectionStatusKind::Connecting;
// Setup configuration by writing to file
self.init_config().await;
if let Err(err) = self.init_config().await {
log::warn!("Failed to initialize: {}", err);
// Kick of the main task and get the channel for controlling it
let (sender, used_gateway) = start_nym_socks5_client();
// Wait a little to give the user some rudimentary feedback that the click actually
// registered.
tokio::time::sleep(Duration::from_secs(1)).await;
self.set_state(ConnectionStatusKind::Disconnected, window);
self.status = ConnectionStatusKind::Disconnected;
return Err(err);
}
// Kick off the main task and get the channel for controlling it
let id = append_config_id(
self.gateway
.as_ref()
.expect("Attempting to start without gateway"),
);
let (sender, used_gateway, status_receiver) = start_nym_socks5_client(&id);
self.gateway = Some(used_gateway.gateway_id);
self.socks5_client_sender = Some(sender);
self.status = ConnectionStatusKind::Connected;
self.set_state(ConnectionStatusKind::Connected, window);
Ok(status_receiver)
}
pub async fn start_disconnecting(&mut self, window: &tauri::Window<tauri::Wry>) {
info!("Disconnecting");
log::info!("Disconnecting");
self.set_state(ConnectionStatusKind::Disconnecting, window);
self.status = ConnectionStatusKind::Disconnecting;
@@ -93,32 +120,11 @@ impl State {
if let Some(ref mut sender) = self.socks5_client_sender {
sender.send(Socks5ControlMessage::Stop).await.unwrap();
}
}
pub async fn mark_disconnected(&mut self, window: &tauri::Window<tauri::Wry>) {
log::info!("Disconnected");
self.status = ConnectionStatusKind::Disconnected;
self.set_state(ConnectionStatusKind::Disconnected, window);
}
}
fn start_nym_socks5_client() -> (Socks5ControlMessageSender, GatewayEndpoint) {
let id: &str = SOCKS5_CONFIG_ID;
info!("Loading config from file");
let config = nym_socks5::client::config::Config::load_from_file(Some(id)).unwrap();
let used_gateway = config.get_base().get_gateway_endpoint().clone();
let mut socks5_client = Socks5NymClient::new(config);
info!("Starting socks5 client");
let (sender, receiver) = mpsc::unbounded();
// Spawn a separate runtime for the socks5 client so we can forcefully terminate.
// Once we can gracefully shutdown the socks5 client we can get rid of this.
std::thread::spawn(|| {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async move {
socks5_client.run_and_listen(receiver).await;
});
});
(sender, used_gateway)
}
+73
View File
@@ -0,0 +1,73 @@
use client_core::config::GatewayEndpoint;
use futures::channel::mpsc;
use log::info;
use std::sync::Arc;
use tokio::sync::RwLock;
use config::NymConfig;
#[cfg(not(feature = "coconut"))]
use nym_socks5::client::NymClient as Socks5NymClient;
use nym_socks5::client::Socks5ControlMessageSender;
use crate::state::State;
pub type StatusReceiver = futures::channel::oneshot::Receiver<Socks5StatusMessage>;
#[derive(Debug)]
pub enum Socks5StatusMessage {
/// The SOCKS5 task successfully stopped
Stopped,
}
pub fn start_nym_socks5_client(
id: &str,
) -> (Socks5ControlMessageSender, GatewayEndpoint, StatusReceiver) {
info!("Loading config from file: {id}");
// TODO: handle this gracefully!
let config = nym_socks5::client::config::Config::load_from_file(Some(id)).unwrap();
let used_gateway = config.get_base().get_gateway_endpoint().clone();
let mut socks5_client = Socks5NymClient::new(config);
info!("Starting socks5 client");
// Channel to send control messages to the socks5 client
let (socks5_ctrl_tx, socks5_ctrl_rx) = mpsc::unbounded();
// Channel to signal back to the main task when the socks5 client finishes, and why
let (socks5_status_tx, socks5_status_rx) = futures::channel::oneshot::channel();
// Spawn a separate runtime for the socks5 client so we can forcefully terminate.
// Once we can gracefully shutdown the socks5 client we can get rid of this.
std::thread::spawn(|| {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async move {
socks5_client.run_and_listen(socks5_ctrl_rx).await;
});
log::info!("SOCKS5 task finished");
socks5_status_tx.send(Socks5StatusMessage::Stopped).unwrap();
});
(socks5_ctrl_tx, used_gateway, socks5_status_rx)
}
pub fn start_disconnect_listener(
state: Arc<RwLock<State>>,
window: tauri::Window<tauri::Wry>,
status_receiver: StatusReceiver,
) {
log::trace!("Starting disconnect listener");
tokio::spawn(async move {
match status_receiver.await {
Ok(Socks5StatusMessage::Stopped) => {
log::info!("SOCKS5 task reported it has finished");
}
Err(_) => {
log::info!("SOCKS5 task appears to have stopped abruptly");
}
}
let mut state_w = state.write().await;
state_w.mark_disconnected(&window).await;
});
}
+11 -1
View File
@@ -7,6 +7,7 @@ import { ConnectedLayout } from './layouts/ConnectedLayout';
export const App: React.FC = () => {
const context = useClientContext();
const [busy, setBusy] = React.useState<boolean>();
const handleConnectClick = React.useCallback(async () => {
const oldStatus = context.connectionStatus;
if (oldStatus === ConnectionStatusKind.connected || oldStatus === ConnectionStatusKind.disconnected) {
@@ -29,7 +30,15 @@ export const App: React.FC = () => {
context.connectionStatus === ConnectionStatusKind.disconnected ||
context.connectionStatus === ConnectionStatusKind.connecting
) {
return <DefaultLayout status={context.connectionStatus} busy={busy} onConnectClick={handleConnectClick} />;
return (
<DefaultLayout
status={context.connectionStatus}
busy={busy}
onConnectClick={handleConnectClick}
services={context.services}
onServiceProviderChange={context.setServiceProvider}
/>
);
}
return (
@@ -40,6 +49,7 @@ export const App: React.FC = () => {
ipAddress="127.0.0.1"
port={1080}
connectedSince={context.connectedSince}
serviceProvider={context.serviceProvider}
stats={[
{
label: 'in:',
@@ -1,6 +1,5 @@
import React from 'react';
import { Box } from '@mui/material';
import { invoke } from '@tauri-apps/api/tauri';
export const AppWindowFrame: React.FC = ({ children }) => (
<Box
@@ -14,11 +13,10 @@ export const AppWindowFrame: React.FC = ({ children }) => (
}}
>
<Box display="flex" justifyContent="space-between" alignItems="center">
<svg width="22" height="6" viewBox="0 0 22 6" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M6.86777 6H5.35495L1.22609 1.32517V6H0V0H1.54986L5.67872 4.67354V0H6.86777V6ZM20.4496 0L18.5658 2.13277L16.6821 0H15.1322V6H16.3578V1.32517L18.2959 3.52046C18.4457 3.68998 18.6865 3.68998 18.8363 3.52046L20.7745 1.32517V6H22V0H20.4496ZM10.4063 3.13181V6H11.6318V3.13181L14.4527 0H12.9028L11.018 2.13277L9.13421 0H7.58435L10.4063 3.13181Z"
fill="#F2F2F2"
/>
<svg width="22" height="6" viewBox="0 0 210 56" fill="#F2F2F2" xmlns="http://www.w3.org/2000/svg">
<path d="M45.8829 0.142822H45.7169V0.28114V48.637L25.3289 0.225818L25.3012 0.142822H25.1905H13.6272H0.652966H0.514648V0.28114V55.7189V55.8572H0.652966H13.6272H13.7655V55.7189V7.28002L34.2365 55.7742L34.2642 55.8572H34.3748H45.8829H58.8294H58.9677V55.7189V0.28114V0.142822H58.8294H45.8829Z" />
<path d="M209.347 0.142822H184.616H184.477L184.45 0.253483L171.78 48.8583L159.082 0.253483L159.054 0.142822H158.944H134.157H133.991V0.28114V55.7189V55.8572H134.157H147.104H147.242V55.7189V7.66731L159.774 55.7466L159.801 55.8572H159.94H183.564H183.675L183.703 55.7466L196.234 7.66731V55.7189V55.8572H196.373H209.347H209.485V55.7189V0.28114V0.142822H209.347Z" />
<path d="M112.663 0.142822H112.58L112.552 0.198153L96.8116 27.5574L80.988 0.198153L80.9604 0.142822H80.8774H65.9114H65.6348L65.7731 0.364136L90.1447 42.5787V55.7189V55.8572H90.283H103.257H103.396V55.7189V42.5787L127.767 0.364136L127.905 0.142822H127.629H112.663Z" />
</svg>
</Box>
{children}
@@ -3,17 +3,21 @@ import { ConnectionStatusKind } from '../types';
export const ConnectionButton: React.FC<{
status: ConnectionStatusKind;
disabled?: boolean;
busy?: boolean;
isError?: boolean;
onClick?: (status: ConnectionStatusKind) => void;
}> = ({ status, isError, onClick, busy }) => {
}> = ({ status, disabled, isError, onClick, busy }) => {
const [hover, setHover] = React.useState<boolean>(false);
const handleClick = React.useCallback(() => {
if (disabled === true) {
return;
}
if (onClick) {
onClick(status);
}
}, [status]);
}, [status, disabled]);
const statusText = getStatusText(status, hover);
const statusTextColor = isError ? '#40475C' : '#FFF';
@@ -21,16 +25,17 @@ export const ConnectionButton: React.FC<{
return (
<svg
opacity={disabled ? 0.75 : 1}
width="208"
height="208"
viewBox="0 0 208 208"
fill="none"
xmlns="http://www.w3.org/2000/svg"
onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
onMouseEnter={() => !disabled && setHover(true)}
onMouseLeave={() => !disabled && setHover(false)}
>
<g transform="translate(-46 -46)">
<g onClick={handleClick} style={{ cursor: 'pointer' }}>
<g onClick={handleClick} style={{ cursor: disabled ? 'not-allowed' : 'pointer' }}>
<g filter="url(#filter0_f_2_303)">
<circle cx="150" cy="150" r="70" fill="#3B445F" />
</g>
@@ -4,6 +4,7 @@ import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
import CircleOutlinedIcon from '@mui/icons-material/CircleOutlined';
import { DateTime } from 'luxon';
import { ConnectionStatusKind } from '../types';
import { ServiceProvider } from '../types/directory';
const FONT_SIZE = '16px';
const FONT_WEIGHT = '600';
@@ -57,7 +58,8 @@ const ConnectionStatusContent: React.FC<{
export const ConnectionStatus: React.FC<{
status: ConnectionStatusKind;
connectedSince?: DateTime;
}> = ({ status, connectedSince }) => {
serviceProvider?: ServiceProvider;
}> = ({ status, connectedSince, serviceProvider }) => {
const color =
status === ConnectionStatusKind.connected || status === ConnectionStatusKind.disconnecting ? '#21D072' : '#888';
const [duration, setDuration] = React.useState<string>();
@@ -72,13 +74,16 @@ export const ConnectionStatus: React.FC<{
};
}, [status, connectedSince]);
return (
<Box display="flex" justifyContent="space-between">
<Box color={color} fontSize={FONT_SIZE} display="flex" alignItems="center">
<ConnectionStatusContent status={status} />
<>
<Box display="flex" justifyContent="space-between">
<Box color={color} fontSize={FONT_SIZE} display="flex" alignItems="center">
<ConnectionStatusContent status={status} />
</Box>
<Typography color={color} fontWeight={FONT_WEIGHT} fontStyle={FONT_STYLE}>
{status === ConnectionStatusKind.connected && duration}
</Typography>
</Box>
<Typography color={color} fontWeight={FONT_WEIGHT} fontStyle={FONT_STYLE}>
{status === ConnectionStatusKind.connected && duration}
</Typography>
</Box>
<Box>{serviceProvider && <Typography fontSize={12}>{serviceProvider.description}</Typography>}</Box>
</>
);
};
@@ -0,0 +1,110 @@
import React from 'react';
import IconButton from '@mui/material/IconButton';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import ArrowDropDownCircleIcon from '@mui/icons-material/ArrowDropDownCircle';
import { Box, CircularProgress, Stack, Tooltip, Typography } from '@mui/material';
import { ServiceProvider, Services } from '../types/directory';
export const ServiceProviderSelector: React.FC<{
onChange?: (serviceProvider: ServiceProvider) => void;
services?: Services;
}> = ({ services, onChange }) => {
const [serviceProvider, setServiceProvider] = React.useState<ServiceProvider | undefined>();
const textEl = React.useRef<null | HTMLElement>(null);
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const handleClick = () => {
setAnchorEl(textEl.current);
};
const handleClose = (newServiceProvider?: ServiceProvider) => {
if (newServiceProvider) {
setServiceProvider(newServiceProvider);
onChange?.(newServiceProvider);
}
setAnchorEl(null);
};
if (!services) {
return (
<Box display="flex" alignItems="center" justifyContent="space-between" sx={{ mt: 3 }}>
<Typography fontSize={14} fontWeight={700} color={(theme) => theme.palette.common.white}>
<CircularProgress size={14} sx={{ mr: 1 }} color="inherit" />
Loading services...
</Typography>
<IconButton id="service-provider-button" disabled>
<ArrowDropDownCircleIcon />
</IconButton>
</Box>
);
}
return (
<>
<Box display="flex" alignItems="center" justifyContent="space-between" sx={{ mt: 3 }}>
<Typography
ref={textEl}
fontSize={14}
fontWeight={700}
color={(theme) => (serviceProvider ? undefined : theme.palette.primary.main)}
>
{serviceProvider ? serviceProvider.description : 'Select a service'}
</Typography>
<IconButton
id="service-provider-button"
aria-controls={open ? 'basic-menu' : undefined}
aria-haspopup="true"
aria-expanded={open ? 'true' : undefined}
onClick={handleClick}
>
<ArrowDropDownCircleIcon />
</IconButton>
</Box>
<Menu
id="service-provider-menu"
anchorEl={anchorEl}
open={open}
onClose={() => handleClose()}
MenuListProps={{
'aria-labelledby': 'service-provider-button',
}}
>
{services.map((service) => (
<>
<MenuItem disabled dense sx={{ fontSize: 'small', fontWeight: 'bold', mb: -1 }}>
{service.description}
</MenuItem>
{service.items.map((sp) => (
<MenuItem dense sx={{ fontSize: 'small', ml: 2, height: 'auto' }} onClick={() => handleClose(sp)}>
<Tooltip
title={
<Stack direction="column">
<Typography fontSize="inherit">
<code>{sp.id}</code>
</Typography>
<Typography fontSize="inherit" fontWeight={700}>
{sp.description}
</Typography>
<Typography fontSize="inherit">
Gateway <code>{sp.gateway.slice(0, 10)}...</code>
</Typography>
<Typography fontSize="inherit">
Provider <code>{sp.address.slice(0, 10)}...</code>
</Typography>
</Stack>
}
arrow
placement="top"
>
<Typography fontSize="inherit" noWrap>
{sp.description}
</Typography>
</Tooltip>
</MenuItem>
))}
</>
))}
</Menu>
</>
);
};
+21
View File
@@ -4,6 +4,7 @@ import { invoke } from '@tauri-apps/api/tauri';
import { listen, UnlistenFn } from '@tauri-apps/api/event';
import { ConnectionStatusKind } from '../types';
import { ConnectionStatsItem } from '../components/ConnectionStats';
import { ServiceProvider, Services } from '../types/directory';
const TAURI_EVENT_STATUS_CHANGED = 'app:connection-status-changed';
@@ -14,11 +15,14 @@ type TClientContext = {
connectionStatus: ConnectionStatusKind;
connectionStats?: ConnectionStatsItem[];
connectedSince?: DateTime;
services?: Services;
serviceProvider?: ServiceProvider;
setMode: (mode: ModeType) => void;
setConnectionStatus: (connectionStatus: ConnectionStatusKind) => void;
setConnectionStats: (connectionStats: ConnectionStatsItem[] | undefined) => void;
setConnectedSince: (connectedSince: DateTime | undefined) => void;
setServiceProvider: (serviceProvider: ServiceProvider) => void;
startConnecting: () => Promise<void>;
startDisconnecting: () => Promise<void>;
@@ -31,6 +35,14 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
const [connectionStatus, setConnectionStatus] = useState<ConnectionStatusKind>(ConnectionStatusKind.disconnected);
const [connectionStats, setConnectionStats] = useState<ConnectionStatsItem[]>();
const [connectedSince, setConnectedSince] = useState<DateTime>();
const [services, setServices] = React.useState<Services>();
const [serviceProvider, setRawServiceProvider] = React.useState<ServiceProvider>();
useEffect(() => {
invoke('get_services').then((result) => {
setServices(result as Services);
});
}, []);
useEffect(() => {
let unlisten: UnlistenFn | undefined;
@@ -59,6 +71,12 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
await invoke('start_disconnecting');
}, []);
const setServiceProvider = useCallback(async (newServiceProvider: ServiceProvider) => {
await invoke('set_gateway', { gateway: newServiceProvider.gateway });
await invoke('set_service_provider', { serviceProvider: newServiceProvider.address });
setRawServiceProvider(newServiceProvider);
}, []);
return (
<ClientContext.Provider
value={{
@@ -72,6 +90,9 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
setConnectedSince,
startConnecting,
startDisconnecting,
services,
serviceProvider,
setServiceProvider,
}}
>
{children}
+5 -3
View File
@@ -8,6 +8,7 @@ import { ConnectionStats, ConnectionStatsItem } from '../components/ConnectionSt
import { NeedHelp } from '../components/NeedHelp';
import { ConnectionButton } from '../components/ConnectionButton';
import { IpAddressAndPort } from '../components/IpAddressAndPort';
import { ServiceProvider } from '../types/directory';
export const ConnectedLayout: React.FC<{
status: ConnectionStatusKind;
@@ -18,15 +19,16 @@ export const ConnectedLayout: React.FC<{
busy?: boolean;
isError?: boolean;
onConnectClick?: (status: ConnectionStatusKind) => void;
}> = ({ status, stats, ipAddress, port, connectedSince, busy, isError, onConnectClick }) => (
serviceProvider?: ServiceProvider;
}> = ({ status, stats, ipAddress, port, connectedSince, busy, isError, serviceProvider, onConnectClick }) => (
<AppWindowFrame>
<Box pb={4}>
<ConnectionStatus status={status} connectedSince={connectedSince} />
<ConnectionStatus status={status} connectedSince={connectedSince} serviceProvider={serviceProvider} />
</Box>
<Box pb={4}>
<IpAddressAndPort label="SOCKS5 Proxy" ipAddress={ipAddress} port={port} />
</Box>
<ConnectionStats stats={stats} />
{/* <ConnectionStats stats={stats} /> */}
<ConnectionButton status={status} busy={busy} onClick={onConnectClick} isError={isError} />
<NeedHelp />
</AppWindowFrame>
+30 -12
View File
@@ -4,21 +4,39 @@ import { AppWindowFrame } from '../components/AppWindowFrame';
import { ConnectionButton } from '../components/ConnectionButton';
import { ConnectionStatusKind } from '../types';
import { NeedHelp } from '../components/NeedHelp';
import { ServiceProviderSelector } from '../components/ServiceProviderSelector';
import { ServiceProvider, Services } from '../types/directory';
export const DefaultLayout: React.FC<{
status: ConnectionStatusKind;
services?: Services;
busy?: boolean;
isError?: boolean;
onConnectClick?: (status: ConnectionStatusKind) => void;
}> = ({ status, busy, isError, onConnectClick }) => (
<AppWindowFrame>
<Typography fontWeight="700" fontSize="14px" textAlign="center">
Connect, your privacy will be 100% protected thanks to the Nym Mixnet
</Typography>
<Typography fontWeight="700" fontSize="14px" textAlign="center" color="#60D6EF" pt={2}>
You are not protected now
</Typography>
<ConnectionButton status={status} busy={busy} isError={isError} onClick={onConnectClick} />
<NeedHelp />
</AppWindowFrame>
);
onServiceProviderChange?: (serviceProvider: ServiceProvider) => void;
}> = ({ status, services, busy, isError, onConnectClick, onServiceProviderChange }) => {
const [serviceProvider, setServiceProvider] = React.useState<ServiceProvider | undefined>();
const handleServiceProviderChange = (newServiceProvider: ServiceProvider) => {
setServiceProvider(newServiceProvider);
onServiceProviderChange?.(newServiceProvider);
};
return (
<AppWindowFrame>
<Typography fontWeight="700" fontSize="14px" textAlign="center">
Connect, your privacy will be 100% protected thanks to the Nym Mixnet
</Typography>
<Typography fontWeight="700" fontSize="14px" textAlign="center" color="#60D6EF" pt={2}>
You are not protected now
</Typography>
<ServiceProviderSelector services={services} onChange={handleServiceProviderChange} />
<ConnectionButton
status={status}
disabled={serviceProvider === undefined}
busy={busy}
isError={isError}
onClick={onConnectClick}
/>
<NeedHelp />
</AppWindowFrame>
);
};
+21 -1
View File
@@ -7,6 +7,7 @@ import { useClientContext } from '../context/main';
import { ConnectionStatusKind } from '../types';
import { DefaultLayout } from '../layouts/DefaultLayout';
import { ConnectedLayout } from '../layouts/ConnectedLayout';
import { Services } from '../types/directory';
export default {
title: 'App/Flow',
@@ -16,6 +17,19 @@ export default {
export const Mock: ComponentStory<typeof AppWindowFrame> = () => {
const context = useClientContext();
const [busy, setBusy] = React.useState<boolean>();
const services: Services = [
{
id: 'keybase',
description: 'Keybase',
items: [
{
id: 'nym-keybase',
description: 'Nym Keybase Service Provider',
address: '1234.5678',
},
],
},
];
const handleConnectClick = React.useCallback(() => {
const oldStatus = context.connectionStatus;
if (oldStatus === ConnectionStatusKind.connected || oldStatus === ConnectionStatusKind.disconnected) {
@@ -53,7 +67,12 @@ export const Mock: ComponentStory<typeof AppWindowFrame> = () => {
) {
return (
<Box p={4} sx={{ background: 'white' }}>
<DefaultLayout status={context.connectionStatus} busy={busy} onConnectClick={handleConnectClick} />
<DefaultLayout
status={context.connectionStatus}
busy={busy}
onConnectClick={handleConnectClick}
services={services}
/>
</Box>
);
}
@@ -67,6 +86,7 @@ export const Mock: ComponentStory<typeof AppWindowFrame> = () => {
ipAddress="127.0.0.1"
port={1080}
connectedSince={context.connectedSince}
serviceProvider={services[0].items[0]}
stats={[
{
label: 'in:',
+14
View File
@@ -0,0 +1,14 @@
export interface ServiceProvider {
id: string;
description: string;
address: string;
gateway: string;
}
export interface Service {
id: string;
description: string;
items: ServiceProvider[];
}
export type Services = Service[];
@@ -0,0 +1,47 @@
import * as React from 'react';
import { useState } from 'react';
import { ComponentMeta, ComponentStory } from '@storybook/react';
import { Button } from '@mui/material';
import SimpleDialog from './SimpleDialog';
export default {
title: 'Bounding/SimpleDialog',
component: SimpleDialog,
} as ComponentMeta<typeof SimpleDialog>;
const Template: ComponentStory<typeof SimpleDialog> = (args) => {
const [open, setOpen] = useState(true);
return (
<>
<Button variant="outlined" onClick={() => setOpen(true)}>
Open simple dialog
</Button>
<SimpleDialog
{...args}
open={open}
confirmButton="Confirm"
onClose={() => setOpen(false)}
onConfirm={() => setOpen(false)}
>
Dialog content.
</SimpleDialog>
</>
);
};
export const Default = Template.bind({});
Default.args = {
title: 'Simple Dialog',
subTitle: '',
fullWidth: true,
maxWidth: 'xs',
closeButton: false,
cancelButton: false,
disabled: false,
};
export const CenteredText = Template.bind({});
CenteredText.args = {
...Default.args,
sx: { textAlign: 'center' },
};
+115
View File
@@ -0,0 +1,115 @@
import React from 'react';
import {
Breakpoint,
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
Stack,
SxProps,
Typography,
} from '@mui/material';
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
import CloseIcon from '@mui/icons-material/Close';
export interface Props {
open: boolean;
onConfirm: () => void;
onClose?: () => void;
onCancel?: () => void;
closeButton?: boolean;
children?: React.ReactNode;
title: React.ReactNode | string;
subTitle?: React.ReactNode | string;
confirmButton: React.ReactNode | string;
cancelButton?: React.ReactNode | boolean;
disabled?: boolean;
sx?: SxProps;
fullWidth?: boolean;
maxWidth?: Breakpoint;
}
const SimpleDialog = ({
open,
onConfirm,
onClose,
children,
title,
subTitle,
confirmButton,
closeButton,
onCancel,
cancelButton,
disabled,
sx,
fullWidth,
maxWidth,
}: Props) => {
const titleComp = (
<DialogTitle id="responsive-dialog-title" sx={{ py: 3 }} color="black">
{title}
{subTitle &&
(typeof subTitle === 'string' ? (
<Typography fontWeight={400} variant="subtitle1" fontSize={12} color={(t) => t.palette.nym.text.muted}>
{subTitle}
</Typography>
) : (
subTitle
))}
</DialogTitle>
);
const confirmButtonComp =
typeof confirmButton === 'string' ? (
<Button onClick={onConfirm} variant="contained" fullWidth disabled={disabled} sx={{ py: 1.6 }}>
<Typography variant="button" fontSize="large">
{confirmButton}
</Typography>
</Button>
) : (
confirmButton
);
const cancelButtonComp: React.ReactNode | undefined =
cancelButton && typeof cancelButton === 'boolean' ? (
<Button onClick={onCancel} variant="outlined" color="primary" sx={{ px: 1 }}>
<ChevronLeftIcon />
</Button>
) : (
cancelButton
);
return (
<Dialog
open={open}
onClose={onClose}
aria-labelledby="responsive-dialog-title"
maxWidth={maxWidth || 'sm'}
sx={sx}
fullWidth={fullWidth}
>
{closeButton ? (
<Stack direction="row" alignItems="flex-start" justifyContent="space-between">
{titleComp}
<IconButton onClick={onClose} sx={{ mr: 2, mt: 2.6 }}>
<CloseIcon sx={{ color: 'black' }} />
</IconButton>
</Stack>
) : (
titleComp
)}
<DialogContent sx={{ pt: closeButton ? 0 : undefined }}>{children}</DialogContent>
<DialogActions sx={{ px: 3, pb: 3 }}>
{cancelButton ? (
<Stack direction="row" spacing={3} width="100%">
{cancelButtonComp}
{confirmButtonComp}
</Stack>
) : (
confirmButtonComp
)}
</DialogActions>
</Dialog>
);
};
export default SimpleDialog;
+2
View File
@@ -20,3 +20,5 @@ export * from './Title';
export * from './TokenPoolSelector';
export * from './TransactionDetails';
export * from './Warning';
export * from './SimpleDialog';
export { default as SimpleDialog } from './SimpleDialog';
+7
View File
@@ -247,6 +247,13 @@ export const getDesignTokens = (mode: PaletteMode): ThemeOptions => {
underline: 'none',
},
},
MuiDialogTitle: {
styleOverrides: {
root: {
fontWeight: 600,
},
},
},
},
palette,
};
+38 -19
View File
@@ -35,9 +35,9 @@
chalk "^4.0.0"
"@sindresorhus/is@^4.0.0":
version "4.2.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.2.0.tgz#667bfc6186ae7c9e0b45a08960c551437176e1ca"
integrity sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw==
version "4.6.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f"
integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==
"@szmarczak/http-timer@^4.0.5":
version "4.0.6"
@@ -115,10 +115,15 @@
dependencies:
"@types/istanbul-lib-report" "*"
"@types/json-buffer@~3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/json-buffer/-/json-buffer-3.0.0.tgz#85c1ff0f0948fc159810d4b5be35bf8c20875f64"
integrity sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==
"@types/keyv@*":
version "3.1.3"
resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.3.tgz#1c9aae32872ec1f20dcdaee89a9f3ba88f465e41"
integrity sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==
version "3.1.4"
resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6"
integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==
dependencies:
"@types/node" "*"
@@ -153,7 +158,12 @@
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.0.0.tgz#3205bcd15ada9bc681ac20bef64e9e6df88fd297"
integrity sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==
"@types/node@*", "@types/node@^16.11.0", "@types/node@^16.11.1":
"@types/node@*":
version "18.0.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a"
integrity sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==
"@types/node@^16.11.0", "@types/node@^16.11.1":
version "16.11.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.1.tgz#2e50a649a50fc403433a14f829eface1a3443e97"
integrity sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==
@@ -647,7 +657,7 @@ cacheable-lookup@^5.0.3:
resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==
cacheable-request@^7.0.1:
cacheable-request@^7.0.2:
version "7.0.2"
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27"
integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==
@@ -770,7 +780,7 @@ cliui@^7.0.2:
clone-response@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
integrity sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==
dependencies:
mimic-response "^1.0.0"
@@ -803,6 +813,14 @@ color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
compress-brotli@^1.3.8:
version "1.3.8"
resolved "https://registry.yarnpkg.com/compress-brotli/-/compress-brotli-1.3.8.tgz#0c0a60c97a989145314ec381e84e26682e7b38db"
integrity sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==
dependencies:
"@types/json-buffer" "~3.0.0"
json-buffer "~3.0.1"
compress-commons@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.1.1.tgz#df2a09a7ed17447642bad10a85cc9a19e5c42a7d"
@@ -1228,16 +1246,16 @@ globule@^1.0.0:
minimatch "~3.0.2"
got@^11.0.2, got@^11.8.1:
version "11.8.2"
resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599"
integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==
version "11.8.5"
resolved "https://registry.yarnpkg.com/got/-/got-11.8.5.tgz#ce77d045136de56e8f024bebb82ea349bc730046"
integrity sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==
dependencies:
"@sindresorhus/is" "^4.0.0"
"@szmarczak/http-timer" "^4.0.5"
"@types/cacheable-request" "^6.0.1"
"@types/responselike" "^1.0.0"
cacheable-lookup "^5.0.3"
cacheable-request "^7.0.1"
cacheable-request "^7.0.2"
decompress-response "^6.0.0"
http2-wrapper "^1.0.0-beta.5.2"
lowercase-keys "^2.0.0"
@@ -1521,7 +1539,7 @@ js2xmlparser@^3.0.0:
dependencies:
xmlcreate "^1.0.1"
json-buffer@3.0.1:
json-buffer@3.0.1, json-buffer@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
@@ -1543,10 +1561,11 @@ jsonfile@^6.0.1:
graceful-fs "^4.1.6"
keyv@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254"
integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==
version "4.3.2"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.3.2.tgz#e839df676a0c7ee594c8835e7c1c83742558e5c2"
integrity sha512-kn8WmodVBe12lmHpA6W8OY7SNh6wVR+Z+wZESF4iF5FCazaVXGWOtnbnvX0tMQ1bO+/TmOD9LziuYMvrIIs0xw==
dependencies:
compress-brotli "^1.3.8"
json-buffer "3.0.1"
ky@^0.28.5:
@@ -1854,7 +1873,7 @@ object-inspect@^1.10.3:
once@^1.3.0, once@^1.3.1, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
dependencies:
wrappy "1"
@@ -2585,7 +2604,7 @@ wrap-ansi@^7.0.0:
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
ws@7.4.6:
version "7.4.6"
+14 -14
View File
@@ -1096,7 +1096,7 @@
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78=
integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==
"@protobufjs/base64@^1.1.2":
version "1.1.2"
@@ -1111,12 +1111,12 @@
"@protobufjs/eventemitter@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A=
integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==
"@protobufjs/fetch@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=
integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==
dependencies:
"@protobufjs/aspromise" "^1.1.1"
"@protobufjs/inquire" "^1.1.0"
@@ -1124,27 +1124,27 @@
"@protobufjs/float@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=
integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==
"@protobufjs/inquire@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=
integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==
"@protobufjs/path@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=
integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==
"@protobufjs/pool@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=
integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==
"@protobufjs/utf8@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
"@swc/helpers@^0.3.6":
version "0.3.8"
@@ -1167,9 +1167,9 @@
integrity sha512-0fDwydE2clKe9MNfvXHBHF9WEahRuj+msTuQqOmAApNORFvhMYZKNGGJdCzuhheVjMps/ti0Ak/iJPACMaevvw==
"@types/long@^4.0.1":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
version "4.0.2"
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a"
integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==
"@types/node@11.11.6":
version "11.11.6"
@@ -3065,9 +3065,9 @@ protobufjs@^6.8.8:
long "^4.0.0"
protobufjs@~6.10.2:
version "6.10.2"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.2.tgz#b9cb6bd8ec8f87514592ba3fdfd28e93f33a469b"
integrity sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==
version "6.10.3"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.3.tgz#11ed1dd02acbfcb330becf1611461d4b407f9eef"
integrity sha512-yvAslS0hNdBhlSKckI4R1l7wunVilX66uvrjzE4MimiAt7/qw1nLpMhZrn/ObuUTM/c3Xnfl01LYMdcSJe6dwg==
dependencies:
"@protobufjs/aspromise" "^1.1.2"
"@protobufjs/base64" "^1.1.2"
+15 -20
View File
@@ -3368,7 +3368,7 @@
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78=
integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==
"@protobufjs/base64@^1.1.2":
version "1.1.2"
@@ -3383,12 +3383,12 @@
"@protobufjs/eventemitter@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A=
integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==
"@protobufjs/fetch@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=
integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==
dependencies:
"@protobufjs/aspromise" "^1.1.1"
"@protobufjs/inquire" "^1.1.0"
@@ -3396,27 +3396,27 @@
"@protobufjs/float@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=
integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==
"@protobufjs/inquire@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=
integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==
"@protobufjs/path@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=
integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==
"@protobufjs/pool@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=
integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==
"@protobufjs/utf8@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
"@sinonjs/commons@^1.7.0":
version "1.8.3"
@@ -4996,9 +4996,9 @@
integrity sha512-uwc1x90yCKqGcIOAT6DwOSuxnrAbpkdPsUOZtwrXb4D/6wZs+6qG7QnIawDuZWg0sWpxl+ltIKCaLoMlna678w==
"@types/long@^4.0.1":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
version "4.0.2"
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a"
integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==
"@types/mdast@^3.0.0":
version "3.0.10"
@@ -5045,16 +5045,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.52.tgz#03c13be70b9031baaed79481c0c0cfb0045e53f7"
integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==
"@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0":
"@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0", "@types/node@^16.7.13":
version "16.11.39"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.39.tgz#07223cd2bc332ad9d92135e3a522eebdee3b060e"
integrity sha512-K0MsdV42vPwm9L6UwhIxMAOmcvH/1OoVkZyCgEtVu4Wx7sElGloy/W7kMBNe/oJ7V/jW9BVt1F6RahH6e7tPXw==
"@types/node@^16.7.13":
version "16.11.26"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.26.tgz#63d204d136c9916fb4dcd1b50f9740fe86884e47"
integrity sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ==
"@types/normalize-package-data@^2.4.0":
version "2.4.1"
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301"
@@ -14983,9 +14978,9 @@ protobufjs@^6.8.8:
long "^4.0.0"
protobufjs@~6.10.2:
version "6.10.2"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.2.tgz#b9cb6bd8ec8f87514592ba3fdfd28e93f33a469b"
integrity sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==
version "6.10.3"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.3.tgz#11ed1dd02acbfcb330becf1611461d4b407f9eef"
integrity sha512-yvAslS0hNdBhlSKckI4R1l7wunVilX66uvrjzE4MimiAt7/qw1nLpMhZrn/ObuUTM/c3Xnfl01LYMdcSJe6dwg==
dependencies:
"@protobufjs/aspromise" "^1.1.2"
"@protobufjs/base64" "^1.1.2"