Compare commits
89 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 340960d957 | |||
| 554e446208 | |||
| a6325b922a | |||
| fae4768b99 | |||
| 2689a4dbd8 | |||
| 02e40ccaef | |||
| b216338364 | |||
| 4a83bb9ba8 | |||
| 66ec3b037f | |||
| 168baa5071 | |||
| 7aef468839 | |||
| cb3ccd7f7e | |||
| 16509dbace | |||
| b907ccbd5b | |||
| 7b3194d7d2 | |||
| 0b81edfc66 | |||
| 8c6150e5ef | |||
| 46164a389a | |||
| 96d256b48f | |||
| f98b93f60e | |||
| 0f6c356f39 | |||
| cf3f5d9a53 | |||
| 2f47e6349a | |||
| 4b2b5390d3 | |||
| 734ff63f6d | |||
| 910c24e7da | |||
| c96b73172a | |||
| 823c2c7262 | |||
| 03d1b72a9e | |||
| 066669440f | |||
| 9fb3443fd1 | |||
| cd89a590b5 | |||
| 06cb8bd969 | |||
| c72fef169c | |||
| 3c27eb41b8 | |||
| 2428374fe7 | |||
| 5a491f0a7e | |||
| 530f9ccb6f | |||
| 2228a81d43 | |||
| c8a1b53071 | |||
| b896aaaed1 | |||
| 828ffc6710 | |||
| 05cdb27029 | |||
| 3f29d3eba5 | |||
| aa2c41dc41 | |||
| 048de771ab | |||
| e1b06f02f3 | |||
| b5b8b8f224 | |||
| 2d7141dfb1 | |||
| a07522258f | |||
| 547a441002 | |||
| 93208fb5e0 | |||
| c9b50dd979 | |||
| 74cdfd5d94 | |||
| 953e813f0e | |||
| 29cf5058a6 | |||
| a2856552d8 | |||
| a33c603471 | |||
| a9f9266992 | |||
| cf34d0d24a | |||
| 5fa7b0a709 | |||
| e232b4fd24 | |||
| 609f174e8d | |||
| a0f4627647 | |||
| 258f8f5f5d | |||
| 38220e05f1 | |||
| 6250ebe235 | |||
| a55323c0e2 | |||
| baa8ac3610 | |||
| 933da11e8f | |||
| 0469036da4 | |||
| 63f9a856fa | |||
| c068948c62 | |||
| 0105f9fa5e | |||
| 004c737965 | |||
| 549121ca32 | |||
| 3f2278dafc | |||
| 25ce0ac814 | |||
| 38d313a101 | |||
| f67bc0ead5 | |||
| 90aaa3572d | |||
| ecc61e4a4a | |||
| 22ac4919e5 | |||
| a1e7cc8e87 | |||
| 57df00637c | |||
| c7eb3bdb7b | |||
| 8f9b704541 | |||
| 6a956c790a | |||
| 2ff5c7221a |
@@ -8,13 +8,10 @@ on:
|
|||||||
- 'gateway/**'
|
- 'gateway/**'
|
||||||
- 'integrations/**'
|
- 'integrations/**'
|
||||||
- 'nym-api/**'
|
- 'nym-api/**'
|
||||||
- 'nym-authenticator-client/**'
|
|
||||||
- 'nym-credential-proxy/**'
|
- 'nym-credential-proxy/**'
|
||||||
- 'nym-ip-packet-client/**'
|
|
||||||
- 'nym-network-monitor/**'
|
- 'nym-network-monitor/**'
|
||||||
- 'nym-node/**'
|
- 'nym-node/**'
|
||||||
- 'nym-node-status-api/**'
|
- 'nym-node-status-api/**'
|
||||||
- 'nym-registration-client/**'
|
|
||||||
- 'nym-statistics-api/**'
|
- 'nym-statistics-api/**'
|
||||||
- 'nym-outfox/**'
|
- 'nym-outfox/**'
|
||||||
- 'nym-validator-rewarder/**'
|
- 'nym-validator-rewarder/**'
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.48.1
|
uses: mikefarah/yq@v4.47.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-if-tag-exists:
|
check-if-tag-exists:
|
||||||
runs-on: arc-linux-latest-dind
|
runs-on: arc-ubuntu-22.04-dind
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.48.1
|
uses: mikefarah/yq@v4.47.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|||||||
@@ -6,14 +6,16 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- "ts-packages/**"
|
- "ts-packages/**"
|
||||||
- "sdk/typescript/**"
|
- "sdk/typescript/**"
|
||||||
|
- "nym-connect/desktop/src/**"
|
||||||
|
- "nym-connect/desktop/package.json"
|
||||||
- "nym-wallet/src/**"
|
- "nym-wallet/src/**"
|
||||||
- "nym-wallet/package.json"
|
- "nym-wallet/package.json"
|
||||||
- "explorer-v2/**"
|
- "explorer/**"
|
||||||
- ".github/workflows/ci-lint-typescript.yml"
|
- ".github/workflows/ci-lint-typescript.yml"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: arc-linux-latest
|
runs-on: ubuntu-22.04
|
||||||
env:
|
env:
|
||||||
RUSTUP_PERMIT_COPY_RENAME: 1
|
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||||
steps:
|
steps:
|
||||||
@@ -23,7 +25,6 @@ jobs:
|
|||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
|
|
||||||
- name: Setup yarn
|
- name: Setup yarn
|
||||||
run: npm install -g yarn
|
run: npm install -g yarn
|
||||||
|
|
||||||
@@ -36,12 +37,14 @@ jobs:
|
|||||||
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
|
|
||||||
- name: Install wasm-opt
|
- name: Install wasm-opt
|
||||||
run: cargo install wasm-opt
|
uses: ./.github/actions/install-wasm-opt
|
||||||
|
with:
|
||||||
|
version: '116'
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v6
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: "1.24.6"
|
go-version: "1.23.7"
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: yarn
|
run: yarn
|
||||||
@@ -49,11 +52,7 @@ jobs:
|
|||||||
- name: Build packages
|
- name: Build packages
|
||||||
run: yarn build:ci
|
run: yarn build:ci
|
||||||
|
|
||||||
- name: Install again
|
|
||||||
run: yarn
|
|
||||||
|
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: yarn lint
|
run: yarn lint
|
||||||
|
|
||||||
- name: Typecheck with tsc
|
- name: Typecheck with tsc
|
||||||
run: yarn tsc
|
run: yarn tsc
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: arc-linux-latest
|
runs-on: custom-linux
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ jobs:
|
|||||||
components: rustfmt, clippy
|
components: rustfmt, clippy
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v6
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: "1.24.6"
|
go-version: "1.24.6"
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||||
- name: SonarQube Scan
|
- name: SonarQube Scan
|
||||||
uses: SonarSource/sonarqube-scan-action@v6
|
uses: SonarSource/sonarqube-scan-action@v5
|
||||||
env:
|
env:
|
||||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
- name: Setup Pages
|
- name: Setup Pages
|
||||||
uses: actions/configure-pages@v5
|
uses: actions/configure-pages@v5
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-pages-artifact@v4
|
uses: actions/upload-pages-artifact@v3
|
||||||
with:
|
with:
|
||||||
# Upload entire repository
|
# Upload entire repository
|
||||||
path: './ppa'
|
path: './ppa'
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/first-interaction@v3
|
- uses: actions/first-interaction@v3
|
||||||
with:
|
with:
|
||||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
issue_message: 'Thank you for raising this issue'
|
issue-message: 'Thank you for raising this issue'
|
||||||
pr_message: 'Thank you for making this first PR'
|
pr-message: 'Thank you for making this first PR'
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish:
|
publish:
|
||||||
runs-on: ubuntu-latest
|
runs-on: arc-ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@@ -17,13 +17,10 @@ jobs:
|
|||||||
- name: Setup yarn
|
- name: Setup yarn
|
||||||
run: npm install -g yarn
|
run: npm install -g yarn
|
||||||
|
|
||||||
- name: Install rust toolchain
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
profile: minimal
|
|
||||||
toolchain: stable
|
toolchain: stable
|
||||||
override: true
|
|
||||||
components: rustfmt, clippy
|
|
||||||
|
|
||||||
- name: Install wasm-pack
|
- name: Install wasm-pack
|
||||||
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
@@ -32,9 +29,9 @@ jobs:
|
|||||||
run: cargo install wasm-opt
|
run: cargo install wasm-opt
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v6
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: "1.24.6"
|
go-version: "1.23.7"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: yarn
|
run: yarn
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.48.1
|
uses: mikefarah/yq@v4.47.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-credential-proxy/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-credential-proxy/Cargo.toml
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.48.1
|
uses: mikefarah/yq@v4.47.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.48.1
|
uses: mikefarah/yq@v4.47.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-network-monitor/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-network-monitor/Cargo.toml
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ name: Build and upload Node Status agent container to harbor.nymte.ch
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
|
gateway_probe_git_ref:
|
||||||
|
type: string
|
||||||
|
default: nym-vpn-core-v1.4.0
|
||||||
|
required: true
|
||||||
|
description: Which gateway probe git ref to build the image with
|
||||||
release_image:
|
release_image:
|
||||||
description: 'Tag image as a release'
|
description: 'Tag image as a release'
|
||||||
required: true
|
required: true
|
||||||
@@ -38,6 +43,16 @@ jobs:
|
|||||||
VERSION=$(yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml)
|
VERSION=$(yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml)
|
||||||
echo "result=$VERSION" >> $GITHUB_OUTPUT
|
echo "result=$VERSION" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: cleanup-gateway-probe-ref
|
||||||
|
id: cleanup_gateway_probe_ref
|
||||||
|
run: |
|
||||||
|
GATEWAY_PROBE_GIT_REF=${{ github.event.inputs.gateway_probe_git_ref }}
|
||||||
|
GIT_REF_SLUG="${GATEWAY_PROBE_GIT_REF//\//-}"
|
||||||
|
echo "git_ref=${GIT_REF_SLUG}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Set GIT_TAG variable
|
||||||
|
run: echo "GIT_TAG=${{ env.WORKING_DIRECTORY }}-${{ steps.get_version.outputs.result }}-${{ steps.cleanup_gateway_probe_ref.outputs.git_ref }}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Initialize RELEASE_TAG
|
- name: Initialize RELEASE_TAG
|
||||||
run: echo "RELEASE_TAG=" >> $GITHUB_ENV
|
run: echo "RELEASE_TAG=" >> $GITHUB_ENV
|
||||||
|
|
||||||
@@ -46,12 +61,24 @@ jobs:
|
|||||||
run: echo "RELEASE_TAG=golden-" >> $GITHUB_ENV
|
run: echo "RELEASE_TAG=golden-" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Set IMAGE_NAME_AND_TAGS variable
|
- name: Set IMAGE_NAME_AND_TAGS variable
|
||||||
run: echo "IMAGE_NAME_AND_TAGS=${{ env.CONTAINER_NAME }}:${{ env.RELEASE_TAG }}${{ steps.get_version.outputs.result }}" >> $GITHUB_ENV
|
run: echo "IMAGE_NAME_AND_TAGS=${{ env.CONTAINER_NAME }}:${{ env.RELEASE_TAG }}${{ steps.get_version.outputs.result }}-${{ steps.cleanup_gateway_probe_ref.outputs.git_ref }}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: New env vars
|
- name: New env vars
|
||||||
run: echo "RELEASE_TAG='$RELEASE_TAG' IMAGE_NAME_AND_TAGS='$IMAGE_NAME_AND_TAGS'"
|
run: echo "RELEASE_TAG='$RELEASE_TAG' GIT_TAG='$GIT_TAG' IMAGE_NAME_AND_TAGS='$IMAGE_NAME_AND_TAGS'"
|
||||||
|
|
||||||
|
# - name: Remove existing tag if exists
|
||||||
|
# run: |
|
||||||
|
# if git rev-parse $${{ env.GIT_TAG }} >/dev/null 2>&1; then
|
||||||
|
# git push --delete origin $${{ env.GIT_TAG }}
|
||||||
|
# git tag -d $${{ env.GIT_TAG }}
|
||||||
|
# fi
|
||||||
|
|
||||||
|
# - name: Create tag
|
||||||
|
# run: |
|
||||||
|
# git tag -a $${{ env.GIT_TAG }} -m "Version ${{ steps.get_version.outputs.result }}-${{ steps.cleanup_gateway_probe_ref.outputs.git_ref }}"
|
||||||
|
# git push origin $${{ env.GIT_TAG }}
|
||||||
|
|
||||||
- name: BuildAndPushImageOnHarbor
|
- name: BuildAndPushImageOnHarbor
|
||||||
run: |
|
run: |
|
||||||
docker build -f ${{ env.WORKING_DIRECTORY }}/Dockerfile . -t harbor.nymte.ch/nym/${{ env.IMAGE_NAME_AND_TAGS }}
|
docker build --build-arg GIT_REF=${{ github.event.inputs.gateway_probe_git_ref }} -f ${{ env.WORKING_DIRECTORY }}/Dockerfile . -t harbor.nymte.ch/nym/${{ env.IMAGE_NAME_AND_TAGS }}
|
||||||
docker push harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }} --all-tags
|
docker push harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }} --all-tags
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.48.1
|
uses: mikefarah/yq@v4.47.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-api/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-api/Cargo.toml
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.48.1
|
uses: mikefarah/yq@v4.47.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.48.1
|
uses: mikefarah/yq@v4.47.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.48.1
|
uses: mikefarah/yq@v4.47.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
git config --global user.name "Lawrence Stalder"
|
git config --global user.name "Lawrence Stalder"
|
||||||
|
|
||||||
- name: Get version from cargo.toml
|
- name: Get version from cargo.toml
|
||||||
uses: mikefarah/yq@v4.48.1
|
uses: mikefarah/yq@v4.47.1
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml
|
||||||
|
|||||||
@@ -4,100 +4,6 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
## [2025.21-mozzarella] (2025-11-25)
|
|
||||||
|
|
||||||
- [bugfix] Tunnel not waiting on MixnetClient to shut down cleanly ([#6225])
|
|
||||||
- bugfix: fix credential proxy upgrade mode attestation url arg ([#6202])
|
|
||||||
- HTTP API resilience enable & domain rotation conditions ([#6200])
|
|
||||||
- Remove debug feature from http-macro spec in gateway probe ([#6195])
|
|
||||||
- DNS relibility and troubleshooting ([#6179])
|
|
||||||
- [bugfix] Distinguish authenticator errors by credential spent ([#6176])
|
|
||||||
- Typescript SDK 1.4.1 ([#6146])
|
|
||||||
- Enable URL rotation and retries for mixnet gateway init ([#6126])
|
|
||||||
- Feature/credential proxy jwt ([#5957])
|
|
||||||
|
|
||||||
[#6225]: https://github.com/nymtech/nym/pull/6225
|
|
||||||
[#6202]: https://github.com/nymtech/nym/pull/6202
|
|
||||||
[#6200]: https://github.com/nymtech/nym/pull/6200
|
|
||||||
[#6195]: https://github.com/nymtech/nym/pull/6195
|
|
||||||
[#6179]: https://github.com/nymtech/nym/pull/6179
|
|
||||||
[#6176]: https://github.com/nymtech/nym/pull/6176
|
|
||||||
[#6146]: https://github.com/nymtech/nym/pull/6146
|
|
||||||
[#6126]: https://github.com/nymtech/nym/pull/6126
|
|
||||||
[#5957]: https://github.com/nymtech/nym/pull/5957
|
|
||||||
|
|
||||||
## [2025.20-leerdammer] (2025-11-12)
|
|
||||||
|
|
||||||
- Max/tweak ts sdk actions ([#6185])
|
|
||||||
- chore: resolve clippy 1.91 warnings ([#6168])
|
|
||||||
- [chore] Remove unused dependencies ([#6151])
|
|
||||||
- Use typed-builder for registration client builder config ([#6150])
|
|
||||||
- tommy is too quick ([#6149])
|
|
||||||
- configurable mixnet client startup timeout ([#6148])
|
|
||||||
- [Feature/operators]: QUIC bridge deployment script v2 ([#6145])
|
|
||||||
- Bugfix: Add circuit breaker ([#6143])
|
|
||||||
- bugfix: update internal owner address in transferred share ([#6139])
|
|
||||||
- Update quic_bridge_deployment.sh for IPv4 and .deb package ([#6138])
|
|
||||||
- feat: expose more explicit new_with_fronted_urls builder for http API client ([#6136])
|
|
||||||
- bugfix: update stored epoch share when changing ownership ([#6135])
|
|
||||||
- Domain fronting ([#6134])
|
|
||||||
- bugfix: update stored epoch share when changing announce address ([#6131])
|
|
||||||
|
|
||||||
[#6185]: https://github.com/nymtech/nym/pull/6185
|
|
||||||
[#6168]: https://github.com/nymtech/nym/pull/6168
|
|
||||||
[#6151]: https://github.com/nymtech/nym/pull/6151
|
|
||||||
[#6150]: https://github.com/nymtech/nym/pull/6150
|
|
||||||
[#6149]: https://github.com/nymtech/nym/pull/6149
|
|
||||||
[#6148]: https://github.com/nymtech/nym/pull/6148
|
|
||||||
[#6145]: https://github.com/nymtech/nym/pull/6145
|
|
||||||
[#6143]: https://github.com/nymtech/nym/pull/6143
|
|
||||||
[#6139]: https://github.com/nymtech/nym/pull/6139
|
|
||||||
[#6138]: https://github.com/nymtech/nym/pull/6138
|
|
||||||
[#6136]: https://github.com/nymtech/nym/pull/6136
|
|
||||||
[#6135]: https://github.com/nymtech/nym/pull/6135
|
|
||||||
[#6134]: https://github.com/nymtech/nym/pull/6134
|
|
||||||
[#6131]: https://github.com/nymtech/nym/pull/6131
|
|
||||||
|
|
||||||
## [2025.19-kase] (2025-10-30)
|
|
||||||
|
|
||||||
- update ns agent workflow ([#6154])
|
|
||||||
- Cherry pick - request #6143 from nymtech/bugfix/mix-tx-closed-v2 ([#6153])
|
|
||||||
- bugfix: nym-credential-proxy query params parsing regression ([#6121])
|
|
||||||
- bugfix: revert some dep updates introduced in #6043 ([#6120])
|
|
||||||
- Skip ipv6 metadata endpoint request ([#6118])
|
|
||||||
- update to no longer use 1mb files ([#6117])
|
|
||||||
- chore: restore pending dkg contract state migration ([#6116])
|
|
||||||
- Revert "Propagate cancel token to mixnet client" ([#6115])
|
|
||||||
- Update dirs to 6.0 ([#6109])
|
|
||||||
- Propagate cancel token to mixnet client ([#6105])
|
|
||||||
- bugfix: retrieve and update ticketbook in the same query ([#6101])
|
|
||||||
- bugfix: include network name in the default gateway probe config path ([#6100])
|
|
||||||
- Bugfix/incompatibility fixes ([#6099])
|
|
||||||
- [DOCs/operators] QUIC deployment script & docs ([#6098])
|
|
||||||
- bugfix: testnet manager 02sql migration ([#6096])
|
|
||||||
- feat: move gateway probe to monorepo (and update to rust edition 2024) ([#6094])
|
|
||||||
- bugfix: use custom topology provider for list of init gateways ([#6092])
|
|
||||||
- Max/fix wasm client + build commands ([#6043])
|
|
||||||
|
|
||||||
[#6154]: https://github.com/nymtech/nym/pull/6154
|
|
||||||
[#6153]: https://github.com/nymtech/nym/pull/6153
|
|
||||||
[#6121]: https://github.com/nymtech/nym/pull/6121
|
|
||||||
[#6120]: https://github.com/nymtech/nym/pull/6120
|
|
||||||
[#6118]: https://github.com/nymtech/nym/pull/6118
|
|
||||||
[#6117]: https://github.com/nymtech/nym/pull/6117
|
|
||||||
[#6116]: https://github.com/nymtech/nym/pull/6116
|
|
||||||
[#6115]: https://github.com/nymtech/nym/pull/6115
|
|
||||||
[#6109]: https://github.com/nymtech/nym/pull/6109
|
|
||||||
[#6105]: https://github.com/nymtech/nym/pull/6105
|
|
||||||
[#6101]: https://github.com/nymtech/nym/pull/6101
|
|
||||||
[#6100]: https://github.com/nymtech/nym/pull/6100
|
|
||||||
[#6099]: https://github.com/nymtech/nym/pull/6099
|
|
||||||
[#6098]: https://github.com/nymtech/nym/pull/6098
|
|
||||||
[#6096]: https://github.com/nymtech/nym/pull/6096
|
|
||||||
[#6094]: https://github.com/nymtech/nym/pull/6094
|
|
||||||
[#6092]: https://github.com/nymtech/nym/pull/6092
|
|
||||||
[#6043]: https://github.com/nymtech/nym/pull/6043
|
|
||||||
|
|
||||||
## [2025.18-jarlsberg] (2025-10-14)
|
## [2025.18-jarlsberg] (2025-10-14)
|
||||||
|
|
||||||
- ns-api: add descriptions to dVPN gateway responses ([#6102])
|
- ns-api: add descriptions to dVPN gateway responses ([#6102])
|
||||||
|
|||||||
Generated
+102
-81
@@ -1283,7 +1283,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2579,7 +2579,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "extension-storage"
|
name = "extension-storage"
|
||||||
version = "1.4.1"
|
version = "1.4.0-rc.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bip39",
|
"bip39",
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
@@ -3965,7 +3965,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4374,11 +4374,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchers"
|
name = "matchers"
|
||||||
version = "0.2.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
|
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"regex-automata",
|
"regex-automata 0.1.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4478,7 +4478,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mix-fetch-wasm"
|
name = "mix-fetch-wasm"
|
||||||
version = "1.4.1"
|
version = "1.4.0-rc.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"futures",
|
"futures",
|
||||||
@@ -4488,7 +4488,6 @@ dependencies = [
|
|||||||
"nym-ordered-buffer",
|
"nym-ordered-buffer",
|
||||||
"nym-service-providers-common",
|
"nym-service-providers-common",
|
||||||
"nym-socks5-requests",
|
"nym-socks5-requests",
|
||||||
"nym-validator-client",
|
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"serde",
|
"serde",
|
||||||
"serde-wasm-bindgen 0.6.5",
|
"serde-wasm-bindgen 0.6.5",
|
||||||
@@ -4741,15 +4740,6 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nu-ansi-term"
|
|
||||||
version = "0.50.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399"
|
|
||||||
dependencies = [
|
|
||||||
"windows-sys 0.52.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-bigint"
|
name = "num-bigint"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@@ -4834,7 +4824,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-api"
|
name = "nym-api"
|
||||||
version = "1.1.70"
|
version = "1.1.67"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -4905,7 +4895,7 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower-http",
|
"tower-http 0.5.2",
|
||||||
"tracing",
|
"tracing",
|
||||||
"ts-rs",
|
"ts-rs",
|
||||||
"url",
|
"url",
|
||||||
@@ -4997,7 +4987,6 @@ dependencies = [
|
|||||||
"nym-network-defaults",
|
"nym-network-defaults",
|
||||||
"nym-service-provider-requests-common",
|
"nym-service-provider-requests-common",
|
||||||
"nym-sphinx",
|
"nym-sphinx",
|
||||||
"nym-test-utils",
|
|
||||||
"nym-wireguard-types",
|
"nym-wireguard-types",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"semver 1.0.26",
|
"semver 1.0.26",
|
||||||
@@ -5005,7 +4994,6 @@ dependencies = [
|
|||||||
"sha2 0.10.9",
|
"sha2 0.10.9",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"tracing",
|
|
||||||
"x25519-dalek",
|
"x25519-dalek",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -5014,16 +5002,21 @@ name = "nym-bandwidth-controller"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"bip39",
|
||||||
"log",
|
"log",
|
||||||
"nym-credential-storage",
|
"nym-credential-storage",
|
||||||
"nym-credentials",
|
"nym-credentials",
|
||||||
"nym-credentials-interface",
|
"nym-credentials-interface",
|
||||||
"nym-crypto",
|
"nym-crypto",
|
||||||
|
"nym-ecash-contract-common",
|
||||||
"nym-ecash-time",
|
"nym-ecash-time",
|
||||||
|
"nym-network-defaults",
|
||||||
"nym-task",
|
"nym-task",
|
||||||
"nym-validator-client",
|
"nym-validator-client",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
|
"url",
|
||||||
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5057,7 +5050,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-cli"
|
name = "nym-cli"
|
||||||
version = "1.1.67"
|
version = "1.1.64"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
@@ -5140,7 +5133,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-client"
|
name = "nym-client"
|
||||||
version = "1.1.67"
|
version = "1.1.64"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bs58",
|
"bs58",
|
||||||
"clap",
|
"clap",
|
||||||
@@ -5290,7 +5283,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-client-wasm"
|
name = "nym-client-wasm"
|
||||||
version = "1.4.1"
|
version = "1.4.0-rc.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"futures",
|
"futures",
|
||||||
@@ -5469,11 +5462,8 @@ dependencies = [
|
|||||||
"nym-crypto",
|
"nym-crypto",
|
||||||
"nym-ecash-contract-common",
|
"nym-ecash-contract-common",
|
||||||
"nym-ecash-signer-check",
|
"nym-ecash-signer-check",
|
||||||
"nym-http-api-client",
|
|
||||||
"nym-http-api-common",
|
"nym-http-api-common",
|
||||||
"nym-network-defaults",
|
"nym-network-defaults",
|
||||||
"nym-pemstore",
|
|
||||||
"nym-upgrade-mode-check",
|
|
||||||
"nym-validator-client",
|
"nym-validator-client",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"reqwest 0.12.22",
|
"reqwest 0.12.22",
|
||||||
@@ -5487,7 +5477,7 @@ dependencies = [
|
|||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower-http",
|
"tower-http 0.5.2",
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
"utoipa",
|
"utoipa",
|
||||||
@@ -5544,7 +5534,6 @@ dependencies = [
|
|||||||
"nym-http-api-client",
|
"nym-http-api-client",
|
||||||
"nym-http-api-common",
|
"nym-http-api-common",
|
||||||
"nym-serde-helpers",
|
"nym-serde-helpers",
|
||||||
"nym-upgrade-mode-check",
|
|
||||||
"reqwest 0.12.22",
|
"reqwest 0.12.22",
|
||||||
"schemars 0.8.22",
|
"schemars 0.8.22",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -5576,7 +5565,6 @@ dependencies = [
|
|||||||
"sqlx",
|
"sqlx",
|
||||||
"sqlx-pool-guard",
|
"sqlx-pool-guard",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"time",
|
|
||||||
"tokio",
|
"tokio",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
@@ -5612,13 +5600,12 @@ dependencies = [
|
|||||||
"nym-api-requests",
|
"nym-api-requests",
|
||||||
"nym-credentials",
|
"nym-credentials",
|
||||||
"nym-credentials-interface",
|
"nym-credentials-interface",
|
||||||
"nym-crypto",
|
|
||||||
"nym-ecash-contract-common",
|
"nym-ecash-contract-common",
|
||||||
"nym-gateway-requests",
|
"nym-gateway-requests",
|
||||||
"nym-gateway-storage",
|
"nym-gateway-storage",
|
||||||
"nym-task",
|
"nym-task",
|
||||||
"nym-upgrade-mode-check",
|
|
||||||
"nym-validator-client",
|
"nym-validator-client",
|
||||||
|
"rand 0.8.5",
|
||||||
"si-scale",
|
"si-scale",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"time",
|
"time",
|
||||||
@@ -5658,7 +5645,6 @@ dependencies = [
|
|||||||
"nym-compact-ecash",
|
"nym-compact-ecash",
|
||||||
"nym-ecash-time",
|
"nym-ecash-time",
|
||||||
"nym-network-defaults",
|
"nym-network-defaults",
|
||||||
"nym-upgrade-mode-check",
|
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"serde",
|
"serde",
|
||||||
"strum",
|
"strum",
|
||||||
@@ -5675,7 +5661,6 @@ dependencies = [
|
|||||||
"aead",
|
"aead",
|
||||||
"aes",
|
"aes",
|
||||||
"aes-gcm-siv",
|
"aes-gcm-siv",
|
||||||
"anyhow",
|
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"blake3",
|
"blake3",
|
||||||
"bs58",
|
"bs58",
|
||||||
@@ -5689,12 +5674,10 @@ dependencies = [
|
|||||||
"jwt-simple",
|
"jwt-simple",
|
||||||
"nym-pemstore",
|
"nym-pemstore",
|
||||||
"nym-sphinx-types",
|
"nym-sphinx-types",
|
||||||
"nym-test-utils",
|
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"rand_chacha 0.3.1",
|
"rand_chacha 0.3.1",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_bytes",
|
"serde_bytes",
|
||||||
"serde_json",
|
|
||||||
"sha2 0.10.9",
|
"sha2 0.10.9",
|
||||||
"subtle-encoding",
|
"subtle-encoding",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
@@ -5809,6 +5792,7 @@ dependencies = [
|
|||||||
name = "nym-gateway"
|
name = "nym-gateway"
|
||||||
version = "1.1.36"
|
version = "1.1.36"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bincode",
|
"bincode",
|
||||||
"bip39",
|
"bip39",
|
||||||
@@ -5819,6 +5803,7 @@ dependencies = [
|
|||||||
"futures",
|
"futures",
|
||||||
"ipnetwork",
|
"ipnetwork",
|
||||||
"mock_instant",
|
"mock_instant",
|
||||||
|
"nym-api-requests",
|
||||||
"nym-authenticator-requests",
|
"nym-authenticator-requests",
|
||||||
"nym-client-core",
|
"nym-client-core",
|
||||||
"nym-credential-verification",
|
"nym-credential-verification",
|
||||||
@@ -5831,6 +5816,7 @@ dependencies = [
|
|||||||
"nym-id",
|
"nym-id",
|
||||||
"nym-ip-packet-router",
|
"nym-ip-packet-router",
|
||||||
"nym-mixnet-client",
|
"nym-mixnet-client",
|
||||||
|
"nym-mixnode-common",
|
||||||
"nym-network-defaults",
|
"nym-network-defaults",
|
||||||
"nym-network-requester",
|
"nym-network-requester",
|
||||||
"nym-node-metrics",
|
"nym-node-metrics",
|
||||||
@@ -5840,18 +5826,20 @@ dependencies = [
|
|||||||
"nym-statistics-common",
|
"nym-statistics-common",
|
||||||
"nym-task",
|
"nym-task",
|
||||||
"nym-topology",
|
"nym-topology",
|
||||||
"nym-upgrade-mode-check",
|
"nym-types",
|
||||||
"nym-validator-client",
|
"nym-validator-client",
|
||||||
"nym-wireguard",
|
"nym-wireguard",
|
||||||
"nym-wireguard-private-metadata-server",
|
"nym-wireguard-private-metadata-server",
|
||||||
"nym-wireguard-types",
|
"nym-wireguard-types",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"serde",
|
"serde",
|
||||||
|
"sha2 0.10.9",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tokio-tungstenite",
|
"tokio-tungstenite",
|
||||||
|
"tokio-util",
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
@@ -6062,7 +6050,6 @@ dependencies = [
|
|||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
|
||||||
"url",
|
"url",
|
||||||
"wasmtimer",
|
"wasmtimer",
|
||||||
]
|
]
|
||||||
@@ -6367,7 +6354,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-network-requester"
|
name = "nym-network-requester"
|
||||||
version = "1.1.68"
|
version = "1.1.65"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"addr",
|
"addr",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
@@ -6417,7 +6404,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-node"
|
name = "nym-node"
|
||||||
version = "1.22.0"
|
version = "1.19.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
@@ -6448,7 +6435,6 @@ dependencies = [
|
|||||||
"nym-bin-common",
|
"nym-bin-common",
|
||||||
"nym-client-core-config-types",
|
"nym-client-core-config-types",
|
||||||
"nym-config",
|
"nym-config",
|
||||||
"nym-credential-verification",
|
|
||||||
"nym-crypto",
|
"nym-crypto",
|
||||||
"nym-gateway",
|
"nym-gateway",
|
||||||
"nym-gateway-stats-storage",
|
"nym-gateway-stats-storage",
|
||||||
@@ -6491,7 +6477,7 @@ dependencies = [
|
|||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"toml 0.8.23",
|
"toml 0.8.23",
|
||||||
"tower-http",
|
"tower-http 0.5.2",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-indicatif",
|
"tracing-indicatif",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
@@ -6521,13 +6507,13 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"celes",
|
"celes",
|
||||||
|
"humantime",
|
||||||
"humantime-serde",
|
"humantime-serde",
|
||||||
"nym-bin-common",
|
"nym-bin-common",
|
||||||
"nym-crypto",
|
"nym-crypto",
|
||||||
"nym-exit-policy",
|
"nym-exit-policy",
|
||||||
"nym-http-api-client",
|
"nym-http-api-client",
|
||||||
"nym-noise-keys",
|
"nym-noise-keys",
|
||||||
"nym-upgrade-mode-check",
|
|
||||||
"nym-wireguard-types",
|
"nym-wireguard-types",
|
||||||
"rand_chacha 0.3.1",
|
"rand_chacha 0.3.1",
|
||||||
"schemars 0.8.22",
|
"schemars 0.8.22",
|
||||||
@@ -6538,7 +6524,6 @@ dependencies = [
|
|||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
"url",
|
|
||||||
"utoipa",
|
"utoipa",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -6561,7 +6546,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-node-status-api"
|
name = "nym-node-status-api"
|
||||||
version = "4.0.12"
|
version = "4.0.11-rc1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ammonia",
|
"ammonia",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
@@ -6609,7 +6594,7 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower-http",
|
"tower-http 0.5.2",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-log 0.2.0",
|
"tracing-log 0.2.0",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
@@ -6657,7 +6642,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-node-tester-wasm"
|
name = "nym-node-tester-wasm"
|
||||||
version = "1.3.1"
|
version = "1.3.0-rc.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
@@ -6946,7 +6931,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-socks5-client"
|
name = "nym-socks5-client"
|
||||||
version = "1.1.67"
|
version = "1.1.64"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bs58",
|
"bs58",
|
||||||
"clap",
|
"clap",
|
||||||
@@ -7206,7 +7191,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-statistics-api"
|
name = "nym-statistics-api"
|
||||||
version = "0.3.0"
|
version = "0.2.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"axum",
|
"axum",
|
||||||
@@ -7220,12 +7205,13 @@ dependencies = [
|
|||||||
"nym-statistics-common",
|
"nym-statistics-common",
|
||||||
"nym-task",
|
"nym-task",
|
||||||
"nym-validator-client",
|
"nym-validator-client",
|
||||||
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower-http",
|
"tower-http 0.5.2",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"url",
|
"url",
|
||||||
@@ -7392,21 +7378,18 @@ dependencies = [
|
|||||||
"jwt-simple",
|
"jwt-simple",
|
||||||
"nym-crypto",
|
"nym-crypto",
|
||||||
"nym-http-api-client",
|
"nym-http-api-client",
|
||||||
"nym-test-utils",
|
|
||||||
"reqwest 0.12.22",
|
"reqwest 0.12.22",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"time",
|
"time",
|
||||||
"tracing",
|
"tracing",
|
||||||
"utoipa",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-validator-client"
|
name = "nym-validator-client"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bip32",
|
"bip32",
|
||||||
@@ -7580,10 +7563,17 @@ dependencies = [
|
|||||||
name = "nym-wireguard"
|
name = "nym-wireguard"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
|
"bincode",
|
||||||
|
"chrono",
|
||||||
|
"dashmap",
|
||||||
"defguard_wireguard_rs",
|
"defguard_wireguard_rs",
|
||||||
|
"dyn-clone",
|
||||||
"futures",
|
"futures",
|
||||||
"ip_network",
|
"ip_network",
|
||||||
|
"log",
|
||||||
|
"nym-authenticator-requests",
|
||||||
"nym-credential-verification",
|
"nym-credential-verification",
|
||||||
"nym-credentials-interface",
|
"nym-credentials-interface",
|
||||||
"nym-crypto",
|
"nym-crypto",
|
||||||
@@ -7594,9 +7584,11 @@ dependencies = [
|
|||||||
"nym-task",
|
"nym-task",
|
||||||
"nym-wireguard-types",
|
"nym-wireguard-types",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
"x25519-dalek",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -7624,7 +7616,7 @@ dependencies = [
|
|||||||
"nym-wireguard-private-metadata-shared",
|
"nym-wireguard-private-metadata-shared",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower-http",
|
"tower-http 0.5.2",
|
||||||
"utoipa",
|
"utoipa",
|
||||||
"utoipa-swagger-ui",
|
"utoipa-swagger-ui",
|
||||||
]
|
]
|
||||||
@@ -7648,21 +7640,16 @@ version = "1.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
"futures",
|
|
||||||
"nym-credential-verification",
|
"nym-credential-verification",
|
||||||
"nym-credentials-interface",
|
"nym-credentials-interface",
|
||||||
"nym-crypto",
|
|
||||||
"nym-http-api-client",
|
"nym-http-api-client",
|
||||||
"nym-http-api-common",
|
"nym-http-api-common",
|
||||||
"nym-upgrade-mode-check",
|
|
||||||
"nym-wireguard",
|
"nym-wireguard",
|
||||||
"nym-wireguard-private-metadata-client",
|
"nym-wireguard-private-metadata-client",
|
||||||
"nym-wireguard-private-metadata-server",
|
"nym-wireguard-private-metadata-server",
|
||||||
"nym-wireguard-private-metadata-shared",
|
"nym-wireguard-private-metadata-shared",
|
||||||
"time",
|
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower 0.5.2",
|
"tower-http 0.5.2",
|
||||||
"tower-http",
|
|
||||||
"utoipa",
|
"utoipa",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -7671,7 +7658,10 @@ name = "nym-wireguard-types"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
|
"log",
|
||||||
|
"nym-config",
|
||||||
"nym-crypto",
|
"nym-crypto",
|
||||||
|
"nym-network-defaults",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
@@ -7680,7 +7670,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nymvisor"
|
name = "nymvisor"
|
||||||
version = "0.1.32"
|
version = "0.1.29"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -7731,7 +7721,7 @@ dependencies = [
|
|||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower-http",
|
"tower-http 0.5.2",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"utoipa",
|
"utoipa",
|
||||||
@@ -7834,9 +7824,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.110"
|
version = "0.9.109"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2"
|
checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -8659,7 +8649,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"socket2 0.5.10",
|
"socket2 0.5.10",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -8820,8 +8810,17 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata",
|
"regex-automata 0.4.9",
|
||||||
"regex-syntax",
|
"regex-syntax 0.8.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||||
|
dependencies = [
|
||||||
|
"regex-syntax 0.6.29",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -8832,9 +8831,15 @@ checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-syntax",
|
"regex-syntax 0.8.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
@@ -8914,7 +8919,7 @@ dependencies = [
|
|||||||
"tokio-rustls 0.26.2",
|
"tokio-rustls 0.26.2",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower 0.5.2",
|
"tower 0.5.2",
|
||||||
"tower-http",
|
"tower-http 0.6.6",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"url",
|
"url",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
@@ -9114,7 +9119,7 @@ dependencies = [
|
|||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.4.15",
|
"linux-raw-sys 0.4.15",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -10430,7 +10435,7 @@ dependencies = [
|
|||||||
"getrandom 0.3.3",
|
"getrandom 0.3.3",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix 1.0.8",
|
"rustix 1.0.8",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -11049,9 +11054,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-http"
|
name = "tower-http"
|
||||||
version = "0.6.6"
|
version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
|
checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-compression",
|
"async-compression",
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
@@ -11063,19 +11068,35 @@ dependencies = [
|
|||||||
"http-body-util",
|
"http-body-util",
|
||||||
"http-range-header",
|
"http-range-header",
|
||||||
"httpdate",
|
"httpdate",
|
||||||
"iri-string",
|
|
||||||
"mime",
|
"mime",
|
||||||
"mime_guess",
|
"mime_guess",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower 0.5.2",
|
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-http"
|
||||||
|
version = "0.6.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.9.1",
|
||||||
|
"bytes",
|
||||||
|
"futures-util",
|
||||||
|
"http 1.3.1",
|
||||||
|
"http-body 1.0.1",
|
||||||
|
"iri-string",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tower 0.5.2",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-layer"
|
name = "tower-layer"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@@ -11181,14 +11202,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-subscriber"
|
name = "tracing-subscriber"
|
||||||
version = "0.3.20"
|
version = "0.3.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5"
|
checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"matchers",
|
"matchers",
|
||||||
"nu-ansi-term 0.50.1",
|
"nu-ansi-term",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"regex-automata",
|
"regex",
|
||||||
"sharded-slab",
|
"sharded-slab",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thread_local",
|
"thread_local",
|
||||||
@@ -11224,7 +11245,7 @@ version = "0.2.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2ec6adcab41b1391b08a308cc6302b79f8095d1673f6947c2dc65ffb028b0b2d"
|
checksum = "2ec6adcab41b1391b08a308cc6302b79f8095d1673f6947c2dc65ffb028b0b2d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nu-ansi-term 0.46.0",
|
"nu-ansi-term",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
"tracing-log 0.1.4",
|
"tracing-log 0.1.4",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
@@ -12226,7 +12247,7 @@ version = "0.1.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
+3
-9
@@ -150,7 +150,7 @@ members = [
|
|||||||
"tools/internal/contract-state-importer/importer-cli",
|
"tools/internal/contract-state-importer/importer-cli",
|
||||||
"tools/internal/contract-state-importer/importer-contract",
|
"tools/internal/contract-state-importer/importer-contract",
|
||||||
"tools/internal/mixnet-connectivity-check",
|
"tools/internal/mixnet-connectivity-check",
|
||||||
# "tools/internal/sdk-version-bump",
|
# "tools/internal/sdk-version-bump",
|
||||||
"tools/internal/ssl-inject",
|
"tools/internal/ssl-inject",
|
||||||
"tools/internal/testnet-manager",
|
"tools/internal/testnet-manager",
|
||||||
"tools/internal/testnet-manager/dkg-bypass-contract",
|
"tools/internal/testnet-manager/dkg-bypass-contract",
|
||||||
@@ -171,7 +171,6 @@ members = [
|
|||||||
default-members = [
|
default-members = [
|
||||||
"clients/native",
|
"clients/native",
|
||||||
"clients/socks5",
|
"clients/socks5",
|
||||||
"nym-authenticator-client",
|
|
||||||
"nym-api",
|
"nym-api",
|
||||||
"nym-credential-proxy/nym-credential-proxy",
|
"nym-credential-proxy/nym-credential-proxy",
|
||||||
"nym-node",
|
"nym-node",
|
||||||
@@ -347,11 +346,11 @@ tokio-tungstenite = { version = "0.20.1" }
|
|||||||
tokio-util = "0.7.15"
|
tokio-util = "0.7.15"
|
||||||
toml = "0.8.22"
|
toml = "0.8.22"
|
||||||
tower = "0.5.2"
|
tower = "0.5.2"
|
||||||
tower-http = "0.6.6"
|
tower-http = "0.5.2"
|
||||||
tracing = "0.1.41"
|
tracing = "0.1.41"
|
||||||
tracing-log = "0.2"
|
tracing-log = "0.2"
|
||||||
tracing-opentelemetry = "0.19.0"
|
tracing-opentelemetry = "0.19.0"
|
||||||
tracing-subscriber = "0.3.20"
|
tracing-subscriber = "0.3.19"
|
||||||
tracing-tree = "0.2.2"
|
tracing-tree = "0.2.2"
|
||||||
tracing-indicatif = "0.3.9"
|
tracing-indicatif = "0.3.9"
|
||||||
tracing-test = "0.2.5"
|
tracing-test = "0.2.5"
|
||||||
@@ -454,11 +453,6 @@ opt-level = 'z'
|
|||||||
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] }
|
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] }
|
||||||
|
|
||||||
[workspace.lints.clippy]
|
[workspace.lints.clippy]
|
||||||
suspicious = "deny"
|
|
||||||
complexity = "deny"
|
|
||||||
perf = "deny"
|
|
||||||
style = "deny"
|
|
||||||
|
|
||||||
unwrap_used = "deny"
|
unwrap_used = "deny"
|
||||||
expect_used = "deny"
|
expect_used = "deny"
|
||||||
todo = "deny"
|
todo = "deny"
|
||||||
|
|||||||
@@ -107,16 +107,16 @@ sdk-wasm-build:
|
|||||||
$(MAKE) -C nym-browser-extension/storage wasm-pack
|
$(MAKE) -C nym-browser-extension/storage wasm-pack
|
||||||
$(MAKE) -C wasm/client
|
$(MAKE) -C wasm/client
|
||||||
$(MAKE) -C wasm/node-tester
|
$(MAKE) -C wasm/node-tester
|
||||||
$(MAKE) -C wasm/mix-fetch
|
# $(MAKE) -C wasm/mix-fetch
|
||||||
$(MAKE) -C wasm/zknym-lib
|
$(MAKE) -C wasm/zknym-lib
|
||||||
# $(MAKE) -C wasm/full-nym-wasm
|
# $(MAKE) -C wasm/full-nym-wasm
|
||||||
|
|
||||||
# run this from npm/yarn to ensure tools are in the path, e.g. yarn build:sdk from root of repo
|
# run this from npm/yarn to ensure tools are in the path, e.g. yarn build:sdk from root of repo
|
||||||
sdk-typescript-build:
|
sdk-typescript-build:
|
||||||
npx lerna run --scope @nymproject/sdk build --stream
|
npx lerna run --scope @nymproject/sdk build --stream
|
||||||
npx lerna run --scope @nymproject/mix-fetch build --stream
|
# npx lerna run --scope @nymproject/mix-fetch build --stream
|
||||||
npx lerna run --scope @nymproject/node-tester build --stream
|
# npx lerna run --scope @nymproject/node-tester build --stream
|
||||||
yarn --cwd sdk/typescript/codegen/contract-clients build
|
# yarn --cwd sdk/typescript/codegen/contract-clients build
|
||||||
|
|
||||||
# NOTE: These targets are part of the main workspace (but not as wasm32-unknown-unknown)
|
# NOTE: These targets are part of the main workspace (but not as wasm32-unknown-unknown)
|
||||||
WASM_CRATES = extension-storage nym-client-wasm nym-node-tester-wasm zknym-lib
|
WASM_CRATES = extension-storage nym-client-wasm nym-node-tester-wasm zknym-lib
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-client"
|
name = "nym-client"
|
||||||
version = "1.1.67"
|
version = "1.1.64"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||||
description = "Implementation of the Nym Client"
|
description = "Implementation of the Nym Client"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-socks5-client"
|
name = "nym-socks5-client"
|
||||||
version = "1.1.67"
|
version = "1.1.64"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||||
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ serde = { workspace = true, features = ["derive"] }
|
|||||||
semver = { workspace = true }
|
semver = { workspace = true }
|
||||||
strum_macros = { workspace = true }
|
strum_macros = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
tracing = { workspace = true }
|
|
||||||
|
|
||||||
nym-credentials-interface = { path = "../credentials-interface" }
|
nym-credentials-interface = { path = "../credentials-interface" }
|
||||||
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
|
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
|
||||||
@@ -30,13 +29,7 @@ hmac = { workspace = true, optional = true }
|
|||||||
sha2 = { workspace = true, optional = true }
|
sha2 = { workspace = true, optional = true }
|
||||||
x25519-dalek = { workspace = true, features = ["static_secrets"] }
|
x25519-dalek = { workspace = true, features = ["static_secrets"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
nym-test-utils = { path = "../test-utils" }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["verify"]
|
default = ["verify"]
|
||||||
# this is moved to a separate feature as we really need clients to import it (especially, *cough*, wasm)
|
# this is moved to a separate feature as we really need clients to import it (especially, *cough*, wasm)
|
||||||
verify = ["hmac", "sha2"]
|
verify = ["hmac", "sha2"]
|
||||||
|
|
||||||
[lints]
|
|
||||||
workspace = true
|
|
||||||
@@ -6,11 +6,9 @@ use nym_wireguard_types::PeerPublicKey;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AuthenticatorVersion, Error,
|
AuthenticatorVersion, Error,
|
||||||
traits::{
|
latest::registration::IpPair,
|
||||||
FinalMessage, InitMessage, QueryBandwidthMessage, TopUpMessage, UpgradeModeMessage,
|
traits::{FinalMessage, InitMessage, QueryBandwidthMessage, TopUpMessage, Versionable},
|
||||||
Versionable,
|
v2, v3, v4, v5,
|
||||||
},
|
|
||||||
v2, v3, v4, v5, v6,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is very redundant with AuthenticatorRequest and I reckon they could be smooshed.
|
// This is very redundant with AuthenticatorRequest and I reckon they could be smooshed.
|
||||||
@@ -21,293 +19,6 @@ pub enum ClientMessage {
|
|||||||
Final(Box<dyn FinalMessage + Send + Sync + 'static>),
|
Final(Box<dyn FinalMessage + Send + Sync + 'static>),
|
||||||
Query(Box<dyn QueryBandwidthMessage + Send + Sync + 'static>),
|
Query(Box<dyn QueryBandwidthMessage + Send + Sync + 'static>),
|
||||||
TopUp(Box<dyn TopUpMessage + Send + Sync + 'static>),
|
TopUp(Box<dyn TopUpMessage + Send + Sync + 'static>),
|
||||||
UpgradeModeCheck(Box<dyn UpgradeModeMessage + Send + Sync + 'static>),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SerialisedRequest {
|
|
||||||
pub bytes: Vec<u8>,
|
|
||||||
pub request_id: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SerialisedRequest {
|
|
||||||
pub fn new(bytes: Vec<u8>, request_id: u64) -> Self {
|
|
||||||
Self { bytes, request_id }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ClientMessage {
|
|
||||||
fn serialise_v1(&self) -> Result<SerialisedRequest, Error> {
|
|
||||||
Err(Error::UnsupportedVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialise_v2(&self, reply_to: Recipient) -> Result<SerialisedRequest, Error> {
|
|
||||||
use v2::{
|
|
||||||
registration::{ClientMac, FinalMessage, GatewayClient, InitMessage},
|
|
||||||
request::AuthenticatorRequest,
|
|
||||||
};
|
|
||||||
match self {
|
|
||||||
ClientMessage::Initial(init_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_initial_request(
|
|
||||||
InitMessage {
|
|
||||||
pub_key: init_message.pub_key(),
|
|
||||||
},
|
|
||||||
reply_to,
|
|
||||||
);
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::Final(final_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_final_request(
|
|
||||||
FinalMessage {
|
|
||||||
gateway_client: GatewayClient {
|
|
||||||
pub_key: final_message.gateway_client_pub_key(),
|
|
||||||
private_ip: final_message
|
|
||||||
.gateway_client_ipv4()
|
|
||||||
.ok_or(Error::UnsupportedMessage)?
|
|
||||||
.into(),
|
|
||||||
mac: ClientMac::new(final_message.gateway_client_mac()),
|
|
||||||
},
|
|
||||||
credential: final_message
|
|
||||||
.credential()
|
|
||||||
.and_then(|c| c.credential.into_zk_nym())
|
|
||||||
.map(|c| *c),
|
|
||||||
},
|
|
||||||
reply_to,
|
|
||||||
);
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::Query(query_message) => {
|
|
||||||
let (req, id) =
|
|
||||||
AuthenticatorRequest::new_query_request(query_message.pub_key(), reply_to);
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
_ => Err(Error::UnsupportedMessage),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialise_v3(&self, reply_to: Recipient) -> Result<SerialisedRequest, Error> {
|
|
||||||
use v3::{
|
|
||||||
registration::{ClientMac, FinalMessage, GatewayClient, InitMessage},
|
|
||||||
request::AuthenticatorRequest,
|
|
||||||
topup::TopUpMessage,
|
|
||||||
};
|
|
||||||
match self {
|
|
||||||
ClientMessage::Initial(init_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_initial_request(
|
|
||||||
InitMessage {
|
|
||||||
pub_key: init_message.pub_key(),
|
|
||||||
},
|
|
||||||
reply_to,
|
|
||||||
);
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::Final(final_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_final_request(
|
|
||||||
FinalMessage {
|
|
||||||
gateway_client: GatewayClient {
|
|
||||||
pub_key: final_message.gateway_client_pub_key(),
|
|
||||||
private_ip: final_message
|
|
||||||
.gateway_client_ipv4()
|
|
||||||
.ok_or(Error::UnsupportedMessage)?
|
|
||||||
.into(),
|
|
||||||
mac: ClientMac::new(final_message.gateway_client_mac()),
|
|
||||||
},
|
|
||||||
credential: final_message
|
|
||||||
.credential()
|
|
||||||
.and_then(|c| c.credential.into_zk_nym())
|
|
||||||
.map(|c| *c),
|
|
||||||
},
|
|
||||||
reply_to,
|
|
||||||
);
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::Query(query_message) => {
|
|
||||||
let (req, id) =
|
|
||||||
AuthenticatorRequest::new_query_request(query_message.pub_key(), reply_to);
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::TopUp(top_up_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_topup_request(
|
|
||||||
TopUpMessage {
|
|
||||||
pub_key: top_up_message.pub_key(),
|
|
||||||
credential: top_up_message.credential(),
|
|
||||||
},
|
|
||||||
reply_to,
|
|
||||||
);
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
_ => Err(Error::UnsupportedMessage),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialise_v4(&self, reply_to: Recipient) -> Result<SerialisedRequest, Error> {
|
|
||||||
use v4::{
|
|
||||||
registration::{ClientMac, FinalMessage, GatewayClient, InitMessage, IpPair},
|
|
||||||
request::AuthenticatorRequest,
|
|
||||||
topup::TopUpMessage,
|
|
||||||
};
|
|
||||||
match self {
|
|
||||||
ClientMessage::Initial(init_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_initial_request(
|
|
||||||
InitMessage {
|
|
||||||
pub_key: init_message.pub_key(),
|
|
||||||
},
|
|
||||||
reply_to,
|
|
||||||
);
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::Final(final_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_final_request(
|
|
||||||
FinalMessage {
|
|
||||||
gateway_client: GatewayClient {
|
|
||||||
pub_key: final_message.gateway_client_pub_key(),
|
|
||||||
private_ips: IpPair {
|
|
||||||
ipv4: final_message
|
|
||||||
.gateway_client_ipv4()
|
|
||||||
.ok_or(Error::UnsupportedMessage)?,
|
|
||||||
ipv6: final_message
|
|
||||||
.gateway_client_ipv6()
|
|
||||||
.ok_or(Error::UnsupportedMessage)?,
|
|
||||||
},
|
|
||||||
mac: ClientMac::new(final_message.gateway_client_mac()),
|
|
||||||
},
|
|
||||||
credential: final_message
|
|
||||||
.credential()
|
|
||||||
.and_then(|c| c.credential.into_zk_nym())
|
|
||||||
.map(|c| *c),
|
|
||||||
},
|
|
||||||
reply_to,
|
|
||||||
);
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::Query(query_message) => {
|
|
||||||
let (req, id) =
|
|
||||||
AuthenticatorRequest::new_query_request(query_message.pub_key(), reply_to);
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::TopUp(top_up_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_topup_request(
|
|
||||||
TopUpMessage {
|
|
||||||
pub_key: top_up_message.pub_key(),
|
|
||||||
credential: top_up_message.credential(),
|
|
||||||
},
|
|
||||||
reply_to,
|
|
||||||
);
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
_ => Err(Error::UnsupportedMessage),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialise_v5(&self) -> Result<SerialisedRequest, Error> {
|
|
||||||
use v5::{
|
|
||||||
registration::{ClientMac, FinalMessage, GatewayClient, InitMessage, IpPair},
|
|
||||||
request::AuthenticatorRequest,
|
|
||||||
topup::TopUpMessage,
|
|
||||||
};
|
|
||||||
match self {
|
|
||||||
ClientMessage::Initial(init_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_initial_request(InitMessage {
|
|
||||||
pub_key: init_message.pub_key(),
|
|
||||||
});
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::Final(final_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_final_request(FinalMessage {
|
|
||||||
gateway_client: GatewayClient {
|
|
||||||
pub_key: final_message.gateway_client_pub_key(),
|
|
||||||
private_ips: IpPair {
|
|
||||||
ipv4: final_message
|
|
||||||
.gateway_client_ipv4()
|
|
||||||
.ok_or(Error::UnsupportedMessage)?,
|
|
||||||
ipv6: final_message
|
|
||||||
.gateway_client_ipv6()
|
|
||||||
.ok_or(Error::UnsupportedMessage)?,
|
|
||||||
},
|
|
||||||
mac: ClientMac::new(final_message.gateway_client_mac()),
|
|
||||||
},
|
|
||||||
credential: final_message
|
|
||||||
.credential()
|
|
||||||
.and_then(|c| c.credential.into_zk_nym())
|
|
||||||
.map(|c| *c),
|
|
||||||
});
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::Query(query_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_query_request(query_message.pub_key());
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::TopUp(top_up_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_topup_request(TopUpMessage {
|
|
||||||
pub_key: top_up_message.pub_key(),
|
|
||||||
credential: top_up_message.credential(),
|
|
||||||
});
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
_ => Err(Error::UnsupportedMessage),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialise_v6(&self) -> Result<SerialisedRequest, Error> {
|
|
||||||
use v6::{
|
|
||||||
registration::{ClientMac, FinalMessage, GatewayClient, InitMessage, IpPair},
|
|
||||||
request::AuthenticatorRequest,
|
|
||||||
topup::TopUpMessage,
|
|
||||||
upgrade_mode_check::UpgradeModeCheckRequest,
|
|
||||||
};
|
|
||||||
match self {
|
|
||||||
ClientMessage::Initial(init_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_initial_request(InitMessage {
|
|
||||||
pub_key: init_message.pub_key(),
|
|
||||||
});
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::Final(final_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_final_request(FinalMessage {
|
|
||||||
gateway_client: GatewayClient {
|
|
||||||
pub_key: final_message.gateway_client_pub_key(),
|
|
||||||
private_ips: IpPair {
|
|
||||||
ipv4: final_message
|
|
||||||
.gateway_client_ipv4()
|
|
||||||
.ok_or(Error::UnsupportedMessage)?,
|
|
||||||
ipv6: final_message
|
|
||||||
.gateway_client_ipv6()
|
|
||||||
.ok_or(Error::UnsupportedMessage)?,
|
|
||||||
},
|
|
||||||
mac: ClientMac::new(final_message.gateway_client_mac()),
|
|
||||||
},
|
|
||||||
credential: final_message.credential(),
|
|
||||||
});
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::Query(query_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_query_request(query_message.pub_key());
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::TopUp(top_up_message) => {
|
|
||||||
let (req, id) = AuthenticatorRequest::new_topup_request(TopUpMessage {
|
|
||||||
pub_key: top_up_message.pub_key(),
|
|
||||||
credential: top_up_message.credential(),
|
|
||||||
});
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
ClientMessage::UpgradeModeCheck(upgrade_mode_check) => {
|
|
||||||
// currently JWT is the only emergency credential option
|
|
||||||
let Some(upgrade_mode_jwt) =
|
|
||||||
upgrade_mode_check.upgrade_mode_global_attestation_jwt()
|
|
||||||
else {
|
|
||||||
return Err(Error::conversion(
|
|
||||||
"no valid known upgrade mode check variants",
|
|
||||||
));
|
|
||||||
};
|
|
||||||
let msg = UpgradeModeCheckRequest::UpgradeModeJwt {
|
|
||||||
token: upgrade_mode_jwt,
|
|
||||||
};
|
|
||||||
|
|
||||||
let (req, id) = AuthenticatorRequest::new_upgrade_mode_check_request(msg);
|
|
||||||
Ok(SerialisedRequest::new(req.to_bytes()?, id))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClientMessage {
|
impl ClientMessage {
|
||||||
@@ -316,7 +27,7 @@ impl ClientMessage {
|
|||||||
match self {
|
match self {
|
||||||
Self::Final(msg) => msg.credential().is_some(),
|
Self::Final(msg) => msg.credential().is_some(),
|
||||||
Self::TopUp(_) => true,
|
Self::TopUp(_) => true,
|
||||||
Self::Initial(_) | Self::Query(_) | Self::UpgradeModeCheck(_) => false,
|
Self::Initial(_) | Self::Query(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,18 +37,208 @@ impl ClientMessage {
|
|||||||
ClientMessage::Final(msg) => msg.version(),
|
ClientMessage::Final(msg) => msg.version(),
|
||||||
ClientMessage::Query(msg) => msg.version(),
|
ClientMessage::Query(msg) => msg.version(),
|
||||||
ClientMessage::TopUp(msg) => msg.version(),
|
ClientMessage::TopUp(msg) => msg.version(),
|
||||||
ClientMessage::UpgradeModeCheck(msg) => msg.version(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bytes(&self, reply_to: Recipient) -> Result<SerialisedRequest, Error> {
|
pub fn bytes(&self, reply_to: Recipient) -> Result<(Vec<u8>, u64), Error> {
|
||||||
match self.version() {
|
match self.version() {
|
||||||
AuthenticatorVersion::V1 => self.serialise_v1(),
|
AuthenticatorVersion::V1 => Err(Error::UnsupportedVersion),
|
||||||
AuthenticatorVersion::V2 => self.serialise_v2(reply_to),
|
AuthenticatorVersion::V2 => {
|
||||||
AuthenticatorVersion::V3 => self.serialise_v3(reply_to),
|
use v2::{
|
||||||
AuthenticatorVersion::V4 => self.serialise_v4(reply_to),
|
registration::{ClientMac, FinalMessage, GatewayClient, InitMessage},
|
||||||
AuthenticatorVersion::V5 => self.serialise_v5(),
|
request::AuthenticatorRequest,
|
||||||
AuthenticatorVersion::V6 => self.serialise_v6(),
|
};
|
||||||
|
match self {
|
||||||
|
ClientMessage::Initial(init_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_initial_request(
|
||||||
|
InitMessage {
|
||||||
|
pub_key: init_message.pub_key(),
|
||||||
|
},
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
ClientMessage::Final(final_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_final_request(
|
||||||
|
FinalMessage {
|
||||||
|
gateway_client: GatewayClient {
|
||||||
|
pub_key: final_message.gateway_client_pub_key(),
|
||||||
|
private_ip: final_message
|
||||||
|
.gateway_client_ipv4()
|
||||||
|
.ok_or(Error::UnsupportedMessage)?
|
||||||
|
.into(),
|
||||||
|
mac: ClientMac::new(final_message.gateway_client_mac()),
|
||||||
|
},
|
||||||
|
credential: final_message.credential(),
|
||||||
|
},
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
ClientMessage::Query(query_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_query_request(
|
||||||
|
query_message.pub_key(),
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
_ => Err(Error::UnsupportedMessage),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AuthenticatorVersion::V3 => {
|
||||||
|
use v3::{
|
||||||
|
registration::{ClientMac, FinalMessage, GatewayClient, InitMessage},
|
||||||
|
request::AuthenticatorRequest,
|
||||||
|
topup::TopUpMessage,
|
||||||
|
};
|
||||||
|
match self {
|
||||||
|
ClientMessage::Initial(init_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_initial_request(
|
||||||
|
InitMessage {
|
||||||
|
pub_key: init_message.pub_key(),
|
||||||
|
},
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
ClientMessage::Final(final_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_final_request(
|
||||||
|
FinalMessage {
|
||||||
|
gateway_client: GatewayClient {
|
||||||
|
pub_key: final_message.gateway_client_pub_key(),
|
||||||
|
private_ip: final_message
|
||||||
|
.gateway_client_ipv4()
|
||||||
|
.ok_or(Error::UnsupportedMessage)?
|
||||||
|
.into(),
|
||||||
|
mac: ClientMac::new(final_message.gateway_client_mac()),
|
||||||
|
},
|
||||||
|
credential: final_message.credential(),
|
||||||
|
},
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
ClientMessage::Query(query_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_query_request(
|
||||||
|
query_message.pub_key(),
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
ClientMessage::TopUp(top_up_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_topup_request(
|
||||||
|
TopUpMessage {
|
||||||
|
pub_key: top_up_message.pub_key(),
|
||||||
|
credential: top_up_message.credential(),
|
||||||
|
},
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AuthenticatorVersion::V4 => {
|
||||||
|
use v4::{
|
||||||
|
registration::{ClientMac, FinalMessage, GatewayClient, InitMessage},
|
||||||
|
request::AuthenticatorRequest,
|
||||||
|
topup::TopUpMessage,
|
||||||
|
};
|
||||||
|
match self {
|
||||||
|
ClientMessage::Initial(init_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_initial_request(
|
||||||
|
InitMessage {
|
||||||
|
pub_key: init_message.pub_key(),
|
||||||
|
},
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
ClientMessage::Final(final_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_final_request(
|
||||||
|
FinalMessage {
|
||||||
|
gateway_client: GatewayClient {
|
||||||
|
pub_key: final_message.gateway_client_pub_key(),
|
||||||
|
private_ips: IpPair {
|
||||||
|
ipv4: final_message
|
||||||
|
.gateway_client_ipv4()
|
||||||
|
.ok_or(Error::UnsupportedMessage)?,
|
||||||
|
ipv6: final_message
|
||||||
|
.gateway_client_ipv6()
|
||||||
|
.ok_or(Error::UnsupportedMessage)?,
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
mac: ClientMac::new(final_message.gateway_client_mac()),
|
||||||
|
},
|
||||||
|
credential: final_message.credential(),
|
||||||
|
},
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
ClientMessage::Query(query_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_query_request(
|
||||||
|
query_message.pub_key(),
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
ClientMessage::TopUp(top_up_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_topup_request(
|
||||||
|
TopUpMessage {
|
||||||
|
pub_key: top_up_message.pub_key(),
|
||||||
|
credential: top_up_message.credential(),
|
||||||
|
},
|
||||||
|
reply_to,
|
||||||
|
);
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AuthenticatorVersion::V5 => {
|
||||||
|
use v5::{
|
||||||
|
registration::{ClientMac, FinalMessage, GatewayClient, InitMessage},
|
||||||
|
request::AuthenticatorRequest,
|
||||||
|
topup::TopUpMessage,
|
||||||
|
};
|
||||||
|
match self {
|
||||||
|
ClientMessage::Initial(init_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_initial_request(InitMessage {
|
||||||
|
pub_key: init_message.pub_key(),
|
||||||
|
});
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
ClientMessage::Final(final_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_final_request(FinalMessage {
|
||||||
|
gateway_client: GatewayClient {
|
||||||
|
pub_key: final_message.gateway_client_pub_key(),
|
||||||
|
private_ips: IpPair {
|
||||||
|
ipv4: final_message
|
||||||
|
.gateway_client_ipv4()
|
||||||
|
.ok_or(Error::UnsupportedMessage)?,
|
||||||
|
ipv6: final_message
|
||||||
|
.gateway_client_ipv6()
|
||||||
|
.ok_or(Error::UnsupportedMessage)?,
|
||||||
|
},
|
||||||
|
mac: ClientMac::new(final_message.gateway_client_mac()),
|
||||||
|
},
|
||||||
|
credential: final_message.credential(),
|
||||||
|
});
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
ClientMessage::Query(query_message) => {
|
||||||
|
let (req, id) =
|
||||||
|
AuthenticatorRequest::new_query_request(query_message.pub_key());
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
ClientMessage::TopUp(top_up_message) => {
|
||||||
|
let (req, id) = AuthenticatorRequest::new_topup_request(TopUpMessage {
|
||||||
|
pub_key: top_up_message.pub_key(),
|
||||||
|
credential: top_up_message.credential(),
|
||||||
|
});
|
||||||
|
Ok((req.to_bytes()?, id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
AuthenticatorVersion::UNKNOWN => Err(Error::UnknownVersion),
|
AuthenticatorVersion::UNKNOWN => Err(Error::UnknownVersion),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,7 +247,7 @@ impl ClientMessage {
|
|||||||
use AuthenticatorVersion::*;
|
use AuthenticatorVersion::*;
|
||||||
match self.version() {
|
match self.version() {
|
||||||
V1 | V2 | V3 | V4 => false,
|
V1 | V2 | V3 | V4 => false,
|
||||||
V5 | V6 => true,
|
V5 => true,
|
||||||
UNKNOWN => true,
|
UNKNOWN => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use std::fmt::Display;
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
@@ -38,13 +37,3 @@ pub enum Error {
|
|||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Bincode(#[from] bincode::Error),
|
Bincode(#[from] bincode::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
|
||||||
pub fn conversion(msg: impl Into<String>) -> Self {
|
|
||||||
Error::Conversion(msg.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn conversion_display(msg: impl Display) -> Self {
|
|
||||||
Error::Conversion(msg.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
pub mod client_message;
|
pub mod client_message;
|
||||||
pub mod models;
|
|
||||||
pub mod request;
|
pub mod request;
|
||||||
pub mod response;
|
pub mod response;
|
||||||
pub mod traits;
|
pub mod traits;
|
||||||
@@ -11,14 +10,13 @@ pub mod v2;
|
|||||||
pub mod v3;
|
pub mod v3;
|
||||||
pub mod v4;
|
pub mod v4;
|
||||||
pub mod v5;
|
pub mod v5;
|
||||||
pub mod v6;
|
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
mod util;
|
mod util;
|
||||||
mod version;
|
mod version;
|
||||||
|
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
pub use v6 as latest;
|
pub use v5 as latest;
|
||||||
pub use version::AuthenticatorVersion;
|
pub use version::AuthenticatorVersion;
|
||||||
|
|
||||||
pub const CURRENT_VERSION: u8 = latest::VERSION;
|
pub const CURRENT_VERSION: u8 = latest::VERSION;
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use nym_credentials_interface::{
|
|
||||||
BandwidthCredential, CredentialSpendingData, TicketType, UnknownTicketType,
|
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
|
|
||||||
pub enum CurrentUpgradeModeStatus {
|
|
||||||
Enabled,
|
|
||||||
Disabled,
|
|
||||||
// everything pre-v6
|
|
||||||
Unknown,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CurrentUpgradeModeStatus {
|
|
||||||
pub fn is_enabled(&self) -> bool {
|
|
||||||
matches!(self, CurrentUpgradeModeStatus::Enabled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<bool> for CurrentUpgradeModeStatus {
|
|
||||||
fn from(value: bool) -> Self {
|
|
||||||
if value {
|
|
||||||
CurrentUpgradeModeStatus::Enabled
|
|
||||||
} else {
|
|
||||||
CurrentUpgradeModeStatus::Disabled
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<CurrentUpgradeModeStatus> for Option<bool> {
|
|
||||||
fn from(value: CurrentUpgradeModeStatus) -> Self {
|
|
||||||
match value {
|
|
||||||
CurrentUpgradeModeStatus::Enabled => Some(true),
|
|
||||||
CurrentUpgradeModeStatus::Disabled => Some(false),
|
|
||||||
CurrentUpgradeModeStatus::Unknown => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
|
||||||
pub struct BandwidthClaim {
|
|
||||||
pub credential: BandwidthCredential,
|
|
||||||
pub kind: TicketType,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<CredentialSpendingData> for BandwidthClaim {
|
|
||||||
type Error = UnknownTicketType;
|
|
||||||
|
|
||||||
fn try_from(credential: CredentialSpendingData) -> Result<Self, Self::Error> {
|
|
||||||
Ok(BandwidthClaim {
|
|
||||||
kind: TicketType::try_from_encoded(credential.payment.t_type)?,
|
|
||||||
credential: BandwidthCredential::from(credential),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,10 +4,8 @@
|
|||||||
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
||||||
use nym_sphinx::addressing::Recipient;
|
use nym_sphinx::addressing::Recipient;
|
||||||
|
|
||||||
use crate::traits::{
|
use crate::traits::{FinalMessage, InitMessage, QueryBandwidthMessage, TopUpMessage};
|
||||||
FinalMessage, InitMessage, QueryBandwidthMessage, TopUpMessage, UpgradeModeMessage,
|
use crate::{v1, v2, v3, v4, v5};
|
||||||
};
|
|
||||||
use crate::{v1, v2, v3, v4, v5, v6};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AuthenticatorRequest {
|
pub enum AuthenticatorRequest {
|
||||||
@@ -35,11 +33,6 @@ pub enum AuthenticatorRequest {
|
|||||||
reply_to: Option<Recipient>,
|
reply_to: Option<Recipient>,
|
||||||
request_id: u64,
|
request_id: u64,
|
||||||
},
|
},
|
||||||
CheckUpgradeMode {
|
|
||||||
msg: Box<dyn UpgradeModeMessage + Send + Sync + 'static>,
|
|
||||||
protocol: Protocol,
|
|
||||||
request_id: u64,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v1::request::AuthenticatorRequest> for AuthenticatorRequest {
|
impl From<v1::request::AuthenticatorRequest> for AuthenticatorRequest {
|
||||||
@@ -209,45 +202,3 @@ impl From<v5::request::AuthenticatorRequest> for AuthenticatorRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v6::request::AuthenticatorRequest> for AuthenticatorRequest {
|
|
||||||
fn from(value: v6::request::AuthenticatorRequest) -> Self {
|
|
||||||
match value.data {
|
|
||||||
v6::request::AuthenticatorRequestData::Initial(init_message) => Self::Initial {
|
|
||||||
msg: Box::new(init_message),
|
|
||||||
protocol: value.protocol,
|
|
||||||
reply_to: None,
|
|
||||||
request_id: value.request_id,
|
|
||||||
},
|
|
||||||
v6::request::AuthenticatorRequestData::Final(final_message) => Self::Final {
|
|
||||||
msg: final_message,
|
|
||||||
protocol: value.protocol,
|
|
||||||
reply_to: None,
|
|
||||||
request_id: value.request_id,
|
|
||||||
},
|
|
||||||
v6::request::AuthenticatorRequestData::QueryBandwidth(peer_public_key) => {
|
|
||||||
Self::QueryBandwidth {
|
|
||||||
msg: Box::new(peer_public_key),
|
|
||||||
protocol: value.protocol,
|
|
||||||
reply_to: None,
|
|
||||||
request_id: value.request_id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v6::request::AuthenticatorRequestData::TopUpBandwidth(top_up_message) => {
|
|
||||||
Self::TopUpBandwidth {
|
|
||||||
msg: top_up_message,
|
|
||||||
protocol: value.protocol,
|
|
||||||
reply_to: None,
|
|
||||||
request_id: value.request_id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v6::request::AuthenticatorRequestData::CheckUpgradeMode(upgrade_mode_check_msg) => {
|
|
||||||
Self::CheckUpgradeMode {
|
|
||||||
msg: Box::new(upgrade_mode_check_msg),
|
|
||||||
protocol: value.protocol,
|
|
||||||
request_id: value.request_id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::models::CurrentUpgradeModeStatus;
|
|
||||||
use crate::traits::{
|
use crate::traits::{
|
||||||
Id, PendingRegistrationResponse, RegisteredResponse, RemainingBandwidthResponse,
|
Id, PendingRegistrationResponse, RegisteredResponse, RemainingBandwidthResponse,
|
||||||
TopUpBandwidthResponse, UpgradeModeStatus,
|
TopUpBandwidthResponse,
|
||||||
};
|
};
|
||||||
use crate::{v2, v3, v4, v5, v6};
|
use crate::{v2, v3, v4, v5};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AuthenticatorResponse {
|
pub enum AuthenticatorResponse {
|
||||||
@@ -14,29 +13,6 @@ pub enum AuthenticatorResponse {
|
|||||||
Registered(Box<dyn RegisteredResponse + Send + Sync + 'static>),
|
Registered(Box<dyn RegisteredResponse + Send + Sync + 'static>),
|
||||||
RemainingBandwidth(Box<dyn RemainingBandwidthResponse + Send + Sync + 'static>),
|
RemainingBandwidth(Box<dyn RemainingBandwidthResponse + Send + Sync + 'static>),
|
||||||
TopUpBandwidth(Box<dyn TopUpBandwidthResponse + Send + Sync + 'static>),
|
TopUpBandwidth(Box<dyn TopUpBandwidthResponse + Send + Sync + 'static>),
|
||||||
UpgradeMode(Box<dyn UpgradeModeStatus + Send + Sync + 'static>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for AuthenticatorResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
match self {
|
|
||||||
AuthenticatorResponse::PendingRegistration(pending_registration_response) => {
|
|
||||||
pending_registration_response.upgrade_mode_status()
|
|
||||||
}
|
|
||||||
AuthenticatorResponse::Registered(registered_response) => {
|
|
||||||
registered_response.upgrade_mode_status()
|
|
||||||
}
|
|
||||||
AuthenticatorResponse::RemainingBandwidth(remaining_bandwidth_response) => {
|
|
||||||
remaining_bandwidth_response.upgrade_mode_status()
|
|
||||||
}
|
|
||||||
AuthenticatorResponse::TopUpBandwidth(top_up_bandwidth_response) => {
|
|
||||||
top_up_bandwidth_response.upgrade_mode_status()
|
|
||||||
}
|
|
||||||
AuthenticatorResponse::UpgradeMode(upgrade_mode_response) => {
|
|
||||||
upgrade_mode_response.upgrade_mode_status()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Id for AuthenticatorResponse {
|
impl Id for AuthenticatorResponse {
|
||||||
@@ -52,7 +28,6 @@ impl Id for AuthenticatorResponse {
|
|||||||
AuthenticatorResponse::TopUpBandwidth(top_up_bandwidth_response) => {
|
AuthenticatorResponse::TopUpBandwidth(top_up_bandwidth_response) => {
|
||||||
top_up_bandwidth_response.id()
|
top_up_bandwidth_response.id()
|
||||||
}
|
}
|
||||||
AuthenticatorResponse::UpgradeMode(upgrade_mode_response) => upgrade_mode_response.id(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,25 +104,3 @@ impl From<v5::response::AuthenticatorResponse> for AuthenticatorResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v6::response::AuthenticatorResponse> for AuthenticatorResponse {
|
|
||||||
fn from(value: v6::response::AuthenticatorResponse) -> Self {
|
|
||||||
match value.data {
|
|
||||||
v6::response::AuthenticatorResponseData::PendingRegistration(
|
|
||||||
pending_registration_response,
|
|
||||||
) => Self::PendingRegistration(Box::new(pending_registration_response)),
|
|
||||||
v6::response::AuthenticatorResponseData::Registered(registered_response) => {
|
|
||||||
Self::Registered(Box::new(registered_response))
|
|
||||||
}
|
|
||||||
v6::response::AuthenticatorResponseData::RemainingBandwidth(
|
|
||||||
remaining_bandwidth_response,
|
|
||||||
) => Self::RemainingBandwidth(Box::new(remaining_bandwidth_response)),
|
|
||||||
v6::response::AuthenticatorResponseData::TopUpBandwidth(top_up_bandwidth_response) => {
|
|
||||||
Self::TopUpBandwidth(Box::new(top_up_bandwidth_response))
|
|
||||||
}
|
|
||||||
v6::response::AuthenticatorResponseData::UpgradeMode(upgrade_mode_check_response) => {
|
|
||||||
Self::UpgradeMode(Box::new(upgrade_mode_check_response))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::latest::registration::IpPair;
|
|
||||||
use crate::models::{BandwidthClaim, CurrentUpgradeModeStatus};
|
|
||||||
use crate::{AuthenticatorVersion, Error, v1, v2, v3, v4, v5, v6};
|
|
||||||
use nym_credentials_interface::CredentialSpendingData;
|
|
||||||
use nym_crypto::asymmetric::x25519;
|
|
||||||
use nym_wireguard_types::PeerPublicKey;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||||
use tracing::error;
|
|
||||||
|
use nym_credentials_interface::CredentialSpendingData;
|
||||||
|
use nym_crypto::asymmetric::x25519::PrivateKey;
|
||||||
|
use nym_wireguard_types::PeerPublicKey;
|
||||||
|
|
||||||
|
use crate::latest::registration::IpPair;
|
||||||
|
use crate::{AuthenticatorVersion, Error, v1, v2, v3, v4, v5};
|
||||||
|
|
||||||
pub trait Versionable {
|
pub trait Versionable {
|
||||||
fn version(&self) -> AuthenticatorVersion;
|
fn version(&self) -> AuthenticatorVersion;
|
||||||
@@ -51,12 +51,6 @@ impl Versionable for v5::registration::InitMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Versionable for v6::registration::InitMessage {
|
|
||||||
fn version(&self) -> AuthenticatorVersion {
|
|
||||||
AuthenticatorVersion::V6
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Versionable for v2::registration::FinalMessage {
|
impl Versionable for v2::registration::FinalMessage {
|
||||||
fn version(&self) -> AuthenticatorVersion {
|
fn version(&self) -> AuthenticatorVersion {
|
||||||
AuthenticatorVersion::V2
|
AuthenticatorVersion::V2
|
||||||
@@ -81,12 +75,6 @@ impl Versionable for v5::registration::FinalMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Versionable for v6::registration::FinalMessage {
|
|
||||||
fn version(&self) -> AuthenticatorVersion {
|
|
||||||
AuthenticatorVersion::V6
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Versionable for PeerPublicKey {
|
impl Versionable for PeerPublicKey {
|
||||||
fn version(&self) -> AuthenticatorVersion {
|
fn version(&self) -> AuthenticatorVersion {
|
||||||
AuthenticatorVersion::V3
|
AuthenticatorVersion::V3
|
||||||
@@ -110,158 +98,6 @@ impl Versionable for v5::topup::TopUpMessage {
|
|||||||
AuthenticatorVersion::V5
|
AuthenticatorVersion::V5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Versionable for v6::topup::TopUpMessage {
|
|
||||||
fn version(&self) -> AuthenticatorVersion {
|
|
||||||
AuthenticatorVersion::V6
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Versionable for v6::upgrade_mode_check::UpgradeModeCheckRequest {
|
|
||||||
fn version(&self) -> AuthenticatorVersion {
|
|
||||||
AuthenticatorVersion::V6
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait UpgradeModeStatus: Id + fmt::Debug {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v1::response::PendingRegistrationResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v1::response::RegisteredResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v1::response::RemainingBandwidthResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v2::response::PendingRegistrationResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v2::response::RegisteredResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v2::response::RemainingBandwidthResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl UpgradeModeStatus for v3::response::PendingRegistrationResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v3::response::RegisteredResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v3::response::RemainingBandwidthResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v3::response::TopUpBandwidthResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v4::response::PendingRegistrationResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v4::response::RegisteredResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v4::response::RemainingBandwidthResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v4::response::TopUpBandwidthResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v5::response::PendingRegistrationResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v5::response::RegisteredResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v5::response::RemainingBandwidthResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v5::response::TopUpBandwidthResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
CurrentUpgradeModeStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v6::response::PendingRegistrationResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
self.upgrade_mode_enabled.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v6::response::RegisteredResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
self.upgrade_mode_enabled.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v6::response::RemainingBandwidthResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
self.upgrade_mode_enabled.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v6::response::TopUpBandwidthResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
self.upgrade_mode_enabled.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeStatus for v6::response::UpgradeModeResponse {
|
|
||||||
fn upgrade_mode_status(&self) -> CurrentUpgradeModeStatus {
|
|
||||||
self.upgrade_mode_enabled.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait InitMessage: Versionable + fmt::Debug {
|
pub trait InitMessage: Versionable + fmt::Debug {
|
||||||
fn pub_key(&self) -> PeerPublicKey;
|
fn pub_key(&self) -> PeerPublicKey;
|
||||||
@@ -297,20 +133,14 @@ impl InitMessage for v5::registration::InitMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InitMessage for v6::registration::InitMessage {
|
|
||||||
fn pub_key(&self) -> PeerPublicKey {
|
|
||||||
self.pub_key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait FinalMessage: Versionable + fmt::Debug {
|
pub trait FinalMessage: Versionable + fmt::Debug {
|
||||||
fn gateway_client_pub_key(&self) -> PeerPublicKey;
|
fn gateway_client_pub_key(&self) -> PeerPublicKey;
|
||||||
fn verify(&self, private_key: &x25519::PrivateKey, nonce: u64) -> Result<(), Error>;
|
fn verify(&self, private_key: &PrivateKey, nonce: u64) -> Result<(), Error>;
|
||||||
fn private_ips(&self) -> IpPair;
|
fn private_ips(&self) -> IpPair;
|
||||||
fn gateway_client_ipv4(&self) -> Option<Ipv4Addr>;
|
fn gateway_client_ipv4(&self) -> Option<Ipv4Addr>;
|
||||||
fn gateway_client_ipv6(&self) -> Option<Ipv6Addr>;
|
fn gateway_client_ipv6(&self) -> Option<Ipv6Addr>;
|
||||||
fn gateway_client_mac(&self) -> Vec<u8>;
|
fn gateway_client_mac(&self) -> Vec<u8>;
|
||||||
fn credential(&self) -> Option<BandwidthClaim>;
|
fn credential(&self) -> Option<CredentialSpendingData>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FinalMessage for v1::GatewayClient {
|
impl FinalMessage for v1::GatewayClient {
|
||||||
@@ -318,7 +148,7 @@ impl FinalMessage for v1::GatewayClient {
|
|||||||
self.pub_key
|
self.pub_key
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(&self, private_key: &x25519::PrivateKey, nonce: u64) -> Result<(), Error> {
|
fn verify(&self, private_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
||||||
self.verify(private_key, nonce)
|
self.verify(private_key, nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,7 +171,7 @@ impl FinalMessage for v1::GatewayClient {
|
|||||||
self.mac.to_vec()
|
self.mac.to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn credential(&self) -> Option<BandwidthClaim> {
|
fn credential(&self) -> Option<CredentialSpendingData> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -351,7 +181,7 @@ impl FinalMessage for v2::registration::FinalMessage {
|
|||||||
self.gateway_client.pub_key
|
self.gateway_client.pub_key
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(&self, private_key: &x25519::PrivateKey, nonce: u64) -> Result<(), Error> {
|
fn verify(&self, private_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
||||||
self.gateway_client.verify(private_key, nonce)
|
self.gateway_client.verify(private_key, nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,12 +204,8 @@ impl FinalMessage for v2::registration::FinalMessage {
|
|||||||
self.gateway_client.mac.to_vec()
|
self.gateway_client.mac.to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn credential(&self) -> Option<BandwidthClaim> {
|
fn credential(&self) -> Option<CredentialSpendingData> {
|
||||||
self.credential.clone().and_then(|c| {
|
self.credential.clone()
|
||||||
c.try_into()
|
|
||||||
.inspect_err(|err| error!("credential conversion error: {err}"))
|
|
||||||
.ok()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,7 +214,7 @@ impl FinalMessage for v3::registration::FinalMessage {
|
|||||||
self.gateway_client.pub_key
|
self.gateway_client.pub_key
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(&self, private_key: &x25519::PrivateKey, nonce: u64) -> Result<(), Error> {
|
fn verify(&self, private_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
||||||
self.gateway_client.verify(private_key, nonce)
|
self.gateway_client.verify(private_key, nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,12 +237,8 @@ impl FinalMessage for v3::registration::FinalMessage {
|
|||||||
self.gateway_client.mac.to_vec()
|
self.gateway_client.mac.to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn credential(&self) -> Option<BandwidthClaim> {
|
fn credential(&self) -> Option<CredentialSpendingData> {
|
||||||
self.credential.clone().and_then(|c| {
|
self.credential.clone()
|
||||||
c.try_into()
|
|
||||||
.inspect_err(|err| error!("credential conversion error: {err}"))
|
|
||||||
.ok()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,42 +247,7 @@ impl FinalMessage for v4::registration::FinalMessage {
|
|||||||
self.gateway_client.pub_key
|
self.gateway_client.pub_key
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(&self, private_key: &x25519::PrivateKey, nonce: u64) -> Result<(), Error> {
|
fn verify(&self, private_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
||||||
self.gateway_client.verify(private_key, nonce)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn private_ips(&self) -> IpPair {
|
|
||||||
// v4 -> v5 -> v6
|
|
||||||
v5::registration::IpPair::from(self.gateway_client.private_ips).into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gateway_client_ipv4(&self) -> Option<Ipv4Addr> {
|
|
||||||
Some(self.gateway_client.private_ips.ipv4)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gateway_client_ipv6(&self) -> Option<Ipv6Addr> {
|
|
||||||
Some(self.gateway_client.private_ips.ipv6)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gateway_client_mac(&self) -> Vec<u8> {
|
|
||||||
self.gateway_client.mac.to_vec()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn credential(&self) -> Option<BandwidthClaim> {
|
|
||||||
self.credential.clone().and_then(|c| {
|
|
||||||
c.try_into()
|
|
||||||
.inspect_err(|err| error!("credential conversion error: {err}"))
|
|
||||||
.ok()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FinalMessage for v5::registration::FinalMessage {
|
|
||||||
fn gateway_client_pub_key(&self) -> PeerPublicKey {
|
|
||||||
self.gateway_client.pub_key
|
|
||||||
}
|
|
||||||
|
|
||||||
fn verify(&self, private_key: &x25519::PrivateKey, nonce: u64) -> Result<(), Error> {
|
|
||||||
self.gateway_client.verify(private_key, nonce)
|
self.gateway_client.verify(private_key, nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,21 +267,17 @@ impl FinalMessage for v5::registration::FinalMessage {
|
|||||||
self.gateway_client.mac.to_vec()
|
self.gateway_client.mac.to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn credential(&self) -> Option<BandwidthClaim> {
|
fn credential(&self) -> Option<CredentialSpendingData> {
|
||||||
self.credential.clone().and_then(|c| {
|
self.credential.clone()
|
||||||
c.try_into()
|
|
||||||
.inspect_err(|err| error!("credential conversion error: {err}"))
|
|
||||||
.ok()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FinalMessage for v6::registration::FinalMessage {
|
impl FinalMessage for v5::registration::FinalMessage {
|
||||||
fn gateway_client_pub_key(&self) -> PeerPublicKey {
|
fn gateway_client_pub_key(&self) -> PeerPublicKey {
|
||||||
self.gateway_client.pub_key
|
self.gateway_client.pub_key
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(&self, private_key: &x25519::PrivateKey, nonce: u64) -> Result<(), Error> {
|
fn verify(&self, private_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
||||||
self.gateway_client.verify(private_key, nonce)
|
self.gateway_client.verify(private_key, nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,7 +297,7 @@ impl FinalMessage for v6::registration::FinalMessage {
|
|||||||
self.gateway_client.mac.to_vec()
|
self.gateway_client.mac.to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn credential(&self) -> Option<BandwidthClaim> {
|
fn credential(&self) -> Option<CredentialSpendingData> {
|
||||||
self.credential.clone()
|
self.credential.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -564,42 +347,10 @@ impl TopUpMessage for v5::topup::TopUpMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TopUpMessage for v6::topup::TopUpMessage {
|
|
||||||
fn pub_key(&self) -> PeerPublicKey {
|
|
||||||
self.pub_key
|
|
||||||
}
|
|
||||||
|
|
||||||
fn credential(&self) -> CredentialSpendingData {
|
|
||||||
self.credential.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait UpgradeModeMessage: Versionable + fmt::Debug {
|
|
||||||
// the idea is to expose different types of emergency credentials here,
|
|
||||||
// like upgrade mode JWT, emergency threshold credential issued by signers, etc.
|
|
||||||
fn upgrade_mode_global_attestation_jwt(&self) -> Option<String>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpgradeModeMessage for v6::upgrade_mode_check::UpgradeModeCheckRequest {
|
|
||||||
fn upgrade_mode_global_attestation_jwt(&self) -> Option<String> {
|
|
||||||
use v6::upgrade_mode_check::UpgradeModeCheckRequest;
|
|
||||||
|
|
||||||
match self {
|
|
||||||
UpgradeModeCheckRequest::UpgradeModeJwt { token } => Some(token.clone()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Id {
|
pub trait Id {
|
||||||
fn id(&self) -> u64;
|
fn id(&self) -> u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Id for v1::response::PendingRegistrationResponse {
|
|
||||||
fn id(&self) -> u64 {
|
|
||||||
self.request_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Id for v2::response::PendingRegistrationResponse {
|
impl Id for v2::response::PendingRegistrationResponse {
|
||||||
fn id(&self) -> u64 {
|
fn id(&self) -> u64 {
|
||||||
self.request_id
|
self.request_id
|
||||||
@@ -624,18 +375,6 @@ impl Id for v5::response::PendingRegistrationResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Id for v6::response::PendingRegistrationResponse {
|
|
||||||
fn id(&self) -> u64 {
|
|
||||||
self.request_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Id for v1::response::RegisteredResponse {
|
|
||||||
fn id(&self) -> u64 {
|
|
||||||
self.request_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Id for v2::response::RegisteredResponse {
|
impl Id for v2::response::RegisteredResponse {
|
||||||
fn id(&self) -> u64 {
|
fn id(&self) -> u64 {
|
||||||
self.request_id
|
self.request_id
|
||||||
@@ -660,18 +399,6 @@ impl Id for v5::response::RegisteredResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Id for v6::response::RegisteredResponse {
|
|
||||||
fn id(&self) -> u64 {
|
|
||||||
self.request_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Id for v1::response::RemainingBandwidthResponse {
|
|
||||||
fn id(&self) -> u64 {
|
|
||||||
self.request_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Id for v2::response::RemainingBandwidthResponse {
|
impl Id for v2::response::RemainingBandwidthResponse {
|
||||||
fn id(&self) -> u64 {
|
fn id(&self) -> u64 {
|
||||||
self.request_id
|
self.request_id
|
||||||
@@ -696,12 +423,6 @@ impl Id for v5::response::RemainingBandwidthResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Id for v6::response::RemainingBandwidthResponse {
|
|
||||||
fn id(&self) -> u64 {
|
|
||||||
self.request_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Id for v3::response::TopUpBandwidthResponse {
|
impl Id for v3::response::TopUpBandwidthResponse {
|
||||||
fn id(&self) -> u64 {
|
fn id(&self) -> u64 {
|
||||||
self.request_id
|
self.request_id
|
||||||
@@ -720,28 +441,11 @@ impl Id for v5::response::TopUpBandwidthResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Id for v6::response::TopUpBandwidthResponse {
|
pub trait PendingRegistrationResponse: Id + fmt::Debug {
|
||||||
fn id(&self) -> u64 {
|
|
||||||
self.request_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Id for v6::response::UpgradeModeResponse {
|
|
||||||
fn id(&self) -> u64 {
|
|
||||||
self.request_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait PendingRegistrationResponse: Id + UpgradeModeStatus + fmt::Debug {
|
|
||||||
fn nonce(&self) -> u64;
|
fn nonce(&self) -> u64;
|
||||||
fn verify(&self, gateway_key: &x25519::PrivateKey) -> Result<(), Error>;
|
fn verify(&self, gateway_key: &PrivateKey) -> std::result::Result<(), Error>;
|
||||||
fn pub_key(&self) -> PeerPublicKey;
|
fn pub_key(&self) -> PeerPublicKey;
|
||||||
fn private_ips(&self) -> IpPair;
|
fn private_ips(&self) -> IpPair;
|
||||||
fn finalise_registration(
|
|
||||||
&self,
|
|
||||||
private_key: &x25519::PrivateKey,
|
|
||||||
credential: Option<BandwidthClaim>,
|
|
||||||
) -> Box<dyn FinalMessage + Send + Sync>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PendingRegistrationResponse for v2::response::PendingRegistrationResponse {
|
impl PendingRegistrationResponse for v2::response::PendingRegistrationResponse {
|
||||||
@@ -749,7 +453,7 @@ impl PendingRegistrationResponse for v2::response::PendingRegistrationResponse {
|
|||||||
self.reply.nonce
|
self.reply.nonce
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(&self, gateway_key: &x25519::PrivateKey) -> Result<(), Error> {
|
fn verify(&self, gateway_key: &PrivateKey) -> std::result::Result<(), Error> {
|
||||||
self.reply.gateway_data.verify(gateway_key, self.nonce())
|
self.reply.gateway_data.verify(gateway_key, self.nonce())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -760,22 +464,6 @@ impl PendingRegistrationResponse for v2::response::PendingRegistrationResponse {
|
|||||||
fn private_ips(&self) -> IpPair {
|
fn private_ips(&self) -> IpPair {
|
||||||
self.reply.gateway_data.private_ip.into()
|
self.reply.gateway_data.private_ip.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finalise_registration(
|
|
||||||
&self,
|
|
||||||
private_key: &x25519::PrivateKey,
|
|
||||||
credential: Option<BandwidthClaim>,
|
|
||||||
) -> Box<dyn FinalMessage + Send + Sync> {
|
|
||||||
Box::new(v2::registration::FinalMessage {
|
|
||||||
gateway_client: v2::registration::GatewayClient::new(
|
|
||||||
private_key,
|
|
||||||
self.pub_key().inner(),
|
|
||||||
self.private_ips().ipv4.into(),
|
|
||||||
self.nonce(),
|
|
||||||
),
|
|
||||||
credential: credential.and_then(|b| b.credential.into_zk_nym().map(|c| *c)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PendingRegistrationResponse for v3::response::PendingRegistrationResponse {
|
impl PendingRegistrationResponse for v3::response::PendingRegistrationResponse {
|
||||||
@@ -783,7 +471,7 @@ impl PendingRegistrationResponse for v3::response::PendingRegistrationResponse {
|
|||||||
self.reply.nonce
|
self.reply.nonce
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(&self, gateway_key: &x25519::PrivateKey) -> Result<(), Error> {
|
fn verify(&self, gateway_key: &PrivateKey) -> std::result::Result<(), Error> {
|
||||||
self.reply.gateway_data.verify(gateway_key, self.nonce())
|
self.reply.gateway_data.verify(gateway_key, self.nonce())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -794,22 +482,6 @@ impl PendingRegistrationResponse for v3::response::PendingRegistrationResponse {
|
|||||||
fn private_ips(&self) -> IpPair {
|
fn private_ips(&self) -> IpPair {
|
||||||
self.reply.gateway_data.private_ip.into()
|
self.reply.gateway_data.private_ip.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finalise_registration(
|
|
||||||
&self,
|
|
||||||
private_key: &x25519::PrivateKey,
|
|
||||||
credential: Option<BandwidthClaim>,
|
|
||||||
) -> Box<dyn FinalMessage + Send + Sync> {
|
|
||||||
Box::new(v3::registration::FinalMessage {
|
|
||||||
gateway_client: v3::registration::GatewayClient::new(
|
|
||||||
private_key,
|
|
||||||
self.pub_key().inner(),
|
|
||||||
self.private_ips().ipv4.into(),
|
|
||||||
self.nonce(),
|
|
||||||
),
|
|
||||||
credential: credential.and_then(|b| b.credential.into_zk_nym().map(|c| *c)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PendingRegistrationResponse for v4::response::PendingRegistrationResponse {
|
impl PendingRegistrationResponse for v4::response::PendingRegistrationResponse {
|
||||||
@@ -817,42 +489,7 @@ impl PendingRegistrationResponse for v4::response::PendingRegistrationResponse {
|
|||||||
self.reply.nonce
|
self.reply.nonce
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(&self, gateway_key: &x25519::PrivateKey) -> Result<(), Error> {
|
fn verify(&self, gateway_key: &PrivateKey) -> std::result::Result<(), Error> {
|
||||||
self.reply.gateway_data.verify(gateway_key, self.nonce())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pub_key(&self) -> PeerPublicKey {
|
|
||||||
self.reply.gateway_data.pub_key
|
|
||||||
}
|
|
||||||
|
|
||||||
fn private_ips(&self) -> IpPair {
|
|
||||||
// v4 -> v5 -> v6
|
|
||||||
v5::registration::IpPair::from(self.reply.gateway_data.private_ips).into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn finalise_registration(
|
|
||||||
&self,
|
|
||||||
private_key: &x25519::PrivateKey,
|
|
||||||
credential: Option<BandwidthClaim>,
|
|
||||||
) -> Box<dyn FinalMessage + Send + Sync> {
|
|
||||||
Box::new(v4::registration::FinalMessage {
|
|
||||||
gateway_client: v4::registration::GatewayClient::new(
|
|
||||||
private_key,
|
|
||||||
self.pub_key().inner(),
|
|
||||||
self.reply.gateway_data.private_ips,
|
|
||||||
self.nonce(),
|
|
||||||
),
|
|
||||||
credential: credential.and_then(|b| b.credential.into_zk_nym().map(|c| *c)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PendingRegistrationResponse for v5::response::PendingRegistrationResponse {
|
|
||||||
fn nonce(&self) -> u64 {
|
|
||||||
self.reply.nonce
|
|
||||||
}
|
|
||||||
|
|
||||||
fn verify(&self, gateway_key: &x25519::PrivateKey) -> Result<(), Error> {
|
|
||||||
self.reply.gateway_data.verify(gateway_key, self.nonce())
|
self.reply.gateway_data.verify(gateway_key, self.nonce())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -863,30 +500,14 @@ impl PendingRegistrationResponse for v5::response::PendingRegistrationResponse {
|
|||||||
fn private_ips(&self) -> IpPair {
|
fn private_ips(&self) -> IpPair {
|
||||||
self.reply.gateway_data.private_ips.into()
|
self.reply.gateway_data.private_ips.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finalise_registration(
|
|
||||||
&self,
|
|
||||||
private_key: &x25519::PrivateKey,
|
|
||||||
credential: Option<BandwidthClaim>,
|
|
||||||
) -> Box<dyn FinalMessage + Send + Sync> {
|
|
||||||
Box::new(v5::registration::FinalMessage {
|
|
||||||
gateway_client: v5::registration::GatewayClient::new(
|
|
||||||
private_key,
|
|
||||||
self.pub_key().inner(),
|
|
||||||
self.reply.gateway_data.private_ips,
|
|
||||||
self.nonce(),
|
|
||||||
),
|
|
||||||
credential: credential.and_then(|b| b.credential.into_zk_nym().map(|c| *c)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PendingRegistrationResponse for v6::response::PendingRegistrationResponse {
|
impl PendingRegistrationResponse for v5::response::PendingRegistrationResponse {
|
||||||
fn nonce(&self) -> u64 {
|
fn nonce(&self) -> u64 {
|
||||||
self.reply.nonce
|
self.reply.nonce
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(&self, gateway_key: &x25519::PrivateKey) -> Result<(), Error> {
|
fn verify(&self, gateway_key: &PrivateKey) -> std::result::Result<(), Error> {
|
||||||
self.reply.gateway_data.verify(gateway_key, self.nonce())
|
self.reply.gateway_data.verify(gateway_key, self.nonce())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -897,25 +518,9 @@ impl PendingRegistrationResponse for v6::response::PendingRegistrationResponse {
|
|||||||
fn private_ips(&self) -> IpPair {
|
fn private_ips(&self) -> IpPair {
|
||||||
self.reply.gateway_data.private_ips
|
self.reply.gateway_data.private_ips
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finalise_registration(
|
|
||||||
&self,
|
|
||||||
private_key: &x25519::PrivateKey,
|
|
||||||
credential: Option<BandwidthClaim>,
|
|
||||||
) -> Box<dyn FinalMessage + Send + Sync> {
|
|
||||||
Box::new(v6::registration::FinalMessage {
|
|
||||||
gateway_client: v6::registration::GatewayClient::new(
|
|
||||||
private_key,
|
|
||||||
self.pub_key().inner(),
|
|
||||||
self.reply.gateway_data.private_ips,
|
|
||||||
self.nonce(),
|
|
||||||
),
|
|
||||||
credential,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait RegisteredResponse: Id + UpgradeModeStatus + fmt::Debug {
|
pub trait RegisteredResponse: Id + fmt::Debug {
|
||||||
fn private_ips(&self) -> IpPair;
|
fn private_ips(&self) -> IpPair;
|
||||||
fn pub_key(&self) -> PeerPublicKey;
|
fn pub_key(&self) -> PeerPublicKey;
|
||||||
fn wg_port(&self) -> u16;
|
fn wg_port(&self) -> u16;
|
||||||
@@ -950,8 +555,7 @@ impl RegisteredResponse for v3::response::RegisteredResponse {
|
|||||||
}
|
}
|
||||||
impl RegisteredResponse for v4::response::RegisteredResponse {
|
impl RegisteredResponse for v4::response::RegisteredResponse {
|
||||||
fn private_ips(&self) -> IpPair {
|
fn private_ips(&self) -> IpPair {
|
||||||
// v4 -> v5 -> v6
|
self.reply.private_ips.into()
|
||||||
v5::registration::IpPair::from(self.reply.private_ips).into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pub_key(&self) -> PeerPublicKey {
|
fn pub_key(&self) -> PeerPublicKey {
|
||||||
@@ -964,20 +568,6 @@ impl RegisteredResponse for v4::response::RegisteredResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RegisteredResponse for v5::response::RegisteredResponse {
|
impl RegisteredResponse for v5::response::RegisteredResponse {
|
||||||
fn private_ips(&self) -> IpPair {
|
|
||||||
self.reply.private_ips.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pub_key(&self) -> PeerPublicKey {
|
|
||||||
self.reply.pub_key
|
|
||||||
}
|
|
||||||
|
|
||||||
fn wg_port(&self) -> u16 {
|
|
||||||
self.reply.wg_port
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RegisteredResponse for v6::response::RegisteredResponse {
|
|
||||||
fn private_ips(&self) -> IpPair {
|
fn private_ips(&self) -> IpPair {
|
||||||
self.reply.private_ips
|
self.reply.private_ips
|
||||||
}
|
}
|
||||||
@@ -991,7 +581,7 @@ impl RegisteredResponse for v6::response::RegisteredResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait RemainingBandwidthResponse: Id + UpgradeModeStatus + fmt::Debug {
|
pub trait RemainingBandwidthResponse: Id + fmt::Debug {
|
||||||
fn available_bandwidth(&self) -> Option<i64>;
|
fn available_bandwidth(&self) -> Option<i64>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1019,13 +609,7 @@ impl RemainingBandwidthResponse for v5::response::RemainingBandwidthResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RemainingBandwidthResponse for v6::response::RemainingBandwidthResponse {
|
pub trait TopUpBandwidthResponse: Id + fmt::Debug {
|
||||||
fn available_bandwidth(&self) -> Option<i64> {
|
|
||||||
self.reply.as_ref().map(|r| r.available_bandwidth)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait TopUpBandwidthResponse: Id + UpgradeModeStatus + fmt::Debug {
|
|
||||||
fn available_bandwidth(&self) -> i64;
|
fn available_bandwidth(&self) -> i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1046,9 +630,3 @@ impl TopUpBandwidthResponse for v5::response::TopUpBandwidthResponse {
|
|||||||
self.reply.available_bandwidth
|
self.reply.available_bandwidth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TopUpBandwidthResponse for v6::response::TopUpBandwidthResponse {
|
|
||||||
fn available_bandwidth(&self) -> i64 {
|
|
||||||
self.reply.available_bandwidth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ pub struct RegistrationData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct RegisteredData {
|
pub struct RegistredData {
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
pub private_ip: IpAddr,
|
pub private_ip: IpAddr,
|
||||||
pub wg_port: u16,
|
pub wg_port: u16,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use super::registration::{RegisteredData, RegistrationData, RemainingBandwidthData};
|
use super::registration::{RegistrationData, RegistredData, RemainingBandwidthData};
|
||||||
use nym_sphinx::addressing::Recipient;
|
use nym_sphinx::addressing::Recipient;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ impl AuthenticatorResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_registered(
|
pub fn new_registered(
|
||||||
registred_data: RegisteredData,
|
registred_data: RegistredData,
|
||||||
reply_to: Recipient,
|
reply_to: Recipient,
|
||||||
request_id: u64,
|
request_id: u64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -108,7 +108,7 @@ pub struct PendingRegistrationResponse {
|
|||||||
pub struct RegisteredResponse {
|
pub struct RegisteredResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
pub reply: RegisteredData,
|
pub reply: RegistredData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
|||||||
@@ -154,8 +154,8 @@ impl From<v2::registration::RegistrationData> for v1::registration::Registration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v2::registration::RegisteredData> for v1::registration::RegisteredData {
|
impl From<v2::registration::RegistredData> for v1::registration::RegistredData {
|
||||||
fn from(value: v2::registration::RegisteredData) -> Self {
|
fn from(value: v2::registration::RegistredData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pub_key: value.pub_key,
|
pub_key: value.pub_key,
|
||||||
private_ip: value.private_ip,
|
private_ip: value.private_ip,
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ pub struct RegistrationData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct RegisteredData {
|
pub struct RegistredData {
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
pub private_ip: IpAddr,
|
pub private_ip: IpAddr,
|
||||||
pub wg_port: u16,
|
pub wg_port: u16,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use super::registration::{RegisteredData, RegistrationData, RemainingBandwidthData};
|
use super::registration::{RegistrationData, RegistredData, RemainingBandwidthData};
|
||||||
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
||||||
use nym_sphinx::addressing::Recipient;
|
use nym_sphinx::addressing::Recipient;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -38,7 +38,7 @@ impl AuthenticatorResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_registered(
|
pub fn new_registered(
|
||||||
registred_data: RegisteredData,
|
registred_data: RegistredData,
|
||||||
reply_to: Recipient,
|
reply_to: Recipient,
|
||||||
request_id: u64,
|
request_id: u64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -118,7 +118,7 @@ pub struct PendingRegistrationResponse {
|
|||||||
pub struct RegisteredResponse {
|
pub struct RegisteredResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
pub reply: RegisteredData,
|
pub reply: RegistredData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
|||||||
@@ -299,8 +299,8 @@ impl From<v2::registration::RegistrationData> for v3::registration::Registration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v3::registration::RegisteredData> for v2::registration::RegisteredData {
|
impl From<v3::registration::RegistredData> for v2::registration::RegistredData {
|
||||||
fn from(value: v3::registration::RegisteredData) -> Self {
|
fn from(value: v3::registration::RegistredData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pub_key: value.pub_key,
|
pub_key: value.pub_key,
|
||||||
private_ip: value.private_ip,
|
private_ip: value.private_ip,
|
||||||
@@ -309,8 +309,8 @@ impl From<v3::registration::RegisteredData> for v2::registration::RegisteredData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v2::registration::RegisteredData> for v3::registration::RegisteredData {
|
impl From<v2::registration::RegistredData> for v3::registration::RegistredData {
|
||||||
fn from(value: v2::registration::RegisteredData) -> Self {
|
fn from(value: v2::registration::RegistredData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pub_key: value.pub_key,
|
pub_key: value.pub_key,
|
||||||
private_ip: value.private_ip,
|
private_ip: value.private_ip,
|
||||||
@@ -674,7 +674,7 @@ mod tests {
|
|||||||
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
let private_ip = IpAddr::from_str("10.10.10.10").unwrap();
|
let private_ip = IpAddr::from_str("10.10.10.10").unwrap();
|
||||||
let wg_port = 51822;
|
let wg_port = 51822;
|
||||||
let registred_data = v2::registration::RegisteredData {
|
let registred_data = v2::registration::RegistredData {
|
||||||
pub_key,
|
pub_key,
|
||||||
private_ip,
|
private_ip,
|
||||||
wg_port,
|
wg_port,
|
||||||
@@ -701,7 +701,7 @@ mod tests {
|
|||||||
v3::response::AuthenticatorResponseData::Registered(v3::response::RegisteredResponse {
|
v3::response::AuthenticatorResponseData::Registered(v3::response::RegisteredResponse {
|
||||||
request_id,
|
request_id,
|
||||||
reply_to,
|
reply_to,
|
||||||
reply: v3::registration::RegisteredData {
|
reply: v3::registration::RegistredData {
|
||||||
wg_port,
|
wg_port,
|
||||||
pub_key,
|
pub_key,
|
||||||
private_ip
|
private_ip
|
||||||
@@ -715,7 +715,7 @@ mod tests {
|
|||||||
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
||||||
let private_ip = IpAddr::from_str("10.10.10.10").unwrap();
|
let private_ip = IpAddr::from_str("10.10.10.10").unwrap();
|
||||||
let wg_port = 51822;
|
let wg_port = 51822;
|
||||||
let registred_data = v3::registration::RegisteredData {
|
let registred_data = v3::registration::RegistredData {
|
||||||
pub_key,
|
pub_key,
|
||||||
private_ip,
|
private_ip,
|
||||||
wg_port,
|
wg_port,
|
||||||
@@ -742,7 +742,7 @@ mod tests {
|
|||||||
v2::response::AuthenticatorResponseData::Registered(v2::response::RegisteredResponse {
|
v2::response::AuthenticatorResponseData::Registered(v2::response::RegisteredResponse {
|
||||||
request_id,
|
request_id,
|
||||||
reply_to,
|
reply_to,
|
||||||
reply: v2::registration::RegisteredData {
|
reply: v2::registration::RegistredData {
|
||||||
wg_port,
|
wg_port,
|
||||||
pub_key,
|
pub_key,
|
||||||
private_ip
|
private_ip
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ pub struct RegistrationData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct RegisteredData {
|
pub struct RegistredData {
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
pub private_ip: IpAddr,
|
pub private_ip: IpAddr,
|
||||||
pub wg_port: u16,
|
pub wg_port: u16,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use super::registration::{RegisteredData, RegistrationData, RemainingBandwidthData};
|
use super::registration::{RegistrationData, RegistredData, RemainingBandwidthData};
|
||||||
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
||||||
use nym_sphinx::addressing::Recipient;
|
use nym_sphinx::addressing::Recipient;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -38,7 +38,7 @@ impl AuthenticatorResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_registered(
|
pub fn new_registered(
|
||||||
registred_data: RegisteredData,
|
registred_data: RegistredData,
|
||||||
reply_to: Recipient,
|
reply_to: Recipient,
|
||||||
request_id: u64,
|
request_id: u64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -139,7 +139,7 @@ pub struct PendingRegistrationResponse {
|
|||||||
pub struct RegisteredResponse {
|
pub struct RegisteredResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
pub reply: RegisteredData,
|
pub reply: RegistredData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
|||||||
@@ -262,8 +262,8 @@ impl From<v4::response::TopUpBandwidthResponse> for v3::response::TopUpBandwidth
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v3::registration::RegisteredData> for v4::registration::RegisteredData {
|
impl From<v3::registration::RegistredData> for v4::registration::RegistredData {
|
||||||
fn from(value: v3::registration::RegisteredData) -> Self {
|
fn from(value: v3::registration::RegistredData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pub_key: value.pub_key,
|
pub_key: value.pub_key,
|
||||||
private_ips: value.private_ip.into(),
|
private_ips: value.private_ip.into(),
|
||||||
@@ -272,8 +272,8 @@ impl From<v3::registration::RegisteredData> for v4::registration::RegisteredData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v4::registration::RegisteredData> for v3::registration::RegisteredData {
|
impl From<v4::registration::RegistredData> for v3::registration::RegistredData {
|
||||||
fn from(value: v4::registration::RegisteredData) -> Self {
|
fn from(value: v4::registration::RegistredData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pub_key: value.pub_key,
|
pub_key: value.pub_key,
|
||||||
private_ip: value.private_ips.ipv4.into(),
|
private_ip: value.private_ips.ipv4.into(),
|
||||||
@@ -565,7 +565,7 @@ mod tests {
|
|||||||
let private_ips =
|
let private_ips =
|
||||||
v4::registration::IpPair::new(ipv4, Ipv6Addr::from_str("fc01::a0a").unwrap());
|
v4::registration::IpPair::new(ipv4, Ipv6Addr::from_str("fc01::a0a").unwrap());
|
||||||
let wg_port = 51822;
|
let wg_port = 51822;
|
||||||
let registred_data = v3::registration::RegisteredData {
|
let registred_data = v3::registration::RegistredData {
|
||||||
pub_key,
|
pub_key,
|
||||||
private_ip: ipv4.into(),
|
private_ip: ipv4.into(),
|
||||||
wg_port,
|
wg_port,
|
||||||
@@ -592,7 +592,7 @@ mod tests {
|
|||||||
v4::response::AuthenticatorResponseData::Registered(v4::response::RegisteredResponse {
|
v4::response::AuthenticatorResponseData::Registered(v4::response::RegisteredResponse {
|
||||||
request_id,
|
request_id,
|
||||||
reply_to,
|
reply_to,
|
||||||
reply: v4::registration::RegisteredData {
|
reply: v4::registration::RegistredData {
|
||||||
wg_port,
|
wg_port,
|
||||||
pub_key,
|
pub_key,
|
||||||
private_ips
|
private_ips
|
||||||
@@ -608,7 +608,7 @@ mod tests {
|
|||||||
let private_ips =
|
let private_ips =
|
||||||
v4::registration::IpPair::new(ipv4, Ipv6Addr::from_str("fc01::10").unwrap());
|
v4::registration::IpPair::new(ipv4, Ipv6Addr::from_str("fc01::10").unwrap());
|
||||||
let wg_port = 51822;
|
let wg_port = 51822;
|
||||||
let registred_data = v4::registration::RegisteredData {
|
let registred_data = v4::registration::RegistredData {
|
||||||
pub_key,
|
pub_key,
|
||||||
private_ips,
|
private_ips,
|
||||||
wg_port,
|
wg_port,
|
||||||
@@ -635,7 +635,7 @@ mod tests {
|
|||||||
v3::response::AuthenticatorResponseData::Registered(v3::response::RegisteredResponse {
|
v3::response::AuthenticatorResponseData::Registered(v3::response::RegisteredResponse {
|
||||||
request_id,
|
request_id,
|
||||||
reply_to,
|
reply_to,
|
||||||
reply: v3::registration::RegisteredData {
|
reply: v3::registration::RegistredData {
|
||||||
wg_port,
|
wg_port,
|
||||||
pub_key,
|
pub_key,
|
||||||
private_ip: ipv4.into()
|
private_ip: ipv4.into()
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ pub struct RegistrationData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct RegisteredData {
|
pub struct RegistredData {
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
pub private_ips: IpPair,
|
pub private_ips: IpPair,
|
||||||
pub wg_port: u16,
|
pub wg_port: u16,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use super::registration::{RegisteredData, RegistrationData, RemainingBandwidthData};
|
use super::registration::{RegistrationData, RegistredData, RemainingBandwidthData};
|
||||||
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
||||||
use nym_sphinx::addressing::Recipient;
|
use nym_sphinx::addressing::Recipient;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -38,7 +38,7 @@ impl AuthenticatorResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_registered(
|
pub fn new_registered(
|
||||||
registred_data: RegisteredData,
|
registred_data: RegistredData,
|
||||||
reply_to: Recipient,
|
reply_to: Recipient,
|
||||||
request_id: u64,
|
request_id: u64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -139,7 +139,7 @@ pub struct PendingRegistrationResponse {
|
|||||||
pub struct RegisteredResponse {
|
pub struct RegisteredResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply_to: Recipient,
|
pub reply_to: Recipient,
|
||||||
pub reply: RegisteredData,
|
pub reply: RegistredData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
|||||||
@@ -186,8 +186,8 @@ impl From<v4::response::TopUpBandwidthResponse> for v5::response::TopUpBandwidth
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<v4::registration::RegisteredData> for v5::registration::RegisteredData {
|
impl From<v4::registration::RegistredData> for v5::registration::RegistredData {
|
||||||
fn from(value: v4::registration::RegisteredData) -> Self {
|
fn from(value: v4::registration::RegistredData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pub_key: value.pub_key,
|
pub_key: value.pub_key,
|
||||||
private_ips: value.private_ips.into(),
|
private_ips: value.private_ips.into(),
|
||||||
@@ -405,7 +405,7 @@ mod tests {
|
|||||||
let ipv6 = Ipv6Addr::from_str("fc01::a0a").unwrap();
|
let ipv6 = Ipv6Addr::from_str("fc01::a0a").unwrap();
|
||||||
let private_ips = v4::registration::IpPair::new(ipv4, ipv6);
|
let private_ips = v4::registration::IpPair::new(ipv4, ipv6);
|
||||||
let wg_port = 51822;
|
let wg_port = 51822;
|
||||||
let registred_data = v4::registration::RegisteredData {
|
let registred_data = v4::registration::RegistredData {
|
||||||
pub_key,
|
pub_key,
|
||||||
private_ips,
|
private_ips,
|
||||||
wg_port,
|
wg_port,
|
||||||
@@ -431,7 +431,7 @@ mod tests {
|
|||||||
upgraded_msg.data,
|
upgraded_msg.data,
|
||||||
v5::response::AuthenticatorResponseData::Registered(v5::response::RegisteredResponse {
|
v5::response::AuthenticatorResponseData::Registered(v5::response::RegisteredResponse {
|
||||||
request_id,
|
request_id,
|
||||||
reply: v5::registration::RegisteredData {
|
reply: v5::registration::RegistredData {
|
||||||
wg_port,
|
wg_port,
|
||||||
pub_key,
|
pub_key,
|
||||||
private_ips: v5::registration::IpPair::new(ipv4, ipv6)
|
private_ips: v5::registration::IpPair::new(ipv4, ipv6)
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ pub struct RegistrationData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub struct RegisteredData {
|
pub struct RegistredData {
|
||||||
pub pub_key: PeerPublicKey,
|
pub pub_key: PeerPublicKey,
|
||||||
pub private_ips: IpPair,
|
pub private_ips: IpPair,
|
||||||
pub wg_port: u16,
|
pub wg_port: u16,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use super::registration::{RegisteredData, RegistrationData, RemainingBandwidthData};
|
use super::registration::{RegistrationData, RegistredData, RemainingBandwidthData};
|
||||||
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ impl AuthenticatorResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_registered(registred_data: RegisteredData, request_id: u64) -> Self {
|
pub fn new_registered(registred_data: RegistredData, request_id: u64) -> Self {
|
||||||
Self {
|
Self {
|
||||||
protocol: Protocol {
|
protocol: Protocol {
|
||||||
service_provider_type: ServiceProviderType::Authenticator,
|
service_provider_type: ServiceProviderType::Authenticator,
|
||||||
@@ -116,7 +116,7 @@ pub struct PendingRegistrationResponse {
|
|||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct RegisteredResponse {
|
pub struct RegisteredResponse {
|
||||||
pub request_id: u64,
|
pub request_id: u64,
|
||||||
pub reply: RegisteredData,
|
pub reply: RegistredData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
|||||||
@@ -1,441 +0,0 @@
|
|||||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::{v5, v6};
|
|
||||||
|
|
||||||
impl TryFrom<v5::request::AuthenticatorRequest> for v6::request::AuthenticatorRequest {
|
|
||||||
type Error = crate::Error;
|
|
||||||
|
|
||||||
fn try_from(
|
|
||||||
authenticator_request: v5::request::AuthenticatorRequest,
|
|
||||||
) -> Result<Self, Self::Error> {
|
|
||||||
Ok(Self {
|
|
||||||
protocol: v6::PROTOCOL,
|
|
||||||
data: authenticator_request.data.try_into()?,
|
|
||||||
request_id: authenticator_request.request_id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<v5::request::AuthenticatorRequestData> for v6::request::AuthenticatorRequestData {
|
|
||||||
type Error = crate::Error;
|
|
||||||
|
|
||||||
fn try_from(
|
|
||||||
authenticator_request_data: v5::request::AuthenticatorRequestData,
|
|
||||||
) -> Result<Self, Self::Error> {
|
|
||||||
match authenticator_request_data {
|
|
||||||
v5::request::AuthenticatorRequestData::Initial(init_msg) => Ok(
|
|
||||||
v6::request::AuthenticatorRequestData::Initial(init_msg.into()),
|
|
||||||
),
|
|
||||||
v5::request::AuthenticatorRequestData::Final(final_msg) => Ok(
|
|
||||||
v6::request::AuthenticatorRequestData::Final(Box::new((*final_msg).try_into()?)),
|
|
||||||
),
|
|
||||||
v5::request::AuthenticatorRequestData::QueryBandwidth(pub_key) => Ok(
|
|
||||||
v6::request::AuthenticatorRequestData::QueryBandwidth(pub_key),
|
|
||||||
),
|
|
||||||
v5::request::AuthenticatorRequestData::TopUpBandwidth(top_up_message) => Ok(
|
|
||||||
v6::request::AuthenticatorRequestData::TopUpBandwidth(top_up_message.into()),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v5::registration::InitMessage> for v6::registration::InitMessage {
|
|
||||||
fn from(init_msg: v5::registration::InitMessage) -> Self {
|
|
||||||
Self {
|
|
||||||
pub_key: init_msg.pub_key,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<v5::registration::FinalMessage> for v6::registration::FinalMessage {
|
|
||||||
type Error = crate::Error;
|
|
||||||
|
|
||||||
fn try_from(final_msg: v5::registration::FinalMessage) -> Result<Self, Self::Error> {
|
|
||||||
Ok(Self {
|
|
||||||
gateway_client: final_msg.gateway_client.into(),
|
|
||||||
credential: final_msg
|
|
||||||
.credential
|
|
||||||
.map(TryInto::try_into)
|
|
||||||
.transpose()
|
|
||||||
.map_err(Self::Error::conversion_display)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v5::registration::GatewayClient> for v6::registration::GatewayClient {
|
|
||||||
fn from(gateway_client: v5::registration::GatewayClient) -> Self {
|
|
||||||
Self {
|
|
||||||
pub_key: gateway_client.pub_key,
|
|
||||||
private_ips: gateway_client.private_ips.into(),
|
|
||||||
mac: gateway_client.mac.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v6::registration::GatewayClient> for v5::registration::GatewayClient {
|
|
||||||
fn from(gateway_client: v6::registration::GatewayClient) -> Self {
|
|
||||||
Self {
|
|
||||||
pub_key: gateway_client.pub_key,
|
|
||||||
private_ips: gateway_client.private_ips.into(),
|
|
||||||
mac: gateway_client.mac.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v5::registration::ClientMac> for v6::registration::ClientMac {
|
|
||||||
fn from(client_mac: v5::registration::ClientMac) -> Self {
|
|
||||||
Self::new((*client_mac).clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v6::registration::ClientMac> for v5::registration::ClientMac {
|
|
||||||
fn from(client_mac: v6::registration::ClientMac) -> Self {
|
|
||||||
Self::new((*client_mac).clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Box<v5::topup::TopUpMessage>> for Box<v6::topup::TopUpMessage> {
|
|
||||||
fn from(top_up_message: Box<v5::topup::TopUpMessage>) -> Self {
|
|
||||||
Box::new(v6::topup::TopUpMessage {
|
|
||||||
pub_key: top_up_message.pub_key,
|
|
||||||
credential: top_up_message.credential,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v5::response::AuthenticatorResponse> for v6::response::AuthenticatorResponse {
|
|
||||||
fn from(value: v5::response::AuthenticatorResponse) -> Self {
|
|
||||||
Self {
|
|
||||||
protocol: v6::PROTOCOL,
|
|
||||||
data: value.data.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v5::response::AuthenticatorResponseData> for v6::response::AuthenticatorResponseData {
|
|
||||||
fn from(authenticator_response_data: v5::response::AuthenticatorResponseData) -> Self {
|
|
||||||
match authenticator_response_data {
|
|
||||||
v5::response::AuthenticatorResponseData::PendingRegistration(pending_response) => {
|
|
||||||
v6::response::AuthenticatorResponseData::PendingRegistration(
|
|
||||||
pending_response.into(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
v5::response::AuthenticatorResponseData::Registered(registered_response) => {
|
|
||||||
v6::response::AuthenticatorResponseData::Registered(registered_response.into())
|
|
||||||
}
|
|
||||||
v5::response::AuthenticatorResponseData::RemainingBandwidth(
|
|
||||||
remaining_bandwidth_response,
|
|
||||||
) => v6::response::AuthenticatorResponseData::RemainingBandwidth(
|
|
||||||
remaining_bandwidth_response.into(),
|
|
||||||
),
|
|
||||||
v5::response::AuthenticatorResponseData::TopUpBandwidth(top_up_response) => {
|
|
||||||
v6::response::AuthenticatorResponseData::TopUpBandwidth(top_up_response.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v5::response::RegisteredResponse> for v6::response::RegisteredResponse {
|
|
||||||
fn from(value: v5::response::RegisteredResponse) -> Self {
|
|
||||||
Self {
|
|
||||||
request_id: value.request_id,
|
|
||||||
reply: value.reply.into(),
|
|
||||||
upgrade_mode_enabled: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v5::response::PendingRegistrationResponse> for v6::response::PendingRegistrationResponse {
|
|
||||||
fn from(value: v5::response::PendingRegistrationResponse) -> Self {
|
|
||||||
Self {
|
|
||||||
request_id: value.request_id,
|
|
||||||
reply: value.reply.into(),
|
|
||||||
upgrade_mode_enabled: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v5::registration::RegistrationData> for v6::registration::RegistrationData {
|
|
||||||
fn from(value: v5::registration::RegistrationData) -> Self {
|
|
||||||
Self {
|
|
||||||
nonce: value.nonce,
|
|
||||||
gateway_data: value.gateway_data.into(),
|
|
||||||
wg_port: value.wg_port,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v6::registration::RegistrationData> for v5::registration::RegistrationData {
|
|
||||||
fn from(value: v6::registration::RegistrationData) -> Self {
|
|
||||||
Self {
|
|
||||||
nonce: value.nonce,
|
|
||||||
gateway_data: value.gateway_data.into(),
|
|
||||||
wg_port: value.wg_port,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v5::response::RemainingBandwidthResponse> for v6::response::RemainingBandwidthResponse {
|
|
||||||
fn from(value: v5::response::RemainingBandwidthResponse) -> Self {
|
|
||||||
Self {
|
|
||||||
request_id: value.request_id,
|
|
||||||
reply: value.reply.map(Into::into),
|
|
||||||
upgrade_mode_enabled: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v5::response::TopUpBandwidthResponse> for v6::response::TopUpBandwidthResponse {
|
|
||||||
fn from(value: v5::response::TopUpBandwidthResponse) -> Self {
|
|
||||||
Self {
|
|
||||||
request_id: value.request_id,
|
|
||||||
reply: value.reply.into(),
|
|
||||||
upgrade_mode_enabled: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v5::registration::RegisteredData> for v6::registration::RegisteredData {
|
|
||||||
fn from(value: v5::registration::RegisteredData) -> Self {
|
|
||||||
Self {
|
|
||||||
pub_key: value.pub_key,
|
|
||||||
private_ips: value.private_ips.into(),
|
|
||||||
wg_port: value.wg_port,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v5::registration::RemainingBandwidthData> for v6::registration::RemainingBandwidthData {
|
|
||||||
fn from(value: v5::registration::RemainingBandwidthData) -> Self {
|
|
||||||
Self {
|
|
||||||
available_bandwidth: value.available_bandwidth,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v5::registration::IpPair> for v6::registration::IpPair {
|
|
||||||
fn from(value: v5::registration::IpPair) -> Self {
|
|
||||||
Self {
|
|
||||||
ipv4: value.ipv4,
|
|
||||||
ipv6: value.ipv6,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<v6::registration::IpPair> for v5::registration::IpPair {
|
|
||||||
fn from(value: v6::registration::IpPair) -> Self {
|
|
||||||
Self {
|
|
||||||
ipv4: value.ipv4,
|
|
||||||
ipv6: value.ipv6,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use std::{
|
|
||||||
net::{Ipv4Addr, Ipv6Addr},
|
|
||||||
str::FromStr,
|
|
||||||
};
|
|
||||||
|
|
||||||
use nym_credentials_interface::{BandwidthCredential, CredentialSpendingData, TicketType};
|
|
||||||
use nym_crypto::asymmetric::x25519::PrivateKey;
|
|
||||||
use nym_wireguard_types::PeerPublicKey;
|
|
||||||
use x25519_dalek::PublicKey;
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
use crate::models::BandwidthClaim;
|
|
||||||
use crate::{util::tests::CREDENTIAL_BYTES, v5};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn upgrade_initial_req() {
|
|
||||||
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
|
||||||
|
|
||||||
let (msg, _) = v5::request::AuthenticatorRequest::new_initial_request(
|
|
||||||
v5::registration::InitMessage::new(pub_key),
|
|
||||||
);
|
|
||||||
let upgraded_msg = v6::request::AuthenticatorRequest::try_from(msg).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(upgraded_msg.protocol, v6::PROTOCOL);
|
|
||||||
assert_eq!(
|
|
||||||
upgraded_msg.data,
|
|
||||||
v6::request::AuthenticatorRequestData::Initial(v6::registration::InitMessage {
|
|
||||||
pub_key
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn upgrade_final_req() {
|
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
|
|
||||||
let local_secret = PrivateKey::new(&mut rng);
|
|
||||||
let remote_secret = x25519_dalek::StaticSecret::random_from_rng(&mut rng);
|
|
||||||
let ipv4 = Ipv4Addr::from_str("10.10.10.10").unwrap();
|
|
||||||
let ipv6 = Ipv6Addr::from_str("fc01::a0a").unwrap();
|
|
||||||
let ips = v5::registration::IpPair::new(ipv4, ipv6);
|
|
||||||
let nonce = 42;
|
|
||||||
let gateway_client = v5::registration::GatewayClient::new(
|
|
||||||
&local_secret,
|
|
||||||
(&remote_secret).into(),
|
|
||||||
ips,
|
|
||||||
nonce,
|
|
||||||
);
|
|
||||||
let credential = CredentialSpendingData::try_from_bytes(&CREDENTIAL_BYTES).unwrap();
|
|
||||||
let final_message = v5::registration::FinalMessage {
|
|
||||||
gateway_client: gateway_client.clone(),
|
|
||||||
credential: Some(credential.clone()),
|
|
||||||
};
|
|
||||||
|
|
||||||
let (msg, _) = v5::request::AuthenticatorRequest::new_final_request(final_message);
|
|
||||||
let upgraded_msg = v6::request::AuthenticatorRequest::try_from(msg).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(upgraded_msg.protocol, v6::PROTOCOL);
|
|
||||||
assert_eq!(
|
|
||||||
upgraded_msg.data,
|
|
||||||
v6::request::AuthenticatorRequestData::Final(Box::new(
|
|
||||||
v6::registration::FinalMessage {
|
|
||||||
gateway_client: v6::registration::GatewayClient::new(
|
|
||||||
&local_secret,
|
|
||||||
(&remote_secret).into(),
|
|
||||||
v6::registration::IpPair::new(ipv4, ipv6),
|
|
||||||
nonce
|
|
||||||
),
|
|
||||||
credential: Some(BandwidthClaim {
|
|
||||||
credential: BandwidthCredential::ZkNym(Box::new(credential)),
|
|
||||||
kind: TicketType::V1MixnetEntry,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn upgrade_query_req() {
|
|
||||||
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
|
||||||
|
|
||||||
let (msg, _) = v5::request::AuthenticatorRequest::new_query_request(pub_key);
|
|
||||||
let upgraded_msg = v6::request::AuthenticatorRequest::try_from(msg).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(upgraded_msg.protocol, v6::PROTOCOL);
|
|
||||||
assert_eq!(
|
|
||||||
upgraded_msg.data,
|
|
||||||
v6::request::AuthenticatorRequestData::QueryBandwidth(pub_key)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn upgrade_pending_reg_resp() {
|
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
|
|
||||||
let local_secret = PrivateKey::new(&mut rng);
|
|
||||||
let remote_secret = x25519_dalek::StaticSecret::random_from_rng(&mut rng);
|
|
||||||
let ipv4 = Ipv4Addr::from_str("10.10.10.10").unwrap();
|
|
||||||
let ipv6 = Ipv6Addr::from_str("fc01::a0a").unwrap();
|
|
||||||
let ips = v5::registration::IpPair::new(ipv4, ipv6);
|
|
||||||
let nonce = 42;
|
|
||||||
let wg_port = 51822;
|
|
||||||
let gateway_data = v5::registration::GatewayClient::new(
|
|
||||||
&local_secret,
|
|
||||||
(&remote_secret).into(),
|
|
||||||
ips,
|
|
||||||
nonce,
|
|
||||||
);
|
|
||||||
let registration_data = v5::registration::RegistrationData {
|
|
||||||
nonce,
|
|
||||||
gateway_data,
|
|
||||||
wg_port,
|
|
||||||
};
|
|
||||||
let request_id = 123;
|
|
||||||
|
|
||||||
let msg = v5::response::AuthenticatorResponse::new_pending_registration_success(
|
|
||||||
registration_data,
|
|
||||||
request_id,
|
|
||||||
);
|
|
||||||
let upgraded_msg = v6::response::AuthenticatorResponse::from(msg);
|
|
||||||
|
|
||||||
assert_eq!(upgraded_msg.protocol, v6::PROTOCOL);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
upgraded_msg.data,
|
|
||||||
v6::response::AuthenticatorResponseData::PendingRegistration(
|
|
||||||
v6::response::PendingRegistrationResponse {
|
|
||||||
request_id,
|
|
||||||
reply: v6::registration::RegistrationData {
|
|
||||||
nonce,
|
|
||||||
gateway_data: v6::registration::GatewayClient::new(
|
|
||||||
&local_secret,
|
|
||||||
(&remote_secret).into(),
|
|
||||||
v6::registration::IpPair::new(ipv4, ipv6),
|
|
||||||
nonce
|
|
||||||
),
|
|
||||||
wg_port
|
|
||||||
},
|
|
||||||
upgrade_mode_enabled: false,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn upgrade_registered_resp() {
|
|
||||||
let pub_key = PeerPublicKey::new(PublicKey::from([0; 32]));
|
|
||||||
let ipv4 = Ipv4Addr::from_str("10.1.10.10").unwrap();
|
|
||||||
let ipv6 = Ipv6Addr::from_str("fc01::a0a").unwrap();
|
|
||||||
let private_ips = v5::registration::IpPair::new(ipv4, ipv6);
|
|
||||||
let wg_port = 51822;
|
|
||||||
let registered_data = v5::registration::RegisteredData {
|
|
||||||
pub_key,
|
|
||||||
private_ips,
|
|
||||||
wg_port,
|
|
||||||
};
|
|
||||||
let request_id = 123;
|
|
||||||
|
|
||||||
let msg = v5::response::AuthenticatorResponse::new_registered(registered_data, request_id);
|
|
||||||
let upgraded_msg = v6::response::AuthenticatorResponse::from(msg);
|
|
||||||
|
|
||||||
assert_eq!(upgraded_msg.protocol, v6::PROTOCOL);
|
|
||||||
assert_eq!(
|
|
||||||
upgraded_msg.data,
|
|
||||||
v6::response::AuthenticatorResponseData::Registered(v6::response::RegisteredResponse {
|
|
||||||
request_id,
|
|
||||||
reply: v6::registration::RegisteredData {
|
|
||||||
wg_port,
|
|
||||||
pub_key,
|
|
||||||
private_ips: v6::registration::IpPair::new(ipv4, ipv6)
|
|
||||||
},
|
|
||||||
upgrade_mode_enabled: false,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn upgrade_remaining_bandwidth_resp() {
|
|
||||||
let available_bandwidth = 42;
|
|
||||||
let remaining_bandwidth_data = Some(v5::registration::RemainingBandwidthData {
|
|
||||||
available_bandwidth,
|
|
||||||
});
|
|
||||||
let request_id = 123;
|
|
||||||
|
|
||||||
let msg = v5::response::AuthenticatorResponse::new_remaining_bandwidth(
|
|
||||||
remaining_bandwidth_data,
|
|
||||||
request_id,
|
|
||||||
);
|
|
||||||
let upgraded_msg = v6::response::AuthenticatorResponse::from(msg);
|
|
||||||
|
|
||||||
assert_eq!(upgraded_msg.protocol, v6::PROTOCOL);
|
|
||||||
assert_eq!(
|
|
||||||
upgraded_msg.data,
|
|
||||||
v6::response::AuthenticatorResponseData::RemainingBandwidth(
|
|
||||||
v6::response::RemainingBandwidthResponse {
|
|
||||||
request_id,
|
|
||||||
reply: Some(v6::registration::RemainingBandwidthData {
|
|
||||||
available_bandwidth,
|
|
||||||
}),
|
|
||||||
upgrade_mode_enabled: false,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
|
||||||
|
|
||||||
pub mod conversion;
|
|
||||||
pub mod registration;
|
|
||||||
pub mod request;
|
|
||||||
pub mod response;
|
|
||||||
pub mod topup;
|
|
||||||
pub mod upgrade_mode_check;
|
|
||||||
|
|
||||||
pub const VERSION: u8 = 6;
|
|
||||||
|
|
||||||
pub const PROTOCOL: Protocol = Protocol::new(VERSION, ServiceProviderType::Authenticator);
|
|
||||||
@@ -1,287 +0,0 @@
|
|||||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::error::Error;
|
|
||||||
use crate::models::BandwidthClaim;
|
|
||||||
use base64::{Engine, engine::general_purpose};
|
|
||||||
use nym_network_defaults::constants::{WG_TUN_DEVICE_IP_ADDRESS_V4, WG_TUN_DEVICE_IP_ADDRESS_V6};
|
|
||||||
use nym_wireguard_types::PeerPublicKey;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
|
||||||
use std::time::SystemTime;
|
|
||||||
use std::{fmt, ops::Deref, str::FromStr};
|
|
||||||
|
|
||||||
#[cfg(feature = "verify")]
|
|
||||||
use hmac::{Hmac, Mac};
|
|
||||||
#[cfg(feature = "verify")]
|
|
||||||
use nym_crypto::asymmetric::x25519::{PrivateKey, PublicKey};
|
|
||||||
#[cfg(feature = "verify")]
|
|
||||||
use sha2::Sha256;
|
|
||||||
|
|
||||||
pub type PendingRegistrations = HashMap<PeerPublicKey, RegistrationData>;
|
|
||||||
pub type PrivateIPs = HashMap<IpPair, Taken>;
|
|
||||||
|
|
||||||
#[cfg(feature = "verify")]
|
|
||||||
pub type HmacSha256 = Hmac<Sha256>;
|
|
||||||
|
|
||||||
pub type Nonce = u64;
|
|
||||||
pub type Taken = Option<SystemTime>;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
||||||
pub struct IpPair {
|
|
||||||
pub ipv4: Ipv4Addr,
|
|
||||||
pub ipv6: Ipv6Addr,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IpPair {
|
|
||||||
pub fn new(ipv4: Ipv4Addr, ipv6: Ipv6Addr) -> Self {
|
|
||||||
IpPair { ipv4, ipv6 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<(Ipv4Addr, Ipv6Addr)> for IpPair {
|
|
||||||
fn from((ipv4, ipv6): (Ipv4Addr, Ipv6Addr)) -> Self {
|
|
||||||
IpPair { ipv4, ipv6 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for IpPair {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(f, "({}, {})", self.ipv4, self.ipv6)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<IpAddr> for IpPair {
|
|
||||||
fn from(value: IpAddr) -> Self {
|
|
||||||
let (before_last_byte, last_byte) = match value {
|
|
||||||
IpAddr::V4(ipv4_addr) => (ipv4_addr.octets()[2], ipv4_addr.octets()[3]),
|
|
||||||
IpAddr::V6(ipv6_addr) => (ipv6_addr.octets()[14], ipv6_addr.octets()[15]),
|
|
||||||
};
|
|
||||||
let last_bytes = ((before_last_byte as u16) << 8) | last_byte as u16;
|
|
||||||
let ipv4 = Ipv4Addr::new(
|
|
||||||
WG_TUN_DEVICE_IP_ADDRESS_V4.octets()[0],
|
|
||||||
WG_TUN_DEVICE_IP_ADDRESS_V4.octets()[1],
|
|
||||||
before_last_byte,
|
|
||||||
last_byte,
|
|
||||||
);
|
|
||||||
let ipv6 = Ipv6Addr::new(
|
|
||||||
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[0],
|
|
||||||
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[1],
|
|
||||||
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[2],
|
|
||||||
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[3],
|
|
||||||
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[4],
|
|
||||||
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[5],
|
|
||||||
WG_TUN_DEVICE_IP_ADDRESS_V6.segments()[6],
|
|
||||||
last_bytes,
|
|
||||||
);
|
|
||||||
IpPair::new(ipv4, ipv6)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
|
||||||
pub struct InitMessage {
|
|
||||||
/// Base64 encoded x25519 public key
|
|
||||||
pub pub_key: PeerPublicKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InitMessage {
|
|
||||||
pub fn new(pub_key: PeerPublicKey) -> Self {
|
|
||||||
InitMessage { pub_key }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
|
||||||
pub struct FinalMessage {
|
|
||||||
/// Gateway client data
|
|
||||||
pub gateway_client: GatewayClient,
|
|
||||||
|
|
||||||
/// Ecash credential
|
|
||||||
pub credential: Option<BandwidthClaim>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
|
||||||
pub struct RegistrationData {
|
|
||||||
pub nonce: u64,
|
|
||||||
pub gateway_data: GatewayClient,
|
|
||||||
pub wg_port: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
|
||||||
pub struct RegisteredData {
|
|
||||||
pub pub_key: PeerPublicKey,
|
|
||||||
pub private_ips: IpPair,
|
|
||||||
pub wg_port: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
|
||||||
pub struct RemainingBandwidthData {
|
|
||||||
pub available_bandwidth: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Client that wants to register sends its PublicKey bytes mac digest encrypted with a DH shared secret.
|
|
||||||
/// Gateway/Nym node can then verify pub_key payload using the same process
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
|
||||||
pub struct GatewayClient {
|
|
||||||
/// Base64 encoded x25519 public key
|
|
||||||
pub pub_key: PeerPublicKey,
|
|
||||||
|
|
||||||
/// Assigned private IPs (v4 and v6)
|
|
||||||
pub private_ips: IpPair,
|
|
||||||
|
|
||||||
/// Sha256 hmac on the data (alongside the prior nonce)
|
|
||||||
pub mac: ClientMac,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GatewayClient {
|
|
||||||
#[cfg(feature = "verify")]
|
|
||||||
pub fn new(
|
|
||||||
local_secret: &PrivateKey,
|
|
||||||
remote_public: x25519_dalek::PublicKey,
|
|
||||||
private_ips: IpPair,
|
|
||||||
nonce: u64,
|
|
||||||
) -> Self {
|
|
||||||
let local_public = PublicKey::from(local_secret);
|
|
||||||
let remote_public = PublicKey::from(remote_public);
|
|
||||||
|
|
||||||
let dh = local_secret.diffie_hellman(&remote_public);
|
|
||||||
|
|
||||||
// TODO: change that to use our nym_crypto::hmac module instead
|
|
||||||
#[allow(clippy::expect_used)]
|
|
||||||
let mut mac = HmacSha256::new_from_slice(&dh[..])
|
|
||||||
.expect("x25519 shared secret is always 32 bytes long");
|
|
||||||
|
|
||||||
mac.update(local_public.as_bytes());
|
|
||||||
mac.update(private_ips.to_string().as_bytes());
|
|
||||||
mac.update(&nonce.to_le_bytes());
|
|
||||||
|
|
||||||
GatewayClient {
|
|
||||||
pub_key: PeerPublicKey::new(local_public.into()),
|
|
||||||
private_ips,
|
|
||||||
mac: ClientMac(mac.finalize().into_bytes().to_vec()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reusable secret should be gateways Wireguard PK
|
|
||||||
// Client should perform this step when generating its payload, using its own WG PK
|
|
||||||
#[cfg(feature = "verify")]
|
|
||||||
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
|
|
||||||
// use gateways key as a ref to an x25519_dalek key
|
|
||||||
let dh = gateway_key.inner().diffie_hellman(&self.pub_key);
|
|
||||||
|
|
||||||
// TODO: change that to use our nym_crypto::hmac module instead
|
|
||||||
#[allow(clippy::expect_used)]
|
|
||||||
let mut mac = HmacSha256::new_from_slice(dh.as_bytes())
|
|
||||||
.expect("x25519 shared secret is always 32 bytes long");
|
|
||||||
|
|
||||||
mac.update(self.pub_key.as_bytes());
|
|
||||||
mac.update(self.private_ips.to_string().as_bytes());
|
|
||||||
mac.update(&nonce.to_le_bytes());
|
|
||||||
|
|
||||||
mac.verify_slice(&self.mac)
|
|
||||||
.map_err(|source| Error::FailedClientMacVerification {
|
|
||||||
client: self.pub_key.to_string(),
|
|
||||||
source,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pub_key(&self) -> PeerPublicKey {
|
|
||||||
self.pub_key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: change the inner type into generic array of size HmacSha256::OutputSize
|
|
||||||
// TODO2: rely on our internal crypto/hmac
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
pub struct ClientMac(Vec<u8>);
|
|
||||||
|
|
||||||
impl fmt::Display for ClientMac {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(f, "{}", general_purpose::STANDARD.encode(&self.0))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Vec<u8>> for ClientMac {
|
|
||||||
fn from(v: Vec<u8>) -> Self {
|
|
||||||
ClientMac(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ClientMac {
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn new(mac: Vec<u8>) -> Self {
|
|
||||||
ClientMac(mac)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for ClientMac {
|
|
||||||
type Target = Vec<u8>;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for ClientMac {
|
|
||||||
type Err = Error;
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
let mac_bytes: Vec<u8> =
|
|
||||||
general_purpose::STANDARD
|
|
||||||
.decode(s)
|
|
||||||
.map_err(|source| Error::MalformedClientMac {
|
|
||||||
mac: s.to_string(),
|
|
||||||
source,
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(ClientMac(mac_bytes))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for ClientMac {
|
|
||||||
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
||||||
let encoded_key = general_purpose::STANDARD.encode(self.0.clone());
|
|
||||||
serializer.serialize_str(&encoded_key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for ClientMac {
|
|
||||||
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
|
||||||
let encoded_key = String::deserialize(deserializer)?;
|
|
||||||
ClientMac::from_str(&encoded_key).map_err(serde::de::Error::custom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use nym_crypto::asymmetric::x25519;
|
|
||||||
use nym_test_utils::helpers::deterministic_rng;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn create_ip_pair() {
|
|
||||||
let ipv4: IpAddr = Ipv4Addr::from_str("10.1.10.50").unwrap().into();
|
|
||||||
let ipv6: IpAddr = Ipv6Addr::from_str("fc01::0a32").unwrap().into();
|
|
||||||
|
|
||||||
assert_eq!(IpPair::from(ipv4), IpPair::from(ipv6));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg(feature = "verify")]
|
|
||||||
fn client_request_roundtrip() {
|
|
||||||
let mut rng = deterministic_rng();
|
|
||||||
|
|
||||||
let gateway_key_pair = x25519::KeyPair::new(&mut rng);
|
|
||||||
let client_key_pair = x25519::KeyPair::new(&mut rng);
|
|
||||||
|
|
||||||
let nonce = 1234567890;
|
|
||||||
|
|
||||||
let client = GatewayClient::new(
|
|
||||||
client_key_pair.private_key(),
|
|
||||||
x25519_dalek::PublicKey::from(gateway_key_pair.public_key().to_bytes()),
|
|
||||||
IpPair::new("10.0.0.42".parse().unwrap(), "fc00::42".parse().unwrap()),
|
|
||||||
nonce,
|
|
||||||
);
|
|
||||||
assert!(client.verify(gateway_key_pair.private_key(), nonce).is_ok())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use super::{
|
|
||||||
PROTOCOL,
|
|
||||||
registration::{FinalMessage, InitMessage},
|
|
||||||
topup::TopUpMessage,
|
|
||||||
upgrade_mode_check::UpgradeModeCheckRequest,
|
|
||||||
};
|
|
||||||
use nym_service_provider_requests_common::Protocol;
|
|
||||||
use nym_wireguard_types::PeerPublicKey;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use crate::make_bincode_serializer;
|
|
||||||
|
|
||||||
fn generate_random() -> u64 {
|
|
||||||
use rand::RngCore;
|
|
||||||
let mut rng = rand::rngs::OsRng;
|
|
||||||
rng.next_u64()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
||||||
pub struct AuthenticatorRequest {
|
|
||||||
pub protocol: Protocol,
|
|
||||||
pub data: AuthenticatorRequestData,
|
|
||||||
pub request_id: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AuthenticatorRequest {
|
|
||||||
pub fn from_reconstructed_message(
|
|
||||||
message: &nym_sphinx::receiver::ReconstructedMessage,
|
|
||||||
) -> Result<Self, bincode::Error> {
|
|
||||||
use bincode::Options;
|
|
||||||
make_bincode_serializer().deserialize(&message.message)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_initial_request(init_message: InitMessage) -> (Self, u64) {
|
|
||||||
let request_id = generate_random();
|
|
||||||
(
|
|
||||||
Self {
|
|
||||||
protocol: PROTOCOL,
|
|
||||||
data: AuthenticatorRequestData::Initial(init_message),
|
|
||||||
request_id,
|
|
||||||
},
|
|
||||||
request_id,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_final_request(final_message: FinalMessage) -> (Self, u64) {
|
|
||||||
let request_id = generate_random();
|
|
||||||
(
|
|
||||||
Self {
|
|
||||||
protocol: PROTOCOL,
|
|
||||||
data: AuthenticatorRequestData::Final(Box::new(final_message)),
|
|
||||||
request_id,
|
|
||||||
},
|
|
||||||
request_id,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_query_request(peer_public_key: PeerPublicKey) -> (Self, u64) {
|
|
||||||
let request_id = generate_random();
|
|
||||||
(
|
|
||||||
Self {
|
|
||||||
protocol: PROTOCOL,
|
|
||||||
data: AuthenticatorRequestData::QueryBandwidth(peer_public_key),
|
|
||||||
request_id,
|
|
||||||
},
|
|
||||||
request_id,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_topup_request(top_up_message: TopUpMessage) -> (Self, u64) {
|
|
||||||
let request_id = generate_random();
|
|
||||||
(
|
|
||||||
Self {
|
|
||||||
protocol: PROTOCOL,
|
|
||||||
data: AuthenticatorRequestData::TopUpBandwidth(Box::new(top_up_message)),
|
|
||||||
request_id,
|
|
||||||
},
|
|
||||||
request_id,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_upgrade_mode_check_request(message: UpgradeModeCheckRequest) -> (Self, u64) {
|
|
||||||
let request_id = generate_random();
|
|
||||||
(
|
|
||||||
Self {
|
|
||||||
protocol: PROTOCOL,
|
|
||||||
data: AuthenticatorRequestData::CheckUpgradeMode(message),
|
|
||||||
request_id,
|
|
||||||
},
|
|
||||||
request_id,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
|
|
||||||
use bincode::Options;
|
|
||||||
make_bincode_serializer().serialize(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
||||||
pub enum AuthenticatorRequestData {
|
|
||||||
Initial(InitMessage),
|
|
||||||
Final(Box<FinalMessage>),
|
|
||||||
QueryBandwidth(PeerPublicKey),
|
|
||||||
TopUpBandwidth(Box<TopUpMessage>),
|
|
||||||
CheckUpgradeMode(UpgradeModeCheckRequest),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::super::VERSION;
|
|
||||||
use super::*;
|
|
||||||
use nym_service_provider_requests_common::ServiceProviderType;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn check_first_bytes_protocol() {
|
|
||||||
let version = VERSION;
|
|
||||||
let data = AuthenticatorRequest {
|
|
||||||
protocol: Protocol {
|
|
||||||
version,
|
|
||||||
service_provider_type: ServiceProviderType::Authenticator,
|
|
||||||
},
|
|
||||||
data: AuthenticatorRequestData::Initial(InitMessage::new(
|
|
||||||
PeerPublicKey::from_str("yvNUDpT5l7W/xDhiu6HkqTHDQwbs/B3J5UrLmORl1EQ=").unwrap(),
|
|
||||||
)),
|
|
||||||
request_id: 1,
|
|
||||||
};
|
|
||||||
let bytes = *data.to_bytes().unwrap().first_chunk::<2>().unwrap();
|
|
||||||
assert_eq!(bytes, [version, ServiceProviderType::Authenticator as u8]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use super::registration::{RegisteredData, RegistrationData, RemainingBandwidthData};
|
|
||||||
use nym_service_provider_requests_common::Protocol;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use crate::make_bincode_serializer;
|
|
||||||
|
|
||||||
use super::PROTOCOL;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
||||||
pub struct AuthenticatorResponse {
|
|
||||||
pub protocol: Protocol,
|
|
||||||
pub data: AuthenticatorResponseData,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AuthenticatorResponse {
|
|
||||||
pub fn new_pending_registration_success(
|
|
||||||
registration_data: RegistrationData,
|
|
||||||
request_id: u64,
|
|
||||||
upgrade_mode_enabled: bool,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
protocol: PROTOCOL,
|
|
||||||
data: AuthenticatorResponseData::PendingRegistration(PendingRegistrationResponse {
|
|
||||||
reply: registration_data,
|
|
||||||
request_id,
|
|
||||||
upgrade_mode_enabled,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_registered(
|
|
||||||
registered_data: RegisteredData,
|
|
||||||
request_id: u64,
|
|
||||||
upgrade_mode_enabled: bool,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
protocol: PROTOCOL,
|
|
||||||
data: AuthenticatorResponseData::Registered(RegisteredResponse {
|
|
||||||
reply: registered_data,
|
|
||||||
request_id,
|
|
||||||
upgrade_mode_enabled,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_remaining_bandwidth(
|
|
||||||
remaining_bandwidth_data: Option<RemainingBandwidthData>,
|
|
||||||
request_id: u64,
|
|
||||||
upgrade_mode_enabled: bool,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
protocol: PROTOCOL,
|
|
||||||
data: AuthenticatorResponseData::RemainingBandwidth(RemainingBandwidthResponse {
|
|
||||||
reply: remaining_bandwidth_data,
|
|
||||||
request_id,
|
|
||||||
upgrade_mode_enabled,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_topup_bandwidth(
|
|
||||||
remaining_bandwidth_data: RemainingBandwidthData,
|
|
||||||
request_id: u64,
|
|
||||||
upgrade_mode_enabled: bool,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
protocol: PROTOCOL,
|
|
||||||
data: AuthenticatorResponseData::TopUpBandwidth(TopUpBandwidthResponse {
|
|
||||||
reply: remaining_bandwidth_data,
|
|
||||||
request_id,
|
|
||||||
upgrade_mode_enabled,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_upgrade_mode_check(request_id: u64, upgrade_mode_enabled: bool) -> Self {
|
|
||||||
Self {
|
|
||||||
protocol: PROTOCOL,
|
|
||||||
data: AuthenticatorResponseData::UpgradeMode(UpgradeModeResponse {
|
|
||||||
request_id,
|
|
||||||
upgrade_mode_enabled,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
|
|
||||||
use bincode::Options;
|
|
||||||
make_bincode_serializer().serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_reconstructed_message(
|
|
||||||
message: &nym_sphinx::receiver::ReconstructedMessage,
|
|
||||||
) -> Result<Self, bincode::Error> {
|
|
||||||
use bincode::Options;
|
|
||||||
make_bincode_serializer().deserialize(&message.message)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn id(&self) -> Option<u64> {
|
|
||||||
match &self.data {
|
|
||||||
AuthenticatorResponseData::PendingRegistration(response) => Some(response.request_id),
|
|
||||||
AuthenticatorResponseData::Registered(response) => Some(response.request_id),
|
|
||||||
AuthenticatorResponseData::RemainingBandwidth(response) => Some(response.request_id),
|
|
||||||
AuthenticatorResponseData::TopUpBandwidth(response) => Some(response.request_id),
|
|
||||||
AuthenticatorResponseData::UpgradeMode(response) => Some(response.request_id),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
||||||
pub enum AuthenticatorResponseData {
|
|
||||||
PendingRegistration(PendingRegistrationResponse),
|
|
||||||
Registered(RegisteredResponse),
|
|
||||||
RemainingBandwidth(RemainingBandwidthResponse),
|
|
||||||
TopUpBandwidth(TopUpBandwidthResponse),
|
|
||||||
UpgradeMode(UpgradeModeResponse),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
||||||
pub struct PendingRegistrationResponse {
|
|
||||||
pub request_id: u64,
|
|
||||||
pub reply: RegistrationData,
|
|
||||||
pub upgrade_mode_enabled: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
||||||
pub struct RegisteredResponse {
|
|
||||||
pub request_id: u64,
|
|
||||||
pub reply: RegisteredData,
|
|
||||||
pub upgrade_mode_enabled: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
||||||
pub struct RemainingBandwidthResponse {
|
|
||||||
pub request_id: u64,
|
|
||||||
pub reply: Option<RemainingBandwidthData>,
|
|
||||||
pub upgrade_mode_enabled: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
||||||
pub struct TopUpBandwidthResponse {
|
|
||||||
pub request_id: u64,
|
|
||||||
pub reply: RemainingBandwidthData,
|
|
||||||
pub upgrade_mode_enabled: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
||||||
pub struct UpgradeModeResponse {
|
|
||||||
pub request_id: u64,
|
|
||||||
pub upgrade_mode_enabled: bool,
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use nym_credentials_interface::CredentialSpendingData;
|
|
||||||
use nym_wireguard_types::PeerPublicKey;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
|
||||||
pub struct TopUpMessage {
|
|
||||||
/// Base64 encoded x25519 public key
|
|
||||||
pub pub_key: PeerPublicKey,
|
|
||||||
|
|
||||||
/// Ecash credential
|
|
||||||
pub credential: CredentialSpendingData,
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
|
||||||
#[non_exhaustive]
|
|
||||||
pub enum UpgradeModeCheckRequest {
|
|
||||||
/// Attempt to request upgrade mode recheck via the JWT issued as the result of
|
|
||||||
/// global attestation.json being published
|
|
||||||
UpgradeModeJwt { token: String },
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use super::{v1, v2, v3, v4, v5, v6};
|
use super::{v1, v2, v3, v4, v5};
|
||||||
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
use nym_service_provider_requests_common::{Protocol, ServiceProviderType};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, strum_macros::Display)]
|
#[derive(Copy, Clone, Debug, PartialEq, strum_macros::Display)]
|
||||||
@@ -22,15 +22,11 @@ pub enum AuthenticatorVersion {
|
|||||||
/// introduced in dorina-patched release (1.6.1)
|
/// introduced in dorina-patched release (1.6.1)
|
||||||
V5,
|
V5,
|
||||||
|
|
||||||
/// introduced in niolo release (1.23.0)
|
|
||||||
V6,
|
|
||||||
|
|
||||||
/// an unknown, future, variant that can be present if running outdated software
|
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AuthenticatorVersion {
|
impl AuthenticatorVersion {
|
||||||
pub const LATEST: Self = Self::V6;
|
pub const LATEST: Self = Self::V5;
|
||||||
|
|
||||||
pub const fn release_version(&self) -> semver::Version {
|
pub const fn release_version(&self) -> semver::Version {
|
||||||
match self {
|
match self {
|
||||||
@@ -39,7 +35,6 @@ impl AuthenticatorVersion {
|
|||||||
AuthenticatorVersion::V3 => semver::Version::new(1, 1, 10),
|
AuthenticatorVersion::V3 => semver::Version::new(1, 1, 10),
|
||||||
AuthenticatorVersion::V4 => semver::Version::new(1, 2, 0),
|
AuthenticatorVersion::V4 => semver::Version::new(1, 2, 0),
|
||||||
AuthenticatorVersion::V5 => semver::Version::new(1, 6, 1),
|
AuthenticatorVersion::V5 => semver::Version::new(1, 6, 1),
|
||||||
AuthenticatorVersion::V6 => semver::Version::new(1, 23, 0),
|
|
||||||
AuthenticatorVersion::UNKNOWN => semver::Version::new(0, 0, 0),
|
AuthenticatorVersion::UNKNOWN => semver::Version::new(0, 0, 0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,8 +54,6 @@ impl From<Protocol> for AuthenticatorVersion {
|
|||||||
AuthenticatorVersion::V4
|
AuthenticatorVersion::V4
|
||||||
} else if value.version == v5::VERSION {
|
} else if value.version == v5::VERSION {
|
||||||
AuthenticatorVersion::V5
|
AuthenticatorVersion::V5
|
||||||
} else if value.version == v6::VERSION {
|
|
||||||
AuthenticatorVersion::V6
|
|
||||||
} else {
|
} else {
|
||||||
AuthenticatorVersion::UNKNOWN
|
AuthenticatorVersion::UNKNOWN
|
||||||
}
|
}
|
||||||
@@ -79,8 +72,6 @@ impl From<u8> for AuthenticatorVersion {
|
|||||||
AuthenticatorVersion::V4
|
AuthenticatorVersion::V4
|
||||||
} else if value == v5::VERSION {
|
} else if value == v5::VERSION {
|
||||||
AuthenticatorVersion::V5
|
AuthenticatorVersion::V5
|
||||||
} else if value == v6::VERSION {
|
|
||||||
AuthenticatorVersion::V6
|
|
||||||
} else {
|
} else {
|
||||||
AuthenticatorVersion::UNKNOWN
|
AuthenticatorVersion::UNKNOWN
|
||||||
}
|
}
|
||||||
@@ -135,14 +126,11 @@ impl From<semver::Version> for AuthenticatorVersion {
|
|||||||
if semver < AuthenticatorVersion::V5.release_version() {
|
if semver < AuthenticatorVersion::V5.release_version() {
|
||||||
return Self::V4;
|
return Self::V4;
|
||||||
}
|
}
|
||||||
if semver < AuthenticatorVersion::V6.release_version() {
|
// if provided version is higher (or equal) to release version of V5,
|
||||||
return Self::V5;
|
// we return the latest (i.e. v5)
|
||||||
}
|
|
||||||
// if provided version is higher (or equal) to release version of V6,
|
|
||||||
// we return the latest (i.e. v6)
|
|
||||||
|
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
Self::V6,
|
Self::V5,
|
||||||
Self::LATEST,
|
Self::LATEST,
|
||||||
"a new AuthenticatorVersion variant has been introduced without adjusting the `From<semver::Version>` trait"
|
"a new AuthenticatorVersion variant has been introduced without adjusting the `From<semver::Version>` trait"
|
||||||
);
|
);
|
||||||
@@ -203,9 +191,5 @@ mod tests {
|
|||||||
assert_eq!(AuthenticatorVersion::V5, "1.7.0".into());
|
assert_eq!(AuthenticatorVersion::V5, "1.7.0".into());
|
||||||
assert_eq!(AuthenticatorVersion::V5, "1.16.11".into());
|
assert_eq!(AuthenticatorVersion::V5, "1.16.11".into());
|
||||||
assert_eq!(AuthenticatorVersion::V5, "1.17.0".into());
|
assert_eq!(AuthenticatorVersion::V5, "1.17.0".into());
|
||||||
assert_eq!(AuthenticatorVersion::V5, "1.22.0".into());
|
|
||||||
assert_eq!(AuthenticatorVersion::V6, "1.23.0".into());
|
|
||||||
assert_eq!(AuthenticatorVersion::V6, "1.23.1".into());
|
|
||||||
assert_eq!(AuthenticatorVersion::V6, "1.24.0".into());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,16 +7,21 @@ license.workspace = true
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = { workspace = true }
|
async-trait = { workspace = true }
|
||||||
|
bip39 = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
rand = { workspace = true }
|
rand = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
|
url = { workspace = true }
|
||||||
|
zeroize = { workspace = true }
|
||||||
|
|
||||||
nym-credential-storage = { path = "../credential-storage" }
|
nym-credential-storage = { path = "../credential-storage" }
|
||||||
nym-credentials = { path = "../credentials" }
|
nym-credentials = { path = "../credentials" }
|
||||||
nym-credentials-interface = { path = "../credentials-interface" }
|
nym-credentials-interface = { path = "../credentials-interface" }
|
||||||
nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "stream_cipher", "aes", "hashing"] }
|
nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "stream_cipher", "aes", "hashing"] }
|
||||||
|
nym-ecash-contract-common = { path = "../cosmwasm-smart-contracts/ecash-contract" }
|
||||||
nym-ecash-time = { path = "../ecash-time" }
|
nym-ecash-time = { path = "../ecash-time" }
|
||||||
|
nym-network-defaults = { path = "../network-defaults" }
|
||||||
nym-task = { path = "../task" }
|
nym-task = { path = "../task" }
|
||||||
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
|
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,6 @@ pub enum BandwidthControllerError {
|
|||||||
#[error("There was a credential storage error - {0}")]
|
#[error("There was a credential storage error - {0}")]
|
||||||
CredentialStorageError(Box<dyn std::error::Error + Send + Sync>),
|
CredentialStorageError(Box<dyn std::error::Error + Send + Sync>),
|
||||||
|
|
||||||
#[error("retrieved upgrade mode token is not a valid String")]
|
|
||||||
MalformedUpgradeModeToken,
|
|
||||||
|
|
||||||
#[error("the credential storage does not contain any usable credentials")]
|
#[error("the credential storage does not contain any usable credentials")]
|
||||||
NoCredentialsAvailable,
|
NoCredentialsAvailable,
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use crate::utils::{
|
|||||||
ApiClientsWrapper,
|
ApiClientsWrapper,
|
||||||
};
|
};
|
||||||
use log::error;
|
use log::error;
|
||||||
use nym_credential_storage::models::{EmergencyCredential, RetrievedTicketbook};
|
use nym_credential_storage::models::RetrievedTicketbook;
|
||||||
use nym_credential_storage::storage::Storage;
|
use nym_credential_storage::storage::Storage;
|
||||||
use nym_credentials::ecash::bandwidth::CredentialSpendingData;
|
use nym_credentials::ecash::bandwidth::CredentialSpendingData;
|
||||||
use nym_credentials_interface::{
|
use nym_credentials_interface::{
|
||||||
@@ -220,19 +220,6 @@ impl<C, St: Storage> BandwidthController<C, St> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_emergency_credential(
|
|
||||||
&self,
|
|
||||||
typ: &str,
|
|
||||||
) -> Result<Option<EmergencyCredential>, BandwidthControllerError>
|
|
||||||
where
|
|
||||||
<St as Storage>::StorageError: Send + Sync + 'static,
|
|
||||||
{
|
|
||||||
self.storage
|
|
||||||
.get_emergency_credential(typ)
|
|
||||||
.await
|
|
||||||
.map_err(BandwidthControllerError::credential_storage_error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, St> Clone for BandwidthController<C, St>
|
impl<C, St> Clone for BandwidthController<C, St>
|
||||||
|
|||||||
@@ -11,9 +11,6 @@ use crate::{error::BandwidthControllerError, BandwidthController, PreparedCreden
|
|||||||
|
|
||||||
pub const DEFAULT_TICKETS_TO_SPEND: u32 = 1;
|
pub const DEFAULT_TICKETS_TO_SPEND: u32 = 1;
|
||||||
|
|
||||||
// TODO: this does not really belong here
|
|
||||||
pub const UPGRADE_MODE_JWT_TYPE: &str = "UPGRADE_MODE_JWT";
|
|
||||||
|
|
||||||
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
||||||
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
|
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
|
||||||
pub trait BandwidthTicketProvider: Send + Sync {
|
pub trait BandwidthTicketProvider: Send + Sync {
|
||||||
@@ -23,8 +20,6 @@ pub trait BandwidthTicketProvider: Send + Sync {
|
|||||||
gateway_id: ed25519::PublicKey,
|
gateway_id: ed25519::PublicKey,
|
||||||
tickets_to_spend: u32,
|
tickets_to_spend: u32,
|
||||||
) -> Result<PreparedCredential, BandwidthControllerError>;
|
) -> Result<PreparedCredential, BandwidthControllerError>;
|
||||||
|
|
||||||
async fn get_upgrade_mode_token(&self) -> Result<Option<String>, BandwidthControllerError>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
||||||
@@ -44,16 +39,4 @@ where
|
|||||||
self.prepare_ecash_ticket(ticket_type, gateway_id.to_bytes(), tickets_to_spend)
|
self.prepare_ecash_ticket(ticket_type, gateway_id.to_bytes(), tickets_to_spend)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_upgrade_mode_token(&self) -> Result<Option<String>, BandwidthControllerError> {
|
|
||||||
let Some(emergency_credential) =
|
|
||||||
self.get_emergency_credential(UPGRADE_MODE_JWT_TYPE).await?
|
|
||||||
else {
|
|
||||||
return Ok(None);
|
|
||||||
};
|
|
||||||
// upgrade mode credential is just a simple stringified JWT
|
|
||||||
let token = String::from_utf8(emergency_credential.data.content)
|
|
||||||
.map_err(|_| BandwidthControllerError::MalformedUpgradeModeToken)?;
|
|
||||||
Ok(Some(token))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,10 +81,6 @@ pub struct CommonClientInitArgs {
|
|||||||
#[cfg_attr(feature = "cli", clap(long, hide = true))]
|
#[cfg_attr(feature = "cli", clap(long, hide = true))]
|
||||||
pub enabled_credentials_mode: Option<bool>,
|
pub enabled_credentials_mode: Option<bool>,
|
||||||
|
|
||||||
/// Change the default minimum node performance used during initial node selection filtering.
|
|
||||||
#[cfg_attr(feature = "cli", clap(long, hide = true))]
|
|
||||||
pub minimum_gateway_performance: Option<u8>,
|
|
||||||
|
|
||||||
/// Mostly debug-related option to increase default traffic rate so that you would not need to
|
/// Mostly debug-related option to increase default traffic rate so that you would not need to
|
||||||
/// modify config post init
|
/// modify config post init
|
||||||
#[cfg_attr(feature = "cli", clap(long, hide = true))]
|
#[cfg_attr(feature = "cli", clap(long, hide = true))]
|
||||||
@@ -177,14 +173,10 @@ where
|
|||||||
})?;
|
})?;
|
||||||
hardcoded_topology.entry_capable_nodes().cloned().collect()
|
hardcoded_topology.entry_capable_nodes().cloned().collect()
|
||||||
} else {
|
} else {
|
||||||
let minimum_performance = common_args
|
|
||||||
.minimum_gateway_performance
|
|
||||||
.unwrap_or(core.debug.topology.minimum_gateway_performance);
|
|
||||||
|
|
||||||
crate::init::helpers::gateways_for_init(
|
crate::init::helpers::gateways_for_init(
|
||||||
&core.client.nym_api_urls,
|
&core.client.nym_api_urls,
|
||||||
user_agent,
|
user_agent,
|
||||||
minimum_performance,
|
core.debug.topology.minimum_gateway_performance,
|
||||||
core.debug.topology.ignore_ingress_epoch_role,
|
core.debug.topology.ignore_ingress_epoch_role,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ pub enum ClientCoreError {
|
|||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
#[error("resolution failed: {0}")]
|
#[error("resolution failed: {0}")]
|
||||||
ResolutionFailed(#[from] nym_http_api_client::ResolveError),
|
ResolutionFailed(#[from] nym_http_api_client::HickoryDnsError),
|
||||||
|
|
||||||
#[error("no gateways on network")]
|
#[error("no gateways on network")]
|
||||||
NoGatewaysOnNetwork,
|
NoGatewaysOnNetwork,
|
||||||
|
|||||||
@@ -441,7 +441,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_multiple_urls_prepared_for_retries() {
|
fn test_multiple_urls_prepared_for_retries() {
|
||||||
let urls = [
|
let urls = vec![
|
||||||
Url::parse("https://api1.nym.com").unwrap(),
|
Url::parse("https://api1.nym.com").unwrap(),
|
||||||
Url::parse("https://api2.nym.com").unwrap(),
|
Url::parse("https://api2.nym.com").unwrap(),
|
||||||
Url::parse("https://api3.nym.com").unwrap(),
|
Url::parse("https://api3.nym.com").unwrap(),
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ pub(crate) async fn connect_async(
|
|||||||
resolver
|
resolver
|
||||||
.resolve_str(domain)
|
.resolve_str(domain)
|
||||||
.await?
|
.await?
|
||||||
|
.into_iter()
|
||||||
.map(|a| SocketAddr::new(a, port))
|
.map(|a| SocketAddr::new(a, port))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,6 +88,3 @@ features = ["js"]
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
wasm = []
|
wasm = []
|
||||||
|
|
||||||
[lints]
|
|
||||||
workspace = true
|
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use si_scale::helpers::bibytes2;
|
use si_scale::helpers::bibytes2;
|
||||||
use std::fmt::{Display, Formatter};
|
|
||||||
use std::sync::atomic::{AtomicBool, AtomicI64, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicI64, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@@ -27,39 +26,6 @@ pub struct ClientBandwidth {
|
|||||||
inner: Arc<ClientBandwidthInner>,
|
inner: Arc<ClientBandwidthInner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// simple helper for logging purposes to accommodate 'unknown' case
|
|
||||||
pub(crate) enum UpgradeModeEnabledWrapper {
|
|
||||||
True,
|
|
||||||
False,
|
|
||||||
Unknown,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Option<bool>> for UpgradeModeEnabledWrapper {
|
|
||||||
fn from(value: Option<bool>) -> Self {
|
|
||||||
match value {
|
|
||||||
Some(true) => UpgradeModeEnabledWrapper::True,
|
|
||||||
Some(false) => UpgradeModeEnabledWrapper::False,
|
|
||||||
None => UpgradeModeEnabledWrapper::Unknown,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<bool> for UpgradeModeEnabledWrapper {
|
|
||||||
fn from(value: bool) -> Self {
|
|
||||||
Some(value).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for UpgradeModeEnabledWrapper {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
UpgradeModeEnabledWrapper::True => write!(f, "true"),
|
|
||||||
UpgradeModeEnabledWrapper::False => write!(f, "false"),
|
|
||||||
UpgradeModeEnabledWrapper::Unknown => write!(f, "unknown"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ClientBandwidthInner {
|
struct ClientBandwidthInner {
|
||||||
/// the actual bandwidth amount (in bytes) available
|
/// the actual bandwidth amount (in bytes) available
|
||||||
available: AtomicI64,
|
available: AtomicI64,
|
||||||
@@ -105,41 +71,26 @@ impl ClientBandwidth {
|
|||||||
self.inner.available.load(Ordering::Acquire)
|
self.inner.available.load(Ordering::Acquire)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn maybe_log_bandwidth(
|
pub(crate) fn maybe_log_bandwidth(&self, now: Option<OffsetDateTime>) {
|
||||||
&self,
|
|
||||||
now: Option<OffsetDateTime>,
|
|
||||||
upgrade_mode: impl Into<UpgradeModeEnabledWrapper>,
|
|
||||||
) {
|
|
||||||
let last = self.last_logged();
|
let last = self.last_logged();
|
||||||
let now = now.unwrap_or_else(OffsetDateTime::now_utc);
|
let now = now.unwrap_or_else(OffsetDateTime::now_utc);
|
||||||
if last + Duration::from_secs(10) < now {
|
if last + Duration::from_secs(10) < now {
|
||||||
self.log_bandwidth(Some(now), upgrade_mode)
|
self.log_bandwidth(Some(now))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn log_bandwidth(
|
pub(crate) fn log_bandwidth(&self, now: Option<OffsetDateTime>) {
|
||||||
&self,
|
|
||||||
now: Option<OffsetDateTime>,
|
|
||||||
upgrade_mode: impl Into<UpgradeModeEnabledWrapper>,
|
|
||||||
) {
|
|
||||||
let now = now.unwrap_or_else(OffsetDateTime::now_utc);
|
let now = now.unwrap_or_else(OffsetDateTime::now_utc);
|
||||||
let upgrade_mode = upgrade_mode.into();
|
|
||||||
|
|
||||||
let remaining = self.remaining();
|
let remaining = self.remaining();
|
||||||
let remaining_bi2 = bibytes2(remaining as f64);
|
let remaining_bi2 = bibytes2(remaining as f64);
|
||||||
|
|
||||||
if remaining < 0 {
|
if remaining < 0 {
|
||||||
tracing::warn!(
|
tracing::warn!("OUT OF BANDWIDTH. remaining: {remaining_bi2}");
|
||||||
"OUT OF BANDWIDTH. remaining: {remaining_bi2}. in 'upgrade mode': {upgrade_mode}"
|
|
||||||
);
|
|
||||||
} else if remaining < 1_000_000 {
|
} else if remaining < 1_000_000 {
|
||||||
tracing::info!(
|
tracing::info!("remaining bandwidth: {remaining_bi2}");
|
||||||
"remaining bandwidth: {remaining_bi2}. in 'upgrade mode': {upgrade_mode}"
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
tracing::trace!(
|
tracing::debug!("remaining bandwidth: {remaining_bi2}");
|
||||||
"remaining bandwidth: {remaining_bi2}. in 'upgrade mode': {upgrade_mode}"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.inner
|
self.inner
|
||||||
@@ -147,35 +98,26 @@ impl ClientBandwidth {
|
|||||||
.store(now.unix_timestamp(), Ordering::Relaxed)
|
.store(now.unix_timestamp(), Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn update_and_maybe_log(
|
pub(crate) fn update_and_maybe_log(&self, remaining: i64) {
|
||||||
&self,
|
|
||||||
remaining: i64,
|
|
||||||
upgrade_mode: impl Into<UpgradeModeEnabledWrapper>,
|
|
||||||
) {
|
|
||||||
let now = OffsetDateTime::now_utc();
|
let now = OffsetDateTime::now_utc();
|
||||||
self.inner.available.store(remaining, Ordering::Release);
|
self.inner.available.store(remaining, Ordering::Release);
|
||||||
self.inner
|
self.inner
|
||||||
.last_updated_ts
|
.last_updated_ts
|
||||||
.store(now.unix_timestamp(), Ordering::Relaxed);
|
.store(now.unix_timestamp(), Ordering::Relaxed);
|
||||||
self.maybe_log_bandwidth(Some(now), upgrade_mode)
|
self.maybe_log_bandwidth(Some(now))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn update_and_log(
|
pub(crate) fn update_and_log(&self, remaining: i64) {
|
||||||
&self,
|
|
||||||
remaining: i64,
|
|
||||||
upgrade_mode: impl Into<UpgradeModeEnabledWrapper>,
|
|
||||||
) {
|
|
||||||
let now = OffsetDateTime::now_utc();
|
let now = OffsetDateTime::now_utc();
|
||||||
self.inner.available.store(remaining, Ordering::Release);
|
self.inner.available.store(remaining, Ordering::Release);
|
||||||
self.inner
|
self.inner
|
||||||
.last_updated_ts
|
.last_updated_ts
|
||||||
.store(now.unix_timestamp(), Ordering::Relaxed);
|
.store(now.unix_timestamp(), Ordering::Relaxed);
|
||||||
self.log_bandwidth(Some(now), upgrade_mode)
|
self.log_bandwidth(Some(now))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn last_logged(&self) -> OffsetDateTime {
|
fn last_logged(&self) -> OffsetDateTime {
|
||||||
// SAFETY: this value is always populated with valid timestamps
|
// SAFETY: this value is always populated with valid timestamps
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
OffsetDateTime::from_unix_timestamp(self.inner.last_logged_ts.load(Ordering::Relaxed))
|
OffsetDateTime::from_unix_timestamp(self.inner.last_logged_ts.load(Ordering::Relaxed))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::error::GatewayClientError;
|
use crate::error::GatewayClientError;
|
||||||
use nym_credentials_interface::DEFAULT_MIXNET_REQUEST_BANDWIDTH_THRESHOLD;
|
use nym_network_defaults::TicketTypeRepr::V1MixnetEntry;
|
||||||
use si_scale::helpers::bibytes2;
|
use si_scale::helpers::bibytes2;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ impl BandwidthTickets {
|
|||||||
|
|
||||||
// 20% of entry ticket value
|
// 20% of entry ticket value
|
||||||
pub const DEFAULT_REMAINING_BANDWIDTH_THRESHOLD: i64 =
|
pub const DEFAULT_REMAINING_BANDWIDTH_THRESHOLD: i64 =
|
||||||
DEFAULT_MIXNET_REQUEST_BANDWIDTH_THRESHOLD;
|
(V1MixnetEntry.bandwidth_value() / 5) as i64;
|
||||||
|
|
||||||
pub const DEFAULT_CUTOFF_REMAINING_BANDWIDTH_THRESHOLD: Option<i64> = None;
|
pub const DEFAULT_CUTOFF_REMAINING_BANDWIDTH_THRESHOLD: Option<i64> = None;
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ use nym_credentials_interface::TicketType;
|
|||||||
use nym_crypto::asymmetric::ed25519;
|
use nym_crypto::asymmetric::ed25519;
|
||||||
use nym_gateway_requests::registration::handshake::client_handshake;
|
use nym_gateway_requests::registration::handshake::client_handshake;
|
||||||
use nym_gateway_requests::{
|
use nym_gateway_requests::{
|
||||||
BandwidthResponse, BinaryRequest, ClientControlRequest, ClientRequest, GatewayProtocolVersion,
|
BinaryRequest, ClientControlRequest, ClientRequest, GatewayProtocolVersionExt,
|
||||||
GatewayProtocolVersionExt, GatewayRequestsError, SensitiveServerResponse, ServerResponse,
|
GatewayRequestsError, SensitiveServerResponse, ServerResponse, SharedGatewayKey,
|
||||||
SharedGatewayKey, SharedSymmetricKey, CREDENTIAL_UPDATE_V2_PROTOCOL_VERSION,
|
SharedSymmetricKey, CREDENTIAL_UPDATE_V2_PROTOCOL_VERSION, CURRENT_PROTOCOL_VERSION,
|
||||||
};
|
};
|
||||||
use nym_sphinx::forwarding::packet::MixPacket;
|
use nym_sphinx::forwarding::packet::MixPacket;
|
||||||
use nym_statistics_common::clients::connection::ConnectionStatsEvent;
|
use nym_statistics_common::clients::connection::ConnectionStatsEvent;
|
||||||
@@ -101,7 +101,8 @@ pub struct GatewayClient<C, St = EphemeralCredentialStorage> {
|
|||||||
bandwidth_controller: Option<BandwidthController<C, St>>,
|
bandwidth_controller: Option<BandwidthController<C, St>>,
|
||||||
stats_reporter: ClientStatsSender,
|
stats_reporter: ClientStatsSender,
|
||||||
|
|
||||||
negotiated_protocol: Option<GatewayProtocolVersion>,
|
// currently unused (but populated)
|
||||||
|
negotiated_protocol: Option<u8>,
|
||||||
|
|
||||||
// Callback on the fd as soon as the connection has been established
|
// Callback on the fd as soon as the connection has been established
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@@ -165,12 +166,10 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
#[allow(clippy::unreachable)]
|
|
||||||
async fn _close_connection(&mut self) -> Result<(), GatewayClientError> {
|
async fn _close_connection(&mut self) -> Result<(), GatewayClientError> {
|
||||||
match std::mem::replace(&mut self.connection, SocketState::NotConnected) {
|
match std::mem::replace(&mut self.connection, SocketState::NotConnected) {
|
||||||
SocketState::Available(mut socket) => Ok((*socket).close(None).await?),
|
SocketState::Available(mut socket) => Ok((*socket).close(None).await?),
|
||||||
SocketState::PartiallyDelegated(_) => {
|
SocketState::PartiallyDelegated(_) => {
|
||||||
// SAFETY: this is only called after the caller has already recovered the connection
|
|
||||||
unreachable!("this branch should have never been reached!")
|
unreachable!("this branch should have never been reached!")
|
||||||
}
|
}
|
||||||
_ => Ok(()), // no need to do anything in those cases
|
_ => Ok(()), // no need to do anything in those cases
|
||||||
@@ -178,7 +177,6 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
#[allow(clippy::unreachable)]
|
|
||||||
async fn _close_connection(&mut self) -> Result<(), GatewayClientError> {
|
async fn _close_connection(&mut self) -> Result<(), GatewayClientError> {
|
||||||
match std::mem::replace(&mut self.connection, SocketState::NotConnected) {
|
match std::mem::replace(&mut self.connection, SocketState::NotConnected) {
|
||||||
SocketState::Available(socket) => {
|
SocketState::Available(socket) => {
|
||||||
@@ -186,7 +184,6 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SocketState::PartiallyDelegated(_) => {
|
SocketState::PartiallyDelegated(_) => {
|
||||||
// SAFETY: this is only called after the caller has already recovered the connection
|
|
||||||
unreachable!("this branch should have never been reached!")
|
unreachable!("this branch should have never been reached!")
|
||||||
}
|
}
|
||||||
_ => Ok(()), // no need to do anything in those cases
|
_ => Ok(()), // no need to do anything in those cases
|
||||||
@@ -461,16 +458,43 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_gateway_protocol(
|
||||||
|
&self,
|
||||||
|
gateway_protocol: Option<u8>,
|
||||||
|
) -> Result<(), GatewayClientError> {
|
||||||
|
debug!("gateway protocol: {gateway_protocol:?}, ours: {CURRENT_PROTOCOL_VERSION}");
|
||||||
|
|
||||||
|
// right now there are no failure cases here, but this might change in the future
|
||||||
|
match gateway_protocol {
|
||||||
|
None => {
|
||||||
|
warn!("the gateway we're connected to has not specified its protocol version. It's probably running version < 1.1.X, but that's still fine for now. It will become a hard error in 1.2.0");
|
||||||
|
// note: in +1.2.0 we will have to return a hard error here
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Some(v) if v > CURRENT_PROTOCOL_VERSION => {
|
||||||
|
let err = GatewayClientError::IncompatibleProtocol {
|
||||||
|
gateway: Some(v),
|
||||||
|
current: CURRENT_PROTOCOL_VERSION,
|
||||||
|
};
|
||||||
|
error!("{err}");
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(_) => {
|
||||||
|
debug!("the gateway is using exactly the same (or older) protocol version as we are. We're good to continue!");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn register(
|
async fn register(
|
||||||
&mut self,
|
&mut self,
|
||||||
supported_gateway_protocol: Option<GatewayProtocolVersion>,
|
derive_aes256_gcm_siv_key: bool,
|
||||||
) -> Result<(), GatewayClientError> {
|
) -> Result<(), GatewayClientError> {
|
||||||
if !self.connection.is_established() {
|
if !self.connection.is_established() {
|
||||||
return Err(GatewayClientError::ConnectionNotEstablished);
|
return Err(GatewayClientError::ConnectionNotEstablished);
|
||||||
}
|
}
|
||||||
|
|
||||||
let derive_aes256_gcm_siv_key = supported_gateway_protocol.supports_aes256_gcm_siv();
|
|
||||||
|
|
||||||
debug_assert!(self.connection.is_available());
|
debug_assert!(self.connection.is_available());
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"registering with gateway. using legacy key derivation: {}",
|
"registering with gateway. using legacy key derivation: {}",
|
||||||
@@ -481,13 +505,14 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
// and putting it into the GatewayClient struct would be a hassle
|
// and putting it into the GatewayClient struct would be a hassle
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
|
|
||||||
let handshake_result = match &mut self.connection {
|
let shared_key = match &mut self.connection {
|
||||||
SocketState::Available(ws_stream) => client_handshake(
|
SocketState::Available(ws_stream) => client_handshake(
|
||||||
&mut rng,
|
&mut rng,
|
||||||
ws_stream,
|
ws_stream,
|
||||||
self.local_identity.as_ref(),
|
self.local_identity.as_ref(),
|
||||||
self.gateway_identity,
|
self.gateway_identity,
|
||||||
supported_gateway_protocol,
|
self.cfg.bandwidth.require_tickets,
|
||||||
|
derive_aes256_gcm_siv_key,
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
self.shutdown_token.clone(),
|
self.shutdown_token.clone(),
|
||||||
)
|
)
|
||||||
@@ -496,31 +521,26 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
_ => return Err(GatewayClientError::ConnectionInInvalidState),
|
_ => return Err(GatewayClientError::ConnectionInInvalidState),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
let authentication_status = match self.read_control_response().await? {
|
let (authentication_status, gateway_protocol) = match self.read_control_response().await? {
|
||||||
ServerResponse::Register {
|
ServerResponse::Register {
|
||||||
|
protocol_version,
|
||||||
status,
|
status,
|
||||||
upgrade_mode,
|
} => (status, protocol_version),
|
||||||
..
|
|
||||||
} => {
|
|
||||||
if upgrade_mode {
|
|
||||||
warn!("the system is currently undergoing an upgrade. some of its functionalities might be unstable")
|
|
||||||
}
|
|
||||||
status
|
|
||||||
}
|
|
||||||
ServerResponse::Error { message } => {
|
ServerResponse::Error { message } => {
|
||||||
return Err(GatewayClientError::GatewayError(message))
|
return Err(GatewayClientError::GatewayError(message))
|
||||||
}
|
}
|
||||||
other => return Err(GatewayClientError::UnexpectedResponse { name: other.name() }),
|
other => return Err(GatewayClientError::UnexpectedResponse { name: other.name() }),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.check_gateway_protocol(gateway_protocol)?;
|
||||||
self.authenticated = authentication_status;
|
self.authenticated = authentication_status;
|
||||||
|
|
||||||
if self.authenticated {
|
if self.authenticated {
|
||||||
self.shared_key = Some(Arc::new(handshake_result.derived_key));
|
self.shared_key = Some(Arc::new(shared_key));
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate the negotiated protocol for future uses
|
// populate the negotiated protocol for future uses
|
||||||
self.negotiated_protocol = Some(handshake_result.negotiated_protocol);
|
self.negotiated_protocol = gateway_protocol;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -603,24 +623,13 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
protocol_version,
|
protocol_version,
|
||||||
status,
|
status,
|
||||||
bandwidth_remaining,
|
bandwidth_remaining,
|
||||||
upgrade_mode,
|
|
||||||
} => {
|
} => {
|
||||||
if protocol_version.is_future_version() {
|
self.check_gateway_protocol(protocol_version)?;
|
||||||
// SAFETY: future version is always defined
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
let version = protocol_version.unwrap();
|
|
||||||
error!("the gateway insists on using v{version} protocol which is not supported by this client");
|
|
||||||
return Err(GatewayClientError::AuthenticationFailure);
|
|
||||||
}
|
|
||||||
self.authenticated = status;
|
self.authenticated = status;
|
||||||
self.bandwidth
|
self.bandwidth.update_and_maybe_log(bandwidth_remaining);
|
||||||
.update_and_maybe_log(bandwidth_remaining, upgrade_mode);
|
|
||||||
|
|
||||||
self.negotiated_protocol = protocol_version;
|
self.negotiated_protocol = protocol_version;
|
||||||
log::debug!("authenticated: {status}, bandwidth remaining: {bandwidth_remaining}");
|
log::debug!("authenticated: {status}, bandwidth remaining: {bandwidth_remaining}");
|
||||||
if upgrade_mode {
|
|
||||||
warn!("the system is currently undergoing an upgrade. some of its functionalities might be unstable")
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -641,7 +650,7 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
.public_key()
|
.public_key()
|
||||||
.derive_destination_address();
|
.derive_destination_address();
|
||||||
|
|
||||||
let msg = ClientControlRequest::new_legacy_authenticate(
|
let msg = ClientControlRequest::new_authenticate(
|
||||||
self_address,
|
self_address,
|
||||||
shared_key,
|
shared_key,
|
||||||
self.cfg.bandwidth.require_tickets,
|
self.cfg.bandwidth.require_tickets,
|
||||||
@@ -650,40 +659,25 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn authenticate_v2(
|
async fn authenticate_v2(&mut self) -> Result<(), GatewayClientError> {
|
||||||
&mut self,
|
|
||||||
requested_protocol_version: GatewayProtocolVersion,
|
|
||||||
) -> Result<(), GatewayClientError> {
|
|
||||||
debug!("using v2 authentication");
|
debug!("using v2 authentication");
|
||||||
let Some(shared_key) = self.shared_key.as_ref() else {
|
let Some(shared_key) = self.shared_key.as_ref() else {
|
||||||
return Err(GatewayClientError::NoSharedKeyAvailable);
|
return Err(GatewayClientError::NoSharedKeyAvailable);
|
||||||
};
|
};
|
||||||
|
|
||||||
let msg = ClientControlRequest::new_authenticate_v2(
|
let msg = ClientControlRequest::new_authenticate_v2(shared_key, &self.local_identity)?;
|
||||||
shared_key,
|
|
||||||
&self.local_identity,
|
|
||||||
requested_protocol_version,
|
|
||||||
)?;
|
|
||||||
self.send_authenticate_request_and_handle_response(msg)
|
self.send_authenticate_request_and_handle_response(msg)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn authenticate(
|
async fn authenticate(&mut self, use_v2: bool) -> Result<(), GatewayClientError> {
|
||||||
&mut self,
|
|
||||||
supported_gateway_protocol: Option<GatewayProtocolVersion>,
|
|
||||||
) -> Result<(), GatewayClientError> {
|
|
||||||
if !self.connection.is_established() {
|
if !self.connection.is_established() {
|
||||||
return Err(GatewayClientError::ConnectionNotEstablished);
|
return Err(GatewayClientError::ConnectionNotEstablished);
|
||||||
}
|
}
|
||||||
debug!("authenticating with gateway");
|
debug!("authenticating with gateway");
|
||||||
|
|
||||||
if supported_gateway_protocol.supports_authenticate_v2() {
|
if use_v2 {
|
||||||
// use the highest possible protocol version the gateway has announced support for
|
self.authenticate_v2().await
|
||||||
|
|
||||||
// SAFETY: if announced protocol supports auth v2, it means it's properly set
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
self.authenticate_v2(supported_gateway_protocol.unwrap())
|
|
||||||
.await
|
|
||||||
} else {
|
} else {
|
||||||
self.authenticate_v1().await
|
self.authenticate_v1().await
|
||||||
}
|
}
|
||||||
@@ -714,12 +708,9 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("supported gateway protocol: {gw_protocol:?}");
|
|
||||||
|
|
||||||
let supports_aes_gcm_siv = gw_protocol.supports_aes256_gcm_siv();
|
let supports_aes_gcm_siv = gw_protocol.supports_aes256_gcm_siv();
|
||||||
let supports_auth_v2 = gw_protocol.supports_authenticate_v2();
|
let supports_auth_v2 = gw_protocol.supports_authenticate_v2();
|
||||||
let supports_key_rotation_info = gw_protocol.supports_key_rotation_packet();
|
let supports_key_rotation_info = gw_protocol.supports_key_rotation_packet();
|
||||||
let supports_upgrade_mode = gw_protocol.supports_upgrade_mode();
|
|
||||||
|
|
||||||
if !supports_aes_gcm_siv {
|
if !supports_aes_gcm_siv {
|
||||||
warn!("this gateway is on an old version that doesn't support AES256-GCM-SIV");
|
warn!("this gateway is on an old version that doesn't support AES256-GCM-SIV");
|
||||||
@@ -730,16 +721,6 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
if !supports_key_rotation_info {
|
if !supports_key_rotation_info {
|
||||||
warn!("this gateway is on an old version that doesn't support key rotation packets")
|
warn!("this gateway is on an old version that doesn't support key rotation packets")
|
||||||
}
|
}
|
||||||
if !supports_upgrade_mode {
|
|
||||||
warn!("this gateway is on an old version that doesn't support upgrade mode")
|
|
||||||
}
|
|
||||||
|
|
||||||
let gw_protocol = if gw_protocol.is_future_version() {
|
|
||||||
warn!("we're running outdated software as gateway is announcing protocol {gw_protocol:?} whilst we're using {}. we're going to attempt to downgrade", GatewayProtocolVersion::CURRENT);
|
|
||||||
Some(GatewayProtocolVersion::CURRENT)
|
|
||||||
} else {
|
|
||||||
gw_protocol
|
|
||||||
};
|
|
||||||
|
|
||||||
if self.authenticated {
|
if self.authenticated {
|
||||||
debug!("Already authenticated");
|
debug!("Already authenticated");
|
||||||
@@ -754,11 +735,10 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.shared_key.is_some() {
|
if self.shared_key.is_some() {
|
||||||
self.authenticate(gw_protocol).await?;
|
self.authenticate(supports_auth_v2).await?;
|
||||||
|
|
||||||
if self.authenticated {
|
if self.authenticated {
|
||||||
// if we are authenticated it means we MUST have an associated shared_key
|
// if we are authenticated it means we MUST have an associated shared_key
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
let shared_key = self.shared_key.as_ref().unwrap();
|
let shared_key = self.shared_key.as_ref().unwrap();
|
||||||
|
|
||||||
let requires_key_upgrade = shared_key.is_legacy() && supports_aes_gcm_siv;
|
let requires_key_upgrade = shared_key.is_legacy() && supports_aes_gcm_siv;
|
||||||
@@ -771,10 +751,9 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
Err(GatewayClientError::AuthenticationFailure)
|
Err(GatewayClientError::AuthenticationFailure)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.register(gw_protocol).await?;
|
self.register(supports_aes_gcm_siv).await?;
|
||||||
|
|
||||||
// if registration didn't return an error, we MUST have an associated shared key
|
// if registration didn't return an error, we MUST have an associated shared key
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
let shared_key = self.shared_key.as_ref().unwrap();
|
let shared_key = self.shared_key.as_ref().unwrap();
|
||||||
|
|
||||||
// we're always registering with the highest supported protocol,
|
// we're always registering with the highest supported protocol,
|
||||||
@@ -804,81 +783,51 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn wait_for_bandwidth_response(
|
async fn claim_ecash_bandwidth(
|
||||||
&mut self,
|
&mut self,
|
||||||
msg: ClientControlRequest,
|
credential: CredentialSpendingData,
|
||||||
) -> Result<BandwidthResponse, GatewayClientError> {
|
) -> Result<(), GatewayClientError> {
|
||||||
let response = match self
|
let msg = ClientControlRequest::new_enc_ecash_credential(
|
||||||
|
credential,
|
||||||
|
self.shared_key.as_ref().unwrap(),
|
||||||
|
)?;
|
||||||
|
let bandwidth_remaining = match self
|
||||||
.send_websocket_message_with_non_send_response(msg)
|
.send_websocket_message_with_non_send_response(msg)
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
ServerResponse::Bandwidth(response) => {
|
ServerResponse::Bandwidth { available_total } => Ok(available_total),
|
||||||
if response.upgrade_mode {
|
|
||||||
info!("the system is currently undergoing an upgrade. our bandwidth shouldn't have been metered")
|
|
||||||
}
|
|
||||||
Ok(response)
|
|
||||||
}
|
|
||||||
ServerResponse::Error { message } => Err(GatewayClientError::GatewayError(message)),
|
ServerResponse::Error { message } => Err(GatewayClientError::GatewayError(message)),
|
||||||
ServerResponse::TypedError { error } => {
|
ServerResponse::TypedError { error } => {
|
||||||
Err(GatewayClientError::TypedGatewayError(error))
|
Err(GatewayClientError::TypedGatewayError(error))
|
||||||
}
|
}
|
||||||
other => Err(GatewayClientError::UnexpectedResponse { name: other.name() }),
|
other => Err(GatewayClientError::UnexpectedResponse { name: other.name() }),
|
||||||
}?;
|
}?;
|
||||||
Ok(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn claim_ecash_bandwidth(
|
|
||||||
&mut self,
|
|
||||||
credential: CredentialSpendingData,
|
|
||||||
) -> Result<(), GatewayClientError> {
|
|
||||||
// SAFETY: claiming ecash bandwidth is called as part of `claim_bandwidth` which
|
|
||||||
// ensures the shared key is defined
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
let msg = ClientControlRequest::new_enc_ecash_credential(
|
|
||||||
credential,
|
|
||||||
self.shared_key.as_ref().unwrap(),
|
|
||||||
)?;
|
|
||||||
let response = self.wait_for_bandwidth_response(msg).await?;
|
|
||||||
|
|
||||||
// TODO: create tracing span
|
// TODO: create tracing span
|
||||||
info!("managed to claim ecash bandwidth");
|
info!("managed to claim ecash bandwidth");
|
||||||
self.bandwidth
|
self.bandwidth.update_and_log(bandwidth_remaining);
|
||||||
.update_and_log(response.available_total, response.upgrade_mode);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_upgrade_mode_jwt(&mut self, token: String) -> Result<(), GatewayClientError> {
|
|
||||||
let msg = ClientControlRequest::new_upgrade_mode_jwt(token);
|
|
||||||
let response = self.wait_for_bandwidth_response(msg).await?;
|
|
||||||
|
|
||||||
// if gateway rejected our jwt, we would have returned an error
|
|
||||||
info!("gateway has accepted our jwt");
|
|
||||||
if !response.upgrade_mode {
|
|
||||||
error!("but we're not in upgrade mode - something is wrong!");
|
|
||||||
return Err(GatewayClientError::UnexpectedUpgradeModeState);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.bandwidth
|
|
||||||
.update_and_log(response.available_total, response.upgrade_mode);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn try_claim_testnet_bandwidth(&mut self) -> Result<(), GatewayClientError> {
|
async fn try_claim_testnet_bandwidth(&mut self) -> Result<(), GatewayClientError> {
|
||||||
let msg = ClientControlRequest::ClaimFreeTestnetBandwidth;
|
let msg = ClientControlRequest::ClaimFreeTestnetBandwidth;
|
||||||
let response = self.wait_for_bandwidth_response(msg).await?;
|
let bandwidth_remaining = match self
|
||||||
|
.send_websocket_message_with_non_send_response(msg)
|
||||||
|
.await?
|
||||||
|
{
|
||||||
|
ServerResponse::Bandwidth { available_total } => Ok(available_total),
|
||||||
|
ServerResponse::Error { message } => Err(GatewayClientError::GatewayError(message)),
|
||||||
|
other => Err(GatewayClientError::UnexpectedResponse { name: other.name() }),
|
||||||
|
}?;
|
||||||
|
|
||||||
info!("managed to claim testnet bandwidth");
|
info!("managed to claim testnet bandwidth");
|
||||||
self.bandwidth
|
self.bandwidth.update_and_log(bandwidth_remaining);
|
||||||
.update_and_log(response.available_total, response.upgrade_mode);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unchecked_bandwidth_controller(&self) -> &BandwidthController<C, St> {
|
fn unchecked_bandwidth_controller(&self) -> &BandwidthController<C, St> {
|
||||||
// this is an unchecked method
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
self.bandwidth_controller.as_ref().unwrap()
|
self.bandwidth_controller.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -970,7 +919,6 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
BinaryRequest::ForwardSphinx { packet }
|
BinaryRequest::ForwardSphinx { packet }
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(clippy::expect_used)]
|
|
||||||
req.into_ws_message(
|
req.into_ws_message(
|
||||||
self.shared_key
|
self.shared_key
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -1077,8 +1025,6 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
self.send_with_reconnection_on_failure(msg).await
|
self.send_with_reconnection_on_failure(msg).await
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAFETY: this method is only called when the connection is in `PartiallyDelegated` state
|
|
||||||
#[allow(clippy::unreachable)]
|
|
||||||
async fn recover_socket_connection(&mut self) -> Result<(), GatewayClientError> {
|
async fn recover_socket_connection(&mut self) -> Result<(), GatewayClientError> {
|
||||||
if self.connection.is_available() {
|
if self.connection.is_available() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -1108,7 +1054,6 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
return Err(GatewayClientError::ConnectionInInvalidState);
|
return Err(GatewayClientError::ConnectionInInvalidState);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::expect_used)]
|
|
||||||
let partially_delegated =
|
let partially_delegated =
|
||||||
match std::mem::replace(&mut self.connection, SocketState::Invalid) {
|
match std::mem::replace(&mut self.connection, SocketState::Invalid) {
|
||||||
SocketState::Available(conn) => {
|
SocketState::Available(conn) => {
|
||||||
@@ -1124,13 +1069,7 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
self.shutdown_token.clone(),
|
self.shutdown_token.clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
other => {
|
_ => unreachable!(),
|
||||||
error!(
|
|
||||||
"attempted to start mixnet listener whilst the connection is in {} state!",
|
|
||||||
other.name()
|
|
||||||
);
|
|
||||||
return Err(GatewayClientError::ConnectionInInvalidState);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.connection = SocketState::PartiallyDelegated(partially_delegated);
|
self.connection = SocketState::PartiallyDelegated(partially_delegated);
|
||||||
@@ -1143,7 +1082,8 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if we're reconnecting, because we lost connection, we need to re-authenticate the connection
|
// if we're reconnecting, because we lost connection, we need to re-authenticate the connection
|
||||||
self.authenticate(self.negotiated_protocol).await?;
|
self.authenticate(self.negotiated_protocol.supports_authenticate_v2())
|
||||||
|
.await?;
|
||||||
|
|
||||||
// this call is NON-blocking
|
// this call is NON-blocking
|
||||||
self.start_listening_for_mixnet_messages()?;
|
self.start_listening_for_mixnet_messages()?;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ pub(crate) async fn connect_async(
|
|||||||
resolver
|
resolver
|
||||||
.resolve_str(domain)
|
.resolve_str(domain)
|
||||||
.await?
|
.await?
|
||||||
|
.into_iter()
|
||||||
.map(|a| SocketAddr::new(a, port))
|
.map(|a| SocketAddr::new(a, port))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ pub enum GatewayClientError {
|
|||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
#[error("resolution failed: {0}")]
|
#[error("resolution failed: {0}")]
|
||||||
ResolutionFailed(#[from] nym_http_api_client::ResolveError),
|
ResolutionFailed(#[from] nym_http_api_client::HickoryDnsError),
|
||||||
|
|
||||||
#[error("No shared key was provided or obtained")]
|
#[error("No shared key was provided or obtained")]
|
||||||
NoSharedKeyAvailable,
|
NoSharedKeyAvailable,
|
||||||
@@ -128,9 +128,6 @@ pub enum GatewayClientError {
|
|||||||
"this operation couldn't be completed as the program is in the process of shutting down"
|
"this operation couldn't be completed as the program is in the process of shutting down"
|
||||||
)]
|
)]
|
||||||
ShutdownInProgress,
|
ShutdownInProgress,
|
||||||
|
|
||||||
#[error("the system is an unexpected upgrade mode state")]
|
|
||||||
UnexpectedUpgradeModeState,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<WsError> for GatewayClientError {
|
impl From<WsError> for GatewayClientError {
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ impl PacketRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::panic)]
|
|
||||||
pub fn route_mixnet_messages(
|
pub fn route_mixnet_messages(
|
||||||
&self,
|
&self,
|
||||||
received_messages: Vec<Vec<u8>>,
|
received_messages: Vec<Vec<u8>>,
|
||||||
@@ -55,7 +54,6 @@ impl PacketRouter {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::panic)]
|
|
||||||
pub fn route_acks(&self, received_acks: Vec<Vec<u8>>) -> Result<(), GatewayClientError> {
|
pub fn route_acks(&self, received_acks: Vec<Vec<u8>>) -> Result<(), GatewayClientError> {
|
||||||
if let Err(err) = self.ack_sender.unbounded_send(received_acks) {
|
if let Err(err) = self.ack_sender.unbounded_send(received_acks) {
|
||||||
// check if the failure is due to the shutdown being in progress and thus the receiver channel
|
// check if the failure is due to the shutdown being in progress and thus the receiver channel
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::bandwidth::ClientBandwidth;
|
use crate::bandwidth::ClientBandwidth;
|
||||||
use crate::client::config::BandwidthTickets;
|
|
||||||
use crate::error::GatewayClientError;
|
use crate::error::GatewayClientError;
|
||||||
use crate::packet_router::PacketRouter;
|
use crate::packet_router::PacketRouter;
|
||||||
use crate::traits::GatewayPacketRouter;
|
use crate::traits::GatewayPacketRouter;
|
||||||
@@ -11,9 +10,7 @@ use futures::channel::oneshot;
|
|||||||
use futures::stream::{SplitSink, SplitStream};
|
use futures::stream::{SplitSink, SplitStream};
|
||||||
use futures::{SinkExt, StreamExt};
|
use futures::{SinkExt, StreamExt};
|
||||||
use nym_gateway_requests::shared_key::SharedGatewayKey;
|
use nym_gateway_requests::shared_key::SharedGatewayKey;
|
||||||
use nym_gateway_requests::{
|
use nym_gateway_requests::{SensitiveServerResponse, ServerResponse, SimpleGatewayRequestsError};
|
||||||
SendResponse, SensitiveServerResponse, ServerResponse, SimpleGatewayRequestsError,
|
|
||||||
};
|
|
||||||
use nym_task::ShutdownToken;
|
use nym_task::ShutdownToken;
|
||||||
use si_scale::helpers::bibytes2;
|
use si_scale::helpers::bibytes2;
|
||||||
use std::os::raw::c_int as RawFd;
|
use std::os::raw::c_int as RawFd;
|
||||||
@@ -157,12 +154,11 @@ impl PartiallyDelegatedRouter {
|
|||||||
fn handle_text_message(&self, text: String) -> Result<(), GatewayClientError> {
|
fn handle_text_message(&self, text: String) -> Result<(), GatewayClientError> {
|
||||||
// if we fail to deserialise the response, return a hard error. we can't handle garbage
|
// if we fail to deserialise the response, return a hard error. we can't handle garbage
|
||||||
match ServerResponse::try_from(text).map_err(|_| GatewayClientError::MalformedResponse)? {
|
match ServerResponse::try_from(text).map_err(|_| GatewayClientError::MalformedResponse)? {
|
||||||
ServerResponse::Send(SendResponse {
|
ServerResponse::Send {
|
||||||
remaining_bandwidth,
|
remaining_bandwidth,
|
||||||
upgrade_mode,
|
} => {
|
||||||
}) => {
|
|
||||||
self.client_bandwidth
|
self.client_bandwidth
|
||||||
.update_and_maybe_log(remaining_bandwidth, upgrade_mode);
|
.update_and_maybe_log(remaining_bandwidth);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
ServerResponse::Error { message } => {
|
ServerResponse::Error { message } => {
|
||||||
@@ -178,20 +174,7 @@ impl PartiallyDelegatedRouter {
|
|||||||
let available_bi2 = bibytes2(available as f64);
|
let available_bi2 = bibytes2(available as f64);
|
||||||
let required_bi2 = bibytes2(required as f64);
|
let required_bi2 = bibytes2(required as f64);
|
||||||
warn!("run out of bandwidth when attempting to send the message! we got {available_bi2} available, but needed at least {required_bi2} to send the previous message");
|
warn!("run out of bandwidth when attempting to send the message! we got {available_bi2} available, but needed at least {required_bi2} to send the previous message");
|
||||||
// if we run out of bandwidth (and tried to send reasonable amount of data),
|
self.client_bandwidth.update_and_log(available);
|
||||||
// the upgrade mode is implicitly disabled, as otherwise we would have been
|
|
||||||
// to proceed
|
|
||||||
let upgrade_mode = if available
|
|
||||||
< BandwidthTickets::DEFAULT_REMAINING_BANDWIDTH_THRESHOLD
|
|
||||||
{
|
|
||||||
Some(false)
|
|
||||||
} else {
|
|
||||||
// we were attempting to send a lot of data at once
|
|
||||||
// - we have no certainty about upgrade mode at this point
|
|
||||||
None
|
|
||||||
};
|
|
||||||
self.client_bandwidth
|
|
||||||
.update_and_log(available, upgrade_mode);
|
|
||||||
// UNIMPLEMENTED: we should stop sending messages until we recover bandwidth
|
// UNIMPLEMENTED: we should stop sending messages until we recover bandwidth
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -344,7 +327,6 @@ impl PartiallyDelegatedHandle {
|
|||||||
Ok(self.sink_half.send_all(&mut send_stream).await?)
|
Ok(self.sink_half.send_all(&mut send_stream).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::panic)]
|
|
||||||
pub(crate) async fn merge(self) -> Result<WsConn, GatewayClientError> {
|
pub(crate) async fn merge(self) -> Result<WsConn, GatewayClientError> {
|
||||||
let (mut stream_receiver, notify) = self.delegated_stream;
|
let (mut stream_receiver, notify) = self.delegated_stream;
|
||||||
|
|
||||||
@@ -373,10 +355,8 @@ impl PartiallyDelegatedHandle {
|
|||||||
// in receive_res
|
// in receive_res
|
||||||
.map_err(|_| GatewayClientError::ConnectionAbruptlyClosed)?;
|
.map_err(|_| GatewayClientError::ConnectionAbruptlyClosed)?;
|
||||||
let stream = stream_results?;
|
let stream = stream_results?;
|
||||||
|
|
||||||
// the error is thrown when trying to reunite sink and stream that did not originate
|
// the error is thrown when trying to reunite sink and stream that did not originate
|
||||||
// from the same split which is impossible to happen here
|
// from the same split which is impossible to happen here
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
Ok(self.sink_half.reunite(stream).unwrap())
|
Ok(self.sink_half.reunite(stream).unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -407,13 +387,4 @@ impl SocketState {
|
|||||||
SocketState::Available(_) | SocketState::PartiallyDelegated(_)
|
SocketState::Available(_) | SocketState::PartiallyDelegated(_)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn name(&self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
SocketState::Available(_) => "available",
|
|
||||||
SocketState::PartiallyDelegated(_) => "partially delegated",
|
|
||||||
SocketState::NotConnected => "not connected",
|
|
||||||
SocketState::Invalid => "invalid",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ workspace = true
|
|||||||
features = ["json", "rustls-tls"]
|
features = ["json", "rustls-tls"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
anyhow = { workspace = true }
|
|
||||||
bip39 = { workspace = true }
|
bip39 = { workspace = true }
|
||||||
cosmrs = { workspace = true, features = ["bip32"] }
|
cosmrs = { workspace = true, features = ["bip32"] }
|
||||||
ts-rs = { workspace = true }
|
ts-rs = { workspace = true }
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ use cosmrs::{tx, AccountId, Coin, Denom};
|
|||||||
use nym_validator_client::http_client;
|
use nym_validator_client::http_client;
|
||||||
use nym_validator_client::nyxd::CosmWasmClient;
|
use nym_validator_client::nyxd::CosmWasmClient;
|
||||||
use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet;
|
use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet;
|
||||||
use nym_validator_client::signing::signer::OfflineSigner;
|
|
||||||
use nym_validator_client::signing::tx_signer::TxSigner;
|
use nym_validator_client::signing::tx_signer::TxSigner;
|
||||||
use nym_validator_client::signing::SignerData;
|
use nym_validator_client::signing::SignerData;
|
||||||
|
|
||||||
@@ -20,8 +19,8 @@ async fn main() {
|
|||||||
let validator = "https://rpc.sandbox.nymtech.net";
|
let validator = "https://rpc.sandbox.nymtech.net";
|
||||||
let to_address: AccountId = "n1pefc2utwpy5w78p2kqdsfmpjxfwmn9d39k5mqa".parse().unwrap();
|
let to_address: AccountId = "n1pefc2utwpy5w78p2kqdsfmpjxfwmn9d39k5mqa".parse().unwrap();
|
||||||
|
|
||||||
let signer = DirectSecp256k1HdWallet::checked_from_mnemonic(prefix, signer_mnemonic).unwrap();
|
let signer = DirectSecp256k1HdWallet::from_mnemonic(prefix, signer_mnemonic);
|
||||||
let signer_address = signer.signer_addresses()[0].clone();
|
let signer_address = signer.try_derive_accounts().unwrap()[0].address().clone();
|
||||||
|
|
||||||
// local 'client' ONLY signing messages
|
// local 'client' ONLY signing messages
|
||||||
let tx_signer = signer;
|
let tx_signer = signer;
|
||||||
@@ -58,15 +57,9 @@ async fn main() {
|
|||||||
100000u32,
|
100000u32,
|
||||||
);
|
);
|
||||||
|
|
||||||
let tx_raw = TxSigner::sign_direct(
|
let tx_raw = tx_signer
|
||||||
&tx_signer,
|
.sign_direct(&signer_address, vec![send_msg], fee, memo, signer_data)
|
||||||
&signer_address,
|
.unwrap();
|
||||||
vec![send_msg],
|
|
||||||
fee,
|
|
||||||
memo,
|
|
||||||
signer_data,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let tx_bytes = tx_raw.to_bytes().unwrap();
|
let tx_bytes = tx_raw.to_bytes().unwrap();
|
||||||
|
|
||||||
// compare balances from before and after the tx
|
// compare balances from before and after the tx
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ use crate::nyxd::{self, NyxdClient};
|
|||||||
use crate::signing::direct_wallet::DirectSecp256k1HdWallet;
|
use crate::signing::direct_wallet::DirectSecp256k1HdWallet;
|
||||||
use crate::signing::signer::{NoSigner, OfflineSigner};
|
use crate::signing::signer::{NoSigner, OfflineSigner};
|
||||||
use crate::{
|
use crate::{
|
||||||
DirectSigningReqwestRpcValidatorClient, QueryReqwestRpcValidatorClient, ValidatorClientError,
|
DirectSigningReqwestRpcValidatorClient, QueryReqwestRpcValidatorClient, ReqwestRpcClient,
|
||||||
|
ValidatorClientError,
|
||||||
};
|
};
|
||||||
use nym_api_requests::ecash::models::{
|
use nym_api_requests::ecash::models::{
|
||||||
AggregatedCoinIndicesSignatureResponse, AggregatedExpirationDateSignatureResponse,
|
AggregatedCoinIndicesSignatureResponse, AggregatedExpirationDateSignatureResponse,
|
||||||
@@ -163,7 +164,7 @@ impl Client<HttpRpcClient, DirectSecp256k1HdWallet> {
|
|||||||
) -> Result<DirectSigningHttpRpcValidatorClient, ValidatorClientError> {
|
) -> Result<DirectSigningHttpRpcValidatorClient, ValidatorClientError> {
|
||||||
let rpc_client = http_client(config.nyxd_url.as_str())?;
|
let rpc_client = http_client(config.nyxd_url.as_str())?;
|
||||||
let prefix = &config.nyxd_config.chain_details.bech32_account_prefix;
|
let prefix = &config.nyxd_config.chain_details.bech32_account_prefix;
|
||||||
let wallet = DirectSecp256k1HdWallet::checked_from_mnemonic(prefix, mnemonic)?;
|
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic);
|
||||||
|
|
||||||
Ok(Self::new_signing_with_rpc_client(
|
Ok(Self::new_signing_with_rpc_client(
|
||||||
config, rpc_client, wallet,
|
config, rpc_client, wallet,
|
||||||
@@ -176,13 +177,12 @@ impl Client<HttpRpcClient, DirectSecp256k1HdWallet> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(deprecated)]
|
impl Client<ReqwestRpcClient, DirectSecp256k1HdWallet> {
|
||||||
impl Client<crate::ReqwestRpcClient, DirectSecp256k1HdWallet> {
|
|
||||||
pub fn new_reqwest_signing(
|
pub fn new_reqwest_signing(
|
||||||
config: Config,
|
config: Config,
|
||||||
mnemonic: bip39::Mnemonic,
|
mnemonic: bip39::Mnemonic,
|
||||||
) -> DirectSigningReqwestRpcValidatorClient {
|
) -> DirectSigningReqwestRpcValidatorClient {
|
||||||
let rpc_client = crate::ReqwestRpcClient::new(config.nyxd_url.clone());
|
let rpc_client = ReqwestRpcClient::new(config.nyxd_url.clone());
|
||||||
let prefix = &config.nyxd_config.chain_details.bech32_account_prefix;
|
let prefix = &config.nyxd_config.chain_details.bech32_account_prefix;
|
||||||
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic);
|
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic);
|
||||||
|
|
||||||
@@ -203,10 +203,9 @@ impl Client<HttpRpcClient> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(deprecated)]
|
impl Client<ReqwestRpcClient> {
|
||||||
impl Client<crate::ReqwestRpcClient> {
|
|
||||||
pub fn new_reqwest_query(config: Config) -> QueryReqwestRpcValidatorClient {
|
pub fn new_reqwest_query(config: Config) -> QueryReqwestRpcValidatorClient {
|
||||||
let rpc_client = crate::ReqwestRpcClient::new(config.nyxd_url.clone());
|
let rpc_client = ReqwestRpcClient::new(config.nyxd_url.clone());
|
||||||
Self::new_with_rpc_client(config, rpc_client)
|
Self::new_with_rpc_client(config, rpc_client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::nym_api;
|
use crate::nym_api;
|
||||||
use crate::signing::direct_wallet::DirectSecp256k1HdWalletError;
|
|
||||||
pub use tendermint_rpc::error::Error as TendermintRpcError;
|
pub use tendermint_rpc::error::Error as TendermintRpcError;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
@@ -27,12 +26,6 @@ pub enum ValidatorClientError {
|
|||||||
|
|
||||||
#[error("No validator API url has been provided")]
|
#[error("No validator API url has been provided")]
|
||||||
NoAPIUrlAvailable,
|
NoAPIUrlAvailable,
|
||||||
|
|
||||||
#[error("failed to derive signing accounts: {source}")]
|
|
||||||
AccountDerivationFailure {
|
|
||||||
#[from]
|
|
||||||
source: DirectSecp256k1HdWalletError,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<nym_api::error::NymAPIError> for ValidatorClientError {
|
impl From<nym_api::error::NymAPIError> for ValidatorClientError {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ pub mod rpc;
|
|||||||
pub mod signing;
|
pub mod signing;
|
||||||
|
|
||||||
pub use crate::error::ValidatorClientError;
|
pub use crate::error::ValidatorClientError;
|
||||||
#[allow(deprecated)]
|
|
||||||
pub use crate::rpc::reqwest::ReqwestRpcClient;
|
pub use crate::rpc::reqwest::ReqwestRpcClient;
|
||||||
pub use crate::signing::direct_wallet::DirectSecp256k1HdWallet;
|
pub use crate::signing::direct_wallet::DirectSecp256k1HdWallet;
|
||||||
pub use client::{Client, Config, EcashApiClient};
|
pub use client::{Client, Config, EcashApiClient};
|
||||||
@@ -39,13 +38,9 @@ pub type DirectSigningHttpRpcValidatorClient = Client<HttpRpcClient, DirectSecp2
|
|||||||
#[cfg(feature = "http-client")]
|
#[cfg(feature = "http-client")]
|
||||||
pub type DirectSigningHttpRpcNyxdClient = nyxd::NyxdClient<HttpRpcClient, DirectSecp256k1HdWallet>;
|
pub type DirectSigningHttpRpcNyxdClient = nyxd::NyxdClient<HttpRpcClient, DirectSecp256k1HdWallet>;
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
pub type QueryReqwestRpcValidatorClient = Client<ReqwestRpcClient>;
|
pub type QueryReqwestRpcValidatorClient = Client<ReqwestRpcClient>;
|
||||||
#[allow(deprecated)]
|
|
||||||
pub type QueryReqwestRpcNyxdClient = nyxd::NyxdClient<ReqwestRpcClient>;
|
pub type QueryReqwestRpcNyxdClient = nyxd::NyxdClient<ReqwestRpcClient>;
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
pub type DirectSigningReqwestRpcValidatorClient = Client<ReqwestRpcClient, DirectSecp256k1HdWallet>;
|
pub type DirectSigningReqwestRpcValidatorClient = Client<ReqwestRpcClient, DirectSecp256k1HdWallet>;
|
||||||
#[allow(deprecated)]
|
|
||||||
pub type DirectSigningReqwestRpcNyxdClient =
|
pub type DirectSigningReqwestRpcNyxdClient =
|
||||||
nyxd::NyxdClient<ReqwestRpcClient, DirectSecp256k1HdWallet>;
|
nyxd::NyxdClient<ReqwestRpcClient, DirectSecp256k1HdWallet>;
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ where
|
|||||||
.ok_or_else(|| NyxdError::unavailable_contract_address("dkg contract"))?;
|
.ok_or_else(|| NyxdError::unavailable_contract_address("dkg contract"))?;
|
||||||
|
|
||||||
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
||||||
let signer_address = &self.signer_addresses()[0];
|
let signer_address = &self.signer_addresses()?[0];
|
||||||
|
|
||||||
self.execute(signer_address, dkg_contract_address, &msg, fee, memo, funds)
|
self.execute(signer_address, dkg_contract_address, &msg, fee, memo, funds)
|
||||||
.await
|
.await
|
||||||
|
|||||||
+1
-1
@@ -99,7 +99,7 @@ where
|
|||||||
.ok_or_else(|| NyxdError::unavailable_contract_address("coconut bandwidth contract"))?;
|
.ok_or_else(|| NyxdError::unavailable_contract_address("coconut bandwidth contract"))?;
|
||||||
|
|
||||||
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
||||||
let signer_address = &self.signer_addresses()[0];
|
let signer_address = &self.signer_addresses()?[0];
|
||||||
|
|
||||||
self.execute(
|
self.execute(
|
||||||
signer_address,
|
signer_address,
|
||||||
|
|||||||
+1
-1
@@ -95,7 +95,7 @@ where
|
|||||||
|
|
||||||
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
||||||
|
|
||||||
let signer_address = &self.signer_addresses()[0];
|
let signer_address = &self.signer_addresses()?[0];
|
||||||
self.execute(
|
self.execute(
|
||||||
signer_address,
|
signer_address,
|
||||||
group_contract_address,
|
group_contract_address,
|
||||||
|
|||||||
+1
-1
@@ -667,7 +667,7 @@ where
|
|||||||
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
||||||
let memo = msg.default_memo();
|
let memo = msg.default_memo();
|
||||||
|
|
||||||
let signer_address = &self.signer_addresses()[0];
|
let signer_address = &self.signer_addresses()?[0];
|
||||||
self.execute(
|
self.execute(
|
||||||
signer_address,
|
signer_address,
|
||||||
mixnet_contract_address,
|
mixnet_contract_address,
|
||||||
|
|||||||
+1
-1
@@ -133,7 +133,7 @@ where
|
|||||||
|
|
||||||
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
||||||
|
|
||||||
let signer_address = &self.signer_addresses()[0];
|
let signer_address = &self.signer_addresses()?[0];
|
||||||
self.execute(
|
self.execute(
|
||||||
signer_address,
|
signer_address,
|
||||||
multisig_contract_address,
|
multisig_contract_address,
|
||||||
|
|||||||
+1
-1
@@ -165,7 +165,7 @@ where
|
|||||||
|
|
||||||
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
||||||
|
|
||||||
let signer_address = &self.signer_addresses()[0];
|
let signer_address = &self.signer_addresses()?[0];
|
||||||
self.execute(
|
self.execute(
|
||||||
signer_address,
|
signer_address,
|
||||||
performance_contract_address,
|
performance_contract_address,
|
||||||
|
|||||||
+1
-1
@@ -375,7 +375,7 @@ where
|
|||||||
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
|
||||||
let memo = msg.name().to_string();
|
let memo = msg.name().to_string();
|
||||||
|
|
||||||
let signer_address = &self.signer_addresses()[0];
|
let signer_address = &self.signer_addresses()?[0];
|
||||||
self.execute(
|
self.execute(
|
||||||
signer_address,
|
signer_address,
|
||||||
vesting_contract_address,
|
vesting_contract_address,
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ where
|
|||||||
{
|
{
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
|
|
||||||
fn get_accounts(&self) -> &[AccountData] {
|
fn get_accounts(&self) -> Result<Vec<AccountData>, Self::Error> {
|
||||||
self.signer.get_accounts()
|
self.signer.get_accounts()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use crate::signing::signer::NoSigner;
|
|||||||
use crate::signing::signer::OfflineSigner;
|
use crate::signing::signer::OfflineSigner;
|
||||||
use crate::signing::tx_signer::TxSigner;
|
use crate::signing::tx_signer::TxSigner;
|
||||||
use crate::signing::AccountData;
|
use crate::signing::AccountData;
|
||||||
use crate::{DirectSigningReqwestRpcNyxdClient, QueryReqwestRpcNyxdClient};
|
use crate::{DirectSigningReqwestRpcNyxdClient, QueryReqwestRpcNyxdClient, ReqwestRpcClient};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use cosmrs::tendermint::{abci, evidence::Evidence, Genesis};
|
use cosmrs::tendermint::{abci, evidence::Evidence, Genesis};
|
||||||
use cosmrs::tx::{Raw, SignDoc};
|
use cosmrs::tx::{Raw, SignDoc};
|
||||||
@@ -158,13 +158,12 @@ impl NyxdClient<HttpClient> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(deprecated)]
|
impl NyxdClient<ReqwestRpcClient> {
|
||||||
impl NyxdClient<crate::ReqwestRpcClient> {
|
|
||||||
pub fn connect_reqwest(
|
pub fn connect_reqwest(
|
||||||
config: Config,
|
config: Config,
|
||||||
endpoint: Url,
|
endpoint: Url,
|
||||||
) -> Result<QueryReqwestRpcNyxdClient, NyxdError> {
|
) -> Result<QueryReqwestRpcNyxdClient, NyxdError> {
|
||||||
let client = crate::ReqwestRpcClient::new(endpoint);
|
let client = ReqwestRpcClient::new(endpoint);
|
||||||
|
|
||||||
Ok(NyxdClient {
|
Ok(NyxdClient {
|
||||||
client: MaybeSigningClient::new(client, (&config).into()),
|
client: MaybeSigningClient::new(client, (&config).into()),
|
||||||
@@ -196,19 +195,18 @@ impl NyxdClient<HttpClient, DirectSecp256k1HdWallet> {
|
|||||||
let client = http_client(endpoint)?;
|
let client = http_client(endpoint)?;
|
||||||
|
|
||||||
let prefix = &config.chain_details.bech32_account_prefix;
|
let prefix = &config.chain_details.bech32_account_prefix;
|
||||||
let wallet = DirectSecp256k1HdWallet::checked_from_mnemonic(prefix, mnemonic)?;
|
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic);
|
||||||
Ok(Self::connect_with_signer(config, client, wallet))
|
Ok(Self::connect_with_signer(config, client, wallet))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(deprecated)]
|
impl NyxdClient<ReqwestRpcClient, DirectSecp256k1HdWallet> {
|
||||||
impl NyxdClient<crate::ReqwestRpcClient, DirectSecp256k1HdWallet> {
|
|
||||||
pub fn connect_reqwest_with_mnemonic(
|
pub fn connect_reqwest_with_mnemonic(
|
||||||
config: Config,
|
config: Config,
|
||||||
endpoint: Url,
|
endpoint: Url,
|
||||||
mnemonic: bip39::Mnemonic,
|
mnemonic: bip39::Mnemonic,
|
||||||
) -> DirectSigningReqwestRpcNyxdClient {
|
) -> DirectSigningReqwestRpcNyxdClient {
|
||||||
let client = crate::ReqwestRpcClient::new(endpoint);
|
let client = ReqwestRpcClient::new(endpoint);
|
||||||
|
|
||||||
let prefix = &config.chain_details.bech32_account_prefix;
|
let prefix = &config.chain_details.bech32_account_prefix;
|
||||||
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic);
|
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic);
|
||||||
@@ -393,12 +391,17 @@ where
|
|||||||
S: OfflineSigner + Send + Sync,
|
S: OfflineSigner + Send + Sync,
|
||||||
NyxdError: From<<S as OfflineSigner>::Error>,
|
NyxdError: From<<S as OfflineSigner>::Error>,
|
||||||
{
|
{
|
||||||
pub fn signing_account(&self) -> Result<&AccountData, NyxdError> {
|
pub fn signing_account(&self) -> Result<AccountData, NyxdError> {
|
||||||
Ok(self.find_account(&self.address())?)
|
Ok(self.find_account(&self.address())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn address(&self) -> AccountId {
|
pub fn address(&self) -> AccountId {
|
||||||
self.client.signer_addresses()[0].clone()
|
match self.client.signer_addresses() {
|
||||||
|
Ok(addresses) => addresses[0].clone(),
|
||||||
|
Err(_) => {
|
||||||
|
panic!("key derivation failure")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mix_coin(&self, amount: u128) -> Coin {
|
pub fn mix_coin(&self, amount: u128) -> Coin {
|
||||||
@@ -864,7 +867,7 @@ where
|
|||||||
{
|
{
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
|
|
||||||
fn get_accounts(&self) -> &[AccountData] {
|
fn get_accounts(&self) -> Result<Vec<AccountData>, Self::Error> {
|
||||||
self.client.get_accounts()
|
self.client.get_accounts()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,15 +42,12 @@ macro_rules! perform_with_compat {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
// the separate implementation is now completely redundant
|
|
||||||
#[deprecated(note = "use HttpClient directly instead")]
|
|
||||||
pub struct ReqwestRpcClient {
|
pub struct ReqwestRpcClient {
|
||||||
compat: CompatMode,
|
compat: CompatMode,
|
||||||
inner: reqwest::Client,
|
inner: reqwest::Client,
|
||||||
url: Url,
|
url: Url,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
impl ReqwestRpcClient {
|
impl ReqwestRpcClient {
|
||||||
pub fn new(url: Url) -> Self {
|
pub fn new(url: Url) -> Self {
|
||||||
ReqwestRpcClient {
|
ReqwestRpcClient {
|
||||||
@@ -134,7 +131,6 @@ impl TendermintRpcErrorMap for reqwest::Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
||||||
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
|
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
|
||||||
impl TendermintRpcClient for ReqwestRpcClient {
|
impl TendermintRpcClient for ReqwestRpcClient {
|
||||||
|
|||||||
@@ -2,18 +2,18 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::signing::signer::{OfflineSigner, SigningError};
|
use crate::signing::signer::{OfflineSigner, SigningError};
|
||||||
use crate::signing::{
|
use crate::signing::{AccountData, Secp256k1Derivation};
|
||||||
derive_extended_private_key, derive_keypair, AccountData, Secp256k1Derivation, Secp256k1Keypair,
|
use cosmrs::bip32::{DerivationPath, XPrv};
|
||||||
};
|
use cosmrs::crypto::secp256k1::SigningKey;
|
||||||
use bip32::XPrv;
|
use cosmrs::crypto::PublicKey;
|
||||||
use cosmrs::bip32::DerivationPath;
|
|
||||||
use cosmrs::tx;
|
use cosmrs::tx;
|
||||||
use cosmrs::tx::SignDoc;
|
use cosmrs::tx::SignDoc;
|
||||||
use nym_config::defaults;
|
use nym_config::defaults;
|
||||||
use std::borrow::Cow;
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};
|
use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};
|
||||||
|
|
||||||
|
type Secp256k1Keypair = (SigningKey, PublicKey);
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum DirectSecp256k1HdWalletError {
|
pub enum DirectSecp256k1HdWalletError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
@@ -36,22 +36,28 @@ pub enum DirectSecp256k1HdWalletError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: maybe lock this one behind feature flag?
|
// TODO: maybe lock this one behind feature flag?
|
||||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
#[derive(Debug, Clone, Zeroize, ZeroizeOnDrop)]
|
||||||
pub struct DirectSecp256k1HdWallet {
|
pub struct DirectSecp256k1HdWallet {
|
||||||
/// Base secret
|
/// Base secret
|
||||||
secret: bip39::Mnemonic,
|
secret: bip39::Mnemonic,
|
||||||
|
|
||||||
/// Derived accounts
|
/// BIP39 seed
|
||||||
|
seed: [u8; 64],
|
||||||
|
|
||||||
|
// An unfortunate result of immature rust async story is that async traits (only available in the separate package)
|
||||||
|
// can't yet figure out everything and if we stored our derived account data on the struct,
|
||||||
|
// that would include the secret key which is a dyn EcdsaSigner and hence not Sync making the wallet
|
||||||
|
// not Sync and if used on the signing client in an async trait, it wouldn't be Send
|
||||||
|
/// Derivation instructions
|
||||||
#[zeroize(skip)]
|
#[zeroize(skip)]
|
||||||
// unfortunately `dyn EcdsaSigner` does not guarantee Zeroize
|
accounts: Vec<Secp256k1Derivation>,
|
||||||
accounts: Vec<AccountData>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OfflineSigner for DirectSecp256k1HdWallet {
|
impl OfflineSigner for DirectSecp256k1HdWallet {
|
||||||
type Error = DirectSecp256k1HdWalletError;
|
type Error = DirectSecp256k1HdWalletError;
|
||||||
|
|
||||||
fn get_accounts(&self) -> &[AccountData] {
|
fn get_accounts(&self) -> Result<Vec<AccountData>, Self::Error> {
|
||||||
&self.accounts
|
self.try_derive_accounts()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_direct_with_account(
|
fn sign_direct_with_account(
|
||||||
@@ -71,27 +77,55 @@ impl DirectSecp256k1HdWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Restores a wallet from the given BIP39 mnemonic using default options.
|
/// Restores a wallet from the given BIP39 mnemonic using default options.
|
||||||
#[deprecated(
|
|
||||||
note = "this function can potentially panic if accounts can't be derived correctly. please use .checked_from_mnemonic() instead"
|
|
||||||
)]
|
|
||||||
pub fn from_mnemonic(prefix: &str, mnemonic: bip39::Mnemonic) -> Self {
|
pub fn from_mnemonic(prefix: &str, mnemonic: bip39::Mnemonic) -> Self {
|
||||||
// unfortunately due to backwards compatibility requirements,
|
|
||||||
// we can't change signature of this method
|
|
||||||
#[allow(deprecated)]
|
|
||||||
DirectSecp256k1HdWalletBuilder::new(prefix).build(mnemonic)
|
DirectSecp256k1HdWalletBuilder::new(prefix).build(mnemonic)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Restores a wallet from the given BIP39 mnemonic using default options.
|
|
||||||
pub fn checked_from_mnemonic(
|
|
||||||
prefix: &str,
|
|
||||||
mnemonic: bip39::Mnemonic,
|
|
||||||
) -> Result<Self, DirectSecp256k1HdWalletError> {
|
|
||||||
DirectSecp256k1HdWalletBuilder::new(prefix).try_build(mnemonic)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate(prefix: &str, word_count: usize) -> Result<Self, DirectSecp256k1HdWalletError> {
|
pub fn generate(prefix: &str, word_count: usize) -> Result<Self, DirectSecp256k1HdWalletError> {
|
||||||
let mneomonic = bip39::Mnemonic::generate(word_count)?;
|
let mneomonic = bip39::Mnemonic::generate(word_count)?;
|
||||||
Self::checked_from_mnemonic(prefix, mneomonic)
|
Ok(Self::from_mnemonic(prefix, mneomonic))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn derive_keypair(
|
||||||
|
&self,
|
||||||
|
hd_path: &DerivationPath,
|
||||||
|
) -> Result<Secp256k1Keypair, DirectSecp256k1HdWalletError> {
|
||||||
|
let extended_private_key = XPrv::derive_from_path(self.seed, hd_path)?;
|
||||||
|
|
||||||
|
let private_key: SigningKey = extended_private_key.into();
|
||||||
|
let public_key = private_key.public_key();
|
||||||
|
|
||||||
|
Ok((private_key, public_key))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn derive_extended_private_key(
|
||||||
|
&self,
|
||||||
|
hd_path: &DerivationPath,
|
||||||
|
) -> Result<XPrv, DirectSecp256k1HdWalletError> {
|
||||||
|
Ok(XPrv::derive_from_path(self.seed, hd_path)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn try_derive_accounts(&self) -> Result<Vec<AccountData>, DirectSecp256k1HdWalletError> {
|
||||||
|
let mut accounts = Vec::with_capacity(self.accounts.len());
|
||||||
|
for derivation_info in &self.accounts {
|
||||||
|
let keypair = self.derive_keypair(&derivation_info.hd_path)?;
|
||||||
|
|
||||||
|
// it seems this can only fail if the provided account prefix is invalid
|
||||||
|
let address = keypair
|
||||||
|
.1
|
||||||
|
.account_id(&derivation_info.prefix)
|
||||||
|
.map_err(
|
||||||
|
|source| DirectSecp256k1HdWalletError::AccountDerivationError { source },
|
||||||
|
)?;
|
||||||
|
|
||||||
|
accounts.push(AccountData {
|
||||||
|
address,
|
||||||
|
public_key: keypair.1,
|
||||||
|
private_key: keypair.0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn secret(&self) -> &bip39::Mnemonic {
|
pub fn secret(&self) -> &bip39::Mnemonic {
|
||||||
@@ -108,43 +142,6 @@ impl DirectSecp256k1HdWallet {
|
|||||||
pub fn mnemonic_string(&self) -> Zeroizing<String> {
|
pub fn mnemonic_string(&self) -> Zeroizing<String> {
|
||||||
Zeroizing::new(self.secret.to_string())
|
Zeroizing::new(self.secret.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn account_seed<'a, P: Into<Cow<'a, str>>>(
|
|
||||||
&self,
|
|
||||||
bip39_password: P,
|
|
||||||
) -> Zeroizing<[u8; 64]> {
|
|
||||||
Zeroizing::new(self.secret.to_seed(bip39_password))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Derive an extended private key from the stored account secret assuming no bip39 password
|
|
||||||
#[deprecated(
|
|
||||||
note = "use derive_extended_private_key_with_password to ensure correct derivation if used bip39 password"
|
|
||||||
)]
|
|
||||||
pub fn derive_extended_private_key(
|
|
||||||
&self,
|
|
||||||
hd_path: &DerivationPath,
|
|
||||||
) -> Result<XPrv, DirectSecp256k1HdWalletError> {
|
|
||||||
let seed = self.account_seed("");
|
|
||||||
derive_extended_private_key(seed, hd_path)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn derive_keypair<'a, P: Into<Cow<'a, str>>>(
|
|
||||||
&self,
|
|
||||||
hd_path: &DerivationPath,
|
|
||||||
bip39_password: P,
|
|
||||||
) -> Result<Secp256k1Keypair, DirectSecp256k1HdWalletError> {
|
|
||||||
let seed = self.account_seed(bip39_password);
|
|
||||||
derive_keypair(seed, hd_path)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn derive_extended_private_key_with_password<'a, P: Into<Cow<'a, str>>>(
|
|
||||||
&self,
|
|
||||||
hd_path: &DerivationPath,
|
|
||||||
bip39_password: P,
|
|
||||||
) -> Result<XPrv, DirectSecp256k1HdWalletError> {
|
|
||||||
let seed = self.account_seed(bip39_password);
|
|
||||||
derive_extended_private_key(seed, hd_path)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@@ -191,39 +188,23 @@ impl DirectSecp256k1HdWalletBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated(
|
|
||||||
note = "this function can potentially panic if accounts can't be derived correctly. please use .try_build() instead"
|
|
||||||
)]
|
|
||||||
pub fn build(self, mnemonic: bip39::Mnemonic) -> DirectSecp256k1HdWallet {
|
pub fn build(self, mnemonic: bip39::Mnemonic) -> DirectSecp256k1HdWallet {
|
||||||
// unfortunately due to backwards compatibility requirements,
|
let seed = mnemonic.to_seed(&self.bip39_password);
|
||||||
// we can't change signature of this method
|
|
||||||
#[allow(clippy::expect_used)]
|
|
||||||
self.try_build(mnemonic)
|
|
||||||
.expect("account derivation failure")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn try_build(
|
|
||||||
self,
|
|
||||||
mnemonic: bip39::Mnemonic,
|
|
||||||
) -> Result<DirectSecp256k1HdWallet, DirectSecp256k1HdWalletError> {
|
|
||||||
let seed = Zeroizing::new(mnemonic.to_seed(&self.bip39_password));
|
|
||||||
let prefix = self.prefix.clone();
|
let prefix = self.prefix.clone();
|
||||||
let accounts = self
|
let accounts = self
|
||||||
.hd_paths
|
.hd_paths
|
||||||
.iter()
|
.iter()
|
||||||
.map(|hd_path| {
|
.map(|hd_path| Secp256k1Derivation {
|
||||||
Secp256k1Derivation {
|
hd_path: hd_path.clone(),
|
||||||
hd_path: hd_path.clone(),
|
prefix: prefix.clone(),
|
||||||
prefix: prefix.clone(),
|
|
||||||
}
|
|
||||||
.try_derive_account(&seed)
|
|
||||||
})
|
})
|
||||||
.collect::<Result<_, _>>()?;
|
.collect();
|
||||||
|
|
||||||
Ok(DirectSecp256k1HdWallet {
|
DirectSecp256k1HdWallet {
|
||||||
accounts,
|
accounts,
|
||||||
|
seed,
|
||||||
secret: mnemonic,
|
secret: mnemonic,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +215,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generating_account_addresses() -> anyhow::Result<()> {
|
fn generating_account_addresses() {
|
||||||
// test vectors produced from our js wallet
|
// test vectors produced from our js wallet
|
||||||
let mnemonics = ["crush minute paddle tobacco message debate cabin peace bar jacket execute twenty winner view sure mask popular couch penalty fragile demise fresh pizza stove",
|
let mnemonics = ["crush minute paddle tobacco message debate cabin peace bar jacket execute twenty winner view sure mask popular couch penalty fragile demise fresh pizza stove",
|
||||||
"acquire rebel spot skin gun such erupt pull swear must define ill chief turtle today flower chunk truth battle claw rigid detail gym feel",
|
"acquire rebel spot skin gun such erupt pull swear must define ill chief turtle today flower chunk truth battle claw rigid detail gym feel",
|
||||||
@@ -249,10 +230,11 @@ mod tests {
|
|||||||
"n17n9flp6jflljg6fp05dsy07wcprf2uuu8g40rf",
|
"n17n9flp6jflljg6fp05dsy07wcprf2uuu8g40rf",
|
||||||
];
|
];
|
||||||
for (idx, mnemonic) in mnemonics.iter().enumerate() {
|
for (idx, mnemonic) in mnemonics.iter().enumerate() {
|
||||||
let wallet =
|
let wallet = DirectSecp256k1HdWallet::from_mnemonic(&prefix, mnemonic.parse().unwrap());
|
||||||
DirectSecp256k1HdWallet::checked_from_mnemonic(&prefix, mnemonic.parse()?)?;
|
assert_eq!(
|
||||||
assert_eq!(wallet.signer_addresses()[0], addrs[idx].parse().unwrap());
|
wallet.try_derive_accounts().unwrap()[0].address,
|
||||||
|
addrs[idx].parse().unwrap()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::signing::direct_wallet::DirectSecp256k1HdWalletError;
|
|
||||||
use bip32::XPrv;
|
|
||||||
use cosmrs::bip32::DerivationPath;
|
use cosmrs::bip32::DerivationPath;
|
||||||
use cosmrs::crypto::secp256k1::SigningKey;
|
use cosmrs::crypto::secp256k1::SigningKey;
|
||||||
use cosmrs::crypto::PublicKey;
|
use cosmrs::crypto::PublicKey;
|
||||||
@@ -14,64 +12,14 @@ pub mod direct_wallet;
|
|||||||
pub mod signer;
|
pub mod signer;
|
||||||
pub mod tx_signer;
|
pub mod tx_signer;
|
||||||
|
|
||||||
pub(crate) type Secp256k1Keypair = (SigningKey, PublicKey);
|
|
||||||
|
|
||||||
/// Derivation information required to derive a keypair and an address from a mnemonic.
|
/// Derivation information required to derive a keypair and an address from a mnemonic.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct Secp256k1Derivation {
|
struct Secp256k1Derivation {
|
||||||
hd_path: DerivationPath,
|
hd_path: DerivationPath,
|
||||||
prefix: String,
|
prefix: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Secp256k1Derivation {
|
// TODO: is this struct going to be derivable with other signer types?
|
||||||
pub(crate) fn try_derive_account<S>(
|
|
||||||
&self,
|
|
||||||
seed: S,
|
|
||||||
) -> Result<AccountData, DirectSecp256k1HdWalletError>
|
|
||||||
where
|
|
||||||
S: AsRef<[u8]>,
|
|
||||||
{
|
|
||||||
let keypair = derive_keypair(seed, &self.hd_path)?;
|
|
||||||
|
|
||||||
// it seems this can only fail if the provided account prefix is invalid
|
|
||||||
let address = keypair
|
|
||||||
.1
|
|
||||||
.account_id(&self.prefix)
|
|
||||||
.map_err(|source| DirectSecp256k1HdWalletError::AccountDerivationError { source })?;
|
|
||||||
|
|
||||||
Ok(AccountData {
|
|
||||||
address,
|
|
||||||
public_key: keypair.1,
|
|
||||||
private_key: keypair.0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn derive_keypair<S>(
|
|
||||||
seed: S,
|
|
||||||
hd_path: &DerivationPath,
|
|
||||||
) -> Result<Secp256k1Keypair, DirectSecp256k1HdWalletError>
|
|
||||||
where
|
|
||||||
S: AsRef<[u8]>,
|
|
||||||
{
|
|
||||||
let extended_private_key = derive_extended_private_key(seed, hd_path)?;
|
|
||||||
|
|
||||||
let private_key: SigningKey = extended_private_key.into();
|
|
||||||
let public_key = private_key.public_key();
|
|
||||||
|
|
||||||
Ok((private_key, public_key))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn derive_extended_private_key<S>(
|
|
||||||
seed: S,
|
|
||||||
hd_path: &DerivationPath,
|
|
||||||
) -> Result<XPrv, DirectSecp256k1HdWalletError>
|
|
||||||
where
|
|
||||||
S: AsRef<[u8]>,
|
|
||||||
{
|
|
||||||
Ok(XPrv::derive_from_path(seed, hd_path)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AccountData {
|
pub struct AccountData {
|
||||||
pub address: AccountId,
|
pub address: AccountId,
|
||||||
|
|
||||||
|
|||||||
@@ -33,18 +33,23 @@ pub enum SignerType {
|
|||||||
pub trait OfflineSigner {
|
pub trait OfflineSigner {
|
||||||
type Error: From<SigningError>;
|
type Error: From<SigningError>;
|
||||||
|
|
||||||
fn signer_addresses(&self) -> Vec<AccountId> {
|
// I really dislike existence of this function because it makes you re-derive your key **twice** for each contract transaction
|
||||||
self.get_accounts()
|
fn signer_addresses(&self) -> Result<Vec<AccountId>, Self::Error> {
|
||||||
.iter()
|
let derived_addresses = self
|
||||||
.map(|account| account.address.clone())
|
.get_accounts()?
|
||||||
.collect()
|
.into_iter()
|
||||||
|
.map(|account| account.address)
|
||||||
|
.collect();
|
||||||
|
Ok(derived_addresses)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_accounts(&self) -> &[AccountData];
|
fn get_accounts(&self) -> Result<Vec<AccountData>, Self::Error>;
|
||||||
|
|
||||||
fn find_account(&self, signer_address: &AccountId) -> Result<&AccountData, Self::Error> {
|
fn find_account(&self, signer_address: &AccountId) -> Result<AccountData, Self::Error> {
|
||||||
self.get_accounts()
|
// TODO: we could really use some zeroize action here
|
||||||
.iter()
|
let accounts = self.get_accounts()?;
|
||||||
|
accounts
|
||||||
|
.into_iter()
|
||||||
.find(|account| &account.address == signer_address)
|
.find(|account| &account.address == signer_address)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
SigningError::AccountNotFound {
|
SigningError::AccountNotFound {
|
||||||
@@ -71,7 +76,7 @@ pub trait OfflineSigner {
|
|||||||
message: M,
|
message: M,
|
||||||
) -> Result<Signature, Self::Error> {
|
) -> Result<Signature, Self::Error> {
|
||||||
let signer = self.find_account(signer_address)?;
|
let signer = self.find_account(signer_address)?;
|
||||||
self.sign_raw_with_account(signer, message)
|
self.sign_raw_with_account(&signer, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_direct(
|
fn sign_direct(
|
||||||
@@ -80,7 +85,7 @@ pub trait OfflineSigner {
|
|||||||
sign_doc: SignDoc,
|
sign_doc: SignDoc,
|
||||||
) -> Result<tx::Raw, Self::Error> {
|
) -> Result<tx::Raw, Self::Error> {
|
||||||
let signer = self.find_account(signer_address)?;
|
let signer = self.find_account(signer_address)?;
|
||||||
self.sign_direct_with_account(signer, sign_doc)
|
self.sign_direct_with_account(&signer, sign_doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// unless explicitly defined, each signing method is unsupported
|
// unless explicitly defined, each signing method is unsupported
|
||||||
@@ -117,7 +122,7 @@ pub struct NoSigner;
|
|||||||
// impl OfflineSigner for NoSigner {
|
// impl OfflineSigner for NoSigner {
|
||||||
// type Error = SignerUnavailable;
|
// type Error = SignerUnavailable;
|
||||||
//
|
//
|
||||||
// fn get_accounts(&self) -> &[AccountData] {
|
// fn get_accounts(&self) -> Result<Vec<AccountData>, Self::Error> {
|
||||||
// return Err(SignerUnavailable);
|
// return Err(SignerUnavailable);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ pub trait TxSigner: OfflineSigner {
|
|||||||
)
|
)
|
||||||
.map_err(|source| SigningError::SignDocFailure { source })?;
|
.map_err(|source| SigningError::SignDocFailure { source })?;
|
||||||
|
|
||||||
self.sign_direct_with_account(account_from_signer, sign_doc)
|
self.sign_direct_with_account(&account_from_signer, sign_doc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet;
|
use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet;
|
||||||
use nym_validator_client::signing::signer::OfflineSigner;
|
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
@@ -16,10 +15,9 @@ pub fn create_account(args: Args, prefix: &str) {
|
|||||||
let word_count = args.word_count.unwrap_or(24);
|
let word_count = args.word_count.unwrap_or(24);
|
||||||
let mnemonic = bip39::Mnemonic::generate(word_count).expect("failed to generate mnemonic!");
|
let mnemonic = bip39::Mnemonic::generate(word_count).expect("failed to generate mnemonic!");
|
||||||
|
|
||||||
let wallet = DirectSecp256k1HdWallet::checked_from_mnemonic(prefix, mnemonic)
|
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic);
|
||||||
.expect("failed to derive accounts!");
|
|
||||||
|
|
||||||
// Output address and mnemonics into separate lines for easier parsing
|
// Output address and mnemonics into separate lines for easier parsing
|
||||||
println!("{}", wallet.mnemonic_string().as_str());
|
println!("{}", wallet.mnemonic_string().as_str());
|
||||||
println!("{}", wallet.signer_addresses()[0]);
|
println!("{}", wallet.try_derive_accounts().unwrap()[0].address());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::context::QueryClient;
|
|
||||||
use crate::utils::show_error;
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use nym_validator_client::nyxd::{AccountId, CosmWasmClient};
|
use nym_validator_client::nyxd::{AccountId, CosmWasmClient};
|
||||||
use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet;
|
use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet;
|
||||||
use nym_validator_client::signing::signer::OfflineSigner;
|
|
||||||
|
use crate::context::QueryClient;
|
||||||
|
use crate::utils::show_error;
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
@@ -50,19 +50,20 @@ pub async fn get_pubkey(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pubkey_from_mnemonic(address: AccountId, prefix: &str, mnemonic: bip39::Mnemonic) {
|
pub fn get_pubkey_from_mnemonic(address: AccountId, prefix: &str, mnemonic: bip39::Mnemonic) {
|
||||||
let wallet = match DirectSecp256k1HdWallet::checked_from_mnemonic(prefix, mnemonic) {
|
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic);
|
||||||
Ok(wallet) => wallet,
|
match wallet.try_derive_accounts() {
|
||||||
Err(err) => {
|
Ok(accounts) => match accounts.iter().find(|a| *a.address() == address) {
|
||||||
error!("Failed to derive accounts. {err}");
|
Some(account) => {
|
||||||
return;
|
println!("{}", account.public_key().to_string());
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
error!("Could not derive key that matches {address}")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
error!("Failed to derive accounts. {e}");
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
let Ok(account) = wallet.find_account(&address) else {
|
|
||||||
error!("Could not derive key that matches {address}");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
println!("{}", account.public_key().to_string());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_pubkey_from_chain(address: AccountId, client: &QueryClient) {
|
pub async fn get_pubkey_from_chain(address: AccountId, client: &QueryClient) {
|
||||||
|
|||||||
@@ -36,35 +36,32 @@ pub fn sign(args: Args, prefix: &str, mnemonic: Option<bip39::Mnemonic>) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let wallet = match DirectSecp256k1HdWallet::checked_from_mnemonic(
|
let wallet =
|
||||||
prefix,
|
DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic.expect("mnemonic not set"));
|
||||||
mnemonic.expect("mnemonic not set"),
|
match wallet.try_derive_accounts() {
|
||||||
) {
|
Ok(accounts) => match accounts.first() {
|
||||||
Ok(wallet) => wallet,
|
Some(account) => {
|
||||||
Err(err) => {
|
let msg = args.message.into_bytes();
|
||||||
error!("Could not derive an account key from the mnemonic: {err}");
|
match wallet.sign_raw_with_account(account, msg) {
|
||||||
return;
|
Ok(signature) => {
|
||||||
}
|
let output = SignatureOutputJson {
|
||||||
};
|
account_id: account.address().to_string(),
|
||||||
match wallet.get_accounts().first() {
|
public_key: account.public_key(),
|
||||||
Some(account) => {
|
signature_as_hex: signature.to_string(),
|
||||||
let msg = args.message.into_bytes();
|
};
|
||||||
match wallet.sign_raw_with_account(account, msg) {
|
println!("{}", json!(output));
|
||||||
Ok(signature) => {
|
}
|
||||||
let output = SignatureOutputJson {
|
Err(e) => {
|
||||||
account_id: account.address().to_string(),
|
error!("Failed to sign message. {e}");
|
||||||
public_key: account.public_key(),
|
}
|
||||||
signature_as_hex: signature.to_string(),
|
|
||||||
};
|
|
||||||
println!("{}", json!(output));
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!("Failed to sign message. {e}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
None => {
|
||||||
None => {
|
error!("Could not derive an account key from the mnemonic",)
|
||||||
error!("Could not derive an account key from the mnemonic",)
|
}
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
error!("Failed to derive accounts. {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -241,28 +241,23 @@ impl Epoch {
|
|||||||
//
|
//
|
||||||
// Note: It's important that the variant ordering is not changed otherwise it would mess up the derived `PartialOrd`
|
// Note: It's important that the variant ordering is not changed otherwise it would mess up the derived `PartialOrd`
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
#[derive(Copy, Default)]
|
#[derive(Copy)]
|
||||||
pub enum EpochState {
|
pub enum EpochState {
|
||||||
#[default]
|
|
||||||
WaitingInitialisation,
|
WaitingInitialisation,
|
||||||
PublicKeySubmission {
|
PublicKeySubmission { resharing: bool },
|
||||||
resharing: bool,
|
DealingExchange { resharing: bool },
|
||||||
},
|
VerificationKeySubmission { resharing: bool },
|
||||||
DealingExchange {
|
VerificationKeyValidation { resharing: bool },
|
||||||
resharing: bool,
|
VerificationKeyFinalization { resharing: bool },
|
||||||
},
|
|
||||||
VerificationKeySubmission {
|
|
||||||
resharing: bool,
|
|
||||||
},
|
|
||||||
VerificationKeyValidation {
|
|
||||||
resharing: bool,
|
|
||||||
},
|
|
||||||
VerificationKeyFinalization {
|
|
||||||
resharing: bool,
|
|
||||||
},
|
|
||||||
InProgress,
|
InProgress,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for EpochState {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::WaitingInitialisation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for EpochState {
|
impl Display for EpochState {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
use sqlx::{Connection, SqliteConnection};
|
use sqlx::{Connection, SqliteConnection};
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
let out_dir = env::var("OUT_DIR").context("missing OUT_DIR env variable")?;
|
let out_dir = env::var("OUT_DIR")?;
|
||||||
let database_path = format!("{out_dir}/nym-credential-proxy-example.sqlite");
|
let database_path = format!("{out_dir}/nym-credential-proxy-example.sqlite");
|
||||||
|
|
||||||
// remove the db file if it already existed from previous build
|
// remove the db file if it already existed from previous build
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// Copyright 2025 Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2025 Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use nym_crypto::asymmetric::ed25519;
|
|
||||||
use nym_ecash_signer_check::SignerCheckError;
|
use nym_ecash_signer_check::SignerCheckError;
|
||||||
use nym_validator_client::coconut::EcashApiError;
|
use nym_validator_client::coconut::EcashApiError;
|
||||||
use nym_validator_client::nym_api::{EpochId, error::NymAPIError};
|
use nym_validator_client::nym_api::{EpochId, error::NymAPIError};
|
||||||
@@ -128,13 +127,6 @@ pub enum CredentialProxyError {
|
|||||||
#[error("failed to create deposit")]
|
#[error("failed to create deposit")]
|
||||||
DepositFailure,
|
DepositFailure,
|
||||||
|
|
||||||
#[error("failed to load jwt signing key from {path}: {err}")]
|
|
||||||
JWTSigningKeyLoadFailure {
|
|
||||||
path: String,
|
|
||||||
#[source]
|
|
||||||
err: std::io::Error,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[error("can't obtain sufficient number of credential shares due to unavailable quorum")]
|
#[error("can't obtain sufficient number of credential shares due to unavailable quorum")]
|
||||||
UnavailableSigningQuorum,
|
UnavailableSigningQuorum,
|
||||||
|
|
||||||
@@ -169,24 +161,6 @@ pub enum CredentialProxyError {
|
|||||||
device_id: String,
|
device_id: String,
|
||||||
credential_id: String,
|
credential_id: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
|
||||||
"the attestation check url has not been provided through either the CLI nor the default .env config"
|
|
||||||
)]
|
|
||||||
AttestationCheckUrlNotSet,
|
|
||||||
|
|
||||||
#[error("the provided attester public key is malformed: {source}")]
|
|
||||||
MalformedAttestationCheckUrl { source: url::ParseError },
|
|
||||||
|
|
||||||
#[error(
|
|
||||||
"the attester public key has not been provided through either the CLI nor the default .env config"
|
|
||||||
)]
|
|
||||||
AttesterPublicKeyNotSet,
|
|
||||||
|
|
||||||
#[error("the provided attester public key is malformed: {source}")]
|
|
||||||
MalformedAttesterPublicKey {
|
|
||||||
source: ed25519::Ed25519RecoveryError,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<NymAPIError> for CredentialProxyError {
|
impl From<NymAPIError> for CredentialProxyError {
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ use crate::ticketbook_manager::TicketbookManager;
|
|||||||
use nym_compact_ecash::Base58;
|
use nym_compact_ecash::Base58;
|
||||||
use nym_credential_proxy_requests::api::v1::ticketbook::models::{
|
use nym_credential_proxy_requests::api::v1::ticketbook::models::{
|
||||||
CurrentEpochResponse, DepositResponse, GlobalDataParams, MasterVerificationKeyResponse,
|
CurrentEpochResponse, DepositResponse, GlobalDataParams, MasterVerificationKeyResponse,
|
||||||
ObtainTicketBookSharesAsyncResponse, PartialVerificationKey, PartialVerificationKeysResponse,
|
PartialVerificationKey, PartialVerificationKeysResponse, TicketbookAsyncRequest,
|
||||||
TicketbookAsyncRequest, TicketbookObtainParams, TicketbookRequest,
|
TicketbookObtainParams, TicketbookRequest, TicketbookWalletSharesAsyncResponse,
|
||||||
TicketbookWalletSharesAsyncResponse, TicketbookWalletSharesResponse,
|
TicketbookWalletSharesResponse,
|
||||||
};
|
};
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use tracing::{Instrument, Level, error, info, span, warn};
|
use tracing::{Instrument, Level, error, info, span, warn};
|
||||||
@@ -65,7 +65,7 @@ impl TicketbookManager {
|
|||||||
uuid: Uuid,
|
uuid: Uuid,
|
||||||
request: TicketbookAsyncRequest,
|
request: TicketbookAsyncRequest,
|
||||||
params: TicketbookObtainParams,
|
params: TicketbookObtainParams,
|
||||||
) -> Result<ObtainTicketBookSharesAsyncResponse, CredentialProxyError> {
|
) -> Result<TicketbookWalletSharesAsyncResponse, CredentialProxyError> {
|
||||||
let requested_on = OffsetDateTime::now_utc();
|
let requested_on = OffsetDateTime::now_utc();
|
||||||
let span = span!(Level::INFO, "[async] obtain ticketboook", uuid = %uuid);
|
let span = span!(Level::INFO, "[async] obtain ticketboook", uuid = %uuid);
|
||||||
async move {
|
async move {
|
||||||
@@ -110,7 +110,7 @@ impl TicketbookManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 4. in the meantime, return the id to the user
|
// 4. in the meantime, return the id to the user
|
||||||
Ok(TicketbookWalletSharesAsyncResponse { id, uuid }.into())
|
Ok(TicketbookWalletSharesAsyncResponse { id, uuid })
|
||||||
}
|
}
|
||||||
.instrument(span)
|
.instrument(span)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ bincode = { workspace = true, optional = true }
|
|||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
serde = { workspace = true, features = ["derive"], optional = true }
|
serde = { workspace = true, features = ["derive"], optional = true }
|
||||||
time = { workspace = true }
|
|
||||||
tokio = { workspace = true, features = ["sync"] }
|
tokio = { workspace = true, features = ["sync"] }
|
||||||
zeroize = { workspace = true, features = ["zeroize_derive"] }
|
zeroize = { workspace = true, features = ["zeroize_derive"] }
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
CREATE TABLE emergency_credential
|
|
||||||
(
|
|
||||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
||||||
type TEXT NOT NULL,
|
|
||||||
-- don't define any strict schema on the content as it might be implementation-dependant
|
|
||||||
content BLOB NOT NULL,
|
|
||||||
expiration TIMESTAMP WITHOUT TIME ZONE
|
|
||||||
);
|
|
||||||
|
|
||||||
-- no point in allowing duplicate data
|
|
||||||
CREATE UNIQUE INDEX emergency_credential_unique_type_content
|
|
||||||
ON emergency_credential (type, content);
|
|
||||||
@@ -1,10 +1,7 @@
|
|||||||
// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::models::{
|
use crate::models::{BasicTicketbookInformation, RetrievedPendingTicketbook, RetrievedTicketbook};
|
||||||
BasicTicketbookInformation, EmergencyCredential, EmergencyCredentialContent,
|
|
||||||
RetrievedPendingTicketbook, RetrievedTicketbook,
|
|
||||||
};
|
|
||||||
use nym_compact_ecash::scheme::coin_indices_signatures::AnnotatedCoinIndexSignature;
|
use nym_compact_ecash::scheme::coin_indices_signatures::AnnotatedCoinIndexSignature;
|
||||||
use nym_compact_ecash::scheme::expiration_date_signatures::AnnotatedExpirationDateSignature;
|
use nym_compact_ecash::scheme::expiration_date_signatures::AnnotatedExpirationDateSignature;
|
||||||
use nym_compact_ecash::VerificationKeyAuth;
|
use nym_compact_ecash::VerificationKeyAuth;
|
||||||
@@ -25,12 +22,6 @@ pub struct MemoryEcachTicketbookManager {
|
|||||||
inner: Arc<RwLock<EcashCredentialManagerInner>>,
|
inner: Arc<RwLock<EcashCredentialManagerInner>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct InternalIdCounters {
|
|
||||||
next_ticketbook_id: i64,
|
|
||||||
next_emergency_credential_id: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct EcashCredentialManagerInner {
|
struct EcashCredentialManagerInner {
|
||||||
ticketbooks: HashMap<i64, RetrievedTicketbook>,
|
ticketbooks: HashMap<i64, RetrievedTicketbook>,
|
||||||
@@ -38,22 +29,13 @@ struct EcashCredentialManagerInner {
|
|||||||
master_vk: HashMap<u64, VerificationKeyAuth>,
|
master_vk: HashMap<u64, VerificationKeyAuth>,
|
||||||
coin_indices_sigs: HashMap<u64, Vec<AnnotatedCoinIndexSignature>>,
|
coin_indices_sigs: HashMap<u64, Vec<AnnotatedCoinIndexSignature>>,
|
||||||
expiration_date_sigs: HashMap<(u64, Date), Vec<AnnotatedExpirationDateSignature>>,
|
expiration_date_sigs: HashMap<(u64, Date), Vec<AnnotatedExpirationDateSignature>>,
|
||||||
emergency_credentials: HashMap<String, Vec<EmergencyCredential>>,
|
_next_id: i64,
|
||||||
|
|
||||||
// internal counters emulating assignment of an increasing id to new inserted database entries
|
|
||||||
internal_counters: InternalIdCounters,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EcashCredentialManagerInner {
|
impl EcashCredentialManagerInner {
|
||||||
fn next_ticketbook_id(&mut self) -> i64 {
|
fn next_id(&mut self) -> i64 {
|
||||||
let next = self.internal_counters.next_ticketbook_id;
|
let next = self._next_id;
|
||||||
self.internal_counters.next_ticketbook_id += 1;
|
self._next_id += 1;
|
||||||
next
|
|
||||||
}
|
|
||||||
|
|
||||||
fn next_emergency_credential_id(&mut self) -> i64 {
|
|
||||||
let next = self.internal_counters.next_emergency_credential_id;
|
|
||||||
self.internal_counters.next_emergency_credential_id += 1;
|
|
||||||
next
|
next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,7 +170,7 @@ impl MemoryEcachTicketbookManager {
|
|||||||
used_tickets: u32,
|
used_tickets: u32,
|
||||||
) {
|
) {
|
||||||
let mut guard = self.inner.write().await;
|
let mut guard = self.inner.write().await;
|
||||||
let id = guard.next_ticketbook_id();
|
let id = guard.next_id();
|
||||||
|
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
let mut nasty_clone = hack_clone_ticketbook(ticketbook);
|
let mut nasty_clone = hack_clone_ticketbook(ticketbook);
|
||||||
@@ -295,41 +277,4 @@ impl MemoryEcachTicketbookManager {
|
|||||||
sigs.signatures.clone(),
|
sigs.signatures.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_emergency_credential(&self, typ: &str) -> Option<EmergencyCredential> {
|
|
||||||
let guard = self.inner.read().await;
|
|
||||||
|
|
||||||
guard.emergency_credentials.get(typ)?.first().cloned()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn insert_emergency_credential(
|
|
||||||
&self,
|
|
||||||
credential: &EmergencyCredentialContent,
|
|
||||||
) {
|
|
||||||
let mut guard = self.inner.write().await;
|
|
||||||
let id = guard.next_emergency_credential_id();
|
|
||||||
|
|
||||||
guard
|
|
||||||
.emergency_credentials
|
|
||||||
.entry(credential.typ.clone())
|
|
||||||
.or_default()
|
|
||||||
.push(EmergencyCredential {
|
|
||||||
id,
|
|
||||||
data: credential.clone(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn remove_emergency_credential(&self, id: i64) {
|
|
||||||
let mut guard = self.inner.write().await;
|
|
||||||
|
|
||||||
guard.emergency_credentials.retain(|_, credentials| {
|
|
||||||
credentials.retain(|c| c.id != id);
|
|
||||||
!credentials.is_empty()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn remove_emergency_credentials_of_type(&self, typ: &str) {
|
|
||||||
let mut guard = self.inner.write().await;
|
|
||||||
guard.emergency_credentials.remove(typ);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user