removed legacy nym-vpn-lib-wasm

This commit is contained in:
Jędrzej Stuczyński
2026-02-26 13:03:48 +00:00
parent 2b88c717c7
commit 4d4e786d5e
13 changed files with 0 additions and 2765 deletions
@@ -1,42 +0,0 @@
name: ci-build-vpn-api-wasm
on:
pull_request:
paths:
- 'common/**'
- 'nym-credential-proxy/**'
- '.github/workflows/ci-build-vpn-api-wasm.yml'
jobs:
wasm:
runs-on: arc-linux-latest
env:
CARGO_TERM_COLOR: always
RUSTUP_PERMIT_COPY_RENAME: 1
steps:
- name: Check out repository code
uses: actions/checkout@v6
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ vars.REQUIRED_RUSTC_VERSION }}
target: wasm32-unknown-unknown
override: true
components: rustfmt, clippy
- name: Install wasm-pack
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'
- name: Install wasm-bindgen-cli
run: cargo install wasm-bindgen-cli
- name: "Build"
run: make
working-directory: nym-credential-proxy/vpn-api-lib-wasm
Generated
-24
View File
@@ -8302,30 +8302,6 @@ dependencies = [
"ts-rs",
]
[[package]]
name = "nym-vpn-api-lib-wasm"
version = "1.20.4"
dependencies = [
"bs58",
"js-sys",
"nym-bin-common",
"nym-compact-ecash",
"nym-credential-proxy-requests",
"nym-credentials",
"nym-credentials-interface",
"nym-crypto",
"nym-ecash-time",
"nym-wasm-utils",
"serde",
"serde-wasm-bindgen 0.6.5",
"serde_json",
"thiserror 2.0.12",
"time",
"tsify",
"wasm-bindgen",
"zeroize",
]
[[package]]
name = "nym-wallet-types"
version = "1.0.0"
-1
View File
@@ -129,7 +129,6 @@ members = [
"nym-browser-extension/storage",
"nym-credential-proxy/nym-credential-proxy",
"nym-credential-proxy/nym-credential-proxy-requests",
"nym-credential-proxy/vpn-api-lib-wasm",
"nym-data-observatory",
"nym-ip-packet-client",
"nym-network-monitor",
@@ -1,37 +0,0 @@
[package]
name = "nym-vpn-api-lib-wasm"
version.workspace = true
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
edition.workspace = true
license.workspace = true
publish = false
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
bs58 = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
time = { workspace = true, features = ["wasm-bindgen"] }
thiserror.workspace = true
zeroize = { workspace = true }
# wasm-specific deps
wasm-bindgen = { workspace = true }
js-sys = { workspace = true }
tsify = { workspace = true, features = ["js"] }
serde-wasm-bindgen = { workspace = true }
# NYM:
nym-bin-common = { workspace = true }
nym-crypto = { workspace = true, features = ["asymmetric"] }
nym-compact-ecash = { workspace = true }
nym-credentials = { workspace = true }
nym-credentials-interface = { workspace = true }
nym-ecash-time = { workspace = true, features = ["expiration"] }
nym-credential-proxy-requests = { workspace = true, features = ["tsify"] }
nym-wasm-utils = { workspace = true }
@@ -1,4 +0,0 @@
build:
wasm-pack build --scope nymproject --target web --out-dir ../../dist/wasm/nym-vpn-api-lib-wasm
wasm-opt -Oz -o ../../dist/wasm/nym-vpn-api-lib-wasm/nym_vpn_api_lib_wasm_bg.wasm ../../dist/wasm/nym-vpn-api-lib-wasm/nym_vpn_api_lib_wasm_bg.wasm
@@ -1,2 +0,0 @@
import("./index.js")
.catch(e => console.error("Error importing `index.js`:", e));
@@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nym WebAssembly Demo</title>
<script src="bootstrap.js"></script>
</head>
<body>
<p>everything happens in the console</p>
</body>
</html>
@@ -1,49 +0,0 @@
import init, { NymIssuanceTicketbook } from "@nymproject/nym-vpn-api-lib-wasm";
async function main() {
await init();
let cryptoData = new NymIssuanceTicketbook({});
console.log("getting partial vks");
const partialVksRes = await fetch("http://localhost:8080/api/v1/ticketbook/partial-verification-keys", {
headers: new Headers({ "Authorization": "Bearer foomp" })
});
const partialVks = await partialVksRes.json();
console.debug(partialVks);
console.log("getting master vk");
const masterVkRes = await fetch("http://localhost:8080/api/v1/ticketbook/master-verification-key", {
headers: new Headers({ "Authorization": "Bearer foomp" })
});
const masterVk = await masterVkRes.json();
console.debug(masterVk);
let request = cryptoData.buildRequestPayload(false);
console.log(request);
console.log("getting blinded wallet shares");
const sharesRes = await fetch("http://localhost:8080/api/v1/ticketbook/obtain?include-coin-index-signatures=true&include-expiration-date-signatures=true", {
method: "POST",
headers: new Headers(
{
"Authorization": "Bearer foomp",
"Content-Type": "application/json"
}
),
body: request
});
const credentialShares = await sharesRes.json();
console.log(credentialShares);
console.log("unblinding shares");
const unblinded = cryptoData.unblindWalletShares(credentialShares, partialVks, masterVk);
const serialised = unblinded.serialise();
console.log("serialised:\n", serialised);
}
main();
@@ -1,40 +0,0 @@
{
"name": "create-wasm-app",
"version": "0.1.0",
"description": "create an app to consume rust-generated wasm packages",
"main": "index.js",
"bin": {
"create-wasm-app": ".bin/create-wasm-app.js"
},
"scripts": {
"build": "webpack --config webpack.config.js",
"build:wasm": "cd ../ && make wasm-build",
"start": "webpack-dev-server --port 8001"
},
"repository": {
"type": "git",
"url": "git+https://github.com/rustwasm/create-wasm-app.git"
},
"keywords": [
"webassembly",
"wasm",
"rust",
"webpack"
],
"author": "Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/nymtech/nym/issues"
},
"homepage": "https://nymtech.net/docs",
"devDependencies": {
"copy-webpack-plugin": "^11.0.0",
"hello-wasm-pack": "^0.1.0",
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^5.2.1"
},
"dependencies": {
"@nymproject/nym-vpn-api-lib-wasm": "file:../../../dist/wasm/nym-vpn-api-lib-wasm"
}
}
@@ -1,33 +0,0 @@
const CopyWebpackPlugin = require("copy-webpack-plugin");
const path = require("path");
module.exports = {
performance: {
hints: false,
maxEntrypointSize: 512000,
maxAssetSize: 512000
},
entry: {
bootstrap: "./bootstrap.js"
// worker: "./worker.js"
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js"
},
mode: "development",
// mode: 'production',
plugins: [
new CopyWebpackPlugin({
patterns: [
"index.html",
{
from: "../../../dist/wasm/nym-vpn-api-lib-wasm/*.(js|wasm)",
to: "[name][ext]"
}
]
})
],
experiments: { syncWebAssembly: true }
};
File diff suppressed because it is too large Load Diff
@@ -1,35 +0,0 @@
// Copyright 2024 Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use nym_wasm_utils::wasm_error;
use serde_wasm_bindgen::Error;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum VpnApiLibError {
#[error("{0}")]
Json(String),
#[error("[ecash] cryptographic failure: {source}")]
EcashFailure {
#[from]
source: nym_compact_ecash::CompactEcashError,
},
#[error("provided invalid ticket type")]
MalformedTicketType,
#[error("the provided shares and issuers are not from the same epoch! {shares} and {issuers}")]
InconsistentEpochId { shares: u64, issuers: u64 },
#[error("failed to recover ed25519 private key from its base58 representation")]
MalformedEd25519Key,
}
wasm_error!(VpnApiLibError);
impl From<serde_wasm_bindgen::Error> for VpnApiLibError {
fn from(value: Error) -> Self {
VpnApiLibError::Json(value.to_string())
}
}
@@ -1,277 +0,0 @@
// Copyright 2024 Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::error::VpnApiLibError;
use nym_compact_ecash::scheme::keygen::KeyPairUser;
use nym_compact_ecash::scheme::withdrawal::RequestInfo;
use nym_compact_ecash::{
Base58, BlindedSignature, VerificationKeyAuth, WithdrawalRequest, aggregate_wallets,
issue_verify, withdrawal_request,
};
use nym_credential_proxy_requests::api::v1::ticketbook::models::{
MasterVerificationKeyResponse, PartialVerificationKeysResponse, TicketbookRequest,
TicketbookWalletSharesResponse, WalletShare,
};
use nym_credentials::{
AggregatedCoinIndicesSignatures, AggregatedExpirationDateSignatures, EpochVerificationKey,
IssuedTicketBook,
};
use nym_credentials_interface::TicketType;
use nym_crypto::asymmetric::ed25519;
use nym_ecash_time::{EcashTime, ecash_default_expiration_date};
use nym_wasm_utils::console_error;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use time::Date;
use tsify::Tsify;
use wasm_bindgen::prelude::*;
use zeroize::Zeroizing;
pub mod error;
#[derive(Tsify, Debug, Default, Clone, Serialize, Deserialize)]
#[tsify(into_wasm_abi, from_wasm_abi)]
#[serde(rename_all = "camelCase")]
pub struct WalletShares(Vec<WalletShare>);
pub type WalletIssuers = PartialVerificationKeysResponse;
impl From<Vec<WalletShare>> for WalletShares {
fn from(shares: Vec<WalletShare>) -> Self {
WalletShares(shares)
}
}
#[derive(Tsify, Debug, Default, Clone, Serialize, Deserialize)]
#[tsify(into_wasm_abi, from_wasm_abi)]
#[serde(rename_all = "camelCase")]
pub struct NymIssuanceTicketbookOpts {
#[tsify(optional)]
pub ticketbook_type: Option<String>,
// bs58-encoded user secret key used for seeding the ecash crypto keypair generation
// I reiterate, this is a **SECRET** key, not a public key.
#[tsify(optional)]
pub user_secret_key: Option<String>,
}
#[wasm_bindgen]
#[derive(Debug)]
#[allow(dead_code)]
pub struct NymIssuanceTicketbook {
/// ecash keypair related to the credential
ecash_keypair: KeyPairUser,
withdrawal_request: WithdrawalRequest,
ticketbook_type: TicketType,
expiration_date: Date,
request_info: Zeroizing<RequestInfo>,
}
#[wasm_bindgen]
impl NymIssuanceTicketbook {
#[wasm_bindgen(constructor)]
pub fn new(opts: NymIssuanceTicketbookOpts) -> Result<NymIssuanceTicketbook, VpnApiLibError> {
let ecash_keypair = match opts.user_secret_key {
None => KeyPairUser::new(),
Some(maybe_sk) => {
let pk = ed25519::PrivateKey::from_base58_string(maybe_sk)
.map(Zeroizing::new)
.map_err(|_| VpnApiLibError::MalformedEd25519Key)?;
let bytes = Zeroizing::new(pk.to_bytes());
KeyPairUser::new_seeded(&bytes)
}
};
let ticketbook_type = match opts.ticketbook_type {
None => TicketType::V1MixnetEntry,
Some(typ) => typ
.parse()
.map_err(|_| VpnApiLibError::MalformedTicketType)?,
};
let expiration_date = ecash_default_expiration_date();
let (withdrawal_request, request_info) = withdrawal_request(
ecash_keypair.secret_key(),
expiration_date.ecash_unix_timestamp(),
ticketbook_type.encode(),
)?;
Ok(NymIssuanceTicketbook {
ecash_keypair,
withdrawal_request,
ticketbook_type,
expiration_date,
request_info: Zeroizing::new(request_info),
})
}
#[wasm_bindgen(js_name = "buildRequestPayload")]
pub fn build_request_payload(&self, is_freepass_request: bool) -> String {
serde_json::to_string(&TicketbookRequest {
withdrawal_request: self.withdrawal_request.clone().into(),
ecash_pubkey: self.ecash_keypair.public_key(),
expiration_date: self.expiration_date,
ticketbook_type: self.ticketbook_type,
is_freepass_request,
})
.unwrap()
}
#[wasm_bindgen(js_name = "getWithdrawalRequest")]
pub fn get_encoded_withdrawal_request(&self) -> String {
self.withdrawal_request.to_bs58()
}
#[wasm_bindgen(js_name = "getEncodedPublicKey")]
pub fn get_encoded_public_key(&self) -> String {
self.ecash_keypair.public_key().to_bs58()
}
//
// #[wasm_bindgen(js_name = "unblindShare")]
// pub fn unblind_share(&self, share: UnblindableShare) -> Result<CredentialWrapper, ZkNymError> {
// let blinded_sig = BlindedSignature::try_from_bs58(share.blinded_share_bs58)?;
// let vk = VerificationKey::try_from_bs58(share.issuer_key_bs58)?;
//
// Ok(blinded_sig
// .unblind(&vk, &self.pedersen_commitments_openings)
// .into())
// }
//
#[wasm_bindgen(js_name = "unblindWalletShares")]
pub fn unblind_wallet_shares(
self,
shares: JsValue,
issuers: WalletIssuers,
master_key: MasterVerificationKeyResponse,
) -> Result<NymIssuedTicketbook, VpnApiLibError> {
// we couldn't derive all the required abi traits due to crypto types deep in the stack
let shares: TicketbookWalletSharesResponse = serde_wasm_bindgen::from_value(shares)?;
if shares.epoch_id != issuers.epoch_id {
console_error!(
"the provided shares and issuers are not from the same epoch! {} and {}",
shares.epoch_id,
issuers.epoch_id
);
return Err(VpnApiLibError::InconsistentEpochId {
shares: shares.epoch_id,
issuers: issuers.epoch_id,
});
}
let master_vk = VerificationKeyAuth::try_from_bs58(master_key.bs58_encoded_key)?;
let mut decoded_keys = HashMap::new();
for key in issuers.keys {
let vk = VerificationKeyAuth::try_from_bs58(key.bs58_encoded_key)?;
decoded_keys.insert(key.node_index, vk);
}
let mut partial_wallets = Vec::new();
for share in shares.shares {
let blinded_sig = BlindedSignature::try_from_bs58(share.bs58_encoded_share)?;
let Some(vk) = decoded_keys.get(&share.node_index) else {
console_error!(
"received a share from issuer {} but did not receive a corresponding verification key!",
share.node_index
);
continue;
};
match issue_verify(
vk,
self.ecash_keypair.secret_key(),
&blinded_sig,
&self.request_info,
share.node_index,
) {
Ok(partial_wallet) => partial_wallets.push(partial_wallet),
Err(err) => {
console_error!(
"failed to unblind partial wallet corresponding to index {}: {err}",
share.node_index
)
}
}
}
let aggregated_wallet = aggregate_wallets(
&master_vk,
self.ecash_keypair.secret_key(),
&partial_wallets,
&self.request_info,
)?;
Ok(NymIssuedTicketbook {
inner_ticketbook: IssuedTicketBook::new(
aggregated_wallet.into_wallet_signatures(),
shares.epoch_id,
self.ecash_keypair.into(),
self.ticketbook_type,
self.expiration_date,
),
master_vk: EpochVerificationKey {
epoch_id: shares.epoch_id,
key: master_vk,
},
expiration_date_signatures: shares
.aggregated_expiration_date_signatures
.map(|s| s.signatures),
coin_index_signatures: shares
.aggregated_coin_index_signatures
.map(|s| s.signatures),
})
}
}
#[wasm_bindgen]
pub struct NymIssuedTicketbook {
inner_ticketbook: IssuedTicketBook,
master_vk: EpochVerificationKey,
expiration_date_signatures: Option<AggregatedExpirationDateSignatures>,
coin_index_signatures: Option<AggregatedCoinIndicesSignatures>,
}
#[wasm_bindgen]
impl NymIssuedTicketbook {
pub fn serialise(self) -> FullSerialisedNymIssuedTicketbook {
let serialised = self
.inner_ticketbook
.begin_export()
.with_master_verification_key(&self.master_vk)
.with_maybe_expiration_date_signatures(&self.expiration_date_signatures)
.with_maybe_coin_index_signatures(&self.coin_index_signatures)
.finalize_export();
FullSerialisedNymIssuedTicketbook {
serialisation_revision: serialised.revision,
bs58_encoded_data: bs58::encode(serialised.data).into_string(),
}
}
}
#[derive(Tsify, Serialize, Deserialize, Debug, PartialEq, Eq)]
#[tsify(into_wasm_abi, from_wasm_abi)]
#[serde(rename_all = "camelCase")]
pub struct FullSerialisedNymIssuedTicketbook {
pub serialisation_revision: u8,
pub bs58_encoded_data: String,
}
#[wasm_bindgen(start)]
pub fn main() {
nym_wasm_utils::console_log!("[rust main]: rust module loaded");
nym_wasm_utils::console_log!(
"vpn-api-lib version used:\n{}",
nym_bin_common::bin_info!().pretty_print()
);
nym_wasm_utils::console_log!("[rust main]: setting panic hook");
nym_wasm_utils::set_panic_hook();
}