Compare commits

..

116 Commits

Author SHA1 Message Date
Mark Sinclair 88442c73ec Bump node tester version and add additional yarn install step to fix linting 2025-11-07 20:24:38 +00:00
Mark Sinclair 95168ac280 Update ci-nym-wallet-storybook.yml 2025-11-07 20:13:36 +00:00
Mark Sinclair 2d0b38ed12 Update ci-lint-typescript.yml 2025-11-07 19:49:22 +00:00
Mark Sinclair 18b83e437a Update ci-lint-typescript.yml 2025-11-07 19:18:56 +00:00
Mark Sinclair 1fd73d7dc4 update yarn lock file after TS SDK 1.4.1 publish 2025-11-07 18:27:23 +00:00
Mark Sinclair 4041e3e95c update docs dependencies to SDK 1.4.1 2025-11-07 18:25:04 +00:00
Mark Sinclair b4046a8969 TS SDK 1.4.1 release 2025-11-07 17:48:08 +00:00
Mark Sinclair ea36ef525a update example docs 2025-11-07 16:55:42 +00:00
Mark Sinclair e76986e607 TS SDK 1.4.1-rc3 2025-11-07 16:15:56 +00:00
Mark Sinclair 1d85cf1ad8 improve wasm js tests 2025-11-07 16:13:33 +00:00
Mark Sinclair b49edba86d wasm: rename main to main_js to avoid collision errors in exporting main from tests
see https://github.com/wasm-bindgen/wasm-bindgen/issues/2206
2025-11-07 16:13:06 +00:00
Mark Sinclair 00571c3892 ts-sdk: fix minimatch dependency and correct casing on selfAddress function call 2025-11-07 14:30:06 +00:00
Mark Sinclair 0257cb050a TS SDK 1.4.1-rc2 2025-11-07 14:29:19 +00:00
Mark Sinclair 503b7c5307 add back version complexity for CI 2025-11-05 15:59:51 +00:00
Mark Sinclair a86b3a3ee3 simplify version dependencies and add dist to dev mode 2025-11-05 15:46:53 +00:00
Mark Sinclair 6841516bf2 TS SDK 1.4.1-rc1 2025-11-05 12:23:45 +00:00
Mark Sinclair 0e97d6c040 limit packages published to only wasm clients 2025-11-04 19:41:45 +00:00
Mark Sinclair 854dccd79c bump versions to rc0 2025-11-04 19:40:04 +00:00
Mark Sinclair a792313b68 try disable typedoc because of minimatch errors 2025-11-04 18:15:45 +00:00
Mark Sinclair 7778adb493 Update publish-sdk-npm.yml 2025-11-04 14:57:24 +00:00
Mark Sinclair 33988b5164 Update publish-sdk-npm.yml 2025-11-04 14:52:22 +00:00
Mark Sinclair 284c25ff5a Update publish-sdk-npm.yml 2025-11-04 14:48:28 +00:00
Mark Sinclair 9d72229fa6 Update publish-sdk-npm.yml 2025-11-04 14:42:36 +00:00
Mark Sinclair da8d14ae84 bump versions to rc 2025-10-31 14:29:21 +00:00
Mark Sinclair 2e4f7bbc70 pin minimatch typings to fix lint errors 2025-10-25 00:24:29 +01:00
Mark Sinclair cbafe4adcf update go 2025-10-24 23:57:20 +01:00
Mark Sinclair 967b6c8e34 ts: fix linting errors 2025-10-24 23:26:17 +01:00
Mark Sinclair c3dad4231d ts-sdk: contract clients: update and re-run autogen 2025-10-24 23:25:35 +01:00
Mark Sinclair ba8ed878c9 remove bump version tool from workspace 2025-10-24 20:29:40 +01:00
Mark Sinclair 744860d4f9 Release Typescript SDK v1.4.1 2025-10-24 19:56:01 +01:00
Mark Sinclair 0013e7ac40 wasm: mix-fetch: fix up internal tester 2025-10-24 19:55:51 +01:00
Mark Sinclair 0fcc42e02d wasm: mix-fetch: remove harbour master client and use Nym API client 2025-10-24 19:55:51 +01:00
p17o 4f0974fcf1 Update quic_bridge_deployment.sh for IPv4 and .deb package (#6138)
Updated ping commands to explicitly use IPv4 and adjusted file permission checks with sudo. Changed the forward address prompt to specify IPv4 and modified the binary download process to fetch and install the latest .deb release URL automatically.
2025-10-22 15:46:23 +00:00
Jędrzej Stuczyński bd2174641e bugfix: update internal owner address in transferred share (#6139) 2025-10-22 10:42:26 +01:00
Tommy Verrall 59b62fabc9 Merge pull request #6134 from nymtech/feature/domain-fronting-v2
Domain fronting
2025-10-22 11:08:21 +02:00
Tommy Verrall e6f4bae895 Last failing test - fix 2025-10-21 19:34:20 +02:00
Tommy Verrall d71742af32 Use explicit Vec<ApiUrl> handling in BaseClientBuilder
- Replace NymNetworkDetails with explicit API URL handling
- Fix deprecated from_network() usage and improve fallback logic
- Add URL validation and remove unused backwards compatibility
2025-10-21 19:15:24 +02:00
Tommy Verrall 3b7c07e249 Actually commit the recommended changes 2025-10-21 18:12:38 +02:00
Tommy Verrall 3b429dde69 Fix broken tests in CI 2025-10-21 16:29:26 +02:00
Tommy Verrall 3a29c296da Replace deprecated from_network() with new_with_fronted_urls() 2025-10-21 16:05:41 +02:00
Tommy Verrall 8544c54f8f Merge develop into feature/domain-fronting-v2
- Use new_with_fronted_urls() for explicit domain fronting
- Deprecate from_network() in favor of explicit method
2025-10-21 15:58:20 +02:00
Jędrzej Stuczyński 9f9639950b feat: expose more explicit new_with_fronted_urls builder for http API client (#6136) 2025-10-21 14:47:58 +01:00
Jędrzej Stuczyński 111a0b20b6 bugfix: update stored epoch share when changing ownership (#6135) 2025-10-21 14:10:20 +01:00
Tommy Verrall 67b300d0b8 Fix new_from_env() to populate nym_api_urls for domain fronting 2025-10-21 12:22:51 +02:00
Jędrzej Stuczyński 88c4e0ce6c bugfix: update stored epoch share when changing announce address (#6131)
* bugfix: update stored epoch share when changing announce address

* chore: remove placeholder legacy mixnode bonding test [mixnet contract]
2025-10-21 10:59:17 +01:00
Tommy Verrall f6800aff0a fix all clippy messages 2025-10-21 11:32:47 +02:00
Tommy Verrall 0c7c927ca2 Add more tests for retry logic 2025-10-21 11:32:47 +02:00
Tommy Verrall a69c8b1660 Fix confusing tracing logs 2025-10-21 11:32:47 +02:00
Tommy Verrall f3ea310a46 Fix retries - this is working 2025-10-21 11:32:46 +02:00
Tommy Verrall 92f9ff035d Add configuration-based domain fronting support
Changes:
- Add network_details field to BaseClientBuilder (optional, backwards compatible)
- Add with_network_details() method for opt-in domain fronting
- Update construct_nym_api_client() to use from_network() when network_details provided
- Enable network-defaults feature in nym-client-core Cargo.toml
- SDK passes network_details to BaseClientBuilder
2025-10-21 11:32:46 +02:00
Tommy Verrall 5a817e1df1 Merge pull request #6126 from nymtech/multiple-fall-back-urls
Changes:

Multiple URL fallback with configurable retries (defaults to 3)
Infallible URL conversion per Andrews feedback (Url::from() instead of parse().ok())
Non-breaking builder pattern for BuilderConfig per Andrej's "too many arguments" feedback
Reverted redundant node filtering per Andrew's clarification that API already filters by supported_roles.entry
2025-10-21 11:27:37 +02:00
Tommy Verrall a07a24db00 Fix CI issues 2025-10-21 11:01:04 +02:00
Tommy Verrall a0cb812eff Allow clippy::enum_variant_names for BuilderConfigError 2025-10-21 10:35:57 +02:00
Tommy Verrall 923c1fa184 Improve error handling
Changes:
- Replace String error with BuilderConfigError enum in BuilderConfigBuilder
- Update tests to use pattern matching instead of string assertions
2025-10-20 16:57:31 +02:00
Tommy Verrall 35ea7e4926 - Add DEFAULT_NYM_API_RETRIES constant (replaces magic number 3)
- Run cargo fmt on all affected packages
- All clippy warnings resolved
2025-10-20 16:51:07 +02:00
Tommy Verrall d1cb9afaf0 not sure what happened but it's fixed 2025-10-20 15:20:24 +02:00
Tommy Verrall 79d4b4b2e3 Merge branch 'develop' into multiple-fall-back-urls 2025-10-20 15:16:36 +02:00
Tommy Verrall 8460b33946 Merge branch 'multiple-fall-back-urls' of https://github.com/nymtech/nym into multiple-fall-back-urls 2025-10-20 15:16:17 +02:00
Tommy Verrall ae6539e07c Merge resolution 2025-10-20 15:14:48 +02:00
Tommy Verrall 18cebdfedc Add accessor methods for Url internals
Add inner_url() and fronts() accessor methods to nym_http_api_client::Url
for VPN client integration
2025-10-20 14:33:57 +02:00
Tommy Verrall c448ec823a Remove tests for removed with_nym_api_client method
These tests were referencing with_nym_api_client() which was removed when
cleaning domain fronting code from this branch
2025-10-20 11:52:04 +02:00
Tommy Verrall a266137278 Add optional builder pattern for BuilderConfig (non-breaking)
Addresses @jstuczyn's feedback about too many arguments by adding
BuilderConfigBuilder as an alternative to the existing new() method.
2025-10-20 11:39:50 +02:00
Tommy Verrall 6f4dfd1dab fix conversion type && make the retry count configurable 2025-10-20 11:15:31 +02:00
Andy Duplain 57719787db Merge pull request #6130 from nymtech/andy/url_fronts
VPN-4262: Update `Url` to return `url` and `front` fields.
2025-10-17 15:44:08 +01:00
Andy Duplain 29a57bf172 VPN-4262: Update Url to return url and front fields.
The VPN client is using the `Url` type alot now and in order to avoid
double URL-parsing we would like the content of the `Url` type exposed.
2025-10-17 15:37:07 +01:00
Tommy Verrall db813b6e3e Revert node filtering changes per Andrew's feedback
Andrew clarified that get_basic_entry_assigned_nodes_v2() already filters by
supported_roles.entry
2025-10-17 15:18:28 +02:00
Tommy Verrall 1be5ba310a Remove domain fronting code to keep gateway changes only
This branch now contains only gateway registration improvements:
- Multiple URL fallback support in gateways_for_init()
- Get all entry-capable nodes for registration
- Performance and code quality improvements
2025-10-17 14:27:31 +02:00
Tommy Verrall 41ff3f7824 Address PR feedback: simplify code and reduce log noise
- Reverted all changes to topology_control/nym_api_provider.rs
- Changed info/warn logs to debug for custom client messages
- Removed unused _rng parameter from gateways_for_init()
- Simplified URL builder to always use new_with_urls()
2025-10-17 14:20:12 +02:00
Tommy Verrall c9d4d62446 Fix clippy warnings: use arrays instead of vec! in tests 2025-10-17 13:30:30 +02:00
Tommy Verrall e839a0d80e Merge develop into multiple-fall-back-urls
Resolved conflicts:
- Added event_tx field to MixnetClientBuilder alongside custom_nym_api_client
- Both features are independent and coexist:
  * custom_nym_api_client: for domain fronting support
  * event_tx: for event handling
- Updated all constructors and methods to properly handle both fields
2025-10-17 13:23:04 +02:00
Tommy Verrall cd61f930bf feat: pass custom HTTP client through SDK stack for domain fronting
- Add with_nym_api_client() to BaseClientBuilder, MixnetClientBuilder, and RegistrationClientBuilderConfig

- Modify nym_api_provider to fetch all nodes then filter by supported_roles.entry (fixes metadata inconsistency)

- Update helpers.rs to build HTTP client with all nym_apis URLs and retries for fallback support

- Fix SDK to use entry_capable_nodes() instead of entry_gateways() for broader gateway selection

This enables domain fronting and URL rotation throughout the entire SDK stack, improving censorship resistance and connection reliability. All changes are backward compatible - custom client is optional.
2025-10-17 08:36:23 +02:00
Bogdan-Ștefan Neacşu 0674f31227 Introduce event backchannel (#6119)
* Introduce even backchannel

* Rust fmt

* Rename Event to MixnetClientEvent

* Use unbounded_send for events

* Remove unused file

* Remove mut borrow

* Event hierarchy and mixnet client intermediary

* Export MixTrafficEvent in sdk
2025-10-16 19:02:36 +03:00
Jędrzej Stuczyński 3e4f563dce Merge pull request #6099 from nymtech/bugfix/incompatibility-fixes
Bugfix/incompatibility fixes
2025-10-16 15:58:43 +01:00
Tommy Verrall edcf2b1204 enable URL rotation and retries for mixnet gateway init 2025-10-16 16:22:57 +02:00
Jędrzej Stuczyński b07fb18113 Merge pull request #6125 from nymtech/merge/release/2025.18-jarlsberg
Merge/release/2025.18 jarlsberg
2025-10-16 14:50:16 +01:00
benedettadavico 017dea4afd update changelog 2025-10-16 14:09:46 +01:00
Jędrzej Stuczyński 5a9ce13beb Bugfix/bloomfilters purge (#6089)
* remove all old bloomfilters upon starting binary

* remove old bloomfilter file upon purging secondary data
2025-10-16 14:09:45 +01:00
benedettadavico 514cf25c68 bump versions 2025-10-16 13:53:06 +01:00
Andrej Mihajlov 49ee0636e4 Merge pull request #6109 from nymtech/am/update-dirs-6
Update dirs to 6.0
2025-10-16 12:59:31 +02:00
Jędrzej Stuczyński bb971ce99c bugfix: nym-credential-proxy query params parsing regression (#6121) 2025-10-16 11:40:12 +01:00
Tommy Verrall 54de369c1e Skip ipv6 metadata endpoint request (#6118)
Co-authored-by: Tommy Verrall <tommy@nymtech.net>
2025-10-16 11:39:53 +01:00
Jędrzej Stuczyński 6d6ce284df bugfix: revert some dep updates introduced in #6043 (#6120) 2025-10-16 11:39:09 +01:00
Andrej Mihajlov 56ad1c6c8e Merge pull request #6115 from nymtech/am/revert-cancel-token
Revert "Propagate cancel token to mixnet client"
2025-10-15 16:54:49 +02:00
Jędrzej Stuczyński 10b4a288c8 chore: restore pending dkg contract state migration (#6116)
since it has not yet been run on mainnet
2025-10-15 14:18:03 +01:00
benedetta davico bbbb9486ce Merge pull request #6117 from nymtech/probe/remove-1mb-file
update to no longer use 1mb files
2025-10-15 15:17:01 +02:00
benedetta davico 16e86e1a07 Update lib.go 2025-10-15 15:15:20 +02:00
Jędrzej Stuczyński ca0c9898f0 bugfix: retrieve and update ticketbook in the same query (#6101)
* bugfix: retrieve and update ticketbook in the same query

* bump up NS version

* Update Cargo.toml

* remove SKIP LOCKED part of the query

---------

Co-authored-by: benedetta davico <46782255+benedettadavico@users.noreply.github.com>
2025-10-15 13:53:07 +01:00
Andrej Mihajlov 8b73d4e615 Revert "Propagate cancel token to mixnet client"
This reverts commit 50a259d454.
2025-10-15 14:17:36 +02:00
mfahampshire 6a9a767ab4 DOCS Jarlsberg Release (#6111)
* First pass release notes

* build info
2025-10-15 09:20:03 +00:00
Andrej Mihajlov e03a9fa16f Merge pull request #6105 from nymtech/am/reg-client-mixnet-cancel-token
Propagate cancel token to mixnet client
2025-10-14 13:10:02 +02:00
Andrej Mihajlov a0fbd57d5b Update dirs to 6.0 2025-10-14 11:17:33 +02:00
mfahampshire 9856198356 Patch for operators to open wg metadata port (#6106) 2025-10-13 14:47:43 +00:00
Jędrzej Stuczyński 5c33846e57 bugfix: use custom topology provider for list of init gateways (#6092) 2025-10-13 12:01:51 +01:00
Andrej Mihajlov cfa7635ae1 Propagate cancel token to mixnet client 2025-10-13 12:25:54 +02:00
Jędrzej Stuczyński 5d45544c27 bugfix: include network name in the default gateway probe config path (#6100) 2025-10-13 10:05:54 +01:00
Jędrzej Stuczyński aa6a79cb3e feat: expose obtaining reference to Mnemonic from DirectSecp256k1HdWallet (#6083)
* feat: expose obtaining reference to Mnemonic from DirectSecp256k1HdWallet

* updated getters for stringified mnemonic
2025-10-13 09:22:15 +01:00
Georgio Nicolas b3a940770a Merge pull request #5919 from nymtech/georgio/dkg-fixes
Additional DKG Fixes
2025-10-10 17:47:11 +02:00
Mark Sinclair e980f76a81 ns-api: add descriptions to dVPN gateway responses (#6102)
* ns-api: add descriptions to dVPN gateway responses

* clippy

* fmt

---------

Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
2025-10-10 15:40:18 +01:00
import this 9b38fef28f [DOCs/operators] QUIC deployment script & docs (#6098)
* add quic_bridge_deployment.sh

* create a snippet with quick install steps

* add quic deployment to changelog

* add quic deployment to node config page

* add version compatibility callout

* last edits and scraped stats update

* correct name of QUIC snippet

* fix naming

* fix naming

* re-run python-prebuild.sh aka time-now updated

* attempt to fix vercel build the hard way

* rerun npm

* build with pnpm

* restore lock file and rebuild w pnpm

* chore: update pnpm lockfile

* attempt to fix build

* attempt to fix runtime builds

* update ci-docs run OS
2025-10-10 14:38:37 +00:00
Mark Sinclair 43910ca635 Update ci-docs.yml 2025-10-10 15:00:25 +01:00
Mark Sinclair d3ccd7575a NS API: use new probe download filesize and milliseconds field (#6097)
* use milliseconds field

* change score thresholds

* bump to version 4.0.8

* NS API: adjust score categories (#6103)

* testing scores

* test version

* Update Cargo.toml

---------

Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
Co-authored-by: benedetta davico <46782255+benedettadavico@users.noreply.github.com>
2025-10-10 14:47:36 +01:00
Jędrzej Stuczyński 422f889df7 bugfix: testnet manager 02sql migration (#6096) 2025-10-10 09:38:45 +01:00
Jędrzej Stuczyński c9e96edc35 chore: remove unnecessary closure in 'calculate_score' inside node-status-api 2025-10-09 15:46:15 +01:00
benedetta davico 7768317046 Merge pull request #6095 from nymtech/bugfix/ns-api-download-filesize
ns-api: use download files size from probes instead of parsing filenames
2025-10-08 18:14:00 +02:00
Mark Sinclair 0ebbb1a540 ns-api: use download files size from probes instead of parsing filenames 2025-10-08 17:05:56 +01:00
Jędrzej Stuczyński 827c13b69e moved nym-gateway-probe to monorepo and updated rust-edition to 2024 (#6094)
dont build netstack in CI

additional rust 2024 fixes

fixes

removed temp.rs

first round of cleanup

removed duplicated NS types

moved gateway probe to the monorepo
2025-10-08 16:17:43 +01:00
Mark Sinclair 18ff09608c ns-api: add new fields for probe output for query_metadata and download file size and duration in ms (#6091)
Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
2025-10-08 09:47:04 +01:00
Mark Sinclair 8cc996bc0d NS API: clamp load to offline when score is offline and add mixnet_score field to preformance_v2 (#6076)
* ns-api: when `score` is `Offline`, clamp `load` to `Offline`

* ns-api: bump version

* ns-api: add mixnet score field to performance_v2 struct

---------

Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
2025-10-07 17:30:37 +01:00
mfahampshire 83a598907f Max/fix wasm client + build commands (#6043)
* Debug logging 

* Yield based logging

* Reintroduce non-dummy task manager, try add counting for
BatchMessageSender, a couple of compiler target introductions on use
statements.

* Fixed time runtime err

* Uncomment forgetme/rememberme

* remove diffs from debug

* missed commented out forgetme

* yet more forgetme comments

* * Added missing clientreqestsender clone to wasm client to stop
  premature drop & busyloop
* Removed hacky mem::forget fix

* Remove debug panic_hook

* Conditional import + use of wasm_utils::console_log

* add wasm_util dep

* Commenting out or removing debug logging

* Remove missed comment

* cleanup gitignore

* clippy

* update go version in ci

* removed unused deps

* add clippy ignore

* remove mixfetch from ci build

* add minifetch fix

* comment out unused ts builds

* stop contract clients killing ci for the moment

* wasm target locking for imports

* Either remove console_log! macro or introduce cfg(debug_assertions)

* downgrade netlink

* debug assertions for console_log import

* modify config logging (debug -> normal)

* remove clone for client_request_sender + grab directly in struct
  creation

* reintroduce debug print for config in debug mode

* remove ood / unused custom topology from worker example file

* clippy

* clippy - ignore todo() tests

* modified humantime test in line with new parsing rules
2025-10-07 09:55:41 +00:00
Georgio Nicolas bb06a1b7a8 Another offering for Clippy 2025-09-12 20:34:50 +02:00
Georgio Nicolas e783a5fced Offerings for clippy 2025-09-12 20:28:49 +02:00
Georgio Nicolas 8a24b45b5d Precompute BSGS table 2025-09-12 20:21:57 +02:00
Georgio Nicolas 10e4eba727 Use LazyLock to precompute generators 2025-08-08 19:14:37 +02:00
Georgio Nicolas 8ebf482f36 Fix clippy suggestion 2025-07-29 16:33:25 +02:00
Georgio Nicolas 6940ca427e Fix zeroization 2025-07-29 15:42:23 +02:00
Georgio Nicolas 24f877fda5 replace unsafe static values by function calls 2025-07-29 15:04:11 +02:00
108 changed files with 5778 additions and 8194 deletions
+10 -9
View File
@@ -6,16 +6,14 @@ on:
paths:
- "ts-packages/**"
- "sdk/typescript/**"
- "nym-connect/desktop/src/**"
- "nym-connect/desktop/package.json"
- "nym-wallet/src/**"
- "nym-wallet/package.json"
- "explorer/**"
- "explorer-v2/**"
- ".github/workflows/ci-lint-typescript.yml"
jobs:
build:
runs-on: ubuntu-22.04
runs-on: arc-linux-latest
env:
RUSTUP_PERMIT_COPY_RENAME: 1
steps:
@@ -25,6 +23,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Setup yarn
run: npm install -g yarn
@@ -37,14 +36,12 @@ jobs:
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Install wasm-opt
uses: ./.github/actions/install-wasm-opt
with:
version: '116'
run: cargo install wasm-opt
- name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: "1.23.7"
go-version: "1.24.6"
- name: Install
run: yarn
@@ -52,7 +49,11 @@ jobs:
- name: Build packages
run: yarn build:ci
- name: Install again
run: yarn
- name: Lint
run: yarn lint
- name: Typecheck with tsc
run: yarn tsc
@@ -8,7 +8,7 @@ on:
jobs:
build:
runs-on: custom-linux
runs-on: arc-linux-latest
steps:
- uses: actions/checkout@v4
+7 -4
View File
@@ -4,7 +4,7 @@ on:
jobs:
publish:
runs-on: arc-ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -17,10 +17,13 @@ jobs:
- name: Setup yarn
run: npm install -g yarn
- name: Install Rust stable
- name: Install rust toolchain
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
@@ -29,9 +32,9 @@ jobs:
run: cargo install wasm-opt
- name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: "1.23.7"
go-version: "1.24.6"
- name: Install dependencies
run: yarn
Generated
+10 -30
View File
@@ -133,9 +133,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "ammonia"
version = "4.1.2"
version = "4.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17e913097e1a2124b46746c980134e8c954bc17a6a59bb3fde96f088d126dde6"
checksum = "d6b346764dd0814805de8abf899fe03065bcee69bb1a4771c785817e39f3978f"
dependencies = [
"cssparser",
"html5ever",
@@ -2579,7 +2579,7 @@ dependencies = [
[[package]]
name = "extension-storage"
version = "1.4.0-rc.0"
version = "1.4.1"
dependencies = [
"bip39",
"console_error_panic_hook",
@@ -4478,7 +4478,7 @@ dependencies = [
[[package]]
name = "mix-fetch-wasm"
version = "1.4.0-rc.0"
version = "1.4.1"
dependencies = [
"async-trait",
"futures",
@@ -4488,6 +4488,7 @@ 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",
@@ -5283,7 +5284,7 @@ dependencies = [
[[package]]
name = "nym-client-wasm"
version = "1.4.0-rc.0"
version = "1.4.1"
dependencies = [
"anyhow",
"futures",
@@ -6546,7 +6547,7 @@ dependencies = [
[[package]]
name = "nym-node-status-api"
version = "4.0.11-rc1"
version = "4.0.10"
dependencies = [
"ammonia",
"anyhow",
@@ -6642,7 +6643,7 @@ dependencies = [
[[package]]
name = "nym-node-tester-wasm"
version = "1.3.0-rc.0"
version = "1.3.1"
dependencies = [
"futures",
"js-sys",
@@ -6798,7 +6799,6 @@ dependencies = [
"tokio",
"tokio-util",
"tracing",
"typed-builder",
"url",
]
@@ -7824,9 +7824,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-sys"
version = "0.9.109"
version = "0.9.110"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571"
checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2"
dependencies = [
"cc",
"libc",
@@ -11392,26 +11392,6 @@ 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"
+13 -2
View File
@@ -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,6 +215,7 @@ 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"
@@ -242,11 +243,13 @@ 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"
@@ -262,8 +265,11 @@ 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"
@@ -287,10 +293,12 @@ 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"
@@ -299,6 +307,7 @@ 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"
@@ -306,10 +315,13 @@ 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"
@@ -356,7 +368,6 @@ 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"
+4 -4
View File
@@ -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
@@ -801,7 +801,7 @@ where
event_tx,
);
let mix_tx = mix_traffic_controller.mix_tx();
let mix_tx = mix_traffic_controller.mix_rx();
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.clone(),
None => nym_task::create_sdk_shutdown_tracker()?,
Some(parent_tracker) => parent_tracker.child_tracker(),
None => nym_task::get_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.clone(),
&shutdown_tracker.child_tracker(),
);
// 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.clone(),
&shutdown_tracker.child_tracker(),
)
.await?;
@@ -1074,7 +1074,7 @@ where
stats_reporter.clone(),
#[cfg(unix)]
self.connection_fd_callback,
&shutdown_tracker.clone(),
&shutdown_tracker.child_tracker(),
)
.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.clone(),
&shutdown_tracker.child_tracker(),
)
.await?;
@@ -1093,7 +1093,7 @@ where
reply_storage.key_storage(),
reply_controller_sender.clone(),
stats_reporter.clone(),
&shutdown_tracker.clone(),
&shutdown_tracker.child_tracker(),
);
// 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.clone(),
&shutdown_tracker.child_tracker(),
EventSender(event_sender),
);
@@ -1134,7 +1134,7 @@ where
shared_lane_queue_lengths.clone(),
client_connection_rx,
stats_reporter.clone(),
&shutdown_tracker.clone(),
&shutdown_tracker.child_tracker(),
);
if !self
@@ -1150,7 +1150,7 @@ where
shared_topology_accessor.clone(),
message_sender,
stats_reporter.clone(),
&shutdown_tracker.clone(),
&shutdown_tracker.child_tracker(),
);
}
@@ -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::trace!("Failed to send cover message - channel full");
tracing::debug!("Failed to send cover message - channel full");
}
TrySendError::Closed(_) => {
tracing::warn!("Failed to send cover message - channel closed");
@@ -20,10 +20,7 @@ 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;
/// 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;
const MAX_FAILURE_COUNT: usize = 100;
// that's also disgusting.
pub struct Empty;
@@ -87,7 +84,7 @@ impl MixTrafficController {
self.client_tx.clone()
}
pub fn mix_tx(&self) -> BatchMixMessageSender {
pub fn mix_rx(&self) -> BatchMixMessageSender {
self.mix_tx.clone()
}
@@ -159,11 +156,6 @@ 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,8 +298,6 @@ 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() {
+2 -2
View File
@@ -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 create_sdk_shutdown_tracker() -> Result<ShutdownTracker, RegistryAccessError> {
Ok(runtime_registry::RuntimeRegistry::create_sdk()?.shutdown_tracker_owned())
pub fn get_sdk_shutdown_tracker() -> Result<ShutdownTracker, RegistryAccessError> {
Ok(runtime_registry::RuntimeRegistry::get_or_create_sdk()?.shutdown_tracker_owned())
}
+16 -34
View File
@@ -19,45 +19,30 @@ 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 {
/// Create a ShutdownManager for SDK use.
/// Get or create a ShutdownManager for SDK use.
/// This manager doesn't listen to OS signals, making it suitable for library use.
/// 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> {
pub(crate) fn get_or_create_sdk() -> Result<Arc<ShutdownManager>, RegistryAccessError> {
let guard = REGISTRY
.sdk_manager
.read()
.map_err(|_| RegistryAccessError::Poisoned)?;
if let Some(manager) = guard.as_ref() {
Ok(manager.clone())
} else {
Err(RegistryAccessError::MissingShutdownManager)
return Ok(manager.clone());
}
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.
@@ -100,13 +85,10 @@ mod tests {
assert!(!RuntimeRegistry::has_sdk_manager().unwrap());
// Error if nothing was created
assert!(RuntimeRegistry::get_sdk().is_err());
let manager1 = RuntimeRegistry::create_sdk().unwrap();
let manager1 = RuntimeRegistry::get_or_create_sdk().unwrap();
assert!(RuntimeRegistry::has_sdk_manager().unwrap());
let manager2 = RuntimeRegistry::get_sdk().unwrap();
let manager2 = RuntimeRegistry::get_or_create_sdk().unwrap();
// Should return the same instance
assert!(Arc::ptr_eq(&manager1, &manager2));
@@ -1,27 +1,26 @@
```ts copy filename="mixFetchExample.tsx"
import React, { useState } from 'react';
import CircularProgress from '@mui/material/CircularProgress';
import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import { mixFetch } from '@nymproject/mix-fetch-full-fat';
import Stack from '@mui/material/Stack';
import Paper from '@mui/material/Paper';
import type { SetupMixFetchOps } from '@nymproject/mix-fetch';
```tsx copy filename="mixFetchExample.tsx"
import React, { useState } from "react";
import CircularProgress from "@mui/material/CircularProgress";
import Button from "@mui/material/Button";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import Box from "@mui/material/Box";
import { mixFetch } from "@nymproject/mix-fetch-full-fat";
import Stack from "@mui/material/Stack";
import Paper from "@mui/material/Paper";
import type { SetupMixFetchOps } from "@nymproject/mix-fetch-full-fat";
const defaultUrl = 'https://nym.com/favicon.svg';
const args = { mode: 'unsafe-ignore-cors' };
const defaultUrl = "https://nymtech.net/.wellknown/network-requester/exit-policy.txt";
const args = { mode: "unsafe-ignore-cors" };
const mixFetchOptions: SetupMixFetchOps = {
preferredGateway: '6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B', // with WSS
preferredNetworkRequester:
'8rRGWy54oC8drFL9DepMegBt2DLrsqQwCoHMXt9nsnTo.2XjCPVbb4FpQ9hNRcXwb9mTzEAVVk1zf1tcch3wdtNEA@6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B',
preferredGateway: "2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW", // with WSS
// preferredNetworkRequester:
// "CTDxrcXgrZHWyCWnuCgjpJPghQUcEVz1HkhUr5mGdFnT.3UAww1YWNyVNYNWFQL1LaHYouQtDiXBGK5GiDZgpXkTK@2RFtU5BwxvJJXagAWAEuaPgb5ZVPRoy2542TT93Edw6v",
mixFetchOverride: {
requestTimeoutMs: 60_000,
},
forceTls: true, // force WSS
extra: {},
};
export const MixFetch = () => {
@@ -45,7 +44,7 @@ export const MixFetch = () => {
};
return (
<div style={{ marginTop: '1rem' }}>
<div style={{ marginTop: "1rem" }}>
<Stack direction="row">
<TextField
disabled={busy}
@@ -56,7 +55,12 @@ export const MixFetch = () => {
defaultValue={defaultUrl}
onChange={(e) => setUrl(e.target.value)}
/>
<Button variant="outlined" disabled={busy} sx={{ marginLeft: '1rem' }} onClick={handleFetch}>
<Button
variant="outlined"
disabled={busy}
sx={{ marginLeft: "1rem" }}
onClick={handleFetch}
>
Fetch
</Button>
</Stack>
@@ -1,15 +1,19 @@
```ts copy filename="MixnetWASMClientExample.tsx"
import React, { useEffect, useState } from 'react';
import { createNymMixnetClient, NymMixnetClient, Payload } from '@nymproject/sdk-full-fat';
import Box from '@mui/material/Box';
import CircularProgress from '@mui/material/CircularProgress';
import Paper from '@mui/material/Paper';
import Typography from '@mui/material/Typography';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import Button from '@mui/material/Button';
import React, { useEffect, useState } from "react";
import {
createNymMixnetClient,
NymMixnetClient,
Payload,
} from "@nymproject/sdk-full-fat";
import Box from "@mui/material/Box";
import CircularProgress from "@mui/material/CircularProgress";
import Paper from "@mui/material/Paper";
import Typography from "@mui/material/Typography";
import Stack from "@mui/material/Stack";
import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button";
const nymApiUrl = 'https://validator.nymtech.net/api';
const nymApiUrl = "https://validator.nymtech.net/api";
export const Traffic = () => {
const [nym, setNym] = useState<NymMixnetClient>();
@@ -17,27 +21,31 @@ export const Traffic = () => {
const [recipient, setRecipient] = useState<string>();
const [payload, setPayload] = useState<Payload>();
const [receivedMessage, setReceivedMessage] = useState<string>();
const [buttonEnabled, setButtonEnabled] = useState<boolean>(false);
const init = async () => {
const client = await createNymMixnetClient();
setNym(client);
// start the client and connect to a gateway
await client?.client.start({
clientId: crypto.randomUUID(),
nymApiUrl,
forceTls: true, // force WSS
});
// check when is connected and set the self address
client?.events.subscribeToConnected((e) => {
const { address } = e.args;
setSelfAddress(address);
});
// show whether the client is ready or not
client?.events.subscribeToLoaded((e) => {
console.log('Client ready: ', e.args);
console.log("Client ready: ", e.args);
});
// show message payload content when received
client?.events.subscribeToTextMessageReceivedEvent((e) => {
console.log(e.args.payload);
setReceivedMessage(e.args.payload);
@@ -48,7 +56,8 @@ export const Traffic = () => {
await nym?.client.stop();
};
const send = () => nym.client.send({ payload, recipient });
const send = () =>
payload && recipient && nym?.client.send({ payload, recipient });
useEffect(() => {
init();
@@ -57,9 +66,17 @@ export const Traffic = () => {
};
}, []);
useEffect(() => {
if (recipient && payload) {
setButtonEnabled(true);
} else {
setButtonEnabled(false);
}
}, [recipient, payload]);
if (!nym || !selfAddress) {
return (
<Box sx={{ display: 'flex' }}>
<Box sx={{ display: "flex" }}>
<CircularProgress />
</Box>
);
@@ -67,10 +84,10 @@ export const Traffic = () => {
return (
<Box padding={3}>
<Paper style={{ marginTop: '1rem', padding: '2rem' }}>
<Paper style={{ marginTop: "1rem", padding: "2rem" }}>
<Stack spacing={3}>
<Typography variant="body1">My self address is:</Typography>
<Typography variant="body1">{selfAddress || 'loading'}</Typography>
<Typography variant="body1">{selfAddress || "loading"}</Typography>
<Typography variant="h5">Communication through the Mixnet</Typography>
<TextField
type="text"
@@ -83,15 +100,22 @@ export const Traffic = () => {
placeholder="Message to send"
multiline
rows={4}
onChange={(e) => setPayload({ message: e.target.value, mimeType: 'text/plain' })}
onChange={(e) =>
setPayload({ message: e.target.value, mimeType: "text/plain" })
}
size="small"
/>
<Button variant="outlined" onClick={() => send()} disabled={!payload || !recipient} sx={{width: 'fit-content'}}>
<Button
variant="outlined"
onClick={() => send()}
disabled={!buttonEnabled}
sx={{ width: "fit-content" }}
>
Send
</Button>
</Stack>
{receivedMessage && (
<Stack spacing={3} style={{ marginTop: '1rem' }}>
<Stack spacing={3} style={{ marginTop: "1rem" }}>
<Typography variant="h5">Message Received!</Typography>
<Typography fontFamily="monospace">{receivedMessage}</Typography>
</Stack>
+4 -4
View File
@@ -9,13 +9,13 @@ import Stack from "@mui/material/Stack";
import Paper from "@mui/material/Paper";
import type { SetupMixFetchOps } from "@nymproject/mix-fetch-full-fat";
const defaultUrl = "https://nym.com/favicon.svg";
const defaultUrl = "https://nymtech.net/.wellknown/network-requester/exit-policy.txt";
const args = { mode: "unsafe-ignore-cors" };
const mixFetchOptions: SetupMixFetchOps = {
preferredGateway: "6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B", // with WSS
preferredNetworkRequester:
"8rRGWy54oC8drFL9DepMegBt2DLrsqQwCoHMXt9nsnTo.2XjCPVbb4FpQ9hNRcXwb9mTzEAVVk1zf1tcch3wdtNEA@6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B",
preferredGateway: "2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW", // with WSS
// preferredNetworkRequester:
// "CTDxrcXgrZHWyCWnuCgjpJPghQUcEVz1HkhUr5mGdFnT.3UAww1YWNyVNYNWFQL1LaHYouQtDiXBGK5GiDZgpXkTK@2RFtU5BwxvJJXagAWAEuaPgb5ZVPRoy2542TT93Edw6v",
mixFetchOverride: {
requestTimeoutMs: 60_000,
},
@@ -15,7 +15,6 @@ 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 && \
@@ -27,7 +26,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
./quic_bridge_deployment.sh full_bridge_setup
./nym-node-setup/quic_bridge_deployment.sh full_bridge_setup
```
###### 3. Follow the interactive prompts
@@ -1 +1 @@
Thursday, October 30th 2025, 13:00:59 UTC
Tuesday, October 14th 2025, 11:34:14 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 [OUTPUT]
-o, --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) | USA, DE, UK, ESP, FR | nan | No | nan | 07/2025 |
| [Ionos](https://www.ionos.com/servers/amd-servers) | US, 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) | USA, 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) | US, 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, USA, DE, UAE, NG, ESP, IN, IT, FR, LT, SG, BG, LV, PL | nan | 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 |
| [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, 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 |
| [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 |
| [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) | USA, UK, Brazil, Japan, Russia, South Africa and many more | Yes | nan | nan | 07/2025 |
| [Psychz](https://www.psychz.net) | US, 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 |
+5 -5
View File
@@ -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, USA, DE, UAE, NG, ESP, IN, IT, FR, LT, SG, BG, LV, PL",,No,,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
[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, 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
[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
[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),"USA, UK, Brazil, Japan, Russia, South Africa and many more",Yes,,,07/2025
[Psychz](https://www.psychz.net),"US, 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
1 **ISP** **Locations** **Public IPv6** **Crypto Payments** **Comments** **Last Updated**
21 [Lowendbox](https://lowendbox.com/category/dedicated-servers) Just an aggregator with good offers 07/2025
22 [Thundervm](https://thundervm.com/en/hosting/dedicated-server) USA, UK, France, Italy, Switzerland, Netherlands Yes 07/2025
23 [OVH](https://us.ovhcloud.com/bare-metal/rise/rise-3/) USA, DE, FR, UK, PL, CA No Not all locations always available 07/2025
24 [Mebilcom](https://www.melbicom.net/dedicatedserver/) NL, USA, DE, UAE, NG, ESP, IN, IT, FR, LT, SG, BG, LV, PL NL, US, DE, UAE, NG, ESP, IN, IT, FR, LT, SG, BG, LV, PL No 07/2025
25 [Servermania](https://www.servermania.com/dedicated-servers-hosting.htm) USA, Canada No 07/2025
26 [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 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
27 [Ionos](https://www.ionos.com/servers/amd-servers) USA, DE, UK, ESP, FR US, DE, UK, ESP, FR No 07/2025
28 [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 US, NL, DE, UK, CA, SG, JP, AUS, HK No KYC mandatory 07/2025
29 [M247](https://m247.com/eu/services/host/dedicated-servers/) UK, Austria, Br, Sw, Jp, Poland, Fr, USA, Netherlands Yes No 07/2025
30 [Hostroyale](https://hostroyale.com/hosting/dedicated-server/) Various countries with different pricing Yes 07/2025
31 [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 [Colocall](https://www.colocall.net/) Ukraine Yes 07/2025
36 [Incognet](https://incognet.io/kansas-city-dedicated-servers) USA, Netherlands Yes 07/2025
37 [FranTech](https://my.frantech.ca) USA Yes 07/2025
38 [Psychz](https://www.psychz.net) USA, UK, Brazil, Japan, Russia, South Africa and many more US, UK, Brazil, Japan, Russia, South Africa and many more Yes 07/2025
39 [Fsit](https://www.fsit.com/server/vps-vserver-kvm) Swiss Yes Yes 07/2025
40 [NiceVPS](https://nicevps.net/) Netherlands Yes 07/2025
41 [Dataclub](https://www.dataclub.eu/) Latvia, Sweden, Netherlands Yes 07/2027
+2 -2
View File
@@ -38,8 +38,8 @@
"@nextui-org/accordion": "^2.0.40",
"@nextui-org/react": "^2.4.8",
"@nymproject/contract-clients": ">=1.2.4-rc.2 || ^1",
"@nymproject/mix-fetch-full-fat": ">=1.2.4-rc.2 || ^1",
"@nymproject/sdk-full-fat": ">=1.2.4-rc.2 || ^1",
"@nymproject/mix-fetch-full-fat": ">=1.5.1-rc.0 || ^1.4.1",
"@nymproject/sdk-full-fat": ">=1.5.1-rc.0 || ^1.4.1",
"@redocly/cli": "^1.25.15",
"@types/mdx": "^2.0.13",
"chain-registry": "^1.19.0",
@@ -49,90 +49,6 @@ 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-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
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
cargo Profile: release
```
+10 -10
View File
@@ -78,11 +78,11 @@ importers:
specifier: '>=1.2.4-rc.2 || ^1'
version: 1.4.1
'@nymproject/mix-fetch-full-fat':
specifier: '>=1.2.4-rc.2 || ^1'
version: 1.2.3
specifier: '>=1.5.1-rc.0 || ^1.4.1'
version: 1.4.1
'@nymproject/sdk-full-fat':
specifier: '>=1.2.4-rc.2 || ^1'
version: 1.2.3
specifier: '>=1.5.1-rc.0 || ^1.4.1'
version: 1.4.1
'@redocly/cli':
specifier: ^1.25.15
version: 1.34.5(ajv@8.17.1)
@@ -1679,11 +1679,11 @@ packages:
'@nymproject/contract-clients@1.4.1':
resolution: {integrity: sha512-HuJZ4Hv+Rl6ZZEtCHKgurNLJapM+QQRJlGkevFH2a4UdqUqF9omUkUi3AVes4679dPoSFgvA7plyVSDBdbgV6w==}
'@nymproject/mix-fetch-full-fat@1.2.3':
resolution: {integrity: sha512-5yAQhw33LC0cNsyV0Rj+LIa2kvJY+8jsfgOSr1aeKNfQ7dG4fngWkKnGUbPGzhUTJjqgXPTwNVeJSd6hwGim+g==}
'@nymproject/mix-fetch-full-fat@1.4.1':
resolution: {integrity: sha512-AMa21sEd9FELqAJe1lCyHPqxxbc13ApiJ1P/exAslQjiFPb/de/3Ow0FHqKGNPrwyVRS/T2pSzjQ3l8TddiEBA==}
'@nymproject/sdk-full-fat@1.2.3':
resolution: {integrity: sha512-lheA1Zk020o2t95FPVZfdUR0aSI52aD0aJQs074fjH16QkoNNEMotzhJGAnsnnczVg3bpddKghNpCLyDOWvg9A==}
'@nymproject/sdk-full-fat@1.4.1':
resolution: {integrity: sha512-dh5bvMUj3m8nEssvO8Nl66WpcJAjwRZrGNwqfczJWLG4nX3Vt95tPLv4v0/Z1W3DQWQFW6WmEPPYHNjl18V/fA==}
'@opentelemetry/api-logs@0.53.0':
resolution: {integrity: sha512-8HArjKx+RaAI8uEIgcORbZIPklyh1YLjPSBus8hjRmvLi6DeFzgOcdZ7KwPabKj8mXF8dX0hyfAyGfycz0DbFw==}
@@ -9247,9 +9247,9 @@ snapshots:
'@nymproject/contract-clients@1.4.1': {}
'@nymproject/mix-fetch-full-fat@1.2.3': {}
'@nymproject/mix-fetch-full-fat@1.4.1': {}
'@nymproject/sdk-full-fat@1.2.3': {}
'@nymproject/sdk-full-fat@1.4.1': {}
'@opentelemetry/api-logs@0.53.0':
dependencies:
+16 -16
View File
@@ -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,5 +1,6 @@
"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,
@@ -13,7 +14,6 @@ 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
View File
@@ -1,6 +1,6 @@
[package]
name = "extension-storage"
version = "1.4.0-rc.0"
version = "1.4.1"
edition = "2024"
license = "Apache-2.0"
repository = "https://github.com/nymtech/nym"
@@ -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 http_api_port\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 FROM\n nym_nodes\n WHERE\n self_described IS NOT NULL\n AND\n bond_info IS NOT NULL\n ",
"describe": {
"columns": [
{
@@ -62,11 +62,6 @@
"ordinal": 11,
"name": "bond_info: serde_json::Value",
"type_info": "Jsonb"
},
{
"ordinal": 12,
"name": "http_api_port",
"type_info": "Int4"
}
],
"parameters": {
@@ -84,9 +79,8 @@
true,
false,
true,
true,
true
]
},
"hash": "3ddc12cc4e1796b787a50c40560d2bd71d1cfe5f5265e6f161b3122d1317a421"
"hash": "283f49a65c7d70bf271702ff6a5c7ad6e68c81932d295ff18ed198c54706a57c"
}
@@ -0,0 +1,26 @@
{
"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"
}
@@ -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 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 ",
"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 ",
"describe": {
"columns": [
{
@@ -62,11 +62,6 @@
"ordinal": 11,
"name": "bond_info: serde_json::Value",
"type_info": "Jsonb"
},
{
"ordinal": 12,
"name": "http_api_port",
"type_info": "Int4"
}
],
"parameters": {
@@ -84,9 +79,8 @@
true,
false,
true,
true,
true
]
},
"hash": "0b51df277ed66c6553f66af9b135342dee177abc1c92e4a89147de3c22d3d1a5"
"hash": "c48d04fc3de59dd484f0a63d40336ced54e08785f77e9ef85f3157d004ec85dc"
}
@@ -1,27 +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, 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.11-rc1"
version = "4.0.10"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
@@ -1,2 +0,0 @@
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, Subcommand};
use clap::Parser;
use nym_bin_common::bin_info;
use nym_credential_proxy_lib::shared_state::ecash_state::TicketType;
use reqwest::Url;
@@ -105,19 +105,6 @@ 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: Option<u16>,
pub http_api_port: i64,
}
impl ScraperNodeInfo {
@@ -395,21 +395,8 @@ impl ScraperNodeInfo {
format!("http://{}", host),
]);
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));
if self.http_api_port != DEFAULT_NYM_NODE_HTTP_PORT as i64 {
urls.insert(0, format!("http://{}:{}", host, self.http_api_port));
}
}
@@ -436,7 +423,6 @@ 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
@@ -454,7 +440,6 @@ 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,
}
@@ -471,12 +456,6 @@ 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)?;
@@ -493,7 +472,6 @@ impl NymNodeInsertRecord {
entry,
self_described,
bond_info,
http_api_port,
last_updated_utc: now,
};
@@ -35,8 +35,7 @@ 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",
http_api_port
bond_info as "bond_info: serde_json::Value"
FROM
nym_nodes
ORDER BY
@@ -73,8 +72,7 @@ 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",
http_api_port
bond_info as "bond_info: serde_json::Value"
FROM
nym_nodes
WHERE
@@ -117,9 +115,9 @@ pub(crate) async fn update_nym_nodes(
supported_roles, entry,
self_described,
bond_info,
performance, last_updated_utc, http_api_port
performance, last_updated_utc
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
ON CONFLICT(node_id) DO UPDATE SET
ed25519_identity_pubkey=excluded.ed25519_identity_pubkey,
ip_addresses=excluded.ip_addresses,
@@ -131,8 +129,7 @@ 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,
http_api_port=excluded.http_api_port
last_updated_utc=excluded.last_updated_utc
;",
record.node_id,
record.ed25519_identity_pubkey,
@@ -147,7 +144,6 @@ 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,11 +21,10 @@ 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_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)),
nodes_dto.into_iter().filter_map(|node| {
let node_id = node.node_id;
match SkimmedNode::try_from(node) {
Ok(node) => Some(node),
Err(e) => {
tracing::error!("Failed to decode node_id={}: {}", node_id, e);
None
@@ -34,7 +33,7 @@ pub(crate) async fn get_nodes_for_scraping(pool: &DbPool) -> Result<Vec<ScraperN
})
})?;
skimmed_nodes.for_each(|(node, http_api_port)| {
skimmed_nodes.for_each(|node| {
// 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()) {
@@ -55,7 +54,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: http_api_port.map(|port| port as u16),
http_api_port: node.mix_port.into(),
})
});
@@ -138,7 +138,6 @@ 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 =
@@ -363,42 +362,22 @@ 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: None,
http_api_port: 8080,
};
let addresses = node_info.contact_addresses();
// Should generate multiple URLs for each host
// When no custom port is specified only default ports should be used
// Custom port (8080) should be inserted at the beginning
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;
@@ -435,7 +414,6 @@ 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();
@@ -473,7 +451,6 @@ 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,6 +1,4 @@
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;
@@ -42,49 +40,11 @@ async fn main() -> anyhow::Result<()> {
tracing::info!("Registered {} agent keys", agent_key_list.len());
let connection_url = args.database_url.clone();
if std::env::var("SHOW_CONFIG").ok().is_some() {
tracing::debug!("Using config:\n{:#?}", args);
}
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 {
@@ -98,9 +58,20 @@ 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(false).await {
if let Err(e) = monitor.run().await {
tracing::error!(
"Monitor run failed: {e}, retrying in {}s...",
MONITOR_FAILURE_RETRY_DELAY.as_secs()
@@ -84,33 +84,8 @@ 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, exit_early: bool) -> anyhow::Result<()> {
async fn run(&mut self) -> anyhow::Result<()> {
self.check_ipinfo_bandwidth().await;
let default_api_url = self
@@ -178,11 +153,6 @@ 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,17 +118,6 @@ 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();
@@ -163,13 +152,7 @@ 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.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);
let sanitized_description = sanitize_description(description, *node.node_id());
insert_scraped_node_description(pool, &node.node_kind, &sanitized_description).await?;
Ok(())
-1
View File
@@ -17,7 +17,6 @@ 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" }
+235 -5
View File
@@ -15,12 +15,10 @@ 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 {
@@ -28,14 +26,11 @@ 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>,
@@ -61,6 +56,53 @@ 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)
@@ -212,6 +254,144 @@ 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::*;
@@ -224,4 +404,54 @@ 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());
}
}
+5 -2
View File
@@ -12,12 +12,15 @@ 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,
}
@@ -46,7 +49,7 @@ impl RegistrationClientBuilder {
let builder = MixnetClientBuilder::new_with_storage(mixnet_client_storage)
.event_tx(EventSender(event_tx));
let mixnet_client = tokio::time::timeout(
self.config.mixnet_client_startup_timeout,
MIXNET_CLIENT_STARTUP_TIMEOUT,
self.config.build_and_connect_mixnet_client(builder),
)
.await??;
@@ -56,7 +59,7 @@ impl RegistrationClientBuilder {
} else {
let builder = MixnetClientBuilder::new_ephemeral().event_tx(EventSender(event_tx));
let mixnet_client = tokio::time::timeout(
self.config.mixnet_client_startup_timeout,
MIXNET_CLIENT_STARTUP_TIMEOUT,
self.config.build_and_connect_mixnet_client(builder),
)
.await??;
+5 -1
View File
@@ -32,7 +32,7 @@
"@mui/styles": "^5.2.2",
"@mui/utils": "^5.7.0",
"@nymproject/mui-theme": "^1.0.0",
"@nymproject/node-tester": "^1.2.3",
"@nymproject/node-tester": "^1.3.1",
"@nymproject/react": "^1.0.0",
"@nymproject/types": "^1.0.0",
"@storybook/react": "^6.5.15",
@@ -80,6 +80,7 @@
"@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",
@@ -131,5 +132,8 @@
"webpack-favicons": "^1.3.8",
"webpack-merge": "^5.8.0"
},
"resolutions": {
"@types/minimatch": "5.1.2"
},
"private": false
}
+22 -26
View File
@@ -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,44 +78,40 @@ 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}>
+43 -42
View File
@@ -1,66 +1,67 @@
{
"name": "@nymproject/nymsphere",
"version": "1.0.0",
"private": true,
"version": "1.0.1",
"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": {
"nuke": "npx rimraf **/node_modules node_modules",
"scrub": "npx rimraf **/dist dist",
"clean": "lerna run clean",
"audit:fix": "npm_config_yes=true npx yarn-audit-fix -- --dry-run",
"build": "run-s build:types build:packages",
"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": "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: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 ",
"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",
"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",
"docs:prod:build": "run-s docs:prod:build:ws",
"docs:prod:build:ws": "lerna run docs:prod:build --stream",
"sdk:build": "./sdk/typescript/scripts/build-prod-sdk.sh",
"sdk:publish": "./sdk/typescript/scripts/publish.sh",
"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",
"tsc": "lerna run tsc --stream",
"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"
"types:lint:fix": "lerna run lint:fix --scope @nymproject/types --scope @nymproject/nym-wallet-app"
},
"dependencies": {
"lucide-react": "^0.453.0"
},
"devDependencies": {
"@npmcli/node-gyp": "^3.0.0",
"@types/minimatch": "^6.0.0",
"@types/minimatch": "5.1.2",
"lerna": "^7.3.0",
"node-gyp": "^9.3.1",
"npm-run-all": "^4.1.5",
"tslog": "3.3.3"
},
"dependencies": {
"lucide-react": "^0.453.0"
},
"private": true,
"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"
}
}
"cosmjs-types": "^0.9.0",
"@types/minimatch": "5.1.2"
},
"workspaces": [
"ts-packages/*",
"nym-wallet",
"explorer-nextjs",
"explorer-v2",
"types",
"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
+10 -6
View File
@@ -736,11 +736,15 @@ where
base_builder = base_builder.with_topology_provider(topology_provider);
}
// 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);
}
// 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);
if let Some(event_tx) = self.event_tx {
base_builder = base_builder.with_event_tx(event_tx);
}
@@ -805,7 +809,7 @@ where
client_output,
client_state.clone(),
nym_address,
started_client.shutdown_handle.clone(),
started_client.shutdown_handle.child_tracker(),
packet_type,
);
@@ -3,13 +3,11 @@ import codegen from '@cosmwasm/ts-codegen';
codegen
.default({
contracts: [
{ name: 'coconut-bandwidth', dir: '../../../../contracts/coconut-bandwidth' },
{ name: 'ecash', dir: '../../../../contracts/ecash' },
{ 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.0-rc.0",
"version": "1.3.1-rc0",
"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": "^0.35.3",
"@cosmwasm/ts-codegen": "^1.13.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,23 +1,58 @@
/**
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
* 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 { 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";
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";
export interface CoconutDkgReadOnlyInterface {
contractAddress: string;
getState: () => Promise<State>;
getCurrentEpochState: () => Promise<Epoch>;
getEpochStateAtHeight: ({
height
}: {
height: number;
}) => Promise<NullableEpoch>;
getCurrentEpochThreshold: () => Promise<Uint64>;
getInitialDealers: () => Promise<NullableInitialReplacementData>;
getEpochThreshold: ({
epochId
}: {
epochId: number;
}) => Promise<Uint64>;
canAdvanceState: () => Promise<StateAdvanceResponse>;
getRegisteredDealer: ({
dealerAddress,
epochId
}: {
dealerAddress: string;
epochId?: number;
}) => Promise<RegisteredDealerDetails>;
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
@@ -25,22 +60,67 @@ export interface CoconutDkgReadOnlyInterface {
limit?: number;
startAfter?: string;
}) => Promise<PagedDealerResponse>;
getPastDealers: ({
getDealerIndices: ({
limit,
startAfter
}: {
limit?: number;
startAfter?: string;
}) => Promise<PagedDealerResponse>;
getDealing: ({
idx,
limit,
startAfter
}) => Promise<PagedDealerIndexResponse>;
getDealingsMetadata: ({
dealer,
dealingIndex,
epochId
}: {
idx: number;
limit?: number;
startAfter?: string;
}) => Promise<PagedDealingsResponse>;
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>;
getVerificationKeys: ({
epochId,
limit,
@@ -50,37 +130,89 @@ export interface CoconutDkgReadOnlyInterface {
limit?: number;
startAfter?: string;
}) => Promise<PagedVKSharesResponse>;
getCw2ContractVersion: () => Promise<GetCw2ContractVersionResponse>;
}
export class CoconutDkgQueryClient implements CoconutDkgReadOnlyInterface {
client: CosmWasmClient;
client: ICosmWasmClient;
contractAddress: string;
constructor(client: CosmWasmClient, contractAddress: string) {
constructor(client: ICosmWasmClient, 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.getInitialDealers = this.getInitialDealers.bind(this);
this.getEpochThreshold = this.getEpochThreshold.bind(this);
this.canAdvanceState = this.canAdvanceState.bind(this);
this.getRegisteredDealer = this.getRegisteredDealer.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.getPastDealers = this.getPastDealers.bind(this);
this.getDealing = this.getDealing.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.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: {}
});
};
getInitialDealers = async (): Promise<NullableInitialReplacementData> => {
getEpochThreshold = async ({
epochId
}: {
epochId: number;
}): Promise<Uint64> => {
return this.client.queryContractSmart(this.contractAddress, {
get_initial_dealers: {}
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
}
});
};
getDealerDetails = async ({
@@ -94,6 +226,40 @@ 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
@@ -108,34 +274,119 @@ export class CoconutDkgQueryClient implements CoconutDkgReadOnlyInterface {
}
});
};
getPastDealers = async ({
getDealerIndices = async ({
limit,
startAfter
}: {
limit?: number;
startAfter?: string;
}): Promise<PagedDealerResponse> => {
}): Promise<PagedDealerIndexResponse> => {
return this.client.queryContractSmart(this.contractAddress, {
get_past_dealers: {
get_dealer_indices: {
limit,
start_after: startAfter
}
});
};
getDealing = async ({
idx,
limit,
startAfter
getDealingsMetadata = async ({
dealer,
dealingIndex,
epochId
}: {
idx: number;
limit?: number;
startAfter?: string;
}): Promise<PagedDealingsResponse> => {
dealer: string;
dealingIndex: number;
epochId: number;
}): Promise<DealingMetadataResponse> => {
return this.client.queryContractSmart(this.contractAddress, {
get_dealing: {
idx,
limit,
start_after: startAfter
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
}
});
};
@@ -156,91 +407,142 @@ 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<ExecuteResult>;
commitDealing: ({
dealingBytes,
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
commitDealingsMetadata: ({
chunks,
dealingIndex,
resharing
}: {
dealingBytes: ContractSafeBytes;
chunks: DealingChunkInfo[];
dealingIndex: number;
resharing: boolean;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
commitDealingsChunk: ({
chunk
}: {
chunk: PartialContractDealing;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
commitVerificationKeyShare: ({
resharing,
share
}: {
resharing: boolean;
share: string;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
verifyVerificationKeyShare: ({
owner,
resharing
}: {
owner: Addr;
owner: string;
resharing: boolean;
}, 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>;
}, 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>;
}
export class CoconutDkgClient extends CoconutDkgQueryClient implements CoconutDkgInterface {
client: SigningCosmWasmClient;
client: ISigningCosmWasmClient;
sender: string;
contractAddress: string;
constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) {
constructor(client: ISigningCosmWasmClient, 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.commitDealing = this.commitDealing.bind(this);
this.commitDealingsMetadata = this.commitDealingsMetadata.bind(this);
this.commitDealingsChunk = this.commitDealingsChunk.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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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_);
};
commitDealing = async ({
dealingBytes,
commitDealingsMetadata = async ({
chunks,
dealingIndex,
resharing
}: {
dealingBytes: ContractSafeBytes;
chunks: DealingChunkInfo[];
dealingIndex: number;
resharing: boolean;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
return await this.client.execute(this.sender, this.contractAddress, {
commit_dealing: {
dealing_bytes: dealingBytes,
commit_dealings_metadata: {
chunks,
dealing_index: dealingIndex,
resharing
}
}, fee, memo, _funds);
}, 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_);
};
commitVerificationKeyShare = async ({
resharing,
@@ -248,36 +550,63 @@ export class CoconutDkgClient extends CoconutDkgQueryClient implements CoconutDk
}: {
resharing: boolean;
share: string;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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: Addr;
owner: string;
resharing: boolean;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
return await this.client.execute(this.sender, this.contractAddress, {
verify_verification_key_share: {
owner,
resharing
}
}, fee, memo, _funds);
}, fee_, memo_, funds_);
};
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> => {
advanceEpochState = async (fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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,11 +1,12 @@
/**
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
* 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 interface InstantiateMsg {
group_addr: string;
key_size: number;
mix_denom: string;
multisig_addr: string;
time_configuration?: TimeConfiguration | null;
@@ -19,16 +20,24 @@ 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_dealing: {
dealing_bytes: ContractSafeBytes;
commit_dealings_metadata: {
chunks: DealingChunkInfo[];
dealing_index: number;
resharing: boolean;
};
} | {
commit_dealings_chunk: {
chunk: PartialContractDealing;
};
} | {
commit_verification_key_share: {
resharing: boolean;
@@ -36,41 +45,115 @@ export type ExecuteMsg = {
};
} | {
verify_verification_key_share: {
owner: Addr;
owner: string;
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 type Addr = string;
export interface DealingChunkInfo {
size: number;
}
export interface PartialContractDealing {
chunk_index: number;
data: ContractSafeBytes;
dealing_index: number;
}
export type QueryMsg = {
get_state: {};
} | {
get_current_epoch_state: {};
} | {
get_epoch_state_at_height: {
height: number;
};
} | {
get_current_epoch_threshold: {};
} | {
get_initial_dealers: {};
get_epoch_threshold: {
epoch_id: number;
};
} | {
can_advance_state: {};
} | {
get_registered_dealer: {
dealer_address: string;
epoch_id?: number | null;
};
} | {
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_past_dealers: {
get_dealer_indices: {
limit?: number | null;
start_after?: string | null;
};
} | {
get_dealing: {
idx: number;
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_verification_keys: {
@@ -78,22 +161,11 @@ export type QueryMsg = {
limit?: number | null;
start_after?: string | null;
};
} | {
get_cw2_contract_version: {};
};
export interface MigrateMsg {}
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" | {
export type EpochState = ("waiting_initialisation" | "in_progress") | {
public_key_submission: {
resharing: boolean;
};
@@ -114,36 +186,132 @@ export type EpochState = "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 type DealerType = "current" | "past" | "unknown";
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 interface DealerDetailsResponse {
dealer_type: DealerType;
details?: DealerDetails | null;
}
export interface PagedDealingsResponse {
dealings: ContractDealing[];
per_page: number;
export interface PagedDealerIndexResponse {
indices: [Addr, number][];
start_next_after?: Addr | null;
}
export interface ContractDealing {
export interface DealingChunkResponse {
chunk?: ContractSafeBytes | null;
chunk_index: number;
dealer: Addr;
dealing: ContractSafeBytes;
dealing_index: number;
epoch_id: number;
}
export type NullableInitialReplacementData = InitialReplacementData | null;
export interface InitialReplacementData {
initial_dealers: Addr[];
initial_height: number;
export interface DealingChunkStatusResponse {
chunk_index: number;
dealer: Addr;
dealing_index: number;
epoch_id: number;
status: ChunkSubmissionStatus;
}
export interface PagedVKSharesResponse {
per_page: number;
shares: ContractVKShare[];
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[];
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;
@@ -151,4 +319,9 @@ export interface ContractVKShare {
owner: Addr;
share: string;
verified: boolean;
}
export interface PagedVKSharesResponse {
per_page: number;
shares: ContractVKShare[];
start_next_after?: Addr | null;
}
@@ -1,13 +1,12 @@
/**
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
* 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 { 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";
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";
export interface Cw3FlexMultisigReadOnlyInterface {
contractAddress: string;
threshold: () => Promise<ThresholdResponse>;
@@ -61,10 +60,9 @@ export interface Cw3FlexMultisigReadOnlyInterface {
config: () => Promise<Config>;
}
export class Cw3FlexMultisigQueryClient implements Cw3FlexMultisigReadOnlyInterface {
client: CosmWasmClient;
client: ICosmWasmClient;
contractAddress: string;
constructor(client: CosmWasmClient, contractAddress: string) {
constructor(client: ICosmWasmClient, contractAddress: string) {
this.client = client;
this.contractAddress = contractAddress;
this.threshold = this.threshold.bind(this);
@@ -77,7 +75,6 @@ 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: {}
@@ -197,36 +194,35 @@ export interface Cw3FlexMultisigInterface extends Cw3FlexMultisigReadOnlyInterfa
latest?: Expiration;
msgs: CosmosMsgForEmpty[];
title: string;
}, 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>;
}, 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>;
execute: ({
proposalId
}: {
proposalId: number;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
close: ({
proposalId
}: {
proposalId: number;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
memberChangedHook: ({
diffs
}: {
diffs: MemberDiff[];
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
}
export class Cw3FlexMultisigClient extends Cw3FlexMultisigQueryClient implements Cw3FlexMultisigInterface {
client: SigningCosmWasmClient;
client: ISigningCosmWasmClient;
sender: string;
contractAddress: string;
constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) {
constructor(client: ISigningCosmWasmClient, sender: string, contractAddress: string) {
super(client, contractAddress);
this.client = client;
this.sender = sender;
@@ -237,7 +233,6 @@ export class Cw3FlexMultisigClient extends Cw3FlexMultisigQueryClient implements
this.close = this.close.bind(this);
this.memberChangedHook = this.memberChangedHook.bind(this);
}
propose = async ({
description,
latest,
@@ -248,7 +243,7 @@ export class Cw3FlexMultisigClient extends Cw3FlexMultisigQueryClient implements
latest?: Expiration;
msgs: CosmosMsgForEmpty[];
title: string;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
return await this.client.execute(this.sender, this.contractAddress, {
propose: {
description,
@@ -256,53 +251,53 @@ export class Cw3FlexMultisigClient extends Cw3FlexMultisigQueryClient implements
msgs,
title
}
}, fee, memo, _funds);
}, 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_);
};
// 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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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@0.35.3.
* 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.
*/
@@ -84,86 +84,17 @@ 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 = {
@@ -171,7 +102,6 @@ export type WasmMsg = {
contract_addr: string;
funds: Coin[];
msg: Binary;
[k: string]: unknown;
};
} | {
instantiate: {
@@ -180,54 +110,30 @@ 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 GovMsg = {
vote: {
proposal_id: number;
vote: VoteOption;
[k: string]: unknown;
};
};
export type VoteOption = "yes" | "no" | "abstain" | "no_with_veto";
export type Binary = string;
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,13 +1,12 @@
/**
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
* 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 { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate";
import { Coin, StdFee } from "@cosmjs/amino";
import { ICosmWasmClient, ISigningCosmWasmClient } from "./baseClient";
import { Coin, StdFee } from "@interchainjs/types";
import { InstantiateMsg, Member, ExecuteMsg, QueryMsg, MigrateMsg, AdminResponse, HooksResponse, MemberListResponse, MemberResponse, TotalWeightResponse } from "./Cw4Group.types";
export interface Cw4GroupReadOnlyInterface {
contractAddress: string;
admin: () => Promise<AdminResponse>;
@@ -33,10 +32,9 @@ export interface Cw4GroupReadOnlyInterface {
hooks: () => Promise<HooksResponse>;
}
export class Cw4GroupQueryClient implements Cw4GroupReadOnlyInterface {
client: CosmWasmClient;
client: ICosmWasmClient;
contractAddress: string;
constructor(client: CosmWasmClient, contractAddress: string) {
constructor(client: ICosmWasmClient, contractAddress: string) {
this.client = client;
this.contractAddress = contractAddress;
this.admin = this.admin.bind(this);
@@ -45,7 +43,6 @@ 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: {}
@@ -103,31 +100,30 @@ export interface Cw4GroupInterface extends Cw4GroupReadOnlyInterface {
admin
}: {
admin?: string;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
updateMembers: ({
add,
remove
}: {
add: Member[];
remove: string[];
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
addHook: ({
addr
}: {
addr: string;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
removeHook: ({
addr
}: {
addr: string;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
}
export class Cw4GroupClient extends Cw4GroupQueryClient implements Cw4GroupInterface {
client: SigningCosmWasmClient;
client: ISigningCosmWasmClient;
sender: string;
contractAddress: string;
constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) {
constructor(client: ISigningCosmWasmClient, sender: string, contractAddress: string) {
super(client, contractAddress);
this.client = client;
this.sender = sender;
@@ -137,17 +133,16 @@ 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<ExecuteResult> => {
}, 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);
}, fee_, memo_, funds_);
};
updateMembers = async ({
add,
@@ -155,34 +150,34 @@ export class Cw4GroupClient extends Cw4GroupQueryClient implements Cw4GroupInter
}: {
add: Member[];
remove: string[];
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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@0.35.3.
* 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.
*/
@@ -0,0 +1,256 @@
/**
* 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_);
};
}
@@ -0,0 +1,106 @@
/**
* 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,80 +1,66 @@
/**
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
* 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 Decimal = string;
export type Percent = Decimal;
/**
* This instantiates the contract.
*/
export type Uint128 = string;
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_size: number;
rewarded_set_params: RewardedSetParams;
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 = {
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_admin: {
admin: string;
};
} | {
update_rewarding_validator_address: {
@@ -82,12 +68,16 @@ export type ExecuteMsg = {
};
} | {
update_contract_state_params: {
updated_parameters: ContractStateParams;
update: ContractStateParamsUpdate;
};
} | {
update_active_set_size: {
active_set_size: number;
update_current_nym_node_semver: {
current_version: string;
};
} | {
update_active_set_distribution: {
force_immediately: boolean;
update: ActiveSetUpdate;
};
} | {
update_rewarding_params: {
@@ -102,24 +92,23 @@ 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: MixNodeCostParams;
cost_params: NodeCostParams;
mix_node: MixNode;
owner_signature: MessageSignature;
};
} | {
bond_mixnode_on_behalf: {
cost_params: MixNodeCostParams;
cost_params: NodeCostParams;
mix_node: MixNode;
owner: string;
owner_signature: MessageSignature;
@@ -146,12 +135,12 @@ export type ExecuteMsg = {
owner: string;
};
} | {
update_mixnode_cost_params: {
new_costs: MixNodeCostParams;
update_cost_params: {
new_costs: NodeCostParams;
};
} | {
update_mixnode_cost_params_on_behalf: {
new_costs: MixNodeCostParams;
new_costs: NodeCostParams;
owner: string;
};
} | {
@@ -163,6 +152,8 @@ export type ExecuteMsg = {
new_config: MixNodeConfigUpdate;
owner: string;
};
} | {
migrate_mixnode: {};
} | {
bond_gateway: {
gateway: Gateway;
@@ -190,8 +181,24 @@ export type ExecuteMsg = {
owner: string;
};
} | {
delegate_to_mixnode: {
mix_id: number;
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_on_behalf: {
@@ -199,8 +206,8 @@ export type ExecuteMsg = {
mix_id: number;
};
} | {
undelegate_from_mixnode: {
mix_id: number;
undelegate: {
node_id: number;
};
} | {
undelegate_from_mixnode_on_behalf: {
@@ -208,9 +215,9 @@ export type ExecuteMsg = {
mix_id: number;
};
} | {
reward_mixnode: {
mix_id: number;
performance: Percent;
reward_node: {
node_id: number;
params: NodeRewardingParameters;
};
} | {
withdraw_operator_reward: {};
@@ -220,42 +227,62 @@ export type ExecuteMsg = {
};
} | {
withdraw_delegator_reward: {
mix_id: number;
node_id: number;
};
} | {
withdraw_delegator_reward_on_behalf: {
mix_id: number;
owner: string;
};
} | {
migrate_vested_mix_node: {};
} | {
migrate_vested_delegation: {
mix_id: number;
};
};
export type Layer = "One" | "Two" | "Three";
export type FamilyHead = string;
export type Role = "eg" | "l1" | "l2" | "l3" | "xg" | "stb";
export type MessageSignature = number[];
export type Uint128 = string;
export interface ContractStateParams {
minimum_gateway_pledge: Coin;
minimum_mixnode_delegation?: Coin | null;
minimum_mixnode_pledge: Coin;
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 interface Coin {
amount: Uint128;
denom: string;
[k: string]: unknown;
}
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;
}
export interface IntervalRewardingParamsUpdate {
active_set_work_factor?: Decimal | null;
interval_pool_emission?: Percent | null;
reward_pool?: Decimal | null;
rewarded_set_size?: number | null;
rewarded_set_params?: RewardedSetParams | null;
staking_supply?: Decimal | null;
staking_supply_scale_factor?: Percent | null;
sybil_resistance_percent?: Percent | null;
}
export interface LayerAssignment {
layer: Layer;
mix_id: number;
export interface RoleAssignment {
nodes: number[];
role: Role;
}
export interface MixNodeCostParams {
export interface NodeCostParams {
interval_operating_cost: Coin;
profit_margin_percent: Percent;
}
@@ -291,32 +318,22 @@ 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 = {
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;
};
admin: {};
} | {
get_contract_version: {};
} | {
@@ -327,17 +344,19 @@ 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;
@@ -389,8 +408,6 @@ export type QueryMsg = {
get_bonded_mixnode_details_by_identity: {
mix_identity: string;
};
} | {
get_layer_distribution: {};
} | {
get_gateways: {
limit?: number | null;
@@ -405,9 +422,71 @@ export type QueryMsg = {
address: string;
};
} | {
get_mixnode_delegations: {
get_preassigned_gateway_ids: {
limit?: number | null;
mix_id: number;
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;
start_after?: string | null;
};
} | {
@@ -419,7 +498,7 @@ export type QueryMsg = {
} | {
get_delegation_details: {
delegator: string;
mix_id: number;
node_id: number;
proxy?: string | null;
};
} | {
@@ -432,26 +511,27 @@ export type QueryMsg = {
address: string;
};
} | {
get_pending_mix_node_operator_reward: {
mix_id: number;
get_pending_node_operator_reward: {
node_id: number;
};
} | {
get_pending_delegator_reward: {
address: string;
mix_id: number;
node_id: number;
proxy?: string | null;
};
} | {
get_estimated_current_epoch_operator_reward: {
estimated_performance: Percent;
mix_id: number;
estimated_work?: Decimal | null;
node_id: number;
};
} | {
get_estimated_current_epoch_delegator_reward: {
address: string;
estimated_performance: Percent;
mix_id: number;
proxy?: string | null;
estimated_work?: Decimal | null;
node_id: number;
};
} | {
get_pending_epoch_events: {
@@ -477,10 +557,18 @@ 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[];
@@ -490,23 +578,10 @@ export interface Delegation {
amount: Coin;
cumulative_reward_ratio: Decimal;
height: number;
mix_id: number;
node_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;
@@ -514,12 +589,11 @@ export interface MixnodeDetailsByIdentityResponse {
export interface MixNodeDetails {
bond_information: MixNodeBond;
pending_changes?: PendingMixNodeChanges;
rewarding_details: MixNodeRewarding;
rewarding_details: NodeRewarding;
}
export interface MixNodeBond {
bonding_height: number;
is_unbonding: boolean;
layer: Layer;
mix_id: number;
mix_node: MixNode;
original_pledge: Coin;
@@ -527,10 +601,11 @@ export interface MixNodeBond {
proxy?: Addr | null;
}
export interface PendingMixNodeChanges {
cost_params_change?: number | null;
pledge_change?: number | null;
}
export interface MixNodeRewarding {
cost_params: MixNodeCostParams;
export interface NodeRewarding {
cost_params: NodeCostParams;
delegates: Decimal;
last_rewarded_epoch: number;
operator: Decimal;
@@ -545,9 +620,12 @@ 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 {
@@ -563,11 +641,29 @@ export interface Interval {
epochs_in_interval: number;
id: number;
total_elapsed_epochs: number;
[k: string]: unknown;
}
export interface MixNodeDelegationResponse {
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 {
delegation?: Delegation | null;
mixnode_still_bonded: boolean;
node_still_bonded: boolean;
}
export interface PagedDelegatorDelegationsResponse {
delegations: Delegation[];
@@ -578,7 +674,11 @@ export type EpochState = "in_progress" | {
final_node_id: number;
last_rewarded: number;
};
} | "reconciling_events" | "advancing_epoch";
} | "reconciling_events" | {
role_assignment: {
next: Role;
};
};
export interface EpochStatus {
being_advanced_by: Addr;
state: EpochState;
@@ -590,22 +690,6 @@ 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;
@@ -622,10 +706,12 @@ export interface PagedGatewayResponse {
per_page: number;
start_next_after?: string | null;
}
export interface LayerDistribution {
layer1: number;
layer2: number;
layer3: number;
export interface KeyRotationIdResponse {
rotation_id: number;
}
export interface KeyRotationState {
initial_epoch_id: number;
validity_epochs: number;
}
export interface PagedMixnodeBondsResponse {
nodes: MixNodeBond[];
@@ -637,22 +723,68 @@ 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?: MixNodeRewarding | null;
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;
}
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;
@@ -661,32 +793,47 @@ 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;
mix_id: number;
node_id: number;
owner: Addr;
proxy?: Addr | null;
};
} | {
undelegate: {
mix_id: number;
node_id: number;
owner: Addr;
proxy?: Addr | null;
};
} | {
pledge_more: {
nym_node_pledge_more: {
amount: Coin;
node_id: number;
};
} | {
mixnode_pledge_more: {
amount: Coin;
mix_id: number;
};
} | {
decrease_pledge: {
nym_node_decrease_pledge: {
decrease_by: Coin;
node_id: number;
};
} | {
mixnode_decrease_pledge: {
decrease_by: Coin;
mix_id: number;
};
@@ -695,8 +842,12 @@ export type PendingEpochEventKind = {
mix_id: number;
};
} | {
update_active_set_size: {
new_size: number;
unbond_nym_node: {
node_id: number;
};
} | {
update_active_set: {
update: ActiveSetUpdate;
};
};
export interface PendingEpochEventResponse {
@@ -719,7 +870,12 @@ export interface PendingEpochEvent {
export type PendingIntervalEventKind = {
change_mix_cost_params: {
mix_id: number;
new_costs: MixNodeCostParams;
new_costs: NodeCostParams;
};
} | {
change_nym_node_cost_params: {
new_costs: NodeCostParams;
node_id: number;
};
} | {
update_rewarding_params: {
@@ -748,15 +904,34 @@ export interface PendingIntervalEvent {
event: PendingIntervalEventData;
id: number;
}
export type RewardedSetNodeStatus = "active" | "standby";
export interface PagedRewardedSetResponse {
nodes: [number, RewardedSetNodeStatus][];
start_next_after?: number | null;
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 interface RewardingParams {
active_set_size: number;
interval: IntervalRewardParams;
rewarded_set_size: number;
rewarded_set: RewardedSetParams;
}
export interface IntervalRewardParams {
active_set_work_factor: Decimal;
@@ -769,19 +944,37 @@ export interface IntervalRewardParams {
sybil_resistance: Percent;
}
export type String = string;
export interface EpochAssignmentResponse {
epoch_id: number;
nodes: number[];
}
export type Uint32 = number;
export interface StakeSaturationResponse {
export interface MixStakeSaturationResponse {
current_saturation?: Decimal | null;
mix_id: number;
uncapped_saturation?: Decimal | null;
}
export interface ContractState {
owner: Addr;
owner?: Addr | null;
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;
@@ -797,3 +990,17 @@ 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,13 +1,12 @@
/**
* This file was automatically generated by @cosmwasm/ts-codegen@0.35.3.
* 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 { 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';
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";
export interface VestingReadOnlyInterface {
contractAddress: string;
getContractVersion: () => Promise<ContractBuildInformation>;
@@ -156,10 +155,9 @@ export interface VestingReadOnlyInterface {
}) => Promise<AllDelegationsResponse>;
}
export class VestingQueryClient implements VestingReadOnlyInterface {
client: CosmWasmClient;
client: ICosmWasmClient;
contractAddress: string;
constructor(client: CosmWasmClient, contractAddress: string) {
constructor(client: ICosmWasmClient, contractAddress: string) {
this.client = client;
this.contractAddress = contractAddress;
this.getContractVersion = this.getContractVersion.bind(this);
@@ -189,7 +187,6 @@ 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: {}
@@ -501,56 +498,34 @@ 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<ExecuteResult>;
claimOperatorReward: (fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
claimOperatorReward: (fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
claimDelegatorReward: ({
mixId
}: {
mixId: number;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
updateMixnodeCostParams: ({
newCosts
}: {
newCosts: MixNodeCostParams;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
newCosts: NodeCostParams;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
updateMixnodeConfig: ({
newConfig
}: {
newConfig: MixNodeConfigUpdate;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
updateMixnetAddress: ({
address
}: {
address: string;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
delegateToMixnode: ({
amount,
mixId,
@@ -559,14 +534,14 @@ export interface VestingInterface extends VestingReadOnlyInterface {
amount: Coin;
mixId: number;
onBehalfOf?: string;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
undelegateFromMixnode: ({
mixId,
onBehalfOf
}: {
mixId: number;
onBehalfOf?: string;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
createAccount: ({
cap,
ownerAddress,
@@ -577,12 +552,12 @@ export interface VestingInterface extends VestingReadOnlyInterface {
ownerAddress: string;
stakingAddress?: string;
vestingSpec?: VestingSpecification;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
withdrawVestedCoins: ({
amount
}: {
amount: Coin;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
trackUndelegation: ({
amount,
mixId,
@@ -591,7 +566,7 @@ export interface VestingInterface extends VestingReadOnlyInterface {
amount: Coin;
mixId: number;
owner: string;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
bondMixnode: ({
amount,
costParams,
@@ -599,35 +574,35 @@ export interface VestingInterface extends VestingReadOnlyInterface {
ownerSignature
}: {
amount: Coin;
costParams: MixNodeCostParams;
costParams: NodeCostParams;
mixNode: MixNode;
ownerSignature: MessageSignature;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
pledgeMore: ({
amount
}: {
amount: Coin;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
decreasePledge: ({
amount
}: {
amount: Coin;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
unbondMixnode: (fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
unbondMixnode: (fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
trackUnbondMixnode: ({
amount,
owner
}: {
amount: Coin;
owner: string;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
trackDecreasePledge: ({
amount,
owner
}: {
amount: Coin;
owner: string;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
bondGateway: ({
amount,
gateway,
@@ -636,52 +611,59 @@ export interface VestingInterface extends VestingReadOnlyInterface {
amount: Coin;
gateway: Gateway;
ownerSignature: MessageSignature;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
unbondGateway: (fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
unbondGateway: (fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
trackUnbondGateway: ({
amount,
owner
}: {
amount: Coin;
owner: string;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
updateGatewayConfig: ({
newConfig
}: {
newConfig: GatewayConfigUpdate;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
transferOwnership: ({
toAddress
}: {
toAddress: string;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
updateStakingAddress: ({
toAddress
}: {
toAddress?: string;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, fee_?: number | StdFee | "auto", memo_?: string, funds_?: Coin[]) => Promise<any>;
updateLockedPledgeCap: ({
address,
cap
}: {
address: string;
cap: PledgeCap;
}, fee?: number | StdFee | "auto", memo?: string, _funds?: Coin[]) => Promise<ExecuteResult>;
}, 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>;
}
export class VestingClient extends VestingQueryClient implements VestingInterface {
client: SigningCosmWasmClient;
client: ISigningCosmWasmClient;
sender: string;
contractAddress: string;
constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) {
constructor(client: ISigningCosmWasmClient, 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);
@@ -706,117 +688,71 @@ 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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
claimOperatorReward = async (fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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: MixNodeCostParams;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
newCosts: NodeCostParams;
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
return await this.client.execute(this.sender, this.contractAddress, {
update_mixnet_address: {
address
}
}, fee, memo, _funds);
}, fee_, memo_, funds_);
};
delegateToMixnode = async ({
amount,
@@ -826,14 +762,14 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
amount: Coin;
mixId: number;
onBehalfOf?: string;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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,
@@ -841,13 +777,13 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
}: {
mixId: number;
onBehalfOf?: string;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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,
@@ -859,7 +795,7 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
ownerAddress: string;
stakingAddress?: string;
vestingSpec?: VestingSpecification;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
return await this.client.execute(this.sender, this.contractAddress, {
create_account: {
cap,
@@ -867,18 +803,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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
return await this.client.execute(this.sender, this.contractAddress, {
withdraw_vested_coins: {
amount
}
}, fee, memo, _funds);
}, fee_, memo_, funds_);
};
trackUndelegation = async ({
amount,
@@ -888,14 +824,14 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
amount: Coin;
mixId: number;
owner: string;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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,
@@ -904,10 +840,10 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
ownerSignature
}: {
amount: Coin;
costParams: MixNodeCostParams;
costParams: NodeCostParams;
mixNode: MixNode;
ownerSignature: MessageSignature;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
return await this.client.execute(this.sender, this.contractAddress, {
bond_mixnode: {
amount,
@@ -915,34 +851,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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
unbondMixnode = async (fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
return await this.client.execute(this.sender, this.contractAddress, {
unbond_mixnode: {}
}, fee, memo, _funds);
}, fee_, memo_, funds_);
};
trackUnbondMixnode = async ({
amount,
@@ -950,13 +886,13 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
}: {
amount: Coin;
owner: string;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
return await this.client.execute(this.sender, this.contractAddress, {
track_unbond_mixnode: {
amount,
owner
}
}, fee, memo, _funds);
}, fee_, memo_, funds_);
};
trackDecreasePledge = async ({
amount,
@@ -964,13 +900,13 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
}: {
amount: Coin;
owner: string;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
return await this.client.execute(this.sender, this.contractAddress, {
track_decrease_pledge: {
amount,
owner
}
}, fee, memo, _funds);
}, fee_, memo_, funds_);
};
bondGateway = async ({
amount,
@@ -980,19 +916,19 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
amount: Coin;
gateway: Gateway;
ownerSignature: MessageSignature;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
unbondGateway = async (fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
return await this.client.execute(this.sender, this.contractAddress, {
unbond_gateway: {}
}, fee, memo, _funds);
}, fee_, memo_, funds_);
};
trackUnbondGateway = async ({
amount,
@@ -1000,46 +936,46 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
}: {
amount: Coin;
owner: string;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
return await this.client.execute(this.sender, this.contractAddress, {
update_staking_address: {
to_address: toAddress
}
}, fee, memo, _funds);
}, fee_, memo_, funds_);
};
updateLockedPledgeCap = async ({
address,
@@ -1047,12 +983,37 @@ export class VestingClient extends VestingQueryClient implements VestingInterfac
}: {
address: string;
cap: PledgeCap;
}, fee: number | StdFee | "auto" = "auto", memo?: string, _funds?: Coin[]): Promise<ExecuteResult> => {
}, fee_: number | StdFee | "auto" = "auto", memo_?: string, funds_?: Coin[]): Promise<any> => {
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@0.35.3.
* 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.
*/
@@ -9,23 +9,6 @@ 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;
@@ -38,7 +21,7 @@ export type ExecuteMsg = {
};
} | {
update_mixnode_cost_params: {
new_costs: MixNodeCostParams;
new_costs: NodeCostParams;
};
} | {
update_mixnode_config: {
@@ -79,7 +62,7 @@ export type ExecuteMsg = {
} | {
bond_mixnode: {
amount: Coin;
cost_params: MixNodeCostParams;
cost_params: NodeCostParams;
mix_node: MixNode;
owner_signature: MessageSignature;
};
@@ -133,9 +116,16 @@ 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;
@@ -144,12 +134,12 @@ export type PledgeCap = {
} | {
absolute: Uint128;
};
export type MessageSignature = number[];
export interface Coin {
amount: Uint128;
denom: string;
[k: string]: unknown;
}
export interface MixNodeCostParams {
export interface NodeCostParams {
interval_operating_cost: Coin;
profit_margin_percent: Percent;
}
@@ -353,9 +343,12 @@ 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" | {
@@ -0,0 +1,200 @@
/**
* 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,35 +1,48 @@
/**
* 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.
*/
* 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 * 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 */
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";
export namespace contracts {
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 };
}
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
};
}
@@ -1,6 +1,6 @@
{
"name": "@nymproject/sdk-example-plain-html-parcel",
"version": "1.0.4-rc.2",
"version": "1.0.5",
"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.2.2-rc.0 || ^1"
"@nymproject/sdk": ">=1.4.1-rc1 || ^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.4-rc.2",
"version": "1.0.5",
"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.2.2-rc.0 || ^1"
"@nymproject/sdk": ">=1.4.1-rc1 || ^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.4-rc.2",
"version": "1.0.5",
"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.2.2-rc.0 || ^1",
"@nymproject/sdk": ">=1.4.1-rc1 || ^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.4-rc.2",
"version": "1.0.5",
"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.2.2-rc.0 || ^1"
"@nymproject/sdk": ">=1.4.1-rc1 || ^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.4-rc.2",
"version": "1.0.5",
"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.2.2-rc.0 || ^1"
"@nymproject/sdk": ">=1.4.1-rc1 || ^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.4-rc.2",
"version": "1.0.5",
"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.2.2-rc.0 || ^1",
"@nymproject/mix-fetch": ">=1.4.1-rc1 || ^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.4-rc.2",
"version": "1.0.5",
"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.2.2-rc.0 || ^1"
"@nymproject/sdk": ">=1.4.1-rc1 || ^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.4-rc.2",
"version": "1.0.5",
"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.2.2-rc.0 || ^1"
"@nymproject/sdk": ">=1.4.1-rc1 || ^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.4-rc.2",
"version": "1.0.5",
"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.2.2-rc.0 || ^1",
"@nymproject/sdk": ">=1.4.1-rc1 || ^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.0-rc.0",
"version": "1.4.1",
"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.4-rc.2 || ^1",
"@nymproject/mix-fetch-wasm-node": ">=1.4.1-rc.3 || ^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.4-rc.2",
"version": "1.0.5",
"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.2.2-rc.0 || ^1"
"@nymproject/mix-fetch": ">=1.4.1-rc1 || ^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.4-rc.2",
"version": "1.0.5",
"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.2.2-rc.0 || ^1"
"@nymproject/mix-fetch": ">=1.4.1-rc1 || ^1"
},
"private": false,
"source": "../src/index.html"
}
}
@@ -21,6 +21,7 @@ async function main() {
// const addr =
// 'EVdJ66jqpoVzmktVecy5UJxsTCEWo5gMn5zDZR7Hm8jy.GXNpoX7RcYcxKvBkV3dSHqC78WaPuWieweRPWzYqNhh5@GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ';
// const addr = '7Y9eyF1p1JmzHnd7TVZufnQHkh93ASc9sRBCFY57ZGr8.F8KPyVMVqFQ5yJC3LqeP2ZC7fukzj9a1T426rjo432yT@q2A2cbooyC16YJzvdYaSMH9X3cSiieZNtfBr8cE8Fi1';
const addr = undefined;
appendOutput('About to set up mixFetch...');
@@ -54,12 +55,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://nymtech.net/favicon.svg';
url = 'https://matrix.org/assets/frontpage/github-mark.svg';
resp = await mixFetch(url, args);
console.log({ resp });
const buffer = await resp.arrayBuffer();
@@ -35,7 +35,8 @@ 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')), 'dist/esm/*.wasm'),
from: path.resolve(path.dirname(require.resolve('@nymproject/mix-fetch/package.json')), '*.wasm'),
to: '[name][ext]',
},
],
@@ -1,7 +1,5 @@
const { mergeWithRules } = require('webpack-merge');
const webpack = require('webpack');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const ReactRefreshTypeScript = require('react-refresh-typescript');
const commonConfig = require('./webpack.common');
module.exports = mergeWithRules({
@@ -22,7 +20,7 @@ module.exports = mergeWithRules({
exclude: /node_modules/,
options: {
getCustomTransformers: () => ({
before: [ReactRefreshTypeScript()],
before: [],
}),
// `ts-loader` does not work with HMR unless `transpileOnly` is used.
// If you need type checking, `ForkTsCheckerWebpackPlugin` is an alternative.
@@ -36,8 +34,6 @@ module.exports = mergeWithRules({
],
},
plugins: [
new ReactRefreshWebpackPlugin(),
// this can be included automatically by the dev server, however build mode fails if missing
new webpack.HotModuleReplacementPlugin(),
],
@@ -1,6 +1,6 @@
{
"name": "@nymproject/mix-fetch",
"version": "1.4.0-rc.0",
"version": "1.4.1",
"description": "This package is a drop-in replacement for `fetch` to send HTTP requests over the Nym Mixnet.",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
@@ -34,7 +34,7 @@
"tsc": "tsc --noEmit true"
},
"dependencies": {
"@nymproject/mix-fetch-wasm": ">=1.2.4-rc.2 || ^1",
"@nymproject/mix-fetch-wasm": ">=1.4.1-rc.3 || ^1",
"comlink": "^4.3.1"
},
"devDependencies": {
@@ -1,6 +1,6 @@
{
"name": "@nymproject/node-tester",
"version": "1.3.0-rc.0",
"version": "1.3.1",
"description": "This package provides a tester that can send test packets to mixnode that is part of the Nym Mixnet.",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
@@ -25,7 +25,7 @@
"tsc": "tsc --noEmit true"
},
"dependencies": {
"@nymproject/nym-node-tester-wasm": ">=1.2.4-rc.2 || ^1",
"@nymproject/nym-node-tester-wasm": ">=1.3.1-rc.0 || ^1",
"comlink": "^4.3.1"
},
"devDependencies": {
@@ -1,6 +1,6 @@
{
"name": "@nymproject/nodejs-client",
"version": "1.4.0-rc.0",
"version": "1.4.1",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
"files": [
@@ -25,7 +25,7 @@
"tsc": "tsc --noEmit true"
},
"dependencies": {
"@nymproject/nym-client-wasm-node": ">=1.2.4-rc.2 || ^1",
"@nymproject/nym-client-wasm-node": ">=1.4.1-rc.3 || ^1",
"comlink": "^4.3.1",
"fake-indexeddb": "^4.0.2",
"rollup-plugin-polyfill": "^4.2.0",
@@ -67,7 +67,7 @@ class ClientWrapper {
console.error('Client has not been initialised. Please call `init` first.');
return undefined;
}
return this.client.self_address();
return this.client.selfAddress();
};
/**
@@ -1,6 +1,6 @@
{
"name": "@nymproject/sdk-react",
"version": "1.4.0-rc.0",
"version": "1.4.1",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
"files": [
@@ -20,7 +20,7 @@
"tsc": "tsc --noEmit true"
},
"dependencies": {
"@nymproject/sdk": ">=1.2.2-rc.0 || ^1"
"@nymproject/sdk": ">=1.4.1-rc.3 || ^1"
},
"devDependencies": {
"@babel/core": "^7.17.5",
@@ -67,4 +67,4 @@
"private": false,
"type": "module",
"types": "./dist/index.d.ts"
}
}
+9 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@nymproject/sdk",
"version": "1.4.0-rc.0",
"version": "1.4.1",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
"files": [
@@ -30,11 +30,8 @@
"test": "node --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js -c=jest.config.mjs --no-cache",
"tsc": "tsc --noEmit true"
},
"typeRoots": [
"./node_modules/@types/*"
],
"dependencies": {
"@nymproject/nym-client-wasm": ">=1.2.4-rc.2 || ^1",
"@nymproject/nym-client-wasm": ">=1.4.1-rc.3 || ^1",
"comlink": "^4.3.1"
},
"devDependencies": {
@@ -54,6 +51,7 @@
"@rollup/plugin-url": "^8.0.1",
"@rollup/plugin-wasm": "^6.1.1",
"@types/jest": "^27.0.1",
"@types/minimatch": "5.1.2",
"@types/node": "^16.7.13",
"@typescript-eslint/eslint-plugin": "^5.13.0",
"@typescript-eslint/parser": "^5.13.0",
@@ -81,7 +79,13 @@
"typedoc": "^0.24.8",
"typescript": "^4.8.4"
},
"resolutions": {
"@types/minimatch": "5.1.2"
},
"private": false,
"type": "module",
"typeRoots": [
"./node_modules/@types/*"
],
"types": "./dist/esm/index.d.ts"
}
@@ -79,7 +79,7 @@ class ClientWrapper {
return undefined;
}
return this.client.self_address();
return this.client.selfAddress();
};
/**
@@ -39,7 +39,7 @@
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-typescript": "^11.0.0",
"@types/minimatch": "^6.0.0",
"@types/minimatch": "5.1.2",
"@typescript-eslint/eslint-plugin": "^5.7.0",
"@typescript-eslint/parser": "^5.7.0",
"axios": "^1.3.3",
+1 -1
View File
@@ -21,7 +21,7 @@ yarn
yarn build:ci:sdk
# build documentation
yarn docs:prod:build
#yarn docs:prod:build
# turn dev mode off
yarn dev:off
+6 -1
View File
@@ -2,7 +2,12 @@ import fs from 'fs';
const packageJson = JSON.parse(fs.readFileSync('package.json').toString());
const devWorkspace = ['sdk/typescript/packages/**', 'sdk/typescript/examples/**', 'sdk/typescript/codegen/**'];
const devWorkspace = [
'dist/**',
'sdk/typescript/packages/**',
'sdk/typescript/examples/**',
'sdk/typescript/codegen/**',
];
if (!packageJson.workspaces.includes(devWorkspace)) {
// add
packageJson.workspaces.push(...devWorkspace);
+6 -1
View File
@@ -2,7 +2,12 @@ import fs from 'fs';
const packageJson = JSON.parse(fs.readFileSync('package.json').toString());
const devWorkspace = ['sdk/typescript/packages/**', 'sdk/typescript/examples/**', 'sdk/typescript/codegen/**'];
const devWorkspace = [
'dist/**',
'sdk/typescript/packages/**',
'sdk/typescript/examples/**',
'sdk/typescript/codegen/**',
];
// remove
packageJson.workspaces = packageJson.workspaces.filter((w) => !devWorkspace.includes(w));
+3 -3
View File
@@ -29,7 +29,7 @@ packages=(
"wasm/extension-storage"
"node/wasm/client"
"node/wasm/mix-fetch"
#"node/wasm/mix-fetch"
"ts/sdk/mix-fetch/cjs"
"ts/sdk/mix-fetch/cjs-full-fat"
@@ -49,7 +49,7 @@ packages=(
"ts/sdk/sdk/esm"
"ts/sdk/sdk/esm-full-fat"
"ts/sdk/contract-clients"
#"ts/sdk/contract-clients"
)
pushd () {
@@ -66,7 +66,7 @@ for item in "${packages[@]}"
do
pushd "$item"
jq -r '. | "📦 " + .version + " " +.name' < package.json
popd
popd
done
echo ""
+13 -5
View File
@@ -1,7 +1,7 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use anyhow::{bail, Context};
use anyhow::{Context, bail};
use semver::{Prerelease, Version};
use std::collections::HashSet;
use std::path::Path;
@@ -72,7 +72,9 @@ pub(crate) fn try_bump_raw_prerelease(raw: &str) -> anyhow::Result<Prerelease> {
impl VersionBumpExt for Version {
fn try_bump_prerelease(&self) -> anyhow::Result<Self> {
if self.pre.is_empty() {
bail!("the current version ({self}) does not have pre-release data set - are you sure you followed the release process correctly?")
bail!(
"the current version ({self}) does not have pre-release data set - are you sure you followed the release process correctly?"
)
}
Ok(Version {
@@ -86,7 +88,9 @@ impl VersionBumpExt for Version {
fn try_bump_patch_without_pre(&self) -> anyhow::Result<Self> {
if !self.pre.is_empty() {
bail!("the current version ({self}) has pre-release data set - are you sure you followed the release process correctly?")
bail!(
"the current version ({self}) has pre-release data set - are you sure you followed the release process correctly?"
)
}
let mut updated = self.clone();
@@ -96,7 +100,9 @@ impl VersionBumpExt for Version {
fn set_initial_release_candidate(&self) -> anyhow::Result<Self> {
if !self.pre.is_empty() {
bail!("the current version ({self}) has pre-release data set - are you sure you followed the release process correctly?")
bail!(
"the current version ({self}) has pre-release data set - are you sure you followed the release process correctly?"
)
}
Ok(Version {
major: self.major,
@@ -109,7 +115,9 @@ impl VersionBumpExt for Version {
fn try_remove_prerelease(&self) -> anyhow::Result<Self> {
if self.pre.is_empty() {
bail!("the current version ({self}) does not have pre-release data set - are you sure you followed the release process correctly?")
bail!(
"the current version ({self}) does not have pre-release data set - are you sure you followed the release process correctly?"
)
}
Ok(Version {
major: self.major,
+2 -2
View File
@@ -3,8 +3,8 @@
use crate::helpers::try_bump_raw_prerelease;
use crate::json_types::DepsSet;
use crate::{json_types, ReleasePackage};
use anyhow::{bail, Context};
use crate::{ReleasePackage, json_types};
use anyhow::{Context, bail};
use semver::{Comparator, Prerelease, Version, VersionReq};
use std::collections::HashSet;
use std::path::{Path, PathBuf};
+1 -1
View File
@@ -4,7 +4,7 @@ authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jedrzej Stuczynski <andrew@nymtech.net>",
]
version = "1.4.0-rc.0"
version = "1.4.1"
edition = "2021"
keywords = ["nym", "sphinx", "wasm", "webassembly", "privacy"]
license = "Apache-2.0"
+6 -1
View File
@@ -1,7 +1,9 @@
all: build build-node
build:
build: test build-wasm
build-wasm:
wasm-pack build --scope nymproject --target web --out-dir ../../dist/wasm/client
wasm-opt -Oz -o ../../dist/wasm/client/nym_client_wasm_bg.wasm ../../dist/wasm/client/nym_client_wasm_bg.wasm
@@ -16,3 +18,6 @@ build-package-json-node:
node build-node.mjs
build-node: build-rust-node build-package-json-node
test:
wasm-pack test --node
+44 -5
View File
@@ -58,7 +58,25 @@ pub fn encode_payload_with_headers(
Ok(metadata) => {
let metadata = metadata.as_bytes().to_vec();
let size = (metadata.len() as u64).to_be_bytes().to_vec();
Ok([size, metadata, payload].concat())
if size.len() != 8 {
return Err(JsValue::from(JsError::new(
format!("Size as big endian u8 is {} instead of 8", size.len()).as_str(),
)));
}
let metadata_length = metadata.len();
let payload_length = payload.len();
let encoded = [size, metadata, payload].concat();
if encoded.len() != (8 + metadata_length + payload_length) {
return Err(JsValue::from(JsError::new(
format!(
"Total size {} != {} (8 + {metadata_length} + {payload_length})",
encoded.len(),
8 + metadata_length + payload_length
)
.as_str(),
)));
}
Ok(encoded)
}
Err(e) => Err(JsValue::from(JsError::new(
format!("Could not encode message: {e}").as_str(),
@@ -90,7 +108,7 @@ pub fn decode_payload(message: Vec<u8>) -> Result<IEncodedPayload, JsValue> {
}
pub(crate) fn parse_payload(message: &[u8]) -> anyhow::Result<(EncodedPayloadMetadata, &[u8])> {
// 1st 8 bytes are the size (as u64 big endian)
// 1st 8 bytes are the size of the metadata field (as u64 big endian)
let mut size = [0u8; 8];
if message.len() < 8 {
bail!("Message is too short to contain size information")
@@ -98,10 +116,23 @@ pub(crate) fn parse_payload(message: &[u8]) -> anyhow::Result<(EncodedPayloadMet
size.clone_from_slice(&message[0..8]);
let metadata_size = u64::from_be_bytes(size) as usize;
if metadata_size + 8 != message.len() {
if metadata_size + 8 > message.len() {
return Err(anyhow::anyhow!(format!(
"Metadata size: {}, exceeds message with length of: {}",
"Metadata size: {} bytes + 8 bytes ({} bytes) > {} bytes, message length. Did you pass the entire message for decoding?",
metadata_size,
metadata_size + 8,
message.len()
),));
}
let payload_size = message.len() - (8 + metadata_size);
if payload_size + metadata_size + 8 != message.len() {
return Err(anyhow::anyhow!(format!(
"Payload size {} + Metadata size {} + 8 ({}) != {} message length",
payload_size,
metadata_size,
payload_size + metadata_size + 8,
message.len()
),));
}
@@ -275,7 +306,7 @@ mod tests {
let error = result.unwrap_err();
assert_eq!(
error.to_string(),
"Metadata size: 20, exceeds message with length of: 18"
"Metadata size: 20 bytes + 8 bytes (28 bytes) > 18 bytes, message length. Did you pass the entire message for decoding?"
);
}
@@ -294,6 +325,14 @@ mod tests {
message.extend_from_slice(serialized_metadata.as_bytes());
message.extend_from_slice(&payload_data);
wasm_utils::console_log!("message length: {}", message.len());
wasm_utils::console_log!("metadata length: {}", metadata_length);
wasm_utils::console_log!("payload length: {}", payload_data.len());
wasm_utils::console_log!(
"8 + metadata_length + payload_length = {}",
payload_data.len() + metadata_length as usize + 8
);
let (parsed_metadata, parsed_payload) = parse_payload(&message).unwrap();
assert_eq!(parsed_metadata.mime_type, metadata.mime_type);
+1 -1
View File
@@ -20,7 +20,7 @@ use wasm_utils::set_panic_hook;
#[wasm_bindgen(start)]
#[cfg(target_arch = "wasm32")]
pub fn main() {
pub fn main_js() {
wasm_utils::console_log!("[rust main]: setting panic hook");
set_panic_hook();
wasm_utils::console_log!("[rust main]: rust module loaded");
+2 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "mix-fetch-wasm"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"]
version = "1.4.0-rc.0"
version = "1.4.1"
edition = "2021"
keywords = ["nym", "fetch", "wasm", "webassembly", "privacy"]
license = "Apache-2.0"
@@ -32,6 +32,7 @@ nym-http-api-client = { path = "../../common/http-api-client" }
nym-socks5-requests = { path = "../../common/socks5/requests" }
nym-ordered-buffer = { path = "../../common/socks5/ordered-buffer" }
nym-service-providers-common = { path = "../../service-providers/common" }
nym-validator-client = { path = "../../common/client-libs/validator-client", default-features = false }
wasm-client-core = { path = "../../common/wasm/client-core" }
wasm-utils = { path = "../../common/wasm/utils" }
+3 -5
View File
@@ -1,9 +1,7 @@
module go-mix-conn
go 1.23.0
go 1.24.0
toolchain go1.23.3
require golang.org/x/net v0.46.0
require golang.org/x/net v0.38.0
require golang.org/x/text v0.23.0 // indirect
require golang.org/x/text v0.30.0 // indirect

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