Compare commits

..

1 Commits

Author SHA1 Message Date
Mark Sinclair c4601c51df ts-packages: APY playground 2022-07-20 14:06:52 +01:00
324 changed files with 22061 additions and 14191 deletions
-36
View File
@@ -1,36 +0,0 @@
name: Daily security audit
on: workflow_dispatch
jobs:
security_audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions-rs/audit-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
notification:
if: ${{ failure() }}
needs: security_audit
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v2
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
env:
NYM_NOTIFICATION_KIND: nightly
NYM_PROJECT_NAME: "Nym daily audit"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBTECH_TEAM }}"
KEYBASE_NYM_CHANNEL: "test"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
-12
View File
@@ -1,7 +1,6 @@
name: CI for Network Explorer
on:
workflow_dispatch:
push:
paths:
- 'explorer/**'
@@ -76,14 +75,3 @@ jobs:
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
- name: Deploy
if: github.event_name == 'workflow_dispatch'
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.CD_PROD_NE_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete"
SOURCE: "explorer/dist/"
REMOTE_HOST: ${{ secrets.CD_PROD_NE_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CD_PROD_NE_REMOTE_USER }}
TARGET: ${{ secrets.CD_PROD_NE_REMOTE_TARGET }}
EXCLUDE: "/dist/, /node_modules/"
@@ -166,8 +166,8 @@ jobs:
GIT_BRANCH: "${GITHUB_REF##*/}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMTECH_TEAM }}"
KEYBASE_NYM_CHANNEL: "test"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-nightly"
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
uses: docker://keybaseio/client:stable-node
with:
@@ -45,4 +45,3 @@ jobs:
target/release/nym-socks5-client
target/release/nym-validator-api
target/release/nym-network-requester
target/release/nym-network-statistics
+5 -5
View File
@@ -51,12 +51,12 @@ jobs:
- name: Install dependencies
run: yarn install
working-directory: nym-wallet/wallet-ui-tests
working-directory: nym-wallet/webdriver
- name: Remove existing user datafile
uses: JesseTG/rm@v1.0.2
with:
path: nym-wallet/wallet-ui-tests/common/user-data.json
path: nym-wallet/webdriver/common/data/user-data.json
- name: Create user data json file
id: create-json
@@ -64,7 +64,7 @@ jobs:
with:
name: "user-data.json"
json: ${{ secrets.WALLET_USERDATA }}
dir: "nym-wallet/wallet-ui-tests/common/"
dir: "nym-wallet/webdriver/common/data/"
- name: Install tauri-driver
uses: actions-rs/cargo@v1
@@ -73,5 +73,5 @@ jobs:
args: tauri-driver
- name: Launch tests
run: xvfb-run yarn test
working-directory: nym-wallet/wallet-ui-tests
run: xvfb-run yarn test:runall
working-directory: nym-wallet/webdriver
+245 -22
View File
@@ -2,20 +2,16 @@
Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Changed
- validator-client: made `fee` argument optional for `execute` and `execute_multiple` ([#1541])
[#1541]: https://github.com/nymtech/nym/pull/1541
## [nym-binaries-1.0.2](https://github.com/nymtech/nym/tree/nym-binaries-1.0.2)
## [Unreleased]
### Added
- 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])
- nym-connect: add ability to export gateway keys as JSON
- nym-connect: add auto updater
- 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
@@ -33,7 +29,6 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- validator-client: add `denom` argument and add simple test for querying an account balance
- gateway, validator-api: Checks for coconut credential double spending attempts, taking the coconut bandwidth contract as source of truth ([#1457])
- coconut-bandwidth-contract: Record the state of a coconut credential; create specific proposal for releasing funds ([#1457])
- inclusion-probability: add simulator for active set inclusion probability
### Fixed
@@ -44,12 +39,10 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- native & socks5 clients: rerun init will now reuse previous gateway configuration instead of failing ([#1353])
- native & socks5 clients: deduplicate big chunks of init logic
- validator: fixed local docker-compose setup to work on Apple M1 ([#1329])
- explorer-api: listen out for SIGTERM and SIGQUIT too, making it play nicely as a system service ([#1482]).
- network-requester: fix filter for suffix-only domains ([#1487])
- validator-api: listen out for SIGTERM and SIGQUIT too, making it play nicely as a system service ([#1496]).
### Changed
- nym-connect: reuse config id instead of creating a new id on each connection
- validator-client: created internal `Coin` type that replaces coins from `cosmrs` and `cosmwasm` for API entrypoints [[#1295]]
- all: updated all `cosmwasm`-related dependencies to `1.0.0` and `cw-storage-plus` to `0.13.4` [[#1318]]
- all: updated `rocket` to `0.5.0-rc.2`.
@@ -60,9 +53,6 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- validator-api: fee payment for multisig operations comes from the gateway account instead of the validator APIs' accounts ([#1419])
- multisig-contract: Limit the proposal creating functionality to one address (coconut-bandwidth-contract address) ([#1457])
- All binaries and cosmwasm blobs are configured at runtime now; binaries are configured using environment variables or .env files and contracts keep the configuration parameters in storage ([#1463])
- gateway, network-statistics: include gateway id in the sent statistical data ([#1478])
- network explorer: tweak how active set probability is shown ([#1503])
- validator-api: rewarder set update fails without panicking on possible nymd queries ([#1520])
[#1249]: https://github.com/nymtech/nym/pull/1249
@@ -84,14 +74,78 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
[#1393]: https://github.com/nymtech/nym/pull/1393
[#1404]: https://github.com/nymtech/nym/pull/1404
[#1419]: https://github.com/nymtech/nym/pull/1419
[#1427]: https://github.com/nymtech/nym/pull/1427
[#1457]: https://github.com/nymtech/nym/pull/1457
[#1463]: https://github.com/nymtech/nym/pull/1463
[#1478]: https://github.com/nymtech/nym/pull/1478
[#1482]: https://github.com/nymtech/nym/pull/1482
[#1487]: https://github.com/nymtech/nym/pull/1487
[#1496]: https://github.com/nymtech/nym/pull/1496
[#1503]: https://github.com/nymtech/nym/pull/1503
[#1520]: https://github.com/nymtech/nym/pull/1520
## [nym-wallet-v1.0.7](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.7) (2022-07-11)
- wallet: dark mode
- wallet: when simulating gas costs, an automatic adjustment is being used ([#1388]).
[#1388]: https://github.com/nymtech/nym/pull/1388
## [nym-contracts-v1.0.1](https://github.com/nymtech/nym/tree/nym-contracts-v1.0.1) (2022-06-22)
### Added
- mixnet-contract: Added ClaimOperatorReward and ClaimDelegatorReward messages ([#1292])
- mixnet-contract: Replace all naked `-` with `saturating_sub`.
- mixnet-contract: Added staking_supply field to ContractStateParams.
- mixnet-contract: Added a query to get MixnodeBond by identity key ([#1369]).
- mixnet-contract: Added a query to get GatewayBond by identity key ([#1369]).
- vesting-contract: Added ClaimOperatorReward and ClaimDelegatorReward messages ([#1292])
- vesting-contract: Added limit to the amount of tokens one can pledge ([#1331])
### Fixed
- mixnet-contract: `estimated_delegator_reward` calculation ([#1284])
- mixnet-contract: delegator and operator rewards use lambda and sigma instead of lambda_ticked and sigma_ticked ([#1284])
- mixnet-contract: removed `expect` in `query_delegator_reward` and queries containing invalid proxy address should now return a more human-readable error ([#1257])
- mixnet-contract: replaced integer division with fixed for performance calculations ([#1284])
- mixnet-contract: Under certain circumstances nodes could not be unbonded ([#1255](https://github.com/nymtech/nym/issues/1255)) ([#1258])
- mixnet-contract: Using correct staking supply when distributing rewards. ([#1373])
- vesting-contract: replaced `checked_sub` with `saturating_sub` to fix the underflow in `get_vesting_tokens` ([#1275])
[#1255]: https://github.com/nymtech/nym/pull/1255
[#1257]: https://github.com/nymtech/nym/pull/1257
[#1258]: https://github.com/nymtech/nym/pull/1258
[#1275]: https://github.com/nymtech/nym/pull/1275
[#1284]: https://github.com/nymtech/nym/pull/1284
[#1292]: https://github.com/nymtech/nym/pull/1292
[#1331]: https://github.com/nymtech/nym/pull/1331
[#1369]: https://github.com/nymtech/nym/pull/1369
[#1373]: https://github.com/nymtech/nym/pull/1373
## [nym-wallet-v1.0.6](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.6) (2022-06-21)
- wallet: undelegating now uses either the mixnet or vesting contract, or both, depending on how delegations were made
- wallet: redeeming and compounding now uses both the mixnet and vesting contract
- wallet: the wallet backend learned how to archive wallet files
- wallet: add ENABLE_QA_MODE environment variable to enable QA mode on built wallet
## [nym-wallet-v1.0.5](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.5) (2022-06-14)
- wallet: add simple CLI tool for decrypting and recovering the wallet file.
- wallet: added support for multiple accounts ([#1265])
- wallet: compound and claim reward endpoints for operators and delegators ([#1302])
- wallet: require password to switch accounts
- wallet: the wallet backend learned how to keep track of validator name, either hardcoded or by querying the status endpoint.
- wallet: new delegation and rewards UI
- wallet: show version in nav bar
- wallet: contract admin route put back
- wallet: staking_supply field to StateParams
- wallet: show transaction hash for redeeming or compounding rewards
[#1265]: https://github.com/nymtech/nym/pull/1265
[#1302]: https://github.com/nymtech/nym/pull/1302
## [nym-wallet-v1.0.4](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.4) (2022-05-04)
### Changed
- all: the default behaviour of validator client is changed to use `broadcast_sync` and poll for transaction inclusion instead of using `broadcast_commit` to deal with timeouts ([#1246])
## [v1.0.1](https://github.com/nymtech/nym/tree/v1.0.1) (2022-05-04)
@@ -124,10 +178,77 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
[Full Changelog](https://github.com/nymtech/nym/compare/nym-wallet-v1.0.3...nym-binaries-1.0.0)
## [nym-wallet-v1.0.3](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.3) (2022-04-25)
[Full Changelog](https://github.com/nymtech/nym/compare/nym-binaries-1.0.0-rc.2...nym-wallet-v1.0.3)
**Fixed bugs:**
- \[Issue\] Wallet 1.0.2 cannot send NYM tokens from a DelayedVestingAccount [\#1215](https://github.com/nymtech/nym/issues/1215)
- Main README not showing properly with GitHub dark mode [\#1211](https://github.com/nymtech/nym/issues/1211)
**Merged pull requests:**
- Bugfix - wallet undelegation for vesting accounts [\#1220](https://github.com/nymtech/nym/pull/1220) ([mmsinclair](https://github.com/mmsinclair))
- Bugfix/delegation reconcile [\#1219](https://github.com/nymtech/nym/pull/1219) ([jstuczyn](https://github.com/jstuczyn))
- Bugfix/query proxied pending delegations [\#1218](https://github.com/nymtech/nym/pull/1218) ([jstuczyn](https://github.com/jstuczyn))
- Using custom gas multiplier in the wallet [\#1217](https://github.com/nymtech/nym/pull/1217) ([jstuczyn](https://github.com/jstuczyn))
- Feature/vesting accounts support [\#1216](https://github.com/nymtech/nym/pull/1216) ([jstuczyn](https://github.com/jstuczyn))
- Release/1.0.0 rc.2 [\#1214](https://github.com/nymtech/nym/pull/1214) ([jstuczyn](https://github.com/jstuczyn))
- chore: fix dark mode rendering [\#1212](https://github.com/nymtech/nym/pull/1212) ([pwnfoo](https://github.com/pwnfoo))
- Feature/spend coconut [\#1210](https://github.com/nymtech/nym/pull/1210) ([neacsu](https://github.com/neacsu))
- Bugfix/unique sphinx key [\#1207](https://github.com/nymtech/nym/pull/1207) ([jstuczyn](https://github.com/jstuczyn))
- Add cache read and write timeouts [\#1206](https://github.com/nymtech/nym/pull/1206) ([durch](https://github.com/durch))
- Additional, more informative routes [\#1204](https://github.com/nymtech/nym/pull/1204) ([durch](https://github.com/durch))
- Feature/aggregated econ dynamics explorer endpoint [\#1203](https://github.com/nymtech/nym/pull/1203) ([jstuczyn](https://github.com/jstuczyn))
- Debugging validator [\#1198](https://github.com/nymtech/nym/pull/1198) ([durch](https://github.com/durch))
- wallet: expose additional validator configuration functionality to the frontend [\#1195](https://github.com/nymtech/nym/pull/1195) ([octol](https://github.com/octol))
- Update rewarding validator address [\#1193](https://github.com/nymtech/nym/pull/1193) ([durch](https://github.com/durch))
- Crypto part of the Groth's NIDKG [\#1182](https://github.com/nymtech/nym/pull/1182) ([jstuczyn](https://github.com/jstuczyn))
- fix unbond page [\#1180](https://github.com/nymtech/nym/pull/1180) ([tommyv1987](https://github.com/tommyv1987))
- Type safe bounds [\#1179](https://github.com/nymtech/nym/pull/1179) ([durch](https://github.com/durch))
- Fix delegation paging [\#1174](https://github.com/nymtech/nym/pull/1174) ([durch](https://github.com/durch))
- Update binaries to rc version [\#1172](https://github.com/nymtech/nym/pull/1172) ([tommyv1987](https://github.com/tommyv1987))
- Bump ansi-regex from 4.1.0 to 4.1.1 in /docker/typescript\_client/upload\_contract [\#1171](https://github.com/nymtech/nym/pull/1171) ([dependabot[bot]](https://github.com/apps/dependabot))
## [nym-binaries-1.0.0-rc.2](https://github.com/nymtech/nym/tree/nym-binaries-1.0.0-rc.2) (2022-04-15)
[Full Changelog](https://github.com/nymtech/nym/compare/nym-wallet-v1.0.2...nym-binaries-1.0.0-rc.2)
## [nym-wallet-v1.0.2](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.2) (2022-04-05)
[Full Changelog](https://github.com/nymtech/nym/compare/nym-wallet-v1.0.1...nym-wallet-v1.0.2)
**Merged pull requests:**
- Wallet 1.0.2 visual tweaks [\#1197](https://github.com/nymtech/nym/pull/1197) ([mmsinclair](https://github.com/mmsinclair))
- Password for wallet with routes [\#1196](https://github.com/nymtech/nym/pull/1196) ([fmtabbara](https://github.com/fmtabbara))
- Add auto-updater to Nym Wallet [\#1194](https://github.com/nymtech/nym/pull/1194) ([mmsinclair](https://github.com/mmsinclair))
- Fix clippy warnings for beta toolchain [\#1191](https://github.com/nymtech/nym/pull/1191) ([octol](https://github.com/octol))
- wallet: expose validator urls to the frontend [\#1190](https://github.com/nymtech/nym/pull/1190) ([octol](https://github.com/octol))
- wallet: add test for decrypting stored wallet file [\#1189](https://github.com/nymtech/nym/pull/1189) ([octol](https://github.com/octol))
- Fix clippy warnings [\#1188](https://github.com/nymtech/nym/pull/1188) ([octol](https://github.com/octol))
- Password for wallet with routes [\#1187](https://github.com/nymtech/nym/pull/1187) ([mmsinclair](https://github.com/mmsinclair))
- wallet: add validate\_mnemonic [\#1186](https://github.com/nymtech/nym/pull/1186) ([octol](https://github.com/octol))
- wallet: support removing accounts from the wallet file [\#1185](https://github.com/nymtech/nym/pull/1185) ([octol](https://github.com/octol))
- Feature/adding discord [\#1184](https://github.com/nymtech/nym/pull/1184) ([gala1234](https://github.com/gala1234))
- wallet: config backend for validator selection [\#1183](https://github.com/nymtech/nym/pull/1183) ([octol](https://github.com/octol))
- Add storybook to wallet [\#1178](https://github.com/nymtech/nym/pull/1178) ([mmsinclair](https://github.com/mmsinclair))
- wallet: connection test nymd and api urls independently [\#1170](https://github.com/nymtech/nym/pull/1170) ([octol](https://github.com/octol))
- wallet: wire up account storage [\#1153](https://github.com/nymtech/nym/pull/1153) ([octol](https://github.com/octol))
- Feature/signature on deposit [\#1151](https://github.com/nymtech/nym/pull/1151) ([neacsu](https://github.com/neacsu))
## [nym-wallet-v1.0.1](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.1) (2022-04-05)
[Full Changelog](https://github.com/nymtech/nym/compare/nym-binaries-1.0.0-rc.1...nym-wallet-v1.0.1)
**Closed issues:**
- Check enabling bbbc simultaneously with open access. Estimate what it would take to make this the default compilation target. [\#1175](https://github.com/nymtech/nym/issues/1175)
- Get coconut credential for deposited tokens [\#1138](https://github.com/nymtech/nym/issues/1138)
- Make payments lazy [\#1135](https://github.com/nymtech/nym/issues/1135)
- Uptime on node selection for sets [\#1049](https://github.com/nymtech/nym/issues/1049)
## [nym-binaries-1.0.0-rc.1](https://github.com/nymtech/nym/tree/nym-binaries-1.0.0-rc.1) (2022-03-28)
[Full Changelog](https://github.com/nymtech/nym/compare/nym-wallet-v1.0.0...nym-binaries-1.0.0-rc.1)
@@ -206,6 +327,108 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- feature/pedersen-commitments [\#1048](https://github.com/nymtech/nym/pull/1048) ([danielementary](https://github.com/danielementary))
- Feature/reuse init owner [\#970](https://github.com/nymtech/nym/pull/970) ([neacsu](https://github.com/neacsu))
## [nym-wallet-v1.0.0](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.0) (2022-02-03)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.12.1...nym-wallet-v1.0.0)
**Implemented enhancements:**
- \[Feature Request\] Please enable registration without need for Telegram account [\#1016](https://github.com/nymtech/nym/issues/1016)
- Fast mixnode launch with a pre-built ISO + VM software [\#1001](https://github.com/nymtech/nym/issues/1001)
**Fixed bugs:**
- \[Issue\] [\#1000](https://github.com/nymtech/nym/issues/1000)
- \[Issue\] `nym-client` requires multiple attempts to run a server [\#869](https://github.com/nymtech/nym/issues/869)
- De-'float'-ing `Interval` \(`Display` impl + `serde`\) [\#1065](https://github.com/nymtech/nym/pull/1065) ([jstuczyn](https://github.com/jstuczyn))
- display client address on wallet creation [\#1058](https://github.com/nymtech/nym/pull/1058) ([fmtabbara](https://github.com/fmtabbara))
**Closed issues:**
- Rewarded set inclusion probability API endpoint [\#1037](https://github.com/nymtech/nym/issues/1037)
- Update cw-storage-plus to 0.11 [\#1032](https://github.com/nymtech/nym/issues/1032)
- Change `u128` fields in `RewardEstimationResponse` to `u64` [\#1029](https://github.com/nymtech/nym/issues/1029)
- Test out the mainnet Gravity Bridge [\#1006](https://github.com/nymtech/nym/issues/1006)
- Add vesting contract interface to nym-wallet [\#959](https://github.com/nymtech/nym/issues/959)
- Mixnode crash [\#486](https://github.com/nymtech/nym/issues/486)
**Merged pull requests:**
- create custom urls for mainnet [\#1095](https://github.com/nymtech/nym/pull/1095) ([fmtabbara](https://github.com/fmtabbara))
- Wallet signing on MacOS [\#1093](https://github.com/nymtech/nym/pull/1093) ([mmsinclair](https://github.com/mmsinclair))
- Fix rust 2018 idioms warnings [\#1092](https://github.com/nymtech/nym/pull/1092) ([octol](https://github.com/octol))
- Prevent contract overwriting [\#1090](https://github.com/nymtech/nym/pull/1090) ([durch](https://github.com/durch))
- Logout operation [\#1087](https://github.com/nymtech/nym/pull/1087) ([jstuczyn](https://github.com/jstuczyn))
- Update to rust edition 2021 everywhere [\#1086](https://github.com/nymtech/nym/pull/1086) ([octol](https://github.com/octol))
- Tag contract errors, and print out lines for easier QA [\#1084](https://github.com/nymtech/nym/pull/1084) ([durch](https://github.com/durch))
- Feature/flexible vesting + utility queries [\#1083](https://github.com/nymtech/nym/pull/1083) ([durch](https://github.com/durch))
- Bump @openzeppelin/contracts from 4.3.1 to 4.4.2 in /contracts/basic-bandwidth-generation [\#1082](https://github.com/nymtech/nym/pull/1082) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump nth-check from 2.0.0 to 2.0.1 in /clients/native/examples/js-examples/websocket [\#1081](https://github.com/nymtech/nym/pull/1081) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump url-parse from 1.5.1 to 1.5.4 in /clients/native/examples/js-examples/websocket [\#1080](https://github.com/nymtech/nym/pull/1080) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump follow-redirects from 1.14.1 to 1.14.7 in /clients/native/examples/js-examples/websocket [\#1079](https://github.com/nymtech/nym/pull/1079) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump nanoid from 3.1.23 to 3.2.0 in /clients/native/examples/js-examples/websocket [\#1078](https://github.com/nymtech/nym/pull/1078) ([dependabot[bot]](https://github.com/apps/dependabot))
- Setup basic test for mixnode stats reporting [\#1077](https://github.com/nymtech/nym/pull/1077) ([octol](https://github.com/octol))
- Make wallet\_address mandatory for mixnode init [\#1076](https://github.com/nymtech/nym/pull/1076) ([octol](https://github.com/octol))
- Tidy nym-mixnode module visibility [\#1075](https://github.com/nymtech/nym/pull/1075) ([octol](https://github.com/octol))
- Feature/wallet login with password [\#1074](https://github.com/nymtech/nym/pull/1074) ([fmtabbara](https://github.com/fmtabbara))
- Add trait to mock client dependency in DelayForwarder [\#1073](https://github.com/nymtech/nym/pull/1073) ([octol](https://github.com/octol))
- Bump rust-version to latest stable for nym-mixnode [\#1072](https://github.com/nymtech/nym/pull/1072) ([octol](https://github.com/octol))
- Fixes CI for our wasm build [\#1069](https://github.com/nymtech/nym/pull/1069) ([jstuczyn](https://github.com/jstuczyn))
- Add @octol as codeowner [\#1068](https://github.com/nymtech/nym/pull/1068) ([octol](https://github.com/octol))
- set-up inclusion probability [\#1067](https://github.com/nymtech/nym/pull/1067) ([fmtabbara](https://github.com/fmtabbara))
- Feature/wasm client [\#1066](https://github.com/nymtech/nym/pull/1066) ([neacsu](https://github.com/neacsu))
- Changed bech32\_prefix from punk to nymt [\#1064](https://github.com/nymtech/nym/pull/1064) ([jstuczyn](https://github.com/jstuczyn))
- Bump nanoid from 3.1.30 to 3.2.0 in /testnet-faucet [\#1063](https://github.com/nymtech/nym/pull/1063) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump nanoid from 3.1.30 to 3.2.0 in /nym-wallet [\#1062](https://github.com/nymtech/nym/pull/1062) ([dependabot[bot]](https://github.com/apps/dependabot))
- Rework vesting contract storage [\#1061](https://github.com/nymtech/nym/pull/1061) ([durch](https://github.com/durch))
- Mixnet Contract constants extraction [\#1060](https://github.com/nymtech/nym/pull/1060) ([jstuczyn](https://github.com/jstuczyn))
- fix: make explorer footer year dynamic [\#1059](https://github.com/nymtech/nym/pull/1059) ([martinyung](https://github.com/martinyung))
- Add mnemonic just on creation, to display it [\#1057](https://github.com/nymtech/nym/pull/1057) ([neacsu](https://github.com/neacsu))
- Network Explorer: updates to API and UI to show the active set [\#1056](https://github.com/nymtech/nym/pull/1056) ([mmsinclair](https://github.com/mmsinclair))
- Made contract addresses for query NymdClient construction optional [\#1055](https://github.com/nymtech/nym/pull/1055) ([jstuczyn](https://github.com/jstuczyn))
- Introduced RPC query for total token supply [\#1053](https://github.com/nymtech/nym/pull/1053) ([jstuczyn](https://github.com/jstuczyn))
- Feature/tokio console [\#1052](https://github.com/nymtech/nym/pull/1052) ([durch](https://github.com/durch))
- Implemented beta clippy lint recommendations [\#1051](https://github.com/nymtech/nym/pull/1051) ([jstuczyn](https://github.com/jstuczyn))
- add new function to update profit percentage [\#1050](https://github.com/nymtech/nym/pull/1050) ([fmtabbara](https://github.com/fmtabbara))
- Upgrade Clap and use declarative argument parsing for nym-mixnode [\#1047](https://github.com/nymtech/nym/pull/1047) ([octol](https://github.com/octol))
- Feature/additional bond validation [\#1046](https://github.com/nymtech/nym/pull/1046) ([fmtabbara](https://github.com/fmtabbara))
- Fix clippy on relevant lints [\#1044](https://github.com/nymtech/nym/pull/1044) ([neacsu](https://github.com/neacsu))
- Bump shelljs from 0.8.4 to 0.8.5 in /contracts/basic-bandwidth-generation [\#1043](https://github.com/nymtech/nym/pull/1043) ([dependabot[bot]](https://github.com/apps/dependabot))
- Endpoint for rewarded set inclusion probabilities [\#1042](https://github.com/nymtech/nym/pull/1042) ([durch](https://github.com/durch))
- Bump follow-redirects from 1.14.4 to 1.14.7 in /contracts/basic-bandwidth-generation [\#1041](https://github.com/nymtech/nym/pull/1041) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump follow-redirects from 1.14.5 to 1.14.7 in /testnet-faucet [\#1040](https://github.com/nymtech/nym/pull/1040) ([dependabot[bot]](https://github.com/apps/dependabot))
- Feature/node settings update [\#1036](https://github.com/nymtech/nym/pull/1036) ([fmtabbara](https://github.com/fmtabbara))
- Migrate to cw-storage-plus 0.11.1 [\#1035](https://github.com/nymtech/nym/pull/1035) ([durch](https://github.com/durch))
- Bump @openzeppelin/contracts from 4.4.1 to 4.4.2 in /contracts/basic-bandwidth-generation [\#1034](https://github.com/nymtech/nym/pull/1034) ([dependabot[bot]](https://github.com/apps/dependabot))
- Feature/configurable wallet [\#1033](https://github.com/nymtech/nym/pull/1033) ([neacsu](https://github.com/neacsu))
- Feature/downcast reward estimation [\#1031](https://github.com/nymtech/nym/pull/1031) ([durch](https://github.com/durch))
- Wallet UI updates [\#1028](https://github.com/nymtech/nym/pull/1028) ([fmtabbara](https://github.com/fmtabbara))
- Remove migration code [\#1027](https://github.com/nymtech/nym/pull/1027) ([neacsu](https://github.com/neacsu))
- Chore/stricter dependency requirements [\#1025](https://github.com/nymtech/nym/pull/1025) ([jstuczyn](https://github.com/jstuczyn))
- Feature/validator api client endpoints [\#1024](https://github.com/nymtech/nym/pull/1024) ([jstuczyn](https://github.com/jstuczyn))
- Updated cosmrs to 0.4.1 [\#1023](https://github.com/nymtech/nym/pull/1023) ([jstuczyn](https://github.com/jstuczyn))
- Feature/testnet deploy scripts [\#1022](https://github.com/nymtech/nym/pull/1022) ([mfahampshire](https://github.com/mfahampshire))
- Changed wallet's client to a full validator client [\#1021](https://github.com/nymtech/nym/pull/1021) ([jstuczyn](https://github.com/jstuczyn))
- Fix 404 link [\#1020](https://github.com/nymtech/nym/pull/1020) ([RiccardoMasutti](https://github.com/RiccardoMasutti))
- Feature/additional mixnode endpoints [\#1019](https://github.com/nymtech/nym/pull/1019) ([jstuczyn](https://github.com/jstuczyn))
- Introduced denom check when trying to withdraw vested coins [\#1018](https://github.com/nymtech/nym/pull/1018) ([jstuczyn](https://github.com/jstuczyn))
- Add network defaults for qa [\#1017](https://github.com/nymtech/nym/pull/1017) ([neacsu](https://github.com/neacsu))
- Feature/expanded events [\#1015](https://github.com/nymtech/nym/pull/1015) ([jstuczyn](https://github.com/jstuczyn))
- update frontend to use new profit update api [\#1014](https://github.com/nymtech/nym/pull/1014) ([fmtabbara](https://github.com/fmtabbara))
- Feature/node state endpoint [\#1013](https://github.com/nymtech/nym/pull/1013) ([jstuczyn](https://github.com/jstuczyn))
- Feature/hourly set updates [\#1012](https://github.com/nymtech/nym/pull/1012) ([durch](https://github.com/durch))
- Feature/remove unused profit margin [\#1011](https://github.com/nymtech/nym/pull/1011) ([neacsu](https://github.com/neacsu))
- Feature/explorer node status [\#1010](https://github.com/nymtech/nym/pull/1010) ([jstuczyn](https://github.com/jstuczyn))
- Use serial integer instead of random [\#1009](https://github.com/nymtech/nym/pull/1009) ([durch](https://github.com/durch))
- Feature/configure profit [\#1008](https://github.com/nymtech/nym/pull/1008) ([neacsu](https://github.com/neacsu))
- Feature/fix gateway sign [\#1004](https://github.com/nymtech/nym/pull/1004) ([neacsu](https://github.com/neacsu))
- Fix clippy [\#1003](https://github.com/nymtech/nym/pull/1003) ([neacsu](https://github.com/neacsu))
- Update wallet version [\#998](https://github.com/nymtech/nym/pull/998) ([tommyv1987](https://github.com/tommyv1987))
- Fix wallet build instructions [\#997](https://github.com/nymtech/nym/pull/997) ([tommyv1987](https://github.com/tommyv1987))
- Make the separation between testnet-mode and erc20 bandwidth mode clearer [\#994](https://github.com/nymtech/nym/pull/994) ([neacsu](https://github.com/neacsu))
- Bump @openzeppelin/contracts from 3.4.0 to 4.4.1 in /contracts/basic-bandwidth-generation [\#983](https://github.com/nymtech/nym/pull/983) ([dependabot[bot]](https://github.com/apps/dependabot))
- Feature/implicit runtime [\#973](https://github.com/nymtech/nym/pull/973) ([jstuczyn](https://github.com/jstuczyn))
- Differentiate staking and ownership [\#961](https://github.com/nymtech/nym/pull/961) ([durch](https://github.com/durch))
## [v0.12.1](https://github.com/nymtech/nym/tree/v0.12.1) (2021-12-23)
Generated
+476 -532
View File
File diff suppressed because it is too large Load Diff
+7 -9
View File
@@ -22,23 +22,22 @@ members = [
"clients/native",
"clients/native/websocket-requests",
"clients/socks5",
"common/bandwidth-claim-contract",
"common/client-libs/gateway-client",
"common/client-libs/mixnet-client",
"common/client-libs/validator-client",
"common/credential-storage",
"common/coconut-interface",
"common/config",
"common/credentials",
"common/crypto",
"common/crypto/dkg",
"common/execute",
"common/bandwidth-claim-contract",
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
"common/cosmwasm-smart-contracts/contracts-common",
"common/cosmwasm-smart-contracts/mixnet-contract",
"common/cosmwasm-smart-contracts/multisig-contract",
"common/cosmwasm-smart-contracts/vesting-contract",
"common/credential-storage",
"common/credentials",
"common/crypto",
"common/crypto/dkg",
"common/execute",
"common/inclusion-probability",
"common/mixnode-common",
"common/network-defaults",
"common/nonexhaustive-delayqueue",
@@ -54,9 +53,9 @@ members = [
"common/nymsphinx/params",
"common/nymsphinx/types",
"common/pemstore",
"common/statistics",
"common/socks5/proxy-helpers",
"common/socks5/requests",
"common/statistics",
"common/task",
"common/topology",
"common/types",
@@ -77,7 +76,6 @@ default-members = [
"clients/socks5",
"gateway",
"service-providers/network-requester",
"service-providers/network-statistics",
"mixnode",
"validator-api",
"explorer-api",
+1 -1
View File
@@ -1,5 +1,5 @@
test: clippy-all cargo-test wasm fmt
test-all: test cargo-test-expensive
test: build clippy-all cargo-test wasm fmt
no-clippy: build cargo-test wasm fmt
happy: fmt clippy-happy test
clippy-all: clippy-all-main clippy-all-contracts clippy-all-wallet clippy-all-connect
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-client"
version = "1.0.2"
version = "1.0.1"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client"
edition = "2021"
+14 -2
View File
@@ -3,6 +3,7 @@
use crate::client::config::{Config, SocketType};
use clap::{Parser, Subcommand};
use url::Url;
#[cfg(not(feature = "coconut"))]
pub(crate) const DEFAULT_ETH_ENDPOINT: &str =
@@ -96,17 +97,28 @@ pub(crate) async fn execute(args: &Cli) {
}
}
fn parse_validators(raw: &str) -> Vec<Url> {
raw.split(',')
.map(|raw_validator| {
raw_validator
.trim()
.parse()
.expect("one of the provided validator api urls is invalid")
})
.collect()
}
pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Config {
if let Some(raw_validators) = args.validators {
config
.get_base_mut()
.set_custom_validator_apis(config::parse_validators(&raw_validators));
.set_custom_validator_apis(parse_validators(&raw_validators));
} else if std::env::var(network_defaults::var_names::CONFIGURED).is_ok() {
let raw_validators = std::env::var(network_defaults::var_names::API_VALIDATOR)
.expect("api validator not set");
config
.get_base_mut()
.set_custom_validator_apis(config::parse_validators(&raw_validators));
.set_custom_validator_apis(parse_validators(&raw_validators));
}
if args.disable_socket {
+1 -1
View File
@@ -82,7 +82,7 @@ fn version_check(cfg: &Config) -> bool {
if binary_version == config_version {
true
} else {
warn!("The native-client binary has different version than what is specified in config file! {} and {}", binary_version, config_version);
warn!("The mixnode binary has different version than what is specified in config file! {} and {}", binary_version, config_version);
if is_minor_version_compatible(binary_version, config_version) {
info!("but they are still semver compatible. However, consider running the `upgrade` command");
true
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-socks5-client"
version = "1.0.2"
version = "1.0.1"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
edition = "2021"
+12 -1
View File
@@ -3,7 +3,7 @@
use crate::client::config::Config;
use clap::{Parser, Subcommand};
use config::parse_validators;
use url::Url;
pub mod init;
pub(crate) mod run;
@@ -96,6 +96,17 @@ pub(crate) async fn execute(args: &Cli) {
}
}
fn parse_validators(raw: &str) -> Vec<Url> {
raw.split(',')
.map(|raw_validator| {
raw_validator
.trim()
.parse()
.expect("one of the provided validator api urls is invalid")
})
.collect()
}
pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Config {
if let Some(raw_validators) = args.validators {
config
+5
View File
@@ -2,4 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
pub mod client;
// This is only used as we reach into the init functions in nym-connect. We need to refactor the
// init functions so that nym-connect can just call the same init function as the regular socks5
// client.
#[allow(unused)]
pub mod commands;
pub mod socks;
+3 -7
View File
@@ -5,7 +5,7 @@ use futures::StreamExt;
use log::*;
use nymsphinx::receiver::ReconstructedMessage;
use proxy_helpers::connection_controller::{ControllerCommand, ControllerSender};
use socks5_requests::Message;
use socks5_requests::Response;
pub(crate) struct MixnetResponseListener {
buffer_requester: ReceivedBufferRequestSender,
@@ -44,16 +44,12 @@ impl MixnetResponseListener {
warn!("this message had a surb - we didn't do anything with it");
}
let response = match Message::try_from_bytes(&raw_message) {
let response = match Response::try_from_bytes(&raw_message) {
Err(err) => {
warn!("failed to parse received response - {:?}", err);
return;
}
Ok(Message::Request(_)) => {
warn!("unexpected request");
return;
}
Ok(Message::Response(data)) => data,
Ok(data) => data,
};
self.controller_sender
@@ -893,7 +893,7 @@ impl<C> NymdClient<C> {
&self,
contract_address: &AccountId,
msg: &M,
fee: Option<Fee>,
fee: Fee,
memo: impl Into<String> + Send + 'static,
funds: Vec<Coin>,
) -> Result<ExecuteResult, NymdError>
@@ -901,7 +901,6 @@ impl<C> NymdClient<C> {
C: SigningCosmWasmClient + Sync,
M: ?Sized + Serialize + Sync,
{
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
self.client
.execute(self.address(), contract_address, msg, fee, memo, funds)
.await
@@ -911,7 +910,7 @@ impl<C> NymdClient<C> {
&self,
contract_address: &AccountId,
msgs: I,
fee: Option<Fee>,
fee: Fee,
memo: impl Into<String> + Send + 'static,
) -> Result<ExecuteResult, NymdError>
where
@@ -919,7 +918,6 @@ impl<C> NymdClient<C> {
I: IntoIterator<Item = (M, Vec<Coin>)> + Send,
M: Serialize,
{
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
self.client
.execute_multiple(self.address(), contract_address, msgs, fee, memo)
.await
@@ -1008,29 +1006,6 @@ impl<C> NymdClient<C> {
.await
}
#[execute("mixnet")]
fn _compound_reward(
&self,
operator: Option<String>,
delegator: Option<String>,
mix_identity: Option<IdentityKey>,
proxy: Option<String>,
fee: Option<Fee>,
) -> (ExecuteMsg, Option<Fee>)
where
C: SigningCosmWasmClient + Sync,
{
(
ExecuteMsg::CompoundReward {
operator,
delegator,
mix_identity,
proxy,
},
fee,
)
}
#[execute("mixnet")]
fn _compound_operator_reward(&self, fee: Option<Fee>) -> (ExecuteMsg, Option<Fee>)
where
-11
View File
@@ -88,14 +88,3 @@ pub trait NymConfig: Default + Serialize + DeserializeOwned {
.map_err(|toml_err| io::Error::new(io::ErrorKind::Other, toml_err))
}
}
pub fn parse_validators(raw: &str) -> Vec<url::Url> {
raw.split(',')
.map(|raw_validator| {
raw_validator
.trim()
.parse()
.expect("one of the provided validator api urls is invalid")
})
.collect()
}
@@ -37,7 +37,7 @@ impl SpendCredentialData {
}
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
pub enum SpendCredentialStatus {
InProgress,
Spent,
@@ -33,12 +33,6 @@ pub enum ExecuteMsg {
CompoundDelegatorReward {
mix_identity: IdentityKey,
},
CompoundReward {
operator: Option<String>,
delegator: Option<String>,
mix_identity: Option<IdentityKey>,
proxy: Option<String>,
},
BondMixnode {
mix_node: MixNode,
owner_signature: String,
@@ -122,7 +116,6 @@ pub enum ExecuteMsg {
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum QueryMsg {
GetBlacklistedNodes {},
GetCurrentOperatorCost {},
GetRewardingValidatorAddress {},
GetAllDelegationKeys {},
@@ -215,29 +208,4 @@ pub enum QueryMsg {
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct MigrateMsg {
pub mixnet_denom: String,
nodes_to_remove: Option<Vec<NodeToRemove>>,
}
impl MigrateMsg {
pub fn nodes_to_remove(&self) -> Vec<NodeToRemove> {
self.nodes_to_remove.clone().unwrap_or_default()
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct NodeToRemove {
owner: String,
proxy: Option<String>,
}
impl NodeToRemove {
pub fn owner(&self) -> &str {
&self.owner
}
pub fn proxy(&self) -> Option<&String> {
self.proxy.as_ref()
}
}
pub struct MigrateMsg {}
@@ -12,9 +12,7 @@ pub struct InitMsg {
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct MigrateMsg {
pub mix_denom: String,
}
pub struct MigrateMsg {}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, Default)]
pub struct VestingSpecification {
-10
View File
@@ -1,10 +0,0 @@
[package]
name = "inclusion-probability"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand = "0.8.5"
thiserror = "1.0.32"
@@ -1,9 +0,0 @@
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("The list of cumulative stake was unexpectedly empty")]
EmptyListCumulStake,
#[error("Sample point was unexpectedly out of bounds")]
SamplePointOutOfBounds,
#[error("Norm computation failed on different size arrarys")]
NormDifferenceSizeArrays,
}
-278
View File
@@ -1,278 +0,0 @@
//! Active set inclusion probability simulator
use error::Error;
mod error;
const TOLERANCE_L2_NORM: f64 = 1e-4;
const TOLERANCE_MAX_NORM: f64 = 1e-3;
pub struct SelectionProbability {
pub active_set_probability: Vec<f64>,
pub reserve_set_probability: Vec<f64>,
pub samples: u32,
pub delta_l2: f64,
pub delta_max: f64,
}
pub fn simulate_selection_probability_mixnodes(
list_stake_for_mixnodes: &[u64],
active_set_size: usize,
reserve_set_size: usize,
max_samples: u32,
) -> Result<SelectionProbability, Error> {
// Total number of existing (registered) nodes
let num_mixnodes = list_stake_for_mixnodes.len();
// Cumulative stake ordered by node index
let list_cumul = cumul_sum(list_stake_for_mixnodes);
// The computed probabilities
let mut active_set_probability = vec![0.0; num_mixnodes];
let mut reserve_set_probability = vec![0.0; num_mixnodes];
// Number sufficiently large to have a good approximation of selection probability
let mut samples = 0;
let mut delta_l2;
let mut delta_max;
let mut rng = rand::thread_rng();
loop {
samples += 1;
let mut sample_active_mixnodes = Vec::new();
let mut sample_reserve_mixnodes = Vec::new();
let mut list_cumul_temp = list_cumul.clone();
let active_set_probability_previous = active_set_probability.clone();
// Select the active nodes for the epoch (hour)
while sample_active_mixnodes.len() < active_set_size {
let candidate = sample_candidate(&list_cumul_temp, &mut rng)?;
if !sample_active_mixnodes.contains(&candidate) {
sample_active_mixnodes.push(candidate);
remove_mixnode_from_cumul_stake(candidate, &mut list_cumul_temp);
}
}
// Select the reserve nodes for the epoch (hour)
while sample_reserve_mixnodes.len() < reserve_set_size {
let candidate = sample_candidate(&list_cumul_temp, &mut rng)?;
if !sample_reserve_mixnodes.contains(&candidate)
&& !sample_active_mixnodes.contains(&candidate)
{
sample_reserve_mixnodes.push(candidate);
remove_mixnode_from_cumul_stake(candidate, &mut list_cumul_temp);
}
}
// Sum up nodes being in active or reserve set
for active_mixnodes in sample_active_mixnodes {
active_set_probability[active_mixnodes] += 1.0;
}
for reserve_mixnodes in sample_reserve_mixnodes {
reserve_set_probability[reserve_mixnodes] += 1.0;
}
// Convergence critera only on active set.
// We devide by samples to get the average, that is not really part of the delta
// computation.
delta_l2 = l2_diff(&active_set_probability, &active_set_probability_previous)?
/ f64::from(samples);
delta_max = max_diff(&active_set_probability, &active_set_probability_previous)?
/ f64::from(samples);
if samples > 10 && delta_l2 < TOLERANCE_L2_NORM && delta_max < TOLERANCE_MAX_NORM
|| samples >= max_samples
{
break;
}
}
active_set_probability
.iter_mut()
.for_each(|x| *x /= f64::from(samples));
reserve_set_probability
.iter_mut()
.for_each(|x| *x /= f64::from(samples));
Ok(SelectionProbability {
active_set_probability,
reserve_set_probability,
samples,
delta_l2,
delta_max,
})
}
// Compute the cumulative sum
fn cumul_sum<'a>(list: impl IntoIterator<Item = &'a u64>) -> Vec<u64> {
let mut list_cumul = Vec::new();
let mut cumul = 0;
for entry in list {
cumul += entry;
list_cumul.push(cumul);
}
list_cumul
}
fn sample_candidate(list_cumul: &[u64], rng: &mut rand::rngs::ThreadRng) -> Result<usize, Error> {
use rand::distributions::{Distribution, Uniform};
let uniform = Uniform::from(0..*list_cumul.last().ok_or(Error::EmptyListCumulStake)?);
let r = uniform.sample(rng);
let candidate = list_cumul
.iter()
.enumerate()
.find(|(_, x)| *x >= &r)
.ok_or(Error::SamplePointOutOfBounds)?
.0;
Ok(candidate)
}
// Update list of cumulative stake to reflect eliminating the picked node
fn remove_mixnode_from_cumul_stake(candidate: usize, list_cumul_stake: &mut [u64]) {
let prob_candidate = if candidate == 0 {
list_cumul_stake[0]
} else {
list_cumul_stake[candidate] - list_cumul_stake[candidate - 1]
};
for cumul in list_cumul_stake.iter_mut().skip(candidate) {
*cumul -= prob_candidate;
}
}
// Compute the difference in l2-norm
fn l2_diff(v1: &[f64], v2: &[f64]) -> Result<f64, Error> {
if v1.len() != v2.len() {
return Err(Error::NormDifferenceSizeArrays);
}
Ok(v1
.iter()
.zip(v2)
.map(|(&i1, &i2)| (i1 - i2).powi(2))
.sum::<f64>()
.sqrt())
}
// Compute the difference in max-norm
fn max_diff(v1: &[f64], v2: &[f64]) -> Result<f64, Error> {
if v1.len() != v2.len() {
return Err(Error::NormDifferenceSizeArrays);
}
Ok(v1
.iter()
.zip(v2)
.map(|(x, y)| (x - y).abs())
.fold(f64::NEG_INFINITY, f64::max))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn compute_cumul_sum() {
let v = cumul_sum(&vec![1, 2, 3]);
assert_eq!(v, &[1, 3, 6]);
}
#[test]
fn remove_mixnode_from_cumul() {
let mut cumul_stake = vec![1, 2, 3, 4, 5, 6];
remove_mixnode_from_cumul_stake(3, &mut cumul_stake);
assert_eq!(cumul_stake, &[1, 2, 3, 3, 4, 5]);
}
#[test]
fn max_norm() {
let v1 = vec![1.0, 2.0, 3.0];
let v2 = vec![2.0, 4.0, -6.0];
assert!((max_diff(&v1, &v2).unwrap() - 9.0).abs() < f64::EPSILON);
}
#[test]
fn ls_norm() {
let v1 = vec![1.0, 2.0, 3.0];
let v2 = vec![2.0, 3.0, -2.0];
assert!((l2_diff(&v1, &v2).unwrap() - 5.196_152_422_706_632).abs() < 1e2 * f64::EPSILON);
}
// Replicate the results from the Python simulation code in https://github.com/nymtech/team-core/issues/114
#[test]
fn replicate_python_simulation() {
let active_set_size = 4;
let standby_set_size = 1;
// this has to contain the total stake per node
let list_mix = vec![
100, 100, 3000, 500_000, 100, 10, 10, 10, 10, 10, 30000, 500, 200, 52345,
];
let max_samples = 100_000;
let SelectionProbability {
active_set_probability,
reserve_set_probability,
samples,
delta_l2,
delta_max,
} = simulate_selection_probability_mixnodes(
&list_mix,
active_set_size,
standby_set_size,
max_samples,
)
.unwrap();
// These values comes from running the python simulator for a very long time
let expected_active_set_probability = vec![
0.025_070_8,
0.025_073_2,
0.744_117,
0.999_999,
0.025_000_2,
0.002_524_4,
0.002_527_8,
0.002_528_6,
0.002_569_6,
0.002_513_6,
0.994,
0.125_482_8,
0.050_279_8,
0.998_313_2,
];
// The same check is used in the convergence criterion, and hence should be reflected in
// `delta_max` too.
assert!(
max_diff(&active_set_probability, &expected_active_set_probability).unwrap() < 1e-2
);
let expected_reserve_set_probability = vec![
0.076_392_4,
0.076_499,
0.204_893_6,
1e-06,
0.076_278_8,
0.007_720_6,
0.007_673,
0.007_700_2,
0.007_669_4,
0.007_731_2,
0.005_789_4,
0.368_465_6,
0.151_537_2,
0.001_648_6,
];
assert!(
max_diff(&reserve_set_probability, &expected_reserve_set_probability).unwrap() < 1e-2
);
// We converge around 20_000, add another 500 for some slack due to random values
assert!(samples < 20_500);
assert!(delta_l2 < TOLERANCE_L2_NORM);
assert!(delta_max < TOLERANCE_MAX_NORM);
}
}
+1 -1
View File
@@ -24,7 +24,7 @@ pub(crate) const _ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] =
hex_literal::hex!("0000000000000000000000000000000000000000");
pub(crate) const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy";
pub(crate) const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "https://mainnet-stats.nymte.ch:8090/";
pub(crate) const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "http://127.0.0.1:8090";
pub const NYMD_VALIDATOR: &str = "https://rpc.nyx.nodes.guru/";
pub const API_VALIDATOR: &str = "https://validator.nymtech.net/api/";
pub(crate) fn validators() -> Vec<ValidatorDetails> {
+2 -6
View File
@@ -34,16 +34,12 @@ pub enum StatsData {
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct StatsGatewayData {
pub gateway_id: String,
pub inbox_count: u32,
}
impl StatsGatewayData {
pub fn new(gateway_id: String, inbox_count: u32) -> Self {
StatsGatewayData {
gateway_id,
inbox_count,
}
pub fn new(inbox_count: u32) -> Self {
StatsGatewayData { inbox_count }
}
}
+1 -1
View File
@@ -507,7 +507,7 @@ mod test {
for (expected, raw_display) in values {
let coin = DecCoin {
denom: Network::MAINNET.mix_denom().display,
denom: Network::MAINNET.mix_denom().display.into(),
amount: raw_display.parse().unwrap(),
};
let base = reg.attempt_convert_to_base_coin(coin).unwrap();
-32
View File
@@ -1,32 +0,0 @@
## [nym-contracts-v1.0.1](https://github.com/nymtech/nym/tree/nym-contracts-v1.0.1) (2022-06-22)
### Added
- mixnet-contract: Added ClaimOperatorReward and ClaimDelegatorReward messages ([#1292])
- mixnet-contract: Replace all naked `-` with `saturating_sub`.
- mixnet-contract: Added staking_supply field to ContractStateParams.
- mixnet-contract: Added a query to get MixnodeBond by identity key ([#1369]).
- mixnet-contract: Added a query to get GatewayBond by identity key ([#1369]).
- vesting-contract: Added ClaimOperatorReward and ClaimDelegatorReward messages ([#1292])
- vesting-contract: Added limit to the amount of tokens one can pledge ([#1331])
### Fixed
- mixnet-contract: `estimated_delegator_reward` calculation ([#1284])
- mixnet-contract: delegator and operator rewards use lambda and sigma instead of lambda_ticked and sigma_ticked ([#1284])
- mixnet-contract: removed `expect` in `query_delegator_reward` and queries containing invalid proxy address should now return a more human-readable error ([#1257])
- mixnet-contract: replaced integer division with fixed for performance calculations ([#1284])
- mixnet-contract: Under certain circumstances nodes could not be unbonded ([#1255](https://github.com/nymtech/nym/issues/1255)) ([#1258])
- mixnet-contract: Using correct staking supply when distributing rewards. ([#1373])
- vesting-contract: replaced `checked_sub` with `saturating_sub` to fix the underflow in `get_vesting_tokens` ([#1275])
[#1255]: https://github.com/nymtech/nym/pull/1255
[#1257]: https://github.com/nymtech/nym/pull/1257
[#1258]: https://github.com/nymtech/nym/pull/1258
[#1275]: https://github.com/nymtech/nym/pull/1275
[#1284]: https://github.com/nymtech/nym/pull/1284
[#1292]: https://github.com/nymtech/nym/pull/1292
[#1331]: https://github.com/nymtech/nym/pull/1331
[#1369]: https://github.com/nymtech/nym/pull/1369
[#1373]: https://github.com/nymtech/nym/pull/1373
+4 -4
View File
@@ -1392,18 +1392,18 @@ dependencies = [
[[package]]
name = "regex"
version = "1.6.0"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.27"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "rfc6979"
+7 -76
View File
@@ -27,18 +27,16 @@ use crate::mixnodes::bonding_queries::{
query_checkpoints_for_mixnode, query_mixnode_at_height, query_mixnodes_paged,
};
use crate::mixnodes::layer_queries::query_layer_distribution;
use crate::mixnodes::transactions::_try_remove_mixnode;
use crate::queued_migrations::migrate_config_from_env;
use crate::rewards::queries::{
query_circulating_supply, query_reward_pool, query_rewarding_status, query_staking_supply,
};
use crate::rewards::storage as rewards_storage;
use cosmwasm_std::{
entry_point, to_binary, Addr, Api, Deps, DepsMut, Env, MessageInfo, QueryResponse, Response,
Storage, Uint128,
Uint128,
};
use mixnet_contract_common::{
ContractStateParams, ExecuteMsg, InstantiateMsg, MigrateMsg, NodeToRemove, QueryMsg,
ContractStateParams, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg,
};
use time::OffsetDateTime;
@@ -114,19 +112,6 @@ pub fn execute(
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
match msg {
ExecuteMsg::CompoundReward {
operator,
delegator,
mix_identity,
proxy,
} => crate::rewards::transactions::try_compound_reward(
deps,
env,
operator,
delegator,
mix_identity,
proxy,
),
ExecuteMsg::UpdateRewardingValidatorAddress { address } => {
try_update_rewarding_validator_address(deps, info, address)
}
@@ -142,7 +127,7 @@ pub fn execute(
owner_signature,
),
ExecuteMsg::UnbondMixnode {} => {
crate::mixnodes::transactions::try_remove_mixnode(&env, deps.storage, deps.api, info)
crate::mixnodes::transactions::try_remove_mixnode(env, deps, info)
}
ExecuteMsg::UpdateMixnodeConfig {
profit_margin_percent,
@@ -236,13 +221,7 @@ pub fn execute(
owner_signature,
),
ExecuteMsg::UnbondMixnodeOnBehalf { owner } => {
crate::mixnodes::transactions::try_remove_mixnode_on_behalf(
&env,
deps.storage,
deps.api,
info,
owner,
)
crate::mixnodes::transactions::try_remove_mixnode_on_behalf(env, deps, info, owner)
}
ExecuteMsg::BondGatewayOnBehalf {
gateway,
@@ -301,7 +280,7 @@ pub fn execute(
)
}
ExecuteMsg::ReconcileDelegations {} => {
crate::delegations::transactions::try_reconcile_all_delegation_events(deps)
crate::delegations::transactions::try_reconcile_all_delegation_events(deps, info)
}
ExecuteMsg::CheckpointMixnodes {} => {
crate::mixnodes::transactions::try_checkpoint_mixnodes(
@@ -342,9 +321,6 @@ pub fn execute(
#[entry_point]
pub fn query(deps: Deps<'_>, env: Env, msg: QueryMsg) -> Result<QueryResponse, ContractError> {
let query_res = match msg {
QueryMsg::GetBlacklistedNodes {} => to_binary(
&crate::mixnodes::bonding_queries::get_blacklisted_nodes(deps),
),
QueryMsg::GetRewardingValidatorAddress {} => {
to_binary(&query_rewarding_validator_address(deps)?)
}
@@ -472,54 +448,9 @@ pub fn query(deps: Deps<'_>, env: Env, msg: QueryMsg) -> Result<QueryResponse, C
Ok(query_res?)
}
fn blacklist_malicious_node(storage: &mut dyn Storage, owner: &Addr) -> Result<(), ContractError> {
let mixnode_bond = match crate::mixnodes::storage::mixnodes()
.idx
.owner
.item(storage, owner.clone())?
{
Some(record) => record.1,
None => {
return Err(ContractError::NoAssociatedMixNodeBond {
owner: owner.to_owned(),
})
}
};
crate::mixnodes::storage::MIXNODES_BOND_BLACKLIST.save(storage, mixnode_bond.identity(), &0)?;
Ok(())
}
// Removes nodes we've deemed malicious, returns the pledge to the owners, but does not send any rewards
fn remove_malicious_node(
storage: &mut dyn Storage,
api: &dyn Api,
env: &Env,
node: &NodeToRemove,
) -> Result<Response, ContractError> {
let proxy = node.proxy().map(|p| {
api.addr_validate(p)
.unwrap_or_else(|_| panic!("Invalid address: {}", p))
});
let owner_addr = api.addr_validate(node.owner())?;
blacklist_malicious_node(storage, &owner_addr)?;
_try_remove_mixnode(env, storage, api, node.owner(), proxy, false)
}
#[entry_point]
pub fn migrate(deps: DepsMut<'_>, env: Env, msg: MigrateMsg) -> Result<Response, ContractError> {
migrate_config_from_env(deps.storage, &msg)?;
let mut response = Response::new();
for node in msg.nodes_to_remove().iter() {
let mut sub_response = remove_malicious_node(deps.storage, deps.api, &env, node)
.unwrap_or_else(|_| panic!("Could not remove node: {:?}", node));
response.messages.append(&mut sub_response.messages);
response.attributes.append(&mut sub_response.attributes);
response.events.append(&mut sub_response.events);
}
Ok(response)
pub fn migrate(_deps: DepsMut<'_>, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
Ok(Default::default())
}
#[cfg(test)]
+183 -35
View File
@@ -19,7 +19,16 @@ use mixnet_contract_common::{Delegation, IdentityKey};
use vesting_contract_common::messages::ExecuteMsg as VestingContractExecuteMsg;
use vesting_contract_common::one_ucoin;
pub fn try_reconcile_all_delegation_events(deps: DepsMut<'_>) -> Result<Response, ContractError> {
pub fn try_reconcile_all_delegation_events(
deps: DepsMut<'_>,
info: MessageInfo,
) -> Result<Response, ContractError> {
let state = mixnet_params_storage::CONTRACT_STATE.load(deps.storage)?;
// check if this is executed by the permitted validator, if not reject the transaction
if info.sender != state.rewarding_validator_address {
return Err(ContractError::Unauthorized);
}
_try_reconcile_all_delegation_events(deps.storage, deps.api)
}
@@ -621,14 +630,7 @@ mod tests {
deps.as_mut(),
);
let delegation_owner = Addr::unchecked("sender");
let api = deps.api.clone();
try_remove_mixnode(
&mock_env(),
deps.as_mut().storage,
&api,
mock_info(mixnode_owner, &[]),
)
.unwrap();
try_remove_mixnode(mock_env(), deps.as_mut(), mock_info(mixnode_owner, &[])).unwrap();
assert_eq!(
Err(ContractError::MixNodeBondNotFound {
identity: identity.clone()
@@ -651,14 +653,7 @@ mod tests {
tests::fixtures::good_mixnode_pledge(),
deps.as_mut(),
);
let api = deps.api.clone();
try_remove_mixnode(
&mock_env(),
deps.as_mut().storage,
&api,
mock_info(mixnode_owner, &[]),
)
.unwrap();
try_remove_mixnode(mock_env(), deps.as_mut(), mock_info(mixnode_owner, &[])).unwrap();
let identity = test_helpers::add_mixnode(
mixnode_owner,
tests::fixtures::good_mixnode_pledge(),
@@ -922,14 +917,7 @@ mod tests {
identity.clone(),
)
.unwrap();
let api = deps.api.clone();
try_remove_mixnode(
&mock_env(),
deps.as_mut().storage,
&api,
mock_info(mixnode_owner, &[]),
)
.unwrap();
try_remove_mixnode(mock_env(), deps.as_mut(), mock_info(mixnode_owner, &[])).unwrap();
assert_eq!(
Err(ContractError::MixNodeBondNotFound {
identity: identity.clone()
@@ -1070,14 +1058,8 @@ mod tests {
.unwrap();
_try_reconcile_all_delegation_events(&mut deps.storage, &deps.api).unwrap();
let api = deps.api.clone();
try_remove_mixnode(
&mock_env(),
deps.as_mut().storage,
&api,
mock_info(mixnode_owner, &[]),
)
.unwrap();
try_remove_mixnode(mock_env(), deps.as_mut(), mock_info(mixnode_owner, &[])).unwrap();
let expected = Delegation::new(
delegation_owner.clone(),
@@ -1102,13 +1084,179 @@ mod tests {
#[cfg(test)]
mod removing_mix_stake_delegation {
use super::*;
use crate::support::tests;
use cosmwasm_std::coin;
use cosmwasm_std::testing::mock_env;
use cosmwasm_std::testing::mock_info;
use cosmwasm_std::Addr;
use crate::support::tests;
use super::*;
// TODO: Probably delete due to reconciliation logic
//#[ignore]
//#[test]
//fn fails_if_delegation_never_existed() {
// let mut deps = test_helpers::init_contract();
// let env = mock_env();
// let mixnode_owner = "bob";
// let identity = test_helpers::add_mixnode(
// mixnode_owner,
// tests::fixtures::good_mixnode_pledge(),
// deps.as_mut(),
// );
// let delegation_owner = Addr::unchecked("sender");
// assert_eq!(
// Err(ContractError::NoMixnodeDelegationFound {
// identity: identity.clone(),
// address: delegation_owner.to_string(),
// }),
// try_remove_delegation_from_mixnode(
// deps.as_mut(),
// env,
// mock_info(delegation_owner.as_str(), &[]),
// identity,
// )
// );
//}
// TODO: Update to work with reconciliation
//#[ignore]
//#[test]
//fn succeeds_if_delegation_existed() {
// let mut deps = test_helpers::init_contract();
// let mixnode_owner = "bob";
// let env = mock_env();
// let identity = test_helpers::add_mixnode(
// mixnode_owner,
// tests::fixtures::good_mixnode_pledge(),
// deps.as_mut(),
// );
// let delegation_owner = Addr::unchecked("sender");
// try_delegate_to_mixnode(
// deps.as_mut(),
// mock_env(),
// mock_info(delegation_owner.as_str(), &coins(100, TEST_COIN_DENOM)),
// identity.clone(),
// )
// .unwrap();
// _try_reconcile_all_delegation_events(&mut deps.storage, &deps.api).unwrap();
// let _delegation = query_mixnode_delegation(
// &deps.storage,
// &deps.api,
// identity.clone(),
// delegation_owner.clone().into_string(),
// None,
// )
// .unwrap();
// let expected_response = Response::new()
// .add_message(BankMsg::Send {
// to_address: delegation_owner.clone().into(),
// amount: coins(100, TEST_COIN_DENOM),
// })
// .add_event(new_undelegation_event(
// &delegation_owner,
// &None,
// &identity,
// Uint128::new(100),
// ));
// assert_eq!(
// Ok(expected_response),
// try_remove_delegation_from_mixnode(
// deps.as_mut(),
// env,
// mock_info(delegation_owner.as_str(), &[]),
// identity.clone(),
// )
// );
// assert!(storage::delegations()
// .may_load(
// &deps.storage,
// (identity.clone(), delegation_owner.as_bytes().to_vec(), 0),
// )
// .unwrap()
// .is_none());
// // and total delegation is cleared
// assert_eq!(
// Uint128::zero(),
// mixnodes_storage::TOTAL_DELEGATION
// .load(&deps.storage, &identity)
// .unwrap()
// )
//}
// TODO: Update to work with reconciliation
//#[ignore]
//#[test]
//fn succeeds_if_delegation_existed_even_if_node_unbonded() {
// let mut deps = test_helpers::init_contract();
// let mixnode_owner = "bob";
// let env = mock_env();
// let identity = test_helpers::add_mixnode(
// mixnode_owner,
// tests::fixtures::good_mixnode_pledge(),
// deps.as_mut(),
// );
// let delegation_owner = Addr::unchecked("sender");
// try_delegate_to_mixnode(
// deps.as_mut(),
// mock_env(),
// mock_info(delegation_owner.as_str(), &coins(100, TEST_COIN_DENOM)),
// identity.clone(),
// )
// .unwrap();
// _try_reconcile_all_delegation_events(&mut deps.storage, &deps.api).unwrap();
// let _delegation = query_mixnode_delegation(
// &deps.storage,
// &deps.api,
// identity.clone(),
// delegation_owner.clone().into_string(),
// None,
// )
// .unwrap();
// let expected_response = Response::new()
// .add_message(BankMsg::Send {
// to_address: delegation_owner.clone().into(),
// amount: coins(100, TEST_COIN_DENOM),
// })
// .add_event(new_undelegation_event(
// &delegation_owner,
// &None,
// &identity,
// Uint128::new(100),
// ));
// try_remove_mixnode(mock_env(), deps.as_mut(), mock_info(mixnode_owner, &[])).unwrap();
// assert_eq!(
// Ok(expected_response),
// try_remove_delegation_from_mixnode(
// deps.as_mut(),
// env,
// mock_info(delegation_owner.as_str(), &[]),
// identity.clone(),
// )
// );
// _try_reconcile_all_delegation_events(&mut deps.storage, &deps.api).unwrap();
// assert!(test_helpers::read_delegation(
// &deps.storage,
// identity,
// delegation_owner.as_bytes(),
// mock_env().block.height
// )
// .is_none());
//}
#[test]
fn total_delegation_is_preserved_if_only_some_undelegate() {
let mut deps = test_helpers::init_contract();
-7
View File
@@ -178,11 +178,4 @@ pub enum ContractError {
last_update_time: u64,
current_block_time: u64,
},
#[error("`mix_identity` is required when `delegator` is set")]
MissingMixIdentity,
#[error("Compounding has been disabled temporarily")]
CompoundDisabled,
#[error("Mixnode {identity} has been blacklisted on the network")]
MixnodeBlacklisted { identity: String },
}
-1
View File
@@ -9,6 +9,5 @@ mod gateways;
mod interval;
mod mixnet_contract_settings;
mod mixnodes;
mod queued_migrations;
mod rewards;
mod support;
@@ -8,13 +8,6 @@ use mixnet_contract_common::{
IdentityKey, MixNodeBond, MixOwnershipResponse, MixnodeBondResponse, PagedMixnodeResponse,
};
pub fn get_blacklisted_nodes(deps: Deps<'_>) -> Vec<IdentityKey> {
storage::MIXNODES_BOND_BLACKLIST
.keys(deps.storage, None, None, Order::Ascending)
.filter_map(|i| i.ok())
.collect()
}
pub fn query_mixnode_at_height(
deps: Deps<'_>,
mix_identity: String,
@@ -259,13 +252,10 @@ pub(crate) mod tests {
let res = query_owns_mixnode(deps.as_ref(), "fred".to_string()).unwrap();
assert!(res.mixnode.is_some());
let api = deps.api.clone();
// but after unbonding it, he doesn't own one anymore
crate::mixnodes::transactions::try_remove_mixnode(
&env,
deps.as_mut().storage,
&api,
env,
deps.as_mut(),
mock_info("fred", &[]),
)
.unwrap();
-4
View File
@@ -19,7 +19,6 @@ const MIXNODES_PK_CHECKPOINTS: &str = "mn__check";
const MIXNODES_PK_CHANGELOG: &str = "mn__change";
const MIXNODES_OWNER_IDX_NAMESPACE: &str = "mno";
const MIXNODES_SPHINX_IDX_NAMESPACE: &str = "mns";
const MIXNODES_BOND_BLACKLIST_NAMESPACE: &str = "mbb";
const LAST_PM_UPDATE_NAMESPACE: &str = "lpm";
@@ -33,9 +32,6 @@ pub(crate) const TOTAL_DELEGATION: Map<'_, IdentityKeyRef<'_>, Uint128> =
pub(crate) const LAST_PM_UPDATE_TIME: Map<'_, IdentityKeyRef<'_>, u64> =
Map::new(LAST_PM_UPDATE_NAMESPACE);
pub(crate) const MIXNODES_BOND_BLACKLIST: Map<'_, IdentityKeyRef<'_>, u8> =
Map::new(MIXNODES_BOND_BLACKLIST_NAMESPACE);
pub(crate) struct MixnodeBondIndex<'a> {
pub(crate) owner: UniqueIndex<'a, Addr, StoredMixnodeBond>,
+27 -43
View File
@@ -8,12 +8,12 @@ use crate::mixnodes::layer_queries::query_layer_distribution;
use crate::mixnodes::storage::StoredMixnodeBond;
use crate::support::helpers::{ensure_no_existing_bond, validate_node_identity_signature};
use cosmwasm_std::{
wasm_execute, Addr, Api, BankMsg, Coin, DepsMut, Env, MessageInfo, Response, Storage, Uint128,
wasm_execute, Addr, BankMsg, Coin, DepsMut, Env, MessageInfo, Response, Storage, Uint128,
};
use mixnet_contract_common::events::{
new_checkpoint_mixnodes_event, new_mixnode_bonding_event, new_mixnode_unbonding_event,
};
use mixnet_contract_common::{IdentityKeyRef, MixNode};
use mixnet_contract_common::MixNode;
use vesting_contract_common::messages::ExecuteMsg as VestingContractExecuteMsg;
use vesting_contract_common::one_ucoin;
@@ -87,15 +87,6 @@ pub fn try_add_mixnode_on_behalf(
)
}
pub fn is_blacklisted(
storage: &dyn Storage,
identity: IdentityKeyRef,
) -> Result<bool, ContractError> {
Ok(storage::MIXNODES_BOND_BLACKLIST
.may_load(storage, identity)?
.is_some())
}
fn _try_add_mixnode(
deps: DepsMut<'_>,
env: Env,
@@ -109,12 +100,6 @@ fn _try_add_mixnode(
// if the client has an active bonded mixnode or gateway, don't allow bonding
ensure_no_existing_bond(deps.storage, &owner)?;
if is_blacklisted(deps.storage, &mix_node.identity_key)? {
return Err(ContractError::MixnodeBlacklisted {
identity: mix_node.identity_key,
});
};
// We don't have to check lower bound as its an u8
if mix_node.profit_margin_percent > 100 {
return Err(ContractError::InvalidProfitMarginPercent(
@@ -182,47 +167,45 @@ fn _try_add_mixnode(
}
pub fn try_remove_mixnode_on_behalf(
env: &Env,
storage: &mut dyn Storage,
api: &dyn Api,
env: Env,
deps: DepsMut<'_>,
info: MessageInfo,
owner: String,
) -> Result<Response, ContractError> {
let proxy = info.sender;
_try_remove_mixnode(env, storage, api, &owner, Some(proxy), true)
_try_remove_mixnode(env, deps, &owner, Some(proxy))
}
pub fn try_remove_mixnode(
env: &Env,
storage: &mut dyn Storage,
api: &dyn Api,
env: Env,
deps: DepsMut<'_>,
info: MessageInfo,
) -> Result<Response, ContractError> {
_try_remove_mixnode(env, storage, api, info.sender.as_ref(), None, true)
_try_remove_mixnode(env, deps, info.sender.as_ref(), None)
}
pub(crate) fn _try_remove_mixnode(
env: &Env,
storage: &mut dyn Storage,
api: &dyn Api,
env: Env,
deps: DepsMut<'_>,
owner: &str,
proxy: Option<Addr>,
collect_rewards: bool,
) -> Result<Response, ContractError> {
let owner = api.addr_validate(owner)?;
let owner = deps.api.addr_validate(owner)?;
if collect_rewards {
crate::rewards::transactions::_try_compound_operator_reward(
storage,
api,
env.block.height,
&owner,
None,
)?;
}
crate::rewards::transactions::_try_compound_operator_reward(
deps.storage,
deps.api,
env.block.height,
&owner,
None,
)?;
// try to find the node of the sender
let mixnode_bond = match storage::mixnodes().idx.owner.item(storage, owner.clone())? {
let mixnode_bond = match storage::mixnodes()
.idx
.owner
.item(deps.storage, owner.clone())?
{
Some(record) => record.1,
None => return Err(ContractError::NoAssociatedMixNodeBond { owner }),
};
@@ -242,10 +225,10 @@ pub(crate) fn _try_remove_mixnode(
};
// remove the bond
storage::mixnodes().remove(storage, mixnode_bond.identity(), env.block.height)?;
storage::mixnodes().remove(deps.storage, mixnode_bond.identity(), env.block.height)?;
// decrement layer count
mixnet_params_storage::decrement_layer_count(storage, mixnode_bond.layer)?;
mixnet_params_storage::decrement_layer_count(deps.storage, mixnode_bond.layer)?;
let mut response = Response::new();
@@ -255,7 +238,8 @@ pub(crate) fn _try_remove_mixnode(
amount: mixnode_bond.pledge_amount(),
};
let track_unbond_message = wasm_execute(proxy, &msg, vec![one_ucoin(mix_denom(storage)?)])?;
let track_unbond_message =
wasm_execute(proxy, &msg, vec![one_ucoin(mix_denom(deps.storage)?)])?;
response = response.add_message(track_unbond_message);
}
-37
View File
@@ -1,37 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use cosmwasm_std::{Addr, Response, Storage};
use cw_storage_plus::Item;
use mixnet_contract_common::{ContractStateParams, MigrateMsg};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::error::ContractError;
use crate::mixnet_contract_settings::models::ContractState;
use crate::mixnet_contract_settings::storage::CONTRACT_STATE;
pub fn migrate_config_from_env(
storage: &mut dyn Storage,
msg: &MigrateMsg,
) -> Result<Response, ContractError> {
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct OldContractState {
pub owner: Addr,
pub rewarding_validator_address: Addr,
pub params: ContractStateParams,
}
const OLD_CONTRACT_STATE: Item<'_, OldContractState> = Item::new("config");
let old_state = OLD_CONTRACT_STATE.load(storage)?;
let new_state = ContractState {
owner: old_state.owner,
mix_denom: msg.mixnet_denom.clone(),
rewarding_validator_address: old_state.rewarding_validator_address,
params: old_state.params,
};
CONTRACT_STATE.save(storage, &new_state)?;
Ok(Default::default())
}
+2 -72
View File
@@ -13,7 +13,6 @@ use crate::error::ContractError;
use crate::mixnet_contract_settings::storage::mix_denom;
use crate::mixnodes::storage::mixnodes;
use crate::mixnodes::storage::{self as mixnodes_storage, StoredMixnodeBond};
use crate::mixnodes::transactions::is_blacklisted;
use crate::rewards::helpers;
use crate::support::helpers::{is_authorized, operator_cost_at_epoch};
use cosmwasm_std::{
@@ -373,56 +372,6 @@ pub fn try_compound_delegator_reward_on_behalf(
)
}
pub fn try_compound_reward(
deps: DepsMut<'_>,
env: Env,
operator: Option<String>,
delegator: Option<String>,
mix_identity: Option<IdentityKey>,
proxy: Option<String>,
) -> Result<Response, ContractError> {
let proxy = proxy.and_then(|p| deps.api.addr_validate(&p).ok());
if let Some(operator_address) = operator {
let operator_address = deps.api.addr_validate(&operator_address)?;
let reward = _try_compound_operator_reward(
deps.storage,
deps.api,
env.block.height,
&operator_address,
proxy,
)?;
Ok(
Response::default().add_event(new_compound_operator_reward_event(
&operator_address,
reward,
)),
)
} else if let Some(delegator_address) = delegator {
if mix_identity.is_none() {
return Err(ContractError::MissingMixIdentity);
}
let delegator_address = deps.api.addr_validate(&delegator_address)?;
let reward = _try_compound_delegator_reward(
env.block.height,
deps,
delegator_address.as_str(),
mix_identity.as_ref().unwrap(),
proxy,
)?;
Ok(
Response::default().add_event(new_compound_delegator_reward_event(
&delegator_address,
&None,
reward,
&mix_identity.unwrap(),
)),
)
} else {
Ok(Response::default())
}
}
pub fn try_compound_delegator_reward(
deps: DepsMut<'_>,
env: Env,
@@ -463,7 +412,7 @@ pub fn _try_compound_delegator_reward(
proxy.as_ref(),
);
let reward = calculate_delegator_reward(deps.storage, deps.api, key.clone(), mix_identity)?;
let mut total_delegation_delegate = Uint128::zero();
let mut compounded_delegation = reward;
// Might want to introduce paging here
let delegation_heights = delegation_map
@@ -475,7 +424,7 @@ pub fn _try_compound_delegator_reward(
for h in delegation_heights {
let delegation =
delegation_map.load(deps.storage, (mix_identity.to_string(), key.clone(), h))?;
total_delegation_delegate += delegation.amount.amount;
compounded_delegation += delegation.amount.amount;
delegation_map.replace(
deps.storage,
(mix_identity.to_string(), key.clone(), h),
@@ -484,22 +433,7 @@ pub fn _try_compound_delegator_reward(
)?;
}
let compounded_delegation = total_delegation_delegate + reward;
if compounded_delegation != Uint128::zero() {
mixnodes_storage::TOTAL_DELEGATION.update::<_, ContractError>(
deps.storage,
mix_identity,
|total_delegation| {
// since we know that the target node exists and because the total_delegation bucket
// entry is created whenever the node itself is added, the unwrap here is fine
// as the entry MUST exist
Ok(total_delegation
.unwrap()
.saturating_sub(total_delegation_delegate))
},
)?;
_try_delegate_to_mixnode(
deps.branch(),
block_height,
@@ -538,10 +472,6 @@ pub fn calculate_delegator_reward(
key: Vec<u8>,
mix_identity: &str,
) -> Result<Uint128, ContractError> {
if is_blacklisted(storage, mix_identity)? {
return Ok(Uint128::zero());
};
let last_claimed_height = storage::DELEGATOR_REWARD_CLAIMED_HEIGHT
.load(storage, (key.clone(), mix_identity.to_string()))
.unwrap_or(0);
-2
View File
@@ -1,5 +1,4 @@
use crate::errors::ContractError;
use crate::queued_migrations::migrate_config_from_env;
use crate::storage::{
account_from_address, locked_pledge_cap, update_locked_pledge_cap, ADMIN,
MIXNET_CONTRACT_ADDRESS, MIX_DENOM,
@@ -42,7 +41,6 @@ pub fn instantiate(
#[entry_point]
pub fn migrate(_deps: DepsMut<'_>, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
migrate_config_from_env(_deps, _env, _msg)?;
Ok(Response::default())
}
-1
View File
@@ -1,6 +1,5 @@
pub mod contract;
mod errors;
mod queued_migrations;
mod storage;
mod support;
mod traits;
@@ -1,17 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use cosmwasm_std::{DepsMut, Env, Response};
use vesting_contract_common::MigrateMsg;
use crate::{errors::ContractError, storage::MIX_DENOM};
pub fn migrate_config_from_env(
deps: DepsMut<'_>,
_env: Env,
msg: MigrateMsg,
) -> Result<Response, ContractError> {
MIX_DENOM.save(deps.storage, &msg.mix_denom)?;
Ok(Default::default())
}
+3 -2
View File
@@ -101,9 +101,10 @@ impl Account {
}
}
/// Returns the index of the next vesting period. Unless the current time is somehow in the past or vesting has not started yet.
/// In case vesting is over it will always return NUM_VESTING_PERIODS.
pub fn get_current_vesting_period(&self, block_time: Timestamp) -> Period {
// Returns the index of the next vesting period. Unless the current time is somehow in the past or vesting has not started yet.
// In case vesting is over it will always return NUM_VESTING_PERIODS.
if block_time.seconds() < self.periods.first().unwrap().start_time {
Period::Before
} else if self.periods.last().unwrap().end_time() < block_time {
+1 -1
View File
@@ -15,6 +15,6 @@ BANDWIDTH_CLAIM_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0
COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0
MULTISIG_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0
REWARDING_VALIDATOR_ADDRESS=n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy
STATISTICS_SERVICE_DOMAIN_ADDRESS="https://mainnet-stats.nymte.ch:8090"
STATISTICS_SERVICE_DOMAIN_ADDRESS="http://127.0.0.1:8090"
NYMD_VALIDATOR="https://rpc.nyx.nodes.guru/"
API_VALIDATOR="https://validator.nymtech.net/api/"
-1
View File
@@ -26,5 +26,4 @@ tokio = {version = "1.19.1", features = ["full"] }
mixnet-contract-common = { path = "../common/cosmwasm-smart-contracts/mixnet-contract" }
network-defaults = { path = "../common/network-defaults" }
task = { path = "../common/task" }
validator-client = { path = "../common/client-libs/validator-client", features=["nymd-client"] }
@@ -1,5 +1,4 @@
use log::info;
use task::ShutdownListener;
use crate::country_statistics::country_nodes_distribution::CountryNodesDistribution;
use crate::COUNTRY_DATA_REFRESH_INTERVAL;
@@ -8,12 +7,11 @@ use crate::state::ExplorerApiStateContext;
pub(crate) struct CountryStatisticsDistributionTask {
state: ExplorerApiStateContext,
shutdown: ShutdownListener,
}
impl CountryStatisticsDistributionTask {
pub(crate) fn new(state: ExplorerApiStateContext, shutdown: ShutdownListener) -> Self {
CountryStatisticsDistributionTask { state, shutdown }
pub(crate) fn new(state: ExplorerApiStateContext) -> Self {
CountryStatisticsDistributionTask { state }
}
pub(crate) fn start(mut self) {
@@ -22,15 +20,10 @@ impl CountryStatisticsDistributionTask {
let mut interval_timer = tokio::time::interval(std::time::Duration::from_secs(
COUNTRY_DATA_REFRESH_INTERVAL,
));
while !self.shutdown.is_shutdown() {
tokio::select! {
_ = interval_timer.tick() => {
self.calculate_nodes_per_country().await;
}
_ = self.shutdown.recv() => {
trace!("Listener: Received shutdown");
}
}
loop {
// wait for the next interval tick
interval_timer.tick().await;
self.calculate_nodes_per_country().await;
}
});
}
@@ -5,17 +5,15 @@ use crate::mix_nodes::location::{GeoLocation, Location};
use crate::state::ExplorerApiStateContext;
use log::{info, warn};
use reqwest::Error as ReqwestError;
use task::ShutdownListener;
use thiserror::Error;
pub(crate) struct GeoLocateTask {
state: ExplorerApiStateContext,
shutdown: ShutdownListener,
}
impl GeoLocateTask {
pub(crate) fn new(state: ExplorerApiStateContext, shutdown: ShutdownListener) -> Self {
GeoLocateTask { state, shutdown }
pub(crate) fn new(state: ExplorerApiStateContext) -> Self {
GeoLocateTask { state }
}
pub(crate) fn start(mut self) {
@@ -29,15 +27,10 @@ impl GeoLocateTask {
info!("Spawning mix node locator task runner...");
tokio::spawn(async move {
let mut interval_timer = tokio::time::interval(std::time::Duration::from_millis(50));
while !self.shutdown.is_shutdown() {
tokio::select! {
_ = interval_timer.tick() => {
self.locate_mix_nodes().await;
}
_ = self.shutdown.recv() => {
trace!("Listener: Received shutdown");
}
}
loop {
// wait for the next interval tick
interval_timer.tick().await;
self.locate_mix_nodes().await;
}
});
}
+12 -47
View File
@@ -6,7 +6,6 @@ extern crate rocket_okapi;
use clap::Parser;
use log::info;
use network_defaults::setup_env;
use task::ShutdownNotifier;
pub(crate) mod cache;
mod client;
@@ -51,63 +50,29 @@ impl ExplorerApi {
let validator_api_url = self.state.inner.validator_client.api_endpoint();
info!("Using validator API - {}", validator_api_url);
let shutdown = ShutdownNotifier::default();
// spawn concurrent tasks
crate::tasks::ExplorerApiTasks::new(self.state.clone(), shutdown.subscribe()).start();
crate::tasks::ExplorerApiTasks::new(self.state.clone()).start();
country_statistics::distribution::CountryStatisticsDistributionTask::new(
self.state.clone(),
shutdown.subscribe(),
)
.start();
country_statistics::geolocate::GeoLocateTask::new(self.state.clone(), shutdown.subscribe())
.start();
// Rocket handles shutdown on it's own, but its shutdown handling should be incorporated
// with that of the rest of the tasks.
// Currently it's runtime is forcefully terminated once the explorer-api exits.
country_statistics::geolocate::GeoLocateTask::new(self.state.clone()).start();
http::start(self.state.clone());
// wait for user to press ctrl+C
self.wait_for_interrupt(shutdown).await
self.wait_for_interrupt().await
}
async fn wait_for_interrupt(&self, mut shutdown: ShutdownNotifier) {
wait_for_signal().await;
log::info!("Sending shutdown");
shutdown.signal_shutdown().ok();
log::info!("Waiting for tasks to finish... (Press ctrl-c to force)");
shutdown.wait_for_shutdown().await;
log::info!("Stopping explorer API");
}
}
#[cfg(unix)]
async fn wait_for_signal() {
use tokio::signal::unix::{signal, SignalKind};
let mut sigterm = signal(SignalKind::terminate()).expect("Failed to setup SIGTERM channel");
let mut sigquit = signal(SignalKind::quit()).expect("Failed to setup SIGQUIT channel");
tokio::select! {
_ = tokio::signal::ctrl_c() => {
log::info!("Received SIGINT");
},
_ = sigterm.recv() => {
log::info!("Received SIGTERM");
async fn wait_for_interrupt(&self) {
if let Err(e) = tokio::signal::ctrl_c().await {
error!(
"There was an error while capturing SIGINT - {:?}. We will terminate regardless",
e
);
}
_ = sigquit.recv() => {
log::info!("Received SIGQUIT");
}
}
}
#[cfg(not(unix))]
async fn wait_for_signal() {
tokio::select! {
_ = tokio::signal::ctrl_c() => {
log::info!("Received SIGINT");
},
info!(
"Received SIGINT - the mixnode will terminate now (threads are not yet nicely stopped, if you see stack traces that's alright)."
);
}
}
+15 -21
View File
@@ -4,7 +4,6 @@
use std::future::Future;
use mixnet_contract_common::GatewayBond;
use task::ShutdownListener;
use validator_client::models::MixNodeBondAnnotated;
use validator_client::nymd::error::NymdError;
use validator_client::nymd::{Paging, QueryNymdClient, ValidatorResponse};
@@ -15,12 +14,11 @@ use crate::state::ExplorerApiStateContext;
pub(crate) struct ExplorerApiTasks {
state: ExplorerApiStateContext,
shutdown: ShutdownListener,
}
impl ExplorerApiTasks {
pub(crate) fn new(state: ExplorerApiStateContext, shutdown: ShutdownListener) -> Self {
ExplorerApiTasks { state, shutdown }
pub(crate) fn new(state: ExplorerApiStateContext) -> Self {
ExplorerApiTasks { state }
}
// a helper to remove duplicate code when grabbing active/rewarded/all mixnodes
@@ -130,28 +128,24 @@ impl ExplorerApiTasks {
}
}
pub(crate) fn start(mut self) {
pub(crate) fn start(self) {
info!("Spawning mix nodes task runner...");
tokio::spawn(async move {
let mut interval_timer = tokio::time::interval(CACHE_REFRESH_RATE);
while !self.shutdown.is_shutdown() {
tokio::select! {
_ = interval_timer.tick() => {
info!("Updating validator cache...");
self.update_validators_cache().await;
info!("Done");
loop {
// wait for the next interval tick
interval_timer.tick().await;
info!("Updating gateway cache...");
self.update_gateways_cache().await;
info!("Done");
info!("Updating validator cache...");
self.update_validators_cache().await;
info!("Done");
info!("Updating mix node cache...");
self.update_mixnode_cache().await;
}
_ = self.shutdown.recv() => {
trace!("Listener: Received shutdown");
}
}
info!("Updating gateway cache...");
self.update_gateways_cache().await;
info!("Done");
info!("Updating mix node cache...");
self.update_mixnode_cache().await;
}
});
}
+5 -6
View File
@@ -1,6 +1,5 @@
EXPLORER_API_URL=https://explorer.nymtech.net/api/v1
VALIDATOR_API_URL=https://validator.nymtech.net
VALIDATOR_URL=https://rpc.nyx.nodes.guru
BIG_DIPPER_URL=https://blocks.nymtech.net
CURRENCY_DENOM=unym
CURRENCY_STAKING_DENOM=unyx
EXPLORER_API_URL=https://sandbox-explorer.nymtech.net/api/v1
VALIDATOR_API_URL=https://sandbox-validator.nymtech.net
BIG_DIPPER_URL=https://sandbox-blocks.nymtech.net
CURRENCY_DENOM=unymt
CURRENCY_STAKING_DENOM=unyxt
+3 -4
View File
@@ -1,6 +1,5 @@
EXPLORER_API_URL=https://qa-explorer.nymtech.net/api/v1
VALIDATOR_API_URL=https://qa-validator-api.nymtech.net
VALIDATOR_URL=https://qa-validator.nymtech.net
VALIDATOR_API_URL=https://qa-validator.nymtech.net
BIG_DIPPER_URL=https://qa-blocks.nymtech.net
CURRENCY_DENOM=unym
CURRENCY_STAKING_DENOM=unyx
CURRENCY_DENOM=unymt
CURRENCY_STAKING_DENOM=unyxt
+1 -2
View File
@@ -1,7 +1,6 @@
// master APIs
export const API_BASE_URL = process.env.EXPLORER_API_URL;
export const VALIDATOR_API_BASE_URL = process.env.VALIDATOR_API_URL;
export const VALIDATOR_URL = process.env.VALIDATOR_URL;
export const BIG_DIPPER = process.env.BIG_DIPPER_URL;
// specific API routes
@@ -10,7 +9,7 @@ export const MIXNODE_PING = `${API_BASE_URL}/ping`;
export const MIXNODES_API = `${API_BASE_URL}/mix-nodes`;
export const MIXNODE_API = `${API_BASE_URL}/mix-node`;
export const GATEWAYS_API = `${VALIDATOR_API_BASE_URL}/api/v1/gateways`;
export const VALIDATORS_API = `${VALIDATOR_URL}/validators`;
export const VALIDATORS_API = `${VALIDATOR_API_BASE_URL}/validators`;
export const BLOCK_API = `${VALIDATOR_API_BASE_URL}/block`;
export const COUNTRY_DATA_API = `${API_BASE_URL}/countries`;
export const UPTIME_STORY_API = `${VALIDATOR_API_BASE_URL}/api/v1/status/mixnode`; // add ID then '/history' to this.
+10 -19
View File
@@ -6,6 +6,7 @@ import {
DialogContent,
DialogActions,
DialogTitle,
IconButton,
Slider,
Typography,
Box,
@@ -24,9 +25,7 @@ import { useIsMobile } from '../../hooks/useIsMobile';
const FilterItem = ({
label,
id,
tooltipInfo,
value,
isSmooth,
marks,
scale,
min,
@@ -37,13 +36,12 @@ const FilterItem = ({
}) => (
<Box sx={{ p: 2 }}>
<Typography gutterBottom>{label}</Typography>
<Typography fontSize={12}>{tooltipInfo}</Typography>
<Slider
value={value}
onChange={(e: Event, newValue: number | number[]) => onChange(id, newValue as number[])}
valueLabelDisplay={isSmooth ? 'auto' : 'off'}
valueLabelDisplay="off"
marks={marks}
step={isSmooth ? 1 : null}
step={null}
scale={scale}
min={min}
max={max}
@@ -52,7 +50,7 @@ const FilterItem = ({
);
export const Filters = () => {
const { filterMixnodes, fetchMixnodes, mixnodes } = useMainContext();
const { filterMixnodes, fetchMixnodes } = useMainContext();
const { status } = useParams<{ status: MixnodeStatusWithAll | undefined }>();
const isMobile = useIsMobile();
@@ -129,26 +127,19 @@ export const Filters = () => {
<Alert
severity="info"
variant={isMobile ? 'standard' : 'outlined'}
sx={{ color: (t) => t.palette.info.light }}
action={
<Button size="small" onClick={onClearFilters}>
CLEAR FILTERS
Clear
</Button>
}
sx={{ width: 300 }}
>
{mixnodes?.data?.length} mixnodes matched your criteria
Filters applied
</Alert>
</Snackbar>
<Button
size="large"
variant="text"
color="inherit"
endIcon={<Tune />}
onClick={handleToggleShowFilters}
sx={{ textTransform: 'none' }}
>
Advanced filters
</Button>
<IconButton size="large" onClick={handleToggleShowFilters}>
<Tune />
</IconButton>
<Dialog open={showFilters} onClose={handleToggleShowFilters} maxWidth="md" fullWidth>
<DialogTitle>Mixnode filters</DialogTitle>
<DialogContent dividers>
+54 -21
View File
@@ -5,7 +5,6 @@ export const generateFilterSchema = (upperSaturationValue?: number) => ({
label: 'Profit margin (%)',
id: EnumFilterKey.profitMargin,
value: [0, 100],
isSmooth: true,
marks: [
{ label: '0', value: 0 },
{ label: '10', value: 10 },
@@ -19,8 +18,6 @@ export const generateFilterSchema = (upperSaturationValue?: number) => ({
{ label: '90', value: 90 },
{ label: '100', value: 100 },
],
tooltipInfo:
'As a delegator you want to chose nodes with lower profit margin, meaning more payout for their delegators',
},
stakeSaturation: {
label: 'Stake saturation (%)',
@@ -46,29 +43,65 @@ export const generateFilterSchema = (upperSaturationValue?: number) => ({
},
],
max: upperSaturationValue,
tooltipInfo: "Select nodes with <100% saturation. Any additional stake above 100% saturation won't get rewards",
},
routingScore: {
label: 'Routing score (%)',
id: EnumFilterKey.routingScore,
value: [0, 100],
stake: {
label: 'Stake (NYM)',
id: EnumFilterKey.stake,
value: [20, 90],
min: 20,
max: 90,
marks: [
{ label: '0', value: 0 },
{ label: '10', value: 10 },
{ label: '20', value: 20 },
{ label: '30', value: 30 },
{ label: '40', value: 40 },
{ label: '50', value: 50 },
{ label: '60', value: 60 },
{ label: '70', value: 70 },
{ label: '80', value: 80 },
{ label: '90', value: 90 },
{ label: '100', value: 100 },
{
value: 0,
label: '1',
},
{
value: 10,
label: '10',
},
{
value: 20,
label: '100',
},
{
value: 30,
label: '1k',
},
{
value: 40,
label: '10k',
},
{
value: 50,
label: '100k',
},
{
value: 60,
label: '1M',
},
{
value: 70,
label: '10M',
},
{
value: 80,
label: '100M',
},
{
value: 90,
label: '1B',
},
],
tooltipInfo: 'The higher the routing score the better the performance of the node and so its rewards',
},
});
const formatStakeValuesToMinorDenom = ([value_1, value_2]: number[]) => {
const lowerValue = 10 ** (value_1 / 10) * 1_000_000;
const upperValue = 10 ** (value_2 / 10) * 1_000_000;
return [lowerValue, upperValue];
};
const formatStakeSaturationValues = ([value_1, value_2]: number[]) => {
const lowerValue = value_1 / 100;
const upperValue = value_2 / 100;
@@ -77,7 +110,7 @@ const formatStakeSaturationValues = ([value_1, value_2]: number[]) => {
};
export const formatOnSave = (filters: TFilters) => ({
routingScore: filters.routingScore.value,
stake: formatStakeValuesToMinorDenom(filters.stake.value),
profitMargin: filters.profitMargin.value,
stakeSaturation: formatStakeSaturationValues(filters.stakeSaturation.value),
});
+2 -2
View File
@@ -102,8 +102,8 @@ export const MainContextProvider: React.FC = ({ children }) => {
m.mix_node.profit_margin_percent <= filters.profitMargin[1] &&
m.stake_saturation >= filters.stakeSaturation[0] &&
m.stake_saturation <= filters.stakeSaturation[1] &&
m.avg_uptime >= filters.routingScore[0] &&
m.avg_uptime <= filters.routingScore[1],
+m.pledge_amount.amount + +m.total_delegation.amount >= filters.stake[0] &&
+m.pledge_amount.amount + +m.total_delegation.amount <= filters.stake[1],
);
setMixnodes({ data: filtered, isLoading: false });
};
+1 -3
View File
@@ -4,19 +4,17 @@ import { Mark } from '@mui/base';
export enum EnumFilterKey {
profitMargin = 'profitMargin',
stakeSaturation = 'stakeSaturation',
routingScore = 'routingScore',
stake = 'stake',
}
export type TFilterItem = {
label: string;
id: EnumFilterKey;
value: number[];
isSmooth?: boolean;
marks: Mark[];
min?: number;
max?: number;
scale?: (value: number) => number;
tooltipInfo?: string;
};
export type TFilters = { [key in EnumFilterKey]: TFilterItem };
+1 -1
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-gateway"
version = "1.0.2"
version = "1.0.1"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Mixnet Gateway"
edition = "2021"
+12 -1
View File
@@ -6,11 +6,11 @@ use std::{process, str::FromStr};
use crate::{config::Config, Cli};
use clap::Subcommand;
use colored::Colorize;
use config::parse_validators;
use crypto::bech32_address_validation;
use network_defaults::var_names::{
API_VALIDATOR, BECH32_PREFIX, CONFIGURED, NYMD_VALIDATOR, STATISTICS_SERVICE_DOMAIN_ADDRESS,
};
use url::Url;
pub(crate) mod init;
pub(crate) mod node_details;
@@ -69,6 +69,17 @@ pub(crate) async fn execute(args: Cli) {
}
}
fn parse_validators(raw: &str) -> Vec<Url> {
raw.split(',')
.map(|raw_validator| {
raw_validator
.trim()
.parse()
.expect("one of the provided validator api urls is invalid")
})
.collect()
}
pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Config {
let mut was_host_overridden = false;
if let Some(host) = args.host {
-1
View File
@@ -336,7 +336,6 @@ where
if self.config.get_enabled_statistics() {
let statistics_service_url = self.config.get_statistics_service_url();
let stats_collector = GatewayStatisticsCollector::new(
self.identity_keypair.public_key().to_base58_string(),
active_clients_store.clone(),
statistics_service_url,
);
+2 -11
View File
@@ -14,19 +14,13 @@ use statistics_common::{
use crate::node::client_handling::active_clients::ActiveClientsStore;
pub(crate) struct GatewayStatisticsCollector {
gateway_id: String,
active_clients_store: ActiveClientsStore,
statistics_service_url: Url,
}
impl GatewayStatisticsCollector {
pub fn new(
gateway_id: String,
active_clients_store: ActiveClientsStore,
statistics_service_url: Url,
) -> Self {
pub fn new(active_clients_store: ActiveClientsStore, statistics_service_url: Url) -> Self {
GatewayStatisticsCollector {
gateway_id,
active_clients_store,
statistics_service_url,
}
@@ -41,10 +35,7 @@ impl StatisticsCollector for GatewayStatisticsCollector {
timestamp: DateTime<Utc>,
) -> StatsMessage {
let inbox_count = self.active_clients_store.size() as u32;
let stats_data = vec![StatsData::Gateway(StatsGatewayData::new(
self.gateway_id.clone(),
inbox_count,
))];
let stats_data = vec![StatsData::Gateway(StatsGatewayData { inbox_count })];
StatsMessage {
stats_data,
interval_seconds: interval.as_secs() as u32,
+1 -1
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-mixnode"
version = "1.0.2"
version = "1.0.1"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
+13 -4
View File
@@ -6,11 +6,9 @@ use std::process;
use crate::{config::Config, Cli};
use clap::Subcommand;
use colored::Colorize;
use config::{
defaults::var_names::{API_VALIDATOR, BECH32_PREFIX, CONFIGURED},
parse_validators,
};
use config::defaults::var_names::{API_VALIDATOR, BECH32_PREFIX, CONFIGURED};
use crypto::bech32_address_validation;
use url::Url;
mod describe;
mod init;
@@ -63,6 +61,17 @@ pub(crate) async fn execute(args: Cli) {
}
}
fn parse_validators(raw: &str) -> Vec<Url> {
raw.split(',')
.map(|raw_validator| {
raw_validator
.trim()
.parse()
.expect("one of the provided validator api urls is invalid")
})
.collect()
}
fn override_config(mut config: Config, args: OverrideConfig) -> Config {
let mut was_host_overridden = false;
if let Some(host) = args.host {
+1 -1
View File
@@ -24,7 +24,7 @@ fn long_version_static() -> &'static str {
#[derive(Parser)]
#[clap(author = "Nymtech", version, about, long_version = long_version_static())]
struct Cli {
/// Path pointing to an env file that configures the mixnode.
/// Path pointing to an env file that configures the gateway.
#[clap(long)]
pub(crate) config_env_file: Option<std::path::PathBuf>,
-1983
View File
File diff suppressed because it is too large Load Diff
-28
View File
@@ -1,28 +0,0 @@
[package]
name = "chitchat-test"
version = "0.3.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chitchat = "0.4"
poem = "1"
poem-openapi = {version="2", features = ["swagger-ui"] }
structopt = "0.3"
tokio = { version = "1.14.0", features = ["net", "sync", "rt-multi-thread", "macros", "time"] }
serde = { version="1", features=["derive"] }
serde_json = "1"
anyhow = "1"
once_cell = "1"
tracing = "0.1"
tracing-subscriber = "0.3"
cool-id-generator = "1"
env_logger = "0.9"
[dev-dependencies]
assert_cmd = "2"
predicates = "2"
reqwest = { version = "0.11", default-features=false, features = ["blocking", "json"] }
[workspace]
-15
View File
@@ -1,15 +0,0 @@
# Chitchat test
Runs simple chitchat servers, mostly copied over from https://github.com/quickwit-oss/chitchat
## Example
```bash
# Starts 5 servers and joins them into a cluster on localhost ports 10000-10004
# All servers print cluster state on `/` ie 127.0.0.1:10000
# `/docs` endpoint has an open api with a key value setter, set it on one node and observe how the state propagates to the other nodes
# NodeState is a regular BTreeMap
./run-servers.sh
# run killall chitchat-test after you're done, as the servers will continue to run forever in the background
```
-15
View File
@@ -1,15 +0,0 @@
#!/bin/bash
killall chitchat-test
cargo build --release
for i in $(seq 10000 10004)
do
listen_addr="127.0.0.1:$i";
echo ${listen_addr};
cargo run --release -- --listen_addr ${listen_addr} --seed 127.0.0.1:10000 --node_id node_$i &
done;
read
kill 0
-123
View File
@@ -1,123 +0,0 @@
use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;
use chitchat::transport::UdpTransport;
use chitchat::{spawn_chitchat, Chitchat, ChitchatConfig, FailureDetectorConfig, NodeId};
use cool_id_generator::Size;
use poem::listener::TcpListener;
use poem::{Route, Server};
use poem_openapi::param::Query;
use poem_openapi::payload::Json;
use poem_openapi::{OpenApi, OpenApiService};
use structopt::StructOpt;
use tokio::sync::Mutex;
use chitchat::ClusterStateSnapshot;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
pub struct ApiResponse {
pub cluster_id: String,
pub cluster_state: ClusterStateSnapshot,
pub live_nodes: Vec<NodeId>,
pub dead_nodes: Vec<NodeId>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SetKeyValueResponse {
pub status: bool,
}
struct Api {
chitchat: Arc<Mutex<Chitchat>>,
}
#[OpenApi]
impl Api {
/// Chitchat state
#[oai(path = "/", method = "get")]
async fn index(&self) -> Json<serde_json::Value> {
let chitchat_guard = self.chitchat.lock().await;
let response = ApiResponse {
cluster_id: chitchat_guard.cluster_id().to_string(),
cluster_state: chitchat_guard.state_snapshot(),
live_nodes: chitchat_guard.live_nodes().cloned().collect::<Vec<_>>(),
dead_nodes: chitchat_guard.dead_nodes().cloned().collect::<Vec<_>>(),
};
Json(serde_json::to_value(&response).unwrap())
}
/// Set a key & value on this node (with no validation).
#[oai(path = "/set_kv/", method = "get")]
async fn set_kv(&self, key: Query<String>, value: Query<String>) -> Json<serde_json::Value> {
let mut chitchat_guard = self.chitchat.lock().await;
let cc_state = chitchat_guard.self_node_state();
cc_state.set(key.as_str(), value.as_str());
Json(serde_json::to_value(&SetKeyValueResponse { status: true }).unwrap())
}
}
#[derive(Debug, StructOpt)]
#[structopt(name = "chitchat", about = "Chitchat test server.")]
struct Opt {
/// Defines the socket addr on which we should listen to.
#[structopt(long = "listen_addr", default_value = "127.0.0.1:10000")]
listen_addr: SocketAddr,
/// Defines the socket_address (host:port) other servers should use to
/// reach this server.
///
/// It defaults to the listen address, but this is only valid
/// when all server are running on the same server.
#[structopt(long = "public_addr")]
public_addr: Option<SocketAddr>,
/// Node id. Has to be unique. If None, the node_id will be generated from
/// the public_addr and a random suffix.
#[structopt(long = "node_id")]
node_id: Option<String>,
#[structopt(long = "seed")]
seeds: Vec<String>,
#[structopt(long = "interval_ms", default_value = "500")]
interval: u64,
}
fn generate_server_id(public_addr: SocketAddr) -> String {
let cool_id = cool_id_generator::get_id(Size::Medium);
format!("server:{}-{}", public_addr, cool_id)
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::init();
let opt = Opt::from_args();
println!("{:?}", opt);
let public_addr = opt.public_addr.unwrap_or(opt.listen_addr);
let node_id_str = opt
.node_id
.unwrap_or_else(|| generate_server_id(public_addr));
let node_id = NodeId::new(node_id_str, public_addr);
let config = ChitchatConfig {
node_id,
cluster_id: "testing".to_string(),
gossip_interval: Duration::from_millis(opt.interval),
listen_addr: opt.listen_addr,
seed_nodes: opt.seeds.clone(),
failure_detector_config: FailureDetectorConfig::default(),
};
let chitchat_handler = spawn_chitchat(config, Vec::new(), &UdpTransport).await?;
let chitchat = chitchat_handler.chitchat();
let api = Api { chitchat };
let api_service = OpenApiService::new(api, "Hello World", "1.0")
.server(&format!("http://{}/", opt.listen_addr));
let docs = api_service.swagger_ui();
let app = Route::new().nest("/", api_service).nest("/docs", docs);
Server::new(TcpListener::bind(&opt.listen_addr))
.run(app)
.await?;
Ok(())
}
-14
View File
@@ -1,14 +0,0 @@
## [nym-connect-v1.0.1](https://github.com/nymtech/nym/tree/nym-connect-v1.0.1) (2022-07-22)
### Added
- 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])
- nym-connect: add ability to export gateway keys as JSON
- nym-connect: add auto updater
### Changed
- nym-connect: reuse config id instead of creating a new id on each connection
[#1427]: https://github.com/nymtech/nym/pull/1427
+3 -2
View File
@@ -3199,6 +3199,7 @@ dependencies = [
"cosmwasm-std",
"fixed",
"log",
"network-defaults",
"schemars",
"serde",
"serde_repr",
@@ -3404,7 +3405,7 @@ dependencies = [
[[package]]
name = "nym-connect"
version = "1.0.1"
version = "1.0.0"
dependencies = [
"bip39",
"client-core",
@@ -3436,7 +3437,7 @@ dependencies = [
[[package]]
name = "nym-socks5-client"
version = "1.0.2"
version = "1.0.1"
dependencies = [
"clap",
"client-core",
+1 -1
View File
@@ -32,7 +32,7 @@ yarn install
## Development mode
You can compile nym-connect in development mode by running the following command inside the `nym-connect` directory:
You can compile nym-connectin development mode by running the following command inside the `nym-connect` directory:
```
yarn dev
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-connect"
version = "1.0.1"
version = "1.0.0"
description = "nym-connect"
authors = ["Nym Technologies SA"]
license = ""
@@ -39,7 +39,7 @@ tokio = { version = "1.19.1", features = ["sync", "time"] }
url = "2.2"
client-core = { path = "../../clients/client-core" }
config-common = { path = "../../common/config", package = "config" }
config = { path = "../../common/config" }
nym-socks5-client = { path = "../../clients/socks5" }
topology = { path = "../../common/topology" }
+1 -7
View File
@@ -6,7 +6,7 @@ use tap::TapFallible;
use tokio::sync::RwLock;
use client_core::config::Config as BaseConfig;
use config_common::NymConfig;
use config::NymConfig;
use nym_socks5::client::config::Config as Socks5Config;
use crate::{
@@ -135,12 +135,6 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str
.get_base_mut()
.with_eth_private_key(DEFAULT_ETH_PRIVATE_KEY);
if let Ok(raw_validators) = std::env::var(config_common::defaults::var_names::API_VALIDATOR) {
config
.get_base_mut()
.set_custom_validator_apis(config_common::parse_validators(&raw_validators));
}
let gateway = setup_gateway(
&id,
register_gateway,
-2
View File
@@ -5,7 +5,6 @@
use std::sync::Arc;
use config_common::defaults::setup_env;
use tauri::Menu;
use tokio::sync::RwLock;
@@ -25,7 +24,6 @@ mod window;
fn main() {
setup_logging();
setup_env(None);
println!("Starting up...");
// As per breaking change description here
+1 -1
View File
@@ -1,6 +1,6 @@
use std::time::Duration;
use ::config_common::NymConfig;
use ::config::NymConfig;
use futures::SinkExt;
use tap::TapFallible;
use tauri::Manager;
+1 -1
View File
@@ -4,7 +4,7 @@ use std::sync::Arc;
use tap::TapFallible;
use tokio::sync::RwLock;
use config_common::NymConfig;
use config::NymConfig;
#[cfg(not(feature = "coconut"))]
use nym_socks5::client::NymClient as Socks5NymClient;
use nym_socks5::client::{config::Config as Socks5Config, Socks5ControlMessageSender};
+1 -1
View File
@@ -1,7 +1,7 @@
{
"package": {
"productName": "nym-connect",
"version": "1.0.1"
"version": "1.0.0"
},
"build": {
"distDir": "../dist",
+4 -7
View File
@@ -22,14 +22,11 @@ export const DefaultLayout: React.FC<{
};
return (
<AppWindowFrame>
<Typography fontWeight="400" fontSize="12px" textAlign="center" sx={{ opacity: 0.6 }}>
This is experimental software. <br />
Do not rely on it for strong anonymity (yet).
<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" pt={2}>
Connect to the
<br />
Nym mixnet for privacy.
<Typography fontWeight="700" fontSize="14px" textAlign="center" color="#60D6EF" pt={2}>
You are not protected now
</Typography>
<ServiceProviderSelector services={services} onChange={handleServiceProviderChange} />
<ConnectionButton
+1 -1
View File
@@ -1 +1 @@
ADMIN_ADDRESS={\"MAINNET\":[],\"SANDBOX\":[],\"QA\":[\"n1c8te4wlc25re97qw5nh8urtpek494zqx30lza2\",\"n177krl498arsfupd2p9097kwfmuf07lkj6crmj9\"]}
ADMIN_ADDRESS={"MAINNET":[],"SANDBOX":[],"QA":["n1c8te4wlc25re97qw5nh8urtpek494zqx30lza2","n177krl498arsfupd2p9097kwfmuf07lkj6crmj9"]}
-213
View File
@@ -1,213 +0,0 @@
## [nym-wallet-v1.0.8](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.0.8) (2022-08-11)
- wallet: new bonding flow and screen for bonded node
- wallet: compound and redeem functionalities for operator rewards
- wallet: a few minor touch ups and bug fixes
## [nym-wallet-v1.0.7](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.7) (2022-07-11)
- wallet: dark mode
- wallet: when simulating gas costs, an automatic adjustment is being used ([#1388]).
[#1388]: https://github.com/nymtech/nym/pull/1388
## [nym-wallet-v1.0.6](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.6) (2022-06-21)
- wallet: undelegating now uses either the mixnet or vesting contract, or both, depending on how delegations were made
- wallet: redeeming and compounding now uses both the mixnet and vesting contract
- wallet: the wallet backend learned how to archive wallet files
- wallet: add ENABLE_QA_MODE environment variable to enable QA mode on built wallet
## [nym-wallet-v1.0.5](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.5) (2022-06-14)
- wallet: add simple CLI tool for decrypting and recovering the wallet file.
- wallet: added support for multiple accounts ([#1265])
- wallet: compound and claim reward endpoints for operators and delegators ([#1302])
- wallet: require password to switch accounts
- wallet: the wallet backend learned how to keep track of validator name, either hardcoded or by querying the status endpoint.
- wallet: new delegation and rewards UI
- wallet: show version in nav bar
- wallet: contract admin route put back
- wallet: staking_supply field to StateParams
- wallet: show transaction hash for redeeming or compounding rewards
[#1265]: https://github.com/nymtech/nym/pull/1265
[#1302]: https://github.com/nymtech/nym/pull/1302
## [nym-wallet-v1.0.4](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.4) (2022-05-04)
### Changed
- all: the default behaviour of validator client is changed to use `broadcast_sync` and poll for transaction inclusion instead of using `broadcast_commit` to deal with timeouts ([#1246])
## [nym-wallet-v1.0.3](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.3) (2022-04-25)
[Full Changelog](https://github.com/nymtech/nym/compare/nym-binaries-1.0.0-rc.2...nym-wallet-v1.0.3)
**Fixed bugs:**
- \[Issue\] Wallet 1.0.2 cannot send NYM tokens from a DelayedVestingAccount [\#1215](https://github.com/nymtech/nym/issues/1215)
- Main README not showing properly with GitHub dark mode [\#1211](https://github.com/nymtech/nym/issues/1211)
**Merged pull requests:**
- Bugfix - wallet undelegation for vesting accounts [\#1220](https://github.com/nymtech/nym/pull/1220) ([mmsinclair](https://github.com/mmsinclair))
- Bugfix/delegation reconcile [\#1219](https://github.com/nymtech/nym/pull/1219) ([jstuczyn](https://github.com/jstuczyn))
- Bugfix/query proxied pending delegations [\#1218](https://github.com/nymtech/nym/pull/1218) ([jstuczyn](https://github.com/jstuczyn))
- Using custom gas multiplier in the wallet [\#1217](https://github.com/nymtech/nym/pull/1217) ([jstuczyn](https://github.com/jstuczyn))
- Feature/vesting accounts support [\#1216](https://github.com/nymtech/nym/pull/1216) ([jstuczyn](https://github.com/jstuczyn))
- Release/1.0.0 rc.2 [\#1214](https://github.com/nymtech/nym/pull/1214) ([jstuczyn](https://github.com/jstuczyn))
- chore: fix dark mode rendering [\#1212](https://github.com/nymtech/nym/pull/1212) ([pwnfoo](https://github.com/pwnfoo))
- Feature/spend coconut [\#1210](https://github.com/nymtech/nym/pull/1210) ([neacsu](https://github.com/neacsu))
- Bugfix/unique sphinx key [\#1207](https://github.com/nymtech/nym/pull/1207) ([jstuczyn](https://github.com/jstuczyn))
- Add cache read and write timeouts [\#1206](https://github.com/nymtech/nym/pull/1206) ([durch](https://github.com/durch))
- Additional, more informative routes [\#1204](https://github.com/nymtech/nym/pull/1204) ([durch](https://github.com/durch))
- Feature/aggregated econ dynamics explorer endpoint [\#1203](https://github.com/nymtech/nym/pull/1203) ([jstuczyn](https://github.com/jstuczyn))
- Debugging validator [\#1198](https://github.com/nymtech/nym/pull/1198) ([durch](https://github.com/durch))
- wallet: expose additional validator configuration functionality to the frontend [\#1195](https://github.com/nymtech/nym/pull/1195) ([octol](https://github.com/octol))
- Update rewarding validator address [\#1193](https://github.com/nymtech/nym/pull/1193) ([durch](https://github.com/durch))
- Crypto part of the Groth's NIDKG [\#1182](https://github.com/nymtech/nym/pull/1182) ([jstuczyn](https://github.com/jstuczyn))
- fix unbond page [\#1180](https://github.com/nymtech/nym/pull/1180) ([tommyv1987](https://github.com/tommyv1987))
- Type safe bounds [\#1179](https://github.com/nymtech/nym/pull/1179) ([durch](https://github.com/durch))
- Fix delegation paging [\#1174](https://github.com/nymtech/nym/pull/1174) ([durch](https://github.com/durch))
- Update binaries to rc version [\#1172](https://github.com/nymtech/nym/pull/1172) ([tommyv1987](https://github.com/tommyv1987))
- Bump ansi-regex from 4.1.0 to 4.1.1 in /docker/typescript\_client/upload\_contract [\#1171](https://github.com/nymtech/nym/pull/1171) ([dependabot[bot]](https://github.com/apps/dependabot))
## [nym-wallet-v1.0.2](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.2) (2022-04-05)
[Full Changelog](https://github.com/nymtech/nym/compare/nym-wallet-v1.0.1...nym-wallet-v1.0.2)
**Merged pull requests:**
- Wallet 1.0.2 visual tweaks [\#1197](https://github.com/nymtech/nym/pull/1197) ([mmsinclair](https://github.com/mmsinclair))
- Password for wallet with routes [\#1196](https://github.com/nymtech/nym/pull/1196) ([fmtabbara](https://github.com/fmtabbara))
- Add auto-updater to Nym Wallet [\#1194](https://github.com/nymtech/nym/pull/1194) ([mmsinclair](https://github.com/mmsinclair))
- Fix clippy warnings for beta toolchain [\#1191](https://github.com/nymtech/nym/pull/1191) ([octol](https://github.com/octol))
- wallet: expose validator urls to the frontend [\#1190](https://github.com/nymtech/nym/pull/1190) ([octol](https://github.com/octol))
- wallet: add test for decrypting stored wallet file [\#1189](https://github.com/nymtech/nym/pull/1189) ([octol](https://github.com/octol))
- Fix clippy warnings [\#1188](https://github.com/nymtech/nym/pull/1188) ([octol](https://github.com/octol))
- Password for wallet with routes [\#1187](https://github.com/nymtech/nym/pull/1187) ([mmsinclair](https://github.com/mmsinclair))
- wallet: add validate\_mnemonic [\#1186](https://github.com/nymtech/nym/pull/1186) ([octol](https://github.com/octol))
- wallet: support removing accounts from the wallet file [\#1185](https://github.com/nymtech/nym/pull/1185) ([octol](https://github.com/octol))
- Feature/adding discord [\#1184](https://github.com/nymtech/nym/pull/1184) ([gala1234](https://github.com/gala1234))
- wallet: config backend for validator selection [\#1183](https://github.com/nymtech/nym/pull/1183) ([octol](https://github.com/octol))
- Add storybook to wallet [\#1178](https://github.com/nymtech/nym/pull/1178) ([mmsinclair](https://github.com/mmsinclair))
- wallet: connection test nymd and api urls independently [\#1170](https://github.com/nymtech/nym/pull/1170) ([octol](https://github.com/octol))
- wallet: wire up account storage [\#1153](https://github.com/nymtech/nym/pull/1153) ([octol](https://github.com/octol))
- Feature/signature on deposit [\#1151](https://github.com/nymtech/nym/pull/1151) ([neacsu](https://github.com/neacsu))
## [nym-wallet-v1.0.1](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.1) (2022-04-05)
[Full Changelog](https://github.com/nymtech/nym/compare/nym-binaries-1.0.0-rc.1...nym-wallet-v1.0.1)
**Closed issues:**
- Check enabling bbbc simultaneously with open access. Estimate what it would take to make this the default compilation target. [\#1175](https://github.com/nymtech/nym/issues/1175)
- Get coconut credential for deposited tokens [\#1138](https://github.com/nymtech/nym/issues/1138)
- Make payments lazy [\#1135](https://github.com/nymtech/nym/issues/1135)
- Uptime on node selection for sets [\#1049](https://github.com/nymtech/nym/issues/1049)
## [nym-wallet-v1.0.0](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.0) (2022-02-03)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.12.1...nym-wallet-v1.0.0)
**Implemented enhancements:**
- \[Feature Request\] Please enable registration without need for Telegram account [\#1016](https://github.com/nymtech/nym/issues/1016)
- Fast mixnode launch with a pre-built ISO + VM software [\#1001](https://github.com/nymtech/nym/issues/1001)
**Fixed bugs:**
- \[Issue\] [\#1000](https://github.com/nymtech/nym/issues/1000)
- \[Issue\] `nym-client` requires multiple attempts to run a server [\#869](https://github.com/nymtech/nym/issues/869)
- De-'float'-ing `Interval` \(`Display` impl + `serde`\) [\#1065](https://github.com/nymtech/nym/pull/1065) ([jstuczyn](https://github.com/jstuczyn))
- display client address on wallet creation [\#1058](https://github.com/nymtech/nym/pull/1058) ([fmtabbara](https://github.com/fmtabbara))
**Closed issues:**
- Rewarded set inclusion probability API endpoint [\#1037](https://github.com/nymtech/nym/issues/1037)
- Update cw-storage-plus to 0.11 [\#1032](https://github.com/nymtech/nym/issues/1032)
- Change `u128` fields in `RewardEstimationResponse` to `u64` [\#1029](https://github.com/nymtech/nym/issues/1029)
- Test out the mainnet Gravity Bridge [\#1006](https://github.com/nymtech/nym/issues/1006)
- Add vesting contract interface to nym-wallet [\#959](https://github.com/nymtech/nym/issues/959)
- Mixnode crash [\#486](https://github.com/nymtech/nym/issues/486)
**Merged pull requests:**
- create custom urls for mainnet [\#1095](https://github.com/nymtech/nym/pull/1095) ([fmtabbara](https://github.com/fmtabbara))
- Wallet signing on MacOS [\#1093](https://github.com/nymtech/nym/pull/1093) ([mmsinclair](https://github.com/mmsinclair))
- Fix rust 2018 idioms warnings [\#1092](https://github.com/nymtech/nym/pull/1092) ([octol](https://github.com/octol))
- Prevent contract overwriting [\#1090](https://github.com/nymtech/nym/pull/1090) ([durch](https://github.com/durch))
- Logout operation [\#1087](https://github.com/nymtech/nym/pull/1087) ([jstuczyn](https://github.com/jstuczyn))
- Update to rust edition 2021 everywhere [\#1086](https://github.com/nymtech/nym/pull/1086) ([octol](https://github.com/octol))
- Tag contract errors, and print out lines for easier QA [\#1084](https://github.com/nymtech/nym/pull/1084) ([durch](https://github.com/durch))
- Feature/flexible vesting + utility queries [\#1083](https://github.com/nymtech/nym/pull/1083) ([durch](https://github.com/durch))
- Bump @openzeppelin/contracts from 4.3.1 to 4.4.2 in /contracts/basic-bandwidth-generation [\#1082](https://github.com/nymtech/nym/pull/1082) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump nth-check from 2.0.0 to 2.0.1 in /clients/native/examples/js-examples/websocket [\#1081](https://github.com/nymtech/nym/pull/1081) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump url-parse from 1.5.1 to 1.5.4 in /clients/native/examples/js-examples/websocket [\#1080](https://github.com/nymtech/nym/pull/1080) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump follow-redirects from 1.14.1 to 1.14.7 in /clients/native/examples/js-examples/websocket [\#1079](https://github.com/nymtech/nym/pull/1079) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump nanoid from 3.1.23 to 3.2.0 in /clients/native/examples/js-examples/websocket [\#1078](https://github.com/nymtech/nym/pull/1078) ([dependabot[bot]](https://github.com/apps/dependabot))
- Setup basic test for mixnode stats reporting [\#1077](https://github.com/nymtech/nym/pull/1077) ([octol](https://github.com/octol))
- Make wallet\_address mandatory for mixnode init [\#1076](https://github.com/nymtech/nym/pull/1076) ([octol](https://github.com/octol))
- Tidy nym-mixnode module visibility [\#1075](https://github.com/nymtech/nym/pull/1075) ([octol](https://github.com/octol))
- Feature/wallet login with password [\#1074](https://github.com/nymtech/nym/pull/1074) ([fmtabbara](https://github.com/fmtabbara))
- Add trait to mock client dependency in DelayForwarder [\#1073](https://github.com/nymtech/nym/pull/1073) ([octol](https://github.com/octol))
- Bump rust-version to latest stable for nym-mixnode [\#1072](https://github.com/nymtech/nym/pull/1072) ([octol](https://github.com/octol))
- Fixes CI for our wasm build [\#1069](https://github.com/nymtech/nym/pull/1069) ([jstuczyn](https://github.com/jstuczyn))
- Add @octol as codeowner [\#1068](https://github.com/nymtech/nym/pull/1068) ([octol](https://github.com/octol))
- set-up inclusion probability [\#1067](https://github.com/nymtech/nym/pull/1067) ([fmtabbara](https://github.com/fmtabbara))
- Feature/wasm client [\#1066](https://github.com/nymtech/nym/pull/1066) ([neacsu](https://github.com/neacsu))
- Changed bech32\_prefix from punk to nymt [\#1064](https://github.com/nymtech/nym/pull/1064) ([jstuczyn](https://github.com/jstuczyn))
- Bump nanoid from 3.1.30 to 3.2.0 in /testnet-faucet [\#1063](https://github.com/nymtech/nym/pull/1063) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump nanoid from 3.1.30 to 3.2.0 in /nym-wallet [\#1062](https://github.com/nymtech/nym/pull/1062) ([dependabot[bot]](https://github.com/apps/dependabot))
- Rework vesting contract storage [\#1061](https://github.com/nymtech/nym/pull/1061) ([durch](https://github.com/durch))
- Mixnet Contract constants extraction [\#1060](https://github.com/nymtech/nym/pull/1060) ([jstuczyn](https://github.com/jstuczyn))
- fix: make explorer footer year dynamic [\#1059](https://github.com/nymtech/nym/pull/1059) ([martinyung](https://github.com/martinyung))
- Add mnemonic just on creation, to display it [\#1057](https://github.com/nymtech/nym/pull/1057) ([neacsu](https://github.com/neacsu))
- Network Explorer: updates to API and UI to show the active set [\#1056](https://github.com/nymtech/nym/pull/1056) ([mmsinclair](https://github.com/mmsinclair))
- Made contract addresses for query NymdClient construction optional [\#1055](https://github.com/nymtech/nym/pull/1055) ([jstuczyn](https://github.com/jstuczyn))
- Introduced RPC query for total token supply [\#1053](https://github.com/nymtech/nym/pull/1053) ([jstuczyn](https://github.com/jstuczyn))
- Feature/tokio console [\#1052](https://github.com/nymtech/nym/pull/1052) ([durch](https://github.com/durch))
- Implemented beta clippy lint recommendations [\#1051](https://github.com/nymtech/nym/pull/1051) ([jstuczyn](https://github.com/jstuczyn))
- add new function to update profit percentage [\#1050](https://github.com/nymtech/nym/pull/1050) ([fmtabbara](https://github.com/fmtabbara))
- Upgrade Clap and use declarative argument parsing for nym-mixnode [\#1047](https://github.com/nymtech/nym/pull/1047) ([octol](https://github.com/octol))
- Feature/additional bond validation [\#1046](https://github.com/nymtech/nym/pull/1046) ([fmtabbara](https://github.com/fmtabbara))
- Fix clippy on relevant lints [\#1044](https://github.com/nymtech/nym/pull/1044) ([neacsu](https://github.com/neacsu))
- Bump shelljs from 0.8.4 to 0.8.5 in /contracts/basic-bandwidth-generation [\#1043](https://github.com/nymtech/nym/pull/1043) ([dependabot[bot]](https://github.com/apps/dependabot))
- Endpoint for rewarded set inclusion probabilities [\#1042](https://github.com/nymtech/nym/pull/1042) ([durch](https://github.com/durch))
- Bump follow-redirects from 1.14.4 to 1.14.7 in /contracts/basic-bandwidth-generation [\#1041](https://github.com/nymtech/nym/pull/1041) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump follow-redirects from 1.14.5 to 1.14.7 in /testnet-faucet [\#1040](https://github.com/nymtech/nym/pull/1040) ([dependabot[bot]](https://github.com/apps/dependabot))
- Feature/node settings update [\#1036](https://github.com/nymtech/nym/pull/1036) ([fmtabbara](https://github.com/fmtabbara))
- Migrate to cw-storage-plus 0.11.1 [\#1035](https://github.com/nymtech/nym/pull/1035) ([durch](https://github.com/durch))
- Bump @openzeppelin/contracts from 4.4.1 to 4.4.2 in /contracts/basic-bandwidth-generation [\#1034](https://github.com/nymtech/nym/pull/1034) ([dependabot[bot]](https://github.com/apps/dependabot))
- Feature/configurable wallet [\#1033](https://github.com/nymtech/nym/pull/1033) ([neacsu](https://github.com/neacsu))
- Feature/downcast reward estimation [\#1031](https://github.com/nymtech/nym/pull/1031) ([durch](https://github.com/durch))
- Wallet UI updates [\#1028](https://github.com/nymtech/nym/pull/1028) ([fmtabbara](https://github.com/fmtabbara))
- Remove migration code [\#1027](https://github.com/nymtech/nym/pull/1027) ([neacsu](https://github.com/neacsu))
- Chore/stricter dependency requirements [\#1025](https://github.com/nymtech/nym/pull/1025) ([jstuczyn](https://github.com/jstuczyn))
- Feature/validator api client endpoints [\#1024](https://github.com/nymtech/nym/pull/1024) ([jstuczyn](https://github.com/jstuczyn))
- Updated cosmrs to 0.4.1 [\#1023](https://github.com/nymtech/nym/pull/1023) ([jstuczyn](https://github.com/jstuczyn))
- Feature/testnet deploy scripts [\#1022](https://github.com/nymtech/nym/pull/1022) ([mfahampshire](https://github.com/mfahampshire))
- Changed wallet's client to a full validator client [\#1021](https://github.com/nymtech/nym/pull/1021) ([jstuczyn](https://github.com/jstuczyn))
- Fix 404 link [\#1020](https://github.com/nymtech/nym/pull/1020) ([RiccardoMasutti](https://github.com/RiccardoMasutti))
- Feature/additional mixnode endpoints [\#1019](https://github.com/nymtech/nym/pull/1019) ([jstuczyn](https://github.com/jstuczyn))
- Introduced denom check when trying to withdraw vested coins [\#1018](https://github.com/nymtech/nym/pull/1018) ([jstuczyn](https://github.com/jstuczyn))
- Add network defaults for qa [\#1017](https://github.com/nymtech/nym/pull/1017) ([neacsu](https://github.com/neacsu))
- Feature/expanded events [\#1015](https://github.com/nymtech/nym/pull/1015) ([jstuczyn](https://github.com/jstuczyn))
- update frontend to use new profit update api [\#1014](https://github.com/nymtech/nym/pull/1014) ([fmtabbara](https://github.com/fmtabbara))
- Feature/node state endpoint [\#1013](https://github.com/nymtech/nym/pull/1013) ([jstuczyn](https://github.com/jstuczyn))
- Feature/hourly set updates [\#1012](https://github.com/nymtech/nym/pull/1012) ([durch](https://github.com/durch))
- Feature/remove unused profit margin [\#1011](https://github.com/nymtech/nym/pull/1011) ([neacsu](https://github.com/neacsu))
- Feature/explorer node status [\#1010](https://github.com/nymtech/nym/pull/1010) ([jstuczyn](https://github.com/jstuczyn))
- Use serial integer instead of random [\#1009](https://github.com/nymtech/nym/pull/1009) ([durch](https://github.com/durch))
- Feature/configure profit [\#1008](https://github.com/nymtech/nym/pull/1008) ([neacsu](https://github.com/neacsu))
- Feature/fix gateway sign [\#1004](https://github.com/nymtech/nym/pull/1004) ([neacsu](https://github.com/neacsu))
- Fix clippy [\#1003](https://github.com/nymtech/nym/pull/1003) ([neacsu](https://github.com/neacsu))
- Update wallet version [\#998](https://github.com/nymtech/nym/pull/998) ([tommyv1987](https://github.com/tommyv1987))
- Fix wallet build instructions [\#997](https://github.com/nymtech/nym/pull/997) ([tommyv1987](https://github.com/tommyv1987))
- Make the separation between testnet-mode and erc20 bandwidth mode clearer [\#994](https://github.com/nymtech/nym/pull/994) ([neacsu](https://github.com/neacsu))
- Bump @openzeppelin/contracts from 3.4.0 to 4.4.1 in /contracts/basic-bandwidth-generation [\#983](https://github.com/nymtech/nym/pull/983) ([dependabot[bot]](https://github.com/apps/dependabot))
- Feature/implicit runtime [\#973](https://github.com/nymtech/nym/pull/973) ([jstuczyn](https://github.com/jstuczyn))
- Differentiate staking and ownership [\#961](https://github.com/nymtech/nym/pull/961) ([durch](https://github.com/durch))
+15 -92
View File
@@ -3055,7 +3055,7 @@ dependencies = [
[[package]]
name = "nym_wallet"
version = "1.0.8"
version = "1.0.7"
dependencies = [
"aes-gcm",
"argon2 0.3.4",
@@ -3273,17 +3273,7 @@ checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
dependencies = [
"instant",
"lock_api",
"parking_lot_core 0.8.5",
]
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core 0.9.3",
"parking_lot_core",
]
[[package]]
@@ -3300,19 +3290,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "parking_lot_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec 1.8.0",
"windows-sys",
]
[[package]]
name = "password-hash"
version = "0.3.2"
@@ -4019,9 +3996,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.6.0"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
@@ -4039,9 +4016,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.27"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "remove_dir_all"
@@ -4573,15 +4550,6 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
dependencies = [
"libc",
]
[[package]]
name = "signature"
version = "1.3.2"
@@ -4667,9 +4635,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "state"
version = "0.5.3"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b"
checksum = "87cf4f5369e6d3044b5e365c9690f451516ac8f0954084622b49ea3fde2f6de5"
dependencies = [
"loom",
]
@@ -4688,7 +4656,7 @@ checksum = "33994d0838dc2d152d17a62adf608a869b5e846b65b389af7f3dbc1de45c5b26"
dependencies = [
"lazy_static",
"new_debug_unreachable",
"parking_lot 0.11.2",
"parking_lot",
"phf_shared 0.10.0",
"precomputed-hash",
"serde",
@@ -4870,7 +4838,7 @@ dependencies = [
"ndk-glue",
"ndk-sys",
"objc",
"parking_lot 0.11.2",
"parking_lot",
"raw-window-handle",
"scopeguard",
"serde",
@@ -5273,9 +5241,7 @@ dependencies = [
"mio",
"num_cpus",
"once_cell",
"parking_lot 0.12.1",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"winapi",
@@ -5932,11 +5898,11 @@ version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b749ebd2304aa012c5992d11a25d07b406bdbe5f79d371cb7a918ce501a19eb0"
dependencies = [
"windows_aarch64_msvc 0.30.0",
"windows_i686_gnu 0.30.0",
"windows_i686_msvc 0.30.0",
"windows_x86_64_gnu 0.30.0",
"windows_x86_64_msvc 0.30.0",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_msvc",
]
[[package]]
@@ -5949,31 +5915,12 @@ dependencies = [
"windows_reader",
]
[[package]]
name = "windows-sys"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
dependencies = [
"windows_aarch64_msvc 0.36.1",
"windows_i686_gnu 0.36.1",
"windows_i686_msvc 0.36.1",
"windows_x86_64_gnu 0.36.1",
"windows_x86_64_msvc 0.36.1",
]
[[package]]
name = "windows_aarch64_msvc"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29277a4435d642f775f63c7d1faeb927adba532886ce0287bd985bffb16b6bca"
[[package]]
name = "windows_aarch64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]]
name = "windows_gen"
version = "0.30.0"
@@ -5990,24 +5937,12 @@ version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1145e1989da93956c68d1864f32fb97c8f561a8f89a5125f6a2b7ea75524e4b8"
[[package]]
name = "windows_i686_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]]
name = "windows_i686_msvc"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4a09e3a0d4753b73019db171c1339cd4362c8c44baf1bcea336235e955954a6"
[[package]]
name = "windows_i686_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
[[package]]
name = "windows_macros"
version = "0.30.0"
@@ -6038,24 +5973,12 @@ version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ca64fcb0220d58db4c119e050e7af03c69e6f4f415ef69ec1773d9aab422d5a"
[[package]]
name = "windows_x86_64_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]]
name = "windows_x86_64_msvc"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08cabc9f0066848fef4bc6a1c1668e6efce38b661d2aeec75d18d8617eebb5f1"
[[package]]
name = "windows_x86_64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]]
name = "winreg"
version = "0.7.0"
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "nym_wallet"
version = "1.0.8"
version = "1.0.7"
description = "Nym Native Wallet"
authors = ["Nym Technologies SA"]
license = ""
@@ -32,14 +32,14 @@ log = "0.4"
once_cell = "1.7.2"
pretty_env_logger = "0.4"
rand = "0.6.5"
reqwest = {version = "0.11.9", features = ["json"] }
reqwest = "0.11.9"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
strum = { version = "0.23", features = ["derive"] }
tauri = { version = "=1.0.0-rc.2", features = ["clipboard-all", "shell-open", "updater", "window-maximize"] }
tendermint-rpc = "0.23.0"
thiserror = "1.0"
tokio = { version = "1.10", features = ["full"] }
tokio = { version = "1.10", features = ["sync", "time"] }
toml = "0.5.8"
url = "2.2"
-2
View File
@@ -58,8 +58,6 @@ fn main() {
mixnet::bond::unbond_gateway,
mixnet::bond::unbond_mixnode,
mixnet::bond::update_mixnode,
mixnet::bond::get_number_of_mixnode_delegators,
mixnet::bond::get_mix_node_description,
mixnet::delegate::delegate_to_mixnode,
mixnet::delegate::get_delegator_rewards,
mixnet::delegate::get_pending_delegation_events,
@@ -1,5 +1,3 @@
use std::time::Duration;
use crate::error::BackendError;
use crate::state::WalletState;
use crate::{Gateway, MixNode};
@@ -7,18 +5,8 @@ use nym_types::currency::DecCoin;
use nym_types::gateway::GatewayBond;
use nym_types::mixnode::MixNodeBond;
use nym_types::transaction::TransactionExecuteResult;
use reqwest::Error as ReqwestError;
use serde::{Deserialize, Serialize};
use validator_client::nymd::{Coin, Fee};
#[derive(Debug, Serialize, Deserialize)]
pub struct NodeDescription {
name: String,
description: String,
link: String,
location: String,
}
#[tauri::command]
pub async fn bond_gateway(
gateway: Gateway,
@@ -210,51 +198,3 @@ pub async fn get_operator_rewards(
);
Ok(display_coin)
}
#[tauri::command]
pub async fn get_number_of_mixnode_delegators(
identity: String,
state: tauri::State<'_, WalletState>,
) -> Result<usize, BackendError> {
let guard = state.read().await;
let client = guard.current_client()?;
let paged_delegations = client
.nymd
.get_mix_delegations_paged(identity, None, Some(20))
.await?;
Ok(paged_delegations.delegations.len())
}
async fn fetch_mix_node_description(
host: &str,
port: u16,
) -> Result<NodeDescription, ReqwestError> {
let milli_second = Duration::from_millis(1000);
let client = reqwest::Client::builder().timeout(milli_second).build()?;
let response = client
.get(format!("http://{}:{}/description", host, port))
.send()
.await;
match response {
Ok(res) => {
let json = res.json::<NodeDescription>().await;
match json {
Ok(json) => Ok(json),
Err(e) => Err(e),
}
}
Err(e) => Err(e),
}
}
#[tauri::command]
pub async fn get_mix_node_description(
host: &str,
port: u16,
) -> Result<NodeDescription, BackendError> {
fetch_mix_node_description(host, port)
.await
.map_err(|e| BackendError::ReqwestError { source: e })
}
@@ -0,0 +1,13 @@
{
"version": 1,
"accounts": [
{
"id": "default",
"account": {
"ciphertext": "cq5w4W5ex5eFFRcqLG+824XyUAUoYmrRY3NGw/rue6/mLoQKQE/07+BxzRuKjyYFasC1HBPg41KJwp2IY+/7+80rB9aXPpaKVLUcG9U40qgCw66WhgxTrXOnrt5toefpSTBL7f9N/PVwpuumfAgD9CS0ioB7/9Qoea7nYKkextGX15ex26B/ndQddvUkQ4gx+Vq7OLymv4l+nkdZ2nKMja349zd/BjnzPBB68/iIjyYlivVjtQ7FRbvpNRj6Mjg4905wGlO7bTpkw+RGiaGK4pK8fTWz8gAKr8GYoXPD",
"salt": "SPVGdbVyoEayD4ZzM4I+Jg==",
"iv": "tjpn/tRjD1gty+fQ"
}
}
]
}
@@ -0,0 +1,13 @@
{
"version": 1,
"accounts": [
{
"id": "default",
"account": {
"ciphertext": "3MDgoU2i5QMc9r80yPeq2AMk5wpkke0tXum5NsOE5NcFciF+aHLQW0dvXbGszap1y3nN4+YZD3cgGrmtKh/cChqRGJDkniaxdf3XPHh9RkiWXw2KSHHeyGrFY0INJeiky1ZtUFhWhopcHJWSnfCmVC15YFpnM5xOKpITjHAFhGt98MaYR+mS+3zoUFrjYbaZRh2TR2lFWsbR8YU1uaTYqJZ1HX1PBCub6aS3vjQm0Fwa+hAtR/gMymXJc5qtruTO4NbqYtMj3Z9eIgoVB+56SLAXlIF1Uo1pjvV0mx1hWNNiIc10ujF/wl/nnKF6icOcmrfm9XhOtsvUYBsE/wAIJZw3LKXgSX+hJbOl+zLAwJZK1xiL8n/nM1IJZDn+Wu6z0OzRaj9S7T16+brMw1oaqjk56saM8n5z725fizJj+ur6gnPBWnoyHPaCHgHdB2PKQNY0ZlwRM6dVncRaEWQDLAboyMq3FXxK9UbusNcDFpYw6bdnuJlNVf6y9yxwyvkUrt5YtgfkLyoW42z1PVtVWsV9P8eE/A/tnYjXf34xvba3K8Y1/3DTi7uuydNrSR/XhA+pevz68VWCbY+j746Yi8Lz7altePphkjfJAezodobKvMplXzqInopIWNovyemw/+1E7WZbkQIOAXg1WC1+Y/df+dffRGuGRdDerfRLmA5XLej1M/wE3WQ7b9KwlAo6XJ4hnQKwyDCqYP/ButBXW1AOnnZpCq59gGbiccZJsTMZB4OP95yFPgz8//IeDgma2PDixVmDEp0SGHhN7dlSoNa5eoglblqzJu/TcTA6jmQFA3ef0GiA3QzBjmyB4bz0bFybh8XA1brVIVlsjRwXb3/UYaVqsP6Hy1QDUpZofXIJs5lK0hUd0ECdaNFXXgHd25ifPocp09WLFyK92H6i3ABDZ7pu3b4lTUt6kHt6LTVsKkyylmYf2iMHnCcmfy4uxGTXxRjPjMgKL8pd++OZ3q62jLBuoTjgdj6pccwDvD+NYQ2FFeHmBzxyTLqUyKltYiyFlJHWLKOcXyeDHzRhHic+e/wn3VhM3NdrvtqYWA9m72Ye1L1I7VX7KatGurG6CeiFiY5xHxxpLT7dF0fJ7uxRye4JnRyYQuU7iK72qCKjgYjwjCIha4qPi5Q/x6S+uVe7yX5Eb73L3eB+IlkyW9wPHmSOcE4GpbMU96tK8xoxT0T9eQlj050GDnJ/oI2XHfZTs1bIxsjfZqW03g==",
"salt": "wXR3RnPmsoA3ncrixIvaUw==",
"iv": "/Zjn1OXsLJhA43n/"
}
}
]
}
@@ -0,0 +1,21 @@
{
"version": 1,
"accounts": [
{
"id": "first",
"account": {
"ciphertext": "icnpxLmr/H7FIIOaEf7DYNLuM6uhh7poEppXpYCllQD33TjY+8eLtVvhEQmjX60IQeFOd+1JCcrHa2B12vlBAYlfM4gBxA6d2ZJ8+Dw/vNvBNyChiyUx2euV3vPGOs22r/XDBsmEeF40XZcXftQZa2kzYaPnkbP+eiMOIWkcY4FYOEHwx5SxT4VBPZIrVTC3iDalJLWybVbbw/Bc2zbzEXI1ckg4Ccydj95SMil9BiyDpALfZqwlai7I97S+BjmcVxSCsYqFjTkRUHVMjrEr7fWHKU4DIOM=",
"salt": "CtnbfkxTybqz0U4cPHW2jQ==",
"iv": "77ZROU6dAMttEWwS"
}
},
{
"id": "second",
"account": {
"ciphertext": "nsqZHdQFlskglc5izKgnr8sBwdMmd82h2Rnjdos9EUca3cqkUdFYEjZDsK8OGR3GZ9alLTNt/1U97Rvvr2HPAWbzl23FW2YXaLTA6yj6ZwQK5w0MYE061NYbcxNHuzT9f5aQWkGULAk4RWb5t8eUX7y/NdJr3tA5xuGOLhooTfBB98/4RpupDsYGZp1DPC/GMFppOA3GmKs9bacZm805Bhfq5mwhXab1SjJQpFHMHisCMhxo/oLqulKML1tQMetBdqDTjJmPpdUnd1mi",
"salt": "J2TMLjKv4dkZ/kXso9FGhg==",
"iv": "CTqqoMa4LetvBKCP"
}
}
]
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"package": {
"productName": "nym-wallet",
"version": "1.0.8"
"version": "1.0.7"
},
"build": {
"distDir": "../dist",
@@ -1,12 +1,8 @@
import React from 'react';
import { Avatar, Typography } from '@mui/material';
import { Avatar } from '@mui/material';
import stc from 'string-to-color';
import { TAccount } from 'src/types';
export const AccountAvatar = ({ name, small }: { name: TAccount['name']; small?: boolean }) => (
<Avatar sx={{ bgcolor: stc(name), ...(small ? { width: 25, height: 25 } : {}) }}>
<Typography fontSize={small ? 14 : 'inherit'} fontWeight={600}>
{name?.split('')[0]}
</Typography>
</Avatar>
export const AccountAvatar = ({ name }: Pick<TAccount, 'name'>) => (
<Avatar sx={{ bgcolor: stc(name), width: 20, height: 20 }}>{name?.split('')[0]}</Avatar>
);
@@ -5,10 +5,10 @@ import { AccountAvatar } from './AccountAvatar';
export const AccountOverview = ({ account, onClick }: { account: AccountEntry; onClick: () => void }) => (
<Button
startIcon={<AccountAvatar name={account.id} small />}
startIcon={<AccountAvatar name={account.id} />}
sx={{ color: 'text.primary' }}
color="inherit"
onClick={onClick}
disableRipple
>
{account.id}
</Button>
@@ -20,7 +20,7 @@ export const MultiAccountHowTo = ({ show, handleClose }: { show: boolean; handle
<Close />
</IconButton>
</Box>
<Typography variant="body1" sx={{ color: (theme) => theme.palette.nym.text.muted }}>
<Typography variant="body1" sx={{ color: (t) => t.palette.nym.text.muted }}>
How to set up multiple accounts
</Typography>
</DialogTitle>
@@ -29,7 +29,7 @@ export const MultiAccountHowTo = ({ show, handleClose }: { show: boolean; handle
<Alert
severity="warning"
icon={false}
sx={(t) => (t.palette.mode === 'dark' ? { bgcolor: (theme) => theme.palette.background.paper } : {})}
sx={(t) => (t.palette.mode === 'dark' ? { bgcolor: (t) => t.palette.background.paper } : {})}
>
<Typography>In order to create multiple accounts your wallet needs a password.</Typography>
<Typography>Follow steps below to create password.</Typography>
@@ -9,7 +9,6 @@ import {
DialogTitle,
IconButton,
Typography,
Divider,
} from '@mui/material';
import { Add, ArrowDownwardSharp, Close } from '@mui/icons-material';
import { AccountsContext } from 'src/context';
@@ -52,7 +51,7 @@ export const AccountsModal = () => {
<Close />
</IconButton>
</Box>
<Typography fontSize="small" sx={{ color: 'grey.600' }}>
<Typography variant="body1" sx={{ color: (theme) => theme.palette.text.disabled }}>
Switch between accounts
</Typography>
</DialogTitle>
@@ -70,7 +69,6 @@ export const AccountsModal = () => {
/>
))}
</DialogContent>
<Divider variant="middle" sx={{ mt: 3 }} />
<DialogActions sx={{ p: 3 }}>
<Button startIcon={<ArrowDownwardSharp />} onClick={() => setDialogToDisplay('Import')}>
Import account
@@ -7,16 +7,17 @@ import {
DialogActions,
DialogContent,
DialogTitle,
IconButton,
TextField,
Typography,
} from '@mui/material';
import { ArrowBackSharp } from '@mui/icons-material';
import { useClipboard } from 'use-clipboard-copy';
import { createMnemonic, validateMnemonic } from 'src/requests';
import { Console } from 'src/utils/console';
import { AccountsContext } from 'src/context';
import { ConfirmPassword, Mnemonic } from 'src/components';
import { MnemonicInput } from 'src/components/textfields';
import { StyledBackButton } from 'src/components/StyledBackButton';
const createAccountSteps = [
'Copy and save mnemonic for your new account',
@@ -29,15 +30,14 @@ const importAccountSteps = [
'Confirm the password used to login to your wallet',
];
const MnemonicStep = ({ mnemonic, onNext, onBack }: { mnemonic: string; onNext: () => void; onBack: () => void }) => {
const MnemonicStep = ({ mnemonic, onNext }: { mnemonic: string; onNext: () => void }) => {
const { copy, copied } = useClipboard({ copiedTimeout: 5000 });
return (
<Box sx={{ mt: 1 }}>
<DialogContent>
<Mnemonic mnemonic={mnemonic} handleCopy={copy} copied={copied} />
</DialogContent>
<DialogActions sx={{ p: 3, pt: 0, gap: 2 }}>
<StyledBackButton onBack={onBack} />
<DialogActions sx={{ p: 3, pt: 0 }}>
<Button disabled={!copied} fullWidth disableElevation variant="contained" size="large" onClick={onNext}>
I saved my mnemonic
</Button>
@@ -50,12 +50,10 @@ const ImportMnemonic = ({
value,
onChange,
onNext,
onBack,
}: {
value: string;
onChange: (value: string) => void;
onNext: () => void;
onBack: () => void;
}) => {
const [error, setError] = useState<string>();
@@ -79,8 +77,7 @@ const ImportMnemonic = ({
}}
/>
</DialogContent>
<DialogActions sx={{ p: 3, pt: 0, gap: 2 }}>
<StyledBackButton onBack={onBack} />
<DialogActions sx={{ p: 3, pt: 0 }}>
<Button
disabled={value.length === 0}
fullWidth
@@ -96,7 +93,7 @@ const ImportMnemonic = ({
);
};
const NameAccount = ({ onNext, onBack }: { onNext: (value: string) => void; onBack: () => void }) => {
const NameAccount = ({ onNext }: { onNext: (value: string) => void }) => {
const [value, setValue] = useState('');
const [error, setError] = useState<string>();
@@ -124,8 +121,7 @@ const NameAccount = ({ onNext, onBack }: { onNext: (value: string) => void; onBa
fullWidth
/>
</DialogContent>
<DialogActions sx={{ p: 3, pt: 0, gap: 2 }}>
<StyledBackButton onBack={onBack} />
<DialogActions sx={{ p: 3, pt: 0 }}>
<Button
disabled={!value.length}
fullWidth
@@ -182,6 +178,9 @@ export const AddAccountModal = () => {
<DialogTitle sx={{ pb: 0 }}>
<Box display="flex" justifyContent="space-between" alignItems="center">
<Typography variant="h6">{`${dialogToDisplay} new account`}</Typography>
<IconButton onClick={() => (step === 0 ? handleClose() : setStep((s) => s - 1))}>
<ArrowBackSharp />
</IconButton>
</Box>
<Typography sx={{ mt: 2 }}>
{dialogToDisplay === 'Add' ? createAccountSteps[step] : importAccountSteps[step]}
@@ -191,17 +190,12 @@ export const AddAccountModal = () => {
switch (step) {
case 0:
return dialogToDisplay === 'Add' ? (
<MnemonicStep
mnemonic={data.mnemonic}
onNext={() => setStep((s) => s + 1)}
onBack={() => (step === 0 ? handleClose() : setStep((s) => s - 1))}
/>
<MnemonicStep mnemonic={data.mnemonic} onNext={() => setStep((s) => s + 1)} />
) : (
<ImportMnemonic
value={data.mnemonic}
onChange={(value) => setData((d) => ({ ...d, mnemonic: value }))}
onNext={() => setStep((s) => s + 1)}
onBack={() => (step === 0 ? handleClose() : setStep((s) => s - 1))}
/>
);
case 1:
@@ -211,7 +205,6 @@ export const AddAccountModal = () => {
setData((d) => ({ ...d, accountName }));
setStep((s) => s + 1);
}}
onBack={() => setStep((s) => s - 1)}
/>
);
case 2:
@@ -229,7 +222,6 @@ export const AddAccountModal = () => {
}
}
}}
onCancel={() => setStep((s) => s - 1)}
isLoading={isLoading}
error={error}
/>
@@ -19,18 +19,17 @@ export const ConfirmPasswordModal = ({
<Dialog open={Boolean(accountName)} onClose={onClose} fullWidth>
<Paper>
<DialogTitle>
<Typography variant="h6">Switch account</Typography>
<Typography fontSize="small" sx={{ color: 'grey.600' }}>
<Box display="flex" justifyContent="space-between" alignItems="center">
<Typography variant="h6">Switch account</Typography>
<IconButton onClick={onClose}>
<ArrowBack />
</IconButton>
</Box>
<Typography variant="body1" sx={{ color: (theme) => theme.palette.text.disabled }}>
Confirm password
</Typography>
</DialogTitle>
<ConfirmPassword
onConfirm={onConfirm}
error={error}
isLoading={isLoading}
buttonTitle="Switch account"
onCancel={onClose}
/>
<ConfirmPassword onConfirm={onConfirm} error={error} isLoading={isLoading} buttonTitle="Switch account" />
</Paper>
</Dialog>
);
@@ -33,7 +33,7 @@ export const EditAccountModal = () => {
<Close />
</IconButton>
</Box>
<Typography fontSize="small" sx={{ color: 'grey.600' }}>
<Typography variant="body1" sx={{ color: (theme) => theme.palette.text.disabled }}>
New wallet address
</Typography>
</DialogTitle>
@@ -0,0 +1,69 @@
import React, { useContext, useState } from 'react';
import {
Box,
Button,
Paper,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
TextField,
Typography,
} from '@mui/material';
import { Close } from '@mui/icons-material';
import { AccountsContext } from 'src/context';
export const ImportAccountModal = () => {
const [mnemonic, setMnemonic] = useState('');
const { dialogToDisplay, setDialogToDisplay, handleImportAccount } = useContext(AccountsContext);
const handleClose = () => {
setMnemonic('');
setDialogToDisplay('Accounts');
};
return (
<Dialog open={dialogToDisplay === 'Import'} onClose={handleClose} fullWidth>
<Paper>
<DialogTitle>
<Box display="flex" justifyContent="space-between" alignItems="center">
<Typography variant="h6">Import account</Typography>
<IconButton onClick={handleClose}>
<Close />
</IconButton>
</Box>
<Typography variant="body1" sx={{ color: (theme) => theme.palette.text.disabled }}>
Provide mnemonic of account you want to import
</Typography>
</DialogTitle>
<DialogContent sx={{ p: 0 }}>
<Box sx={{ px: 3, mt: 1 }}>
<TextField
placeholder="Paste or type your mnemonic here"
fullWidth
value={mnemonic}
onChange={(e) => setMnemonic(e.target.value)}
autoFocus
multiline
rows={3}
/>
</Box>
</DialogContent>
<DialogActions sx={{ p: 3 }}>
<Button
fullWidth
disableElevation
variant="contained"
size="large"
onClick={() => handleImportAccount({ id: '', address: '' })}
disabled={!mnemonic.length}
>
Import account
</Button>
</DialogActions>
</Paper>
</Dialog>
);
};
-42
View File
@@ -1,42 +0,0 @@
import React, { useRef } from 'react';
import { MoreVertSharp } from '@mui/icons-material';
import { IconButton, ListItemIcon, ListItemText, Menu, MenuItem } from '@mui/material';
export const ActionsMenu: React.FC<{ open: boolean; onOpen: () => void; onClose: () => void }> = ({
children,
open,
onOpen,
onClose,
}) => {
const anchorEl: any = useRef<HTMLElement>();
return (
<>
<IconButton ref={anchorEl} onClick={onOpen}>
<MoreVertSharp />
</IconButton>
<Menu anchorEl={anchorEl.current} open={open} onClose={onClose}>
{children}
</Menu>
</>
);
};
export const ActionsMenuItem = ({
title,
description,
onClick,
Icon,
disabled,
}: {
title: string;
description?: string;
onClick?: () => void;
Icon?: React.ReactNode;
disabled?: boolean;
}) => (
<MenuItem sx={{ p: 2 }} onClick={onClick} disabled={disabled}>
<ListItemIcon sx={{ color: 'text.primary' }}>{Icon}</ListItemIcon>
<ListItemText sx={{ color: 'text.primary' }} primary={title} secondary={description} />
</MenuItem>
);
+13 -2
View File
@@ -7,11 +7,13 @@ import ModeNightOutlinedIcon from '@mui/icons-material/ModeNightOutlined';
import LightModeOutlinedIcon from '@mui/icons-material/LightModeOutlined';
import { AppContext } from '../context/main';
import { NetworkSelector } from './NetworkSelector';
import { Node as NodeIcon } from '../svg-icons/node';
import { MultiAccounts } from './Accounts';
import { config } from '../config';
export const AppBar = () => {
const { logOut, handleShowTerminal, appEnv, mode, handleSwitchMode } = useContext(AppContext);
const { logOut, handleShowTerminal, appEnv, handleShowSettings, showSettings, mode, handleSwitchMode } =
useContext(AppContext);
const navigate = useNavigate();
return (
@@ -29,7 +31,7 @@ export const AppBar = () => {
<Grid item container justifyContent="flex-end" md={12} lg={5} spacing={2}>
<Grid item>
<IconButton size="small" onClick={handleSwitchMode} sx={{ color: 'text.primary' }}>
{mode === 'dark' ? (
{mode === 'light' ? (
<LightModeOutlinedIcon fontSize="small" />
) : (
<ModeNightOutlinedIcon fontSize="small" sx={{ transform: 'rotate(180deg)' }} />
@@ -43,6 +45,15 @@ export const AppBar = () => {
</IconButton>
</Grid>
)}
<Grid item>
<IconButton
onClick={handleShowSettings}
sx={{ color: showSettings ? 'primary.main' : 'text.primary' }}
size="small"
>
<NodeIcon fontSize="small" />
</IconButton>
</Grid>
<Grid item>
<IconButton
size="small"
@@ -0,0 +1,65 @@
import React, { useContext } from 'react';
import { Logout } from '@mui/icons-material';
import TerminalIcon from '@mui/icons-material/Terminal';
import ModeNightOutlinedIcon from '@mui/icons-material/ModeNightOutlined';
import LightModeOutlinedIcon from '@mui/icons-material/LightModeOutlined';
import { AppBar as MuiAppBar, Grid, IconButton, Toolbar } from '@mui/material';
import { Node } from 'src/svg-icons/node';
import { config } from '../../config';
import { AppContext } from '../../context/main';
import { MultiAccounts } from '../Accounts';
import { NetworkSelector } from '../NetworkSelector';
export const AppBar = () => {
const { showSettings, handleShowTerminal, appEnv, handleShowSettings, logOut, mode, handleSwitchMode } =
useContext(AppContext);
return (
<MuiAppBar position="sticky" sx={{ boxShadow: 'none', bgcolor: 'transparent', backgroundImage: 'none' }}>
<Toolbar disableGutters>
<Grid container justifyContent="space-between" alignItems="center" flexWrap="nowrap">
<Grid item container alignItems="center" spacing={1}>
<Grid item>
<MultiAccounts />
</Grid>
<Grid item>
<NetworkSelector />
</Grid>
</Grid>
<Grid item container justifyContent="flex-end" md={12} lg={5} spacing={2}>
<Grid item>
<IconButton size="small" onClick={handleSwitchMode} sx={{ color: 'text.primary' }}>
{mode === 'light' ? (
<ModeNightOutlinedIcon fontSize="small" />
) : (
<LightModeOutlinedIcon fontSize="small" />
)}
</IconButton>
</Grid>
{(appEnv?.SHOW_TERMINAL || config.IS_DEV_MODE) && (
<Grid item>
<IconButton size="small" onClick={handleShowTerminal} sx={{ color: 'text.primary' }}>
<TerminalIcon fontSize="small" />
</IconButton>
</Grid>
)}
<Grid item>
<IconButton
onClick={handleShowSettings}
sx={{ color: showSettings ? 'primary.main' : 'text.primary' }}
size="small"
>
<Node fontSize="small" />
</IconButton>
</Grid>
<Grid item>
<IconButton size="small" onClick={logOut} sx={{ color: 'text.primary' }}>
<Logout fontSize="small" />
</IconButton>
</Grid>
</Grid>
</Grid>
</Toolbar>
</MuiAppBar>
);
};
@@ -0,0 +1 @@
export * from './AppBar';
@@ -1,44 +0,0 @@
import React from 'react';
import { Box, Button, Typography } from '@mui/material';
import { NymCard } from '../NymCard';
export const Bond = ({
onBond,
disabled,
}: {
onBond: () => void;
disabled: boolean;
}) => (
<NymCard title="Bonding" borderless>
<Box
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}}
>
<Typography>Bond a mixnode or a gateway</Typography>
<Box
sx={{
display: 'flex',
alignItems: 'flex-end',
justifyContent: 'space-between',
gap: 2,
}}
>
<Button
size="large"
variant="contained"
color="primary"
type="button"
disableElevation
onClick={onBond}
disabled={disabled}
>
Bond
</Button>
</Box>
</Box>
</NymCard>
);

Some files were not shown because too many files have changed in this diff Show More