Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| afc37988e3 | |||
| 18b0943846 | |||
| 15223fb19f | |||
| 90886091ee | |||
| babf113fe5 | |||
| fc2bd74d75 | |||
| b21c43b106 | |||
| f7a9e22cf3 | |||
| 0d7487f530 | |||
| 378f32e6d7 | |||
| 3e9b8d237f | |||
| f5a4dbc555 | |||
| 4480534e4d | |||
| d355f9d752 | |||
| 9f3a370496 | |||
| e4adc5d954 | |||
| 00373b70e2 | |||
| 65f2017422 | |||
| 192f258463 | |||
| a5eee7444b | |||
| 6abd7e7352 | |||
| 1ecc2a8dda | |||
| 3306ca5357 | |||
| 9c2ccead0e | |||
| b7aeb51362 | |||
| e9e725defe | |||
| f9659ef42c | |||
| c74494a21d | |||
| 54f6c98c22 | |||
| 846484bbb4 | |||
| fb3f5501ba | |||
| e8a607f520 | |||
| f5f6df9eaf | |||
| c647ab5605 | |||
| 416c21a42e | |||
| fd5a95fa4d | |||
| c61df79182 | |||
| 08559a7660 | |||
| 6dce55a99b | |||
| bc0b89b31c | |||
| 67c32faa11 | |||
| aa0d15ee67 | |||
| 17d11f201e | |||
| fef7e42eb4 | |||
| ceeeb6211b | |||
| cd77b1032f | |||
| 6bbb14f12f | |||
| de8030d85a | |||
| e18e64bf21 | |||
| a50c9ac3fb | |||
| 2235a6e147 | |||
| db6defa122 | |||
| df7768dec0 | |||
| f3a449b7cc | |||
| cf21593ffa | |||
| f0d8dabb9f | |||
| f105bcbafe | |||
| dc0f4af2c1 | |||
| 2a621e07a8 | |||
| 485aeebabd | |||
| 3b726bada9 | |||
| 1d1b2e17d2 | |||
| b5b2dbdfd8 | |||
| 82806f47d8 | |||
| c6f85cf23e | |||
| ed8de7234d | |||
| e25d83b047 | |||
| 9974d480b5 | |||
| 2211f13cdd | |||
| 4505f18a02 | |||
| a717a18948 |
@@ -8,10 +8,13 @@ on:
|
||||
- 'gateway/**'
|
||||
- 'integrations/**'
|
||||
- 'nym-api/**'
|
||||
- 'nym-authenticator-client/**'
|
||||
- 'nym-credential-proxy/**'
|
||||
- 'nym-ip-packet-client/**'
|
||||
- 'nym-network-monitor/**'
|
||||
- 'nym-node/**'
|
||||
- 'nym-node-status-api/**'
|
||||
- 'nym-registration-client/**'
|
||||
- 'nym-statistics-api/**'
|
||||
- 'nym-outfox/**'
|
||||
- 'nym-validator-rewarder/**'
|
||||
|
||||
@@ -4,7 +4,7 @@ on:
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: arc-ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -17,13 +17,10 @@ jobs:
|
||||
- name: Setup yarn
|
||||
run: npm install -g yarn
|
||||
|
||||
- name: Install rust toolchain
|
||||
- name: Install Rust stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
|
||||
- name: Install wasm-pack
|
||||
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||
@@ -32,9 +29,9 @@ jobs:
|
||||
run: cargo install wasm-opt
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.24.6"
|
||||
go-version: "1.23.7"
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
|
||||
@@ -3,11 +3,6 @@ name: Build and upload Node Status agent container to harbor.nymte.ch
|
||||
on:
|
||||
workflow_dispatch:
|
||||
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:
|
||||
description: 'Tag image as a release'
|
||||
required: true
|
||||
@@ -43,16 +38,6 @@ jobs:
|
||||
VERSION=$(yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml)
|
||||
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
|
||||
run: echo "RELEASE_TAG=" >> $GITHUB_ENV
|
||||
|
||||
@@ -61,24 +46,12 @@ jobs:
|
||||
run: echo "RELEASE_TAG=golden-" >> $GITHUB_ENV
|
||||
|
||||
- name: Set IMAGE_NAME_AND_TAGS variable
|
||||
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
|
||||
run: echo "IMAGE_NAME_AND_TAGS=${{ env.CONTAINER_NAME }}:${{ env.RELEASE_TAG }}${{ steps.get_version.outputs.result }}" >> $GITHUB_ENV
|
||||
|
||||
- name: New env vars
|
||||
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 }}
|
||||
run: echo "RELEASE_TAG='$RELEASE_TAG' IMAGE_NAME_AND_TAGS='$IMAGE_NAME_AND_TAGS'"
|
||||
|
||||
- name: BuildAndPushImageOnHarbor
|
||||
run: |
|
||||
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 build -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
|
||||
|
||||
@@ -4,6 +4,78 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [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)
|
||||
|
||||
- ns-api: add descriptions to dVPN gateway responses ([#6102])
|
||||
|
||||
Generated
+38
-17
@@ -133,9 +133,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "ammonia"
|
||||
version = "4.1.1"
|
||||
version = "4.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6b346764dd0814805de8abf899fe03065bcee69bb1a4771c785817e39f3978f"
|
||||
checksum = "17e913097e1a2124b46746c980134e8c954bc17a6a59bb3fde96f088d126dde6"
|
||||
dependencies = [
|
||||
"cssparser",
|
||||
"html5ever",
|
||||
@@ -2579,7 +2579,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "extension-storage"
|
||||
version = "1.4.1"
|
||||
version = "1.4.0-rc.0"
|
||||
dependencies = [
|
||||
"bip39",
|
||||
"console_error_panic_hook",
|
||||
@@ -4478,7 +4478,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mix-fetch-wasm"
|
||||
version = "1.4.1-rc2"
|
||||
version = "1.4.0-rc.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
@@ -4488,7 +4488,6 @@ dependencies = [
|
||||
"nym-ordered-buffer",
|
||||
"nym-service-providers-common",
|
||||
"nym-socks5-requests",
|
||||
"nym-validator-client",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde-wasm-bindgen 0.6.5",
|
||||
@@ -4825,7 +4824,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-api"
|
||||
version = "1.1.67"
|
||||
version = "1.1.69"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -5051,7 +5050,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-cli"
|
||||
version = "1.1.64"
|
||||
version = "1.1.66"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.22.1",
|
||||
@@ -5134,7 +5133,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-client"
|
||||
version = "1.1.64"
|
||||
version = "1.1.66"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"clap",
|
||||
@@ -5284,7 +5283,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-client-wasm"
|
||||
version = "1.4.1-rc2"
|
||||
version = "1.4.0-rc.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures",
|
||||
@@ -6051,6 +6050,7 @@ dependencies = [
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"url",
|
||||
"wasmtimer",
|
||||
]
|
||||
@@ -6355,7 +6355,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-network-requester"
|
||||
version = "1.1.65"
|
||||
version = "1.1.67"
|
||||
dependencies = [
|
||||
"addr",
|
||||
"anyhow",
|
||||
@@ -6405,7 +6405,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node"
|
||||
version = "1.19.0"
|
||||
version = "1.21.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arc-swap",
|
||||
@@ -6547,7 +6547,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node-status-api"
|
||||
version = "4.0.10"
|
||||
version = "4.0.11-rc1"
|
||||
dependencies = [
|
||||
"ammonia",
|
||||
"anyhow",
|
||||
@@ -6643,7 +6643,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node-tester-wasm"
|
||||
version = "1.3.1-rc0"
|
||||
version = "1.3.0-rc.0"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"js-sys",
|
||||
@@ -6799,6 +6799,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
"typed-builder",
|
||||
"url",
|
||||
]
|
||||
|
||||
@@ -6931,7 +6932,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.64"
|
||||
version = "1.1.66"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"clap",
|
||||
@@ -7670,7 +7671,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nymvisor"
|
||||
version = "0.1.29"
|
||||
version = "0.1.31"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -7824,9 +7825,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.110"
|
||||
version = "0.9.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2"
|
||||
checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@@ -11392,6 +11393,26 @@ dependencies = [
|
||||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-builder"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d0dd654273fc253fde1df4172c31fb6615cf8b041d3a4008a028ef8b1119e66"
|
||||
dependencies = [
|
||||
"typed-builder-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-builder-macro"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "016c26257f448222014296978b2c8456e2cad4de308c35bdb1e383acd569ef5b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.18.0"
|
||||
|
||||
+2
-13
@@ -150,7 +150,7 @@ members = [
|
||||
"tools/internal/contract-state-importer/importer-cli",
|
||||
"tools/internal/contract-state-importer/importer-contract",
|
||||
"tools/internal/mixnet-connectivity-check",
|
||||
# "tools/internal/sdk-version-bump",
|
||||
# "tools/internal/sdk-version-bump",
|
||||
"tools/internal/ssl-inject",
|
||||
"tools/internal/testnet-manager",
|
||||
"tools/internal/testnet-manager/dkg-bypass-contract",
|
||||
@@ -215,7 +215,6 @@ base64 = "0.22.1"
|
||||
base85rs = "0.1.3"
|
||||
bincode = "1.3.3"
|
||||
bip39 = { version = "2.0.0", features = ["zeroize"] }
|
||||
bit-vec = "0.7.0" # can we unify those?
|
||||
bitvec = "1.0.0"
|
||||
blake3 = "1.7.0"
|
||||
bloomfilter = "3.0.1"
|
||||
@@ -243,13 +242,11 @@ criterion = "0.5"
|
||||
csv = "1.3.1"
|
||||
ctr = "0.9.1"
|
||||
cupid = "0.6.1"
|
||||
curve25519-dalek = "4.1"
|
||||
dashmap = "5.5.3"
|
||||
# We want https://github.com/DefGuard/wireguard-rs/pull/64 , but there's no crates.io release being pushed out anymore
|
||||
defguard_wireguard_rs = { git = "https://github.com/DefGuard/wireguard-rs.git", rev = "v0.4.7" }
|
||||
digest = "0.10.7"
|
||||
dirs = "6.0"
|
||||
doc-comment = "0.3"
|
||||
dotenvy = "0.15.6"
|
||||
dyn-clone = "1.0.19"
|
||||
ecdsa = "0.16"
|
||||
@@ -265,11 +262,8 @@ futures = "0.3.31"
|
||||
futures-util = "0.3"
|
||||
generic-array = "0.14.7"
|
||||
getrandom = "0.2.10"
|
||||
getset = "0.1.5"
|
||||
handlebars = "3.5.5"
|
||||
headers = "0.4.0"
|
||||
hex = "0.4.3"
|
||||
hex-literal = "0.3.3"
|
||||
hickory-resolver = "0.25"
|
||||
hkdf = "0.12.3"
|
||||
hmac = "0.12.1"
|
||||
@@ -293,12 +287,10 @@ lazy_static = "1.5.0"
|
||||
ledger-transport = "0.10.0"
|
||||
ledger-transport-hid = "0.10.0"
|
||||
log = "0.4"
|
||||
maxminddb = "0.23.0"
|
||||
mime = "0.3.17"
|
||||
moka = { version = "0.12", features = ["future"] }
|
||||
nix = "0.27.1"
|
||||
notify = "5.1.0"
|
||||
okapi = "0.7.0"
|
||||
once_cell = "1.21.3"
|
||||
opentelemetry = "0.19.0"
|
||||
opentelemetry-jaeger = "0.18.0"
|
||||
@@ -307,7 +299,6 @@ pem = "0.8"
|
||||
petgraph = "0.6.5"
|
||||
pin-project = "1.1"
|
||||
pnet_packet = "0.35.0"
|
||||
pin-project-lite = "0.2.16"
|
||||
publicsuffix = "2.3.0"
|
||||
proc_pidinfo = "0.1.3"
|
||||
quote = "1"
|
||||
@@ -315,13 +306,10 @@ rand = "0.8.5"
|
||||
rand_chacha = "0.3"
|
||||
rand_core = "0.6.3"
|
||||
rand_distr = "0.4"
|
||||
rand_pcg = "0.3.1"
|
||||
rand_seeder = "0.2.3"
|
||||
rayon = "1.5.1"
|
||||
regex = "1.10.6"
|
||||
reqwest = { version = "0.12.15", default-features = false }
|
||||
rs_merkle = "1.5.0"
|
||||
safer-ffi = "0.1.13"
|
||||
schemars = "0.8.22"
|
||||
semver = "1.0.26"
|
||||
serde = "1.0.219"
|
||||
@@ -368,6 +356,7 @@ tracing-indicatif = "0.3.9"
|
||||
tracing-test = "0.2.5"
|
||||
ts-rs = "10.1.0"
|
||||
tungstenite = { version = "0.20.1", default-features = false }
|
||||
typed-builder = "0.23.0"
|
||||
uniffi = "0.29.2"
|
||||
uniffi_build = "0.29.0"
|
||||
url = "2.5"
|
||||
|
||||
@@ -107,16 +107,16 @@ sdk-wasm-build:
|
||||
$(MAKE) -C nym-browser-extension/storage wasm-pack
|
||||
$(MAKE) -C wasm/client
|
||||
$(MAKE) -C wasm/node-tester
|
||||
$(MAKE) -C wasm/mix-fetch
|
||||
# $(MAKE) -C wasm/mix-fetch
|
||||
$(MAKE) -C wasm/zknym-lib
|
||||
# $(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
|
||||
sdk-typescript-build:
|
||||
npx lerna run --scope @nymproject/sdk build --stream
|
||||
npx lerna run --scope @nymproject/mix-fetch build --stream
|
||||
npx lerna run --scope @nymproject/node-tester build --stream
|
||||
yarn --cwd sdk/typescript/codegen/contract-clients build
|
||||
# npx lerna run --scope @nymproject/mix-fetch build --stream
|
||||
# npx lerna run --scope @nymproject/node-tester build --stream
|
||||
# yarn --cwd sdk/typescript/codegen/contract-clients build
|
||||
|
||||
# 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-client"
|
||||
version = "1.1.64"
|
||||
version = "1.1.66"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||
description = "Implementation of the Nym Client"
|
||||
edition = "2021"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.64"
|
||||
version = "1.1.66"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||
edition = "2021"
|
||||
|
||||
@@ -801,7 +801,7 @@ where
|
||||
event_tx,
|
||||
);
|
||||
|
||||
let mix_tx = mix_traffic_controller.mix_rx();
|
||||
let mix_tx = mix_traffic_controller.mix_tx();
|
||||
let client_tx = mix_traffic_controller.client_tx();
|
||||
|
||||
shutdown_tracker.try_spawn_named(
|
||||
@@ -1004,8 +1004,8 @@ where
|
||||
// Create a shutdown tracker for this client - either as a child of provided tracker
|
||||
// or get one from the registry
|
||||
let shutdown_tracker = match self.shutdown {
|
||||
Some(parent_tracker) => parent_tracker.child_tracker(),
|
||||
None => nym_task::get_sdk_shutdown_tracker()?,
|
||||
Some(parent_tracker) => parent_tracker.clone(),
|
||||
None => nym_task::create_sdk_shutdown_tracker()?,
|
||||
};
|
||||
|
||||
Self::start_event_control(self.event_tx, event_receiver, &shutdown_tracker);
|
||||
@@ -1044,7 +1044,7 @@ where
|
||||
self.user_agent.clone(),
|
||||
generate_client_stats_id(*self_address.identity()),
|
||||
input_sender.clone(),
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
);
|
||||
|
||||
// needs to be started as the first thing to block if required waiting for the gateway
|
||||
@@ -1054,7 +1054,7 @@ where
|
||||
shared_topology_accessor.clone(),
|
||||
self_address.gateway(),
|
||||
self.wait_for_gateway,
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -1074,7 +1074,7 @@ where
|
||||
stats_reporter.clone(),
|
||||
#[cfg(unix)]
|
||||
self.connection_fd_callback,
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
)
|
||||
.await?;
|
||||
let gateway_ws_fd = gateway_transceiver.ws_fd();
|
||||
@@ -1082,7 +1082,7 @@ where
|
||||
let reply_storage = Self::setup_persistent_reply_storage(
|
||||
reply_storage_backend,
|
||||
key_rotation_config,
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -1093,7 +1093,7 @@ where
|
||||
reply_storage.key_storage(),
|
||||
reply_controller_sender.clone(),
|
||||
stats_reporter.clone(),
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
);
|
||||
|
||||
// The message_sender is the transmitter for any component generating sphinx packets
|
||||
@@ -1103,7 +1103,7 @@ where
|
||||
|
||||
let (message_sender, client_request_sender) = Self::start_mix_traffic_controller(
|
||||
gateway_transceiver,
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
EventSender(event_sender),
|
||||
);
|
||||
|
||||
@@ -1134,7 +1134,7 @@ where
|
||||
shared_lane_queue_lengths.clone(),
|
||||
client_connection_rx,
|
||||
stats_reporter.clone(),
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
);
|
||||
|
||||
if !self
|
||||
@@ -1150,7 +1150,7 @@ where
|
||||
shared_topology_accessor.clone(),
|
||||
message_sender,
|
||||
stats_reporter.clone(),
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
||||
TrySendError::Full(_) => {
|
||||
// This isn't a problem, if the channel is full means we're already sending the
|
||||
// max amount of messages downstream can handle.
|
||||
tracing::debug!("Failed to send cover message - channel full");
|
||||
tracing::trace!("Failed to send cover message - channel full");
|
||||
}
|
||||
TrySendError::Closed(_) => {
|
||||
tracing::warn!("Failed to send cover message - channel closed");
|
||||
|
||||
@@ -20,7 +20,10 @@ pub mod transceiver;
|
||||
|
||||
// We remind ourselves that 32 x 32kb = 1024kb, a reasonable size for a network buffer.
|
||||
pub const MIX_MESSAGE_RECEIVER_BUFFER_SIZE: usize = 32;
|
||||
const MAX_FAILURE_COUNT: usize = 100;
|
||||
|
||||
/// Reduced from 100 to 20 to fail fast (~1-2 seconds instead of ~6 seconds).
|
||||
/// If we can't send 20 packets in a row, the gateway is unreachable.
|
||||
const MAX_FAILURE_COUNT: usize = 20;
|
||||
|
||||
// that's also disgusting.
|
||||
pub struct Empty;
|
||||
@@ -84,7 +87,7 @@ impl MixTrafficController {
|
||||
self.client_tx.clone()
|
||||
}
|
||||
|
||||
pub fn mix_rx(&self) -> BatchMixMessageSender {
|
||||
pub fn mix_tx(&self) -> BatchMixMessageSender {
|
||||
self.mix_tx.clone()
|
||||
}
|
||||
|
||||
@@ -156,6 +159,11 @@ impl MixTrafficController {
|
||||
// Do we need to handle the embedded mixnet client case
|
||||
// separately?
|
||||
self.event_tx.send(MixnetClientEvent::Traffic(MixTrafficEvent::FailedSendingSphinx));
|
||||
// IMO it shouldn't be signalled from there but it is how it is
|
||||
// TODO : report the failure upwards and shutdown from upwards
|
||||
// Gateway is dead, we have to shut down currently
|
||||
error!("Signalling shutdown from the MixTrafficController");
|
||||
self.shutdown_token.cancel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,6 +298,8 @@ where
|
||||
"failed to send mixnet packet due to closed channel (outside of shutdown!)"
|
||||
);
|
||||
}
|
||||
// Early return to avoid further processing when channel is closed
|
||||
return;
|
||||
}
|
||||
Ok(_) => {
|
||||
let event = if fragment_id.is_some() {
|
||||
|
||||
@@ -45,7 +45,7 @@ pub enum ClientCoreError {
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[error("resolution failed: {0}")]
|
||||
ResolutionFailed(#[from] nym_http_api_client::HickoryDnsError),
|
||||
ResolutionFailed(#[from] nym_http_api_client::ResolveError),
|
||||
|
||||
#[error("no gateways on network")]
|
||||
NoGatewaysOnNetwork,
|
||||
|
||||
@@ -441,7 +441,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_multiple_urls_prepared_for_retries() {
|
||||
let urls = vec![
|
||||
let urls = [
|
||||
Url::parse("https://api1.nym.com").unwrap(),
|
||||
Url::parse("https://api2.nym.com").unwrap(),
|
||||
Url::parse("https://api3.nym.com").unwrap(),
|
||||
|
||||
@@ -30,7 +30,6 @@ pub(crate) async fn connect_async(
|
||||
resolver
|
||||
.resolve_str(domain)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|a| SocketAddr::new(a, port))
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ pub(crate) async fn connect_async(
|
||||
resolver
|
||||
.resolve_str(domain)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|a| SocketAddr::new(a, port))
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ pub enum GatewayClientError {
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[error("resolution failed: {0}")]
|
||||
ResolutionFailed(#[from] nym_http_api_client::HickoryDnsError),
|
||||
ResolutionFailed(#[from] nym_http_api_client::ResolveError),
|
||||
|
||||
#[error("No shared key was provided or obtained")]
|
||||
NoSharedKeyAvailable,
|
||||
|
||||
@@ -241,23 +241,28 @@ impl Epoch {
|
||||
//
|
||||
// Note: It's important that the variant ordering is not changed otherwise it would mess up the derived `PartialOrd`
|
||||
#[cw_serde]
|
||||
#[derive(Copy)]
|
||||
#[derive(Copy, Default)]
|
||||
pub enum EpochState {
|
||||
#[default]
|
||||
WaitingInitialisation,
|
||||
PublicKeySubmission { resharing: bool },
|
||||
DealingExchange { resharing: bool },
|
||||
VerificationKeySubmission { resharing: bool },
|
||||
VerificationKeyValidation { resharing: bool },
|
||||
VerificationKeyFinalization { resharing: bool },
|
||||
PublicKeySubmission {
|
||||
resharing: bool,
|
||||
},
|
||||
DealingExchange {
|
||||
resharing: bool,
|
||||
},
|
||||
VerificationKeySubmission {
|
||||
resharing: bool,
|
||||
},
|
||||
VerificationKeyValidation {
|
||||
resharing: bool,
|
||||
},
|
||||
VerificationKeyFinalization {
|
||||
resharing: bool,
|
||||
},
|
||||
InProgress,
|
||||
}
|
||||
|
||||
impl Default for EpochState {
|
||||
fn default() -> Self {
|
||||
Self::WaitingInitialisation
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for EpochState {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
|
||||
@@ -246,7 +246,7 @@ mod tests {
|
||||
let _exp_date_sigs = generate_expiration_date_signatures(
|
||||
sig_req.expiration_date.ecash_unix_timestamp(),
|
||||
&[signing_keys.secret_key()],
|
||||
&vec![signing_keys.verification_key()],
|
||||
&[signing_keys.verification_key()],
|
||||
&signing_keys.verification_key(),
|
||||
&[1],
|
||||
)?;
|
||||
@@ -263,7 +263,7 @@ mod tests {
|
||||
|
||||
let wallet = issuance.aggregate_signature_shares(
|
||||
&signing_keys.verification_key(),
|
||||
&vec![partial_wallet],
|
||||
&[partial_wallet],
|
||||
sig_req,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ mod tests {
|
||||
let exp_date_sigs = generate_expiration_date_signatures(
|
||||
sig_req.expiration_date.ecash_unix_timestamp(),
|
||||
&[keypair.secret_key()],
|
||||
&vec![keypair.verification_key()],
|
||||
&[keypair.verification_key()],
|
||||
&keypair.verification_key(),
|
||||
&[keypair.index.unwrap()],
|
||||
)
|
||||
@@ -106,14 +106,14 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let wallet = issuance
|
||||
.aggregate_signature_shares(&keypair.verification_key(), &vec![partial_wallet], sig_req)
|
||||
.aggregate_signature_shares(&keypair.verification_key(), &[partial_wallet], sig_req)
|
||||
.unwrap();
|
||||
|
||||
let mut issued = issuance.into_issued_ticketbook(wallet, 1);
|
||||
let coin_indices_signatures = generate_coin_indices_signatures(
|
||||
nym_credentials_interface::ecash_parameters(),
|
||||
&[keypair.secret_key()],
|
||||
&vec![keypair.verification_key()],
|
||||
&[keypair.verification_key()],
|
||||
&keypair.verification_key(),
|
||||
&[keypair.index.unwrap()],
|
||||
)
|
||||
|
||||
@@ -32,7 +32,7 @@ thiserror = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
itertools = { workspace = true }
|
||||
inventory = { workspace = true }
|
||||
|
||||
tokio = { workspace = true, features = ["rt", "macros", "time"] }
|
||||
# used for decoding text responses (they were already implicitly included)
|
||||
bytes = { workspace = true }
|
||||
encoding_rs = { workspace = true }
|
||||
@@ -52,5 +52,4 @@ workspace = true
|
||||
features = ["tokio"]
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { workspace = true, features = ["rt", "macros"] }
|
||||
|
||||
tracing-subscriber.workspace = true
|
||||
|
||||
@@ -30,19 +30,26 @@
|
||||
use crate::ClientBuilder;
|
||||
|
||||
use std::{
|
||||
net::SocketAddr,
|
||||
collections::HashMap,
|
||||
net::{IpAddr, SocketAddr},
|
||||
str::FromStr,
|
||||
sync::{Arc, LazyLock},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use hickory_resolver::{
|
||||
ResolveError, TokioResolver,
|
||||
TokioResolver,
|
||||
config::{LookupIpStrategy, NameServerConfigGroup, ResolverConfig, ServerOrderingStrategy},
|
||||
lookup_ip::{LookupIp, LookupIpIntoIter},
|
||||
lookup_ip::LookupIpIntoIter,
|
||||
name_server::TokioConnectionProvider,
|
||||
};
|
||||
use once_cell::sync::OnceCell;
|
||||
use reqwest::dns::{Addrs, Name, Resolve, Resolving};
|
||||
use tracing::warn;
|
||||
use tracing::*;
|
||||
|
||||
mod constants;
|
||||
mod static_resolver;
|
||||
pub use static_resolver::*;
|
||||
|
||||
impl ClientBuilder {
|
||||
/// Override the DNS resolver implementation used by the underlying http client.
|
||||
@@ -59,10 +66,6 @@ impl ClientBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
struct SocketAddrs {
|
||||
iter: LookupIpIntoIter,
|
||||
}
|
||||
|
||||
// n.b. static items do not call [`Drop`] on program termination, so this won't be deallocated.
|
||||
// this is fine, as the OS can deallocate the terminated program faster than we can free memory
|
||||
// but tools like valgrind might report "memory leaks" as it isn't obvious this is intentional.
|
||||
@@ -72,11 +75,17 @@ static SHARED_RESOLVER: LazyLock<HickoryDnsResolver> = LazyLock::new(|| {
|
||||
});
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[error("hickory-dns resolver error: {hickory_error}")]
|
||||
#[allow(missing_docs)]
|
||||
/// Error occurring while resolving a hostname into an IP address.
|
||||
pub struct HickoryDnsError {
|
||||
#[from]
|
||||
hickory_error: ResolveError,
|
||||
pub enum ResolveError {
|
||||
#[error("invalid name: {0}")]
|
||||
InvalidNameError(String),
|
||||
#[error("hickory-dns resolver error: {0}")]
|
||||
ResolveError(#[from] hickory_resolver::ResolveError),
|
||||
#[error("high level lookup timed out")]
|
||||
Timeout,
|
||||
#[error("hostname not found in static lookup table")]
|
||||
StaticLookupMiss,
|
||||
}
|
||||
|
||||
/// Wrapper around an `AsyncResolver`, which implements the `Resolve` trait.
|
||||
@@ -87,69 +96,118 @@ pub struct HickoryDnsError {
|
||||
/// The default initialization uses a shared underlying `AsyncResolver`. If a thread local resolver
|
||||
/// is required use `thread_resolver()` to build a resolver with an independently instantiated
|
||||
/// internal `AsyncResolver`.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct HickoryDnsResolver {
|
||||
// Since we might not have been called in the context of a
|
||||
// Tokio Runtime in initialization, so we must delay the actual
|
||||
// construction of the resolver.
|
||||
state: Arc<OnceCell<TokioResolver>>,
|
||||
fallback: Option<Arc<OnceCell<TokioResolver>>>,
|
||||
static_base: Option<Arc<OnceCell<StaticResolver>>>,
|
||||
dont_use_shared: bool,
|
||||
/// Overall timeout for dns lookup associated with any individual host resolution. For example,
|
||||
/// use of retries, server_ordering_strategy, etc. ends absolutely if this timeout is reached.
|
||||
overall_dns_timeout: Duration,
|
||||
}
|
||||
|
||||
impl Default for HickoryDnsResolver {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
state: Default::default(),
|
||||
// Disable system resolver fallback by default - often blocked by firewalls in VPN environments
|
||||
// Enable static fallback for known domains
|
||||
fallback: None,
|
||||
static_base: Some(Default::default()),
|
||||
dont_use_shared: Default::default(),
|
||||
overall_dns_timeout: Duration::from_secs(10),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Resolve for HickoryDnsResolver {
|
||||
fn resolve(&self, name: Name) -> Resolving {
|
||||
let resolver = self.state.clone();
|
||||
let maybe_fallback = self.fallback.clone();
|
||||
let maybe_static = self.static_base.clone();
|
||||
let independent = self.dont_use_shared;
|
||||
let overall_dns_timeout = self.overall_dns_timeout;
|
||||
Box::pin(async move {
|
||||
let resolver = resolver.get_or_try_init(|| {
|
||||
// using a closure here is slightly gross, but this makes sure that if the
|
||||
// lazy-init returns an error it can be handled by the client
|
||||
if independent {
|
||||
new_resolver()
|
||||
} else {
|
||||
Ok(SHARED_RESOLVER.state.get_or_try_init(new_resolver)?.clone())
|
||||
}
|
||||
})?;
|
||||
resolve(
|
||||
name,
|
||||
resolver,
|
||||
maybe_fallback,
|
||||
maybe_static,
|
||||
independent,
|
||||
overall_dns_timeout,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// try the primary DNS resolver that we set up (DoH or DoT or whatever)
|
||||
let lookup = match resolver.lookup_ip(name.as_str()).await {
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
if let Some(ref fallback) = maybe_fallback {
|
||||
// on failure use the fall back system configured DNS resolver
|
||||
if !e.is_no_records_found() {
|
||||
warn!("primary DNS failed w/ error {e}: using system fallback");
|
||||
}
|
||||
let resolver = fallback.get_or_try_init(|| {
|
||||
// using a closure here is slightly gross, but this makes sure that if the
|
||||
// lazy-init returns an error it can be handled by the client
|
||||
if independent {
|
||||
new_resolver_system()
|
||||
} else {
|
||||
Ok(SHARED_RESOLVER
|
||||
.fallback
|
||||
.as_ref()
|
||||
.ok_or(e)? // if the shared resolver has no fallback return the original error
|
||||
.get_or_try_init(new_resolver_system)?
|
||||
.clone())
|
||||
}
|
||||
})?;
|
||||
|
||||
resolver.lookup_ip(name.as_str()).await?
|
||||
} else {
|
||||
return Err(e.into());
|
||||
}
|
||||
}
|
||||
};
|
||||
async fn resolve(
|
||||
name: Name,
|
||||
resolver: Arc<OnceCell<TokioResolver>>,
|
||||
maybe_fallback: Option<Arc<OnceCell<TokioResolver>>>,
|
||||
maybe_static: Option<Arc<OnceCell<StaticResolver>>>,
|
||||
independent: bool,
|
||||
overall_dns_timeout: Duration,
|
||||
) -> Result<Addrs, ResolveError> {
|
||||
let resolver = resolver.get_or_try_init(|| HickoryDnsResolver::new_resolver(independent))?;
|
||||
|
||||
// Attempt a lookup using the primary resolver
|
||||
let resolve_fut = tokio::time::timeout(overall_dns_timeout, resolver.lookup_ip(name.as_str()));
|
||||
let primary_err = match resolve_fut.await {
|
||||
Err(_) => ResolveError::Timeout,
|
||||
Ok(Ok(lookup)) => {
|
||||
let addrs: Addrs = Box::new(SocketAddrs {
|
||||
iter: lookup.into_iter(),
|
||||
});
|
||||
Ok(addrs)
|
||||
})
|
||||
return Ok(addrs);
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
// on failure use the fall back system configured DNS resolver
|
||||
if !e.is_no_records_found() {
|
||||
warn!("primary DNS failed w/ error: {e}");
|
||||
}
|
||||
e.into()
|
||||
}
|
||||
};
|
||||
|
||||
// If the primary resolver encountered an error, attempt a lookup using the fallback
|
||||
// resolver if one is configured.
|
||||
if let Some(ref fallback) = maybe_fallback {
|
||||
let resolver =
|
||||
fallback.get_or_try_init(|| HickoryDnsResolver::new_resolver_system(independent))?;
|
||||
|
||||
let resolve_fut =
|
||||
tokio::time::timeout(overall_dns_timeout, resolver.lookup_ip(name.as_str()));
|
||||
if let Ok(Ok(lookup)) = resolve_fut.await {
|
||||
let addrs: Addrs = Box::new(SocketAddrs {
|
||||
iter: lookup.into_iter(),
|
||||
});
|
||||
return Ok(addrs);
|
||||
}
|
||||
}
|
||||
|
||||
// If no record has been found and a static map of fallback addresses is configured
|
||||
// check the table for our entry
|
||||
if let Some(ref static_resolver) = maybe_static {
|
||||
debug!("checking static");
|
||||
let resolver =
|
||||
static_resolver.get_or_init(|| HickoryDnsResolver::new_static_fallback(independent));
|
||||
|
||||
if let Ok(addrs) = resolver.resolve(name).await {
|
||||
return Ok(addrs);
|
||||
}
|
||||
}
|
||||
|
||||
Err(primary_err)
|
||||
}
|
||||
|
||||
struct SocketAddrs {
|
||||
iter: LookupIpIntoIter,
|
||||
}
|
||||
|
||||
impl Iterator for SocketAddrs {
|
||||
@@ -162,28 +220,22 @@ impl Iterator for SocketAddrs {
|
||||
|
||||
impl HickoryDnsResolver {
|
||||
/// Attempt to resolve a domain name to a set of ['IpAddr']s
|
||||
pub async fn resolve_str(&self, name: &str) -> Result<LookupIp, HickoryDnsError> {
|
||||
let resolver = self.state.get_or_try_init(|| self.new_resolver())?;
|
||||
|
||||
// try the primary DNS resolver that we set up (DoH or DoT or whatever)
|
||||
let lookup = match resolver.lookup_ip(name).await {
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
if let Some(ref fallback) = self.fallback {
|
||||
// on failure use the fall back system configured DNS resolver
|
||||
if !e.is_no_records_found() {
|
||||
warn!("primary DNS failed w/ error {e}: using system fallback");
|
||||
}
|
||||
|
||||
let resolver = fallback.get_or_try_init(|| self.new_resolver_system())?;
|
||||
resolver.lookup_ip(name).await?
|
||||
} else {
|
||||
return Err(e.into());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(lookup)
|
||||
pub async fn resolve_str(
|
||||
&self,
|
||||
name: &str,
|
||||
) -> Result<impl Iterator<Item = IpAddr> + use<>, ResolveError> {
|
||||
let n =
|
||||
Name::from_str(name).map_err(|_| ResolveError::InvalidNameError(name.to_string()))?;
|
||||
resolve(
|
||||
n,
|
||||
self.state.clone(),
|
||||
self.fallback.clone(),
|
||||
self.static_base.clone(),
|
||||
self.dont_use_shared,
|
||||
self.overall_dns_timeout,
|
||||
)
|
||||
.await
|
||||
.map(|addrs| addrs.map(|socket_addr| socket_addr.ip()))
|
||||
}
|
||||
|
||||
/// Create a (lazy-initialized) resolver that is not shared across threads.
|
||||
@@ -194,16 +246,20 @@ impl HickoryDnsResolver {
|
||||
}
|
||||
}
|
||||
|
||||
fn new_resolver(&self) -> Result<TokioResolver, HickoryDnsError> {
|
||||
if self.dont_use_shared {
|
||||
fn new_resolver(dont_use_shared: bool) -> Result<TokioResolver, ResolveError> {
|
||||
// using a closure here is slightly gross, but this makes sure that if the
|
||||
// lazy-init returns an error it can be handled by the client
|
||||
if dont_use_shared {
|
||||
new_resolver()
|
||||
} else {
|
||||
Ok(SHARED_RESOLVER.state.get_or_try_init(new_resolver)?.clone())
|
||||
}
|
||||
}
|
||||
|
||||
fn new_resolver_system(&self) -> Result<TokioResolver, HickoryDnsError> {
|
||||
if self.dont_use_shared || SHARED_RESOLVER.fallback.is_none() {
|
||||
fn new_resolver_system(dont_use_shared: bool) -> Result<TokioResolver, ResolveError> {
|
||||
// using a closure here is slightly gross, but this makes sure that if the
|
||||
// lazy-init returns an error it can be handled by the client
|
||||
if dont_use_shared || SHARED_RESOLVER.fallback.is_none() {
|
||||
new_resolver_system()
|
||||
} else {
|
||||
Ok(SHARED_RESOLVER
|
||||
@@ -215,8 +271,18 @@ impl HickoryDnsResolver {
|
||||
}
|
||||
}
|
||||
|
||||
fn new_static_fallback(dont_use_shared: bool) -> StaticResolver {
|
||||
if !dont_use_shared && let Some(ref shared_resolver) = SHARED_RESOLVER.static_base {
|
||||
shared_resolver
|
||||
.get_or_init(new_default_static_fallback)
|
||||
.clone()
|
||||
} else {
|
||||
new_default_static_fallback()
|
||||
}
|
||||
}
|
||||
|
||||
/// Enable fallback to the system default resolver if the primary (DoX) resolver fails
|
||||
pub fn enable_system_fallback(&mut self) -> Result<(), HickoryDnsError> {
|
||||
pub fn enable_system_fallback(&mut self) -> Result<(), ResolveError> {
|
||||
self.fallback = Some(Default::default());
|
||||
let _ = self
|
||||
.fallback
|
||||
@@ -231,22 +297,52 @@ impl HickoryDnsResolver {
|
||||
pub fn disable_system_fallback(&mut self) {
|
||||
self.fallback = None;
|
||||
}
|
||||
|
||||
/// Get the current map of hostname to address in use by the fallback static lookup if one
|
||||
/// exists.
|
||||
pub fn get_static_fallbacks(&self) -> Option<HashMap<String, Vec<IpAddr>>> {
|
||||
Some(self.static_base.as_ref()?.get()?.get_addrs())
|
||||
}
|
||||
|
||||
/// Set (or overwrite) the map of addresses used in the fallback static hostname lookup
|
||||
pub fn set_static_fallbacks(&mut self, addrs: HashMap<String, Vec<IpAddr>>) {
|
||||
let cell = OnceCell::new();
|
||||
cell.set(StaticResolver::new(addrs))
|
||||
.expect("infallible assign");
|
||||
self.static_base = Some(Arc::new(cell));
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new resolver with a custom DoT based configuration. The options are overridden to look
|
||||
/// up for both IPv4 and IPv6 addresses to work with "happy eyeballs" algorithm.
|
||||
fn new_resolver() -> Result<TokioResolver, HickoryDnsError> {
|
||||
///
|
||||
/// Timeout Defaults to 5 seconds
|
||||
/// Number of retries after lookup failure before giving up Defaults to 2
|
||||
///
|
||||
/// Caches successfully resolved addresses for 30 minutes to prevent continual use of remote lookup.
|
||||
/// This resolver is intended to be used for OUR API endpoints that do not rapidly rotate IPs.
|
||||
fn new_resolver() -> Result<TokioResolver, ResolveError> {
|
||||
info!("building new configured resolver");
|
||||
|
||||
let mut name_servers = NameServerConfigGroup::quad9_tls();
|
||||
name_servers.merge(NameServerConfigGroup::quad9_https());
|
||||
name_servers.merge(NameServerConfigGroup::cloudflare_tls());
|
||||
name_servers.merge(NameServerConfigGroup::cloudflare_https());
|
||||
|
||||
configure_and_build_resolver(name_servers)
|
||||
}
|
||||
|
||||
fn configure_and_build_resolver(
|
||||
name_servers: NameServerConfigGroup,
|
||||
) -> Result<TokioResolver, ResolveError> {
|
||||
let config = ResolverConfig::from_parts(None, Vec::new(), name_servers);
|
||||
let mut resolver_builder =
|
||||
TokioResolver::builder_with_config(config, TokioConnectionProvider::default());
|
||||
|
||||
resolver_builder.options_mut().ip_strategy = LookupIpStrategy::Ipv4AndIpv6;
|
||||
resolver_builder.options_mut().ip_strategy = get_ip_strategy();
|
||||
resolver_builder.options_mut().server_ordering_strategy = ServerOrderingStrategy::RoundRobin;
|
||||
// Cache successful responses for queries received by this resolver for 30 min minimum.
|
||||
resolver_builder.options_mut().positive_min_ttl = Some(Duration::from_secs(1800));
|
||||
|
||||
Ok(resolver_builder.build())
|
||||
}
|
||||
@@ -254,20 +350,54 @@ fn new_resolver() -> Result<TokioResolver, HickoryDnsError> {
|
||||
/// Create a new resolver with the default configuration, which reads from the system DNS config
|
||||
/// (i.e. `/etc/resolve.conf` in unix). The options are overridden to look up for both IPv4 and IPv6
|
||||
/// addresses to work with "happy eyeballs" algorithm.
|
||||
fn new_resolver_system() -> Result<TokioResolver, HickoryDnsError> {
|
||||
fn new_resolver_system() -> Result<TokioResolver, ResolveError> {
|
||||
let mut resolver_builder = TokioResolver::builder_tokio()?;
|
||||
resolver_builder.options_mut().ip_strategy = LookupIpStrategy::Ipv4AndIpv6;
|
||||
resolver_builder.options_mut().ip_strategy = get_ip_strategy();
|
||||
|
||||
Ok(resolver_builder.build())
|
||||
}
|
||||
|
||||
fn new_default_static_fallback() -> StaticResolver {
|
||||
StaticResolver::new(constants::default_static_addrs())
|
||||
}
|
||||
|
||||
/// Check if IPv6 stack is available for DNS resolution.
|
||||
fn should_use_ipv6_dns() -> bool {
|
||||
use std::net::UdpSocket;
|
||||
|
||||
match UdpSocket::bind("[::]:0") {
|
||||
Ok(_) => {
|
||||
debug!("IPv6 stack available - enabling dual-stack DNS");
|
||||
true
|
||||
}
|
||||
Err(e) => {
|
||||
debug!("IPv6 unavailable ({}), using IPv4-only DNS", e);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get DNS lookup strategy based on IPv6 availability.
|
||||
fn get_ip_strategy() -> LookupIpStrategy {
|
||||
if should_use_ipv6_dns() {
|
||||
debug!("Using dual-stack DNS (IPv4 + IPv6)");
|
||||
LookupIpStrategy::Ipv4AndIpv6
|
||||
} else {
|
||||
debug!("Using IPv4-only DNS");
|
||||
LookupIpStrategy::Ipv4Only
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use itertools::Itertools;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[tokio::test]
|
||||
async fn reqwest_hickory_doh() {
|
||||
let resolver = HickoryDnsResolver::default();
|
||||
async fn reqwest_with_custom_dns() {
|
||||
let var_name = HickoryDnsResolver::default();
|
||||
let resolver = var_name;
|
||||
let client = reqwest::ClientBuilder::new()
|
||||
.dns_resolver(resolver.into())
|
||||
.build()
|
||||
@@ -286,7 +416,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn dns_lookup() -> Result<(), HickoryDnsError> {
|
||||
async fn dns_lookup() -> Result<(), ResolveError> {
|
||||
let resolver = HickoryDnsResolver::default();
|
||||
|
||||
let domain = "ifconfig.me";
|
||||
@@ -296,4 +426,153 @@ mod test {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn static_resolver_as_fallback() -> Result<(), ResolveError> {
|
||||
let example_domain = "non-existent.nymvpn.com";
|
||||
let mut resolver = HickoryDnsResolver {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let result = resolver.resolve_str(example_domain).await;
|
||||
assert!(result.is_err()); // should be NXDomain
|
||||
|
||||
resolver.static_base = Some(Default::default());
|
||||
|
||||
let mut addr_map = HashMap::new();
|
||||
let example_ip4: IpAddr = "10.10.10.10".parse().unwrap();
|
||||
let example_ip6: IpAddr = "dead::beef".parse().unwrap();
|
||||
addr_map.insert(example_domain.to_string(), vec![example_ip4, example_ip6]);
|
||||
|
||||
resolver.set_static_fallbacks(addr_map);
|
||||
|
||||
let mut addrs = resolver.resolve_str(example_domain).await?;
|
||||
assert!(addrs.contains(&example_ip4));
|
||||
assert!(addrs.contains(&example_ip6));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_resolver_fallback_config() {
|
||||
let resolver = HickoryDnsResolver::default();
|
||||
assert!(
|
||||
resolver.fallback.is_none(),
|
||||
"system fallback should be disabled by default for VPN environments"
|
||||
);
|
||||
assert!(
|
||||
resolver.static_base.is_some(),
|
||||
"static fallback should be enabled by default"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ipv6_detection_returns_valid_strategy() {
|
||||
let strategy = get_ip_strategy();
|
||||
match strategy {
|
||||
LookupIpStrategy::Ipv4Only | LookupIpStrategy::Ipv4AndIpv6 => {}
|
||||
_ => panic!("Unexpected IP strategy returned: {:?}", strategy),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ipv6_dns_detection_is_consistent() {
|
||||
let first_result = should_use_ipv6_dns();
|
||||
let second_result = should_use_ipv6_dns();
|
||||
assert_eq!(first_result, second_result);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod failure_test {
|
||||
use super::*;
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
|
||||
/// IP addresses guaranteed to fail attempts to resolve
|
||||
///
|
||||
/// Addresses drawn from blocks set off by RFC5737 (ipv4) and RFC3849 (ipv6)
|
||||
const GUARANTEED_BROKEN_IPS_1: &[IpAddr] = &[
|
||||
IpAddr::V4(Ipv4Addr::new(192, 0, 2, 1)),
|
||||
IpAddr::V4(Ipv4Addr::new(198, 51, 100, 1)),
|
||||
IpAddr::V6(Ipv6Addr::new(0x2001, 0x0db8, 0, 0, 0, 0, 0, 0x1111)),
|
||||
IpAddr::V6(Ipv6Addr::new(0x2001, 0x0db8, 0, 0, 0, 0, 0, 0x1001)),
|
||||
];
|
||||
|
||||
// Create a resolver that behaves the same as the custom configured router, except for the fact
|
||||
// that it is guaranteed to fail.
|
||||
fn build_broken_resolver() -> Result<TokioResolver, ResolveError> {
|
||||
info!("building new faulty resolver");
|
||||
|
||||
let mut broken_ns_group = NameServerConfigGroup::from_ips_tls(
|
||||
GUARANTEED_BROKEN_IPS_1,
|
||||
853,
|
||||
"cloudflare-dns.com".to_string(),
|
||||
true,
|
||||
);
|
||||
let broken_ns_https = NameServerConfigGroup::from_ips_https(
|
||||
GUARANTEED_BROKEN_IPS_1,
|
||||
443,
|
||||
"cloudflare-dns.com".to_string(),
|
||||
true,
|
||||
);
|
||||
broken_ns_group.merge(broken_ns_https);
|
||||
|
||||
configure_and_build_resolver(broken_ns_group)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn dns_lookup_failures() -> Result<(), ResolveError> {
|
||||
let time_start = std::time::Instant::now();
|
||||
|
||||
let r = OnceCell::new();
|
||||
r.set(build_broken_resolver().expect("failed to build resolver"))
|
||||
.expect("broken resolver init error");
|
||||
|
||||
// create a new resolver that won't mess with the shared resolver used by other tests
|
||||
let resolver = HickoryDnsResolver {
|
||||
dont_use_shared: true,
|
||||
state: Arc::new(r),
|
||||
overall_dns_timeout: Duration::from_secs(5),
|
||||
..Default::default()
|
||||
};
|
||||
build_broken_resolver()?;
|
||||
let domain = "ifconfig.me";
|
||||
let result = resolver.resolve_str(domain).await;
|
||||
assert!(result.is_err_and(|e| matches!(e, ResolveError::Timeout)));
|
||||
|
||||
let duration = time_start.elapsed();
|
||||
assert!(duration < resolver.overall_dns_timeout + Duration::from_secs(1));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn fallback_to_static() -> Result<(), ResolveError> {
|
||||
let r = OnceCell::new();
|
||||
r.set(build_broken_resolver().expect("failed to build resolver"))
|
||||
.expect("broken resolver init error");
|
||||
|
||||
// create a new resolver that won't mess with the shared resolver used by other tests
|
||||
let resolver = HickoryDnsResolver {
|
||||
dont_use_shared: true,
|
||||
state: Arc::new(r),
|
||||
static_base: Some(Default::default()),
|
||||
overall_dns_timeout: Duration::from_secs(5),
|
||||
..Default::default()
|
||||
};
|
||||
build_broken_resolver()?;
|
||||
|
||||
// successful lookup using fallback to static resolver
|
||||
let domain = "nymvpn.com";
|
||||
let _ = resolver
|
||||
.resolve_str(domain)
|
||||
.await
|
||||
.expect("failed to resolve address in static lookup");
|
||||
|
||||
// unsuccessful lookup - primary times out, and not in
|
||||
let domain = "non-existent.nymtech.net";
|
||||
let result = resolver.resolve_str(domain).await;
|
||||
assert!(result.is_err_and(|e| matches!(e, ResolveError::Timeout)));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::net::{IpAddr, Ipv4Addr};
|
||||
|
||||
pub const NYM_API_DOMAIN: &str = "validator.nymtech.net";
|
||||
pub const NYM_API_IPS: &[IpAddr] = &[IpAddr::V4(Ipv4Addr::new(212, 71, 233, 232))];
|
||||
|
||||
pub const NYM_VPN_API_DOMAIN: &str = "nymvpn.com";
|
||||
pub const NYM_VPN_API_IPS: &[IpAddr] = &[IpAddr::V4(Ipv4Addr::new(76, 76, 21, 21))];
|
||||
|
||||
pub const NYM_FRONTDOOR_VERCEL_DOMAIN: &str = "nym-frontdoor.vercel.app";
|
||||
pub const NYM_FRONTDOOR_VERCEL_IPS: &[IpAddr] = &[
|
||||
IpAddr::V4(Ipv4Addr::new(64, 29, 17, 195)),
|
||||
IpAddr::V4(Ipv4Addr::new(216, 198, 79, 195)),
|
||||
];
|
||||
|
||||
pub const NYM_FRONTDOOR_FASTLY_DOMAIN: &str = "nym-frontdoor.global.ssl.fastly.net";
|
||||
pub const NYM_FRONTDOOR_FASTLY_IPS: &[IpAddr] = &[
|
||||
IpAddr::V4(Ipv4Addr::new(151, 101, 193, 194)),
|
||||
IpAddr::V4(Ipv4Addr::new(151, 101, 129, 194)),
|
||||
IpAddr::V4(Ipv4Addr::new(151, 101, 1, 194)),
|
||||
IpAddr::V4(Ipv4Addr::new(151, 101, 65, 194)),
|
||||
];
|
||||
|
||||
pub const NYMVPN_FRONTDOOR_FASTLY_DOMAIN: &str = "nymvpn-frontdoor.global.ssl.fastly.net";
|
||||
pub const NYMVPN_FRONTDOOR_FASTLY_IPS: &[IpAddr] = &[
|
||||
IpAddr::V4(Ipv4Addr::new(151, 101, 193, 194)),
|
||||
IpAddr::V4(Ipv4Addr::new(151, 101, 129, 194)),
|
||||
IpAddr::V4(Ipv4Addr::new(151, 101, 1, 194)),
|
||||
IpAddr::V4(Ipv4Addr::new(151, 101, 65, 194)),
|
||||
];
|
||||
|
||||
pub const VERCEL_APP_DOMAIN: &str = "vercel.app";
|
||||
pub const VERCEL_APP_IPS: &[IpAddr] = &[
|
||||
IpAddr::V4(Ipv4Addr::new(64, 29, 17, 195)),
|
||||
IpAddr::V4(Ipv4Addr::new(216, 198, 79, 195)),
|
||||
];
|
||||
|
||||
pub const VERCEL_COM_DOMAIN: &str = "vercel.com";
|
||||
pub const VERCEL_COM_IPS: &[IpAddr] = &[
|
||||
IpAddr::V4(Ipv4Addr::new(198, 169, 2, 129)),
|
||||
IpAddr::V4(Ipv4Addr::new(198, 169, 1, 193)),
|
||||
];
|
||||
|
||||
pub const NYM_COM_DOMAIN: &str = "nym.com";
|
||||
pub const NYM_COM_IPS: &[IpAddr] = &[IpAddr::V4(Ipv4Addr::new(76, 76, 21, 22))];
|
||||
|
||||
pub const NYM_STATS_API_DOMAIN: &str = "nym-statistics-api.nymtech.cc";
|
||||
pub const NYM_STATS_API_IPS: &[IpAddr] = &[IpAddr::V4(Ipv4Addr::new(91, 92, 153, 96))];
|
||||
|
||||
pub fn default_static_addrs() -> HashMap<String, Vec<IpAddr>> {
|
||||
let mut m = HashMap::new();
|
||||
m.insert(NYM_API_DOMAIN.to_string(), NYM_API_IPS.to_vec());
|
||||
m.insert(NYM_VPN_API_DOMAIN.to_string(), NYM_VPN_API_IPS.to_vec());
|
||||
m.insert(
|
||||
NYM_FRONTDOOR_VERCEL_DOMAIN.to_string(),
|
||||
NYM_FRONTDOOR_VERCEL_IPS.to_vec(),
|
||||
);
|
||||
m.insert(
|
||||
NYM_FRONTDOOR_FASTLY_DOMAIN.to_string(),
|
||||
NYM_FRONTDOOR_FASTLY_IPS.to_vec(),
|
||||
);
|
||||
m.insert(
|
||||
NYMVPN_FRONTDOOR_FASTLY_DOMAIN.to_string(),
|
||||
NYMVPN_FRONTDOOR_FASTLY_IPS.to_vec(),
|
||||
);
|
||||
m.insert(VERCEL_APP_DOMAIN.to_string(), VERCEL_APP_IPS.to_vec());
|
||||
m.insert(VERCEL_COM_DOMAIN.to_string(), VERCEL_COM_IPS.to_vec());
|
||||
m.insert(NYM_COM_DOMAIN.to_string(), NYM_COM_IPS.to_vec());
|
||||
m.insert(NYM_STATS_API_DOMAIN.to_string(), NYM_STATS_API_IPS.to_vec());
|
||||
m
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
use crate::dns::ResolveError;
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
net::{IpAddr, SocketAddr},
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use reqwest::dns::{Addrs, Name, Resolve, Resolving};
|
||||
use tracing::*;
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct StaticResolver {
|
||||
static_addr_map: Arc<Mutex<HashMap<String, Vec<IpAddr>>>>,
|
||||
}
|
||||
|
||||
impl StaticResolver {
|
||||
pub fn new(static_entries: HashMap<String, Vec<IpAddr>>) -> StaticResolver {
|
||||
debug!("building static resolver");
|
||||
Self {
|
||||
static_addr_map: Arc::new(Mutex::new(static_entries)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_addrs(&self) -> HashMap<String, Vec<IpAddr>> {
|
||||
self.static_addr_map.lock().unwrap().clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Resolve for StaticResolver {
|
||||
fn resolve(&self, name: Name) -> Resolving {
|
||||
debug!("looking up {name:?} in static resolver");
|
||||
let addr_map = self.static_addr_map.clone();
|
||||
Box::pin(async move {
|
||||
let addr_map = addr_map.lock().unwrap();
|
||||
let lookup = match addr_map.get(name.as_str()) {
|
||||
None => return Err(ResolveError::StaticLookupMiss.into()),
|
||||
Some(addrs) => addrs,
|
||||
};
|
||||
let addrs: Addrs = Box::new(
|
||||
lookup
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|ip_addr| SocketAddr::new(ip_addr, 0)),
|
||||
);
|
||||
|
||||
Ok(addrs)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use itertools::Itertools;
|
||||
|
||||
use super::*;
|
||||
use std::error::Error as StdError;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[tokio::test]
|
||||
async fn lookup_using_static_resolver() -> Result<(), Box<dyn StdError + Send + Sync>> {
|
||||
let example_domain = String::from("static.nymvpn.com");
|
||||
|
||||
// lookup for domain for which there is no entry
|
||||
let resolver = StaticResolver::new(HashMap::new());
|
||||
|
||||
let url = reqwest::dns::Name::from_str(&example_domain).unwrap();
|
||||
let result = resolver.resolve(url).await;
|
||||
assert!(result.is_err());
|
||||
match result {
|
||||
Ok(_) => panic!("lookup with empty map should fail"),
|
||||
Err(e) => assert_eq!(e.to_string(), ResolveError::StaticLookupMiss.to_string()),
|
||||
}
|
||||
|
||||
// Successful lookup
|
||||
let mut addr_map = HashMap::new();
|
||||
let example_ip4: IpAddr = "10.10.10.10".parse().unwrap();
|
||||
let example_ip6: IpAddr = "dead::beef".parse().unwrap();
|
||||
addr_map.insert(example_domain.clone(), vec![example_ip4, example_ip6]);
|
||||
|
||||
let url = reqwest::dns::Name::from_str(&example_domain).unwrap();
|
||||
let resolver = StaticResolver::new(addr_map);
|
||||
let mut addrs = resolver.resolve(url).await?;
|
||||
assert!(addrs.contains(&SocketAddr::new(example_ip4, 0)));
|
||||
assert!(addrs.contains(&SocketAddr::new(example_ip6, 0)));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -179,7 +179,7 @@ mod dns;
|
||||
mod path;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub use dns::{HickoryDnsError, HickoryDnsResolver};
|
||||
pub use dns::{HickoryDnsResolver, ResolveError};
|
||||
|
||||
// helper for generating user agent based on binary information
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
||||
@@ -24,6 +24,6 @@ pub use crate::runtime_registry::RegistryAccessError;
|
||||
|
||||
/// Get or create a ShutdownTracker for SDK use.
|
||||
/// This provides automatic task management without requiring manual setup.
|
||||
pub fn get_sdk_shutdown_tracker() -> Result<ShutdownTracker, RegistryAccessError> {
|
||||
Ok(runtime_registry::RuntimeRegistry::get_or_create_sdk()?.shutdown_tracker_owned())
|
||||
pub fn create_sdk_shutdown_tracker() -> Result<ShutdownTracker, RegistryAccessError> {
|
||||
Ok(runtime_registry::RuntimeRegistry::create_sdk()?.shutdown_tracker_owned())
|
||||
}
|
||||
|
||||
@@ -19,30 +19,45 @@ pub(crate) struct RuntimeRegistry {
|
||||
pub enum RegistryAccessError {
|
||||
#[error("the runtime registry is poisoned")]
|
||||
Poisoned,
|
||||
|
||||
#[error("The SDK ShutdownManager already exists")]
|
||||
ExistingShutdownManager,
|
||||
|
||||
#[error("No existing SDK ShutdownManager")]
|
||||
MissingShutdownManager,
|
||||
}
|
||||
|
||||
impl RuntimeRegistry {
|
||||
/// Get or create a ShutdownManager for SDK use.
|
||||
/// Create a ShutdownManager for SDK use.
|
||||
/// This manager doesn't listen to OS signals, making it suitable for library use.
|
||||
pub(crate) fn get_or_create_sdk() -> Result<Arc<ShutdownManager>, RegistryAccessError> {
|
||||
/// This function overwrite any existing manager!
|
||||
pub(crate) fn create_sdk() -> Result<Arc<ShutdownManager>, RegistryAccessError> {
|
||||
let mut guard = REGISTRY
|
||||
.sdk_manager
|
||||
.write()
|
||||
.map_err(|_| RegistryAccessError::Poisoned)?;
|
||||
|
||||
Ok(guard
|
||||
.insert(Arc::new(
|
||||
ShutdownManager::new_without_signals().with_cancel_on_panic(),
|
||||
))
|
||||
.clone())
|
||||
}
|
||||
|
||||
/// Get the ShutdownManager for SDK use.
|
||||
/// This manager doesn't listen to OS signals, making it suitable for library use.
|
||||
/// Not yet used, but maybe in the future
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn get_sdk() -> Result<Arc<ShutdownManager>, RegistryAccessError> {
|
||||
let guard = REGISTRY
|
||||
.sdk_manager
|
||||
.read()
|
||||
.map_err(|_| RegistryAccessError::Poisoned)?;
|
||||
if let Some(manager) = guard.as_ref() {
|
||||
return Ok(manager.clone());
|
||||
Ok(manager.clone())
|
||||
} else {
|
||||
Err(RegistryAccessError::MissingShutdownManager)
|
||||
}
|
||||
drop(guard);
|
||||
|
||||
let mut guard = REGISTRY
|
||||
.sdk_manager
|
||||
.write()
|
||||
.map_err(|_| RegistryAccessError::Poisoned)?;
|
||||
Ok(guard
|
||||
.get_or_insert_with(|| {
|
||||
Arc::new(ShutdownManager::new_without_signals().with_cancel_on_panic())
|
||||
})
|
||||
.clone())
|
||||
}
|
||||
|
||||
/// Check if an SDK manager has been created.
|
||||
@@ -85,10 +100,13 @@ mod tests {
|
||||
|
||||
assert!(!RuntimeRegistry::has_sdk_manager().unwrap());
|
||||
|
||||
let manager1 = RuntimeRegistry::get_or_create_sdk().unwrap();
|
||||
// Error if nothing was created
|
||||
assert!(RuntimeRegistry::get_sdk().is_err());
|
||||
|
||||
let manager1 = RuntimeRegistry::create_sdk().unwrap();
|
||||
assert!(RuntimeRegistry::has_sdk_manager().unwrap());
|
||||
|
||||
let manager2 = RuntimeRegistry::get_or_create_sdk().unwrap();
|
||||
let manager2 = RuntimeRegistry::get_sdk().unwrap();
|
||||
// Should return the same instance
|
||||
assert!(Arc::ptr_eq(&manager1, &manager2));
|
||||
|
||||
|
||||
+2
-1
@@ -15,6 +15,7 @@ Operators can use [Nym Bridge Configuration Tool](https://github.com/nymtech/nym
|
||||
<Steps>
|
||||
###### 1. Download [`quic_bridge_deployment.sh`](https://github.com/nymtech/nym/blob/develop/scripts/nym-node-setup/quic_bridge_deployment.sh) script
|
||||
- SSH to your server
|
||||
- **Run as root**
|
||||
- Download the script and make executable
|
||||
```sh
|
||||
wget https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/quic_bridge_deployment.sh && \
|
||||
@@ -26,7 +27,7 @@ chmod +x quic_bridge_deployment.sh
|
||||
- Optional: open `tmux` in case you will need to run another commands on the VPS
|
||||
- Run the script with a command `full_bridge_setup`
|
||||
```sh
|
||||
./nym-node-setup/quic_bridge_deployment.sh full_bridge_setup
|
||||
./quic_bridge_deployment.sh full_bridge_setup
|
||||
```
|
||||
|
||||
###### 3. Follow the interactive prompts
|
||||
|
||||
@@ -1 +1 @@
|
||||
Tuesday, October 14th 2025, 11:34:14 UTC
|
||||
Thursday, October 30th 2025, 13:00:59 UTC
|
||||
|
||||
@@ -11,7 +11,7 @@ options:
|
||||
--no_routing_history Display node stats without routing history
|
||||
--no_verloc_metrics Display node stats without verloc metrics
|
||||
-m, --markdown Display results in markdown format
|
||||
-o, --output [OUTPUT]
|
||||
-o [OUTPUT], --output [OUTPUT]
|
||||
Save results to file (in current dir or supply with
|
||||
path without filename)
|
||||
```
|
||||
|
||||
@@ -18,23 +18,23 @@
|
||||
| [Hostslick](https://hostslick.com) | Netherlands, Germany | Yes, on by default | Yes | Good amount of bandwidth for the price. Make sure you open the ticket if you want to run Exit node | 07/2024 |
|
||||
| [Incognet](https://incognet.io) | Netherlands and USA | Yes, on by default | Yes | They allow Tor exit nodes but you must adhere to their rules https://incognet.io/tor-exits | 07/2024 |
|
||||
| [Incognet](https://incognet.io/kansas-city-dedicated-servers) | USA, Netherlands | Yes | nan | nan | 07/2025 |
|
||||
| [Ionos](https://www.ionos.com/servers/amd-servers) | US, DE, UK, ESP, FR | nan | No | nan | 07/2025 |
|
||||
| [Ionos](https://www.ionos.com/servers/amd-servers) | USA, DE, UK, ESP, FR | nan | No | nan | 07/2025 |
|
||||
| [IsHosting](https://ishosting.com/en) | Brazil, Netherlands | Yes, based on ticket | Yes | Expensive | 05/2024 |
|
||||
| [Leaseweb](https://www.leaseweb.com/en/configure/vc/product/entityKey/DEDSER02_NEW_ORDER_BUSINESS_R740XD-24SFF-6134) | US, NL, DE, UK, CA, SG, JP, AUS, HK | nan | No | KYC mandatory | 07/2025 |
|
||||
| [Leaseweb](https://www.leaseweb.com/en/configure/vc/product/entityKey/DEDSER02_NEW_ORDER_BUSINESS_R740XD-24SFF-6134) | USA, NL, DE, UK, CA, SG, JP, AUS, HK | nan | No | KYC mandatory | 07/2025 |
|
||||
| [Linode](https://linode.com) | USA, Canada, Japan, India, Indonesia, Sweden, Netherlands, Germany, Brazil, France, UK, Australia, Italy | Yes out of the box | No, only through [BitLAunch](https://bitlaunch.io) | IPv6 sometimes need to be re-added in Networking tab, no reboot needed | 05/2024 |
|
||||
| [LiteServer](https://liteserver.nl) | Netherlands | Yes, on by default | Yes | Very reliable Dutch provider. They do allow Relay nodes but for Exit nodes you need to contact them. Always check T&C https://liteserver.nl/legal | 07/2024 |
|
||||
| [Lowendbox](https://lowendbox.com/category/dedicated-servers) | | | | Just an aggregator with good offers | 07/2025 |
|
||||
| [M247](https://m247.com/eu/services/host/dedicated-servers/) | UK, Austria, Br, Sw, Jp, Poland, Fr, USA, Netherlands | Yes | No | nan | 07/2025 |
|
||||
| [Mebilcom](https://www.melbicom.net/dedicatedserver/) | NL, US, DE, UAE, NG, ESP, IN, IT, FR, LT, SG, BG, LV, PL | nan | No | nan | 07/2025 |
|
||||
| [Mebilcom](https://www.melbicom.net/dedicatedserver/) | NL, USA, DE, UAE, NG, ESP, IN, IT, FR, LT, SG, BG, LV, PL | nan | No | nan | 07/2025 |
|
||||
| [Mevspace](https://mevspace.com) | Poland | Yes, on by default | Yes | Flexible Polish providers with 3 DCs in Poland. They do allow Tor Exit nodes but you may need a dedicated server for this. Make sure you open a ticket to check. As of today's date, they have 48h for 1 EUR tariff | 07/2024 |
|
||||
| [Misaka](https://www.misaka.io/) | South Africa | Yes, native support | No | Very Expensive | 05/2024 |
|
||||
| [NiceVPS](https://nicevps.net/) | Netherlands | Yes | nan | nan | 07/2025 |
|
||||
| [Njalla](https://nja.la) | Sweden | Yes | Yes | Privacy vandguards! The biggest VPS 45 is 3 cores only, but it works better than many “larger” servers on the market. | 05/2024 |
|
||||
| [OVH](https://us.ovhcloud.com/bare-metal/rise/rise-3/) | USA, DE, FR, UK, PL, CA | | No | Not all locations always available | 07/2025 |
|
||||
| [Oneprovider](https://oneprovider.com/en/dedicated-servers/ipv6) | PL, FR, NL, UA, US, BG, RO, DK, ESP, NO, CZ, RS, IE, IT, UK, HU, CH, SK, AT, BE, BA, HK, JP, SG, LU, AU, SWE, UAE, BR, CR, MX, GR, CL, MA, AR | Yes | No | nan | 07/2025 |
|
||||
| [Oneprovider](https://oneprovider.com/en/dedicated-servers/ipv6) | PL, FR, NL, UA, USA, BG, RO, DK, ESP, NO, CZ, RS, IE, IT, UK, HU, CH, SK, AT, BE, BA, HK, JP, SG, LU, AU, SWE, UAE, BR, CR, MX, GR, CL, MA, AR | Yes | No | nan | 07/2025 |
|
||||
| [PrivateLayer](https://privatelayer.com) | Swiss | Yes | Yes | Slow customer response | 07/2025 |
|
||||
| [Privex](https://www.privex.io/tor-exit-policy/) | USA, Germany, Sweden | Yes | Yes | nan | 07/2025 |
|
||||
| [Psychz](https://www.psychz.net) | US, UK, Brazil, Japan, Russia, South Africa and many more | Yes | nan | nan | 07/2025 |
|
||||
| [Psychz](https://www.psychz.net) | USA, UK, Brazil, Japan, Russia, South Africa and many more | Yes | nan | nan | 07/2025 |
|
||||
| [RDP](https://rdp.sh) | Netherlands, USA, Poland | Yes, on by default | Yes | German provider. Exit nodes are allowed, policy is here https://rdp.sh/docs/faq/tor ports 25,465,587 must be closed. Make sure you open a ticket before running an exit node. | 07/2024 |
|
||||
| [Servermania](https://www.servermania.com/dedicated-servers-hosting.htm) | USA, Canada | nan | No | nan | 07/2025 |
|
||||
| [Svea](https://svea.net/vps) | Sweden | Yes | nan | nan | 07/2025 |
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
[Lowendbox](https://lowendbox.com/category/dedicated-servers), , , ,Just an aggregator with good offers,07/2025
|
||||
[Thundervm](https://thundervm.com/en/hosting/dedicated-server),"USA, UK, France, Italy, Switzerland, Netherlands",,Yes, ,07/2025
|
||||
[OVH](https://us.ovhcloud.com/bare-metal/rise/rise-3/),"USA, DE, FR, UK, PL, CA", ,No,Not all locations always available,07/2025
|
||||
[Mebilcom](https://www.melbicom.net/dedicatedserver/),"NL, US, DE, UAE, NG, ESP, IN, IT, FR, LT, SG, BG, LV, PL",,No,,07/2025
|
||||
[Mebilcom](https://www.melbicom.net/dedicatedserver/),"NL, USA, DE, UAE, NG, ESP, IN, IT, FR, LT, SG, BG, LV, PL",,No,,07/2025
|
||||
[Servermania](https://www.servermania.com/dedicated-servers-hosting.htm),"USA, Canada",,No,,07/2025
|
||||
[Oneprovider](https://oneprovider.com/en/dedicated-servers/ipv6),"PL, FR, NL, UA, US, BG, RO, DK, ESP, NO, CZ, RS, IE, IT, UK, HU, CH, SK, AT, BE, BA, HK, JP, SG, LU, AU, SWE, UAE, BR, CR, MX, GR, CL, MA, AR",Yes,No,,07/2025
|
||||
[Ionos](https://www.ionos.com/servers/amd-servers),"US, DE, UK, ESP, FR",,No,,07/2025
|
||||
[Leaseweb](https://www.leaseweb.com/en/configure/vc/product/entityKey/DEDSER02_NEW_ORDER_BUSINESS_R740XD-24SFF-6134),"US, NL, DE, UK, CA, SG, JP, AUS, HK",,No,KYC mandatory,07/2025
|
||||
[Oneprovider](https://oneprovider.com/en/dedicated-servers/ipv6),"PL, FR, NL, UA, USA, BG, RO, DK, ESP, NO, CZ, RS, IE, IT, UK, HU, CH, SK, AT, BE, BA, HK, JP, SG, LU, AU, SWE, UAE, BR, CR, MX, GR, CL, MA, AR",Yes,No,,07/2025
|
||||
[Ionos](https://www.ionos.com/servers/amd-servers),"USA, DE, UK, ESP, FR",,No,,07/2025
|
||||
[Leaseweb](https://www.leaseweb.com/en/configure/vc/product/entityKey/DEDSER02_NEW_ORDER_BUSINESS_R740XD-24SFF-6134),"USA, NL, DE, UK, CA, SG, JP, AUS, HK",,No,KYC mandatory,07/2025
|
||||
[M247](https://m247.com/eu/services/host/dedicated-servers/),"UK, Austria, Br, Sw, Jp, Poland, Fr, USA, Netherlands",Yes,No,,07/2025
|
||||
[Hostroyale](https://hostroyale.com/hosting/dedicated-server/),Various countries with different pricing,, Yes,,07/2025
|
||||
[DataPacket](https://www.datapacket.com/pricing),"NL, GR, SK, BE, RO, HU, DK, IE, DE, UA, PT, GB, ES, FR, IT, NO, CZ, BG, SE, AT, PL, HR, CH, USA, CO, AR, PE, MX, CL, TR, ZA, NG, IL, HK, AU, SG, JP",Yes,,,07/2025
|
||||
@@ -35,7 +35,7 @@
|
||||
[Colocall](https://www.colocall.net/),Ukraine,Yes,,,07/2025
|
||||
[Incognet](https://incognet.io/kansas-city-dedicated-servers),"USA, Netherlands",Yes,,,07/2025
|
||||
[FranTech](https://my.frantech.ca),USA,Yes,,,07/2025
|
||||
[Psychz](https://www.psychz.net),"US, UK, Brazil, Japan, Russia, South Africa and many more",Yes,,,07/2025
|
||||
[Psychz](https://www.psychz.net),"USA, UK, Brazil, Japan, Russia, South Africa and many more",Yes,,,07/2025
|
||||
[Fsit](https://www.fsit.com/server/vps-vserver-kvm),Swiss,Yes,Yes,,07/2025
|
||||
[NiceVPS](https://nicevps.net/),Netherlands,Yes,,,07/2025
|
||||
[Dataclub](https://www.dataclub.eu/),"Latvia, Sweden, Netherlands",Yes,,,07/2027
|
||||
|
||||
|
@@ -49,6 +49,90 @@ This page displays a full list of all the changes during our release cycle from
|
||||
|
||||
<VarInfo />
|
||||
|
||||
## `v2025.19-kase`
|
||||
|
||||
- [Release Binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2025.19-kase)
|
||||
- [`nym-node`](nodes/nym-node.mdx) version `1.20.0`
|
||||
|
||||
```sh
|
||||
nym-node
|
||||
Binary Name: nym-node
|
||||
Build Timestamp: 2025-10-30T12:43:37.933354749Z
|
||||
Build Version: 1.20.0
|
||||
Commit SHA: 75a6d3426bd18dca600ad1cfa39b0a3c4f319c69
|
||||
Commit Date: 2025-10-30T11:59:32.000000000+01:00
|
||||
Commit Branch: HEAD
|
||||
rustc Version: 1.88.0
|
||||
rustc Channel: stable
|
||||
cargo Profile: release
|
||||
```
|
||||
|
||||
### Operators Updates & Tools
|
||||
|
||||
<Callout type="info" emoji="ℹ️">
|
||||
**When this platform release becomes latest, we would like to ask operators ruuning any Gateway mode of `nym-node`, to use new version of [QUIC brige deployment tool](https://github.com/nymtech/nym/blob/develop/scripts/nym-node-setup/quic_bridge_deployment.sh)and install QUIC `nym-bridge` on their server, following [these steps](#quic-transport-bridge-deployment).**
|
||||
</Callout>
|
||||
|
||||
Alongside this platform release we are happy to introduce several improvements and new tools for node operators.
|
||||
|
||||
- [Updated version of QUIC brige deployment tool](https://github.com/nymtech/nym/blob/develop/scripts/nym-node-setup/quic_bridge_deployment.sh), **if you run a `nym-node` in any Gateway mode, please install QUIC on your server, following [these steps](#quic-transport-bridge-deployment)**
|
||||
|
||||
- [New **Nym Node Status Dashboard**](https://node-status.nym.com)
|
||||
|
||||
- [New **Harbourmaster** aka ***Nym Node Status Observatory***](https://harbourmaster.nymtech.net)
|
||||
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
- [Propagate cancel token to mixnet client](https://github.com/nymtech/nym/pull/6105): Ensures cancellation token propagation to mixnet client
|
||||
|
||||
- [[DOCs/operators] QUIC deployment script & docs](https://github.com/nymtech/nym/pull/6098): Script and documentation for QUIC deployment, referencing `nym-bridges` repository
|
||||
|
||||
- [Move gateway probe to monorepo (Rust edition 2024)](https://github.com/nymtech/nym/pull/6094): Moves `nym-gateway-probe` and related packages into monorepo, updates to Rust 2024 edition
|
||||
|
||||
- [Expose reference to Mnemonic from `DirectSecp256k1HdWallet`](https://github.com/nymtech/nym/pull/6083): Adds safer accessors for mnemonic references and deprecates unsafe cloning
|
||||
|
||||
### Bugfix
|
||||
|
||||
- [Cherry pick - request #6143 from nymtech/bugfix/mix-tx-closed-v2](https://github.com/nymtech/nym/pull/6153): Add circuit breaker
|
||||
<AccordionTemplate name={<TestingSteps/>}>
|
||||
**Summary:**
|
||||
- Network-requester started successfully
|
||||
- SOCKS5 client started successfully
|
||||
- Traffic was proxied through the mixnet
|
||||
- Shutdown was clean
|
||||
- No 'channel closed (outside of shutdown!)' errors
|
||||
</AccordionTemplate>
|
||||
|
||||
- [`nym-credential-proxy` query params parsing regression](https://github.com/nymtech/nym/pull/6121): Fix query deserialization issue with `serde_urlencoded` breaking compatibility with VPN API
|
||||
|
||||
- [Revert some dep updates introduced in #6043](https://github.com/nymtech/nym/pull/6120): Revert dependency updates that broke ANSI escape characters within tracing output
|
||||
|
||||
- [Skip IPv6 metadata endpoint request](https://github.com/nymtech/nym/pull/6118): Skip querying IPv4-only metadata endpoints during IPv6 probing tests
|
||||
|
||||
- [Revert "Propagate cancel token to mixnet client"](https://github.com/nymtech/nym/pull/6115): Reverts earlier change due to premature mixnet exit issues
|
||||
|
||||
- [Retrieve and update ticketbook in the same query](https://github.com/nymtech/nym/pull/6101): Fix concurrency issue with multiple agents retrieving ticketbooks simultaneously
|
||||
|
||||
- [Include network name in default gateway probe config path](https://github.com/nymtech/nym/pull/6100): Prevents reuse of credentials across different networks
|
||||
|
||||
- [Incompatibility fixes](https://github.com/nymtech/nym/pull/6099): Fixes several incompatibilities, including initialization and build mismatches
|
||||
|
||||
- [Testnet manager `02sql` migration](https://github.com/nymtech/nym/pull/6096): Fix invalid FK constraint blocking SQL migration
|
||||
|
||||
- [Use custom topology provider for list of init gateways](https://github.com/nymtech/nym/pull/6092): Fixes SDK bug where clients ignored custom topology provider on registration
|
||||
|
||||
- [Fix `WASM` client + build commands](https://github.com/nymtech/nym/pull/6043): Fixes WASM client hang and runtime time-related issues; improves internal dev testing stability
|
||||
|
||||
### Refactors & Maintenance
|
||||
|
||||
- [Update to no longer use 1mb files](https://github.com/nymtech/nym/pull/6117)
|
||||
|
||||
- [Restore pending DKG contract state migration](https://github.com/nymtech/nym/pull/6116)
|
||||
|
||||
- [Update `dirs` to `6.0`](https://github.com/nymtech/nym/pull/6109): Minor dependency update, safe for compatibility
|
||||
|
||||
## `v2025.18-jarlsberg`
|
||||
|
||||
- [Release Binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2025.18-jarlsberg)
|
||||
|
||||
@@ -21,13 +21,13 @@ This documentation page provides a guide on how to set up and run a [NYM NODE](.
|
||||
```sh
|
||||
nym-node
|
||||
Binary Name: nym-node
|
||||
Build Timestamp: 2025-10-15T09:04:32.043934599Z
|
||||
Build Version: 1.19.0
|
||||
Commit SHA: 2235a6e1477bea7368ee5443a298f544deb63504
|
||||
Commit Date: 2025-10-15T10:22:16.000000000+02:00
|
||||
Commit Branch: master
|
||||
rustc Version: 1.92.0-nightly
|
||||
rustc Channel: nightly
|
||||
Build Timestamp: 2025-10-30T12:43:37.933354749Z
|
||||
Build Version: 1.20.0
|
||||
Commit SHA: 75a6d3426bd18dca600ad1cfa39b0a3c4f319c69
|
||||
Commit Date: 2025-10-30T11:59:32.000000000+01:00
|
||||
Commit Branch: HEAD
|
||||
rustc Version: 1.88.0
|
||||
rustc Channel: stable
|
||||
cargo Profile: release
|
||||
```
|
||||
|
||||
|
||||
+16
-16
@@ -2,23 +2,23 @@
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
reactStrictMode: true,
|
||||
reactStrictMode: true,
|
||||
|
||||
basePath: "/explorer",
|
||||
assetPrefix: "/explorer",
|
||||
trailingSlash: false,
|
||||
basePath: "/explorer",
|
||||
assetPrefix: "/explorer",
|
||||
trailingSlash: false,
|
||||
|
||||
async redirects() {
|
||||
return [
|
||||
// Change the basePath to /explorer
|
||||
{
|
||||
source: "/",
|
||||
destination: "/explorer",
|
||||
basePath: false,
|
||||
permanent: true,
|
||||
},
|
||||
];
|
||||
},
|
||||
async redirects() {
|
||||
return [
|
||||
// Change the basePath to /explorer
|
||||
{
|
||||
source: "/",
|
||||
destination: "/explorer",
|
||||
basePath: false,
|
||||
permanent: true,
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = nextConfig;
|
||||
module.exports = nextConfig
|
||||
@@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
import type { IObservatoryNode } from "@/app/api/types";
|
||||
import { NYM_ACCOUNT_ADDRESS } from "@/app/api/urls";
|
||||
import { Search } from "@mui/icons-material";
|
||||
import {
|
||||
Autocomplete,
|
||||
@@ -14,6 +13,7 @@ import { useQuery } from "@tanstack/react-query";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { fetchObservatoryNodes } from "../../app/api";
|
||||
import { NYM_ACCOUNT_ADDRESS } from "@/app/api/urls";
|
||||
|
||||
const NodeAndAddressSearch = () => {
|
||||
const router = useRouter();
|
||||
@@ -50,7 +50,7 @@ const NodeAndAddressSearch = () => {
|
||||
}
|
||||
} catch {
|
||||
setErrorText(
|
||||
"No node found with the provided Name, Node ID or Identity Key. Please check your input and try again.",
|
||||
"No node found with the provided Name, Node ID or Identity Key. Please check your input and try again."
|
||||
);
|
||||
setIsLoading(false); // Stop loading
|
||||
|
||||
@@ -58,7 +58,7 @@ const NodeAndAddressSearch = () => {
|
||||
}
|
||||
} else {
|
||||
setErrorText(
|
||||
"No node found with the provided Name, Node ID or Identity Key. Please check your input and try again.",
|
||||
"No node found with the provided Name, Node ID or Identity Key. Please check your input and try again."
|
||||
);
|
||||
setIsLoading(false); // Stop loading
|
||||
|
||||
@@ -68,7 +68,7 @@ const NodeAndAddressSearch = () => {
|
||||
// Check if it's a node identity key
|
||||
if (nymNodes) {
|
||||
const matchingNode = nymNodes.find(
|
||||
(node) => node.identity_key === inputValue,
|
||||
(node) => node.identity_key === inputValue
|
||||
);
|
||||
|
||||
if (matchingNode) {
|
||||
@@ -77,13 +77,13 @@ const NodeAndAddressSearch = () => {
|
||||
}
|
||||
}
|
||||
setErrorText(
|
||||
"No node found with the provided Name, Node ID or Identity Key. Please check your input and try again.",
|
||||
"No node found with the provided Name, Node ID or Identity Key. Please check your input and try again."
|
||||
);
|
||||
setIsLoading(false);
|
||||
}
|
||||
} catch (error) {
|
||||
setErrorText(
|
||||
"No node found with the provided Name, Node ID or Identity Key. Please check your input and try again.",
|
||||
"No node found with the provided Name, Node ID or Identity Key. Please check your input and try again."
|
||||
);
|
||||
console.error(error);
|
||||
setIsLoading(false); // Stop loading
|
||||
@@ -92,7 +92,7 @@ const NodeAndAddressSearch = () => {
|
||||
|
||||
// Handle search input change
|
||||
const handleSearchInputChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>,
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
const value = event.target.value;
|
||||
setInputValue(value);
|
||||
@@ -107,7 +107,7 @@ const NodeAndAddressSearch = () => {
|
||||
const filteredNodes = nymNodes.filter((node) =>
|
||||
node.self_description?.moniker
|
||||
?.toLowerCase()
|
||||
.includes(value.toLowerCase()),
|
||||
.includes(value.toLowerCase())
|
||||
);
|
||||
setSearchOptions(filteredNodes);
|
||||
} else {
|
||||
@@ -118,7 +118,7 @@ const NodeAndAddressSearch = () => {
|
||||
// Handle node selection from dropdown
|
||||
const handleNodeSelect = (
|
||||
event: React.SyntheticEvent,
|
||||
value: string | IObservatoryNode | null,
|
||||
value: string | IObservatoryNode | null
|
||||
) => {
|
||||
if (value && typeof value !== "string") {
|
||||
setIsLoading(true); // Show loading spinner
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
[package]
|
||||
name = "nym-api"
|
||||
license = "GPL-3.0"
|
||||
version = "1.1.67"
|
||||
version = "1.1.69"
|
||||
authors.workspace = true
|
||||
edition = "2021"
|
||||
rust-version.workspace = true
|
||||
|
||||
@@ -2,7 +2,7 @@ use nym_credentials_interface::TicketType;
|
||||
use nym_sdk::mixnet::InputMessage;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum Error {
|
||||
pub enum AuthenticationClientError {
|
||||
#[error("mixnet client stopped returning responses")]
|
||||
NoMixnetMessagesReceived,
|
||||
|
||||
@@ -42,10 +42,19 @@ pub enum Error {
|
||||
|
||||
#[error("unknown authenticator version number")]
|
||||
UnsupportedAuthenticatorVersion,
|
||||
}
|
||||
|
||||
#[error("failed to wait on AuthenticatorClientListener")]
|
||||
FailedToJoinOnTask(#[from] tokio::task::JoinError),
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum RegistrationError {
|
||||
#[error(transparent)]
|
||||
NoCredentialSent(AuthenticationClientError), // This intentionnally doesn't use `from` to avoid random ? operator to land here when they shouldn't
|
||||
|
||||
#[error("an error occured after a credential was sent : {source}")]
|
||||
CredentialSent {
|
||||
#[source]
|
||||
source: AuthenticationClientError,
|
||||
},
|
||||
}
|
||||
|
||||
// Result type based on our error type
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
pub(crate) type Result<T> = std::result::Result<T, AuthenticationClientError>;
|
||||
|
||||
@@ -6,11 +6,11 @@ use nym_bandwidth_controller::{BandwidthTicketProvider, DEFAULT_TICKETS_TO_SPEND
|
||||
use nym_crypto::asymmetric::x25519::KeyPair;
|
||||
use nym_registration_common::GatewayData;
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tracing::{debug, error, trace};
|
||||
|
||||
use crate::error::Result;
|
||||
use crate::mixnet_listener::{MixnetMessageBroadcastReceiver, MixnetMessageInputSender};
|
||||
use nym_authenticator_requests::{
|
||||
AuthenticatorVersion, client_message::ClientMessage, response::AuthenticatorResponse,
|
||||
@@ -25,7 +25,7 @@ mod error;
|
||||
mod helpers;
|
||||
mod mixnet_listener;
|
||||
|
||||
pub use crate::error::{Error, Result};
|
||||
pub use crate::error::{AuthenticationClientError, RegistrationError};
|
||||
pub use crate::mixnet_listener::{AuthClientMixnetListener, AuthClientMixnetListenerHandle};
|
||||
|
||||
pub struct AuthenticatorClient {
|
||||
@@ -91,7 +91,7 @@ impl AuthenticatorClient {
|
||||
self.mixnet_sender
|
||||
.send(input_message)
|
||||
.await
|
||||
.map_err(|e| Error::SendMixnetMessage(Box::new(e)))?;
|
||||
.map_err(|e| AuthenticationClientError::SendMixnetMessage(Box::new(e)))?;
|
||||
|
||||
Ok(request_id)
|
||||
}
|
||||
@@ -104,11 +104,11 @@ impl AuthenticatorClient {
|
||||
tokio::select! {
|
||||
_ = &mut timeout => {
|
||||
error!("Timed out waiting for reply to connect request");
|
||||
return Err(Error::TimeoutWaitingForConnectResponse);
|
||||
return Err(AuthenticationClientError::TimeoutWaitingForConnectResponse);
|
||||
}
|
||||
msg = self.mixnet_listener.recv() => match msg {
|
||||
Err(_) => {
|
||||
return Err(Error::NoMixnetMessagesReceived);
|
||||
return Err(AuthenticationClientError::NoMixnetMessagesReceived);
|
||||
}
|
||||
Ok(msg) => {
|
||||
let Some(header) = msg.message.first_chunk::<2>() else {
|
||||
@@ -131,12 +131,12 @@ impl AuthenticatorClient {
|
||||
// Then we deserialize the message
|
||||
debug!("AuthClient: got message while waiting for connect response with version {version:?}");
|
||||
let ret: Result<AuthenticatorResponse> = match version {
|
||||
AuthenticatorVersion::V1 => Err(Error::UnsupportedVersion),
|
||||
AuthenticatorVersion::V1 => Err(AuthenticationClientError::UnsupportedVersion),
|
||||
AuthenticatorVersion::V2 => v2::response::AuthenticatorResponse::from_reconstructed_message(&msg).map(Into::into).map_err(Into::into),
|
||||
AuthenticatorVersion::V3 => v3::response::AuthenticatorResponse::from_reconstructed_message(&msg).map(Into::into).map_err(Into::into),
|
||||
AuthenticatorVersion::V4 => v4::response::AuthenticatorResponse::from_reconstructed_message(&msg).map(Into::into).map_err(Into::into),
|
||||
AuthenticatorVersion::V5 => v5::response::AuthenticatorResponse::from_reconstructed_message(&msg).map(Into::into).map_err(Into::into),
|
||||
AuthenticatorVersion::UNKNOWN => Err(Error::UnknownVersion),
|
||||
AuthenticatorVersion::UNKNOWN => Err(AuthenticationClientError::UnknownVersion),
|
||||
};
|
||||
let Ok(response) = ret else {
|
||||
// This is ok, it's likely just one of our self-pings
|
||||
@@ -158,10 +158,14 @@ impl AuthenticatorClient {
|
||||
&mut self,
|
||||
controller: &dyn BandwidthTicketProvider,
|
||||
ticketbook_type: TicketType,
|
||||
) -> Result<GatewayData> {
|
||||
) -> std::result::Result<GatewayData, RegistrationError> {
|
||||
debug!("Registering with the wg gateway...");
|
||||
let init_message = match self.auth_version {
|
||||
AuthenticatorVersion::V1 => return Err(Error::UnsupportedAuthenticatorVersion),
|
||||
AuthenticatorVersion::V1 | AuthenticatorVersion::UNKNOWN => {
|
||||
return Err(RegistrationError::NoCredentialSent(
|
||||
AuthenticationClientError::UnsupportedAuthenticatorVersion,
|
||||
));
|
||||
}
|
||||
AuthenticatorVersion::V2 => {
|
||||
ClientMessage::Initial(Box::new(v2::registration::InitMessage {
|
||||
pub_key: PeerPublicKey::new(self.keypair.public_key().to_bytes().into()),
|
||||
@@ -182,16 +186,20 @@ impl AuthenticatorClient {
|
||||
pub_key: PeerPublicKey::new(self.keypair.public_key().to_bytes().into()),
|
||||
}))
|
||||
}
|
||||
AuthenticatorVersion::UNKNOWN => return Err(Error::UnsupportedAuthenticatorVersion),
|
||||
};
|
||||
trace!("sending init msg to {}: {:?}", &self.ip_addr, &init_message);
|
||||
let response = self.send_and_wait_for_response(&init_message).await?;
|
||||
let response = self
|
||||
.send_and_wait_for_response(&init_message)
|
||||
.await
|
||||
.map_err(RegistrationError::NoCredentialSent)?;
|
||||
let registered_data = match response {
|
||||
AuthenticatorResponse::PendingRegistration(pending_registration_response) => {
|
||||
// Unwrap since we have already checked that we have the keypair.
|
||||
debug!("Verifying data");
|
||||
if let Err(e) = pending_registration_response.verify(self.keypair.private_key()) {
|
||||
return Err(Error::VerificationFailed(e));
|
||||
return Err(RegistrationError::NoCredentialSent(
|
||||
AuthenticationClientError::VerificationFailed(e),
|
||||
));
|
||||
}
|
||||
|
||||
trace!(
|
||||
@@ -199,6 +207,7 @@ impl AuthenticatorClient {
|
||||
&self.ip_addr, &pending_registration_response
|
||||
);
|
||||
|
||||
// This call takes care of updating the credential count in storage, so failure of this must be counted as credential waste
|
||||
let credential = Some(
|
||||
controller
|
||||
.get_ecash_ticket(
|
||||
@@ -207,15 +216,21 @@ impl AuthenticatorClient {
|
||||
DEFAULT_TICKETS_TO_SPEND,
|
||||
)
|
||||
.await
|
||||
.map_err(|source| Error::GetTicket {
|
||||
ticketbook_type,
|
||||
source,
|
||||
.map_err(|source| RegistrationError::CredentialSent {
|
||||
source: AuthenticationClientError::GetTicket {
|
||||
ticketbook_type,
|
||||
source,
|
||||
},
|
||||
})?
|
||||
.data,
|
||||
);
|
||||
|
||||
let finalized_message = match self.auth_version {
|
||||
AuthenticatorVersion::V1 => return Err(Error::UnsupportedAuthenticatorVersion),
|
||||
AuthenticatorVersion::V1 | AuthenticatorVersion::UNKNOWN => {
|
||||
return Err(RegistrationError::CredentialSent {
|
||||
source: AuthenticationClientError::UnsupportedAuthenticatorVersion,
|
||||
});
|
||||
}
|
||||
AuthenticatorVersion::V2 => {
|
||||
ClientMessage::Final(Box::new(v2::registration::FinalMessage {
|
||||
gateway_client: v2::registration::GatewayClient::new(
|
||||
@@ -260,23 +275,29 @@ impl AuthenticatorClient {
|
||||
credential,
|
||||
}))
|
||||
}
|
||||
AuthenticatorVersion::UNKNOWN => {
|
||||
return Err(Error::UnsupportedAuthenticatorVersion);
|
||||
}
|
||||
};
|
||||
trace!(
|
||||
"sending final msg to {}: {:?}",
|
||||
&self.ip_addr, &finalized_message
|
||||
);
|
||||
|
||||
let response = self.send_and_wait_for_response(&finalized_message).await?;
|
||||
let response = self
|
||||
.send_and_wait_for_response(&finalized_message)
|
||||
.await
|
||||
.map_err(|source| RegistrationError::CredentialSent { source })?;
|
||||
let AuthenticatorResponse::Registered(registered_response) = response else {
|
||||
return Err(Error::InvalidGatewayAuthResponse);
|
||||
return Err(RegistrationError::CredentialSent {
|
||||
source: AuthenticationClientError::InvalidGatewayAuthResponse,
|
||||
});
|
||||
};
|
||||
registered_response
|
||||
}
|
||||
AuthenticatorResponse::Registered(registered_response) => registered_response,
|
||||
_ => return Err(Error::InvalidGatewayAuthResponse),
|
||||
_ => {
|
||||
return Err(RegistrationError::NoCredentialSent(
|
||||
AuthenticationClientError::InvalidGatewayAuthResponse,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
trace!(
|
||||
@@ -286,12 +307,7 @@ impl AuthenticatorClient {
|
||||
|
||||
let gateway_data = GatewayData {
|
||||
public_key: registered_data.pub_key().inner().into(),
|
||||
endpoint: SocketAddr::from_str(&format!(
|
||||
"{}:{}",
|
||||
self.ip_addr,
|
||||
registered_data.wg_port()
|
||||
))
|
||||
.map_err(Error::FailedToParseEntryGatewaySocketAddr)?,
|
||||
endpoint: SocketAddr::new(self.ip_addr, registered_data.wg_port()),
|
||||
private_ipv4: registered_data.private_ips().ipv4,
|
||||
private_ipv6: registered_data.private_ips().ipv6,
|
||||
};
|
||||
@@ -299,9 +315,12 @@ impl AuthenticatorClient {
|
||||
Ok(gateway_data)
|
||||
}
|
||||
|
||||
// This is up to the caller to know nothing is ever spent there
|
||||
pub async fn query_bandwidth(&mut self) -> Result<Option<i64>> {
|
||||
let query_message = match self.auth_version {
|
||||
AuthenticatorVersion::V1 => return Err(Error::UnsupportedAuthenticatorVersion),
|
||||
AuthenticatorVersion::V1 => {
|
||||
return Err(AuthenticationClientError::UnsupportedAuthenticatorVersion);
|
||||
}
|
||||
AuthenticatorVersion::V2 => ClientMessage::Query(Box::new(QueryMessageImpl {
|
||||
pub_key: PeerPublicKey::new(self.keypair.public_key().to_bytes().into()),
|
||||
version: AuthenticatorVersion::V2,
|
||||
@@ -318,7 +337,9 @@ impl AuthenticatorClient {
|
||||
pub_key: PeerPublicKey::new(self.keypair.public_key().to_bytes().into()),
|
||||
version: AuthenticatorVersion::V5,
|
||||
})),
|
||||
AuthenticatorVersion::UNKNOWN => return Err(Error::UnsupportedAuthenticatorVersion),
|
||||
AuthenticatorVersion::UNKNOWN => {
|
||||
return Err(AuthenticationClientError::UnsupportedAuthenticatorVersion);
|
||||
}
|
||||
};
|
||||
let response = self.send_and_wait_for_response(&query_message).await?;
|
||||
|
||||
@@ -332,7 +353,7 @@ impl AuthenticatorClient {
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
_ => return Err(Error::InvalidGatewayAuthResponse),
|
||||
_ => return Err(AuthenticationClientError::InvalidGatewayAuthResponse),
|
||||
};
|
||||
|
||||
let remaining_pretty = if available_bandwidth > 1024 * 1024 {
|
||||
@@ -347,13 +368,13 @@ impl AuthenticatorClient {
|
||||
);
|
||||
if available_bandwidth < 1024 * 1024 {
|
||||
tracing::warn!(
|
||||
"Remaining bandwidth is under 1 MB. The wireguard mode will get suspended after that until tomorrow, UTC time. The client might shutdown with timeout soon
|
||||
"
|
||||
);
|
||||
"Remaining bandwidth is under 1 MB. The wireguard mode will get suspended after that until tomorrow, UTC time. The client might shutdown with timeout soon"
|
||||
);
|
||||
}
|
||||
Ok(Some(available_bandwidth))
|
||||
}
|
||||
|
||||
// Since the caller provides the credential, it knows it is spent
|
||||
pub async fn top_up(&mut self, credential: CredentialSpendingData) -> Result<i64> {
|
||||
let top_up_message = match self.auth_version {
|
||||
AuthenticatorVersion::V3 => ClientMessage::TopUp(Box::new(v3::topup::TopUpMessage {
|
||||
@@ -371,7 +392,7 @@ impl AuthenticatorClient {
|
||||
credential,
|
||||
})),
|
||||
AuthenticatorVersion::V1 | AuthenticatorVersion::V2 | AuthenticatorVersion::UNKNOWN => {
|
||||
return Err(Error::UnsupportedAuthenticatorVersion);
|
||||
return Err(AuthenticationClientError::UnsupportedAuthenticatorVersion);
|
||||
}
|
||||
};
|
||||
let response = self.send_and_wait_for_response(&top_up_message).await?;
|
||||
@@ -380,7 +401,7 @@ impl AuthenticatorClient {
|
||||
AuthenticatorResponse::TopUpBandwidth(top_up_bandwidth_response) => {
|
||||
top_up_bandwidth_response.available_bandwidth()
|
||||
}
|
||||
_ => return Err(Error::InvalidGatewayAuthResponse),
|
||||
_ => return Err(AuthenticationClientError::InvalidGatewayAuthResponse),
|
||||
};
|
||||
|
||||
Ok(remaining_bandwidth)
|
||||
|
||||
@@ -50,7 +50,7 @@ impl AuthClientMixnetListener {
|
||||
}
|
||||
}
|
||||
|
||||
async fn run(mut self) -> Self {
|
||||
async fn run(mut self) {
|
||||
let mixnet_cancel_token = self.mixnet_client.cancellation_token();
|
||||
self.shutdown_token.run_until_cancelled(async {
|
||||
loop {
|
||||
@@ -95,12 +95,8 @@ impl AuthClientMixnetListener {
|
||||
tracing::debug!("AuthClientMixnetListener is shutting down");
|
||||
}).await;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
// Disconnects the mixnet client and effectively drop itself, since it doesn't work without one, and reconnecting isn't supported
|
||||
pub async fn disconnect_mixnet_client(self) {
|
||||
if !self.mixnet_client.cancellation_token().is_cancelled() {
|
||||
tracing::debug!("AuthClientMixnetListener: Disconnect mixnet client");
|
||||
if !mixnet_cancel_token.is_cancelled() {
|
||||
self.mixnet_client.disconnect().await;
|
||||
}
|
||||
}
|
||||
@@ -128,7 +124,7 @@ pub struct AuthClientMixnetListenerHandle {
|
||||
message_sender: MixnetMessageInputSender,
|
||||
cancellation_token: CancellationToken,
|
||||
mixnet_cancellation_token: CancellationToken,
|
||||
handle: JoinHandle<AuthClientMixnetListener>,
|
||||
handle: JoinHandle<()>,
|
||||
}
|
||||
|
||||
impl AuthClientMixnetListenerHandle {
|
||||
@@ -148,13 +144,8 @@ impl AuthClientMixnetListenerHandle {
|
||||
// If shutdown was externally called, that call is a no-op
|
||||
// If we're only stopping this, it is very much needed
|
||||
self.cancellation_token.cancel();
|
||||
match self.handle.await {
|
||||
Ok(auth_client_mixnet_listener) => {
|
||||
auth_client_mixnet_listener.disconnect_mixnet_client().await;
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error waiting for auth clients mixnet listener to stop: {e}");
|
||||
}
|
||||
if let Err(e) = self.handle.await {
|
||||
tracing::error!("Error waiting for auth clients mixnet listener to stop: {e}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "extension-storage"
|
||||
version = "1.4.1"
|
||||
version = "1.4.0-rc.0"
|
||||
edition = "2024"
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/nymtech/nym"
|
||||
|
||||
@@ -765,7 +765,7 @@ async fn connect_exit(
|
||||
);
|
||||
// The IPR supports cancellation, but it's unused in the gateway probe
|
||||
let cancel_token = CancellationToken::new();
|
||||
let mut ipr_client = IprClientConnect::new(mixnet_client, cancel_token).await;
|
||||
let mut ipr_client = IprClientConnect::new(mixnet_client, cancel_token);
|
||||
|
||||
let maybe_ip_pair = ipr_client.connect(exit_router_address).await;
|
||||
let mixnet_client = ipr_client.into_mixnet_client();
|
||||
|
||||
@@ -43,7 +43,7 @@ pub struct IprClientConnect {
|
||||
}
|
||||
|
||||
impl IprClientConnect {
|
||||
pub async fn new(mixnet_client: MixnetClient, cancel_token: CancellationToken) -> Self {
|
||||
pub fn new(mixnet_client: MixnetClient, cancel_token: CancellationToken) -> Self {
|
||||
Self {
|
||||
mixnet_client,
|
||||
connected: ConnectionState::Disconnected,
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
# this will only work with VPN, otherwise remove the harbor part
|
||||
FROM harbor.nymte.ch/dockerhub/rust:latest AS builder
|
||||
|
||||
ARG GIT_REF=main
|
||||
|
||||
RUN apt update && apt install -yy libdbus-1-dev pkg-config libclang-dev
|
||||
|
||||
# Install go
|
||||
RUN wget https://go.dev/dl/go1.22.5.linux-amd64.tar.gz -O go.tar.gz
|
||||
RUN tar -xzvf go.tar.gz -C /usr/local
|
||||
|
||||
RUN git clone https://github.com/nymtech/nym-vpn-client /usr/src/nym-vpn-client
|
||||
RUN cd /usr/src/nym-vpn-client && git checkout $GIT_REF
|
||||
ENV PATH=/go/bin:/usr/local/go/bin:$PATH
|
||||
WORKDIR /usr/src/nym-vpn-client/nym-vpn-core
|
||||
RUN cargo build --release --package nym-gateway-probe
|
||||
|
||||
COPY ./ /usr/src/nym
|
||||
WORKDIR /usr/src/nym
|
||||
RUN cargo build --release --package nym-gateway-probe
|
||||
|
||||
WORKDIR /usr/src/nym/nym-node-status-api/nym-node-status-agent
|
||||
RUN cargo build --release
|
||||
|
||||
@@ -35,7 +31,7 @@ RUN apt-get update && apt-get install -y ca-certificates
|
||||
WORKDIR /nym
|
||||
|
||||
COPY --from=builder /usr/src/nym/target/release/nym-node-status-agent ./
|
||||
COPY --from=builder /usr/src/nym-vpn-client/nym-vpn-core/target/release/nym-gateway-probe ./
|
||||
COPY --from=builder /usr/src/nym/target/release/nym-gateway-probe ./
|
||||
COPY --from=builder /usr/src/nym/nym-node-status-api/nym-node-status-agent/entrypoint.sh ./
|
||||
RUN chmod +x /nym/entrypoint.sh
|
||||
|
||||
|
||||
+8
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT\n node_id,\n ed25519_identity_pubkey,\n total_stake,\n ip_addresses as \"ip_addresses!: serde_json::Value\",\n mix_port,\n x25519_sphinx_pubkey,\n node_role as \"node_role: serde_json::Value\",\n supported_roles as \"supported_roles: serde_json::Value\",\n entry as \"entry: serde_json::Value\",\n performance,\n self_described as \"self_described: serde_json::Value\",\n bond_info as \"bond_info: serde_json::Value\"\n FROM\n nym_nodes\n ORDER BY\n node_id\n ",
|
||||
"query": "SELECT\n node_id,\n ed25519_identity_pubkey,\n total_stake,\n ip_addresses as \"ip_addresses!: serde_json::Value\",\n mix_port,\n x25519_sphinx_pubkey,\n node_role as \"node_role: serde_json::Value\",\n supported_roles as \"supported_roles: serde_json::Value\",\n entry as \"entry: serde_json::Value\",\n performance,\n self_described as \"self_described: serde_json::Value\",\n bond_info as \"bond_info: serde_json::Value\",\n http_api_port\n FROM\n nym_nodes\n WHERE\n self_described IS NOT NULL\n AND\n bond_info IS NOT NULL\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -62,6 +62,11 @@
|
||||
"ordinal": 11,
|
||||
"name": "bond_info: serde_json::Value",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "http_api_port",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -79,8 +84,9 @@
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "c48d04fc3de59dd484f0a63d40336ced54e08785f77e9ef85f3157d004ec85dc"
|
||||
"hash": "0b51df277ed66c6553f66af9b135342dee177abc1c92e4a89147de3c22d3d1a5"
|
||||
}
|
||||
+8
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT\n node_id,\n ed25519_identity_pubkey,\n total_stake,\n ip_addresses as \"ip_addresses!: serde_json::Value\",\n mix_port,\n x25519_sphinx_pubkey,\n node_role as \"node_role: serde_json::Value\",\n supported_roles as \"supported_roles: serde_json::Value\",\n entry as \"entry: serde_json::Value\",\n performance,\n self_described as \"self_described: serde_json::Value\",\n bond_info as \"bond_info: serde_json::Value\"\n FROM\n nym_nodes\n WHERE\n self_described IS NOT NULL\n AND\n bond_info IS NOT NULL\n ",
|
||||
"query": "SELECT\n node_id,\n ed25519_identity_pubkey,\n total_stake,\n ip_addresses as \"ip_addresses!: serde_json::Value\",\n mix_port,\n x25519_sphinx_pubkey,\n node_role as \"node_role: serde_json::Value\",\n supported_roles as \"supported_roles: serde_json::Value\",\n entry as \"entry: serde_json::Value\",\n performance,\n self_described as \"self_described: serde_json::Value\",\n bond_info as \"bond_info: serde_json::Value\",\n http_api_port\n FROM\n nym_nodes\n ORDER BY\n node_id\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -62,6 +62,11 @@
|
||||
"ordinal": 11,
|
||||
"name": "bond_info: serde_json::Value",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "http_api_port",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -79,8 +84,9 @@
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "283f49a65c7d70bf271702ff6a5c7ad6e68c81932d295ff18ed198c54706a57c"
|
||||
"hash": "3ddc12cc4e1796b787a50c40560d2bd71d1cfe5f5265e6f161b3122d1317a421"
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO nym_nodes\n (node_id, ed25519_identity_pubkey,\n total_stake,\n ip_addresses, mix_port,\n x25519_sphinx_pubkey, node_role,\n supported_roles, entry,\n self_described,\n bond_info,\n performance, last_updated_utc\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)\n ON CONFLICT(node_id) DO UPDATE SET\n ed25519_identity_pubkey=excluded.ed25519_identity_pubkey,\n ip_addresses=excluded.ip_addresses,\n mix_port=excluded.mix_port,\n x25519_sphinx_pubkey=excluded.x25519_sphinx_pubkey,\n node_role=excluded.node_role,\n supported_roles=excluded.supported_roles,\n entry=excluded.entry,\n self_described=excluded.self_described,\n bond_info=excluded.bond_info,\n performance=excluded.performance,\n last_updated_utc=excluded.last_updated_utc\n ;",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4",
|
||||
"Varchar",
|
||||
"Int8",
|
||||
"Jsonb",
|
||||
"Int4",
|
||||
"Varchar",
|
||||
"Jsonb",
|
||||
"Jsonb",
|
||||
"Jsonb",
|
||||
"Jsonb",
|
||||
"Jsonb",
|
||||
"Varchar",
|
||||
"Int4"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "b010fb91828f7e4f0b72bdfe3b58b2abb437cccdb6ebd2e1087cc822ed737b0e"
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO nym_nodes\n (node_id, ed25519_identity_pubkey,\n total_stake,\n ip_addresses, mix_port,\n x25519_sphinx_pubkey, node_role,\n supported_roles, entry,\n self_described,\n bond_info,\n performance, last_updated_utc, http_api_port\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)\n ON CONFLICT(node_id) DO UPDATE SET\n ed25519_identity_pubkey=excluded.ed25519_identity_pubkey,\n ip_addresses=excluded.ip_addresses,\n mix_port=excluded.mix_port,\n x25519_sphinx_pubkey=excluded.x25519_sphinx_pubkey,\n node_role=excluded.node_role,\n supported_roles=excluded.supported_roles,\n entry=excluded.entry,\n self_described=excluded.self_described,\n bond_info=excluded.bond_info,\n performance=excluded.performance,\n last_updated_utc=excluded.last_updated_utc,\n http_api_port=excluded.http_api_port\n ;",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4",
|
||||
"Varchar",
|
||||
"Int8",
|
||||
"Jsonb",
|
||||
"Int4",
|
||||
"Varchar",
|
||||
"Jsonb",
|
||||
"Jsonb",
|
||||
"Jsonb",
|
||||
"Jsonb",
|
||||
"Jsonb",
|
||||
"Varchar",
|
||||
"Int4",
|
||||
"Int4"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "dde9aff827c34086077927bbe33fa3d5c939e7122ba7c88b78a353f00b271ec2"
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-node-status-api"
|
||||
version = "4.0.10"
|
||||
version = "4.0.11-rc1"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE nym_nodes
|
||||
ADD COLUMN IF NOT EXISTS http_api_port INTEGER;
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::ticketbook_manager::TicketbookManagerConfig;
|
||||
use clap::Parser;
|
||||
use clap::{Parser, Subcommand};
|
||||
use nym_bin_common::bin_info;
|
||||
use nym_credential_proxy_lib::shared_state::ecash_state::TicketType;
|
||||
use reqwest::Url;
|
||||
@@ -105,6 +105,19 @@ pub(crate) struct Cli {
|
||||
|
||||
#[clap(flatten)]
|
||||
pub(crate) ticketbook: TicketbookArgs,
|
||||
|
||||
#[command(subcommand)]
|
||||
pub(crate) command: Option<Commands>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
pub(crate) enum Commands {
|
||||
/// Scrape a single node and output detailed debug logs
|
||||
ScrapeNode {
|
||||
/// The id of the node to scrape
|
||||
#[arg(long)]
|
||||
node_id: i64,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
|
||||
@@ -381,7 +381,7 @@ impl ScrapeNodeKind {
|
||||
pub(crate) struct ScraperNodeInfo {
|
||||
pub node_kind: ScrapeNodeKind,
|
||||
pub hosts: Vec<String>,
|
||||
pub http_api_port: i64,
|
||||
pub http_api_port: Option<u16>,
|
||||
}
|
||||
|
||||
impl ScraperNodeInfo {
|
||||
@@ -395,8 +395,21 @@ impl ScraperNodeInfo {
|
||||
format!("http://{}", host),
|
||||
]);
|
||||
|
||||
if self.http_api_port != DEFAULT_NYM_NODE_HTTP_PORT as i64 {
|
||||
urls.insert(0, format!("http://{}:{}", host, self.http_api_port));
|
||||
if let Some(custom_http_api_port) = self.http_api_port {
|
||||
urls = Vec::new();
|
||||
for host in &self.hosts {
|
||||
urls.append(&mut vec![format!(
|
||||
"http://{}:{}",
|
||||
host, custom_http_api_port
|
||||
)]);
|
||||
}
|
||||
|
||||
// do not fall back to default ports, if the operator sets a custom http api port
|
||||
// in their bond, use it and error out if it's not available
|
||||
// this will correctly handle cases where some operators run multiple nodes
|
||||
// on a single IP address and assign different custom http port apis at bond time
|
||||
|
||||
// urls.insert(0, format!("http://{}:{}", host, custom_http_api_port));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,6 +436,7 @@ pub(crate) struct NymNodeDto {
|
||||
pub performance: String,
|
||||
pub self_described: Option<serde_json::Value>,
|
||||
pub bond_info: Option<serde_json::Value>,
|
||||
pub http_api_port: Option<i32>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // it's not dead code but clippy doesn't detect usage in sqlx macros
|
||||
@@ -440,6 +454,7 @@ pub(crate) struct NymNodeInsertRecord {
|
||||
pub entry: Option<serde_json::Value>,
|
||||
pub self_described: Option<serde_json::Value>,
|
||||
pub bond_info: Option<serde_json::Value>,
|
||||
pub http_api_port: Option<i32>,
|
||||
pub last_updated_utc: i64,
|
||||
}
|
||||
|
||||
@@ -456,6 +471,12 @@ impl NymNodeInsertRecord {
|
||||
.map(|info| decimal_to_i64(info.total_stake()))
|
||||
.unwrap_or(0);
|
||||
let entry = serialize_opt_to_value!(skimmed_node.entry)?;
|
||||
let http_api_port = bond_info.and_then(|bond| {
|
||||
bond.bond_information
|
||||
.node
|
||||
.custom_http_port
|
||||
.map(|port| port as i32)
|
||||
});
|
||||
let bond_info = serialize_opt_to_value!(bond_info)?;
|
||||
let self_described = serialize_opt_to_value!(self_described)?;
|
||||
|
||||
@@ -472,6 +493,7 @@ impl NymNodeInsertRecord {
|
||||
entry,
|
||||
self_described,
|
||||
bond_info,
|
||||
http_api_port,
|
||||
last_updated_utc: now,
|
||||
};
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ pub(crate) async fn get_all_nym_nodes(pool: &DbPool) -> anyhow::Result<Vec<NymNo
|
||||
entry as "entry: serde_json::Value",
|
||||
performance,
|
||||
self_described as "self_described: serde_json::Value",
|
||||
bond_info as "bond_info: serde_json::Value"
|
||||
bond_info as "bond_info: serde_json::Value",
|
||||
http_api_port
|
||||
FROM
|
||||
nym_nodes
|
||||
ORDER BY
|
||||
@@ -72,7 +73,8 @@ pub(crate) async fn get_described_bonded_nym_nodes(
|
||||
entry as "entry: serde_json::Value",
|
||||
performance,
|
||||
self_described as "self_described: serde_json::Value",
|
||||
bond_info as "bond_info: serde_json::Value"
|
||||
bond_info as "bond_info: serde_json::Value",
|
||||
http_api_port
|
||||
FROM
|
||||
nym_nodes
|
||||
WHERE
|
||||
@@ -115,9 +117,9 @@ pub(crate) async fn update_nym_nodes(
|
||||
supported_roles, entry,
|
||||
self_described,
|
||||
bond_info,
|
||||
performance, last_updated_utc
|
||||
performance, last_updated_utc, http_api_port
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
|
||||
ON CONFLICT(node_id) DO UPDATE SET
|
||||
ed25519_identity_pubkey=excluded.ed25519_identity_pubkey,
|
||||
ip_addresses=excluded.ip_addresses,
|
||||
@@ -129,7 +131,8 @@ pub(crate) async fn update_nym_nodes(
|
||||
self_described=excluded.self_described,
|
||||
bond_info=excluded.bond_info,
|
||||
performance=excluded.performance,
|
||||
last_updated_utc=excluded.last_updated_utc
|
||||
last_updated_utc=excluded.last_updated_utc,
|
||||
http_api_port=excluded.http_api_port
|
||||
;",
|
||||
record.node_id,
|
||||
record.ed25519_identity_pubkey,
|
||||
@@ -144,6 +147,7 @@ pub(crate) async fn update_nym_nodes(
|
||||
record.bond_info,
|
||||
record.performance,
|
||||
record.last_updated_utc as i32,
|
||||
record.http_api_port,
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
|
||||
@@ -21,10 +21,11 @@ pub(crate) async fn get_nodes_for_scraping(pool: &DbPool) -> Result<Vec<ScraperN
|
||||
let skimmed_nodes = queries::get_described_bonded_nym_nodes(pool)
|
||||
.await
|
||||
.map(|nodes_dto| {
|
||||
nodes_dto.into_iter().filter_map(|node| {
|
||||
let node_id = node.node_id;
|
||||
match SkimmedNode::try_from(node) {
|
||||
Ok(node) => Some(node),
|
||||
nodes_dto.into_iter().filter_map(|node_dto| {
|
||||
let node_id = node_dto.node_id;
|
||||
let http_api_port = node_dto.http_api_port;
|
||||
match SkimmedNode::try_from(node_dto) {
|
||||
Ok(node) => Some((node, http_api_port)),
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to decode node_id={}: {}", node_id, e);
|
||||
None
|
||||
@@ -33,7 +34,7 @@ pub(crate) async fn get_nodes_for_scraping(pool: &DbPool) -> Result<Vec<ScraperN
|
||||
})
|
||||
})?;
|
||||
|
||||
skimmed_nodes.for_each(|node| {
|
||||
skimmed_nodes.for_each(|(node, http_api_port)| {
|
||||
// TODO: relies on polyfilling: Nym nodes table might contain legacy mixnodes
|
||||
// as well. Categorize them here.
|
||||
let node_kind = if gateway_keys.contains(&node.ed25519_identity_pubkey.to_base58_string()) {
|
||||
@@ -54,7 +55,7 @@ pub(crate) async fn get_nodes_for_scraping(pool: &DbPool) -> Result<Vec<ScraperN
|
||||
.into_iter()
|
||||
.map(|ip| ip.to_string())
|
||||
.collect::<Vec<_>>(),
|
||||
http_api_port: node.mix_port.into(),
|
||||
http_api_port: http_api_port.map(|port| port as u16),
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
@@ -138,6 +138,7 @@ mod db_tests {
|
||||
performance: "1.0".to_string(),
|
||||
self_described: None,
|
||||
bond_info: None,
|
||||
http_api_port: None,
|
||||
};
|
||||
|
||||
let skimmed_node: nym_validator_client::nym_api::SkimmedNode =
|
||||
@@ -362,22 +363,42 @@ fn test_scraper_node_info_contact_addresses() {
|
||||
let node_info = ScraperNodeInfo {
|
||||
node_kind: ScrapeNodeKind::MixingNymNode { node_id: 123 },
|
||||
hosts: vec!["1.1.1.1".to_string(), "example.com".to_string()],
|
||||
http_api_port: 8080,
|
||||
http_api_port: None,
|
||||
};
|
||||
|
||||
let addresses = node_info.contact_addresses();
|
||||
|
||||
// Should generate multiple URLs for each host
|
||||
// Custom port (8080) should be inserted at the beginning
|
||||
// When no custom port is specified only default ports should be used
|
||||
assert!(addresses.contains(&"http://1.1.1.1:8080".to_string()));
|
||||
assert!(addresses.contains(&"http://example.com:8080".to_string()));
|
||||
assert!(addresses.contains(&"http://1.1.1.1:8000".to_string()));
|
||||
assert!(addresses.contains(&"https://1.1.1.1".to_string()));
|
||||
assert!(addresses.contains(&"http://1.1.1.1".to_string()));
|
||||
assert!(addresses.contains(&"http://example.com:8000".to_string()));
|
||||
// Check that URLs follow the expected pattern
|
||||
assert!(addresses.len() >= 8); // At least 4 URLs per host
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scraper_node_info_contact_addresses_with_custom_http_api_port() {
|
||||
use crate::db::models::{ScrapeNodeKind, ScraperNodeInfo};
|
||||
|
||||
let node_info = ScraperNodeInfo {
|
||||
node_kind: ScrapeNodeKind::MixingNymNode { node_id: 123 },
|
||||
hosts: vec!["1.1.1.1".to_string(), "example.com".to_string()],
|
||||
http_api_port: Some(4444),
|
||||
};
|
||||
|
||||
let addresses = node_info.contact_addresses();
|
||||
|
||||
// Should generate multiple URLs for each host
|
||||
// Custom port (4444) should be the only port in the list
|
||||
assert!(addresses.contains(&"http://1.1.1.1:4444".to_string()));
|
||||
assert!(addresses.contains(&"http://example.com:4444".to_string()));
|
||||
// Check that URLs follow the expected pattern
|
||||
assert!(addresses.len() >= 2); // At least 4 URLs per host
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scrape_node_kind_node_id() {
|
||||
use crate::db::models::ScrapeNodeKind;
|
||||
@@ -414,6 +435,7 @@ fn test_nym_node_dto_with_invalid_keys() {
|
||||
performance: "1.0".to_string(),
|
||||
self_described: None,
|
||||
bond_info: None,
|
||||
http_api_port: None,
|
||||
};
|
||||
|
||||
let result: Result<nym_validator_client::nym_api::SkimmedNode, _> = nym_node_dto.try_into();
|
||||
@@ -451,6 +473,7 @@ fn test_nym_node_dto_with_invalid_performance() {
|
||||
performance: "invalid_percent".to_string(),
|
||||
self_described: None,
|
||||
bond_info: None,
|
||||
http_api_port: None,
|
||||
};
|
||||
|
||||
let result: Result<nym_validator_client::nym_api::SkimmedNode, _> = nym_node_dto.try_into();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
use crate::cli::Commands;
|
||||
use crate::monitor::DelegationsCache;
|
||||
use crate::node_scraper::helpers::scrape_and_store_description_by_node_id;
|
||||
use crate::ticketbook_manager::TicketbookManager;
|
||||
use crate::ticketbook_manager::state::TicketbookManagerState;
|
||||
use clap::Parser;
|
||||
@@ -40,11 +42,49 @@ async fn main() -> anyhow::Result<()> {
|
||||
tracing::info!("Registered {} agent keys", agent_key_list.len());
|
||||
|
||||
let connection_url = args.database_url.clone();
|
||||
tracing::debug!("Using config:\n{:#?}", args);
|
||||
if std::env::var("SHOW_CONFIG").ok().is_some() {
|
||||
tracing::debug!("Using config:\n{:#?}", args);
|
||||
}
|
||||
|
||||
let storage = db::Storage::init(connection_url, args.sqlx_busy_timeout_s).await?;
|
||||
let db_pool = storage.pool_owned();
|
||||
|
||||
// node geocache is shared between node monitor and HTTP server
|
||||
let geocache = moka::future::Cache::builder()
|
||||
.time_to_live(args.geodata_ttl)
|
||||
.build();
|
||||
let delegations_cache = DelegationsCache::new();
|
||||
|
||||
let client_config = nym_validator_client::nyxd::Config::try_from_nym_network_details(
|
||||
&nym_network_defaults::NymNetworkDetails::new_from_env(),
|
||||
)?;
|
||||
let nyxd_client = NyxdClient::connect(client_config.clone(), args.nyxd_addr.as_str())
|
||||
.map_err(|err| anyhow::anyhow!("Couldn't connect: {}", err))?;
|
||||
|
||||
match args.command {
|
||||
Some(Commands::ScrapeNode { node_id }) => {
|
||||
if std::env::var("RUN_ONCE_INIT_NODES").ok().is_some() {
|
||||
let geocache_clone = geocache.clone();
|
||||
let delegations_cache_clone = Arc::clone(&delegations_cache);
|
||||
monitor::run_once(
|
||||
db_pool.clone(),
|
||||
args.nym_api_client_timeout,
|
||||
nyxd_client,
|
||||
args.ipinfo_api_token,
|
||||
geocache_clone,
|
||||
delegations_cache_clone,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
tracing::info!("Scraping node with id {node_id}...");
|
||||
scrape_and_store_description_by_node_id(&db_pool, node_id).await?;
|
||||
return Ok(());
|
||||
}
|
||||
None => {
|
||||
// default behaviour
|
||||
}
|
||||
}
|
||||
|
||||
// Start the node scraper
|
||||
let scraper = node_scraper::DescriptionScraper::new(storage.pool_owned());
|
||||
shutdown_manager.spawn_with_shutdown(async move {
|
||||
@@ -58,20 +98,9 @@ async fn main() -> anyhow::Result<()> {
|
||||
scraper.start().await;
|
||||
});
|
||||
|
||||
// node geocache is shared between node monitor and HTTP server
|
||||
let geocache = moka::future::Cache::builder()
|
||||
.time_to_live(args.geodata_ttl)
|
||||
.build();
|
||||
let delegations_cache = DelegationsCache::new();
|
||||
|
||||
// Start the monitor
|
||||
let geocache_clone = geocache.clone();
|
||||
let delegations_cache_clone = Arc::clone(&delegations_cache);
|
||||
let client_config = nym_validator_client::nyxd::Config::try_from_nym_network_details(
|
||||
&nym_network_defaults::NymNetworkDetails::new_from_env(),
|
||||
)?;
|
||||
let nyxd_client = NyxdClient::connect(client_config.clone(), args.nyxd_addr.as_str())
|
||||
.map_err(|err| anyhow::anyhow!("Couldn't connect: {}", err))?;
|
||||
|
||||
shutdown_manager.spawn_with_shutdown(async move {
|
||||
monitor::run_in_background(
|
||||
|
||||
@@ -68,7 +68,7 @@ pub(crate) async fn run_in_background(
|
||||
loop {
|
||||
tracing::info!("Refreshing node info...");
|
||||
|
||||
if let Err(e) = monitor.run().await {
|
||||
if let Err(e) = monitor.run(false).await {
|
||||
tracing::error!(
|
||||
"Monitor run failed: {e}, retrying in {}s...",
|
||||
MONITOR_FAILURE_RETRY_DELAY.as_secs()
|
||||
@@ -84,8 +84,33 @@ pub(crate) async fn run_in_background(
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", name = "data_monitor", skip_all)]
|
||||
pub(crate) async fn run_once(
|
||||
db_pool: DbPool,
|
||||
nym_api_client_timeout: Duration,
|
||||
nyxd_client: nym_validator_client::QueryHttpRpcNyxdClient,
|
||||
ipinfo_api_token: String,
|
||||
geocache: NodeGeoCache,
|
||||
node_delegations: Arc<RwLock<DelegationsCache>>,
|
||||
) -> anyhow::Result<()> {
|
||||
let ipinfo = IpInfoClient::new(ipinfo_api_token.clone());
|
||||
|
||||
let mut monitor = Monitor {
|
||||
db_pool,
|
||||
network_details: nym_network_defaults::NymNetworkDetails::new_from_env(),
|
||||
nym_api_client_timeout,
|
||||
nyxd_client,
|
||||
ipinfo,
|
||||
geocache,
|
||||
node_delegations,
|
||||
};
|
||||
|
||||
tracing::info!("Refreshing node info...");
|
||||
monitor.run(true).await
|
||||
}
|
||||
|
||||
impl Monitor {
|
||||
async fn run(&mut self) -> anyhow::Result<()> {
|
||||
async fn run(&mut self, exit_early: bool) -> anyhow::Result<()> {
|
||||
self.check_ipinfo_bandwidth().await;
|
||||
|
||||
let default_api_url = self
|
||||
@@ -153,6 +178,11 @@ impl Monitor {
|
||||
tracing::debug!("{} nym nodes written to DB!", inserted);
|
||||
})?;
|
||||
|
||||
// stop here if running once
|
||||
if exit_early {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// refresh geodata for all nodes
|
||||
for node_description in described_nodes.values() {
|
||||
self.location_cached(node_description).await;
|
||||
|
||||
@@ -118,6 +118,17 @@ pub fn sanitize_description(
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn scrape_and_store_description_by_node_id(pool: &DbPool, node_id: i64) -> Result<()> {
|
||||
let nodes = crate::db::queries::get_nodes_for_scraping(pool).await?;
|
||||
match nodes.iter().find(|n| *n.node_kind.node_id() == node_id) {
|
||||
Some(node) => Ok(scrape_and_store_description(pool, node.clone()).await?),
|
||||
None => {
|
||||
error!("Could not find node with id {node_id}");
|
||||
Err(anyhow!("Could not find node with id {node_id}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn scrape_and_store_description(pool: &DbPool, node: ScraperNodeInfo) -> Result<()> {
|
||||
let client = build_client()?;
|
||||
let urls = node.contact_addresses();
|
||||
@@ -152,7 +163,13 @@ pub async fn scrape_and_store_description(pool: &DbPool, node: ScraperNodeInfo)
|
||||
anyhow::anyhow!("Failed to fetch description from any URL: {}", err_msg)
|
||||
})?;
|
||||
|
||||
let sanitized_description = sanitize_description(description, *node.node_id());
|
||||
let sanitized_description = sanitize_description(description.clone(), *node.node_id());
|
||||
|
||||
trace!("tried_url_list = {tried_url_list:?}");
|
||||
trace!("ndoe_id = {}", node.node_id());
|
||||
trace!("description = {:?}", description);
|
||||
trace!("sanitized_description = {:?}", sanitized_description);
|
||||
|
||||
insert_scraped_node_description(pool, &node.node_kind, &sanitized_description).await?;
|
||||
|
||||
Ok(())
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-node"
|
||||
version = "1.19.0"
|
||||
version = "1.21.0"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
|
||||
@@ -17,6 +17,7 @@ thiserror.workspace = true
|
||||
tokio.workspace = true
|
||||
tokio-util.workspace = true
|
||||
tracing.workspace = true
|
||||
typed-builder.workspace = true
|
||||
url.workspace = true
|
||||
|
||||
nym-authenticator-client = { path = "../nym-authenticator-client" }
|
||||
|
||||
@@ -15,10 +15,12 @@ use nym_sdk::{
|
||||
use std::os::fd::RawFd;
|
||||
use std::{path::PathBuf, sync::Arc, time::Duration};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use typed_builder::TypedBuilder;
|
||||
|
||||
use crate::error::RegistrationClientError;
|
||||
|
||||
const VPN_AVERAGE_PACKET_DELAY: Duration = Duration::from_millis(15);
|
||||
const MIXNET_CLIENT_STARTUP_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NymNodeWithKeys {
|
||||
@@ -26,11 +28,14 @@ pub struct NymNodeWithKeys {
|
||||
pub keys: Arc<KeyPair>,
|
||||
}
|
||||
|
||||
#[derive(TypedBuilder)]
|
||||
pub struct BuilderConfig {
|
||||
pub entry_node: NymNodeWithKeys,
|
||||
pub exit_node: NymNodeWithKeys,
|
||||
pub data_path: Option<PathBuf>,
|
||||
pub mixnet_client_config: MixnetClientConfig,
|
||||
#[builder(default = MIXNET_CLIENT_STARTUP_TIMEOUT)]
|
||||
pub mixnet_client_startup_timeout: Duration,
|
||||
pub two_hops: bool,
|
||||
pub user_agent: UserAgent,
|
||||
pub custom_topology_provider: Box<dyn TopologyProvider + Send + Sync>,
|
||||
@@ -56,53 +61,6 @@ pub struct MixnetClientConfig {
|
||||
}
|
||||
|
||||
impl BuilderConfig {
|
||||
/// Creates a new BuilderConfig with all required parameters.
|
||||
///
|
||||
/// However, consider using `BuilderConfig::builder()` instead.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
entry_node: NymNodeWithKeys,
|
||||
exit_node: NymNodeWithKeys,
|
||||
data_path: Option<PathBuf>,
|
||||
mixnet_client_config: MixnetClientConfig,
|
||||
two_hops: bool,
|
||||
user_agent: UserAgent,
|
||||
custom_topology_provider: Box<dyn TopologyProvider + Send + Sync>,
|
||||
network_env: NymNetworkDetails,
|
||||
cancel_token: CancellationToken,
|
||||
#[cfg(unix)] connection_fd_callback: Arc<dyn Fn(RawFd) + Send + Sync>,
|
||||
) -> Self {
|
||||
Self {
|
||||
entry_node,
|
||||
exit_node,
|
||||
data_path,
|
||||
mixnet_client_config,
|
||||
two_hops,
|
||||
user_agent,
|
||||
custom_topology_provider,
|
||||
network_env,
|
||||
cancel_token,
|
||||
#[cfg(unix)]
|
||||
connection_fd_callback,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a builder for BuilderConfig
|
||||
///
|
||||
/// This is the preferred way to construct a BuilderConfig.
|
||||
///
|
||||
/// # Example
|
||||
/// ```ignore
|
||||
/// let config = BuilderConfig::builder()
|
||||
/// .entry_node(entry)
|
||||
/// .exit_node(exit)
|
||||
/// .user_agent(agent)
|
||||
/// .build()?;
|
||||
/// ```
|
||||
pub fn builder() -> BuilderConfigBuilder {
|
||||
BuilderConfigBuilder::default()
|
||||
}
|
||||
|
||||
pub fn mixnet_client_debug_config(&self) -> DebugConfig {
|
||||
if self.two_hops {
|
||||
two_hop_debug_config(&self.mixnet_client_config)
|
||||
@@ -254,144 +212,6 @@ fn true_to_disabled(val: bool) -> &'static str {
|
||||
if val { "disabled" } else { "enabled" }
|
||||
}
|
||||
|
||||
/// Error type for BuilderConfig validation
|
||||
#[derive(Debug, Clone, thiserror::Error)]
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
pub enum BuilderConfigError {
|
||||
#[error("entry_node is required")]
|
||||
MissingEntryNode,
|
||||
#[error("exit_node is required")]
|
||||
MissingExitNode,
|
||||
#[error("mixnet_client_config is required")]
|
||||
MissingMixnetClientConfig,
|
||||
#[error("user_agent is required")]
|
||||
MissingUserAgent,
|
||||
#[error("custom_topology_provider is required")]
|
||||
MissingTopologyProvider,
|
||||
#[error("network_env is required")]
|
||||
MissingNetworkEnv,
|
||||
#[error("cancel_token is required")]
|
||||
MissingCancelToken,
|
||||
#[cfg(unix)]
|
||||
#[error("connection_fd_callback is required")]
|
||||
MissingConnectionFdCallback,
|
||||
}
|
||||
|
||||
/// Builder for `BuilderConfig`
|
||||
///
|
||||
/// This provides a more convenient way to construct a `BuilderConfig` compared to the
|
||||
/// `new()` constructor with many arguments.
|
||||
#[derive(Default)]
|
||||
pub struct BuilderConfigBuilder {
|
||||
entry_node: Option<NymNodeWithKeys>,
|
||||
exit_node: Option<NymNodeWithKeys>,
|
||||
data_path: Option<PathBuf>,
|
||||
mixnet_client_config: Option<MixnetClientConfig>,
|
||||
two_hops: bool,
|
||||
user_agent: Option<UserAgent>,
|
||||
custom_topology_provider: Option<Box<dyn TopologyProvider + Send + Sync>>,
|
||||
network_env: Option<NymNetworkDetails>,
|
||||
cancel_token: Option<CancellationToken>,
|
||||
#[cfg(unix)]
|
||||
connection_fd_callback: Option<Arc<dyn Fn(RawFd) + Send + Sync>>,
|
||||
}
|
||||
|
||||
impl BuilderConfigBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn entry_node(mut self, entry_node: NymNodeWithKeys) -> Self {
|
||||
self.entry_node = Some(entry_node);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn exit_node(mut self, exit_node: NymNodeWithKeys) -> Self {
|
||||
self.exit_node = Some(exit_node);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn data_path(mut self, data_path: Option<PathBuf>) -> Self {
|
||||
self.data_path = data_path;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn mixnet_client_config(mut self, mixnet_client_config: MixnetClientConfig) -> Self {
|
||||
self.mixnet_client_config = Some(mixnet_client_config);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn two_hops(mut self, two_hops: bool) -> Self {
|
||||
self.two_hops = two_hops;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn user_agent(mut self, user_agent: UserAgent) -> Self {
|
||||
self.user_agent = Some(user_agent);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn custom_topology_provider(
|
||||
mut self,
|
||||
custom_topology_provider: Box<dyn TopologyProvider + Send + Sync>,
|
||||
) -> Self {
|
||||
self.custom_topology_provider = Some(custom_topology_provider);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn network_env(mut self, network_env: NymNetworkDetails) -> Self {
|
||||
self.network_env = Some(network_env);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn cancel_token(mut self, cancel_token: CancellationToken) -> Self {
|
||||
self.cancel_token = Some(cancel_token);
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
pub fn connection_fd_callback(
|
||||
mut self,
|
||||
connection_fd_callback: Arc<dyn Fn(RawFd) + Send + Sync>,
|
||||
) -> Self {
|
||||
self.connection_fd_callback = Some(connection_fd_callback);
|
||||
self
|
||||
}
|
||||
|
||||
/// Builds the `BuilderConfig`.
|
||||
///
|
||||
/// Returns an error if any required field is missing.
|
||||
pub fn build(self) -> Result<BuilderConfig, BuilderConfigError> {
|
||||
Ok(BuilderConfig {
|
||||
entry_node: self
|
||||
.entry_node
|
||||
.ok_or(BuilderConfigError::MissingEntryNode)?,
|
||||
exit_node: self.exit_node.ok_or(BuilderConfigError::MissingExitNode)?,
|
||||
data_path: self.data_path,
|
||||
mixnet_client_config: self
|
||||
.mixnet_client_config
|
||||
.ok_or(BuilderConfigError::MissingMixnetClientConfig)?,
|
||||
two_hops: self.two_hops,
|
||||
user_agent: self
|
||||
.user_agent
|
||||
.ok_or(BuilderConfigError::MissingUserAgent)?,
|
||||
custom_topology_provider: self
|
||||
.custom_topology_provider
|
||||
.ok_or(BuilderConfigError::MissingTopologyProvider)?,
|
||||
network_env: self
|
||||
.network_env
|
||||
.ok_or(BuilderConfigError::MissingNetworkEnv)?,
|
||||
cancel_token: self
|
||||
.cancel_token
|
||||
.ok_or(BuilderConfigError::MissingCancelToken)?,
|
||||
#[cfg(unix)]
|
||||
connection_fd_callback: self
|
||||
.connection_fd_callback
|
||||
.ok_or(BuilderConfigError::MissingConnectionFdCallback)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -404,54 +224,4 @@ mod tests {
|
||||
assert_eq!(config.min_mixnode_performance, None);
|
||||
assert_eq!(config.min_gateway_performance, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_builder_config_builder_fails_without_required_fields() {
|
||||
// Building without any fields should fail with specific error
|
||||
let result = BuilderConfig::builder().build();
|
||||
assert!(result.is_err());
|
||||
match result {
|
||||
Err(BuilderConfigError::MissingEntryNode) => (), // Expected
|
||||
Err(e) => panic!("Expected MissingEntryNode, got: {}", e),
|
||||
Ok(_) => panic!("Expected error, got Ok"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_builder_config_builder_validates_all_required_fields() {
|
||||
// Test that each required field is validated
|
||||
let result = BuilderConfig::builder().build();
|
||||
assert!(result.is_err());
|
||||
|
||||
// Short-circuits at first missing field, so we just verify it's one of the expected errors
|
||||
#[allow(unreachable_patterns)] // All variants are covered, but keeping catch-all for safety
|
||||
match result {
|
||||
Err(BuilderConfigError::MissingEntryNode)
|
||||
| Err(BuilderConfigError::MissingExitNode)
|
||||
| Err(BuilderConfigError::MissingMixnetClientConfig)
|
||||
| Err(BuilderConfigError::MissingUserAgent)
|
||||
| Err(BuilderConfigError::MissingTopologyProvider)
|
||||
| Err(BuilderConfigError::MissingNetworkEnv)
|
||||
| Err(BuilderConfigError::MissingCancelToken) => (),
|
||||
#[cfg(unix)]
|
||||
Err(BuilderConfigError::MissingConnectionFdCallback) => (),
|
||||
Err(e) => panic!("Unexpected error: {}", e),
|
||||
Ok(_) => panic!("Expected validation error, got Ok"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_builder_config_builder_method_chaining() {
|
||||
// Test that builder methods chain properly and return Self
|
||||
let builder = BuilderConfig::builder();
|
||||
|
||||
// Verify the builder returns itself for chaining
|
||||
let builder = builder.two_hops(true);
|
||||
let builder = builder.two_hops(false);
|
||||
let builder = builder.data_path(None);
|
||||
|
||||
// Builder should still fail because required fields are missing
|
||||
let result = builder.build();
|
||||
assert!(result.is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,15 +12,12 @@ use nym_validator_client::{
|
||||
QueryHttpRpcNyxdClient,
|
||||
nyxd::{Config as NyxdClientConfig, NyxdClient},
|
||||
};
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::{RegistrationClient, config::RegistrationClientConfig, error::RegistrationClientError};
|
||||
use config::BuilderConfig;
|
||||
|
||||
pub(crate) mod config;
|
||||
|
||||
pub(crate) const MIXNET_CLIENT_STARTUP_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
||||
pub struct RegistrationClientBuilder {
|
||||
pub config: BuilderConfig,
|
||||
}
|
||||
@@ -49,7 +46,7 @@ impl RegistrationClientBuilder {
|
||||
let builder = MixnetClientBuilder::new_with_storage(mixnet_client_storage)
|
||||
.event_tx(EventSender(event_tx));
|
||||
let mixnet_client = tokio::time::timeout(
|
||||
MIXNET_CLIENT_STARTUP_TIMEOUT,
|
||||
self.config.mixnet_client_startup_timeout,
|
||||
self.config.build_and_connect_mixnet_client(builder),
|
||||
)
|
||||
.await??;
|
||||
@@ -59,7 +56,7 @@ impl RegistrationClientBuilder {
|
||||
} else {
|
||||
let builder = MixnetClientBuilder::new_ephemeral().event_tx(EventSender(event_tx));
|
||||
let mixnet_client = tokio::time::timeout(
|
||||
MIXNET_CLIENT_STARTUP_TIMEOUT,
|
||||
self.config.mixnet_client_startup_timeout,
|
||||
self.config.build_and_connect_mixnet_client(builder),
|
||||
)
|
||||
.await??;
|
||||
|
||||
@@ -35,19 +35,85 @@ pub enum RegistrationClientError {
|
||||
#[error("timeout connecting the mixnet client")]
|
||||
Timeout(#[from] tokio::time::error::Elapsed),
|
||||
|
||||
#[error("failed to register wireguard with the gateway for {gateway_id}")]
|
||||
EntryGatewayRegisterWireguard {
|
||||
#[error(
|
||||
"failed to register wireguard with the gateway for {gateway_id}, no credential was sent"
|
||||
)]
|
||||
WireguardEntryRegistration {
|
||||
gateway_id: String,
|
||||
authenticator_address: Box<nym_sdk::mixnet::Recipient>,
|
||||
#[source]
|
||||
source: Box<nym_authenticator_client::Error>,
|
||||
source: Box<nym_authenticator_client::AuthenticationClientError>,
|
||||
},
|
||||
|
||||
#[error("failed to register wireguard with the gateway for {gateway_id}")]
|
||||
ExitGatewayRegisterWireguard {
|
||||
#[error(
|
||||
"failed to register wireguard with the gateway for {gateway_id}, no credential was sent"
|
||||
)]
|
||||
WireguardExitRegistration {
|
||||
gateway_id: String,
|
||||
authenticator_address: Box<nym_sdk::mixnet::Recipient>,
|
||||
#[source]
|
||||
source: Box<nym_authenticator_client::Error>,
|
||||
source: Box<nym_authenticator_client::AuthenticationClientError>,
|
||||
},
|
||||
|
||||
#[error(
|
||||
"failed to register wireguard with the gateway for {gateway_id}, a credential was sent"
|
||||
)]
|
||||
WireguardEntryRegistrationCredentialSent {
|
||||
gateway_id: String,
|
||||
authenticator_address: Box<nym_sdk::mixnet::Recipient>,
|
||||
#[source]
|
||||
source: Box<nym_authenticator_client::AuthenticationClientError>,
|
||||
},
|
||||
|
||||
#[error(
|
||||
"failed to register wireguard with the gateway for {gateway_id}, a credential was sent"
|
||||
)]
|
||||
WireguardExitRegistrationCredentialSent {
|
||||
gateway_id: String,
|
||||
authenticator_address: Box<nym_sdk::mixnet::Recipient>,
|
||||
#[source]
|
||||
source: Box<nym_authenticator_client::AuthenticationClientError>,
|
||||
},
|
||||
}
|
||||
|
||||
impl RegistrationClientError {
|
||||
pub fn from_authenticator_error(
|
||||
error: nym_authenticator_client::RegistrationError,
|
||||
gateway_id: String,
|
||||
authenticator_address: nym_sdk::mixnet::Recipient,
|
||||
entry: bool,
|
||||
) -> Self {
|
||||
match error {
|
||||
nym_authenticator_client::RegistrationError::NoCredentialSent(source) => {
|
||||
if entry {
|
||||
Self::WireguardEntryRegistration {
|
||||
gateway_id,
|
||||
authenticator_address: Box::new(authenticator_address),
|
||||
source: Box::new(source),
|
||||
}
|
||||
} else {
|
||||
Self::WireguardExitRegistration {
|
||||
gateway_id,
|
||||
authenticator_address: Box::new(authenticator_address),
|
||||
source: Box::new(source),
|
||||
}
|
||||
}
|
||||
}
|
||||
nym_authenticator_client::RegistrationError::CredentialSent { source } => {
|
||||
if entry {
|
||||
Self::WireguardEntryRegistrationCredentialSent {
|
||||
gateway_id,
|
||||
authenticator_address: Box::new(authenticator_address),
|
||||
source: Box::new(source),
|
||||
}
|
||||
} else {
|
||||
Self::WireguardExitRegistrationCredentialSent {
|
||||
gateway_id,
|
||||
authenticator_address: Box::new(authenticator_address),
|
||||
source: Box::new(source),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use nym_credentials_interface::TicketType;
|
||||
use nym_ip_packet_client::IprClientConnect;
|
||||
use nym_registration_common::AssignedAddresses;
|
||||
use nym_sdk::mixnet::{EventReceiver, MixnetClient, Recipient};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::config::RegistrationClientConfig;
|
||||
|
||||
@@ -34,23 +35,49 @@ pub struct RegistrationClient {
|
||||
event_rx: EventReceiver,
|
||||
}
|
||||
|
||||
// Bundle of an actual error and the underlying mixnet client so it can be shutdown correctly if needed
|
||||
struct RegistrationError {
|
||||
mixnet_client: Option<MixnetClient>,
|
||||
source: crate::RegistrationClientError,
|
||||
}
|
||||
|
||||
impl RegistrationClient {
|
||||
async fn register_mix_exit(self) -> Result<RegistrationResult, RegistrationClientError> {
|
||||
async fn register_mix_exit(self) -> Result<RegistrationResult, RegistrationError> {
|
||||
let entry_mixnet_gateway_ip = self.config.entry.node.ip_address;
|
||||
|
||||
let exit_mixnet_gateway_ip = self.config.exit.node.ip_address;
|
||||
|
||||
let ipr_address = self.config.exit.node.ipr_address.ok_or(
|
||||
RegistrationClientError::NoIpPacketRouterAddress {
|
||||
node_id: self.config.exit.node.identity.to_base58_string(),
|
||||
},
|
||||
)?;
|
||||
let Some(ipr_address) = self.config.exit.node.ipr_address else {
|
||||
return Err(RegistrationError {
|
||||
mixnet_client: Some(self.mixnet_client),
|
||||
source: RegistrationClientError::NoIpPacketRouterAddress {
|
||||
node_id: self.config.exit.node.identity.to_base58_string(),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
let mut ipr_client =
|
||||
IprClientConnect::new(self.mixnet_client, self.cancel_token.clone()).await;
|
||||
let interface_addresses = ipr_client
|
||||
.connect(ipr_address)
|
||||
IprClientConnect::new(self.mixnet_client, self.cancel_token.child_token());
|
||||
|
||||
let interface_addresses = match self
|
||||
.cancel_token
|
||||
.run_until_cancelled(ipr_client.connect(ipr_address))
|
||||
.await
|
||||
.map_err(RegistrationClientError::ConnectToIpPacketRouter)?;
|
||||
{
|
||||
Some(Ok(addr)) => addr,
|
||||
Some(Err(e)) => {
|
||||
return Err(RegistrationError {
|
||||
mixnet_client: Some(ipr_client.into_mixnet_client()),
|
||||
source: RegistrationClientError::ConnectToIpPacketRouter(e),
|
||||
});
|
||||
}
|
||||
None => {
|
||||
return Err(RegistrationError {
|
||||
mixnet_client: Some(ipr_client.into_mixnet_client()),
|
||||
source: RegistrationClientError::Cancelled,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Ok(RegistrationResult::Mixnet(Box::new(
|
||||
MixnetRegistrationResult {
|
||||
@@ -67,18 +94,24 @@ impl RegistrationClient {
|
||||
)))
|
||||
}
|
||||
|
||||
async fn register_wg(self) -> Result<RegistrationResult, RegistrationClientError> {
|
||||
let entry_auth_address = self.config.entry.node.authenticator_address.ok_or(
|
||||
RegistrationClientError::AuthenticationNotPossible {
|
||||
node_id: self.config.entry.node.identity.to_base58_string(),
|
||||
},
|
||||
)?;
|
||||
async fn register_wg(self) -> Result<RegistrationResult, RegistrationError> {
|
||||
let Some(entry_auth_address) = self.config.entry.node.authenticator_address else {
|
||||
return Err(RegistrationError {
|
||||
mixnet_client: Some(self.mixnet_client),
|
||||
source: RegistrationClientError::AuthenticationNotPossible {
|
||||
node_id: self.config.entry.node.identity.to_base58_string(),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
let exit_auth_address = self.config.exit.node.authenticator_address.ok_or(
|
||||
RegistrationClientError::AuthenticationNotPossible {
|
||||
node_id: self.config.exit.node.identity.to_base58_string(),
|
||||
},
|
||||
)?;
|
||||
let Some(exit_auth_address) = self.config.exit.node.authenticator_address else {
|
||||
return Err(RegistrationError {
|
||||
mixnet_client: Some(self.mixnet_client),
|
||||
source: RegistrationClientError::AuthenticationNotPossible {
|
||||
node_id: self.config.exit.node.identity.to_base58_string(),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
let entry_version = self.config.entry.node.version;
|
||||
tracing::debug!("Entry gateway version: {entry_version}");
|
||||
@@ -87,8 +120,10 @@ impl RegistrationClient {
|
||||
|
||||
// Start the auth client mixnet listener, which will listen for incoming messages from the
|
||||
// mixnet and rebroadcast them to the auth clients.
|
||||
// From this point on, we don't need to care about the mixnet client anymore
|
||||
let mixnet_listener =
|
||||
AuthClientMixnetListener::new(self.mixnet_client, self.cancel_token.clone()).start();
|
||||
AuthClientMixnetListener::new(self.mixnet_client, self.cancel_token.child_token())
|
||||
.start();
|
||||
|
||||
let mut entry_auth_client = AuthenticatorClient::new(
|
||||
mixnet_listener.subscribe(),
|
||||
@@ -115,24 +150,35 @@ impl RegistrationClient {
|
||||
let exit_fut = exit_auth_client
|
||||
.register_wireguard(&*self.bandwidth_controller, TicketType::V1WireguardExit);
|
||||
|
||||
let (entry, exit) = Box::pin(async { tokio::join!(entry_fut, exit_fut) }).await;
|
||||
let (entry, exit) = Box::pin(
|
||||
self.cancel_token
|
||||
.run_until_cancelled(async { tokio::join!(entry_fut, exit_fut) }),
|
||||
)
|
||||
.await
|
||||
.ok_or(RegistrationError {
|
||||
mixnet_client: None,
|
||||
source: RegistrationClientError::Cancelled,
|
||||
})?;
|
||||
|
||||
let entry =
|
||||
entry.map_err(
|
||||
|source| RegistrationClientError::EntryGatewayRegisterWireguard {
|
||||
gateway_id: self.config.entry.node.identity.to_base58_string(),
|
||||
authenticator_address: Box::new(entry_auth_address),
|
||||
source: Box::new(source),
|
||||
},
|
||||
)?;
|
||||
let exit =
|
||||
exit.map_err(
|
||||
|source| RegistrationClientError::ExitGatewayRegisterWireguard {
|
||||
gateway_id: self.config.exit.node.identity.to_base58_string(),
|
||||
authenticator_address: Box::new(exit_auth_address),
|
||||
source: Box::new(source),
|
||||
},
|
||||
)?;
|
||||
let entry = entry.map_err(|source| RegistrationError {
|
||||
mixnet_client: None,
|
||||
source: RegistrationClientError::from_authenticator_error(
|
||||
source,
|
||||
self.config.entry.node.identity.to_base58_string(),
|
||||
entry_auth_address,
|
||||
true,
|
||||
),
|
||||
})?;
|
||||
|
||||
let exit = exit.map_err(|source| RegistrationError {
|
||||
mixnet_client: None,
|
||||
source: RegistrationClientError::from_authenticator_error(
|
||||
source,
|
||||
self.config.exit.node.identity.to_base58_string(),
|
||||
exit_auth_address,
|
||||
false,
|
||||
),
|
||||
})?;
|
||||
|
||||
Ok(RegistrationResult::Wireguard(Box::new(
|
||||
WireguardRegistrationResult {
|
||||
@@ -147,16 +193,23 @@ impl RegistrationClient {
|
||||
}
|
||||
|
||||
pub async fn register(self) -> Result<RegistrationResult, RegistrationClientError> {
|
||||
self.cancel_token
|
||||
.clone()
|
||||
.run_until_cancelled(async {
|
||||
if self.config.two_hops {
|
||||
self.register_wg().await
|
||||
} else {
|
||||
self.register_mix_exit().await
|
||||
let registration_result = if self.config.two_hops {
|
||||
self.register_wg().await
|
||||
} else {
|
||||
self.register_mix_exit().await
|
||||
};
|
||||
|
||||
// If we failed to register, and we were the owner of the mixnet client, shut it down
|
||||
match registration_result {
|
||||
Ok(result) => Ok(result),
|
||||
Err(error) => {
|
||||
debug!("Registration failed");
|
||||
if let Some(mixnet_client) = error.mixnet_client {
|
||||
debug!("Shutting down mixnet client");
|
||||
mixnet_client.disconnect().await;
|
||||
}
|
||||
})
|
||||
.await
|
||||
.ok_or(RegistrationClientError::Cancelled)?
|
||||
Err(error.source)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,6 @@
|
||||
"@types/big.js": "^6.1.6",
|
||||
"@types/bs58": "^4.0.1",
|
||||
"@types/jest": "^27.0.1",
|
||||
"@types/minimatch": "5.1.2",
|
||||
"@types/node": "^16.7.13",
|
||||
"@types/qrcode.react": "^1.0.2",
|
||||
"@types/react": "^18.0.26",
|
||||
@@ -132,8 +131,5 @@
|
||||
"webpack-favicons": "^1.3.8",
|
||||
"webpack-merge": "^5.8.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/minimatch": "5.1.2"
|
||||
},
|
||||
"private": false
|
||||
}
|
||||
@@ -1,32 +1,32 @@
|
||||
import React from 'react';
|
||||
import { Box, Typography, Grid, Link, Card, CardContent, Stack } from '@mui/material';
|
||||
import { NymCard } from '..';
|
||||
import BitfinexIcon from 'src/svg-icons/bitfinex.svg';
|
||||
import KrakenIcon from 'src/svg-icons/kraken.svg';
|
||||
import BybitIcon from 'src/svg-icons/bybit.svg';
|
||||
import GateIcon from 'src/svg-icons/gate22.svg';
|
||||
import HTXIcon from 'src/svg-icons/htx.svg';
|
||||
import { NymCard } from '..';
|
||||
|
||||
const ExchangeCard = ({
|
||||
name,
|
||||
tokenType,
|
||||
url,
|
||||
IconComponent,
|
||||
const ExchangeCard = ({
|
||||
name,
|
||||
tokenType,
|
||||
url,
|
||||
IconComponent
|
||||
}: {
|
||||
name: string;
|
||||
tokenType: string;
|
||||
url: string;
|
||||
IconComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
|
||||
}) => (
|
||||
<Card
|
||||
variant="outlined"
|
||||
sx={{
|
||||
<Card
|
||||
variant="outlined"
|
||||
sx={{
|
||||
height: '100%',
|
||||
transition: 'all 0.2s ease-in-out',
|
||||
'&:hover': {
|
||||
transform: 'translateY(-2px)',
|
||||
boxShadow: 2,
|
||||
},
|
||||
}
|
||||
}}
|
||||
>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
@@ -51,17 +51,17 @@ const ExchangeCard = ({
|
||||
<Typography variant="body2" sx={{ color: 'text.secondary' }}>
|
||||
{tokenType}
|
||||
</Typography>
|
||||
<Link
|
||||
href={url}
|
||||
target="_blank"
|
||||
<Link
|
||||
href={url}
|
||||
target="_blank"
|
||||
variant="body2"
|
||||
data-testid="link-get-nym"
|
||||
sx={{
|
||||
sx={{
|
||||
textDecoration: 'underline',
|
||||
fontWeight: 500,
|
||||
'&:hover': {
|
||||
textDecoration: 'none',
|
||||
},
|
||||
}
|
||||
}}
|
||||
>
|
||||
GET NYM
|
||||
@@ -78,40 +78,44 @@ export const Tutorial = () => {
|
||||
name: 'Bitfinex',
|
||||
tokenType: 'Native NYM, ERC-20',
|
||||
url: 'https://www.bitfinex.com/',
|
||||
IconComponent: BitfinexIcon,
|
||||
IconComponent: BitfinexIcon
|
||||
},
|
||||
{
|
||||
name: 'Kraken',
|
||||
tokenType: 'Native NYM',
|
||||
url: 'https://www.kraken.com/',
|
||||
IconComponent: KrakenIcon,
|
||||
IconComponent: KrakenIcon
|
||||
},
|
||||
{
|
||||
name: 'Bybit',
|
||||
tokenType: 'ERC-20',
|
||||
url: 'https://www.bybit.com/en/',
|
||||
IconComponent: BybitIcon,
|
||||
IconComponent: BybitIcon
|
||||
},
|
||||
{
|
||||
name: 'Gate.io',
|
||||
tokenType: 'ERC-20',
|
||||
url: 'https://www.gate.io/',
|
||||
IconComponent: GateIcon,
|
||||
IconComponent: GateIcon
|
||||
},
|
||||
{
|
||||
name: 'HTX',
|
||||
tokenType: 'ERC-20',
|
||||
url: 'https://www.htx.com/',
|
||||
IconComponent: HTXIcon,
|
||||
IconComponent: HTXIcon
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<NymCard borderless title="Where you can get NYM tokens" sx={{ mt: 4 }}>
|
||||
<NymCard
|
||||
borderless
|
||||
title="Where you can get NYM tokens"
|
||||
sx={{ mt: 4 }}
|
||||
>
|
||||
<Typography mb={3} fontSize={14} sx={{ color: 'text.secondary' }}>
|
||||
You can get NYM tokens from these exchanges
|
||||
</Typography>
|
||||
|
||||
|
||||
<Grid container spacing={3}>
|
||||
{exchanges.map((exchange) => (
|
||||
<Grid item xs={12} md={6} lg={4} key={exchange.name}>
|
||||
|
||||
+40
-41
@@ -1,41 +1,49 @@
|
||||
{
|
||||
"name": "@nymproject/nymsphere",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"license": "Apache 2.0",
|
||||
"workspaces": [
|
||||
"sdk/typescript/packages/**",
|
||||
"sdk/typescript/examples/**",
|
||||
"ts-packages/*",
|
||||
"nym-wallet",
|
||||
"explorer-nextjs",
|
||||
"explorer-v2",
|
||||
"types",
|
||||
"clients/validator",
|
||||
"sdk/typescript/packages/**",
|
||||
"sdk/typescript/examples/**",
|
||||
"sdk/typescript/codegen/**"
|
||||
],
|
||||
"scripts": {
|
||||
"audit:fix": "npm_config_yes=true npx yarn-audit-fix -- --dry-run",
|
||||
"nuke": "npx rimraf **/node_modules node_modules",
|
||||
"scrub": "npx rimraf **/dist dist",
|
||||
"clean": "lerna run clean",
|
||||
"build": "run-s build:types build:packages",
|
||||
"build:ci": "run-s build:types build:packages build:wasm build:ci:sdk",
|
||||
"build:ci:sdk": "lerna run --scope '{@nymproject/sdk,@nymproject/node-tester,@nymproject/sdk-react,@nymproject/mix-fetch,@nymproject/nodejs-client,@nymproject/mix-fetch-node}' build --stream",
|
||||
"build:wasm": "make sdk-wasm-build",
|
||||
"build:types": "lerna run --scope @nymproject/types build --stream",
|
||||
"build:packages": "run-s build:packages:theme build:packages:react",
|
||||
"build:packages:theme": "lerna run --scope @nymproject/mui-theme build",
|
||||
"build:packages:react": "lerna run --scope @nymproject/react build",
|
||||
"build:playground": "lerna run --scope @nymproject/react storybook:build --stream",
|
||||
"build:ci:storybook": "yarn build && yarn dev:on && run-p build:playground && yarn build:ci:storybook:collect-artifacts ",
|
||||
"build:ci:storybook:collect-artifacts": "mkdir -p ts-packages/dist && mv sdk/typescript/packages/react-components/storybook-static ts-packages/dist/storybook ",
|
||||
"build:packages": "run-s build:packages:theme build:packages:react",
|
||||
"build:packages:react": "lerna run --scope @nymproject/react build",
|
||||
"build:packages:theme": "lerna run --scope @nymproject/mui-theme build",
|
||||
"build:playground": "lerna run --scope @nymproject/react storybook:build --stream",
|
||||
"build:types": "lerna run --scope @nymproject/types build --stream",
|
||||
"build:wasm": "make sdk-wasm-build",
|
||||
"clean": "lerna run clean",
|
||||
"dev:off": "node sdk/typescript/scripts/dev-mode-remove.mjs",
|
||||
"dev:on": "node sdk/typescript/scripts/dev-mode-add.mjs",
|
||||
"prebuild:ci": "yarn dev:on && yarn",
|
||||
"build:ci": "run-s build:types build:packages build:wasm build:ci:sdk",
|
||||
"postbuild:ci": "yarn dev:off",
|
||||
"build:ci:sdk": "lerna run --scope '{@nymproject/sdk,@nymproject/node-tester,@nymproject/sdk-react,@nymproject/mix-fetch,@nymproject/nodejs-client,@nymproject/mix-fetch-node}' build --stream",
|
||||
"docs:prod:build": "run-s docs:prod:build:ws",
|
||||
"docs:prod:build:ws": "lerna run docs:prod:build --stream",
|
||||
"lint": "lerna run lint --stream",
|
||||
"lint:fix": "lerna run lint:fix --stream",
|
||||
"nuke": "npx rimraf **/node_modules node_modules",
|
||||
"postbuild:ci": "yarn dev:off",
|
||||
"prebuild:ci": "yarn dev:on && yarn",
|
||||
"scrub": "npx rimraf **/dist dist",
|
||||
"sdk:build": "./sdk/typescript/scripts/build-prod-sdk.sh",
|
||||
"sdk:publish": "./sdk/typescript/scripts/publish.sh",
|
||||
"sdk:versions:add-rc": "cargo run -p sdk-version-bump --pre-release",
|
||||
"sdk:versions:bump": "cargo run -p sdk-version-bump bump-version",
|
||||
"sdk:versions:remove-rc": "cargo run -p sdk-version-bump remove-suffix",
|
||||
"lint": "lerna run lint --stream",
|
||||
"lint:fix": "lerna run lint:fix --stream",
|
||||
"tsc": "lerna run tsc --stream",
|
||||
"types:lint:fix": "lerna run lint:fix --scope @nymproject/types --scope @nymproject/nym-wallet-app"
|
||||
},
|
||||
"dependencies": {
|
||||
"lucide-react": "^0.453.0"
|
||||
"types:lint:fix": "lerna run lint:fix --scope @nymproject/types --scope @nymproject/nym-wallet-app",
|
||||
"audit:fix": "npm_config_yes=true npx yarn-audit-fix -- --dry-run",
|
||||
"dev:on": "node sdk/typescript/scripts/dev-mode-add.mjs",
|
||||
"dev:off": "node sdk/typescript/scripts/dev-mode-remove.mjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@npmcli/node-gyp": "^3.0.0",
|
||||
@@ -45,23 +53,14 @@
|
||||
"npm-run-all": "^4.1.5",
|
||||
"tslog": "3.3.3"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"lucide-react": "^0.453.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"@cosmjs/amino": "^0.32.4",
|
||||
"@cosmjs/cosmwasm-stargate": "^0.32.4",
|
||||
"@cosmjs/proto-signing": "^0.32.4",
|
||||
"@cosmjs/stargate": "^0.32.4",
|
||||
"@cosmjs/cosmwasm-stargate": "^0.32.4",
|
||||
"cosmjs-types": "^0.9.0"
|
||||
},
|
||||
"workspaces": [
|
||||
"ts-packages/*",
|
||||
"nym-wallet",
|
||||
"explorer-nextjs",
|
||||
"explorer-v2",
|
||||
"types",
|
||||
"clients/validator",
|
||||
"sdk/typescript/packages/mix-fetch/internal-dev",
|
||||
"sdk/typescript/packages/react-components",
|
||||
"sdk/typescript/packages/mui-theme"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -736,15 +736,11 @@ where
|
||||
base_builder = base_builder.with_topology_provider(topology_provider);
|
||||
}
|
||||
|
||||
// Use custom shutdown if provided, otherwise get from registry
|
||||
let shutdown_tracker = match self.custom_shutdown {
|
||||
Some(custom) => custom,
|
||||
None => {
|
||||
// Auto-create from registry for SDK use
|
||||
nym_task::get_sdk_shutdown_tracker()?
|
||||
}
|
||||
};
|
||||
base_builder = base_builder.with_shutdown(shutdown_tracker);
|
||||
// Use custom shutdown if provided, otherwise the sdk one will be used later down the line
|
||||
if let Some(shutdown_tracker) = self.custom_shutdown {
|
||||
base_builder = base_builder.with_shutdown(shutdown_tracker);
|
||||
}
|
||||
|
||||
if let Some(event_tx) = self.event_tx {
|
||||
base_builder = base_builder.with_event_tx(event_tx);
|
||||
}
|
||||
@@ -809,7 +805,7 @@ where
|
||||
client_output,
|
||||
client_state.clone(),
|
||||
nym_address,
|
||||
started_client.shutdown_handle.child_tracker(),
|
||||
started_client.shutdown_handle.clone(),
|
||||
packet_type,
|
||||
);
|
||||
|
||||
|
||||
@@ -3,11 +3,13 @@ import codegen from '@cosmwasm/ts-codegen';
|
||||
codegen
|
||||
.default({
|
||||
contracts: [
|
||||
{ name: 'ecash', dir: '../../../../contracts/ecash' },
|
||||
{ name: 'coconut-bandwidth', dir: '../../../../contracts/coconut-bandwidth' },
|
||||
{ name: 'coconut-dkg', dir: '../../../../contracts/coconut-dkg' },
|
||||
{ name: 'mixnet', dir: '../../../../contracts/mixnet' },
|
||||
{ name: 'cw3-flex-multisig', dir: '../../../../contracts/multisig/cw3-flex-multisig' },
|
||||
{ name: 'cw4-group', dir: '../../../../contracts/multisig/cw4-group' },
|
||||
{ name: 'name-service', dir: '../../../../contracts/name-service' },
|
||||
{ name: 'service-provider-directory', dir: '../../../../contracts/service-provider-directory' },
|
||||
{ name: 'vesting', dir: '../../../../contracts/vesting' },
|
||||
],
|
||||
outPath: './src',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/contract-clients",
|
||||
"version": "1.3.1-rc0",
|
||||
"version": "1.3.0-rc.0",
|
||||
"description": "A client for all Nym smart contracts",
|
||||
"license": "Apache-2.0",
|
||||
"author": "Nym Technologies SA",
|
||||
@@ -18,7 +18,7 @@
|
||||
"docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"yarn docs:generate\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cosmwasm/ts-codegen": "^1.13.3",
|
||||
"@cosmwasm/ts-codegen": "^0.35.3",
|
||||
"nodemon": "3.0.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"reload": "^3.2.1",
|
||||
@@ -27,4 +27,4 @@
|
||||
},
|
||||
"private": false,
|
||||
"types": "./dist/index.d.ts"
|
||||
}
|
||||
}
|
||||
@@ -1,58 +1,23 @@
|
||||
/**
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@1.13.3.
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
|
||||
import { ICosmWasmClient, ISigningCosmWasmClient } from "./baseClient";
|
||||
import { Coin, StdFee } from "@interchainjs/types";
|
||||
import { InstantiateMsg, TimeConfiguration, ExecuteMsg, ContractSafeBytes, DealingChunkInfo, PartialContractDealing, QueryMsg, MigrateMsg, EpochState, Timestamp, Uint64, StateAdvanceResponse, StateProgress, ContractVersion, Addr, PagedDealerResponse, DealerDetails, Epoch, DealerDealingsStatusResponse, DealerType, DealerDetailsResponse, PagedDealerIndexResponse, DealingChunkResponse, DealingChunkStatusResponse, ChunkSubmissionStatus, DealingStatusResponse, DealingStatus, DealingMetadataResponse, DealingMetadata, PagedDealerAddressesResponse, NullableEpoch, RegisteredDealerDetails, DealerRegistrationDetails, Cw4Contract, State, VkShareResponse, ContractVKShare, PagedVKSharesResponse } from "./CoconutDkg.types";
|
||||
import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate";
|
||||
import { Coin, StdFee } from "@cosmjs/amino";
|
||||
import { InstantiateMsg, TimeConfiguration, ExecuteMsg, ContractSafeBytes, Addr, QueryMsg, MigrateMsg, PagedDealerResponse, DealerDetails, Timestamp, Uint64, EpochState, Epoch, DealerType, DealerDetailsResponse, PagedDealingsResponse, ContractDealing, NullableInitialReplacementData, InitialReplacementData, PagedVKSharesResponse, ContractVKShare } from "./CoconutDkg.types";
|
||||
|
||||
export interface CoconutDkgReadOnlyInterface {
|
||||
contractAddress: string;
|
||||
getState: () => Promise<State>;
|
||||
getCurrentEpochState: () => Promise<Epoch>;
|
||||
getEpochStateAtHeight: ({
|
||||
height
|
||||
}: {
|
||||
height: number;
|
||||
}) => Promise<NullableEpoch>;
|
||||
getCurrentEpochThreshold: () => Promise<Uint64>;
|
||||
getEpochThreshold: ({
|
||||
epochId
|
||||
}: {
|
||||
epochId: number;
|
||||
}) => Promise<Uint64>;
|
||||
canAdvanceState: () => Promise<StateAdvanceResponse>;
|
||||
getRegisteredDealer: ({
|
||||
dealerAddress,
|
||||
epochId
|
||||
}: {
|
||||
dealerAddress: string;
|
||||
epochId?: number;
|
||||
}) => Promise<RegisteredDealerDetails>;
|
||||
getInitialDealers: () => Promise<NullableInitialReplacementData>;
|
||||
getDealerDetails: ({
|
||||
dealerAddress
|
||||
}: {
|
||||
dealerAddress: string;
|
||||
}) => Promise<DealerDetailsResponse>;
|
||||
getEpochDealersAddresses: ({
|
||||
epochId,
|
||||
limit,
|
||||
startAfter
|
||||
}: {
|
||||
epochId: number;
|
||||
limit?: number;
|
||||
startAfter?: string;
|
||||
}) => Promise<PagedDealerAddressesResponse>;
|
||||
getEpochDealers: ({
|
||||
epochId,
|
||||
limit,
|
||||
startAfter
|
||||
}: {
|
||||
epochId: number;
|
||||
limit?: number;
|
||||
startAfter?: string;
|
||||
}) => Promise<PagedDealerResponse>;
|
||||
getCurrentDealers: ({
|
||||
limit,
|
||||
startAfter
|
||||
@@ -60,67 +25,22 @@ export interface CoconutDkgReadOnlyInterface {
|
||||
limit?: number;
|
||||
startAfter?: string;
|
||||
}) => Promise<PagedDealerResponse>;
|
||||
getDealerIndices: ({
|
||||
getPastDealers: ({
|
||||
limit,
|
||||
startAfter
|
||||
}: {
|
||||
limit?: number;
|
||||
startAfter?: string;
|
||||
}) => Promise<PagedDealerIndexResponse>;
|
||||
getDealingsMetadata: ({
|
||||
dealer,
|
||||
dealingIndex,
|
||||
epochId
|
||||
}) => Promise<PagedDealerResponse>;
|
||||
getDealing: ({
|
||||
idx,
|
||||
limit,
|
||||
startAfter
|
||||
}: {
|
||||
dealer: string;
|
||||
dealingIndex: number;
|
||||
epochId: number;
|
||||
}) => Promise<DealingMetadataResponse>;
|
||||
getDealerDealingsStatus: ({
|
||||
dealer,
|
||||
epochId
|
||||
}: {
|
||||
dealer: string;
|
||||
epochId: number;
|
||||
}) => Promise<DealerDealingsStatusResponse>;
|
||||
getDealingStatus: ({
|
||||
dealer,
|
||||
dealingIndex,
|
||||
epochId
|
||||
}: {
|
||||
dealer: string;
|
||||
dealingIndex: number;
|
||||
epochId: number;
|
||||
}) => Promise<DealingStatusResponse>;
|
||||
getDealingChunkStatus: ({
|
||||
chunkIndex,
|
||||
dealer,
|
||||
dealingIndex,
|
||||
epochId
|
||||
}: {
|
||||
chunkIndex: number;
|
||||
dealer: string;
|
||||
dealingIndex: number;
|
||||
epochId: number;
|
||||
}) => Promise<DealingChunkStatusResponse>;
|
||||
getDealingChunk: ({
|
||||
chunkIndex,
|
||||
dealer,
|
||||
dealingIndex,
|
||||
epochId
|
||||
}: {
|
||||
chunkIndex: number;
|
||||
dealer: string;
|
||||
dealingIndex: number;
|
||||
epochId: number;
|
||||
}) => Promise<DealingChunkResponse>;
|
||||
getVerificationKey: ({
|
||||
epochId,
|
||||
owner
|
||||
}: {
|
||||
epochId: number;
|
||||
owner: string;
|
||||
}) => Promise<VkShareResponse>;
|
||||
idx: number;
|
||||
limit?: number;
|
||||
startAfter?: string;
|
||||
}) => Promise<PagedDealingsResponse>;
|
||||
getVerificationKeys: ({
|
||||
epochId,
|
||||
limit,
|
||||
@@ -130,89 +50,37 @@ export interface CoconutDkgReadOnlyInterface {
|
||||
limit?: number;
|
||||
startAfter?: string;
|
||||
}) => Promise<PagedVKSharesResponse>;
|
||||
getCw2ContractVersion: () => Promise<GetCw2ContractVersionResponse>;
|
||||
}
|
||||
export class CoconutDkgQueryClient implements CoconutDkgReadOnlyInterface {
|
||||
client: ICosmWasmClient;
|
||||
client: CosmWasmClient;
|
||||
contractAddress: string;
|
||||
constructor(client: ICosmWasmClient, contractAddress: string) {
|
||||
|
||||
constructor(client: CosmWasmClient, contractAddress: string) {
|
||||
this.client = client;
|
||||
this.contractAddress = contractAddress;
|
||||
this.getState = this.getState.bind(this);
|
||||
this.getCurrentEpochState = this.getCurrentEpochState.bind(this);
|
||||
this.getEpochStateAtHeight = this.getEpochStateAtHeight.bind(this);
|
||||
this.getCurrentEpochThreshold = this.getCurrentEpochThreshold.bind(this);
|
||||
this.getEpochThreshold = this.getEpochThreshold.bind(this);
|
||||
this.canAdvanceState = this.canAdvanceState.bind(this);
|
||||
this.getRegisteredDealer = this.getRegisteredDealer.bind(this);
|
||||
this.getInitialDealers = this.getInitialDealers.bind(this);
|
||||
this.getDealerDetails = this.getDealerDetails.bind(this);
|
||||
this.getEpochDealersAddresses = this.getEpochDealersAddresses.bind(this);
|
||||
this.getEpochDealers = this.getEpochDealers.bind(this);
|
||||
this.getCurrentDealers = this.getCurrentDealers.bind(this);
|
||||
this.getDealerIndices = this.getDealerIndices.bind(this);
|
||||
this.getDealingsMetadata = this.getDealingsMetadata.bind(this);
|
||||
this.getDealerDealingsStatus = this.getDealerDealingsStatus.bind(this);
|
||||
this.getDealingStatus = this.getDealingStatus.bind(this);
|
||||
this.getDealingChunkStatus = this.getDealingChunkStatus.bind(this);
|
||||
this.getDealingChunk = this.getDealingChunk.bind(this);
|
||||
this.getVerificationKey = this.getVerificationKey.bind(this);
|
||||
this.getPastDealers = this.getPastDealers.bind(this);
|
||||
this.getDealing = this.getDealing.bind(this);
|
||||
this.getVerificationKeys = this.getVerificationKeys.bind(this);
|
||||
this.getCw2ContractVersion = this.getCw2ContractVersion.bind(this);
|
||||
}
|
||||
getState = async (): Promise<State> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_state: {}
|
||||
});
|
||||
};
|
||||
|
||||
getCurrentEpochState = async (): Promise<Epoch> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_current_epoch_state: {}
|
||||
});
|
||||
};
|
||||
getEpochStateAtHeight = async ({
|
||||
height
|
||||
}: {
|
||||
height: number;
|
||||
}): Promise<NullableEpoch> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_epoch_state_at_height: {
|
||||
height
|
||||
}
|
||||
});
|
||||
};
|
||||
getCurrentEpochThreshold = async (): Promise<Uint64> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_current_epoch_threshold: {}
|
||||
});
|
||||
};
|
||||
getEpochThreshold = async ({
|
||||
epochId
|
||||
}: {
|
||||
epochId: number;
|
||||
}): Promise<Uint64> => {
|
||||
getInitialDealers = async (): Promise<NullableInitialReplacementData> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_epoch_threshold: {
|
||||
epoch_id: epochId
|
||||
}
|
||||
});
|
||||
};
|
||||
canAdvanceState = async (): Promise<StateAdvanceResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
can_advance_state: {}
|
||||
});
|
||||
};
|
||||
getRegisteredDealer = async ({
|
||||
dealerAddress,
|
||||
epochId
|
||||
}: {
|
||||
dealerAddress: string;
|
||||
epochId?: number;
|
||||
}): Promise<RegisteredDealerDetails> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_registered_dealer: {
|
||||
dealer_address: dealerAddress,
|
||||
epoch_id: epochId
|
||||
}
|
||||
get_initial_dealers: {}
|
||||
});
|
||||
};
|
||||
getDealerDetails = async ({
|
||||
@@ -226,40 +94,6 @@ export class CoconutDkgQueryClient implements CoconutDkgReadOnlyInterface {
|
||||
}
|
||||
});
|
||||
};
|
||||
getEpochDealersAddresses = async ({
|
||||
epochId,
|
||||
limit,
|
||||
startAfter
|
||||
}: {
|
||||
epochId: number;
|
||||
limit?: number;
|
||||
startAfter?: string;
|
||||
}): Promise<PagedDealerAddressesResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_epoch_dealers_addresses: {
|
||||
epoch_id: epochId,
|
||||
limit,
|
||||
start_after: startAfter
|
||||
}
|
||||
});
|
||||
};
|
||||
getEpochDealers = async ({
|
||||
epochId,
|
||||
limit,
|
||||
startAfter
|
||||
}: {
|
||||
epochId: number;
|
||||
limit?: number;
|
||||
startAfter?: string;
|
||||
}): Promise<PagedDealerResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_epoch_dealers: {
|
||||
epoch_id: epochId,
|
||||
limit,
|
||||
start_after: startAfter
|
||||
}
|
||||
});
|
||||
};
|
||||
getCurrentDealers = async ({
|
||||
limit,
|
||||
startAfter
|
||||
@@ -274,119 +108,34 @@ export class CoconutDkgQueryClient implements CoconutDkgReadOnlyInterface {
|
||||
}
|
||||
});
|
||||
};
|
||||
getDealerIndices = async ({
|
||||
getPastDealers = async ({
|
||||
limit,
|
||||
startAfter
|
||||
}: {
|
||||
limit?: number;
|
||||
startAfter?: string;
|
||||
}): Promise<PagedDealerIndexResponse> => {
|
||||
}): Promise<PagedDealerResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_dealer_indices: {
|
||||
get_past_dealers: {
|
||||
limit,
|
||||
start_after: startAfter
|
||||
}
|
||||
});
|
||||
};
|
||||
getDealingsMetadata = async ({
|
||||
dealer,
|
||||
dealingIndex,
|
||||
epochId
|
||||
getDealing = async ({
|
||||
idx,
|
||||
limit,
|
||||
startAfter
|
||||
}: {
|
||||
dealer: string;
|
||||
dealingIndex: number;
|
||||
epochId: number;
|
||||
}): Promise<DealingMetadataResponse> => {
|
||||
idx: number;
|
||||
limit?: number;
|
||||
startAfter?: string;
|
||||
}): Promise<PagedDealingsResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_dealings_metadata: {
|
||||
dealer,
|
||||
dealing_index: dealingIndex,
|
||||
epoch_id: epochId
|
||||
}
|
||||
});
|
||||
};
|
||||
getDealerDealingsStatus = async ({
|
||||
dealer,
|
||||
epochId
|
||||
}: {
|
||||
dealer: string;
|
||||
epochId: number;
|
||||
}): Promise<DealerDealingsStatusResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_dealer_dealings_status: {
|
||||
dealer,
|
||||
epoch_id: epochId
|
||||
}
|
||||
});
|
||||
};
|
||||
getDealingStatus = async ({
|
||||
dealer,
|
||||
dealingIndex,
|
||||
epochId
|
||||
}: {
|
||||
dealer: string;
|
||||
dealingIndex: number;
|
||||
epochId: number;
|
||||
}): Promise<DealingStatusResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_dealing_status: {
|
||||
dealer,
|
||||
dealing_index: dealingIndex,
|
||||
epoch_id: epochId
|
||||
}
|
||||
});
|
||||
};
|
||||
getDealingChunkStatus = async ({
|
||||
chunkIndex,
|
||||
dealer,
|
||||
dealingIndex,
|
||||
epochId
|
||||
}: {
|
||||
chunkIndex: number;
|
||||
dealer: string;
|
||||
dealingIndex: number;
|
||||
epochId: number;
|
||||
}): Promise<DealingChunkStatusResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_dealing_chunk_status: {
|
||||
chunk_index: chunkIndex,
|
||||
dealer,
|
||||
dealing_index: dealingIndex,
|
||||
epoch_id: epochId
|
||||
}
|
||||
});
|
||||
};
|
||||
getDealingChunk = async ({
|
||||
chunkIndex,
|
||||
dealer,
|
||||
dealingIndex,
|
||||
epochId
|
||||
}: {
|
||||
chunkIndex: number;
|
||||
dealer: string;
|
||||
dealingIndex: number;
|
||||
epochId: number;
|
||||
}): Promise<DealingChunkResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_dealing_chunk: {
|
||||
chunk_index: chunkIndex,
|
||||
dealer,
|
||||
dealing_index: dealingIndex,
|
||||
epoch_id: epochId
|
||||
}
|
||||
});
|
||||
};
|
||||
getVerificationKey = async ({
|
||||
epochId,
|
||||
owner
|
||||
}: {
|
||||
epochId: number;
|
||||
owner: string;
|
||||
}): Promise<VkShareResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_verification_key: {
|
||||
epoch_id: epochId,
|
||||
owner
|
||||
get_dealing: {
|
||||
idx,
|
||||
limit,
|
||||
start_after: startAfter
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -407,142 +156,91 @@ export class CoconutDkgQueryClient implements CoconutDkgReadOnlyInterface {
|
||||
}
|
||||
});
|
||||
};
|
||||
getCw2ContractVersion = async (): Promise<GetCw2ContractVersionResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_cw2_contract_version: {}
|
||||
});
|
||||
};
|
||||
}
|
||||
export interface CoconutDkgInterface extends CoconutDkgReadOnlyInterface {
|
||||
contractAddress: string;
|
||||
sender: string;
|
||||
initiateDkg: (fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
registerDealer: ({
|
||||
announceAddress,
|
||||
bteKeyWithProof,
|
||||
identityKey,
|
||||
resharing
|
||||
}: {
|
||||
announceAddress: string;
|
||||
bteKeyWithProof: string;
|
||||
identityKey: string;
|
||||
resharing: boolean;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
commitDealingsMetadata: ({
|
||||
chunks,
|
||||
dealingIndex,
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
commitDealing: ({
|
||||
dealingBytes,
|
||||
resharing
|
||||
}: {
|
||||
chunks: DealingChunkInfo[];
|
||||
dealingIndex: number;
|
||||
dealingBytes: ContractSafeBytes;
|
||||
resharing: boolean;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
commitDealingsChunk: ({
|
||||
chunk
|
||||
}: {
|
||||
chunk: PartialContractDealing;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
commitVerificationKeyShare: ({
|
||||
resharing,
|
||||
share
|
||||
}: {
|
||||
resharing: boolean;
|
||||
share: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
verifyVerificationKeyShare: ({
|
||||
owner,
|
||||
resharing
|
||||
}: {
|
||||
owner: string;
|
||||
owner: Addr;
|
||||
resharing: boolean;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
advanceEpochState: (fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
triggerReset: (fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
triggerResharing: (fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
transferOwnership: ({
|
||||
transferTo
|
||||
}: {
|
||||
transferTo: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
updateAnnounceAddress: ({
|
||||
newAddress
|
||||
}: {
|
||||
newAddress: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
surpassedThreshold: (fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
advanceEpochState: (fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
}
|
||||
export class CoconutDkgClient extends CoconutDkgQueryClient implements CoconutDkgInterface {
|
||||
client: ISigningCosmWasmClient;
|
||||
client: SigningCosmWasmClient;
|
||||
sender: string;
|
||||
contractAddress: string;
|
||||
constructor(client: ISigningCosmWasmClient, sender: string, contractAddress: string) {
|
||||
|
||||
constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) {
|
||||
super(client, contractAddress);
|
||||
this.client = client;
|
||||
this.sender = sender;
|
||||
this.contractAddress = contractAddress;
|
||||
this.initiateDkg = this.initiateDkg.bind(this);
|
||||
this.registerDealer = this.registerDealer.bind(this);
|
||||
this.commitDealingsMetadata = this.commitDealingsMetadata.bind(this);
|
||||
this.commitDealingsChunk = this.commitDealingsChunk.bind(this);
|
||||
this.commitDealing = this.commitDealing.bind(this);
|
||||
this.commitVerificationKeyShare = this.commitVerificationKeyShare.bind(this);
|
||||
this.verifyVerificationKeyShare = this.verifyVerificationKeyShare.bind(this);
|
||||
this.surpassedThreshold = this.surpassedThreshold.bind(this);
|
||||
this.advanceEpochState = this.advanceEpochState.bind(this);
|
||||
this.triggerReset = this.triggerReset.bind(this);
|
||||
this.triggerResharing = this.triggerResharing.bind(this);
|
||||
this.transferOwnership = this.transferOwnership.bind(this);
|
||||
this.updateAnnounceAddress = this.updateAnnounceAddress.bind(this);
|
||||
}
|
||||
initiateDkg = async (fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
initiate_dkg: {}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
|
||||
registerDealer = async ({
|
||||
announceAddress,
|
||||
bteKeyWithProof,
|
||||
identityKey,
|
||||
resharing
|
||||
}: {
|
||||
announceAddress: string;
|
||||
bteKeyWithProof: string;
|
||||
identityKey: string;
|
||||
resharing: boolean;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
register_dealer: {
|
||||
announce_address: announceAddress,
|
||||
bte_key_with_proof: bteKeyWithProof,
|
||||
identity_key: identityKey,
|
||||
resharing
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
commitDealingsMetadata = async ({
|
||||
chunks,
|
||||
dealingIndex,
|
||||
commitDealing = async ({
|
||||
dealingBytes,
|
||||
resharing
|
||||
}: {
|
||||
chunks: DealingChunkInfo[];
|
||||
dealingIndex: number;
|
||||
dealingBytes: ContractSafeBytes;
|
||||
resharing: boolean;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
commit_dealings_metadata: {
|
||||
chunks,
|
||||
dealing_index: dealingIndex,
|
||||
commit_dealing: {
|
||||
dealing_bytes: dealingBytes,
|
||||
resharing
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
commitDealingsChunk = async ({
|
||||
chunk
|
||||
}: {
|
||||
chunk: PartialContractDealing;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
commit_dealings_chunk: {
|
||||
chunk
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
commitVerificationKeyShare = async ({
|
||||
resharing,
|
||||
@@ -550,63 +248,36 @@ export class CoconutDkgClient extends CoconutDkgQueryClient implements CoconutDk
|
||||
}: {
|
||||
resharing: boolean;
|
||||
share: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
commit_verification_key_share: {
|
||||
resharing,
|
||||
share
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
verifyVerificationKeyShare = async ({
|
||||
owner,
|
||||
resharing
|
||||
}: {
|
||||
owner: string;
|
||||
owner: Addr;
|
||||
resharing: boolean;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
verify_verification_key_share: {
|
||||
owner,
|
||||
resharing
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
advanceEpochState = async (fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
surpassedThreshold = async (fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
surpassed_threshold: {}
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
advanceEpochState = async (fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
advance_epoch_state: {}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
triggerReset = async (fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
trigger_reset: {}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
triggerResharing = async (fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
trigger_resharing: {}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
transferOwnership = async ({
|
||||
transferTo
|
||||
}: {
|
||||
transferTo: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
transfer_ownership: {
|
||||
transfer_to: transferTo
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
updateAnnounceAddress = async ({
|
||||
newAddress
|
||||
}: {
|
||||
newAddress: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
update_announce_address: {
|
||||
new_address: newAddress
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
/**
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@1.13.3.
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
|
||||
export interface InstantiateMsg {
|
||||
group_addr: string;
|
||||
key_size: number;
|
||||
mix_denom: string;
|
||||
multisig_addr: string;
|
||||
time_configuration?: TimeConfiguration | null;
|
||||
@@ -20,24 +19,16 @@ export interface TimeConfiguration {
|
||||
verification_key_validation_time_secs: number;
|
||||
}
|
||||
export type ExecuteMsg = {
|
||||
initiate_dkg: {};
|
||||
} | {
|
||||
register_dealer: {
|
||||
announce_address: string;
|
||||
bte_key_with_proof: string;
|
||||
identity_key: string;
|
||||
resharing: boolean;
|
||||
};
|
||||
} | {
|
||||
commit_dealings_metadata: {
|
||||
chunks: DealingChunkInfo[];
|
||||
dealing_index: number;
|
||||
commit_dealing: {
|
||||
dealing_bytes: ContractSafeBytes;
|
||||
resharing: boolean;
|
||||
};
|
||||
} | {
|
||||
commit_dealings_chunk: {
|
||||
chunk: PartialContractDealing;
|
||||
};
|
||||
} | {
|
||||
commit_verification_key_share: {
|
||||
resharing: boolean;
|
||||
@@ -45,115 +36,41 @@ export type ExecuteMsg = {
|
||||
};
|
||||
} | {
|
||||
verify_verification_key_share: {
|
||||
owner: string;
|
||||
owner: Addr;
|
||||
resharing: boolean;
|
||||
};
|
||||
} | {
|
||||
surpassed_threshold: {};
|
||||
} | {
|
||||
advance_epoch_state: {};
|
||||
} | {
|
||||
trigger_reset: {};
|
||||
} | {
|
||||
trigger_resharing: {};
|
||||
} | {
|
||||
transfer_ownership: {
|
||||
transfer_to: string;
|
||||
};
|
||||
} | {
|
||||
update_announce_address: {
|
||||
new_address: string;
|
||||
};
|
||||
};
|
||||
export type ContractSafeBytes = number[];
|
||||
export interface DealingChunkInfo {
|
||||
size: number;
|
||||
}
|
||||
export interface PartialContractDealing {
|
||||
chunk_index: number;
|
||||
data: ContractSafeBytes;
|
||||
dealing_index: number;
|
||||
}
|
||||
export type Addr = string;
|
||||
export type QueryMsg = {
|
||||
get_state: {};
|
||||
} | {
|
||||
get_current_epoch_state: {};
|
||||
} | {
|
||||
get_epoch_state_at_height: {
|
||||
height: number;
|
||||
};
|
||||
} | {
|
||||
get_current_epoch_threshold: {};
|
||||
} | {
|
||||
get_epoch_threshold: {
|
||||
epoch_id: number;
|
||||
};
|
||||
} | {
|
||||
can_advance_state: {};
|
||||
} | {
|
||||
get_registered_dealer: {
|
||||
dealer_address: string;
|
||||
epoch_id?: number | null;
|
||||
};
|
||||
get_initial_dealers: {};
|
||||
} | {
|
||||
get_dealer_details: {
|
||||
dealer_address: string;
|
||||
};
|
||||
} | {
|
||||
get_epoch_dealers_addresses: {
|
||||
epoch_id: number;
|
||||
limit?: number | null;
|
||||
start_after?: string | null;
|
||||
};
|
||||
} | {
|
||||
get_epoch_dealers: {
|
||||
epoch_id: number;
|
||||
limit?: number | null;
|
||||
start_after?: string | null;
|
||||
};
|
||||
} | {
|
||||
get_current_dealers: {
|
||||
limit?: number | null;
|
||||
start_after?: string | null;
|
||||
};
|
||||
} | {
|
||||
get_dealer_indices: {
|
||||
get_past_dealers: {
|
||||
limit?: number | null;
|
||||
start_after?: string | null;
|
||||
};
|
||||
} | {
|
||||
get_dealings_metadata: {
|
||||
dealer: string;
|
||||
dealing_index: number;
|
||||
epoch_id: number;
|
||||
};
|
||||
} | {
|
||||
get_dealer_dealings_status: {
|
||||
dealer: string;
|
||||
epoch_id: number;
|
||||
};
|
||||
} | {
|
||||
get_dealing_status: {
|
||||
dealer: string;
|
||||
dealing_index: number;
|
||||
epoch_id: number;
|
||||
};
|
||||
} | {
|
||||
get_dealing_chunk_status: {
|
||||
chunk_index: number;
|
||||
dealer: string;
|
||||
dealing_index: number;
|
||||
epoch_id: number;
|
||||
};
|
||||
} | {
|
||||
get_dealing_chunk: {
|
||||
chunk_index: number;
|
||||
dealer: string;
|
||||
dealing_index: number;
|
||||
epoch_id: number;
|
||||
};
|
||||
} | {
|
||||
get_verification_key: {
|
||||
epoch_id: number;
|
||||
owner: string;
|
||||
get_dealing: {
|
||||
idx: number;
|
||||
limit?: number | null;
|
||||
start_after?: string | null;
|
||||
};
|
||||
} | {
|
||||
get_verification_keys: {
|
||||
@@ -161,11 +78,22 @@ export type QueryMsg = {
|
||||
limit?: number | null;
|
||||
start_after?: string | null;
|
||||
};
|
||||
} | {
|
||||
get_cw2_contract_version: {};
|
||||
};
|
||||
export interface MigrateMsg {}
|
||||
export type EpochState = ("waiting_initialisation" | "in_progress") | {
|
||||
export interface PagedDealerResponse {
|
||||
dealers: DealerDetails[];
|
||||
per_page: number;
|
||||
start_next_after?: Addr | null;
|
||||
}
|
||||
export interface DealerDetails {
|
||||
address: Addr;
|
||||
announce_address: string;
|
||||
assigned_index: number;
|
||||
bte_public_key_with_proof: string;
|
||||
}
|
||||
export type Timestamp = Uint64;
|
||||
export type Uint64 = number;
|
||||
export type EpochState = "in_progress" | {
|
||||
public_key_submission: {
|
||||
resharing: boolean;
|
||||
};
|
||||
@@ -186,132 +114,36 @@ export type EpochState = ("waiting_initialisation" | "in_progress") | {
|
||||
resharing: boolean;
|
||||
};
|
||||
};
|
||||
export type Timestamp = Uint64;
|
||||
export type Uint64 = number;
|
||||
export interface StateAdvanceResponse {
|
||||
current_state: EpochState;
|
||||
deadline?: Timestamp | null;
|
||||
is_complete: boolean;
|
||||
progress: StateProgress;
|
||||
reached_deadline: boolean;
|
||||
}
|
||||
export interface StateProgress {
|
||||
registered_dealers: number;
|
||||
registered_resharing_dealers: number;
|
||||
submitted_dealings: number;
|
||||
submitted_key_shares: number;
|
||||
verified_keys: number;
|
||||
}
|
||||
export interface ContractVersion {
|
||||
contract: string;
|
||||
version: string;
|
||||
}
|
||||
export type Addr = string;
|
||||
export interface PagedDealerResponse {
|
||||
dealers: DealerDetails[];
|
||||
per_page: number;
|
||||
start_next_after?: Addr | null;
|
||||
}
|
||||
export interface DealerDetails {
|
||||
address: Addr;
|
||||
announce_address: string;
|
||||
assigned_index: number;
|
||||
bte_public_key_with_proof: string;
|
||||
ed25519_identity: string;
|
||||
}
|
||||
export interface Epoch {
|
||||
deadline?: Timestamp | null;
|
||||
epoch_id: number;
|
||||
finish_timestamp: Timestamp;
|
||||
state: EpochState;
|
||||
state_progress: StateProgress;
|
||||
time_configuration: TimeConfiguration;
|
||||
}
|
||||
export interface DealerDealingsStatusResponse {
|
||||
all_dealings_fully_submitted: boolean;
|
||||
dealer: Addr;
|
||||
dealing_submission_status: {};
|
||||
epoch_id: number;
|
||||
}
|
||||
export type DealerType = "unknown" | {
|
||||
current: {
|
||||
assigned_index: number;
|
||||
};
|
||||
} | {
|
||||
past: {
|
||||
assigned_index: number;
|
||||
};
|
||||
};
|
||||
export type DealerType = "current" | "past" | "unknown";
|
||||
export interface DealerDetailsResponse {
|
||||
dealer_type: DealerType;
|
||||
details?: DealerDetails | null;
|
||||
}
|
||||
export interface PagedDealerIndexResponse {
|
||||
indices: [Addr, number][];
|
||||
export interface PagedDealingsResponse {
|
||||
dealings: ContractDealing[];
|
||||
per_page: number;
|
||||
start_next_after?: Addr | null;
|
||||
}
|
||||
export interface DealingChunkResponse {
|
||||
chunk?: ContractSafeBytes | null;
|
||||
chunk_index: number;
|
||||
export interface ContractDealing {
|
||||
dealer: Addr;
|
||||
dealing_index: number;
|
||||
epoch_id: number;
|
||||
dealing: ContractSafeBytes;
|
||||
}
|
||||
export interface DealingChunkStatusResponse {
|
||||
chunk_index: number;
|
||||
dealer: Addr;
|
||||
dealing_index: number;
|
||||
epoch_id: number;
|
||||
status: ChunkSubmissionStatus;
|
||||
export type NullableInitialReplacementData = InitialReplacementData | null;
|
||||
export interface InitialReplacementData {
|
||||
initial_dealers: Addr[];
|
||||
initial_height: number;
|
||||
}
|
||||
export interface ChunkSubmissionStatus {
|
||||
submission_height?: number | null;
|
||||
}
|
||||
export interface DealingStatusResponse {
|
||||
dealer: Addr;
|
||||
dealing_index: number;
|
||||
epoch_id: number;
|
||||
status: DealingStatus;
|
||||
}
|
||||
export interface DealingStatus {
|
||||
chunk_submission_status: {};
|
||||
fully_submitted: boolean;
|
||||
has_metadata: boolean;
|
||||
}
|
||||
export interface DealingMetadataResponse {
|
||||
dealer: Addr;
|
||||
dealing_index: number;
|
||||
epoch_id: number;
|
||||
metadata?: DealingMetadata | null;
|
||||
}
|
||||
export interface DealingMetadata {
|
||||
dealing_index: number;
|
||||
submitted_chunks: {};
|
||||
}
|
||||
export interface PagedDealerAddressesResponse {
|
||||
dealers: Addr[];
|
||||
export interface PagedVKSharesResponse {
|
||||
per_page: number;
|
||||
shares: ContractVKShare[];
|
||||
start_next_after?: Addr | null;
|
||||
}
|
||||
export type NullableEpoch = Epoch | null;
|
||||
export interface RegisteredDealerDetails {
|
||||
details?: DealerRegistrationDetails | null;
|
||||
}
|
||||
export interface DealerRegistrationDetails {
|
||||
announce_address: string;
|
||||
bte_public_key_with_proof: string;
|
||||
ed25519_identity: string;
|
||||
}
|
||||
export type Cw4Contract = Addr;
|
||||
export interface State {
|
||||
group_addr: Cw4Contract;
|
||||
key_size: number;
|
||||
mix_denom: string;
|
||||
multisig_addr: Addr;
|
||||
}
|
||||
export interface VkShareResponse {
|
||||
epoch_id: number;
|
||||
owner: Addr;
|
||||
share?: ContractVKShare | null;
|
||||
}
|
||||
export interface ContractVKShare {
|
||||
announce_address: string;
|
||||
epoch_id: number;
|
||||
@@ -319,9 +151,4 @@ export interface ContractVKShare {
|
||||
owner: Addr;
|
||||
share: string;
|
||||
verified: boolean;
|
||||
}
|
||||
export interface PagedVKSharesResponse {
|
||||
per_page: number;
|
||||
shares: ContractVKShare[];
|
||||
start_next_after?: Addr | null;
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
/**
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@1.13.3.
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
|
||||
import { ICosmWasmClient, ISigningCosmWasmClient } from "./baseClient";
|
||||
import { StdFee } from "@interchainjs/types";
|
||||
import { Executor, Addr, Duration, Uint128, UncheckedDenom, Threshold, Decimal, InstantiateMsg, UncheckedDepositInfo, ExecuteMsg, Expiration, Timestamp, Uint64, CosmosMsgForEmpty, BankMsg, WasmMsg, Binary, Vote, Coin, Empty, MemberChangedHookMsg, MemberDiff, QueryMsg, MigrateMsg, Cw4Contract, Denom, Config, DepositInfo, Status, ThresholdResponse, ProposalListResponseForEmpty, ProposalResponseForEmpty, VoterListResponse, VoterDetail, VoteListResponse, VoteInfo, VoteResponse, VoterResponse } from "./Cw3FlexMultisig.types";
|
||||
import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate";
|
||||
import { StdFee } from "@cosmjs/amino";
|
||||
import { Executor, Addr, Duration, Uint128, UncheckedDenom, Threshold, Decimal, InstantiateMsg, UncheckedDepositInfo, ExecuteMsg, Expiration, Timestamp, Uint64, CosmosMsgForEmpty, BankMsg, StakingMsg, DistributionMsg, Binary, IbcMsg, WasmMsg, GovMsg, VoteOption, Vote, Coin, Empty, IbcTimeout, IbcTimeoutBlock, MemberChangedHookMsg, MemberDiff, QueryMsg, MigrateMsg, Cw4Contract, Denom, Config, DepositInfo, Status, ThresholdResponse, ProposalListResponseForEmpty, ProposalResponseForEmpty, VoterListResponse, VoterDetail, VoteListResponse, VoteInfo, VoteResponse, VoterResponse } from "./Cw3FlexMultisig.types";
|
||||
|
||||
export interface Cw3FlexMultisigReadOnlyInterface {
|
||||
contractAddress: string;
|
||||
threshold: () => Promise<ThresholdResponse>;
|
||||
@@ -60,9 +61,10 @@ export interface Cw3FlexMultisigReadOnlyInterface {
|
||||
config: () => Promise<Config>;
|
||||
}
|
||||
export class Cw3FlexMultisigQueryClient implements Cw3FlexMultisigReadOnlyInterface {
|
||||
client: ICosmWasmClient;
|
||||
client: CosmWasmClient;
|
||||
contractAddress: string;
|
||||
constructor(client: ICosmWasmClient, contractAddress: string) {
|
||||
|
||||
constructor(client: CosmWasmClient, contractAddress: string) {
|
||||
this.client = client;
|
||||
this.contractAddress = contractAddress;
|
||||
this.threshold = this.threshold.bind(this);
|
||||
@@ -75,6 +77,7 @@ export class Cw3FlexMultisigQueryClient implements Cw3FlexMultisigReadOnlyInterf
|
||||
this.listVoters = this.listVoters.bind(this);
|
||||
this.config = this.config.bind(this);
|
||||
}
|
||||
|
||||
threshold = async (): Promise<ThresholdResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
threshold: {}
|
||||
@@ -194,35 +197,36 @@ export interface Cw3FlexMultisigInterface extends Cw3FlexMultisigReadOnlyInterfa
|
||||
latest?: Expiration;
|
||||
msgs: CosmosMsgForEmpty[];
|
||||
title: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
vote: ({
|
||||
proposalId,
|
||||
vote
|
||||
}: {
|
||||
proposalId: number;
|
||||
vote: Vote;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
// vote: ({
|
||||
// proposalId,
|
||||
// vote
|
||||
// }: {
|
||||
// proposalId: number;
|
||||
// vote: Vote;
|
||||
// }, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
execute: ({
|
||||
proposalId
|
||||
}: {
|
||||
proposalId: number;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
close: ({
|
||||
proposalId
|
||||
}: {
|
||||
proposalId: number;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
memberChangedHook: ({
|
||||
diffs
|
||||
}: {
|
||||
diffs: MemberDiff[];
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
}
|
||||
export class Cw3FlexMultisigClient extends Cw3FlexMultisigQueryClient implements Cw3FlexMultisigInterface {
|
||||
client: ISigningCosmWasmClient;
|
||||
client: SigningCosmWasmClient;
|
||||
sender: string;
|
||||
contractAddress: string;
|
||||
constructor(client: ISigningCosmWasmClient, sender: string, contractAddress: string) {
|
||||
|
||||
constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) {
|
||||
super(client, contractAddress);
|
||||
this.client = client;
|
||||
this.sender = sender;
|
||||
@@ -233,6 +237,7 @@ export class Cw3FlexMultisigClient extends Cw3FlexMultisigQueryClient implements
|
||||
this.close = this.close.bind(this);
|
||||
this.memberChangedHook = this.memberChangedHook.bind(this);
|
||||
}
|
||||
|
||||
propose = async ({
|
||||
description,
|
||||
latest,
|
||||
@@ -243,7 +248,7 @@ export class Cw3FlexMultisigClient extends Cw3FlexMultisigQueryClient implements
|
||||
latest?: Expiration;
|
||||
msgs: CosmosMsgForEmpty[];
|
||||
title: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
propose: {
|
||||
description,
|
||||
@@ -251,53 +256,53 @@ export class Cw3FlexMultisigClient extends Cw3FlexMultisigQueryClient implements
|
||||
msgs,
|
||||
title
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
vote = async ({
|
||||
proposalId,
|
||||
vote
|
||||
}: {
|
||||
proposalId: number;
|
||||
vote: Vote;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
vote: {
|
||||
proposal_id: proposalId,
|
||||
vote
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
// vote = async ({
|
||||
// proposalId,
|
||||
// vote
|
||||
// }: {
|
||||
// proposalId: number;
|
||||
// vote: Vote;
|
||||
// }, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
// return await this.client.execute(this.sender, this.contractAddress, {
|
||||
// vote: {
|
||||
// proposal_id: proposalId,
|
||||
// vote
|
||||
// }
|
||||
// }, fee, memo, _funds);
|
||||
// };
|
||||
execute = async ({
|
||||
proposalId
|
||||
}: {
|
||||
proposalId: number;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
execute: {
|
||||
proposal_id: proposalId
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
close = async ({
|
||||
proposalId
|
||||
}: {
|
||||
proposalId: number;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
close: {
|
||||
proposal_id: proposalId
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
memberChangedHook = async ({
|
||||
diffs
|
||||
}: {
|
||||
diffs: MemberDiff[];
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
member_changed_hook: {
|
||||
diffs
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@1.13.3.
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
@@ -84,17 +84,86 @@ export type CosmosMsgForEmpty = {
|
||||
bank: BankMsg;
|
||||
} | {
|
||||
custom: Empty;
|
||||
} | {
|
||||
staking: StakingMsg;
|
||||
} | {
|
||||
distribution: DistributionMsg;
|
||||
} | {
|
||||
stargate: {
|
||||
type_url: string;
|
||||
value: Binary;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
} | {
|
||||
ibc: IbcMsg;
|
||||
} | {
|
||||
wasm: WasmMsg;
|
||||
} | {
|
||||
gov: GovMsg;
|
||||
};
|
||||
export type BankMsg = {
|
||||
send: {
|
||||
amount: Coin[];
|
||||
to_address: string;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
} | {
|
||||
burn: {
|
||||
amount: Coin[];
|
||||
[k: string]: unknown;
|
||||
};
|
||||
};
|
||||
export type StakingMsg = {
|
||||
delegate: {
|
||||
amount: Coin;
|
||||
validator: string;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
} | {
|
||||
undelegate: {
|
||||
amount: Coin;
|
||||
validator: string;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
} | {
|
||||
redelegate: {
|
||||
amount: Coin;
|
||||
dst_validator: string;
|
||||
src_validator: string;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
};
|
||||
export type DistributionMsg = {
|
||||
set_withdraw_address: {
|
||||
address: string;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
} | {
|
||||
withdraw_delegator_reward: {
|
||||
validator: string;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
};
|
||||
export type Binary = string;
|
||||
export type IbcMsg = {
|
||||
transfer: {
|
||||
amount: Coin;
|
||||
channel_id: string;
|
||||
timeout: IbcTimeout;
|
||||
to_address: string;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
} | {
|
||||
send_packet: {
|
||||
channel_id: string;
|
||||
data: Binary;
|
||||
timeout: IbcTimeout;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
} | {
|
||||
close_channel: {
|
||||
channel_id: string;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
};
|
||||
export type WasmMsg = {
|
||||
@@ -102,6 +171,7 @@ export type WasmMsg = {
|
||||
contract_addr: string;
|
||||
funds: Coin[];
|
||||
msg: Binary;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
} | {
|
||||
instantiate: {
|
||||
@@ -110,30 +180,54 @@ export type WasmMsg = {
|
||||
funds: Coin[];
|
||||
label: string;
|
||||
msg: Binary;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
} | {
|
||||
migrate: {
|
||||
contract_addr: string;
|
||||
msg: Binary;
|
||||
new_code_id: number;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
} | {
|
||||
update_admin: {
|
||||
admin: string;
|
||||
contract_addr: string;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
} | {
|
||||
clear_admin: {
|
||||
contract_addr: string;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
};
|
||||
export type Binary = string;
|
||||
export type GovMsg = {
|
||||
vote: {
|
||||
proposal_id: number;
|
||||
vote: VoteOption;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
};
|
||||
export type VoteOption = "yes" | "no" | "abstain" | "no_with_veto";
|
||||
export type Vote = "yes" | "no" | "abstain" | "veto";
|
||||
export interface Coin {
|
||||
amount: Uint128;
|
||||
denom: string;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
export interface Empty {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
export interface IbcTimeout {
|
||||
block?: IbcTimeoutBlock | null;
|
||||
timestamp?: Timestamp | null;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
export interface IbcTimeoutBlock {
|
||||
height: number;
|
||||
revision: number;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
export interface Empty {}
|
||||
export interface MemberChangedHookMsg {
|
||||
diffs: MemberDiff[];
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
/**
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@1.13.3.
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
|
||||
import { ICosmWasmClient, ISigningCosmWasmClient } from "./baseClient";
|
||||
import { Coin, StdFee } from "@interchainjs/types";
|
||||
import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate";
|
||||
import { Coin, StdFee } from "@cosmjs/amino";
|
||||
import { InstantiateMsg, Member, ExecuteMsg, QueryMsg, MigrateMsg, AdminResponse, HooksResponse, MemberListResponse, MemberResponse, TotalWeightResponse } from "./Cw4Group.types";
|
||||
|
||||
export interface Cw4GroupReadOnlyInterface {
|
||||
contractAddress: string;
|
||||
admin: () => Promise<AdminResponse>;
|
||||
@@ -32,9 +33,10 @@ export interface Cw4GroupReadOnlyInterface {
|
||||
hooks: () => Promise<HooksResponse>;
|
||||
}
|
||||
export class Cw4GroupQueryClient implements Cw4GroupReadOnlyInterface {
|
||||
client: ICosmWasmClient;
|
||||
client: CosmWasmClient;
|
||||
contractAddress: string;
|
||||
constructor(client: ICosmWasmClient, contractAddress: string) {
|
||||
|
||||
constructor(client: CosmWasmClient, contractAddress: string) {
|
||||
this.client = client;
|
||||
this.contractAddress = contractAddress;
|
||||
this.admin = this.admin.bind(this);
|
||||
@@ -43,6 +45,7 @@ export class Cw4GroupQueryClient implements Cw4GroupReadOnlyInterface {
|
||||
this.member = this.member.bind(this);
|
||||
this.hooks = this.hooks.bind(this);
|
||||
}
|
||||
|
||||
admin = async (): Promise<AdminResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
admin: {}
|
||||
@@ -100,30 +103,31 @@ export interface Cw4GroupInterface extends Cw4GroupReadOnlyInterface {
|
||||
admin
|
||||
}: {
|
||||
admin?: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
updateMembers: ({
|
||||
add,
|
||||
remove
|
||||
}: {
|
||||
add: Member[];
|
||||
remove: string[];
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
addHook: ({
|
||||
addr
|
||||
}: {
|
||||
addr: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
removeHook: ({
|
||||
addr
|
||||
}: {
|
||||
addr: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
}
|
||||
export class Cw4GroupClient extends Cw4GroupQueryClient implements Cw4GroupInterface {
|
||||
client: ISigningCosmWasmClient;
|
||||
client: SigningCosmWasmClient;
|
||||
sender: string;
|
||||
contractAddress: string;
|
||||
constructor(client: ISigningCosmWasmClient, sender: string, contractAddress: string) {
|
||||
|
||||
constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) {
|
||||
super(client, contractAddress);
|
||||
this.client = client;
|
||||
this.sender = sender;
|
||||
@@ -133,16 +137,17 @@ export class Cw4GroupClient extends Cw4GroupQueryClient implements Cw4GroupInter
|
||||
this.addHook = this.addHook.bind(this);
|
||||
this.removeHook = this.removeHook.bind(this);
|
||||
}
|
||||
|
||||
updateAdmin = async ({
|
||||
admin
|
||||
}: {
|
||||
admin?: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
update_admin: {
|
||||
admin
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
updateMembers = async ({
|
||||
add,
|
||||
@@ -150,34 +155,34 @@ export class Cw4GroupClient extends Cw4GroupQueryClient implements Cw4GroupInter
|
||||
}: {
|
||||
add: Member[];
|
||||
remove: string[];
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
update_members: {
|
||||
add,
|
||||
remove
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
addHook = async ({
|
||||
addr
|
||||
}: {
|
||||
addr: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
add_hook: {
|
||||
addr
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
removeHook = async ({
|
||||
addr
|
||||
}: {
|
||||
addr: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
remove_hook: {
|
||||
addr
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@1.13.3.
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
|
||||
@@ -1,256 +0,0 @@
|
||||
/**
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@1.13.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
|
||||
import { ICosmWasmClient, ISigningCosmWasmClient } from "./baseClient";
|
||||
import { StdFee } from "@interchainjs/types";
|
||||
import { Uint128, InstantiateMsg, Coin, ExecuteMsg, QueryMsg, MigrateMsg, PagedBlacklistedAccountResponse, BlacklistedAccount, Blacklisting, BlacklistedAccountResponse, DepositResponse, Deposit, PagedDepositsResponse, DepositData, LatestDepositResponse } from "./Ecash.types";
|
||||
export interface EcashReadOnlyInterface {
|
||||
contractAddress: string;
|
||||
getBlacklistedAccount: ({
|
||||
publicKey
|
||||
}: {
|
||||
publicKey: string;
|
||||
}) => Promise<BlacklistedAccountResponse>;
|
||||
getBlacklistPaged: ({
|
||||
limit,
|
||||
startAfter
|
||||
}: {
|
||||
limit?: number;
|
||||
startAfter?: string;
|
||||
}) => Promise<PagedBlacklistedAccountResponse>;
|
||||
getRequiredDepositAmount: () => Promise<Coin>;
|
||||
getDeposit: ({
|
||||
depositId
|
||||
}: {
|
||||
depositId: number;
|
||||
}) => Promise<DepositResponse>;
|
||||
getLatestDeposit: () => Promise<LatestDepositResponse>;
|
||||
getDepositsPaged: ({
|
||||
limit,
|
||||
startAfter
|
||||
}: {
|
||||
limit?: number;
|
||||
startAfter?: number;
|
||||
}) => Promise<PagedDepositsResponse>;
|
||||
}
|
||||
export class EcashQueryClient implements EcashReadOnlyInterface {
|
||||
client: ICosmWasmClient;
|
||||
contractAddress: string;
|
||||
constructor(client: ICosmWasmClient, contractAddress: string) {
|
||||
this.client = client;
|
||||
this.contractAddress = contractAddress;
|
||||
this.getBlacklistedAccount = this.getBlacklistedAccount.bind(this);
|
||||
this.getBlacklistPaged = this.getBlacklistPaged.bind(this);
|
||||
this.getRequiredDepositAmount = this.getRequiredDepositAmount.bind(this);
|
||||
this.getDeposit = this.getDeposit.bind(this);
|
||||
this.getLatestDeposit = this.getLatestDeposit.bind(this);
|
||||
this.getDepositsPaged = this.getDepositsPaged.bind(this);
|
||||
}
|
||||
getBlacklistedAccount = async ({
|
||||
publicKey
|
||||
}: {
|
||||
publicKey: string;
|
||||
}): Promise<BlacklistedAccountResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_blacklisted_account: {
|
||||
public_key: publicKey
|
||||
}
|
||||
});
|
||||
};
|
||||
getBlacklistPaged = async ({
|
||||
limit,
|
||||
startAfter
|
||||
}: {
|
||||
limit?: number;
|
||||
startAfter?: string;
|
||||
}): Promise<PagedBlacklistedAccountResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_blacklist_paged: {
|
||||
limit,
|
||||
start_after: startAfter
|
||||
}
|
||||
});
|
||||
};
|
||||
getRequiredDepositAmount = async (): Promise<Coin> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_required_deposit_amount: {}
|
||||
});
|
||||
};
|
||||
getDeposit = async ({
|
||||
depositId
|
||||
}: {
|
||||
depositId: number;
|
||||
}): Promise<DepositResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_deposit: {
|
||||
deposit_id: depositId
|
||||
}
|
||||
});
|
||||
};
|
||||
getLatestDeposit = async (): Promise<LatestDepositResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_latest_deposit: {}
|
||||
});
|
||||
};
|
||||
getDepositsPaged = async ({
|
||||
limit,
|
||||
startAfter
|
||||
}: {
|
||||
limit?: number;
|
||||
startAfter?: number;
|
||||
}): Promise<PagedDepositsResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_deposits_paged: {
|
||||
limit,
|
||||
start_after: startAfter
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
export interface EcashInterface extends EcashReadOnlyInterface {
|
||||
contractAddress: string;
|
||||
sender: string;
|
||||
depositTicketBookFunds: ({
|
||||
identityKey
|
||||
}: {
|
||||
identityKey: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
requestRedemption: ({
|
||||
commitmentBs58,
|
||||
numberOfTickets
|
||||
}: {
|
||||
commitmentBs58: string;
|
||||
numberOfTickets: number;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
redeemTickets: ({
|
||||
gw,
|
||||
n
|
||||
}: {
|
||||
gw: string;
|
||||
n: number;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
updateAdmin: ({
|
||||
admin
|
||||
}: {
|
||||
admin: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
updateDepositValue: ({
|
||||
newDeposit
|
||||
}: {
|
||||
newDeposit: Coin;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
proposeToBlacklist: ({
|
||||
publicKey
|
||||
}: {
|
||||
publicKey: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
addToBlacklist: ({
|
||||
publicKey
|
||||
}: {
|
||||
publicKey: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}
|
||||
export class EcashClient extends EcashQueryClient implements EcashInterface {
|
||||
client: ISigningCosmWasmClient;
|
||||
sender: string;
|
||||
contractAddress: string;
|
||||
constructor(client: ISigningCosmWasmClient, sender: string, contractAddress: string) {
|
||||
super(client, contractAddress);
|
||||
this.client = client;
|
||||
this.sender = sender;
|
||||
this.contractAddress = contractAddress;
|
||||
this.depositTicketBookFunds = this.depositTicketBookFunds.bind(this);
|
||||
this.requestRedemption = this.requestRedemption.bind(this);
|
||||
this.redeemTickets = this.redeemTickets.bind(this);
|
||||
this.updateAdmin = this.updateAdmin.bind(this);
|
||||
this.updateDepositValue = this.updateDepositValue.bind(this);
|
||||
this.proposeToBlacklist = this.proposeToBlacklist.bind(this);
|
||||
this.addToBlacklist = this.addToBlacklist.bind(this);
|
||||
}
|
||||
depositTicketBookFunds = async ({
|
||||
identityKey
|
||||
}: {
|
||||
identityKey: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
deposit_ticket_book_funds: {
|
||||
identity_key: identityKey
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
requestRedemption = async ({
|
||||
commitmentBs58,
|
||||
numberOfTickets
|
||||
}: {
|
||||
commitmentBs58: string;
|
||||
numberOfTickets: number;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
request_redemption: {
|
||||
commitment_bs58: commitmentBs58,
|
||||
number_of_tickets: numberOfTickets
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
redeemTickets = async ({
|
||||
gw,
|
||||
n
|
||||
}: {
|
||||
gw: string;
|
||||
n: number;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
redeem_tickets: {
|
||||
gw,
|
||||
n
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
updateAdmin = async ({
|
||||
admin
|
||||
}: {
|
||||
admin: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
update_admin: {
|
||||
admin
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
updateDepositValue = async ({
|
||||
newDeposit
|
||||
}: {
|
||||
newDeposit: Coin;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
update_deposit_value: {
|
||||
new_deposit: newDeposit
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
proposeToBlacklist = async ({
|
||||
publicKey
|
||||
}: {
|
||||
publicKey: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
propose_to_blacklist: {
|
||||
public_key: publicKey
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
addToBlacklist = async ({
|
||||
publicKey
|
||||
}: {
|
||||
publicKey: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
add_to_blacklist: {
|
||||
public_key: publicKey
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/**
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@1.13.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
|
||||
export type Uint128 = string;
|
||||
export interface InstantiateMsg {
|
||||
deposit_amount: Coin;
|
||||
group_addr: string;
|
||||
holding_account: string;
|
||||
multisig_addr: string;
|
||||
}
|
||||
export interface Coin {
|
||||
amount: Uint128;
|
||||
denom: string;
|
||||
}
|
||||
export type ExecuteMsg = {
|
||||
deposit_ticket_book_funds: {
|
||||
identity_key: string;
|
||||
};
|
||||
} | {
|
||||
request_redemption: {
|
||||
commitment_bs58: string;
|
||||
number_of_tickets: number;
|
||||
};
|
||||
} | {
|
||||
redeem_tickets: {
|
||||
gw: string;
|
||||
n: number;
|
||||
};
|
||||
} | {
|
||||
update_admin: {
|
||||
admin: string;
|
||||
};
|
||||
} | {
|
||||
update_deposit_value: {
|
||||
new_deposit: Coin;
|
||||
};
|
||||
} | {
|
||||
propose_to_blacklist: {
|
||||
public_key: string;
|
||||
};
|
||||
} | {
|
||||
add_to_blacklist: {
|
||||
public_key: string;
|
||||
};
|
||||
};
|
||||
export type QueryMsg = {
|
||||
get_blacklisted_account: {
|
||||
public_key: string;
|
||||
};
|
||||
} | {
|
||||
get_blacklist_paged: {
|
||||
limit?: number | null;
|
||||
start_after?: string | null;
|
||||
};
|
||||
} | {
|
||||
get_required_deposit_amount: {};
|
||||
} | {
|
||||
get_deposit: {
|
||||
deposit_id: number;
|
||||
};
|
||||
} | {
|
||||
get_latest_deposit: {};
|
||||
} | {
|
||||
get_deposits_paged: {
|
||||
limit?: number | null;
|
||||
start_after?: number | null;
|
||||
};
|
||||
};
|
||||
export interface MigrateMsg {}
|
||||
export interface PagedBlacklistedAccountResponse {
|
||||
accounts: BlacklistedAccount[];
|
||||
per_page: number;
|
||||
start_next_after?: string | null;
|
||||
}
|
||||
export interface BlacklistedAccount {
|
||||
info: Blacklisting;
|
||||
public_key: string;
|
||||
}
|
||||
export interface Blacklisting {
|
||||
finalized_at_height?: number | null;
|
||||
proposal_id: number;
|
||||
}
|
||||
export interface BlacklistedAccountResponse {
|
||||
account?: Blacklisting | null;
|
||||
}
|
||||
export interface DepositResponse {
|
||||
deposit?: Deposit | null;
|
||||
id: number;
|
||||
}
|
||||
export interface Deposit {
|
||||
bs58_encoded_ed25519_pubkey: string;
|
||||
}
|
||||
export interface PagedDepositsResponse {
|
||||
deposits: DepositData[];
|
||||
start_next_after?: number | null;
|
||||
}
|
||||
export interface DepositData {
|
||||
deposit: Deposit;
|
||||
id: number;
|
||||
}
|
||||
export interface LatestDepositResponse {
|
||||
deposit?: DepositData | null;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,66 +1,80 @@
|
||||
/**
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@1.13.3.
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
|
||||
export type Decimal = string;
|
||||
export type Percent = Decimal;
|
||||
export type Uint128 = string;
|
||||
|
||||
/**
|
||||
* This instantiates the contract.
|
||||
*/
|
||||
export interface InstantiateMsg {
|
||||
current_nym_node_version: string;
|
||||
epoch_duration: Duration;
|
||||
epochs_in_interval: number;
|
||||
initial_rewarding_params: InitialRewardingParams;
|
||||
interval_operating_cost?: RangedValueForUint128;
|
||||
key_validity_in_epochs?: number | null;
|
||||
profit_margin?: RangedValueForPercent;
|
||||
rewarding_denom: string;
|
||||
rewarding_validator_address: string;
|
||||
version_score_params?: VersionScoreFormulaParams;
|
||||
version_score_weights?: OutdatedVersionWeights;
|
||||
vesting_contract_address: string;
|
||||
}
|
||||
export interface Duration {
|
||||
nanos: number;
|
||||
secs: number;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
export interface InitialRewardingParams {
|
||||
active_set_size: number;
|
||||
active_set_work_factor: Decimal;
|
||||
initial_reward_pool: Decimal;
|
||||
initial_staking_supply: Decimal;
|
||||
interval_pool_emission: Percent;
|
||||
rewarded_set_params: RewardedSetParams;
|
||||
rewarded_set_size: number;
|
||||
staking_supply_scale_factor: Percent;
|
||||
sybil_resistance: Percent;
|
||||
}
|
||||
export interface RewardedSetParams {
|
||||
entry_gateways: number;
|
||||
exit_gateways: number;
|
||||
mixnodes: number;
|
||||
standby: number;
|
||||
}
|
||||
export interface RangedValueForUint128 {
|
||||
maximum: Uint128;
|
||||
minimum: Uint128;
|
||||
}
|
||||
export interface RangedValueForPercent {
|
||||
maximum: Percent;
|
||||
minimum: Percent;
|
||||
}
|
||||
export interface VersionScoreFormulaParams {
|
||||
penalty: Decimal;
|
||||
penalty_scaling: Decimal;
|
||||
}
|
||||
export interface OutdatedVersionWeights {
|
||||
major: number;
|
||||
minor: number;
|
||||
patch: number;
|
||||
prerelease: number;
|
||||
}
|
||||
export type ExecuteMsg = {
|
||||
update_admin: {
|
||||
admin: string;
|
||||
assign_node_layer: {
|
||||
layer: Layer;
|
||||
mix_id: number;
|
||||
};
|
||||
} | {
|
||||
create_family: {
|
||||
label: string;
|
||||
};
|
||||
} | {
|
||||
join_family: {
|
||||
family_head: FamilyHead;
|
||||
join_permit: MessageSignature;
|
||||
};
|
||||
} | {
|
||||
leave_family: {
|
||||
family_head: FamilyHead;
|
||||
};
|
||||
} | {
|
||||
kick_family_member: {
|
||||
member: string;
|
||||
};
|
||||
} | {
|
||||
create_family_on_behalf: {
|
||||
label: string;
|
||||
owner_address: string;
|
||||
};
|
||||
} | {
|
||||
join_family_on_behalf: {
|
||||
family_head: FamilyHead;
|
||||
join_permit: MessageSignature;
|
||||
member_address: string;
|
||||
};
|
||||
} | {
|
||||
leave_family_on_behalf: {
|
||||
family_head: FamilyHead;
|
||||
member_address: string;
|
||||
};
|
||||
} | {
|
||||
kick_family_member_on_behalf: {
|
||||
head_address: string;
|
||||
member: string;
|
||||
};
|
||||
} | {
|
||||
update_rewarding_validator_address: {
|
||||
@@ -68,16 +82,12 @@ export type ExecuteMsg = {
|
||||
};
|
||||
} | {
|
||||
update_contract_state_params: {
|
||||
update: ContractStateParamsUpdate;
|
||||
updated_parameters: ContractStateParams;
|
||||
};
|
||||
} | {
|
||||
update_current_nym_node_semver: {
|
||||
current_version: string;
|
||||
};
|
||||
} | {
|
||||
update_active_set_distribution: {
|
||||
update_active_set_size: {
|
||||
active_set_size: number;
|
||||
force_immediately: boolean;
|
||||
update: ActiveSetUpdate;
|
||||
};
|
||||
} | {
|
||||
update_rewarding_params: {
|
||||
@@ -92,23 +102,24 @@ export type ExecuteMsg = {
|
||||
};
|
||||
} | {
|
||||
begin_epoch_transition: {};
|
||||
} | {
|
||||
advance_current_epoch: {
|
||||
expected_active_set_size: number;
|
||||
new_rewarded_set: LayerAssignment[];
|
||||
};
|
||||
} | {
|
||||
reconcile_epoch_events: {
|
||||
limit?: number | null;
|
||||
};
|
||||
} | {
|
||||
assign_roles: {
|
||||
assignment: RoleAssignment;
|
||||
};
|
||||
} | {
|
||||
bond_mixnode: {
|
||||
cost_params: NodeCostParams;
|
||||
cost_params: MixNodeCostParams;
|
||||
mix_node: MixNode;
|
||||
owner_signature: MessageSignature;
|
||||
};
|
||||
} | {
|
||||
bond_mixnode_on_behalf: {
|
||||
cost_params: NodeCostParams;
|
||||
cost_params: MixNodeCostParams;
|
||||
mix_node: MixNode;
|
||||
owner: string;
|
||||
owner_signature: MessageSignature;
|
||||
@@ -135,12 +146,12 @@ export type ExecuteMsg = {
|
||||
owner: string;
|
||||
};
|
||||
} | {
|
||||
update_cost_params: {
|
||||
new_costs: NodeCostParams;
|
||||
update_mixnode_cost_params: {
|
||||
new_costs: MixNodeCostParams;
|
||||
};
|
||||
} | {
|
||||
update_mixnode_cost_params_on_behalf: {
|
||||
new_costs: NodeCostParams;
|
||||
new_costs: MixNodeCostParams;
|
||||
owner: string;
|
||||
};
|
||||
} | {
|
||||
@@ -152,8 +163,6 @@ export type ExecuteMsg = {
|
||||
new_config: MixNodeConfigUpdate;
|
||||
owner: string;
|
||||
};
|
||||
} | {
|
||||
migrate_mixnode: {};
|
||||
} | {
|
||||
bond_gateway: {
|
||||
gateway: Gateway;
|
||||
@@ -181,24 +190,8 @@ export type ExecuteMsg = {
|
||||
owner: string;
|
||||
};
|
||||
} | {
|
||||
migrate_gateway: {
|
||||
cost_params?: NodeCostParams | null;
|
||||
};
|
||||
} | {
|
||||
bond_nym_node: {
|
||||
cost_params: NodeCostParams;
|
||||
node: NymNode;
|
||||
owner_signature: MessageSignature;
|
||||
};
|
||||
} | {
|
||||
unbond_nym_node: {};
|
||||
} | {
|
||||
update_node_config: {
|
||||
update: NodeConfigUpdate;
|
||||
};
|
||||
} | {
|
||||
delegate: {
|
||||
node_id: number;
|
||||
delegate_to_mixnode: {
|
||||
mix_id: number;
|
||||
};
|
||||
} | {
|
||||
delegate_to_mixnode_on_behalf: {
|
||||
@@ -206,8 +199,8 @@ export type ExecuteMsg = {
|
||||
mix_id: number;
|
||||
};
|
||||
} | {
|
||||
undelegate: {
|
||||
node_id: number;
|
||||
undelegate_from_mixnode: {
|
||||
mix_id: number;
|
||||
};
|
||||
} | {
|
||||
undelegate_from_mixnode_on_behalf: {
|
||||
@@ -215,9 +208,9 @@ export type ExecuteMsg = {
|
||||
mix_id: number;
|
||||
};
|
||||
} | {
|
||||
reward_node: {
|
||||
node_id: number;
|
||||
params: NodeRewardingParameters;
|
||||
reward_mixnode: {
|
||||
mix_id: number;
|
||||
performance: Percent;
|
||||
};
|
||||
} | {
|
||||
withdraw_operator_reward: {};
|
||||
@@ -227,62 +220,42 @@ export type ExecuteMsg = {
|
||||
};
|
||||
} | {
|
||||
withdraw_delegator_reward: {
|
||||
node_id: number;
|
||||
mix_id: number;
|
||||
};
|
||||
} | {
|
||||
withdraw_delegator_reward_on_behalf: {
|
||||
mix_id: number;
|
||||
owner: string;
|
||||
};
|
||||
} | {
|
||||
migrate_vested_mix_node: {};
|
||||
} | {
|
||||
migrate_vested_delegation: {
|
||||
mix_id: number;
|
||||
};
|
||||
};
|
||||
export type Role = "eg" | "l1" | "l2" | "l3" | "xg" | "stb";
|
||||
export type Layer = "One" | "Two" | "Three";
|
||||
export type FamilyHead = string;
|
||||
export type MessageSignature = number[];
|
||||
export interface ContractStateParamsUpdate {
|
||||
config_score_params?: ConfigScoreParamsUpdate | null;
|
||||
delegations_params?: DelegationsParams | null;
|
||||
operators_params?: OperatorsParamsUpdate | null;
|
||||
}
|
||||
export interface ConfigScoreParamsUpdate {
|
||||
version_score_formula_params?: VersionScoreFormulaParams | null;
|
||||
version_weights?: OutdatedVersionWeights | null;
|
||||
}
|
||||
export interface DelegationsParams {
|
||||
minimum_delegation?: Coin | null;
|
||||
export type Uint128 = string;
|
||||
export interface ContractStateParams {
|
||||
minimum_gateway_pledge: Coin;
|
||||
minimum_mixnode_delegation?: Coin | null;
|
||||
minimum_mixnode_pledge: Coin;
|
||||
}
|
||||
export interface Coin {
|
||||
amount: Uint128;
|
||||
denom: string;
|
||||
}
|
||||
export interface OperatorsParamsUpdate {
|
||||
interval_operating_cost?: RangedValueForUint128 | null;
|
||||
minimum_pledge?: Coin | null;
|
||||
profit_margin?: RangedValueForPercent | null;
|
||||
}
|
||||
export interface ActiveSetUpdate {
|
||||
entry_gateways: number;
|
||||
exit_gateways: number;
|
||||
mixnodes: number;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
export interface IntervalRewardingParamsUpdate {
|
||||
active_set_work_factor?: Decimal | null;
|
||||
interval_pool_emission?: Percent | null;
|
||||
reward_pool?: Decimal | null;
|
||||
rewarded_set_params?: RewardedSetParams | null;
|
||||
rewarded_set_size?: number | null;
|
||||
staking_supply?: Decimal | null;
|
||||
staking_supply_scale_factor?: Percent | null;
|
||||
sybil_resistance_percent?: Percent | null;
|
||||
}
|
||||
export interface RoleAssignment {
|
||||
nodes: number[];
|
||||
role: Role;
|
||||
export interface LayerAssignment {
|
||||
layer: Layer;
|
||||
mix_id: number;
|
||||
}
|
||||
export interface NodeCostParams {
|
||||
export interface MixNodeCostParams {
|
||||
interval_operating_cost: Coin;
|
||||
profit_margin_percent: Percent;
|
||||
}
|
||||
@@ -318,22 +291,32 @@ export interface GatewayConfigUpdate {
|
||||
mix_port: number;
|
||||
version: string;
|
||||
}
|
||||
export interface NymNode {
|
||||
custom_http_port?: number | null;
|
||||
host: string;
|
||||
identity_key: string;
|
||||
}
|
||||
export interface NodeConfigUpdate {
|
||||
custom_http_port?: number | null;
|
||||
host?: string | null;
|
||||
restore_default_http_port?: boolean;
|
||||
}
|
||||
export interface NodeRewardingParameters {
|
||||
performance: Percent;
|
||||
work_factor: Decimal;
|
||||
}
|
||||
export type QueryMsg = {
|
||||
admin: {};
|
||||
get_all_families_paged: {
|
||||
limit?: number | null;
|
||||
start_after?: string | null;
|
||||
};
|
||||
} | {
|
||||
get_all_members_paged: {
|
||||
limit?: number | null;
|
||||
start_after?: string | null;
|
||||
};
|
||||
} | {
|
||||
get_family_by_head: {
|
||||
head: string;
|
||||
};
|
||||
} | {
|
||||
get_family_by_label: {
|
||||
label: string;
|
||||
};
|
||||
} | {
|
||||
get_family_members_by_head: {
|
||||
head: string;
|
||||
};
|
||||
} | {
|
||||
get_family_members_by_label: {
|
||||
label: string;
|
||||
};
|
||||
} | {
|
||||
get_contract_version: {};
|
||||
} | {
|
||||
@@ -344,19 +327,17 @@ export type QueryMsg = {
|
||||
get_state_params: {};
|
||||
} | {
|
||||
get_state: {};
|
||||
} | {
|
||||
get_current_nym_node_version: {};
|
||||
} | {
|
||||
get_nym_node_version_history: {
|
||||
limit?: number | null;
|
||||
start_after?: number | null;
|
||||
};
|
||||
} | {
|
||||
get_rewarding_params: {};
|
||||
} | {
|
||||
get_epoch_status: {};
|
||||
} | {
|
||||
get_current_interval_details: {};
|
||||
} | {
|
||||
get_rewarded_set: {
|
||||
limit?: number | null;
|
||||
start_after?: number | null;
|
||||
};
|
||||
} | {
|
||||
get_mix_node_bonds: {
|
||||
limit?: number | null;
|
||||
@@ -408,6 +389,8 @@ export type QueryMsg = {
|
||||
get_bonded_mixnode_details_by_identity: {
|
||||
mix_identity: string;
|
||||
};
|
||||
} | {
|
||||
get_layer_distribution: {};
|
||||
} | {
|
||||
get_gateways: {
|
||||
limit?: number | null;
|
||||
@@ -422,71 +405,9 @@ export type QueryMsg = {
|
||||
address: string;
|
||||
};
|
||||
} | {
|
||||
get_preassigned_gateway_ids: {
|
||||
get_mixnode_delegations: {
|
||||
limit?: number | null;
|
||||
start_after?: string | null;
|
||||
};
|
||||
} | {
|
||||
get_nym_node_bonds_paged: {
|
||||
limit?: number | null;
|
||||
start_after?: number | null;
|
||||
};
|
||||
} | {
|
||||
get_nym_nodes_detailed_paged: {
|
||||
limit?: number | null;
|
||||
start_after?: number | null;
|
||||
};
|
||||
} | {
|
||||
get_unbonded_nym_node: {
|
||||
node_id: number;
|
||||
};
|
||||
} | {
|
||||
get_unbonded_nym_nodes_paged: {
|
||||
limit?: number | null;
|
||||
start_after?: number | null;
|
||||
};
|
||||
} | {
|
||||
get_unbonded_nym_nodes_by_owner_paged: {
|
||||
limit?: number | null;
|
||||
owner: string;
|
||||
start_after?: number | null;
|
||||
};
|
||||
} | {
|
||||
get_unbonded_nym_nodes_by_identity_key_paged: {
|
||||
identity_key: string;
|
||||
limit?: number | null;
|
||||
start_after?: number | null;
|
||||
};
|
||||
} | {
|
||||
get_owned_nym_node: {
|
||||
address: string;
|
||||
};
|
||||
} | {
|
||||
get_nym_node_details: {
|
||||
node_id: number;
|
||||
};
|
||||
} | {
|
||||
get_nym_node_details_by_identity_key: {
|
||||
node_identity: string;
|
||||
};
|
||||
} | {
|
||||
get_node_rewarding_details: {
|
||||
node_id: number;
|
||||
};
|
||||
} | {
|
||||
get_node_stake_saturation: {
|
||||
node_id: number;
|
||||
};
|
||||
} | {
|
||||
get_role_assignment: {
|
||||
role: Role;
|
||||
};
|
||||
} | {
|
||||
get_rewarded_set_metadata: {};
|
||||
} | {
|
||||
get_node_delegations: {
|
||||
limit?: number | null;
|
||||
node_id: number;
|
||||
mix_id: number;
|
||||
start_after?: string | null;
|
||||
};
|
||||
} | {
|
||||
@@ -498,7 +419,7 @@ export type QueryMsg = {
|
||||
} | {
|
||||
get_delegation_details: {
|
||||
delegator: string;
|
||||
node_id: number;
|
||||
mix_id: number;
|
||||
proxy?: string | null;
|
||||
};
|
||||
} | {
|
||||
@@ -511,27 +432,26 @@ export type QueryMsg = {
|
||||
address: string;
|
||||
};
|
||||
} | {
|
||||
get_pending_node_operator_reward: {
|
||||
node_id: number;
|
||||
get_pending_mix_node_operator_reward: {
|
||||
mix_id: number;
|
||||
};
|
||||
} | {
|
||||
get_pending_delegator_reward: {
|
||||
address: string;
|
||||
node_id: number;
|
||||
mix_id: number;
|
||||
proxy?: string | null;
|
||||
};
|
||||
} | {
|
||||
get_estimated_current_epoch_operator_reward: {
|
||||
estimated_performance: Percent;
|
||||
estimated_work?: Decimal | null;
|
||||
node_id: number;
|
||||
mix_id: number;
|
||||
};
|
||||
} | {
|
||||
get_estimated_current_epoch_delegator_reward: {
|
||||
address: string;
|
||||
estimated_performance: Percent;
|
||||
estimated_work?: Decimal | null;
|
||||
node_id: number;
|
||||
mix_id: number;
|
||||
proxy?: string | null;
|
||||
};
|
||||
} | {
|
||||
get_pending_epoch_events: {
|
||||
@@ -557,18 +477,10 @@ export type QueryMsg = {
|
||||
get_signing_nonce: {
|
||||
address: string;
|
||||
};
|
||||
} | {
|
||||
get_key_rotation_state: {};
|
||||
} | {
|
||||
get_key_rotation_id: {};
|
||||
};
|
||||
export interface MigrateMsg {
|
||||
unsafe_skip_state_updates?: boolean | null;
|
||||
vesting_contract_address?: string | null;
|
||||
}
|
||||
export interface AdminResponse {
|
||||
admin?: string | null;
|
||||
}
|
||||
export type Addr = string;
|
||||
export interface PagedAllDelegationsResponse {
|
||||
delegations: Delegation[];
|
||||
@@ -578,10 +490,23 @@ export interface Delegation {
|
||||
amount: Coin;
|
||||
cumulative_reward_ratio: Decimal;
|
||||
height: number;
|
||||
node_id: number;
|
||||
mix_id: number;
|
||||
owner: Addr;
|
||||
proxy?: Addr | null;
|
||||
}
|
||||
export interface PagedFamiliesResponse {
|
||||
families: Family[];
|
||||
start_next_after?: string | null;
|
||||
}
|
||||
export interface Family {
|
||||
head: FamilyHead;
|
||||
label: string;
|
||||
proxy?: string | null;
|
||||
}
|
||||
export interface PagedMembersResponse {
|
||||
members: [string, FamilyHead][];
|
||||
start_next_after?: string | null;
|
||||
}
|
||||
export interface MixnodeDetailsByIdentityResponse {
|
||||
identity_key: string;
|
||||
mixnode_details?: MixNodeDetails | null;
|
||||
@@ -589,11 +514,12 @@ export interface MixnodeDetailsByIdentityResponse {
|
||||
export interface MixNodeDetails {
|
||||
bond_information: MixNodeBond;
|
||||
pending_changes?: PendingMixNodeChanges;
|
||||
rewarding_details: NodeRewarding;
|
||||
rewarding_details: MixNodeRewarding;
|
||||
}
|
||||
export interface MixNodeBond {
|
||||
bonding_height: number;
|
||||
is_unbonding: boolean;
|
||||
layer: Layer;
|
||||
mix_id: number;
|
||||
mix_node: MixNode;
|
||||
original_pledge: Coin;
|
||||
@@ -601,11 +527,10 @@ export interface MixNodeBond {
|
||||
proxy?: Addr | null;
|
||||
}
|
||||
export interface PendingMixNodeChanges {
|
||||
cost_params_change?: number | null;
|
||||
pledge_change?: number | null;
|
||||
}
|
||||
export interface NodeRewarding {
|
||||
cost_params: NodeCostParams;
|
||||
export interface MixNodeRewarding {
|
||||
cost_params: MixNodeCostParams;
|
||||
delegates: Decimal;
|
||||
last_rewarded_epoch: number;
|
||||
operator: Decimal;
|
||||
@@ -620,12 +545,9 @@ export interface ContractVersion {
|
||||
export interface ContractBuildInformation {
|
||||
build_timestamp: string;
|
||||
build_version: string;
|
||||
cargo_debug?: string;
|
||||
cargo_opt_level?: string;
|
||||
commit_branch: string;
|
||||
commit_sha: string;
|
||||
commit_timestamp: string;
|
||||
contract_name?: string;
|
||||
rustc_version: string;
|
||||
}
|
||||
export interface CurrentIntervalResponse {
|
||||
@@ -641,29 +563,11 @@ export interface Interval {
|
||||
epochs_in_interval: number;
|
||||
id: number;
|
||||
total_elapsed_epochs: number;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
export interface CurrentNymNodeVersionResponse {
|
||||
version?: HistoricalNymNodeVersionEntry | null;
|
||||
}
|
||||
export interface HistoricalNymNodeVersionEntry {
|
||||
id: number;
|
||||
version_information: HistoricalNymNodeVersion;
|
||||
}
|
||||
export interface HistoricalNymNodeVersion {
|
||||
difference_since_genesis: TotalVersionDifference;
|
||||
introduced_at_height: number;
|
||||
semver: string;
|
||||
}
|
||||
export interface TotalVersionDifference {
|
||||
major: number;
|
||||
minor: number;
|
||||
patch: number;
|
||||
prerelease: number;
|
||||
}
|
||||
export interface NodeDelegationResponse {
|
||||
export interface MixNodeDelegationResponse {
|
||||
delegation?: Delegation | null;
|
||||
mixnode_still_bonded: boolean;
|
||||
node_still_bonded: boolean;
|
||||
}
|
||||
export interface PagedDelegatorDelegationsResponse {
|
||||
delegations: Delegation[];
|
||||
@@ -674,11 +578,7 @@ export type EpochState = "in_progress" | {
|
||||
final_node_id: number;
|
||||
last_rewarded: number;
|
||||
};
|
||||
} | "reconciling_events" | {
|
||||
role_assignment: {
|
||||
next: Role;
|
||||
};
|
||||
};
|
||||
} | "reconciling_events" | "advancing_epoch";
|
||||
export interface EpochStatus {
|
||||
being_advanced_by: Addr;
|
||||
state: EpochState;
|
||||
@@ -690,6 +590,22 @@ export interface EstimatedCurrentEpochRewardResponse {
|
||||
estimation?: Coin | null;
|
||||
original_stake?: Coin | null;
|
||||
}
|
||||
export interface FamilyByHeadResponse {
|
||||
family?: Family | null;
|
||||
head: FamilyHead;
|
||||
}
|
||||
export interface FamilyByLabelResponse {
|
||||
family?: Family | null;
|
||||
label: string;
|
||||
}
|
||||
export interface FamilyMembersByHeadResponse {
|
||||
head: FamilyHead;
|
||||
members: string[];
|
||||
}
|
||||
export interface FamilyMembersByLabelResponse {
|
||||
label: string;
|
||||
members: string[];
|
||||
}
|
||||
export interface GatewayBondResponse {
|
||||
gateway?: GatewayBond | null;
|
||||
identity: string;
|
||||
@@ -706,12 +622,10 @@ export interface PagedGatewayResponse {
|
||||
per_page: number;
|
||||
start_next_after?: string | null;
|
||||
}
|
||||
export interface KeyRotationIdResponse {
|
||||
rotation_id: number;
|
||||
}
|
||||
export interface KeyRotationState {
|
||||
initial_epoch_id: number;
|
||||
validity_epochs: number;
|
||||
export interface LayerDistribution {
|
||||
layer1: number;
|
||||
layer2: number;
|
||||
layer3: number;
|
||||
}
|
||||
export interface PagedMixnodeBondsResponse {
|
||||
nodes: MixNodeBond[];
|
||||
@@ -723,68 +637,22 @@ export interface PagedMixnodesDetailsResponse {
|
||||
per_page: number;
|
||||
start_next_after?: number | null;
|
||||
}
|
||||
export interface PagedMixNodeDelegationsResponse {
|
||||
delegations: Delegation[];
|
||||
start_next_after?: string | null;
|
||||
}
|
||||
export interface MixnodeDetailsResponse {
|
||||
mix_id: number;
|
||||
mixnode_details?: MixNodeDetails | null;
|
||||
}
|
||||
export interface MixnodeRewardingDetailsResponse {
|
||||
mix_id: number;
|
||||
rewarding_details?: NodeRewarding | null;
|
||||
}
|
||||
export interface PagedNodeDelegationsResponse {
|
||||
delegations: Delegation[];
|
||||
start_next_after?: string | null;
|
||||
}
|
||||
export interface NodeRewardingDetailsResponse {
|
||||
node_id: number;
|
||||
rewarding_details?: NodeRewarding | null;
|
||||
}
|
||||
export interface StakeSaturationResponse {
|
||||
current_saturation?: Decimal | null;
|
||||
node_id: number;
|
||||
uncapped_saturation?: Decimal | null;
|
||||
rewarding_details?: MixNodeRewarding | null;
|
||||
}
|
||||
export interface NumberOfPendingEventsResponse {
|
||||
epoch_events: number;
|
||||
interval_events: number;
|
||||
}
|
||||
export interface PagedNymNodeBondsResponse {
|
||||
nodes: NymNodeBond[];
|
||||
start_next_after?: number | null;
|
||||
}
|
||||
export interface NymNodeBond {
|
||||
bonding_height: number;
|
||||
is_unbonding: boolean;
|
||||
node: NymNode;
|
||||
node_id: number;
|
||||
original_pledge: Coin;
|
||||
owner: Addr;
|
||||
}
|
||||
export interface NodeDetailsResponse {
|
||||
details?: NymNodeDetails | null;
|
||||
node_id: number;
|
||||
}
|
||||
export interface NymNodeDetails {
|
||||
bond_information: NymNodeBond;
|
||||
pending_changes: PendingNodeChanges;
|
||||
rewarding_details: NodeRewarding;
|
||||
}
|
||||
export interface PendingNodeChanges {
|
||||
cost_params_change?: number | null;
|
||||
pledge_change?: number | null;
|
||||
}
|
||||
export interface NodeDetailsByIdentityResponse {
|
||||
details?: NymNodeDetails | null;
|
||||
identity_key: string;
|
||||
}
|
||||
export interface NymNodeVersionHistoryResponse {
|
||||
history: HistoricalNymNodeVersionEntry[];
|
||||
start_next_after?: number | null;
|
||||
}
|
||||
export interface PagedNymNodeDetailsResponse {
|
||||
nodes: NymNodeDetails[];
|
||||
start_next_after?: number | null;
|
||||
}
|
||||
export interface GatewayOwnershipResponse {
|
||||
address: Addr;
|
||||
gateway?: GatewayBond | null;
|
||||
@@ -793,47 +661,32 @@ export interface MixOwnershipResponse {
|
||||
address: Addr;
|
||||
mixnode_details?: MixNodeDetails | null;
|
||||
}
|
||||
export interface NodeOwnershipResponse {
|
||||
address: Addr;
|
||||
details?: NymNodeDetails | null;
|
||||
}
|
||||
export interface PendingRewardResponse {
|
||||
amount_earned?: Coin | null;
|
||||
amount_earned_detailed?: Decimal | null;
|
||||
amount_staked?: Coin | null;
|
||||
mixnode_still_fully_bonded: boolean;
|
||||
node_still_fully_bonded: boolean;
|
||||
}
|
||||
export type PendingEpochEventKind = {
|
||||
delegate: {
|
||||
amount: Coin;
|
||||
node_id: number;
|
||||
mix_id: number;
|
||||
owner: Addr;
|
||||
proxy?: Addr | null;
|
||||
};
|
||||
} | {
|
||||
undelegate: {
|
||||
node_id: number;
|
||||
mix_id: number;
|
||||
owner: Addr;
|
||||
proxy?: Addr | null;
|
||||
};
|
||||
} | {
|
||||
nym_node_pledge_more: {
|
||||
amount: Coin;
|
||||
node_id: number;
|
||||
};
|
||||
} | {
|
||||
mixnode_pledge_more: {
|
||||
pledge_more: {
|
||||
amount: Coin;
|
||||
mix_id: number;
|
||||
};
|
||||
} | {
|
||||
nym_node_decrease_pledge: {
|
||||
decrease_by: Coin;
|
||||
node_id: number;
|
||||
};
|
||||
} | {
|
||||
mixnode_decrease_pledge: {
|
||||
decrease_pledge: {
|
||||
decrease_by: Coin;
|
||||
mix_id: number;
|
||||
};
|
||||
@@ -842,12 +695,8 @@ export type PendingEpochEventKind = {
|
||||
mix_id: number;
|
||||
};
|
||||
} | {
|
||||
unbond_nym_node: {
|
||||
node_id: number;
|
||||
};
|
||||
} | {
|
||||
update_active_set: {
|
||||
update: ActiveSetUpdate;
|
||||
update_active_set_size: {
|
||||
new_size: number;
|
||||
};
|
||||
};
|
||||
export interface PendingEpochEventResponse {
|
||||
@@ -870,12 +719,7 @@ export interface PendingEpochEvent {
|
||||
export type PendingIntervalEventKind = {
|
||||
change_mix_cost_params: {
|
||||
mix_id: number;
|
||||
new_costs: NodeCostParams;
|
||||
};
|
||||
} | {
|
||||
change_nym_node_cost_params: {
|
||||
new_costs: NodeCostParams;
|
||||
node_id: number;
|
||||
new_costs: MixNodeCostParams;
|
||||
};
|
||||
} | {
|
||||
update_rewarding_params: {
|
||||
@@ -904,34 +748,15 @@ export interface PendingIntervalEvent {
|
||||
event: PendingIntervalEventData;
|
||||
id: number;
|
||||
}
|
||||
export interface PreassignedGatewayIdsResponse {
|
||||
ids: PreassignedId[];
|
||||
start_next_after?: string | null;
|
||||
}
|
||||
export interface PreassignedId {
|
||||
identity: string;
|
||||
node_id: number;
|
||||
}
|
||||
export interface RolesMetadataResponse {
|
||||
metadata: RewardedSetMetadata;
|
||||
}
|
||||
export interface RewardedSetMetadata {
|
||||
entry_gateway_metadata: RoleMetadata;
|
||||
epoch_id: number;
|
||||
exit_gateway_metadata: RoleMetadata;
|
||||
fully_assigned: boolean;
|
||||
layer1_metadata: RoleMetadata;
|
||||
layer2_metadata: RoleMetadata;
|
||||
layer3_metadata: RoleMetadata;
|
||||
standby_metadata: RoleMetadata;
|
||||
}
|
||||
export interface RoleMetadata {
|
||||
highest_id: number;
|
||||
num_nodes: number;
|
||||
export type RewardedSetNodeStatus = "active" | "standby";
|
||||
export interface PagedRewardedSetResponse {
|
||||
nodes: [number, RewardedSetNodeStatus][];
|
||||
start_next_after?: number | null;
|
||||
}
|
||||
export interface RewardingParams {
|
||||
active_set_size: number;
|
||||
interval: IntervalRewardParams;
|
||||
rewarded_set: RewardedSetParams;
|
||||
rewarded_set_size: number;
|
||||
}
|
||||
export interface IntervalRewardParams {
|
||||
active_set_work_factor: Decimal;
|
||||
@@ -944,37 +769,19 @@ export interface IntervalRewardParams {
|
||||
sybil_resistance: Percent;
|
||||
}
|
||||
export type String = string;
|
||||
export interface EpochAssignmentResponse {
|
||||
epoch_id: number;
|
||||
nodes: number[];
|
||||
}
|
||||
export type Uint32 = number;
|
||||
export interface MixStakeSaturationResponse {
|
||||
export interface StakeSaturationResponse {
|
||||
current_saturation?: Decimal | null;
|
||||
mix_id: number;
|
||||
uncapped_saturation?: Decimal | null;
|
||||
}
|
||||
export interface ContractState {
|
||||
owner?: Addr | null;
|
||||
owner: Addr;
|
||||
params: ContractStateParams;
|
||||
rewarding_denom: string;
|
||||
rewarding_validator_address: Addr;
|
||||
vesting_contract_address: Addr;
|
||||
}
|
||||
export interface ContractStateParams {
|
||||
config_score_params: ConfigScoreParams;
|
||||
delegations_params: DelegationsParams;
|
||||
operators_params: OperatorsParams;
|
||||
}
|
||||
export interface ConfigScoreParams {
|
||||
version_score_formula_params: VersionScoreFormulaParams;
|
||||
version_weights: OutdatedVersionWeights;
|
||||
}
|
||||
export interface OperatorsParams {
|
||||
interval_operating_cost: RangedValueForUint128;
|
||||
minimum_pledge: Coin;
|
||||
profit_margin: RangedValueForPercent;
|
||||
}
|
||||
export interface UnbondedMixnodeResponse {
|
||||
mix_id: number;
|
||||
unbonded_info?: UnbondedMixnode | null;
|
||||
@@ -990,17 +797,3 @@ export interface PagedUnbondedMixnodesResponse {
|
||||
per_page: number;
|
||||
start_next_after?: number | null;
|
||||
}
|
||||
export interface UnbondedNodeResponse {
|
||||
details?: UnbondedNymNode | null;
|
||||
node_id: number;
|
||||
}
|
||||
export interface UnbondedNymNode {
|
||||
identity_key: string;
|
||||
node_id: number;
|
||||
owner: Addr;
|
||||
unbonding_height: number;
|
||||
}
|
||||
export interface PagedUnbondedNymNodesResponse {
|
||||
nodes: UnbondedNymNode[];
|
||||
start_next_after?: number | null;
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
/**
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@1.13.3.
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
|
||||
import { ICosmWasmClient, ISigningCosmWasmClient } from "./baseClient";
|
||||
import { StdFee } from "@interchainjs/types";
|
||||
import { InstantiateMsg, ExecuteMsg, Uint128, Percent, Decimal, PledgeCap, MessageSignature, Coin, NodeCostParams, MixNodeConfigUpdate, VestingSpecification, MixNode, Gateway, GatewayConfigUpdate, QueryMsg, Timestamp, Uint64, MigrateMsg, Addr, Account, VestingPeriod, AccountsResponse, BaseVestingAccountInfo, VestingCoinsResponse, AccountVestingCoins, AllDelegationsResponse, VestingDelegation, ContractVersion, ContractBuildInformation, Period, DelegationTimesResponse, NullablePledgeData, PledgeData, OriginalVestingResponse } from "./Vesting.types";
|
||||
import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate";
|
||||
import { StdFee } from "@cosmjs/amino";
|
||||
import { InstantiateMsg, ExecuteMsg, FamilyHead, MessageSignature, Uint128, Percent, Decimal, PledgeCap, Coin, MixNodeCostParams, MixNodeConfigUpdate, VestingSpecification, MixNode, Gateway, GatewayConfigUpdate, QueryMsg, Timestamp, Uint64, MigrateMsg, Addr, Account, VestingPeriod, AccountsResponse, BaseVestingAccountInfo, VestingCoinsResponse, AccountVestingCoins, AllDelegationsResponse, VestingDelegation, ContractVersion, ContractBuildInformation, Period, DelegationTimesResponse, NullablePledgeData, PledgeData, OriginalVestingResponse } from "./Vesting.types";
|
||||
import { GetCw2ContractVersionResponse } from './types';
|
||||
export interface VestingReadOnlyInterface {
|
||||
contractAddress: string;
|
||||
getContractVersion: () => Promise<ContractBuildInformation>;
|
||||
@@ -155,9 +156,10 @@ export interface VestingReadOnlyInterface {
|
||||
}) => Promise<AllDelegationsResponse>;
|
||||
}
|
||||
export class VestingQueryClient implements VestingReadOnlyInterface {
|
||||
client: ICosmWasmClient;
|
||||
client: CosmWasmClient;
|
||||
contractAddress: string;
|
||||
constructor(client: ICosmWasmClient, contractAddress: string) {
|
||||
|
||||
constructor(client: CosmWasmClient, contractAddress: string) {
|
||||
this.client = client;
|
||||
this.contractAddress = contractAddress;
|
||||
this.getContractVersion = this.getContractVersion.bind(this);
|
||||
@@ -187,6 +189,7 @@ export class VestingQueryClient implements VestingReadOnlyInterface {
|
||||
this.getDelegationTimes = this.getDelegationTimes.bind(this);
|
||||
this.getAllDelegations = this.getAllDelegations.bind(this);
|
||||
}
|
||||
|
||||
getContractVersion = async (): Promise<ContractBuildInformation> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
get_contract_version: {}
|
||||
@@ -498,34 +501,56 @@ export class VestingQueryClient implements VestingReadOnlyInterface {
|
||||
export interface VestingInterface extends VestingReadOnlyInterface {
|
||||
contractAddress: string;
|
||||
sender: string;
|
||||
createFamily: ({
|
||||
label
|
||||
}: {
|
||||
label: string;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
joinFamily: ({
|
||||
familyHead,
|
||||
joinPermit
|
||||
}: {
|
||||
familyHead: FamilyHead;
|
||||
joinPermit: MessageSignature;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
leaveFamily: ({
|
||||
familyHead
|
||||
}: {
|
||||
familyHead: FamilyHead;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
kickFamilyMember: ({
|
||||
member
|
||||
}: {
|
||||
member: string;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
trackReward: ({
|
||||
address,
|
||||
amount
|
||||
}: {
|
||||
address: string;
|
||||
amount: Coin;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
claimOperatorReward: (fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
claimOperatorReward: (fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
claimDelegatorReward: ({
|
||||
mixId
|
||||
}: {
|
||||
mixId: number;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
updateMixnodeCostParams: ({
|
||||
newCosts
|
||||
}: {
|
||||
newCosts: NodeCostParams;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
newCosts: MixNodeCostParams;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
updateMixnodeConfig: ({
|
||||
newConfig
|
||||
}: {
|
||||
newConfig: MixNodeConfigUpdate;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
updateMixnetAddress: ({
|
||||
address
|
||||
}: {
|
||||
address: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
delegateToMixnode: ({
|
||||
amount,
|
||||
mixId,
|
||||
@@ -534,14 +559,14 @@ export interface VestingInterface extends VestingReadOnlyInterface {
|
||||
amount: Coin;
|
||||
mixId: number;
|
||||
onBehalfOf?: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
undelegateFromMixnode: ({
|
||||
mixId,
|
||||
onBehalfOf
|
||||
}: {
|
||||
mixId: number;
|
||||
onBehalfOf?: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
createAccount: ({
|
||||
cap,
|
||||
ownerAddress,
|
||||
@@ -552,12 +577,12 @@ export interface VestingInterface extends VestingReadOnlyInterface {
|
||||
ownerAddress: string;
|
||||
stakingAddress?: string;
|
||||
vestingSpec?: VestingSpecification;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
withdrawVestedCoins: ({
|
||||
amount
|
||||
}: {
|
||||
amount: Coin;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
trackUndelegation: ({
|
||||
amount,
|
||||
mixId,
|
||||
@@ -566,7 +591,7 @@ export interface VestingInterface extends VestingReadOnlyInterface {
|
||||
amount: Coin;
|
||||
mixId: number;
|
||||
owner: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
bondMixnode: ({
|
||||
amount,
|
||||
costParams,
|
||||
@@ -574,35 +599,35 @@ export interface VestingInterface extends VestingReadOnlyInterface {
|
||||
ownerSignature
|
||||
}: {
|
||||
amount: Coin;
|
||||
costParams: NodeCostParams;
|
||||
costParams: MixNodeCostParams;
|
||||
mixNode: MixNode;
|
||||
ownerSignature: MessageSignature;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
pledgeMore: ({
|
||||
amount
|
||||
}: {
|
||||
amount: Coin;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
decreasePledge: ({
|
||||
amount
|
||||
}: {
|
||||
amount: Coin;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
unbondMixnode: (fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
unbondMixnode: (fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
trackUnbondMixnode: ({
|
||||
amount,
|
||||
owner
|
||||
}: {
|
||||
amount: Coin;
|
||||
owner: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
trackDecreasePledge: ({
|
||||
amount,
|
||||
owner
|
||||
}: {
|
||||
amount: Coin;
|
||||
owner: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
bondGateway: ({
|
||||
amount,
|
||||
gateway,
|
||||
@@ -611,59 +636,52 @@ export interface VestingInterface extends VestingReadOnlyInterface {
|
||||
amount: Coin;
|
||||
gateway: Gateway;
|
||||
ownerSignature: MessageSignature;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
unbondGateway: (fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
unbondGateway: (fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
trackUnbondGateway: ({
|
||||
amount,
|
||||
owner
|
||||
}: {
|
||||
amount: Coin;
|
||||
owner: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
updateGatewayConfig: ({
|
||||
newConfig
|
||||
}: {
|
||||
newConfig: GatewayConfigUpdate;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
transferOwnership: ({
|
||||
toAddress
|
||||
}: {
|
||||
toAddress: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
updateStakingAddress: ({
|
||||
toAddress
|
||||
}: {
|
||||
toAddress?: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
updateLockedPledgeCap: ({
|
||||
address,
|
||||
cap
|
||||
}: {
|
||||
address: string;
|
||||
cap: PledgeCap;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
trackMigratedMixnode: ({
|
||||
owner
|
||||
}: {
|
||||
owner: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
trackMigratedDelegation: ({
|
||||
mixId,
|
||||
owner
|
||||
}: {
|
||||
mixId: number;
|
||||
owner: string;
|
||||
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
|
||||
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
|
||||
}
|
||||
export class VestingClient extends VestingQueryClient implements VestingInterface {
|
||||
client: ISigningCosmWasmClient;
|
||||
client: SigningCosmWasmClient;
|
||||
sender: string;
|
||||
contractAddress: string;
|
||||
constructor(client: ISigningCosmWasmClient, sender: string, contractAddress: string) {
|
||||
|
||||
constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) {
|
||||
super(client, contractAddress);
|
||||
this.client = client;
|
||||
this.sender = sender;
|
||||
this.contractAddress = contractAddress;
|
||||
this.createFamily = this.createFamily.bind(this);
|
||||
this.joinFamily = this.joinFamily.bind(this);
|
||||
this.leaveFamily = this.leaveFamily.bind(this);
|
||||
this.kickFamilyMember = this.kickFamilyMember.bind(this);
|
||||
this.trackReward = this.trackReward.bind(this);
|
||||
this.claimOperatorReward = this.claimOperatorReward.bind(this);
|
||||
this.claimDelegatorReward = this.claimDelegatorReward.bind(this);
|
||||
@@ -688,71 +706,117 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
|
||||
this.transferOwnership = this.transferOwnership.bind(this);
|
||||
this.updateStakingAddress = this.updateStakingAddress.bind(this);
|
||||
this.updateLockedPledgeCap = this.updateLockedPledgeCap.bind(this);
|
||||
this.trackMigratedMixnode = this.trackMigratedMixnode.bind(this);
|
||||
this.trackMigratedDelegation = this.trackMigratedDelegation.bind(this);
|
||||
}
|
||||
|
||||
createFamily = async ({
|
||||
label
|
||||
}: {
|
||||
label: string;
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
create_family: {
|
||||
label
|
||||
}
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
joinFamily = async ({
|
||||
familyHead,
|
||||
joinPermit
|
||||
}: {
|
||||
familyHead: FamilyHead;
|
||||
joinPermit: MessageSignature;
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
join_family: {
|
||||
family_head: familyHead,
|
||||
join_permit: joinPermit
|
||||
}
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
leaveFamily = async ({
|
||||
familyHead
|
||||
}: {
|
||||
familyHead: FamilyHead;
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
leave_family: {
|
||||
family_head: familyHead
|
||||
}
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
kickFamilyMember = async ({
|
||||
member
|
||||
}: {
|
||||
member: string;
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
kick_family_member: {
|
||||
member
|
||||
}
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
trackReward = async ({
|
||||
address,
|
||||
amount
|
||||
}: {
|
||||
address: string;
|
||||
amount: Coin;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
track_reward: {
|
||||
address,
|
||||
amount
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
claimOperatorReward = async (fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
claimOperatorReward = async (fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
claim_operator_reward: {}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
claimDelegatorReward = async ({
|
||||
mixId
|
||||
}: {
|
||||
mixId: number;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
claim_delegator_reward: {
|
||||
mix_id: mixId
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
updateMixnodeCostParams = async ({
|
||||
newCosts
|
||||
}: {
|
||||
newCosts: NodeCostParams;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
newCosts: MixNodeCostParams;
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
update_mixnode_cost_params: {
|
||||
new_costs: newCosts
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
updateMixnodeConfig = async ({
|
||||
newConfig
|
||||
}: {
|
||||
newConfig: MixNodeConfigUpdate;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
update_mixnode_config: {
|
||||
new_config: newConfig
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
updateMixnetAddress = async ({
|
||||
address
|
||||
}: {
|
||||
address: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
update_mixnet_address: {
|
||||
address
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
delegateToMixnode = async ({
|
||||
amount,
|
||||
@@ -762,14 +826,14 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
|
||||
amount: Coin;
|
||||
mixId: number;
|
||||
onBehalfOf?: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
delegate_to_mixnode: {
|
||||
amount,
|
||||
mix_id: mixId,
|
||||
on_behalf_of: onBehalfOf
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
undelegateFromMixnode = async ({
|
||||
mixId,
|
||||
@@ -777,13 +841,13 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
|
||||
}: {
|
||||
mixId: number;
|
||||
onBehalfOf?: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
undelegate_from_mixnode: {
|
||||
mix_id: mixId,
|
||||
on_behalf_of: onBehalfOf
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
createAccount = async ({
|
||||
cap,
|
||||
@@ -795,7 +859,7 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
|
||||
ownerAddress: string;
|
||||
stakingAddress?: string;
|
||||
vestingSpec?: VestingSpecification;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
create_account: {
|
||||
cap,
|
||||
@@ -803,18 +867,18 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
|
||||
staking_address: stakingAddress,
|
||||
vesting_spec: vestingSpec
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
withdrawVestedCoins = async ({
|
||||
amount
|
||||
}: {
|
||||
amount: Coin;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
withdraw_vested_coins: {
|
||||
amount
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
trackUndelegation = async ({
|
||||
amount,
|
||||
@@ -824,14 +888,14 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
|
||||
amount: Coin;
|
||||
mixId: number;
|
||||
owner: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
track_undelegation: {
|
||||
amount,
|
||||
mix_id: mixId,
|
||||
owner
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
bondMixnode = async ({
|
||||
amount,
|
||||
@@ -840,10 +904,10 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
|
||||
ownerSignature
|
||||
}: {
|
||||
amount: Coin;
|
||||
costParams: NodeCostParams;
|
||||
costParams: MixNodeCostParams;
|
||||
mixNode: MixNode;
|
||||
ownerSignature: MessageSignature;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
bond_mixnode: {
|
||||
amount,
|
||||
@@ -851,34 +915,34 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
|
||||
mix_node: mixNode,
|
||||
owner_signature: ownerSignature
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
pledgeMore = async ({
|
||||
amount
|
||||
}: {
|
||||
amount: Coin;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
pledge_more: {
|
||||
amount
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
decreasePledge = async ({
|
||||
amount
|
||||
}: {
|
||||
amount: Coin;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
decrease_pledge: {
|
||||
amount
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
unbondMixnode = async (fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
unbondMixnode = async (fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
unbond_mixnode: {}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
trackUnbondMixnode = async ({
|
||||
amount,
|
||||
@@ -886,13 +950,13 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
|
||||
}: {
|
||||
amount: Coin;
|
||||
owner: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
track_unbond_mixnode: {
|
||||
amount,
|
||||
owner
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
trackDecreasePledge = async ({
|
||||
amount,
|
||||
@@ -900,13 +964,13 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
|
||||
}: {
|
||||
amount: Coin;
|
||||
owner: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
track_decrease_pledge: {
|
||||
amount,
|
||||
owner
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
bondGateway = async ({
|
||||
amount,
|
||||
@@ -916,19 +980,19 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
|
||||
amount: Coin;
|
||||
gateway: Gateway;
|
||||
ownerSignature: MessageSignature;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
bond_gateway: {
|
||||
amount,
|
||||
gateway,
|
||||
owner_signature: ownerSignature
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
unbondGateway = async (fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
unbondGateway = async (fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
unbond_gateway: {}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
trackUnbondGateway = async ({
|
||||
amount,
|
||||
@@ -936,46 +1000,46 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
|
||||
}: {
|
||||
amount: Coin;
|
||||
owner: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
track_unbond_gateway: {
|
||||
amount,
|
||||
owner
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
updateGatewayConfig = async ({
|
||||
newConfig
|
||||
}: {
|
||||
newConfig: GatewayConfigUpdate;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
update_gateway_config: {
|
||||
new_config: newConfig
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
transferOwnership = async ({
|
||||
toAddress
|
||||
}: {
|
||||
toAddress: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
transfer_ownership: {
|
||||
to_address: toAddress
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
updateStakingAddress = async ({
|
||||
toAddress
|
||||
}: {
|
||||
toAddress?: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
update_staking_address: {
|
||||
to_address: toAddress
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
updateLockedPledgeCap = async ({
|
||||
address,
|
||||
@@ -983,37 +1047,12 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
|
||||
}: {
|
||||
address: string;
|
||||
cap: PledgeCap;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
update_locked_pledge_cap: {
|
||||
address,
|
||||
cap
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
}, fee, memo, _funds);
|
||||
};
|
||||
trackMigratedMixnode = async ({
|
||||
owner
|
||||
}: {
|
||||
owner: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
track_migrated_mixnode: {
|
||||
owner
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
trackMigratedDelegation = async ({
|
||||
mixId,
|
||||
owner
|
||||
}: {
|
||||
mixId: number;
|
||||
owner: string;
|
||||
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
|
||||
return await this.client.execute(this.sender, this.contractAddress, {
|
||||
track_migrated_delegation: {
|
||||
mix_id: mixId,
|
||||
owner
|
||||
}
|
||||
}, fee_, memo_, funds_);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@1.13.3.
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
@@ -9,6 +9,23 @@ export interface InstantiateMsg {
|
||||
mixnet_contract_address: string;
|
||||
}
|
||||
export type ExecuteMsg = {
|
||||
create_family: {
|
||||
label: string;
|
||||
};
|
||||
} | {
|
||||
join_family: {
|
||||
family_head: FamilyHead;
|
||||
join_permit: MessageSignature;
|
||||
};
|
||||
} | {
|
||||
leave_family: {
|
||||
family_head: FamilyHead;
|
||||
};
|
||||
} | {
|
||||
kick_family_member: {
|
||||
member: string;
|
||||
};
|
||||
} | {
|
||||
track_reward: {
|
||||
address: string;
|
||||
amount: Coin;
|
||||
@@ -21,7 +38,7 @@ export type ExecuteMsg = {
|
||||
};
|
||||
} | {
|
||||
update_mixnode_cost_params: {
|
||||
new_costs: NodeCostParams;
|
||||
new_costs: MixNodeCostParams;
|
||||
};
|
||||
} | {
|
||||
update_mixnode_config: {
|
||||
@@ -62,7 +79,7 @@ export type ExecuteMsg = {
|
||||
} | {
|
||||
bond_mixnode: {
|
||||
amount: Coin;
|
||||
cost_params: NodeCostParams;
|
||||
cost_params: MixNodeCostParams;
|
||||
mix_node: MixNode;
|
||||
owner_signature: MessageSignature;
|
||||
};
|
||||
@@ -116,16 +133,9 @@ export type ExecuteMsg = {
|
||||
address: string;
|
||||
cap: PledgeCap;
|
||||
};
|
||||
} | {
|
||||
track_migrated_mixnode: {
|
||||
owner: string;
|
||||
};
|
||||
} | {
|
||||
track_migrated_delegation: {
|
||||
mix_id: number;
|
||||
owner: string;
|
||||
};
|
||||
};
|
||||
export type FamilyHead = string;
|
||||
export type MessageSignature = number[];
|
||||
export type Uint128 = string;
|
||||
export type Percent = Decimal;
|
||||
export type Decimal = string;
|
||||
@@ -134,12 +144,12 @@ export type PledgeCap = {
|
||||
} | {
|
||||
absolute: Uint128;
|
||||
};
|
||||
export type MessageSignature = number[];
|
||||
export interface Coin {
|
||||
amount: Uint128;
|
||||
denom: string;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
export interface NodeCostParams {
|
||||
export interface MixNodeCostParams {
|
||||
interval_operating_cost: Coin;
|
||||
profit_margin_percent: Percent;
|
||||
}
|
||||
@@ -343,12 +353,9 @@ export interface ContractVersion {
|
||||
export interface ContractBuildInformation {
|
||||
build_timestamp: string;
|
||||
build_version: string;
|
||||
cargo_debug?: string;
|
||||
cargo_opt_level?: string;
|
||||
commit_branch: string;
|
||||
commit_sha: string;
|
||||
commit_timestamp: string;
|
||||
contract_name?: string;
|
||||
rustc_version: string;
|
||||
}
|
||||
export type Period = "before" | {
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
/**
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@1.13.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
|
||||
|
||||
import { StdFee, Coin } from '@interchainjs/types';
|
||||
import { DirectSigner } from '@interchainjs/cosmos';
|
||||
import { getSmartContractState } from 'interchainjs/cosmwasm/wasm/v1/query.rpc.func';
|
||||
import { executeContract } from 'interchainjs/cosmwasm/wasm/v1/tx.rpc.func';
|
||||
import { QuerySmartContractStateRequest, QuerySmartContractStateResponse } from 'interchainjs/cosmwasm/wasm/v1/query';
|
||||
import { MsgExecuteContract } from 'interchainjs/cosmwasm/wasm/v1/tx';
|
||||
import { Chain } from '@chain-registry/v2-types';
|
||||
|
||||
// Encoding utility functions
|
||||
const fromUint8Array = <T>(uint8Array: Uint8Array): T => {
|
||||
const text = new TextDecoder().decode(uint8Array);
|
||||
return JSON.parse(text);
|
||||
};
|
||||
|
||||
const toUint8Array = (obj: any): Uint8Array => {
|
||||
const text = JSON.stringify(obj);
|
||||
return new TextEncoder().encode(text);
|
||||
};
|
||||
|
||||
// Chain registry configuration
|
||||
// The amount under gasPrice represents gas price per unit
|
||||
export interface ChainConfig {
|
||||
chain?: Chain;
|
||||
gasPrice?: {
|
||||
denom: string;
|
||||
amount: string;
|
||||
};
|
||||
}
|
||||
|
||||
// Gas fee calculation utilities
|
||||
export const calculateGasFromChain = (chain: Chain, gasAmount: string): StdFee => {
|
||||
try {
|
||||
const feeTokens = chain.fees?.feeTokens;
|
||||
|
||||
if (feeTokens && feeTokens.length > 0) {
|
||||
const primaryToken = feeTokens[0];
|
||||
// v2 chain-registry uses camelCase: averageGasPrice, lowGasPrice, fixedMinGasPrice
|
||||
const gasPrice = primaryToken.averageGasPrice || primaryToken.lowGasPrice || primaryToken.fixedMinGasPrice || 0.025;
|
||||
const gasAmountNum = parseInt(gasAmount);
|
||||
const feeAmount = Math.ceil(gasAmountNum * gasPrice).toString();
|
||||
|
||||
return {
|
||||
amount: [{
|
||||
denom: primaryToken.denom,
|
||||
amount: feeAmount
|
||||
}],
|
||||
gas: gasAmount
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to calculate gas from chain registry:', error);
|
||||
}
|
||||
|
||||
// Fallback to default
|
||||
return { amount: [], gas: gasAmount };
|
||||
};
|
||||
|
||||
// Default gas amount - users can easily change this
|
||||
export let DEFAULT_GAS_AMOUNT = '200000';
|
||||
|
||||
// Allow users to set their preferred default gas amount
|
||||
export const setDefaultGasAmount = (gasAmount: string): void => {
|
||||
DEFAULT_GAS_AMOUNT = gasAmount;
|
||||
};
|
||||
|
||||
// Get current default gas amount
|
||||
export const getDefaultGasAmount = (): string => DEFAULT_GAS_AMOUNT;
|
||||
|
||||
export const getAutoGasFee = (chainConfig?: ChainConfig): StdFee => {
|
||||
const gasAmount = DEFAULT_GAS_AMOUNT;
|
||||
|
||||
if (chainConfig?.chain) {
|
||||
return calculateGasFromChain(chainConfig.chain, gasAmount);
|
||||
}
|
||||
|
||||
if (chainConfig?.gasPrice) {
|
||||
const gasAmountNum = parseInt(gasAmount);
|
||||
const gasPriceNum = parseFloat(chainConfig.gasPrice.amount);
|
||||
const feeAmount = Math.ceil(gasAmountNum * gasPriceNum).toString();
|
||||
|
||||
return {
|
||||
amount: [{
|
||||
denom: chainConfig.gasPrice.denom,
|
||||
amount: feeAmount
|
||||
}],
|
||||
gas: gasAmount
|
||||
};
|
||||
}
|
||||
|
||||
// Fallback: no fee tokens, just gas amount
|
||||
return { amount: [], gas: gasAmount };
|
||||
};
|
||||
|
||||
// InterchainJS interfaces for CosmWasm clients
|
||||
export interface ICosmWasmClient {
|
||||
queryContractSmart(contractAddr: string, query: any): Promise<any>;
|
||||
}
|
||||
|
||||
export interface ISigningCosmWasmClient extends ICosmWasmClient {
|
||||
execute(
|
||||
sender: string,
|
||||
contractAddress: string,
|
||||
msg: any,
|
||||
fee?: number | StdFee | "auto",
|
||||
memo?: string,
|
||||
funds?: Coin[],
|
||||
chainConfig?: ChainConfig
|
||||
): Promise<any>;
|
||||
}
|
||||
|
||||
export interface ISigningClient {
|
||||
signAndBroadcast(
|
||||
signerAddress: string,
|
||||
messages: any[],
|
||||
fee: number | StdFee | "auto",
|
||||
memo?: string
|
||||
): Promise<any>;
|
||||
}
|
||||
|
||||
// Helper functions to create InterchainJS clients
|
||||
export function getCosmWasmClient(rpcEndpoint: string): ICosmWasmClient {
|
||||
return {
|
||||
queryContractSmart: async (contractAddr: string, query: any) => {
|
||||
// Create the request object
|
||||
const request: QuerySmartContractStateRequest = {
|
||||
address: contractAddr,
|
||||
queryData: toUint8Array(query)
|
||||
};
|
||||
|
||||
// Execute the query using InterchainJS
|
||||
const response: QuerySmartContractStateResponse = await getSmartContractState(rpcEndpoint, request);
|
||||
|
||||
// Parse and return the result
|
||||
return fromUint8Array(response.data);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function getSigningCosmWasmClient(signingClient: DirectSigner, rpcEndpoint?: string): ISigningCosmWasmClient {
|
||||
return {
|
||||
queryContractSmart: async (contractAddr: string, query: any) => {
|
||||
if (!rpcEndpoint) {
|
||||
throw new Error('rpcEndpoint is required for queryContractSmart in signing client');
|
||||
}
|
||||
const request: QuerySmartContractStateRequest = {
|
||||
address: contractAddr,
|
||||
queryData: toUint8Array(query)
|
||||
};
|
||||
const response: QuerySmartContractStateResponse = await getSmartContractState(rpcEndpoint, request);
|
||||
return fromUint8Array(response.data);
|
||||
},
|
||||
execute: async (
|
||||
sender: string,
|
||||
contractAddress: string,
|
||||
msg: any,
|
||||
fee?: number | StdFee | "auto",
|
||||
memo?: string,
|
||||
funds?: Coin[],
|
||||
chainConfig?: ChainConfig
|
||||
) => {
|
||||
// Handle fee conversion
|
||||
let finalFee: StdFee;
|
||||
if (typeof fee === 'number') {
|
||||
finalFee = { amount: [], gas: fee.toString() };
|
||||
} else if (fee === 'auto') {
|
||||
finalFee = getAutoGasFee(chainConfig);
|
||||
} else if (fee) {
|
||||
finalFee = fee;
|
||||
} else {
|
||||
finalFee = getAutoGasFee(chainConfig);
|
||||
}
|
||||
|
||||
// Create the message object
|
||||
const message: MsgExecuteContract = {
|
||||
sender,
|
||||
contract: contractAddress,
|
||||
msg: toUint8Array(msg),
|
||||
funds: funds || []
|
||||
};
|
||||
|
||||
// Execute the transaction using InterchainJS
|
||||
const result = await executeContract(
|
||||
signingClient as any,
|
||||
sender,
|
||||
message,
|
||||
finalFee,
|
||||
memo || ''
|
||||
);
|
||||
|
||||
return result;
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,48 +1,35 @@
|
||||
/**
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@1.13.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
|
||||
*/
|
||||
|
||||
import * as _0 from "./Ecash.types";
|
||||
import * as _1 from "./Ecash.client";
|
||||
import * as _2 from "./CoconutDkg.types";
|
||||
import * as _3 from "./CoconutDkg.client";
|
||||
import * as _4 from "./Mixnet.types";
|
||||
import * as _5 from "./Mixnet.client";
|
||||
import * as _6 from "./Cw3FlexMultisig.types";
|
||||
import * as _7 from "./Cw3FlexMultisig.client";
|
||||
import * as _8 from "./Cw4Group.types";
|
||||
import * as _9 from "./Cw4Group.client";
|
||||
import * as _10 from "./Vesting.types";
|
||||
import * as _11 from "./Vesting.client";
|
||||
import * as _12 from "./baseClient";
|
||||
import * as _0 from './CoconutBandwidth.types';
|
||||
import * as _1 from './CoconutBandwidth.client';
|
||||
import * as _2 from './CoconutDkg.types';
|
||||
import * as _3 from './CoconutDkg.client';
|
||||
import * as _4 from './Mixnet.types';
|
||||
import * as _5 from './Mixnet.client';
|
||||
import * as _6 from './Cw3FlexMultisig.types';
|
||||
import * as _7 from './Cw3FlexMultisig.client';
|
||||
import * as _8 from './Cw4Group.types';
|
||||
import * as _9 from './Cw4Group.client';
|
||||
import * as _10 from './NameService.types';
|
||||
import * as _11 from './NameService.client';
|
||||
import * as _12 from './ServiceProviderDirectory.types';
|
||||
import * as _13 from './ServiceProviderDirectory.client';
|
||||
import * as _14 from './Vesting.types';
|
||||
import * as _15 from './Vesting.client';
|
||||
export * from './types';
|
||||
|
||||
/** @namespace */
|
||||
export namespace contracts {
|
||||
export const Ecash = {
|
||||
..._0,
|
||||
..._1
|
||||
};
|
||||
export const CoconutDkg = {
|
||||
..._2,
|
||||
..._3
|
||||
};
|
||||
export const Mixnet = {
|
||||
..._4,
|
||||
..._5
|
||||
};
|
||||
export const Cw3FlexMultisig = {
|
||||
..._6,
|
||||
..._7
|
||||
};
|
||||
export const Cw4Group = {
|
||||
..._8,
|
||||
..._9
|
||||
};
|
||||
export const Vesting = {
|
||||
..._10,
|
||||
..._11
|
||||
};
|
||||
export const baseClient = {
|
||||
..._12
|
||||
};
|
||||
}
|
||||
export const CoconutBandwidth = { ..._0, ..._1 };
|
||||
export const CoconutDkg = { ..._2, ..._3 };
|
||||
export const Mixnet = { ..._4, ..._5 };
|
||||
export const Cw3FlexMultisig = { ..._6, ..._7 };
|
||||
export const Cw4Group = { ..._8, ..._9 };
|
||||
export const NameService = { ..._10, ..._11 };
|
||||
export const ServiceProviderDirectory = { ..._12, ..._13 };
|
||||
export const Vesting = { ..._14, ..._15 };
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/sdk-example-plain-html-parcel",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.4-rc.2",
|
||||
"description": "An example project that uses WASM and plain HTML bundled with Parcel v2",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
@@ -15,7 +15,7 @@
|
||||
"tsc:watch": "tsc --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nymproject/sdk": ">=1.4.1-rc1 || ^1"
|
||||
"@nymproject/sdk": ">=1.2.2-rc.0 || ^1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^27.0.1",
|
||||
@@ -41,4 +41,4 @@
|
||||
"private": false,
|
||||
"browserslist": "> 0.5%, last 2 versions, not dead",
|
||||
"source": "src/index.html"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/sdk-example-plain-html",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.4-rc.2",
|
||||
"description": "An example project that uses WASM and plain HTML",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
@@ -16,7 +16,7 @@
|
||||
"tsc:watch": "tsc --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nymproject/sdk": ">=1.4.1-rc1 || ^1"
|
||||
"@nymproject/sdk": ">=1.2.2-rc.0 || ^1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.15.0",
|
||||
@@ -62,4 +62,4 @@
|
||||
"webpack-merge": "^5.8.0"
|
||||
},
|
||||
"private": false
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/sdk-example-react-webpack-wasm",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.4-rc.2",
|
||||
"description": "An example project that uses WASM, React, Webpack, Typescript and the Nym theme + components library",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
@@ -20,7 +20,7 @@
|
||||
"@mui/lab": "^5.0.0-alpha.72",
|
||||
"@mui/material": "^5.0.1",
|
||||
"@mui/styles": "^5.0.1",
|
||||
"@nymproject/sdk": ">=1.4.1-rc1 || ^1",
|
||||
"@nymproject/sdk": ">=1.2.2-rc.0 || ^1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-dropzone": "^14.2.3",
|
||||
@@ -90,4 +90,4 @@
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/sdk-example-chrome-extension",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.4-rc.2",
|
||||
"description": "This is an example of how Nym can be used within the context of a Chrome extension.",
|
||||
"license": "ISC",
|
||||
"author": "",
|
||||
@@ -9,7 +9,7 @@
|
||||
"build": "webpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nymproject/sdk": ">=1.4.1-rc1 || ^1"
|
||||
"@nymproject/sdk": ">=1.2.2-rc.0 || ^1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-webpack-plugin": "^4.0.0",
|
||||
@@ -18,4 +18,4 @@
|
||||
"webpack-cli": "^5.1.4"
|
||||
},
|
||||
"private": false
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/sdk-example-firefox-extension",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.4-rc.2",
|
||||
"description": "This is an example of how Nym can be used within the context of a Firefox extension.",
|
||||
"license": "ISC",
|
||||
"author": "",
|
||||
@@ -9,7 +9,7 @@
|
||||
"build": "yarn webpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nymproject/sdk": ">=1.4.1-rc1 || ^1"
|
||||
"@nymproject/sdk": ">=1.2.2-rc.0 || ^1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
@@ -18,4 +18,4 @@
|
||||
"worker-loader": "^3.0.8"
|
||||
},
|
||||
"private": false
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/mix-fetch-example-parcel",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.4-rc.2",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "parcel build --no-cache --no-content-hash",
|
||||
@@ -8,9 +8,9 @@
|
||||
"start": "parcel --no-cache"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nymproject/mix-fetch": ">=1.4.1-rc1 || ^1",
|
||||
"@nymproject/mix-fetch": ">=1.2.2-rc.0 || ^1",
|
||||
"parcel": "^2.9.3"
|
||||
},
|
||||
"private": false,
|
||||
"source": "src/index.html"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/sdk-example-node-tester-plain-html-parcel",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.4-rc.2",
|
||||
"description": "An example project that uses WASM and plain HTML bundled with Parcel v2",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
@@ -15,7 +15,7 @@
|
||||
"tsc:watch": "tsc --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nymproject/sdk": ">=1.4.1-rc1 || ^1"
|
||||
"@nymproject/sdk": ">=1.2.2-rc.0 || ^1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^27.0.1",
|
||||
@@ -41,4 +41,4 @@
|
||||
"private": false,
|
||||
"browserslist": "> 0.5%, last 2 versions, not dead",
|
||||
"source": "src/index.html"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/sdk-example-node-tester-plain-html",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.4-rc.2",
|
||||
"description": "An example project that uses WASM node tester and plain HTML",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
@@ -16,7 +16,7 @@
|
||||
"tsc:watch": "tsc --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nymproject/sdk": ">=1.4.1-rc1 || ^1"
|
||||
"@nymproject/sdk": ">=1.2.2-rc.0 || ^1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.15.0",
|
||||
@@ -62,4 +62,4 @@
|
||||
"webpack-merge": "^5.8.0"
|
||||
},
|
||||
"private": false
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/sdk-example-node-tester-react",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.4-rc.2",
|
||||
"description": "An example project that uses WASM node tester and React",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
@@ -11,10 +11,10 @@
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@mui/icons-material": "^5.14.0",
|
||||
"@mui/material": "^5.14.0",
|
||||
"@nymproject/sdk": ">=1.4.1-rc1 || ^1",
|
||||
"@nymproject/sdk": ">=1.2.2-rc.0 || ^1",
|
||||
"parcel": "^2.9.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"private": false
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/mix-fetch-node",
|
||||
"version": "1.4.1-rc0",
|
||||
"version": "1.4.0-rc.0",
|
||||
"description": "This package is a drop-in replacement for `fetch` in NodeJS to send HTTP requests over the Nym Mixnet.",
|
||||
"license": "Apache-2.0",
|
||||
"author": "Nym Technologies SA",
|
||||
@@ -28,7 +28,7 @@
|
||||
"tsc": "tsc --noEmit true"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nymproject/mix-fetch-wasm-node": ">=1.2.5-rc.0 || ^1",
|
||||
"@nymproject/mix-fetch-wasm-node": ">=1.2.4-rc.2 || ^1",
|
||||
"comlink": "^4.3.1",
|
||||
"fake-indexeddb": "^5.0.0",
|
||||
"node-fetch": "^3.3.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/mix-fetch-tester-webpack",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.4-rc.2",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "webpack build --progress --config webpack.prod.js",
|
||||
@@ -8,7 +8,7 @@
|
||||
"start": "webpack serve --progress --port 3000"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nymproject/mix-fetch": ">=1.4.1-rc1 || ^1"
|
||||
"@nymproject/mix-fetch": ">=1.2.2-rc.0 || ^1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.22.10",
|
||||
@@ -55,4 +55,4 @@
|
||||
"webpack-merge": "^5.9.0"
|
||||
},
|
||||
"private": false
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nymproject/mix-fetch-tester-parcel",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.4-rc.2",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "npx parcel build --no-cache --no-content-hash",
|
||||
@@ -8,8 +8,8 @@
|
||||
"start": "npx parcel --no-cache"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nymproject/mix-fetch": ">=1.4.1-rc1 || ^1"
|
||||
"@nymproject/mix-fetch": ">=1.2.2-rc.0 || ^1"
|
||||
},
|
||||
"private": false,
|
||||
"source": "../src/index.html"
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,6 @@ async function main() {
|
||||
|
||||
// const addr =
|
||||
// 'EVdJ66jqpoVzmktVecy5UJxsTCEWo5gMn5zDZR7Hm8jy.GXNpoX7RcYcxKvBkV3dSHqC78WaPuWieweRPWzYqNhh5@GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ';
|
||||
// const addr = '7Y9eyF1p1JmzHnd7TVZufnQHkh93ASc9sRBCFY57ZGr8.F8KPyVMVqFQ5yJC3LqeP2ZC7fukzj9a1T426rjo432yT@q2A2cbooyC16YJzvdYaSMH9X3cSiieZNtfBr8cE8Fi1';
|
||||
const addr = undefined;
|
||||
|
||||
appendOutput('About to set up mixFetch...');
|
||||
@@ -55,12 +54,12 @@ async function main() {
|
||||
appendOutput(JSON.stringify(resp, null, 2));
|
||||
appendOutput(JSON.stringify({ text }, null, 2));
|
||||
|
||||
// console.log('disconnecting');
|
||||
// await disconnectMixFetch();
|
||||
// console.log('disconnected! all further usages should fail');
|
||||
console.log('disconnecting');
|
||||
await disconnectMixFetch();
|
||||
console.log('disconnected! all further usages should fail');
|
||||
|
||||
// get an image
|
||||
url = 'https://matrix.org/assets/frontpage/github-mark.svg';
|
||||
url = 'https://nymtech.net/favicon.svg';
|
||||
resp = await mixFetch(url, args);
|
||||
console.log({ resp });
|
||||
const buffer = await resp.arrayBuffer();
|
||||
|
||||
@@ -35,8 +35,7 @@ module.exports = mergeWithRules({
|
||||
{
|
||||
// copy the WASM files, because webpack doesn't do this automatically even though there are
|
||||
// `new URL(..., import.meta.url)` statements in the web worker
|
||||
// from: path.resolve(path.dirname(require.resolve('@nymproject/mix-fetch/package.json')), 'dist/esm/*.wasm'),
|
||||
from: path.resolve(path.dirname(require.resolve('@nymproject/mix-fetch/package.json')), '*.wasm'),
|
||||
from: path.resolve(path.dirname(require.resolve('@nymproject/mix-fetch/package.json')), 'dist/esm/*.wasm'),
|
||||
to: '[name][ext]',
|
||||
},
|
||||
],
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user