Compare commits

..

1 Commits

Author SHA1 Message Date
Tommy Verrall f95e9a7d37 Implement base line for tests on the validator ts client
- This will need to be separated and configured accordingly 
- This was a quick spin up, using jest as a library to implement some coverage
- Further things to be refined - mocks, more coverage, better configuration, clean up methods, improve env vars
2022-01-06 10:01:08 +00:00
832 changed files with 80219 additions and 75682 deletions
Vendored
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -15,8 +15,8 @@
* @futurechimp @mmsinclair
# Rust rules:
*.rs @durch @futurechimp @jstuczyn @neacsu @octol
Cargo.* @durch @futurechimp @jstuczyn @neacsu @octol
*.rs @durch @futurechimp @jstuczyn @neacsu
Cargo.* @durch @futurechimp @jstuczyn @neacsu
# JS rules:
*.js @mmsinclair @fmtabbara @Aid19801
-63
View File
@@ -1,63 +0,0 @@
name: CI for ts-packages
on:
push:
paths:
- 'ts-packages/**'
jobs:
build:
runs-on: custom-runner-linux
steps:
- uses: actions/checkout@v2
- name: Install rsync
run: sudo apt-get install rsync
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v2
with:
node-version: '16'
- name: Setup yarn
run: npm install -g yarn
- name: Build
run: yarn && yarn build && yarn build:ci
- name: Deploy branch to CI www (storybook)
continue-on-error: true
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete"
SOURCE: "ts-packages/dist/storybook/"
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/ts-${{ env.GITHUB_REF_SLUG }}
EXCLUDE: "/dist/, /node_modules/"
- name: Deploy branch to CI www (example)
continue-on-error: true
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete"
SOURCE: "ts-packages/dist/example/"
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/ts-${{ env.GITHUB_REF_SLUG }}-example
EXCLUDE: "/dist/, /node_modules/"
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
env:
NYM_NOTIFICATION_KIND: ts-packages
NYM_PROJECT_NAME: "ts-packages"
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
NYM_CI_WWW_LOCATION: "ts-${{ env.GITHUB_REF_SLUG }}"
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_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-ts-packages"
IS_SUCCESS: "${{ job.status == 'success' }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
+36 -12
View File
@@ -9,14 +9,28 @@ on:
- 'explorer/**'
jobs:
matrix_prep:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
# creates the matrix strategy from build_matrix_includes.json
- uses: actions/checkout@v2
- id: set-matrix
uses: JoshuaTheMiller/conditional-build-matrix@main
with:
inputFile: '.github/workflows/build_matrix_includes.json'
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
build:
runs-on: [ self-hosted, custom-linux-exoscale ]
# Enable sccache via environment variable
env:
RUSTC_WRAPPER: /home/ubuntu/.cargo/bin/sccache
needs: matrix_prep
strategy:
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.rust == 'nightly' || matrix.rust == 'beta' || matrix.os == 'windows-latest' }}
steps:
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
if: matrix.os == 'ubuntu-latest'
- name: Check out repository code
uses: actions/checkout@v2
@@ -25,7 +39,7 @@ jobs:
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
toolchain: ${{ matrix.rust }}
override: true
components: rustfmt, clippy
@@ -33,13 +47,13 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace
args: --all
- name: Run all tests
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --all-features
args: --all
- name: Check formatting
uses: actions-rs/cargo@v1
@@ -49,30 +63,40 @@ jobs:
- uses: actions-rs/clippy-check@v1
name: Clippy checks
# if: matrix.os == 'ubuntu-latest' && matrix.rust == 'stable'
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
- name: Run clippy
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --workspace -- -D warnings
args: -- -D warnings
# COCONUT stuff
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Build all binaries with coconut enabled
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --features=coconut
args: --all --features=coconut
- name: Run all tests with coconut enabled
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --features=coconut
args: --all --features=coconut
- name: Run clippy with coconut enabled
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --features=coconut -- -D warnings
args: --features=coconut -- -D warnings
+33 -2
View File
@@ -10,10 +10,41 @@
"rust":"stable",
"runOnEvent":"pull_request"
},
{
"os":"macos-latest",
"rust":"stable",
"runOnEvent":"pull_request"
},
{
"os":"ubuntu-latest",
"rust":"beta",
"runOnEvent":"pull_request"
},
{
"os":"windows-latest",
"rust":"beta",
"runOnEvent":"pull_request"
},
{
"os":"macos-latest",
"rust":"beta",
"runOnEvent":"pull_request"
},
{
"os":"ubuntu-latest",
"rust":"nightly",
"runOnEvent":"pull_request"
},
{
"os":"windows-latest",
"rust":"nightly",
"runOnEvent":"pull_request"
},
{
"os":"macos-latest",
"rust":"nightly",
"runOnEvent":"pull_request"
}
]
]
+2 -2
View File
@@ -45,7 +45,7 @@ jobs:
RUSTFLAGS: '-C link-arg=-s'
with:
command: build
args: --manifest-path contracts/Cargo.toml --workspace --target wasm32-unknown-unknown
args: --manifest-path contracts/Cargo.toml --all --target wasm32-unknown-unknown
- uses: actions-rs/cargo@v1
with:
@@ -61,4 +61,4 @@ jobs:
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --manifest-path contracts/Cargo.toml --workspace -- -D warnings
args: --manifest-path contracts/Cargo.toml --all -- -D warnings
+3 -4
View File
@@ -16,9 +16,8 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- name: Setup yarn
run: npm install -g yarn
node-version: '14'
- run: npm install
- name: Run ESLint
# GitHub should automatically annotate the PR
run: yarn && yarn lint
run: npm run lint
+7 -11
View File
@@ -19,17 +19,14 @@ jobs:
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v2
with:
node-version: '16'
- name: Setup yarn
run: npm install -g yarn
node-version: '14'
- run: npm install
continue-on-error: true
- name: Build shared packages
run: cd .. && yarn && yarn build
- name: Set environment from the example
run: cp .env.prod .env
# - run: yarn test
# continue-on-error: true
- run: yarn && yarn build
- run: npm run test
continue-on-error: true
- run: npm run build
continue-on-error: true
- name: Deploy branch to CI www
continue-on-error: true
@@ -44,10 +41,9 @@ jobs:
EXCLUDE: "/dist/, /node_modules/"
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
working-directory: .github/workflows/support-files/messages
- name: Keybase - Send Notification
env:
NYM_NOTIFICATION_KIND: network-explorer
NYM_PROJECT_NAME: "Network Explorer"
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
NYM_CI_WWW_LOCATION: "network-explorer-${{ env.GITHUB_REF_SLUG }}"
@@ -60,4 +56,4 @@ jobs:
IS_SUCCESS: "${{ job.status == 'success' }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
args: .github/workflows/support-files/messages/entry_point_notifications.sh
-125
View File
@@ -1,125 +0,0 @@
name: Nightly builds
on:
schedule:
- cron: '14 4 * * *'
jobs:
matrix_prep:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
# creates the matrix strategy from nightly_build_matrix_includes.json
- uses: actions/checkout@v2
- id: set-matrix
uses: JoshuaTheMiller/conditional-build-matrix@main
with:
inputFile: '.github/workflows/nightly_build_matrix_includes.json'
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
build:
needs: matrix_prep
strategy:
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.rust == 'nightly' || matrix.rust == 'beta' || matrix.rust == 'stable' }}
steps:
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
if: matrix.os == 'ubuntu-latest'
- name: Check out repository code
uses: actions/checkout@v2
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
components: rustfmt, clippy
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace
- name: Run all tests
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- uses: actions-rs/clippy-check@v1
name: Clippy checks
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
- name: Run clippy
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --workspace --all-targets -- -D warnings
# COCONUT stuff
- name: Build all binaries with coconut enabled
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --features=coconut
- name: Run all tests with coconut enabled
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --features=coconut
- name: Run clippy with coconut enabled
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --workspace --all-targets --features=coconut -- -D warnings
notification:
needs: build
runs-on: ubuntu-latest
steps:
- name: Collect jobs status
uses: technote-space/workflow-conclusion-action@v2
- name: Check out repository code
uses: actions/checkout@v2
- name: Keybase - Node Install
if: env.WORKFLOW_CONCLUSION == 'failure'
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
if: env.WORKFLOW_CONCLUSION == 'failure'
env:
NYM_NOTIFICATION_KIND: nightly
NYM_PROJECT_NAME: "Nym nightly build"
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_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-nightly"
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
@@ -1,50 +0,0 @@
[
{
"os":"ubuntu-latest",
"rust":"stable",
"runOnEvent":"schedule"
},
{
"os":"windows-latest",
"rust":"stable",
"runOnEvent":"schedule"
},
{
"os":"macos-latest",
"rust":"stable",
"runOnEvent":"schedule"
},
{
"os":"ubuntu-latest",
"rust":"beta",
"runOnEvent":"schedule"
},
{
"os":"windows-latest",
"rust":"beta",
"runOnEvent":"schedule"
},
{
"os":"macos-latest",
"rust":"beta",
"runOnEvent":"schedule"
},
{
"os":"ubuntu-latest",
"rust":"nightly",
"runOnEvent":"schedule"
},
{
"os":"windows-latest",
"rust":"nightly",
"runOnEvent":"schedule"
},
{
"os":"macos-latest",
"rust":"nightly",
"runOnEvent":"schedule"
}
]
@@ -1,77 +0,0 @@
name: Publish Nym Wallet (MacOS)
on:
release:
types: [created]
defaults:
run:
working-directory: nym-wallet
jobs:
publish-tauri:
strategy:
fail-fast: false
matrix:
platform: [macos-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- name: Check the release tag starts with `nym-wallet-`
if: startsWith(github.ref, 'refs/tags/nym-wallet-') == false
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-wallet-...')
- name: Node v16
uses: actions/setup-node@v1
with:
node-version: 16.x
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install the Apple developer certificate for code signing
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$APPLE_CERTIFICATE" | base64 --decode --output $CERTIFICATE_PATH
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
- name: Install app dependencies and build it
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_IDENTITY_ID }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
run: yarn && yarn build
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
with:
files: nym-wallet/target/release/bundle/dmg/*.dmg
- name: Clean up keychain
if: ${{ always() }}
run: |
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
@@ -1,46 +0,0 @@
name: Publish Nym Wallet (Ubuntu)
on:
release:
types: [created]
defaults:
run:
working-directory: nym-wallet
jobs:
publish-tauri:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- name: Tauri dependencies
run: >
sudo apt-get update &&
sudo apt-get install -y webkit2gtk-4.0
- name: Check the release tag starts with `nym-wallet-`
if: startsWith(github.ref, 'refs/tags/nym-wallet-') == false
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-wallet-...')
- name: Node v16
uses: actions/setup-node@v1
with:
node-version: 16.x
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install app dependencies and build it
run: yarn && yarn build
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
with:
files: nym-wallet/target/release/bundle/appimage/*.AppImage
+12
View File
@@ -0,0 +1,12 @@
name: Publish Nym Wallet
on:
push:
tags:
- nym-wallet-*
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Run a one-line script
run: echo Hello, world!
+29
View File
@@ -0,0 +1,29 @@
name: Generate TS types
on:
push:
paths-ignore:
- "explorer/**"
pull_request:
paths-ignore:
- "explorer/**"
jobs:
nym-wallet-types:
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request' }}
steps:
- name: Prepare
run: sudo apt-get update && sudo apt-get install -y libpango1.0-dev libatk1.0-dev libgdk-pixbuf2.0-dev libsoup2.4-dev librust-gdk-dev libwebkit2gtk-4.0-dev
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Generate TS
run: cd nym-wallet/src-tauri && cargo test
- uses: EndBug/add-and-commit@v7.2.1 # https://github.com/marketplace/actions/add-commit
with:
add: '["nym-wallet"]'
message: "[ci skip] Generate TS types"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1,35 +0,0 @@
KEYBASE_NYM_CHANNEL=
KEYBASE_NYMBOT_USERNAME=
KEYBASE_NYMBOT_PAPERKEY=
NYM_NOTIFICATION_KIND=nightly
NYM_PROJECT_NAME=Nightly Build
#----------------------------------------------------------------
# Custom GitHub Actions mock env vars
IS_SUCCESS=true
#----------------------------------------------------------------
# GitHub Actions context mock env vars
GITHUB_SHA=abcdef
GITHUB_RUN_ID=123456
GITHUB_REPOSITORY=nymtech/nym
GITHUB_SERVER_URL=https://github.com
GIT_BRANCH_NAME=feature/testing-support-files
GIT_BRANCH=feature/testing-support-files
GIT_COMMIT_MESSAGE=This is the commit message
GITHUB_ACTOR=octocat
# add a Personal Access Token (PAT) generated from GitHub here for use in testing
GITHUB_TOKEN=
#----------------------------------------------------------------
# Network Explorer
NYM_CI_WWW_LOCATION=some-branch
NYM_CI_WWW_BASE=example.com
#----------------------------------------------------------------
# Nightly builds
WORKFLOW_CONCLUSION=success
SHOW_DEBUG=true
@@ -1,5 +0,0 @@
node_modules
.idea
# don't commit the lock file to avoid cross-platform issues
package-lock.json
-1
View File
@@ -1 +0,0 @@
16
-58
View File
@@ -1,58 +0,0 @@
# GitHub Actions Support Files
This is a collection of scripts and files to support GitHub Actions.
## Sending Notifications
These scripts send CI notifications to Keybase by creating messages from templates and env vars passed from GitHub Actions.
### Adding notifications to a GitHub Action
```
jobs:
build:
...
- name: Notifications - Node Install
run: npm install
working-directory: .github/workflows/support-files/notifications
- name: Notifications - Send
env:
NYM_NOTIFICATION_KIND: "my-component"
GIT_BRANCH: "${GITHUB_REF##*/}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-network-explorer"
IS_SUCCESS: "${{ job.status == 'success' }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
```
Notifications are run by adding the snippet above to a GitHub Action, and:
1. Installing node packages needed at run time
2. Set the env vars as required:
- `NYM_NOTIFICATION_KIND` matches the directory in `.github/workflows/support-files/${NYM_NOTIFICATION_KIND}` to provide the templates and extra scripting in `index.js`
- Keybase credentials, channel and other env vars for the status of the build and repo
3. Replacing the default entry point shell script on the `keybaseio/client:stable-node` docker image to run `.github/workflows/support-files/notifications/entry_point.sh`
### Running locally
You will need:
- Node 16 LTS
- npm
Copy `.github/workflows/support-files/.env.example` to `.github/workflows/support-files/.env` and valid Keybase credentials.
Then run `npm install` to get dependencies.
Start development mode for the notification type you want either by passing the value as an env var called `NYM_NOTIFICATION_KIND` or set the `.env` file values correctly.
```bash
cd .github/workflows/support-files
npm install
cp .env.example .env
vi .env
npm run dev
```
-1
View File
@@ -1 +0,0 @@
require('./notifications/send_message');
@@ -0,0 +1,2 @@
node_modules
.idea
@@ -4,14 +4,11 @@
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "node dev.js",
"format": "prettier --write **/*.js"
"format": "prettier --write send_message.js"
},
"dependencies": {
"dotenv": "^16.0.0",
"handlebars": "^4.7.7",
"keybase-bot": "^3.6.1",
"octokit": "^1.7.1"
"keybase-bot": "^3.6.1"
},
"devDependencies": {
"prettier": "2.3.2"
@@ -0,0 +1,69 @@
const Bot = require('keybase-bot');
const Handlebars = require('handlebars');
const fs = require('fs');
async function main() {
const data = { env: process.env };
// const data = { ...PASTE TEST DATA HERE ... }; // -- DEV: uncomment to set test data
// validation of environment
if(!(process.env.NYM_PROJECT_NAME || data.env.NYM_PROJECT_NAME)) {
throw new Error('Please set env var NYM_PROJECT_NAME with the project name for displaying in notification messages');
}
const keybaseChannel = process.env.KEYBASE_NYM_CHANNEL || data.env.KEYBASE_NYM_CHANNEL;
if(!keybaseChannel) {
throw new Error('Please set env var KEYBASE_NYM_CHANNEL with the channel name for the notification message');
}
// extract the git branch name
const GIT_BRANCH_NAME = (process.env.GITHUB_REF || data.env.GITHUB_REF).split('/').slice(2).join('/');
data.env.GIT_BRANCH_NAME = GIT_BRANCH_NAME;
const source = fs
.readFileSync(process.env.IS_SUCCESS === 'true' ? 'success' : 'failure')
.toString();
const template = Handlebars.compile(source);
const result = template(data);
// -- DEV: uncomment to show what is available in the handlebars template / show the result
// console.dir({ data }, { depth: null });
// console.log(result);
const bot = new Bot();
try {
const username = process.env.KEYBASE_NYMBOT_USERNAME;
const paperkey = process.env.KEYBASE_NYMBOT_PAPERKEY;
if(!username) {
throw new Error('Username is not defined. Please set env var KEYBASE_NYMBOT_USERNAME');
}
if(!paperkey) {
throw new Error('Paperkey is not defined. Please set env var KEYBASE_NYMBOT_PAPERKEY');
}
console.log(`Initialising keybase with user "${username}" and key: "${'*'.repeat(paperkey.length)}"...`);
await bot.init(username, paperkey, { verbose: false });
const channel = {
name: 'nymtech_bot',
membersType: 'team',
topicName: keybaseChannel,
topic_type: 'CHAT',
};
const message = {
body: result,
};
console.log(`Sending to ${channel.name}#${channel.topicName}...`);
await bot.chat.send(channel, message);
console.log('Message sent!');
} catch (error) {
console.error(error);
process.exitCode = -1;
} finally {
await bot.deinit();
}
}
main();
@@ -5,7 +5,7 @@
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
Commit message by `{{ env.GITHUB_ACTOR }}` at {{ timestamp }}:
Commit message:
```
{{ env.GIT_COMMIT_MESSAGE }}
```
@@ -1,29 +0,0 @@
const Handlebars = require('handlebars');
const fs = require('fs');
const path = require('path');
async function addToContextAndValidate(context) {
if (!context.env.NYM_CI_WWW_LOCATION) {
throw new Error('Please ensure the env var NYM_CI_WWW_LOCATION is set');
}
if (!context.env.NYM_CI_WWW_BASE) {
throw new Error('Please ensure the env var NYM_CI_WWW_BASE is set');
}
}
async function getMessageBody(context) {
const source = fs
.readFileSync(
context.env.IS_SUCCESS === 'true'
? path.resolve(__dirname, 'templates', 'success')
: path.resolve(__dirname, 'templates', 'failure'),
)
.toString();
const template = Handlebars.compile(source);
return template(context);
}
module.exports = {
addToContextAndValidate,
getMessageBody,
};
@@ -1,162 +0,0 @@
const Handlebars = require('handlebars');
const fs = require('fs');
const path = require('path');
const { Octokit, App } = require('octokit');
async function addToContextAndValidate(context) {
if (!context.env.WORKFLOW_CONCLUSION) {
throw new Error('Please ensure the env var WORKFLOW_CONCLUSION is set');
}
if (!context.env.GITHUB_TOKEN) {
throw new Error('Please ensure the env var GITHUB_TOKEN is set');
}
if (!context.env.GITHUB_RUN_ID) {
throw new Error('Please ensure the env var GITHUB_RUN_ID is set');
}
if (!context.env.GITHUB_REPOSITORY) {
throw new Error('Please ensure the env var GITHUB_REPOSITORY is set');
}
}
async function getMessageBody(context) {
const source = fs
.readFileSync(
context.env.WORKFLOW_CONCLUSION === 'success'
? path.resolve(__dirname, 'templates', 'success')
: path.resolve(__dirname, 'templates', 'failure'),
)
.toString();
const template = Handlebars.compile(source);
// get job details from GitHub API
const octokit = new Octokit({ auth: context.env.GITHUB_TOKEN });
const [owner, repo] = context.env.GITHUB_REPOSITORY.split('/');
const {
data: { jobs },
} = await octokit.rest.actions.listJobsForWorkflowRun({
run_id: context.env.GITHUB_RUN_ID,
owner,
repo,
});
// uncomment this to see what is available for each job
if(process.env.SHOW_DEBUG) {
console.dir(jobs, { depth: null });
}
/*
a sample of the response is:
{
total_count: 10,
jobs: [
{
id: 5182940024,
run_id: 1840752095,
run_url: 'https://api.github.com/repos/nymtech/nym/actions/runs/1840752095',
run_attempt: 1,
node_id: 'CR_kwDODdjOis8AAAABNO1jeA',
head_sha: 'aa00eb70d57751bfa556bd3602df87c7473367fc',
url: 'https://api.github.com/repos/nymtech/nym/actions/jobs/5182940024',
html_url: 'https://github.com/nymtech/nym/runs/5182940024?check_suite_focus=true',
status: 'completed',
conclusion: 'success',
started_at: '2022-02-14T11:28:34Z',
completed_at: '2022-02-14T11:28:38Z',
name: 'matrix_prep',
steps: [
{
name: 'Set up job',
status: 'completed',
conclusion: 'success',
number: 1,
started_at: '2022-02-14T13:28:34.000+02:00',
completed_at: '2022-02-14T13:28:36.000+02:00'
},
{
name: 'Run actions/checkout@v2',
status: 'completed',
conclusion: 'success',
number: 2,
started_at: '2022-02-14T13:28:36.000+02:00',
completed_at: '2022-02-14T13:28:37.000+02:00'
},
...
],
check_run_url: 'https://api.github.com/repos/nymtech/nym/check-runs/5182940024',
labels: [ 'ubuntu-latest' ],
runner_id: 1,
runner_name: 'Hosted Agent',
runner_group_id: 2,
runner_group_name: 'GitHub Actions'
},
{
id: 5182943473,
run_id: 1840752095,
run_url: 'https://api.github.com/repos/nymtech/nym/actions/runs/1840752095',
run_attempt: 1,
node_id: 'CR_kwDODdjOis8AAAABNO1w8Q',
head_sha: 'aa00eb70d57751bfa556bd3602df87c7473367fc',
url: 'https://api.github.com/repos/nymtech/nym/actions/jobs/5182943473',
html_url: 'https://github.com/nymtech/nym/runs/5182943473?check_suite_focus=true',
status: 'completed',
conclusion: 'failure',
started_at: '2022-02-14T11:29:04Z',
completed_at: '2022-02-14T11:55:45Z',
name: 'build (macos-latest, stable, schedule)',
steps: [
{
name: 'Set up job',
status: 'completed',
conclusion: 'success',
number: 1,
started_at: '2022-02-14T13:29:04.000+02:00',
completed_at: '2022-02-14T13:29:26.000+02:00'
},
{
name: 'Install Dependencies (Linux)',
status: 'completed',
conclusion: 'skipped',
number: 2,
started_at: '2022-02-14T13:29:26.000+02:00',
completed_at: '2022-02-14T13:29:26.000+02:00'
},
{
name: 'Keybase - Send Notification',
status: 'completed',
conclusion: 'failure',
number: 15,
started_at: '2022-02-14T13:55:44.000+02:00',
completed_at: '2022-02-14T13:55:44.000+02:00'
},
],
check_run_url: 'https://api.github.com/repos/nymtech/nym/check-runs/5182943473',
labels: [ 'macos-latest' ],
runner_id: 4,
runner_name: 'GitHub Actions 4',
runner_group_id: 2,
runner_group_name: 'GitHub Actions'
},
...
]
}
*/
const jobResults = jobs
.map((job) => {
const icon = job.conclusion === 'success' ? '🟩' : '🟥';
// each job is converted into formatted markdown text
return `${icon} ${job.conclusion}: ${job.name} - ${job.html_url}`;
})
// and join with newlines for display in the template
.join('\n');
return template({ ...context, jobResults });
}
module.exports = {
addToContextAndValidate,
getMessageBody,
};
@@ -1,9 +0,0 @@
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
> :rocket: {{ env.NYM_PROJECT_NAME }}
> 🔴 **FAILURE** :cry:
> `when` {{ timestamp }}
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
{{ jobResults }}
@@ -1,9 +0,0 @@
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
> :rocket: {{ env.NYM_PROJECT_NAME }}
> ✅ **SUCCESS**
> `when` {{ timestamp }}
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
{{ jobResults }}
@@ -1,153 +0,0 @@
require('dotenv').config();
const Bot = require('keybase-bot');
let context = {
kinds: ['ts-packages', 'network-explorer', 'nightly'],
};
/**
* Validate that all required env and context vars are available
*/
function validateContext() {
if (!context.env.NYM_NOTIFICATION_KIND) {
throw new Error(
'Please set env var NYM_NOTIFICATION_KIND with the project kind that matches a directory in ".github/workflows/support-files"',
);
}
if (!context.kinds.includes(context.env.NYM_NOTIFICATION_KIND)) {
throw new Error(`Env var NYM_NOTIFICATION_KIND is not in ${context.kinds}`);
}
if (!context.env.NYM_PROJECT_NAME) {
throw new Error(
'Please set env var NYM_PROJECT_NAME with the project name for displaying in notification messages',
);
}
if (!context.env.KEYBASE_NYM_CHANNEL) {
throw new Error(
'Please set env var KEYBASE_NYM_CHANNEL with the channel name for the notification message',
);
}
if (!context.env.KEYBASE_NYMBOT_USERNAME) {
throw new Error(
'Username is not defined. Please set env var KEYBASE_NYMBOT_USERNAME',
);
}
if (!context.env.KEYBASE_NYMBOT_PAPERKEY) {
throw new Error(
'Paperkey is not defined. Please set env var KEYBASE_NYMBOT_PAPERKEY',
);
}
}
/**
* Creates a context that will be available in the templates for rendering notifications
*/
function createTemplateContext() {
const options = { dateStyle: 'full', timeStyle: 'long' };
context.timestamp = new Date().toLocaleString(undefined, options);
// add environment to template context and validate
context.env = process.env;
try {
validateContext();
} catch (e) {
if(process.env.SHOW_DEBUG) {
// recursively print the context for easy debugging and rethrow the error
console.dir({ context }, { depth: null });
}
throw e;
}
context.kind = context.env.NYM_NOTIFICATION_KIND;
context.keybase = {
channel: context.env.KEYBASE_NYM_CHANNEL,
username: context.env.KEYBASE_NYMBOT_USERNAME,
paperkey: context.env.KEYBASE_NYMBOT_PAPERKEY,
};
if (!context.env.GIT_BRANCH_NAME) {
context.env.GIT_BRANCH_NAME = context.env.GITHUB_REF.split('/')
.slice(2)
.join('/');
}
context.status = process.env.IS_SUCCESS === 'true' ? 'success' : 'failure';
}
async function sendKeybaseMessage(messageBody) {
const bot = new Bot();
try {
console.log(
`Initialising keybase with user "${
context.keybase.username
}" and key: "${'*'.repeat(context.keybase.paperkey.length)}"...`,
);
await bot.init(context.keybase.username, context.keybase.paperkey, {
verbose: false,
});
const channel = {
name: 'nymtech_bot',
membersType: 'team',
topicName: context.keybase.channel,
topic_type: 'CHAT',
};
const message = {
body: messageBody,
};
console.log(`Sending to ${channel.name}#${channel.topicName}...`);
await bot.chat.send(channel, message);
console.log('Message sent!');
} catch (error) {
console.error(error);
process.exitCode = -1;
} finally {
await bot.deinit();
}
}
/**
* Uses the `kind` set in the context to process the context and generate a notification message
* @returns {Promise<string>} A string notification message body
*/
async function processKindScript() {
const script = require(`../${context.kind}`);
if (!script.addToContextAndValidate) {
throw new Error(
`"./${context.kind}/index.js" does not export a method called "async addToContextAndValidate(context)"`,
);
}
if (!script.getMessageBody) {
throw new Error(
`"./${context.kind}/index.js" does not export a method called "async getMessageBody(context)"`,
);
}
// call the script to modify and validate the context
await script.addToContextAndValidate(context);
// let the script create a message body and return the result as a string for sending
return await script.getMessageBody(context);
}
/**
* The main function, as async so that await syntax is available
*/
async function main() {
createTemplateContext();
console.log(`Sending notification for kind "${context.kind}"...`);
const messageBody = await processKindScript();
if(process.env.SHOW_DEBUG) {
console.log('-----------------------------------------');
console.log(messageBody);
console.log('-----------------------------------------');
}
await sendKeybaseMessage(messageBody);
}
// call main function and let NodeJS handle the promise
main();
@@ -1,29 +0,0 @@
const Handlebars = require('handlebars');
const fs = require('fs');
const path = require('path');
async function addToContextAndValidate(context) {
if (!context.env.NYM_CI_WWW_LOCATION) {
throw new Error('Please ensure the env var NYM_CI_WWW_LOCATION is set');
}
if (!context.env.NYM_CI_WWW_BASE) {
throw new Error('Please ensure the env var NYM_CI_WWW_BASE is set');
}
}
async function getMessageBody(context) {
const source = fs
.readFileSync(
context.env.IS_SUCCESS === 'true'
? path.resolve(__dirname, 'templates', 'success')
: path.resolve(__dirname, 'templates', 'failure'),
)
.toString();
const template = Handlebars.compile(source);
return template(context);
}
module.exports = {
addToContextAndValidate,
getMessageBody,
};
@@ -1,11 +0,0 @@
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
> :rocket: {{ env.NYM_PROJECT_NAME }}
> 🔴 **FAILURE** :cry:
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
Commit message:
```
{{ env.GIT_COMMIT_MESSAGE }}
```
@@ -1,16 +0,0 @@
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
> :rocket: {{ env.NYM_PROJECT_NAME }}
> ✅ **SUCCESS**
> ➡️➡️➡️➡️➡️ **View output:**
> `storybook`: https://{{ env.NYM_CI_WWW_LOCATION }}.{{ env.NYM_CI_WWW_BASE }}
> `example`: https://{{ env.NYM_CI_WWW_LOCATION }}-example.{{ env.NYM_CI_WWW_BASE }}
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
Commit message by `{{ env.GITHUB_ACTOR }}` at {{ timestamp }}:
```
{{ env.GIT_COMMIT_MESSAGE }}
```
+15 -12
View File
@@ -19,27 +19,30 @@ jobs:
override: true
components: rustfmt, clippy
- uses: actions-rs/cargo@v1
with:
command: build
args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown
# token credentials (non-coconut) don't work for wasm right now
# - uses: actions-rs/cargo@v1
# with:
# command: build
# args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown
- uses: actions-rs/cargo@v1
with:
command: build
args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown --features=coconut
- uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path clients/webassembly/Cargo.toml
# for some reason this does not seem to work correctly, leave it for later, building is good enough for now
# - uses: actions-rs/cargo@v1
# with:
# command: test
# args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown
- uses: actions-rs/cargo@v1
with:
command: fmt
args: --manifest-path clients/webassembly/Cargo.toml -- --check
- uses: actions-rs/cargo@v1
with:
command: clippy
args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown -- -D warnings
# for some reason this does not seem to work correctly, leave it for later, building is good enough for now
# - uses: actions-rs/cargo@v1
# with:
# command: clippy
# args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown -- -D warnings
+1 -3
View File
@@ -35,6 +35,4 @@ contracts/mixnet/Justfile
contracts/mixnet/Makefile
validator-config
*.patch
validator-api-config.toml
dist
storybook-static
validator-api-config.toml
-6
View File
@@ -1,6 +0,0 @@
{
"mainnet":[{
"nymd_url":"https://rpc.nyx.nodes.guru/",
"api_url":"https://api.nyx.nodes.guru/"
}]
}
Generated
+2592 -1303
View File
File diff suppressed because it is too large Load Diff
+5 -10
View File
@@ -11,13 +11,13 @@ panic = "abort"
[workspace]
resolver = "2"
members = [
"clients/client-core",
"clients/native",
"clients/native/websocket-requests",
"clients/socks5",
# "clients/tauri-client/src-tauri",
"clients/tauri-client/src-tauri",
"clients/webassembly",
"common/client-libs/gateway-client",
"common/client-libs/mixnet-client",
"common/client-libs/validator-client",
@@ -26,16 +26,11 @@ members = [
"common/credentials",
"common/crypto",
"common/bandwidth-claim-contract",
"common/cosmwasm-smart-contracts/contracts-common",
"common/cosmwasm-smart-contracts/mixnet-contract",
"common/cosmwasm-smart-contracts/vesting-contract",
"common/mixnet-contract",
"common/mixnode-common",
"common/network-defaults",
"common/nonexhaustive-delayqueue",
"common/nymcoconut",
"common/nym_offline_compact_ecash",
"common/nym_offline_divisible_ecash",
"common/nym_online_divisible_ecash",
"common/nymsphinx",
"common/nymsphinx/acknowledgements",
"common/nymsphinx/addressing",
@@ -57,12 +52,12 @@ members = [
"mixnode",
"service-providers/network-requester",
"validator-api",
"validator-api/validator-api-requests",
]
default-members = [
"clients/native",
"clients/socks5",
# "clients/webassembly",
"gateway",
"service-providers/network-requester",
"mixnode",
@@ -70,4 +65,4 @@ default-members = [
"explorer-api",
]
exclude = ["explorer", "contracts", "tokenomics-py", "clients/webassembly"]
exclude = ["explorer", "contracts", "tokenomics-py"]
+9 -20
View File
@@ -1,10 +1,8 @@
test: build clippy-all cargo-test wasm fmt
no-clippy: build cargo-test wasm fmt
happy: fmt clippy-happy test
all: clippy-all test fmt
happy: clippy-happy test fmt
clippy-all: clippy-all-main clippy-all-contracts clippy-all-wallet
clippy-happy: clippy-happy-main clippy-happy-contracts clippy-happy-wallet
cargo-test: test-main test-contracts test-wallet
build: build-contracts build-wallet build-main
test: test-main test-contracts test-wallet
fmt: fmt-main fmt-contracts fmt-wallet
clippy-happy-main:
@@ -13,20 +11,20 @@ clippy-happy-main:
clippy-happy-contracts:
cargo clippy --manifest-path contracts/Cargo.toml --target wasm32-unknown-unknown
clippy-happy-wallet:
clippy-happy-wallet:
cargo clippy --manifest-path nym-wallet/Cargo.toml
clippy-all-main:
cargo clippy --workspace --all-features -- -D warnings
cargo clippy --all-features -- -D warnings
clippy-all-contracts:
cargo clippy --workspace --manifest-path contracts/Cargo.toml --all-features --target wasm32-unknown-unknown -- -D warnings
cargo clippy --manifest-path contracts/Cargo.toml --all-features --target wasm32-unknown-unknown -- -D warnings
clippy-all-wallet:
cargo clippy --workspace --manifest-path nym-wallet/Cargo.toml --all-features -- -D warnings
clippy-all-wallet:
cargo clippy --manifest-path nym-wallet/Cargo.toml --all-features -- -D warnings
test-main:
cargo test --all-features --workspace
cargo test --all-features
test-contracts:
cargo test --manifest-path contracts/Cargo.toml --all-features
@@ -34,15 +32,6 @@ test-contracts:
test-wallet:
cargo test --manifest-path nym-wallet/Cargo.toml --all-features
build-main:
cargo build --workspace
build-contracts:
cargo build --manifest-path contracts/Cargo.toml --workspace
build-wallet:
cargo build --manifest-path nym-wallet/Cargo.toml --workspace
fmt-main:
cargo fmt --all
+1 -4
View File
@@ -21,15 +21,12 @@ The platform is composed of multiple Rust crates. Top-level executable binary cr
### Building
Platform build instructions are available on [our docs site](https://nymtech.net/docs/stable/run-nym-nodes/build-nym).
Wallet build instructions are also available on [our docs site](https://nymtech.net/docs/stable/nym-apps/wallet#for-developers).
Platform build instructions are available on [our docs site](https://nymtech.net/docs/0.11.0/overview/index/).
### Developing
There's a `.env.sample-dev` file provided which you can rename to `.env` if you want convenient logging, backtrace, or other environment variables pre-set. The `.env` file is ignored so you don't need to worry about checking it in.
For Typescript components, please see [ts-packages](./ts-packages).
### Developer chat
You can chat to us in [Keybase](https://keybase.io). Download their chat app, then click **Teams -> Join a team**. Type **nymtech.friends** into the team name and hit **continue**. For general chat, hang out in the **#general** channel. Our development takes places in the **#dev** channel. Node operators should be in the **#node-operators** channel.
-12
View File
@@ -1,12 +0,0 @@
# Shared assets
This directory contains asset files shared by many projects in this repo.
You will find:
- favicons
- logos
- shared fonts
- shared icon SVGs
See [ts-packages/react-webpack-with-theme-example](../ts-packages/react-webpack-with-theme-example) for examples of usage.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 545 KiB

-10
View File
@@ -1,10 +0,0 @@
<svg width="64" height="64" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M40 78.5C61.263 78.5 78.5 61.263 78.5 40C78.5 18.737 61.263 1.5 40 1.5C18.737 1.5 1.5 18.737 1.5 40C1.5 61.263 18.737 78.5 40 78.5Z" fill="#070B15" stroke="url(#paint0_linear_0_1)" stroke-width="3"/>
<path d="M31.4894 27.56L41.8623 56H48.5106H56V24H48.5106V52.4L38.1777 24H31.4894H24V56H31.4894V27.56Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_0_1" x1="0.839161" y1="80" x2="80" y2="80" gradientUnits="userSpaceOnUse">
<stop offset="0.09375" stop-color="#FB6E4E"/>
<stop offset="1" stop-color="#F51473"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 672 B

Binary file not shown.
-6
View File
@@ -1,6 +0,0 @@
@font-face {
font-family: 'Open Sans';
src: url('./OpenSans-VariableFont_wdth,wght.ttf') format('truetype-variations'),
url('./OpenSans-Italic-VariableFont_wdth,wght.ttf') format('truetype-variations');
font-weight: 100 1000;
}
-10
View File
@@ -1,10 +0,0 @@
<svg width="64" height="64" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M40 78.5C61.263 78.5 78.5 61.263 78.5 40C78.5 18.737 61.263 1.5 40 1.5C18.737 1.5 1.5 18.737 1.5 40C1.5 61.263 18.737 78.5 40 78.5Z" fill="#070B15" stroke="url(#paint0_linear_0_1)" stroke-width="3"/>
<path d="M31.4894 27.56L41.8623 56H48.5106H56V24H48.5106V52.4L38.1777 24H31.4894H24V56H31.4894V27.56Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_0_1" x1="0.839161" y1="80" x2="80" y2="80" gradientUnits="userSpaceOnUse">
<stop offset="0.09375" stop-color="#FB6E4E"/>
<stop offset="1" stop-color="#F51473"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 714 B

-13
View File
@@ -1,13 +0,0 @@
<svg width="300" height="300" viewBox="0 0 296 296" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M148 296C229.738 296 296 229.738 296 148C296 66.2619 229.738 0 148 0C66.2619 0 0 66.2619 0 148C0 229.738 66.2619 296 148 296Z" fill="url(#paint0_linear_113_1244)"/>
<path d="M148 285.875C224.147 285.875 285.875 224.146 285.875 148C285.875 71.8536 224.147 10.1248 148 10.1248C71.8538 10.1248 10.125 71.8536 10.125 148C10.125 224.146 71.8538 285.875 148 285.875Z" fill="#121725"/>
<path d="M88.8829 120.143H88.7169V120.281V168.637L68.3289 120.226L68.3012 120.143H68.1905H56.6272H43.653H43.5146V120.281V175.719V175.857H43.653H56.6272H56.7655V175.719V127.28L77.2365 175.774L77.2642 175.857H77.3748H88.8829H101.829H101.968V175.719V120.281V120.143H101.829H88.8829Z" fill="white"/>
<path d="M252.347 120.143H227.616H227.477L227.45 120.253L214.78 168.858L202.082 120.253L202.054 120.143H201.944H177.157H176.991V120.281V175.719V175.857H177.157H190.104H190.242V175.719V127.667L202.774 175.747L202.801 175.857H202.94H226.564H226.675L226.703 175.747L239.234 127.667V175.719V175.857H239.373H252.347H252.485V175.719V120.281V120.143H252.347Z" fill="white"/>
<path d="M155.663 120.143H155.58L155.552 120.198L139.812 147.557L123.988 120.198L123.96 120.143H123.877H108.911H108.635L108.773 120.364L133.145 162.579V175.719V175.857H133.283H146.257H146.396V175.719V162.579L170.767 120.364L170.905 120.143H170.629H155.663Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_113_1244" x1="0" y1="148" x2="296" y2="148" gradientUnits="userSpaceOnUse">
<stop offset="0.09375" stop-color="#FB6E4E"/>
<stop offset="1" stop-color="#FC1D60"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

-5
View File
@@ -1,5 +0,0 @@
<svg width="210" height="56" viewBox="0 0 210 56" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M45.8829 0.142822H45.7169V0.28114V48.637L25.3289 0.225818L25.3012 0.142822H25.1905H13.6272H0.652966H0.514648V0.28114V55.7189V55.8572H0.652966H13.6272H13.7655V55.7189V7.28002L34.2365 55.7742L34.2642 55.8572H34.3748H45.8829H58.8294H58.9677V55.7189V0.28114V0.142822H58.8294H45.8829Z"/>
<path d="M209.347 0.142822H184.616H184.477L184.45 0.253483L171.78 48.8583L159.082 0.253483L159.054 0.142822H158.944H134.157H133.991V0.28114V55.7189V55.8572H134.157H147.104H147.242V55.7189V7.66731L159.774 55.7466L159.801 55.8572H159.94H183.564H183.675L183.703 55.7466L196.234 7.66731V55.7189V55.8572H196.373H209.347H209.485V55.7189V0.28114V0.142822H209.347Z"/>
<path d="M112.663 0.142822H112.58L112.552 0.198153L96.8116 27.5574L80.988 0.198153L80.9604 0.142822H80.8774H65.9114H65.6348L65.7731 0.364136L90.1447 42.5787V55.7189V55.8572H90.283H103.257H103.396V55.7189V42.5787L127.767 0.364136L127.905 0.142822H127.629H112.663Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

-5
View File
@@ -1,5 +0,0 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M170.7 29.3001C131.7 -9.7999 68.3001 -9.7999 29.3001 29.3001C-9.7999 68.4001 -9.7999 131.7 29.3001 170.7C68.4001 209.8 131.7 209.8 170.7 170.7C209.8 131.7 209.8 68.3001 170.7 29.3001ZM162.1 162.1C127.8 196.4 72.1001 196.4 37.8001 162.1C3.5001 127.8 3.5001 72.1001 37.8001 37.8001C72.1001 3.5001 127.8 3.5001 162.1 37.8001C196.5 72.2001 196.5 127.8 162.1 162.1Z" fill="white"/>
<path d="M162.1 37.9C127.8 3.60005 72.1002 3.60005 37.8002 37.9C3.50019 72.2 3.50019 127.9 37.8002 162.2C72.1002 196.5 127.8 196.5 162.1 162.2C196.5 127.8 196.5 72.2 162.1 37.9ZM63.0002 170.7C56.8002 167.4 51.1002 163.2 46.1002 158.4V41.7C51.3002 36.7 57.2002 32.5 63.6002 29.1L137 140.9V29.3C143.2 32.6 148.9 36.8 153.9 41.6V158.3C148.7 163.3 142.8 167.5 136.4 170.9L63.0002 59.1V170.7Z" fill="#070B15"/>
<path d="M154 158.3V41.7C148.9 36.9 143.2 32.7 137.1 29.4V140.9L63.5 29C57.1 32.4 51.2 36.6 46 41.6V158.3C51.1 163.1 56.8 167.3 62.9 170.6V59.1L136.5 171C142.9 167.6 148.8 163.3 154 158.3Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

-5
View File
@@ -1,5 +0,0 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M170.7 29.3001C131.7 -9.7999 68.3001 -9.7999 29.3001 29.3001C-9.7999 68.4001 -9.7999 131.7 29.3001 170.7C68.4001 209.8 131.7 209.8 170.7 170.7C209.8 131.7 209.8 68.3001 170.7 29.3001ZM162.1 162.1C127.8 196.4 72.1001 196.4 37.8001 162.1C3.5001 127.8 3.5001 72.1001 37.8001 37.8001C72.1001 3.5001 127.8 3.5001 162.1 37.8001C196.5 72.2001 196.5 127.8 162.1 162.1Z" fill="#141521"/>
<path d="M162.1 37.9C127.8 3.60005 72.1002 3.60005 37.8002 37.9C3.50019 72.2 3.50019 127.9 37.8002 162.2C72.1002 196.5 127.8 196.5 162.1 162.2C196.5 127.8 196.5 72.2 162.1 37.9ZM63.0002 170.7C56.8002 167.4 51.1002 163.2 46.1002 158.4V41.7C51.3002 36.7 57.2002 32.5 63.6002 29.1L137 140.9V29.3C143.2 32.6 148.9 36.8 153.9 41.6V158.3C148.7 163.3 142.8 167.5 136.4 170.9L63.0002 59.1V170.7Z" fill="white"/>
<path d="M154 158.3V41.7C148.9 36.9 143.2 32.7 137.1 29.4V140.9L63.5 29C57.1 32.4 51.2 36.6 46 41.6V158.3C51.1 163.1 56.8 167.3 62.9 170.6V59.1L136.5 171C142.9 167.6 148.8 163.3 154 158.3Z" fill="#141521"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

+1 -1
View File
@@ -2,7 +2,7 @@
name = "client-core"
version = "0.12.0"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
edition = "2021"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -79,9 +79,9 @@ impl KeyManager {
))?;
let gateway_shared_key: SharedKeys =
pemstore::load_key(client_pathfinder.gateway_shared_key())?;
pemstore::load_key(&client_pathfinder.gateway_shared_key().to_owned())?;
let ack_key: AckKey = pemstore::load_key(client_pathfinder.ack_key())?;
let ack_key: AckKey = pemstore::load_key(&client_pathfinder.ack_key().to_owned())?;
// TODO: ack key is never stored so it is generated now. But perhaps it should be stored
// after all for consistency sake?
@@ -1,10 +1,10 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crypto::generic_array::typenum::Unsigned;
use log::*;
use nymsphinx::anonymous_replies::{
encryption_key::EncryptionKeyDigest, SurbEncryptionKey, SurbEncryptionKeySize,
encryption_key::EncryptionKeyDigest, encryption_key::Unsigned, SurbEncryptionKey,
SurbEncryptionKeySize,
};
use std::path::Path;
@@ -43,7 +43,7 @@ impl ReplyKeyStorage {
// if this fails it means we have some database corruption and we
// absolutely can't continue
if key_bytes_ref.len() != SurbEncryptionKeySize::USIZE {
if key_bytes_ref.len() != SurbEncryptionKeySize::to_usize() {
error!("REPLY KEY STORAGE DATA CORRUPTION - ENCRYPTION KEY HAS INVALID LENGTH");
panic!("REPLY KEY STORAGE DATA CORRUPTION - ENCRYPTION KEY HAS INVALID LENGTH");
}
@@ -59,7 +59,7 @@ impl ReplyKeyStorage {
) -> Result<(), ReplyKeyStorageError> {
let digest = encryption_key.compute_digest();
let insertion_result = match self.db.insert(digest, encryption_key.to_bytes()) {
let insertion_result = match self.db.insert(digest.to_vec(), encryption_key.to_bytes()) {
Err(e) => Err(ReplyKeyStorageError::DbWriteError(e)),
Ok(existing_key) => {
if existing_key.is_some() {
@@ -79,7 +79,7 @@ impl ReplyKeyStorage {
&self,
key_digest: EncryptionKeyDigest,
) -> Result<Option<SurbEncryptionKey>, ReplyKeyStorageError> {
let removal_result = match self.db.remove(key_digest) {
let removal_result = match self.db.remove(&key_digest.to_vec()) {
Err(e) => Err(ReplyKeyStorageError::DbReadError(e)),
Ok(existing_key) => {
Ok(existing_key.map(|existing_key| self.read_encryption_key(existing_key)))
+14 -30
View File
@@ -121,16 +121,12 @@ impl<T: NymConfig> Config<T> {
self.client.testnet_mode = testnet_mode;
}
pub fn with_gateway_endpoint<S: Into<String>>(&mut self, id: S, owner: S, listener: S) {
self.client.gateway_endpoint = GatewayEndpoint {
gateway_id: id.into(),
gateway_owner: owner.into(),
gateway_listener: listener.into(),
};
pub fn with_gateway_id<S: Into<String>>(&mut self, id: S) {
self.client.gateway_id = id.into();
}
pub fn with_gateway_id<S: Into<String>>(&mut self, id: S) {
self.client.gateway_endpoint.gateway_id = id.into();
pub fn with_gateway_listener<S: Into<String>>(&mut self, gateway_listener: S) {
self.client.gateway_listener = gateway_listener.into();
}
#[cfg(not(feature = "coconut"))]
@@ -202,15 +198,11 @@ impl<T: NymConfig> Config<T> {
}
pub fn get_gateway_id(&self) -> String {
self.client.gateway_endpoint.gateway_id.clone()
}
pub fn get_gateway_owner(&self) -> String {
self.client.gateway_endpoint.gateway_owner.clone()
self.client.gateway_id.clone()
}
pub fn get_gateway_listener(&self) -> String {
self.client.gateway_endpoint.gateway_listener.clone()
self.client.gateway_listener.clone()
}
#[cfg(not(feature = "coconut"))]
@@ -280,19 +272,6 @@ impl<T: NymConfig> Default for Config<T> {
}
}
#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
struct GatewayEndpoint {
/// gateway_id specifies ID of the gateway to which the client should send messages.
/// If initially omitted, a random gateway will be chosen from the available topology.
gateway_id: String,
/// Address of the gateway owner to which the client should send messages.
gateway_owner: String,
/// Address of the gateway listener to which all client requests should be sent.
gateway_listener: String,
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct Client<T> {
/// Version of the client for which this configuration was created.
@@ -334,8 +313,12 @@ pub struct Client<T> {
/// sent but not received back.
reply_encryption_key_store_path: PathBuf,
/// Information regarding how the client should send data to gateway.
gateway_endpoint: GatewayEndpoint,
/// gateway_id specifies ID of the gateway to which the client should send messages.
/// If initially omitted, a random gateway will be chosen from the available topology.
gateway_id: String,
/// Address of the gateway listener to which all client requests should be sent.
gateway_listener: String,
/// Path to directory containing public/private keys used for bandwidth token purchase.
/// Those are saved in case of emergency, to be able to reclaim bandwidth tokens.
@@ -374,7 +357,8 @@ impl<T: NymConfig> Default for Client<T> {
gateway_shared_key_file: Default::default(),
ack_key_file: Default::default(),
reply_encryption_key_store_path: Default::default(),
gateway_endpoint: Default::default(),
gateway_id: "".to_string(),
gateway_listener: "".to_string(),
#[cfg(not(feature = "coconut"))]
backup_bandwidth_token_keys_dir: Default::default(),
#[cfg(not(feature = "coconut"))]
+1 -1
View File
@@ -2,7 +2,7 @@
name = "nym-client"
version = "0.12.1"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
edition = "2018"
rust-version = "1.56"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -2441,9 +2441,9 @@
}
},
"node_modules/follow-redirects": {
"version": "1.14.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
"dev": true,
"funding": [
{
@@ -3806,9 +3806,9 @@
"optional": true
},
"node_modules/nanoid": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
"version": "3.1.23",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
"integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==",
"dev": true,
"peer": true,
"bin": {
@@ -3943,9 +3943,9 @@
}
},
"node_modules/nth-check": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
"integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz",
"integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==",
"dependencies": {
"boolbase": "^1.0.0"
},
@@ -6085,9 +6085,9 @@
}
},
"node_modules/url-parse": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
"dev": true,
"dependencies": {
"querystringify": "^2.1.1",
@@ -8853,9 +8853,9 @@
}
},
"follow-redirects": {
"version": "1.14.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
"dev": true
},
"for-in": {
@@ -9871,9 +9871,9 @@
"optional": true
},
"nanoid": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
"version": "3.1.23",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
"integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==",
"dev": true,
"peer": true
},
@@ -9984,9 +9984,9 @@
}
},
"nth-check": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
"integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz",
"integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==",
"requires": {
"boolbase": "^1.0.0"
}
@@ -11733,9 +11733,9 @@
}
},
"url-parse": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
"dev": true,
"requires": {
"querystringify": "^2.1.1",
@@ -35,7 +35,7 @@ async fn send_file_with_reply() {
let (mut ws_stream, _) = connect_async(uri).await.unwrap();
let recipient = get_self_address(&mut ws_stream).await;
println!("our full address is: {}", recipient);
println!("our full address is: {}", recipient.to_string());
let read_data = std::fs::read("examples/dummy_file").unwrap();
@@ -83,7 +83,7 @@ async fn send_file_without_reply() {
let (mut ws_stream, _) = connect_async(uri).await.unwrap();
let recipient = get_self_address(&mut ws_stream).await;
println!("our full address is: {}", recipient);
println!("our full address is: {}", recipient.to_string());
let read_data = std::fs::read("examples/dummy_file").unwrap();
@@ -36,7 +36,7 @@ async fn send_text_with_reply() {
let (mut ws_stream, _) = connect_async(uri).await.unwrap();
let recipient = get_self_address(&mut ws_stream).await;
println!("our full address is: {}", recipient);
println!("our full address is: {}", recipient.to_string());
let send_request = json!({
"type" : "send",
@@ -76,7 +76,7 @@ async fn send_text_without_reply() {
let (mut ws_stream, _) = connect_async(uri).await.unwrap();
let recipient = get_self_address(&mut ws_stream).await;
println!("our full address is: {}", recipient);
println!("our full address is: {}", recipient.to_string());
let send_request = json!({
"type" : "send",
+6 -11
View File
@@ -59,6 +59,12 @@ eth_endpoint = '{{ client.eth_endpoint }}'
##### additional client config options #####
# ID of the gateway from which the client should be fetching messages.
gateway_id = '{{ client.gateway_id }}'
# Address of the gateway listener to which all client requests should be sent.
gateway_listener = '{{ client.gateway_listener }}'
# A gateway specific, optional, base58 stringified shared key used for
# communication with particular gateway.
gateway_shared_key_file = '{{ client.gateway_shared_key_file }}'
@@ -72,17 +78,6 @@ ack_key_file = '{{ client.ack_key_file }}'
# Absolute path to the home Nym Clients directory.
nym_root_directory = '{{ client.nym_root_directory }}'
[client.gateway_endpoint]
# ID of the gateway from which the client should be fetching messages.
gateway_id = '{{ client.gateway_endpoint.gateway_id }}'
# Address of the gateway owner to which the client should send messages.
gateway_owner = '{{ client.gateway_endpoint.gateway_owner }}'
# Address of the gateway listener to which all client requests should be sent.
gateway_listener = '{{ client.gateway_endpoint.gateway_listener }}'
##### socket config options #####
-5
View File
@@ -160,10 +160,6 @@ impl NymClient {
if gateway_id.is_empty() {
panic!("The identity of the gateway is unknown - did you run `nym-client` init?")
}
let gateway_owner = self.config.get_base().get_gateway_owner();
if gateway_owner.is_empty() {
panic!("The owner of the gateway is unknown - did you run `nym-client` init?")
}
let gateway_address = self.config.get_base().get_gateway_listener();
if gateway_address.is_empty() {
panic!("The address of the gateway is unknown - did you run `nym-client` init?")
@@ -189,7 +185,6 @@ impl NymClient {
gateway_address,
self.key_manager.identity_keypair(),
gateway_identity,
gateway_owner,
Some(self.key_manager.gateway_shared_key()),
mixnet_message_sender,
ack_sender,
+6 -6
View File
@@ -136,7 +136,6 @@ async fn register_with_gateway(
let mut gateway_client = GatewayClient::new_init(
gateway.clients_address(),
gateway.identity_key,
gateway.owner.clone(),
our_identity.clone(),
timeout,
);
@@ -256,14 +255,15 @@ pub async fn execute(matches: ArgMatches<'static>) {
chosen_gateway_id,
)
.await;
config
.get_base_mut()
.with_gateway_id(gateway_details.identity_key.to_base58_string());
let shared_keys =
register_with_gateway(&gateway_details, key_manager.identity_keypair()).await;
config.get_base_mut().with_gateway_endpoint(
gateway_details.identity_key.to_base58_string(),
gateway_details.owner.clone(),
gateway_details.clients_address(),
);
config
.get_base_mut()
.with_gateway_listener(gateway_details.clients_address());
key_manager.insert_gateway_shared_key(shared_keys);
let pathfinder = ClientKeyPathfinder::new_from_config(config.get_base());
+3 -3
View File
@@ -32,7 +32,7 @@ fn parse_validators(raw: &str) -> Vec<Url> {
.collect()
}
pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> Config {
pub(crate) fn override_config(mut config: Config, matches: &ArgMatches) -> Config {
if let Some(raw_validators) = matches.value_of("validators") {
config
.get_base_mut()
@@ -58,7 +58,7 @@ pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> C
#[cfg(not(feature = "coconut"))]
if let Some(eth_endpoint) = matches.value_of(ETH_ENDPOINT_ARG_NAME) {
config.get_base_mut().with_eth_endpoint(eth_endpoint);
} else if !cfg!(feature = "eth") {
} else {
config
.get_base_mut()
.with_eth_endpoint(DEFAULT_ETH_ENDPOINT);
@@ -66,7 +66,7 @@ pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> C
#[cfg(not(feature = "coconut"))]
if let Some(eth_private_key) = matches.value_of(ETH_PRIVATE_KEY_ARG_NAME) {
config.get_base_mut().with_eth_private_key(eth_private_key);
} else if !cfg!(feature = "eth") {
} else {
config
.get_base_mut()
.with_eth_private_key(DEFAULT_ETH_PRIVATE_KEY);
+3 -3
View File
@@ -95,7 +95,7 @@ fn parse_package_version() -> Version {
fn minor_0_12_upgrade(
mut config: Config,
_matches: &ArgMatches<'_>,
_matches: &ArgMatches,
config_version: &Version,
package_version: &Version,
) -> Config {
@@ -131,7 +131,7 @@ fn minor_0_12_upgrade(
config
}
fn do_upgrade(mut config: Config, matches: &ArgMatches<'_>, package_version: Version) {
fn do_upgrade(mut config: Config, matches: &ArgMatches, package_version: Version) {
loop {
let config_version = parse_config_version(&config);
@@ -151,7 +151,7 @@ fn do_upgrade(mut config: Config, matches: &ArgMatches<'_>, package_version: Ver
}
}
pub fn execute(matches: &ArgMatches<'_>) {
pub fn execute(matches: &ArgMatches) {
let package_version = parse_package_version();
let id = matches.value_of("id").unwrap();
+1 -1
View File
@@ -2,7 +2,7 @@
name = "websocket-requests"
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+1 -1
View File
@@ -2,7 +2,7 @@
name = "nym-socks5-client"
version = "0.12.1"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
edition = "2021"
edition = "2018"
rust-version = "1.56"
[lib]
+7 -11
View File
@@ -59,6 +59,12 @@ eth_endpoint = '{{ client.eth_endpoint }}'
##### additional client config options #####
# ID of the gateway from which the client should be fetching messages.
gateway_id = '{{ client.gateway_id }}'
# Address of the gateway listener to which all client requests should be sent.
gateway_listener = '{{ client.gateway_listener }}'
# A gateway specific, optional, base58 stringified shared key used for
# communication with particular gateway.
gateway_shared_key_file = '{{ client.gateway_shared_key_file }}'
@@ -66,22 +72,12 @@ gateway_shared_key_file = '{{ client.gateway_shared_key_file }}'
# Path to file containing key used for encrypting and decrypting the content of an
# acknowledgement so that nobody besides the client knows which packet it refers to.
ack_key_file = '{{ client.ack_key_file }}'
##### advanced configuration options #####
# Absolute path to the home Nym Clients directory.
nym_root_directory = '{{ client.nym_root_directory }}'
[client.gateway_endpoint]
# ID of the gateway from which the client should be fetching messages.
gateway_id = '{{ client.gateway_endpoint.gateway_id }}'
# Address of the gateway owner to which the client should send messages.
gateway_owner = '{{ client.gateway_endpoint.gateway_owner }}'
# Address of the gateway listener to which all client requests should be sent.
gateway_listener = '{{ client.gateway_endpoint.gateway_listener }}'
##### socket config options #####
-5
View File
@@ -148,10 +148,6 @@ impl NymClient {
if gateway_id.is_empty() {
panic!("The identity of the gateway is unknown - did you run `nym-client` init?")
}
let gateway_owner = self.config.get_base().get_gateway_owner();
if gateway_owner.is_empty() {
panic!("The owner of the gateway is unknown - did you run `nym-client` init?")
}
let gateway_address = self.config.get_base().get_gateway_listener();
if gateway_address.is_empty() {
panic!("The address of the gateway is unknown - did you run `nym-client` init?")
@@ -177,7 +173,6 @@ impl NymClient {
gateway_address,
self.key_manager.identity_keypair(),
gateway_identity,
gateway_owner,
Some(self.key_manager.gateway_shared_key()),
mixnet_message_sender,
ack_sender,
+6 -6
View File
@@ -136,7 +136,6 @@ async fn register_with_gateway(
let mut gateway_client = GatewayClient::new_init(
gateway.clients_address(),
gateway.identity_key,
gateway.owner.clone(),
our_identity.clone(),
timeout,
);
@@ -257,14 +256,15 @@ pub async fn execute(matches: ArgMatches<'static>) {
chosen_gateway_id,
)
.await;
config
.get_base_mut()
.with_gateway_id(gateway_details.identity_key.to_base58_string());
let shared_keys =
register_with_gateway(&gateway_details, key_manager.identity_keypair()).await;
config.get_base_mut().with_gateway_endpoint(
gateway_details.identity_key.to_base58_string(),
gateway_details.owner.clone(),
gateway_details.clients_address(),
);
config
.get_base_mut()
.with_gateway_listener(gateway_details.clients_address());
key_manager.insert_gateway_shared_key(shared_keys);
let pathfinder = ClientKeyPathfinder::new_from_config(config.get_base());
+3 -3
View File
@@ -32,7 +32,7 @@ fn parse_validators(raw: &str) -> Vec<Url> {
.collect()
}
pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> Config {
pub(crate) fn override_config(mut config: Config, matches: &ArgMatches) -> Config {
if let Some(raw_validators) = matches.value_of("validators") {
config
.get_base_mut()
@@ -54,7 +54,7 @@ pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> C
#[cfg(not(feature = "coconut"))]
if let Some(eth_endpoint) = matches.value_of(ETH_ENDPOINT_ARG_NAME) {
config.get_base_mut().with_eth_endpoint(eth_endpoint);
} else if !cfg!(feature = "eth") {
} else {
config
.get_base_mut()
.with_eth_endpoint(DEFAULT_ETH_ENDPOINT);
@@ -62,7 +62,7 @@ pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> C
#[cfg(not(feature = "coconut"))]
if let Some(eth_private_key) = matches.value_of(ETH_PRIVATE_KEY_ARG_NAME) {
config.get_base_mut().with_eth_private_key(eth_private_key);
} else if !cfg!(feature = "eth") {
} else {
config
.get_base_mut()
.with_eth_private_key(DEFAULT_ETH_PRIVATE_KEY);
+3 -3
View File
@@ -95,7 +95,7 @@ fn parse_package_version() -> Version {
fn minor_0_12_upgrade(
mut config: Config,
_matches: &ArgMatches<'_>,
_matches: &ArgMatches,
config_version: &Version,
package_version: &Version,
) -> Config {
@@ -131,7 +131,7 @@ fn minor_0_12_upgrade(
config
}
fn do_upgrade(mut config: Config, matches: &ArgMatches<'_>, package_version: Version) {
fn do_upgrade(mut config: Config, matches: &ArgMatches, package_version: Version) {
loop {
let config_version = parse_config_version(&config);
@@ -151,7 +151,7 @@ fn do_upgrade(mut config: Config, matches: &ArgMatches<'_>, package_version: Ver
}
}
pub fn execute(matches: &ArgMatches<'_>) {
pub fn execute(matches: &ArgMatches) {
let package_version = parse_package_version();
let id = matches.value_of("id").unwrap();
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -26,7 +26,7 @@
"@rollup/plugin-node-resolve": "^8.0.0",
"@rollup/plugin-replace": "^2.4.0",
"@rollup/plugin-url": "^5.0.0",
"@tauri-apps/cli": "^1.0.0-rc.5",
"@tauri-apps/cli": "^1.0.0-beta.5",
"rollup": "^2.3.4",
"rollup-plugin-svelte": "^7.0.0",
"rollup-plugin-terser": "^7.0.0",
+3 -7
View File
@@ -6,25 +6,21 @@ authors = ["you"]
license = ""
repository = ""
default-run = "app"
edition = "2021"
edition = "2018"
build = "src/build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies]
tauri-build = { version = "=1.0.0-rc.2" }
tauri-build = { version = "1.0.0-beta.2" }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "=1.0.0-rc.2", features = [] }
tauri = { version = "1.0.0-beta.4", features = [] }
tokio = "1.4"
url = "2.2"
tauri-codegen = "=1.0.0-rc.1"
tauri-macros = "=1.0.0-rc.1"
core-graphics = "=0.22.2"
coconut-interface = { path = "../../../common/coconut-interface" }
credentials = { path = "../../../common/credentials" }
validator-client = {path = "../../../common/client-libs/validator-client"}
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
NYMD_URL=https://sandbox-validator.nymtech.net
VALIDATOR_API=https://sandbox-validator.nymtech.net/api
MIXNET_CONTRACT=nymt1ghd753shjuwexxywmgs4xz7x2q732vcnstz02j
VESTING_CONTRACT=nymt1nc5tatafv6eyq7llkr2gv50ff9e22mnfp9pc5s
CURRENCY_PREFIX=nymt
CHAIN_ID=nym-sandbox
+6 -12
View File
@@ -3,26 +3,20 @@ Nym Validator Client
A TypeScript client for interacting with CosmWasm smart contracts in Nym validators.
Running examples
-----------------
With the code checked out, `cd examples`. This folder contains runnable example code that will set up a blockchain and allow you to interact with it through the client.
Running tests
-------------
The tests will be separated into three categories: unit, integration and mock.
Currently the command to run all tests:
```
npm test
```
You can also trigger test execution with a test watcher. I don't have the centuries of life left to me that are needed to fight through the arcana of wiring up a working TypeScript mocha triggered execution setup, so for now my Cargo-based hack is:
The tests require `.env.example` being renamed to `.env`. The variables and their values for these tests are currently pointing to the `nym-sandbox` environment.
```
cargo watch -s "cd clients/validator && npm test"
```
It's ugly but works fine if you have Cargo installed. TypeScript setup help happily accepted here.
`Tests are still in development` - the test libary is `jest` and the test script will execute currently with: `--coverage --verbosity false`
Generating Documentation
------------------------
+6
View File
@@ -0,0 +1,6 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
setupFiles: ["dotenv/config"]
};
+7 -14
View File
@@ -6,9 +6,7 @@
"main": "./dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"test": "ts-mocha tests/**/*.test.ts",
"coverage": "nyc npm test",
"test": "jest --coverage --verbose false",
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"docs": "typedoc --out docs src/index.ts"
@@ -21,27 +19,21 @@
],
"license": "Apache-2.0",
"devDependencies": {
"@types/chai": "^4.2.15",
"@types/expect": "^24.3.0",
"@types/mocha": "^8.2.1",
"@types/jest": "27.4.0",
"@typescript-eslint/eslint-plugin": "^5.7.0",
"@typescript-eslint/parser": "^5.7.0",
"chai": "^4.2.0",
"eslint": "^7.18.0",
"eslint-config-airbnb": "^19.0.2",
"eslint-config-airbnb-typescript": "^16.1.0",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-root-import": "^1.0.4",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-mocha": "^10.0.3",
"eslint-plugin-prettier": "^4.0.0",
"mocha": "^8.2.1",
"moq.ts": "^7.2.0",
"nyc": "^15.1.0",
"jest": "^27.4.5",
"prettier": "^2.5.1",
"ts-mocha": "^8.0.0",
"ts-jest": "^27.1.2",
"typedoc": "^0.20.27",
"typescript": "^4.1.3"
"typescript": "^4.5.4"
},
"dependencies": {
"@cosmjs/cosmwasm-stargate": "^0.27.0-rc2",
@@ -51,6 +43,7 @@
"@cosmjs/stargate": "^0.27.0-rc2",
"@cosmjs/tendermint-rpc": "^0.27.0-rc2",
"axios": "^0.21.1",
"cosmjs-types": "^0.4.0"
"cosmjs-types": "^0.4.0",
"dotenv": "^10.0.0"
}
}
+5 -21
View File
@@ -64,23 +64,15 @@ export default class ValidatorClient implements INymClient {
readonly vestingContract: string;
readonly mainnetDenom = "unym";
readonly mainnetPrefix = "n";
private constructor(
client: SigningClient | QueryClient,
prefix: string,
mixnetContract: string,
vestingContract: string
vestingContract: string,
) {
this.client = client;
this.prefix = prefix;
if (prefix == this.mainnetPrefix) {
this.denom = this.mainnetDenom;
} else {
this.denom = `u${prefix}`;
}
this.denom = `u${prefix}`;
this.mixnetContract = mixnetContract;
this.vestingContract = vestingContract;
@@ -188,8 +180,8 @@ export default class ValidatorClient implements INymClient {
return this.client.getSybilResistancePercent(this.mixnetContract);
}
public async getIntervalRewardPercent(): Promise<number> {
return this.client.getIntervalRewardPercent(this.mixnetContract);
public async getEpochRewardPercent(): Promise<number> {
return this.client.getEpochRewardPercent(this.mixnetContract);
}
public async getAllNymdMixnodes(): Promise<MixNodeBond[]> {
@@ -441,14 +433,6 @@ export default class ValidatorClient implements INymClient {
return (this.client as ISigningClient).undelegateFromMixNode(this.mixnetContract, mixIdentity, fee, memo);
}
public async updateMixnodeConfig(
mixIdentity: string,
fee: StdFee | 'auto' | number,
profitPercentage: number,
): Promise<ExecuteResult> {
return (this.client as ISigningClient).updateMixnodeConfig(this.mixnetContract, mixIdentity, profitPercentage, fee);
}
public async updateContractStateParams(
newParams: ContractStateParams,
fee?: StdFee | 'auto' | number,
@@ -457,4 +441,4 @@ export default class ValidatorClient implements INymClient {
this.assertSigning();
return (this.client as ISigningClient).updateContractStateParams(this.mixnetContract, newParams, fee, memo);
}
}
}
+9 -2
View File
@@ -18,6 +18,7 @@ import {
PagedGatewayResponse,
PagedMixDelegationsResponse,
PagedMixnodeResponse,
RewardingIntervalResponse,
RewardingStatus,
} from './types';
@@ -78,6 +79,12 @@ export default class NymdQuerier implements INymdQuery {
});
}
getCurrentRewardingInterval(mixnetContractAddress: string): Promise<RewardingIntervalResponse> {
return this.client.queryContractSmart(mixnetContractAddress, {
current_rewarding_interval: {},
});
}
getAllNetworkDelegationsPaged(
mixnetContractAddress: string,
limit?: number,
@@ -148,9 +155,9 @@ export default class NymdQuerier implements INymdQuery {
});
}
getIntervalRewardPercent(mixnetContractAddress: string): Promise<number> {
getEpochRewardPercent(mixnetContractAddress: string): Promise<number> {
return this.client.queryContractSmart(mixnetContractAddress, {
get_interval_reward_percent: {},
get_epoch_reward_percent: {},
});
}
+9 -3
View File
@@ -28,6 +28,7 @@ import {
PagedGatewayResponse,
PagedMixDelegationsResponse,
PagedMixnodeResponse,
RewardingIntervalResponse,
RewardingStatus,
} from './types';
import ValidatorApiQuerier, { IValidatorApiQuery } from './validator-api-querier';
@@ -62,6 +63,7 @@ export interface INymdQuery {
ownsMixNode(mixnetContractAddress: string, address: string): Promise<MixOwnershipResponse>;
ownsGateway(mixnetContractAddress: string, address: string): Promise<GatewayOwnershipResponse>;
getStateParams(mixnetContractAddress: string): Promise<ContractStateParams>;
getCurrentRewardingInterval(mixnetContractAddress: string): Promise<RewardingIntervalResponse>;
getAllNetworkDelegationsPaged(
mixnetContractAddress: string,
@@ -85,7 +87,7 @@ export interface INymdQuery {
getLayerDistribution(mixnetContractAddress: string): Promise<LayerDistribution>;
getRewardPool(mixnetContractAddress: string): Promise<string>;
getCirculatingSupply(mixnetContractAddress: string): Promise<string>;
getIntervalRewardPercent(mixnetContractAddress: string): Promise<number>;
getEpochRewardPercent(mixnetContractAddress: string): Promise<number>;
getSybilResistancePercent(mixnetContractAddress: string): Promise<number>;
getRewardingStatus(
mixnetContractAddress: string,
@@ -136,6 +138,10 @@ export default class QueryClient extends CosmWasmClient implements IQueryClient
return this.nymdQuerier.getStateParams(mixnetContractAddress);
}
getCurrentRewardingInterval(mixnetContractAddress: string): Promise<RewardingIntervalResponse> {
return this.nymdQuerier.getCurrentRewardingInterval(mixnetContractAddress);
}
getAllNetworkDelegationsPaged(
mixnetContractAddress: string,
limit?: number,
@@ -178,8 +184,8 @@ export default class QueryClient extends CosmWasmClient implements IQueryClient
return this.nymdQuerier.getCirculatingSupply(mixnetContractAddress);
}
getIntervalRewardPercent(mixnetContractAddress: string): Promise<number> {
return this.nymdQuerier.getIntervalRewardPercent(mixnetContractAddress);
getEpochRewardPercent(mixnetContractAddress: string): Promise<number> {
return this.nymdQuerier.getEpochRewardPercent(mixnetContractAddress);
}
getSybilResistancePercent(mixnetContractAddress: string): Promise<number> {
+7 -23
View File
@@ -31,6 +31,7 @@ import {
PagedGatewayResponse,
PagedMixDelegationsResponse,
PagedMixnodeResponse,
RewardingIntervalResponse,
RewardingStatus,
} from './types';
import ValidatorApiQuerier from './validator-api-querier';
@@ -177,13 +178,6 @@ export interface ISigningClient extends IQueryClient, ICosmWasmSigning, INymSign
memo?: string,
): Promise<ExecuteResult>;
updateMixnodeConfig(
mixnetContractAddress: string,
mixIdentity: string,
profitMarginPercent: number,
fee: StdFee | 'auto' | number,
): Promise<ExecuteResult>;
updateContractStateParams(
mixnetContractAddress: string,
newParams: ContractStateParams,
@@ -256,6 +250,10 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
return this.nymdQuerier.getStateParams(mixnetContractAddress);
}
getCurrentRewardingInterval(mixnetContractAddress: string): Promise<RewardingIntervalResponse> {
return this.nymdQuerier.getCurrentRewardingInterval(mixnetContractAddress);
}
getAllNetworkDelegationsPaged(
mixnetContractAddress: string,
limit?: number,
@@ -298,8 +296,8 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
return this.nymdQuerier.getCirculatingSupply(mixnetContractAddress);
}
getIntervalRewardPercent(mixnetContractAddress: string): Promise<number> {
return this.nymdQuerier.getIntervalRewardPercent(mixnetContractAddress);
getEpochRewardPercent(mixnetContractAddress: string): Promise<number> {
return this.nymdQuerier.getEpochRewardPercent(mixnetContractAddress);
}
getSybilResistancePercent(mixnetContractAddress: string): Promise<number> {
@@ -450,20 +448,6 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
);
}
updateMixnodeConfig(
mixnetContractAddress: string,
mixIdentity: string,
profitMarginPercent: number,
fee: StdFee | 'auto' | number,
): Promise<ExecuteResult> {
return this.execute(
this.clientAddress,
mixnetContractAddress,
{ update_mixnode_config: { profit_margin_percent: profitMarginPercent, mix_identity: mixIdentity } },
fee,
);
}
updateContractStateParams(
mixnetContractAddress: string,
newParams: ContractStateParams,
-6
View File
@@ -1,14 +1,8 @@
import axios from 'axios';
import { GasPrice } from '@cosmjs/stargate';
const mainnetPrefix = 'n';
const mainnetDenom = 'nym';
export function nymGasPrice(prefix: string): GasPrice {
if (typeof prefix === 'string') {
if (prefix === mainnetPrefix) {
prefix = mainnetDenom;
}
return GasPrice.fromString(`0.025u${prefix}`); // TODO: ideally this ugly conversion shouldn't be hardcoded here.
}
else {
+6 -1
View File
@@ -43,6 +43,12 @@ export type ContractStateParams = {
mixnode_active_set_size: number;
};
export type RewardingIntervalResponse = {
current_rewarding_interval_starting_block: number;
current_rewarding_interval_nonce: number;
rewarding_in_progress: boolean;
};
export type LayerDistribution = {
gateways: number;
layer1: number;
@@ -129,7 +135,6 @@ export type MixNode = {
sphinx_key: string;
identity_key: string;
version: string;
profit_margin_percent: number;
};
export type GatewayBond = {
@@ -0,0 +1,92 @@
import validatorClient from "../../src/index";
import { config } from '../test-utils/config';
let client: validatorClient;
let mnemonic: string;
beforeEach(async () => {
mnemonic = validatorClient.randomMnemonic();
client = await validatorClient.connect(
mnemonic,
config.NYMD_URL as string,
config.VALIDATOR_API as string,
config.CURRENCY_PREFIX as string,
config.MIXNET_CONTRACT as string,
config.VESTING_CONTRACT as string
);
});
//todos
//we want to mock the majority of these tests
//and keep a few integration tests in place
describe("connect to the nym validator client and perform integration tests against the current testnet", () => {
test("get cached mixnodes", async () => {
try {
const response = await client.getCachedMixnodes();
//expect all mixnodes to have their owner address
response.forEach(mixnodeDetails => {
expect(mixnodeDetails.owner).toHaveLength(43)
});
}
catch (e) {
console.log(e);
}
});
test("get balance of address and denom of the network", async () => {
try {
//provide a users address and get their balance
//we expect their balance to be zero, as it's a new account
const address = await validatorClient.mnemonicToAddress(mnemonic, config.CURRENCY_PREFIX as string);
const response = await client.getBalance(address);
expect(response.amount).toStrictEqual("0");
expect(response.denom).toBe("unymt");
}
catch (e) {
console.log(e);
}
});
test("get minimium pledge amount for a mixnode", async () => {
try {
const response = await client.minimumMixnodePledge();
expect(response.amount).toBe("100000000");
expect(response.denom).toBe(config.CURRENCY_PREFIX as string);
}
catch (e) {
console.log(e);
}
});
test("get minimium gateway pledge amount", async () => {
try {
const response = await client.minimumGatewayPledge();
expect(response.amount).toBe("100000000");
expect(response.denom).toBe(config.CURRENCY_PREFIX as string);
}
catch (e) {
console.log(e);
}
});
test("get current mixnet contract address", () => {
try {
const response = client.mixnetContract;
expect(response).toStrictEqual(config.MIXNET_CONTRACT as string)
}
catch (e) {
console.log(e);
}
});
test("get current vesting contract address", () => {
try {
const response = client.vestingContract;
expect(response).toStrictEqual(config.VESTING_CONTRACT as string)
}
catch (e) {
console.log(e);
}
});
});
@@ -0,0 +1,66 @@
import SigningClient from '../../src/signing-client';
import validator from "../../src/index";
import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate';
import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing';
import { config } from '../test-utils/config';
let cosmWasmClient: CosmWasmClient;
let signingClient: SigningClient;
let mnemonic: string;
beforeEach(async () => {
cosmWasmClient = await SigningClient.connect(config.NYMD_URL as string);
mnemonic = validator.randomMnemonic();
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic)
signingClient = await SigningClient.connectWithNymSigner(
wallet,
config.NYMD_URL as string,
config.VALIDATOR_API as string,
config.CURRENCY_PREFIX as string);
});
describe("alternate between the signing clients of nym and perform basic requests", () => {
test("retrieve balance using the cosmwasm client", async () => {
try {
const randomAddress = await validator.mnemonicToAddress(mnemonic, config.CURRENCY_PREFIX as string);
const balance = await cosmWasmClient.getBalance(randomAddress, config.CURRENCY_PREFIX as string);
expect(balance.denom).toStrictEqual(config.CURRENCY_PREFIX as string);
expect(balance.amount).toStrictEqual("0");
}
catch (e) {
console.log(e);
}
});
test("get the chain id of the network", async () => {
try {
//pass these values in environment variables in the future
const chainId = await cosmWasmClient.getChainId();
expect(chainId).toStrictEqual(config.CHAIN_ID as string);
}
catch (e) {
console.log(e);
}
});
test("get height then search its block", async () => {
try {
const height = await cosmWasmClient.getHeight()
const block = await cosmWasmClient.getBlock(height);
expect(block.header.chainId).toStrictEqual(config.CHAIN_ID as string);
expect(block.header.height).toStrictEqual(height);
}
catch (e) {
console.log(e);
}
});
test("get current reward pool", async () => {
try {
//this is due to change due to when rewards get distributed
const rewards = await signingClient.getRewardPool(config.MIXNET_CONTRACT as string);
expect(rewards).toStrictEqual("250000000000000");
}
catch (e) {
console.log(e);
}
});
});
@@ -0,0 +1,70 @@
import ValidatorApiQuerier from '../../src/validator-api-querier';
import { config } from '../test-utils/config';
import { now, elapsed} from '../test-utils/utils';
let client: ValidatorApiQuerier;
beforeEach(() => {
client = new ValidatorApiQuerier(config.VALIDATOR_API as string);
});
//todos
//we want to mock the majority of these tests
//and keep a few integration tests in place
describe("call out to the validator api and run queries", () => {
test.skip("build client and get all mixnodes", async () => {
try {
//this test was currently ran against a set of prefix data
//this will change
const ownerAddress = "nymt1ydqkmz0ddpvkd3l0vyf8k5xjrqtcnxxvhlpdsr";
let response = await client.getActiveMixnodes();
expect(response[0].owner).toStrictEqual(ownerAddress);
}
catch (e) {
console.log(e);
}
});
test("get rewarded mixnodes", async () => {
try {
// we assume that all mixnodes will have their owners address
// also active sets will determine rewarded mixnodes
let response = await client.getRewardedMixnodes();
response.forEach(rNode => {
expect(rNode.owner.length).toStrictEqual(43);
})
}
catch (e) {
console.log(e);
}
});
test("get cached gateways and it should be six", async () => {
try {
//current gateways running in sandbox-testnet 6
let response = await client.getCachedGateways();
expect(response.length).toStrictEqual(6);
}
catch (e) {
console.log(e);
}
});
test("get cached mixnodes", async () => {
try {
const start = now();
let response = await client.getCachedMixnodes();
response.forEach(mixnode => {
expect(mixnode.owner.length).toStrictEqual(43);
})
console.log(elapsed(start, true));
}
catch (e) {
console.log(e);
}
});
});
@@ -0,0 +1,9 @@
export const config = {
NYMD_URL: process.env.NYMD_URL,
VALIDATOR_API: process.env.VALIDATOR_API,
MIXNET_CONTRACT: process.env.MIXNET_CONTRACT,
VESTING_CONTRACT: process.env.MIXNET_CONTRACT,
USER_MNEMONIC: process.env.MNEMONIC,
CURRENCY_PREFIX: process.env.CURRENCY_PREFIX,
CHAIN_ID: process.env.CHAIN_ID
}
@@ -0,0 +1,17 @@
// timer actions
// Store current time as `start`
export const now = (eventName = null) => {
if (eventName) {
console.log(`Started ${eventName}..`);
}
return new Date().getTime();
}
//takes arg of start time
export const elapsed = (beginning: number, log = false) => {
const duration = new Date().getTime() - beginning;
if (log) {
console.log(`${duration / 1000}s`);
}
return duration;
}
@@ -0,0 +1,10 @@
const currency = require('../../src/currency');
describe("provide unit tests around the the currency module", () => {
test.skip("convert to native balance", () => {
const decimal = "12.0346";
const value = currency.printableBalanceToNative(decimal);
expect(value).toStrictEqual("12034600");
});
});
@@ -0,0 +1,27 @@
const stargate = require("../../src/stargate-helper");
import { config } from '../test-utils/config';
describe("test the stargate functions within the client", () => {
test("test that the gas price is returned correctly", () => {
const nymCurrency = config.CURRENCY_PREFIX as string;
const getGasPrice = stargate.nymGasPrice(nymCurrency);
expect(getGasPrice.denom).toBe(`u${nymCurrency}`);
});
test("provide invalid type returns an error message", () => {
//pass invalid type
expect(() => {
const nymCurrency = 13;
stargate.nymGasPrice(nymCurrency);
}).toThrow("13 is not of type string");
});
//provide test for downloading wasm
//mock this test
// test.skip("providing nothing returns", async () => {
// //pass invalid type
// const downloadWasm = stargate.downloadWasm("http://localhost");
// console.log(downloadWasm);
// })
});
@@ -0,0 +1,19 @@
import validator from "../../src/index";
import { config } from '../test-utils/config';
const NETWORK_DENOM = config.CURRENCY_PREFIX as string;
describe("perform basic interactions with the validator", () => {
test("build client and get all mixnodes", async () => {
const mnemonic = validator.randomMnemonic();
const mnemonicCount = mnemonic.split(" ").length;
expect(mnemonicCount).toStrictEqual(24);
});
test("build client and get all mixnodes", async () => {
const buildMnemonic = validator.randomMnemonic();
const mnemonic = await validator.mnemonicToAddress(buildMnemonic, NETWORK_DENOM);
expect(mnemonic).toHaveLength(43);
expect(mnemonic).toContain(NETWORK_DENOM);
});
});
+10 -2
View File
@@ -5,7 +5,11 @@
"esModuleInterop": true,
"strict": true,
"declaration": true,
"outDir": "./dist"
"outDir": "./dist",
"types": [
"jest",
"node",
]
},
"typedocOptions": {
"entryPoints": [
@@ -16,7 +20,11 @@
"exclude": [
"dist",
"examples",
"tests",
"node_modules"
],
"include": [
"tests",
"./tests/*/*.tsx",
"./tests/*/*.ts"
]
}
+3643 -2960
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -2,7 +2,7 @@
name = "nym-client-wasm"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jedrzej Stuczynski <andrew@nymtech.net>"]
version = "0.12.0"
edition = "2021"
edition = "2018"
keywords = ["nym", "sphinx", "wasm", "webassembly", "privacy", "client"]
license = "Apache-2.0"
repository = "https://github.com/nymtech/nym"
@@ -20,7 +20,7 @@ coconut = ["coconut-interface", "credentials", "gateway-client/coconut"]
[dependencies]
futures = "0.3"
serde = { version = "1.0", features = ["derive"] }
wasm-bindgen = { version = "=0.2.78", features = ["serde-serialize"] }
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
wasm-bindgen-futures = "0.4"
js-sys = "0.3"
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
@@ -32,7 +32,7 @@ credentials = { path = "../../common/credentials", optional = true }
crypto = { path = "../../common/crypto" }
nymsphinx = { path = "../../common/nymsphinx" }
topology = { path = "../../common/topology" }
gateway-client = { path = "../../common/client-libs/gateway-client", default-features = false, features = ["wasm"] }
gateway-client = { path = "../../common/client-libs/gateway-client" }
validator-client = { path = "../../common/client-libs/validator-client", default-features = false }
wasm-utils = { path = "../../common/wasm-utils" }
+16 -19
View File
@@ -22,10 +22,7 @@
"webpack-dev-server": "^3.11.0"
}
},
"../pkg": {
"name": "@nymproject/nym-client-wasm",
"version": "0.0.1"
},
"../pkg": {},
"node_modules/@nymproject/nym-client-wasm": {
"resolved": "../pkg",
"link": true
@@ -2354,9 +2351,9 @@
}
},
"node_modules/follow-redirects": {
"version": "1.14.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
"dev": true,
"funding": [
{
@@ -5862,9 +5859,9 @@
}
},
"node_modules/url-parse": {
"version": "1.5.7",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.7.tgz",
"integrity": "sha512-HxWkieX+STA38EDk7CE9MEryFeHCKzgagxlGvsdS7WBImq9Mk+PGwiT56w82WI3aicwJA8REp42Cxo98c8FZMA==",
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
"dev": true,
"dependencies": {
"querystringify": "^2.1.1",
@@ -6503,9 +6500,9 @@
"dev": true
},
"node_modules/ws": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
"integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
"dev": true,
"dependencies": {
"async-limiter": "~1.0.0"
@@ -8545,9 +8542,9 @@
}
},
"follow-redirects": {
"version": "1.14.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
"dev": true
},
"for-in": {
@@ -11402,9 +11399,9 @@
}
},
"url-parse": {
"version": "1.5.7",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.7.tgz",
"integrity": "sha512-HxWkieX+STA38EDk7CE9MEryFeHCKzgagxlGvsdS7WBImq9Mk+PGwiT56w82WI3aicwJA8REp42Cxo98c8FZMA==",
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
"dev": true,
"requires": {
"querystringify": "^2.1.1",
File diff suppressed because it is too large Load Diff
@@ -8,7 +8,7 @@
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"bootstrap": "^4.5.0",
"node-sass": "^7.0.0",
"node-sass": "^4.14.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "^4.0.0",

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