From e939c7bbe8ed7cbfe83496efb43b4d1758ab3318 Mon Sep 17 00:00:00 2001 From: Nutomic Date: Fri, 12 May 2023 13:03:39 +0200 Subject: [PATCH] Fees for substrate (#375) Co-authored-by: shekohex Co-authored-by: Salman Pathan Co-authored-by: drewstone --- Cargo.lock | 1 + README.md | 12 +- crates/relayer-handler-utils/src/lib.rs | 24 +- crates/relayer-handlers/src/lib.rs | 34 ++- crates/tx-relay/Cargo.toml | 1 + crates/tx-relay/src/evm/fees.rs | 71 +++-- crates/tx-relay/src/evm/vanchor.rs | 29 +- crates/tx-relay/src/lib.rs | 5 + crates/tx-relay/src/substrate/fees.rs | 71 +++++ crates/tx-relay/src/substrate/mixer.rs | 4 +- crates/tx-relay/src/substrate/mod.rs | 19 ++ crates/tx-relay/src/substrate/vanchor.rs | 128 ++++++-- services/webb-relayer/src/service/evm.rs | 6 +- .../webb-relayer/src/service/substrate.rs | 5 + tests/lib/webbRelayer.ts | 39 ++- tests/package.json | 24 +- tests/test/evm/RelayerTxTransfer.test.ts | 6 +- .../evm/vanchorPrivateTransaction.test.ts | 6 +- .../vanchorPrivateTransaction.test.ts | 129 +++++--- tests/yarn.lock | 289 +++++++++++------- 20 files changed, 645 insertions(+), 258 deletions(-) create mode 100644 crates/tx-relay/src/substrate/fees.rs diff --git a/Cargo.lock b/Cargo.lock index 99ea7010a..1234697f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9285,6 +9285,7 @@ dependencies = [ "native-tls", "once_cell", "serde", + "sp-core", "tokio 1.27.0", "tracing", "webb 0.5.22", diff --git a/README.md b/README.md index f9906d21c..560138c78 100644 --- a/README.md +++ b/README.md @@ -488,7 +488,7 @@ cargo test ### To run E2E tests -First you will need [`protocol-substrate`](https://github.com/webb-tools/protocol-substrate) node, compiled locally (in release mode) and both the `protocol-substrate` and `relayer` project must be next to each other. The relayer must be compiled using `--features integration-tests,cli`. +First you will need [`protocol-substrate`](https://github.com/webb-tools/protocol-substrate) and [`tangle`](https://github.com/webb-tools/tangle) nodes, compiled locally (in release mode) and both the `protocol-substrate` and `relayer` project must be next to each other. The relayer must be compiled using `--features integration-tests,cli`. Here is the basic setup you will need: @@ -496,10 +496,12 @@ Here is the basic setup you will need: 2. Clone Protocol Substrate node `https://github.com/webb-tools/protocol-substrate.git` 3. Then fetch the submodules for the node `cd protocol-substrate && git submodule update --init` 4. While you are there, build the standalone node `cargo build --release -p webb-standalone-node` -5. And then go back to the relayer `cd ../relayer` -6. Run `cd tests && dvc pull` -7. Run `yarn install` (in `tests` dir) -8. `yarn test` +5. Clone Tangle repo `https://github.com/webb-tools/tangle.git` +6. Build tangle `cd tangle && cargo build --release --features integration-tests -p tangle-standalone` +7. And then go back to the relayer `cd ../relayer` +8. Run `cd tests && dvc pull` +9. Run `yarn install` (in `tests` dir) +10. `yarn test` ### Tips for E2E tests diff --git a/crates/relayer-handler-utils/src/lib.rs b/crates/relayer-handler-utils/src/lib.rs index 09b4f2b7a..01a5536c9 100644 --- a/crates/relayer-handler-utils/src/lib.rs +++ b/crates/relayer-handler-utils/src/lib.rs @@ -18,7 +18,7 @@ use serde::{Deserialize, Deserializer, Serialize}; use tokio::sync::mpsc; use webb::evm::ethers::abi::Address; -use webb::evm::ethers::prelude::{ContractError, I256}; +use webb::evm::ethers::prelude::{ContractError, I256, U128}; use webb::evm::ethers::providers::Middleware; use webb::evm::ethers::types::Bytes; use webb::evm::ethers::types::{H256, U256}; @@ -52,6 +52,24 @@ impl<'de> Deserialize<'de> for WebbI256 { Ok(WebbI256(i128_val)) } } +/// A wrapper type around [`i128`] that implements a correct way for [`Serialize`] and [`Deserialize`]. +/// +/// This supports the signed integer hex values that are not originally supported by the [`i128`] type. +#[derive(Debug, Clone, Serialize)] +#[serde(transparent)] +pub struct WebbI128(pub i128); + +impl<'de> Deserialize<'de> for WebbI128 { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let i128_str = String::deserialize(deserializer)?; + let value = i128::from_str_radix(&i128_str, 16) + .map_err(serde::de::Error::custom)?; + Ok(WebbI128(value)) + } +} /// Type of Command to use #[derive(Debug, Clone, Deserialize)] @@ -170,8 +188,8 @@ type P = Vec; // Substrate raw proof bytes type R = Vec<[u8; 32]>; // Substrate roots format type E = [u8; 32]; // Substrate element type type I = AccountId32; // Substrate account identifier -type B = u128; // Substrate balance type -type A = i128; // Substrate signed amount type +type B = U128; // Substrate balance type +type A = WebbI128; // Substrate signed amount type type T = u32; // Substrate assetId /// The command type for Substrate mixer txes diff --git a/crates/relayer-handlers/src/lib.rs b/crates/relayer-handlers/src/lib.rs index eb69680fa..abf7d549d 100644 --- a/crates/relayer-handlers/src/lib.rs +++ b/crates/relayer-handlers/src/lib.rs @@ -24,6 +24,7 @@ use std::sync::Arc; use futures::prelude::*; use axum::extract::ws::{Message, WebSocket}; +use axum::http::StatusCode; use axum::response::Response; use axum::Json; use axum_client_ip::InsecureClientIp; @@ -36,9 +37,12 @@ use webb_relayer_handler_utils::{ Command, CommandResponse, CommandStream, EvmCommandType, IpInformationResponse, SubstrateCommandType, }; -use webb_relayer_tx_relay::evm::fees::{get_fee_info, FeeInfo}; +use webb_relayer_tx_relay::evm::fees::{get_evm_fee_info, EvmFeeInfo}; use webb_relayer_tx_relay::evm::vanchor::handle_vanchor_relay_tx; +use webb_relayer_tx_relay::substrate::fees::{ + get_substrate_fee_info, SubstrateFeeInfo, +}; use webb_relayer_tx_relay::substrate::mixer::handle_substrate_mixer_relay_tx; use webb_relayer_tx_relay::substrate::vanchor::handle_substrate_vanchor_relay_tx; use webb_relayer_utils::HandlerError; @@ -201,13 +205,33 @@ pub async fn handle_cmd( /// * `vanchor` - Address of the smart contract /// * `gas_amount` - How much gas the transaction needs. Don't use U256 here because it /// gets parsed incorrectly. -pub async fn handle_fee_info( +pub async fn handle_evm_fee_info( State(ctx): State>, Path((chain_id, vanchor, gas_amount)): Path<(u64, Address, u64)>, -) -> Result, HandlerError> { +) -> Result, HandlerError> { let chain_id = TypedChainId::from(chain_id); let gas_amount = U256::from(gas_amount); - Ok(get_fee_info(chain_id, vanchor, gas_amount, ctx.as_ref()) + Ok( + get_evm_fee_info(chain_id, vanchor, gas_amount, ctx.as_ref()) + .await + .map(Json)?, + ) +} + +/// Handler for fee estimation +/// +/// # Arguments +/// * `chain_id` - ID of the blockchain +/// * `estimated_tx_fees` - Estimated transaction fees +/// * `ctx` - RelayContext reference that holds the configuration +pub async fn handle_substrate_fee_info( + State(ctx): State>, + Path((chain_id, estimated_tx_fees)): Path<(u64, u128)>, +) -> Result, HandlerError> { + get_substrate_fee_info(chain_id, estimated_tx_fees.into(), ctx.as_ref()) .await - .map(Json)?) + .map(Json) + .map_err(|e| { + HandlerError(StatusCode::INTERNAL_SERVER_ERROR, e.to_string()) + }) } diff --git a/crates/tx-relay/Cargo.toml b/crates/tx-relay/Cargo.toml index 19a2d5c53..3fbb2ade5 100644 --- a/crates/tx-relay/Cargo.toml +++ b/crates/tx-relay/Cargo.toml @@ -27,6 +27,7 @@ native-tls = { workspace = true, optional = true } webb-proposals = { workspace = true } ethereum-types = { workspace = true } serde = { workspace = true } +sp-core = { workspace = true } once_cell = "1.17.0" chrono = { version = "0.4.23", features = ["serde"] } diff --git a/crates/tx-relay/src/evm/fees.rs b/crates/tx-relay/src/evm/fees.rs index 409182a9e..738f7a8f5 100644 --- a/crates/tx-relay/src/evm/fees.rs +++ b/crates/tx-relay/src/evm/fees.rs @@ -1,8 +1,10 @@ +use crate::{MAX_REFUND_USD, TRANSACTION_PROFIT_USD}; use chrono::DateTime; use chrono::Duration; use chrono::Utc; use once_cell::sync::Lazy; use serde::Serialize; +use std::cmp::min; use std::collections::HashMap; use std::ops::Add; use std::sync::{Arc, Mutex}; @@ -11,6 +13,8 @@ use webb::evm::contract::protocol_solidity::{ }; use webb::evm::ethers::middleware::gas_oracle::GasOracle; use webb::evm::ethers::prelude::U256; +use webb::evm::ethers::providers::Middleware; +use webb::evm::ethers::signers::Signer; use webb::evm::ethers::types::Address; use webb::evm::ethers::utils::{format_units, parse_units}; use webb_chains_info::chain_info_by_chain_id; @@ -19,22 +23,19 @@ use webb_proposals::TypedChainId; use webb_relayer_context::RelayerContext; use webb_relayer_utils::Result; -/// Maximum refund amount per relay transaction in USD. -const MAX_REFUND_USD: f64 = 5.; /// Amount of time for which a `FeeInfo` is valid after creation static FEE_CACHE_TIME: Lazy = Lazy::new(|| Duration::minutes(1)); -/// Amount of profit that the relay should make with each transaction (in USD). -const TRANSACTION_PROFIT_USD: f64 = 5.; /// Cache for previously generated fee info. Key consists of the VAnchor address and chain id. /// Entries are valid as long as `timestamp` is no older than `FEE_CACHE_TIME`. -static FEE_INFO_CACHED: Lazy>> = - Lazy::new(|| Mutex::new(HashMap::new())); +static FEE_INFO_CACHED: Lazy< + Mutex>, +> = Lazy::new(|| Mutex::new(HashMap::new())); /// Return value of fee_info API call. Contains information about relay transaction fee and refunds. #[derive(Debug, Serialize, Clone)] #[serde(rename_all = "camelCase")] -pub struct FeeInfo { +pub struct EvmFeeInfo { /// Estimated fee for an average relay transaction, in `wrappedToken`. This is only for /// display to the user pub estimated_fee: U256, @@ -49,6 +50,9 @@ pub struct FeeInfo { /// Price of the native token in USD, internally cached to recalculate estimated fee #[serde(skip)] native_token_price: f64, + /// Number of decimals of the native token, internally cached to recalculate max refund + #[serde(skip)] + native_token_decimals: u8, /// Price of the wrapped token in USD, internally cached to recalculate estimated fee #[serde(skip)] wrapped_token_price: f64, @@ -61,12 +65,12 @@ pub struct FeeInfo { /// /// If fee info was recently requested, the cached value is used. Otherwise it is regenerated /// based on the current exchange rate and estimated gas price. -pub async fn get_fee_info( +pub async fn get_evm_fee_info( chain_id: TypedChainId, vanchor: Address, gas_amount: U256, ctx: &RelayerContext, -) -> Result { +) -> Result { // Retrieve cached fee info item let fee_info_cached = { let mut lock = @@ -89,6 +93,14 @@ pub async fn get_fee_info( fee_info.wrapped_token_price, fee_info.wrapped_token_decimals, )?; + // Recalculate max refund in case relayer balance changed. + fee_info.max_refund = max_refund( + chain_id, + fee_info.native_token_price, + fee_info.native_token_decimals, + ctx, + ) + .await?; Ok(fee_info) } else { let fee_info = @@ -109,7 +121,7 @@ async fn generate_fee_info( vanchor: Address, gas_amount: U256, ctx: &RelayerContext, -) -> Result { +) -> Result { // Get token names let (native_token, native_token_decimals) = get_native_token_name_and_decimals(chain_id)?; @@ -162,25 +174,44 @@ async fn generate_fee_info( )? .into(); - // Calculate the maximum refund amount per relay transaction in `nativeToken`. - let max_refund = parse_units( - MAX_REFUND_USD / native_token_price, - u32::from(native_token_decimals), - )? - .into(); - - Ok(FeeInfo { + Ok(EvmFeeInfo { estimated_fee, gas_price, refund_exchange_rate, - max_refund, + max_refund: max_refund( + chain_id, + native_token_price, + native_token_decimals, + ctx, + ) + .await?, timestamp: Utc::now(), native_token_price, + native_token_decimals, wrapped_token_price, wrapped_token_decimals, }) } +async fn max_refund( + chain_id: TypedChainId, + native_token_price: f64, + native_token_decimals: u8, + ctx: &RelayerContext, +) -> Result { + let wallet = ctx.evm_wallet(chain_id.underlying_chain_id()).await?; + let provider = ctx.evm_provider(chain_id.underlying_chain_id()).await?; + let relayer_balance = provider.get_balance(wallet.address(), None).await?; + // Calculate the maximum refund amount per relay transaction in `nativeToken`. + // Ensuring that refund <= relayer balance + let max_refund = parse_units( + MAX_REFUND_USD / native_token_price, + u32::from(native_token_decimals), + )? + .into(); + Ok(min(relayer_balance, max_refund)) +} + /// Pull USD prices of base token from coingecko.com, and use this to calculate the transaction /// fee in `wrappedToken` wei. This fee includes a profit for the relay of `TRANSACTION_PROFIT_USD`. /// @@ -265,7 +296,7 @@ fn get_native_token_name_and_decimals( }, ), Substrate(id) => match id { - 1080 => Ok(("tTNT", 18)), + 1081 => Ok(("tTNT", 18)), _ => { // During testing, we will use the tTNT token for all substrate chains. if cfg!(debug_assertions) { diff --git a/crates/tx-relay/src/evm/vanchor.rs b/crates/tx-relay/src/evm/vanchor.rs index a36aeb176..4c83ed739 100644 --- a/crates/tx-relay/src/evm/vanchor.rs +++ b/crates/tx-relay/src/evm/vanchor.rs @@ -1,7 +1,8 @@ use super::*; -use crate::evm::fees::{get_fee_info, FeeInfo}; +use crate::evm::fees::{get_evm_fee_info, EvmFeeInfo}; use crate::evm::handle_evm_tx; use ethereum_types::U256; +use futures::TryFutureExt; use std::{collections::HashMap, sync::Arc}; use webb::evm::ethers::utils::{format_units, parse_ether}; use webb::evm::{ @@ -81,19 +82,6 @@ pub async fn handle_vanchor_relay_tx<'a>( })?; let _ = stream.send(Network(NetworkStatus::Connected)).await; - // ensure that relayer has enough balance for refund - let relayer_balance = provider - .get_balance(wallet.address(), None) - .await - .map_err(|e| { - Error(format!("Failed to retrieve relayer balance: {e}")) - })?; - if cmd.ext_data.refund > relayer_balance { - return Err(Error( - "Requested refund is higher than relayer balance".to_string(), - )); - } - let client = Arc::new(SignerMiddleware::new(provider, wallet)); let contract = VAnchorContract::new(cmd.id, client.clone()); @@ -142,6 +130,7 @@ pub async fn handle_vanchor_relay_tx<'a>( public_inputs, encryptions, ); + if !cmd.ext_data.refund.is_zero() { call = call.value(cmd.ext_data.refund); } @@ -153,7 +142,7 @@ pub async fn handle_vanchor_relay_tx<'a>( }) })?; let typed_chain_id = TypedChainId::Evm(chain.chain_id); - let fee_info = get_fee_info( + let fee_info = get_evm_fee_info( typed_chain_id, contract_config.common.address, gas_amount, @@ -186,7 +175,8 @@ pub async fn handle_vanchor_relay_tx<'a>( if cmd.ext_data.fee < adjusted_fee + wrapped_amount { let msg = format!( "User sent a fee that is too low {} but expected {}", - cmd.ext_data.fee, fee_info.estimated_fee + cmd.ext_data.fee, + adjusted_fee + wrapped_amount ); return Err(Error(msg)); } @@ -214,6 +204,11 @@ pub async fn handle_vanchor_relay_tx<'a>( .total_fee_earned .inc_by(cmd.ext_data.fee.as_u128() as f64); + let relayer_balance = client + .get_balance(client.signer().address(), None) + .unwrap_or_else(|_| U256::zero()) + .await; + metrics .account_balance_entry(typed_chain_id) .set(wei_to_gwei(relayer_balance)); @@ -222,7 +217,7 @@ pub async fn handle_vanchor_relay_tx<'a>( fn calculate_wrapped_refund_amount( refund: U256, - fee_info: &FeeInfo, + fee_info: &EvmFeeInfo, ) -> webb_relayer_utils::Result { let refund_exchange_rate: f32 = format_units(fee_info.refund_exchange_rate, "ether")?.parse()?; diff --git a/crates/tx-relay/src/lib.rs b/crates/tx-relay/src/lib.rs index ca4bd99a0..62c11da01 100644 --- a/crates/tx-relay/src/lib.rs +++ b/crates/tx-relay/src/lib.rs @@ -4,3 +4,8 @@ pub mod evm; /// Substrate Transactional Relayer. #[cfg(feature = "substrate")] pub mod substrate; + +/// Maximum refund amount per relay transaction in USD. +const MAX_REFUND_USD: f64 = 5.; +/// Amount of profit that the relay should make with each transaction (in USD). +const TRANSACTION_PROFIT_USD: f64 = 5.; diff --git a/crates/tx-relay/src/substrate/fees.rs b/crates/tx-relay/src/substrate/fees.rs new file mode 100644 index 000000000..744692e8a --- /dev/null +++ b/crates/tx-relay/src/substrate/fees.rs @@ -0,0 +1,71 @@ +use crate::substrate::balance; +use crate::{MAX_REFUND_USD, TRANSACTION_PROFIT_USD}; +use chrono::{DateTime, Utc}; +use serde::Serialize; +use sp_core::U256; +use std::cmp::min; +use webb::evm::ethers::utils::__serde_json::Value; +use webb::substrate::subxt::tx::PairSigner; +use webb::substrate::subxt::PolkadotConfig; +use webb_relayer_context::RelayerContext; +use webb_relayer_utils::Error; + +const TOKEN_PRICE_USD: f64 = 0.1; + +#[derive(Debug, Serialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct SubstrateFeeInfo { + /// Estimated fee for an average relay transaction, in `wrappedToken`. Includes network fees + /// and relay fee. + pub estimated_fee: U256, + /// Exchange rate for refund from `wrappedToken` to `nativeToken` + pub refund_exchange_rate: U256, + /// Maximum amount of `nativeToken` which can be exchanged to `wrappedToken` by relay + pub max_refund: U256, + /// Time when this FeeInfo was generated + timestamp: DateTime, +} + +pub async fn get_substrate_fee_info( + chain_id: u64, + estimated_tx_fees: U256, + ctx: &RelayerContext, +) -> webb_relayer_utils::Result { + let client = ctx + .substrate_provider::(&chain_id.to_string()) + .await?; + let decimals: i32 = client + .rpc() + .system_properties() + .await? + .get("tokenDecimals") + .and_then(Value::as_i64) + .ok_or(Error::ReadSubstrateStorageError)? + as i32; + let estimated_fee = estimated_tx_fees + + native_token_to_unit( + TRANSACTION_PROFIT_USD / TOKEN_PRICE_USD, + decimals, + ); + let refund_exchange_rate = native_token_to_unit(1., decimals); + let max_refund = + native_token_to_unit(MAX_REFUND_USD / TOKEN_PRICE_USD, decimals); + let pair = ctx.substrate_wallet(&chain_id.to_string()).await?; + let signer = PairSigner::new(pair.clone()); + + let max_refund = + min(max_refund, U256::from(balance(client, signer).await?)); + Ok(SubstrateFeeInfo { + estimated_fee, + refund_exchange_rate, + max_refund, + timestamp: Utc::now(), + }) +} + +/// Convert from full wrapped token amount to smallest unit amount. +/// +/// It looks like subxt has no built-in functionality for this. +fn native_token_to_unit(matic: f64, token_decimals: i32) -> U256 { + U256::from((matic * 10_f64.powi(token_decimals)) as u128) +} diff --git a/crates/tx-relay/src/substrate/mixer.rs b/crates/tx-relay/src/substrate/mixer.rs index de5ea2a75..ee71a0d07 100644 --- a/crates/tx-relay/src/substrate/mixer.rs +++ b/crates/tx-relay/src/substrate/mixer.rs @@ -49,8 +49,8 @@ pub async fn handle_substrate_mixer_relay_tx<'a>( nullifier_hash_element, cmd.recipient, cmd.relayer, - cmd.fee, - cmd.refund, + cmd.fee.as_u128(), + cmd.refund.as_u128(), ); let withdraw_tx_hash = client diff --git a/crates/tx-relay/src/substrate/mod.rs b/crates/tx-relay/src/substrate/mod.rs index 6b847af1e..13d117887 100644 --- a/crates/tx-relay/src/substrate/mod.rs +++ b/crates/tx-relay/src/substrate/mod.rs @@ -1,13 +1,17 @@ use ethereum_types::H256; use futures::TryStreamExt; +use sp_core::sr25519::Pair; +use webb::substrate::subxt::tx::PairSigner; use webb::substrate::subxt::{ tx::TxProgress, tx::TxStatus as TransactionStatus, OnlineClient, PolkadotConfig, }; +use webb::substrate::tangle_runtime::api; use webb_relayer_handler_utils::{ CommandResponse, CommandStream, WithdrawStatus, }; +pub mod fees; /// Substrate Mixer Transactional Relayer. pub mod mixer; /// Substrate Variable Anchor Transactional Relayer. @@ -115,3 +119,18 @@ pub async fn handle_substrate_tx( fn wei_to_gwei(wei: u128) -> f64 { (wei / (10 ^ 9)) as f64 } + +async fn balance( + client: OnlineClient, + signer: PairSigner, +) -> webb_relayer_utils::Result { + let account = api::storage().system().account(signer.account_id()); + let balance = client + .storage() + .at(None) + .await? + .fetch(&account) + .await? + .ok_or(webb_relayer_utils::Error::ReadSubstrateStorageError)?; + Ok(balance.data.free) +} diff --git a/crates/tx-relay/src/substrate/vanchor.rs b/crates/tx-relay/src/substrate/vanchor.rs index 5c372e72d..b6c7c2d3f 100644 --- a/crates/tx-relay/src/substrate/vanchor.rs +++ b/crates/tx-relay/src/substrate/vanchor.rs @@ -1,15 +1,15 @@ use super::*; +use crate::substrate::fees::get_substrate_fee_info; use crate::substrate::handle_substrate_tx; -use webb::evm::ethers::utils::hex; use webb::substrate::tangle_runtime::api as RuntimeApi; use webb::substrate::subxt::utils::AccountId32; use webb::substrate::tangle_runtime::api::runtime_types::tangle_standalone_runtime::protocol_substrate_config::Element; use webb::substrate::{ - tangle_runtime::api::runtime_types::{ - webb_primitives::types::vanchor, - }, - subxt::{tx::PairSigner, PolkadotConfig}, -}; + subxt::{PolkadotConfig, tx::PairSigner}, + tangle_runtime::api::runtime_types::webb_primitives::types::vanchor, +};use ethereum_types::U256; +use sp_core::{Decode, Encode}; +use webb::substrate::scale::Compact; use webb_proposals::{ ResourceId, SubstrateTargetSystem, TargetSystem, TypedChainId, }; @@ -52,11 +52,11 @@ pub async fn handle_substrate_vanchor_relay_tx<'a>( vanchor::ExtData { recipient: cmd.ext_data.recipient, relayer: cmd.ext_data.relayer, - fee: cmd.ext_data.fee, - ext_amount: cmd.ext_data.ext_amount, + fee: cmd.ext_data.fee.as_u128(), + ext_amount: cmd.ext_data.ext_amount.0, encrypted_output1: cmd.ext_data.encrypted_output1.clone(), encrypted_output2: cmd.ext_data.encrypted_output2.clone(), - refund: cmd.ext_data.refund, + refund: cmd.ext_data.refund.as_u128(), token: cmd.ext_data.token, }; @@ -75,17 +75,71 @@ pub async fn handle_substrate_vanchor_relay_tx<'a>( Error(format!("Misconfigured Network {:?}: {e}", cmd.chain_id)) })?; - let signer = PairSigner::new(pair); + let signer = PairSigner::new(pair.clone()); let transact_tx = RuntimeApi::tx().v_anchor_bn254().transact( cmd.id, proof_elements, ext_data_elements, ); - let transact_tx_hash = client + + // TODO: Taken from subxt PR. Replace with new method state_call_decoded() after upgrading subxt. + // https://github.com/paritytech/subxt/pull/910 + let signed = client .tx() - .sign_and_submit_then_watch_default(&transact_tx, &signer) - .await; + .create_signed(&transact_tx, &signer, Default::default()) + .await + .map_err(|e| Error(format!("Failed to sign transaction: {e}")))?; + let mut params = signed.encoded().to_vec(); + (signed.encoded().len() as u32).encode_to(&mut params); + let bytes = client + .rpc() + .state_call("TransactionPaymentApi_query_info", Some(¶ms), None) + .await + .map_err(|e| { + Error(format!( + "RPC call TransactionPaymentApi_query_info failed: {e}" + )) + })?; + let cursor = &mut &bytes[..]; + let payment_info: (Compact, Compact, u8, u128) = + Decode::decode(cursor).map_err(|e| { + Error(format!("Failed to decode payment info: {e}")) + })?; + let fee_info = get_substrate_fee_info( + requested_chain, + U256::from(payment_info.3), + &ctx, + ) + .await + .map_err(|e| Error(format!("Get substrate fee info failed: {e}")))?; + + // validate refund amount + if U256::from(cmd.ext_data.refund) > fee_info.max_refund { + // TODO: use error enum for these messages so they dont have to be duplicated between + // evm/substrate + let msg = format!( + "User requested a refund which is higher than the maximum of {}", + fee_info.max_refund + ); + return Err(Error(msg)); + } + + // Check that transaction fee is enough to cover network fee and relayer fee + // TODO: refund needs to be converted from wrapped token to native token once there + // is an exchange rate + if U256::from(cmd.ext_data.fee) + < fee_info.estimated_fee + cmd.ext_data.refund + { + let msg = format!( + "User sent a fee that is too low ({}) but expected {}", + cmd.ext_data.fee, + fee_info.estimated_fee + cmd.ext_data.refund + ); + return Err(Error(msg)); + } + + let transact_tx_hash = signed.submit_and_watch().await; let event_stream = transact_tx_hash .map_err(|e| Error(format!("Error while sending Tx: {e}")))?; @@ -114,27 +168,45 @@ pub async fn handle_substrate_vanchor_relay_tx<'a>( metrics .resource_metric_entry(resource_id) .total_fee_earned - .inc_by(cmd.ext_data.fee as f64); + .inc_by(cmd.ext_data.fee.as_u128() as f64); // update metric for total fee earned by relayer metrics .total_fee_earned - .inc_by(wei_to_gwei(cmd.ext_data.fee)); + .inc_by(wei_to_gwei(cmd.ext_data.fee.as_u128())); - let account = RuntimeApi::storage().system().account(signer.account_id()); - let balance = client - .storage() - .at(None) - .await - .map_err(|e| Error(e.to_string()))? - .fetch(&account) + let balance = balance(client, signer) .await - .map_err(|e| Error(e.to_string()))? - .ok_or(Error(format!( - "Substrate storage returned None for {}", - hex::encode(account.to_bytes()) - )))?; + .map_err(|e| Error(format!("Failed to read substrate balance: {e}")))?; metrics .account_balance_entry(typed_chain_id) - .set(wei_to_gwei(balance.data.free)); + .set(wei_to_gwei(balance)); Ok(()) } + +#[cfg(tests)] +mod test { + use webb::substrate::subxt::runtime_api::RuntimeApiClient; + use webb::substrate::subxt::tx::PairSigner; + use webb::substrate::subxt::utils::AccountId32; + use webb::substrate::subxt::SubstrateConfig; + + #[tokio::test] + async fn test_account_balance() { + // TODO: use alice account id from + // https://docs.rs/sp-keyring/latest/sp_keyring/ed25519/enum.Keyring.html + let account_id = AccountId32::from([0u8; 32]); + let account = RuntimeApi::storage().balances().account(account_id); + let client = subxt::OnlineClient::::default().await?; + let balance = client + .storage() + .at(None) + .await + .unwrap() + .fetch(&account) + .await + .unwrap(); + dbg!(balance); + assert_eq!(balance, None); + fail!(); + } +} diff --git a/services/webb-relayer/src/service/evm.rs b/services/webb-relayer/src/service/evm.rs index 4a330dc33..b0a4aa926 100644 --- a/services/webb-relayer/src/service/evm.rs +++ b/services/webb-relayer/src/service/evm.rs @@ -24,7 +24,7 @@ use webb_relayer_config::evm::{ Contract, SignatureBridgeContractConfig, VAnchorContractConfig, }; use webb_relayer_context::RelayerContext; -use webb_relayer_handlers::handle_fee_info; +use webb_relayer_handlers::handle_evm_fee_info; use webb_relayer_handlers::routes::{encrypted_outputs, leaves, metric}; use webb_relayer_tx_queue::evm::TxQueue; @@ -52,8 +52,8 @@ pub fn build_web_services() -> Router> { // for backward compatibility .route("/metrics", get(metric::handle_metric_info)) .route( - "/fee_info/:chain_id/:vanchor/:gas_amount", - get(handle_fee_info), + "/fee_info/evm/:chain_id/:vanchor/:gas_amount", + get(handle_evm_fee_info), ) } diff --git a/services/webb-relayer/src/service/substrate.rs b/services/webb-relayer/src/service/substrate.rs index ac7a2e1bc..b47c56507 100644 --- a/services/webb-relayer/src/service/substrate.rs +++ b/services/webb-relayer/src/service/substrate.rs @@ -24,6 +24,7 @@ use webb_relayer_config::substrate::{ SignatureBridgePalletConfig, SubstrateConfig, VAnchorBn254PalletConfig, }; use webb_relayer_context::RelayerContext; +use webb_relayer_handlers::handle_substrate_fee_info; use webb_relayer_handlers::routes::{leaves, metric}; use webb_relayer_tx_queue::substrate::SubstrateTxQueue; @@ -43,6 +44,10 @@ pub fn build_web_services() -> Router> { "/metrics/substrate/:chain_id/:tree_id/:pallet_id", get(metric::handle_substrate_metric_info), ) + .route( + "/fee_info/substrate/:chain_id/:estimated_tx_fees", + get(handle_substrate_fee_info), + ) } /// Fires up all background services for all Substrate chains configured in the config file. diff --git a/tests/lib/webbRelayer.ts b/tests/lib/webbRelayer.ts index 1f3efd516..2bb9f9a53 100644 --- a/tests/lib/webbRelayer.ts +++ b/tests/lib/webbRelayer.ts @@ -28,6 +28,7 @@ import JSONStream from 'JSONStream'; import { BigNumber } from 'ethers'; import { ConvertToKebabCase } from './tsHacks'; import { padHexString } from '../lib/utils.js'; +import * as BN from 'bn.js'; export type CommonConfig = { features?: FeaturesConfig; @@ -234,13 +235,19 @@ export class WebbRelayer { const response = await fetch(endpoint); return response; } - // API to fetch metrics for particular resource - public async getFeeInfo( + + public async getEvmFeeInfo( chainId: number, vanchor: string, gas_amount: BigNumber ) { - const endpoint = `http://127.0.0.1:${this.opts.commonConfig.port}/api/v1/fee_info/${chainId}/${vanchor}/${gas_amount}`; + const endpoint = `http://127.0.0.1:${this.opts.commonConfig.port}/api/v1/fee_info/evm/${chainId}/${vanchor}/${gas_amount}`; + const response = await fetch(endpoint); + return response; + } + + public async getSubstrateFeeInfo(chainId: number, partialFee: BN) { + const endpoint = `http://127.0.0.1:${this.opts.commonConfig.port}/api/v1/fee_info/substrate/${chainId}/${partialFee}`; const response = await fetch(endpoint); return response; } @@ -413,7 +420,7 @@ export class WebbRelayer { }, }; - console.log(cmd); + console.log(JSON.stringify(cmd)); return substrateTxHashOrReject(ws, cmd); } } @@ -583,11 +590,11 @@ export type EventSelector = { export type SubstrateVAnchorExtData = { recipient: string; relayer: string; - extAmount: number; - fee: number; + extAmount: string; + fee: string; encryptedOutput1: number[]; encryptedOutput2: number[]; - refund: number; + refund: string; token: number; }; @@ -665,11 +672,18 @@ export interface ChainInfo { blockConfirmations: number; } -export interface FeeInfo { - estimatedFee: BigNumber; - gasPrice: BigNumber; - refundExchangeRate: BigNumber; - maxRefund: BigNumber; +export interface EvmFeeInfo { + estimatedFee: string; + gasPrice: string; + refundExchangeRate: string; + maxRefund: string; + timestamp: string; +} + +export interface SubstrateFeeInfo { + estimatedFee: string; + refundExchangeRate: string; + maxRefund: string; timestamp: string; } @@ -746,7 +760,6 @@ type ContractKind = | 'VAnchor' | 'OpenVAnchor'; -type RuntimeKind = 'DKG' | 'WebbProtocol'; type PalletKind = | 'DKG' | 'DKGProposals' diff --git a/tests/package.json b/tests/package.json index fdb470a88..8f86f8c04 100644 --- a/tests/package.json +++ b/tests/package.json @@ -9,7 +9,7 @@ "type": "module", "scripts": { "lint": "eslint . --ext .ts", - "test": "mocha test **/*.test.*", + "test": "mocha test test/*/*.test.*", "test-evm": "mocha test test/evm/*.test.*", "test-substrate": "mocha test test/substrate/*.test.*", "format": "prettier -w '**/*.ts'", @@ -19,10 +19,10 @@ "node": "18.x.x" }, "resolutions": { - "@webb-tools/api": "0.1.4-123", - "@webb-tools/api-derive": "0.1.4-123", - "@webb-tools/sdk-core": "0.1.4-123", - "@webb-tools/test-utils": "0.1.4-123" + "@webb-tools/api": "0.1.4-125", + "@webb-tools/api-derive": "0.1.4-125", + "@webb-tools/sdk-core": "0.1.4-125", + "@webb-tools/test-utils": "0.1.4-125" }, "dependencies": { "@babel/core": "^7.17.8", @@ -36,16 +36,16 @@ "@polkadot/keyring": "11.1.3", "@truffle/hdwallet-provider": "^2.0.3", "@webb-tools/anchors": "0.5.38", - "@webb-tools/vbridge": "0.5.38", + "@webb-tools/api": "0.1.4-125", + "@webb-tools/api-derive": "0.1.4-125", + "@webb-tools/evm-test-utils": "0.5.38", "@webb-tools/protocol-solidity": "0.5.38", - "@webb-tools/evm-test-utils":"0.5.38", + "@webb-tools/sdk-core": "0.1.4-125", + "@webb-tools/tangle-substrate-types": "0.0.1", + "@webb-tools/test-utils": "0.1.4-125", "@webb-tools/tokens": "0.5.38", "@webb-tools/utils": "0.5.30", - "@webb-tools/api": "0.1.4-123", - "@webb-tools/api-derive": "0.1.4-123", - "@webb-tools/sdk-core": "0.1.4-123", - "@webb-tools/test-utils": "0.1.4-123", - "@webb-tools/tangle-substrate-types": "0.0.1", + "@webb-tools/vbridge": "0.5.38", "JSONStream": "^1.3.5", "async-retry": "^1.3.3", "dotenv": "^16.0.0", diff --git a/tests/test/evm/RelayerTxTransfer.test.ts b/tests/test/evm/RelayerTxTransfer.test.ts index c2ecc0f42..27b329fa8 100644 --- a/tests/test/evm/RelayerTxTransfer.test.ts +++ b/tests/test/evm/RelayerTxTransfer.test.ts @@ -33,8 +33,8 @@ import { LocalChain } from '../../lib/localTestnet.js'; import { defaultWithdrawConfigValue, EnabledContracts, + EvmFeeInfo, EvmEtherscanConfig, - FeeInfo, WebbRelayer, } from '../../lib/webbRelayer.js'; import getPort, { portNumbers } from 'get-port'; @@ -298,13 +298,13 @@ describe('Relayer transfer assets', function () { outputData.extData ); - const feeInfoResponse = await webbRelayer.getFeeInfo( + const feeInfoResponse = await webbRelayer.getEvmFeeInfo( localChain1.chainId, vanchor1.getAddress(), gas_amount ); expect(feeInfoResponse.status).equal(200); - const feeInfo = await (feeInfoResponse.json() as Promise); + const feeInfo = await (feeInfoResponse.json() as Promise); console.log(feeInfo); const maxRefund = Number(formatEther(feeInfo.maxRefund)); const refundExchangeRate = Number(formatEther(feeInfo.refundExchangeRate)); diff --git a/tests/test/evm/vanchorPrivateTransaction.test.ts b/tests/test/evm/vanchorPrivateTransaction.test.ts index 325982144..9a19b06c3 100644 --- a/tests/test/evm/vanchorPrivateTransaction.test.ts +++ b/tests/test/evm/vanchorPrivateTransaction.test.ts @@ -27,8 +27,8 @@ import { LocalChain, setupVanchorEvmTx } from '../../lib/localTestnet.js'; import { defaultWithdrawConfigValue, EnabledContracts, + EvmFeeInfo, EvmEtherscanConfig, - FeeInfo, ResourceMetricResponse, WebbRelayer, } from '../../lib/webbRelayer.js'; @@ -300,13 +300,13 @@ describe('Vanchor Private Tx relaying with mocked governor', function () { dummyOutput.extData ); - const feeInfoResponse = await webbRelayer.getFeeInfo( + const feeInfoResponse = await webbRelayer.getEvmFeeInfo( localChain2.chainId, vanchor2.getAddress(), gas_amount ); expect(feeInfoResponse.status).equal(200); - const feeInfo = await (feeInfoResponse.json() as Promise); + const feeInfo = await (feeInfoResponse.json() as Promise); console.log(feeInfo); const maxRefund = Number(formatEther(feeInfo.maxRefund)); const refundExchangeRate = Number(formatEther(feeInfo.refundExchangeRate)); diff --git a/tests/test/substrate/vanchorPrivateTransaction.test.ts b/tests/test/substrate/vanchorPrivateTransaction.test.ts index 6e9437928..62c5b9d48 100644 --- a/tests/test/substrate/vanchorPrivateTransaction.test.ts +++ b/tests/test/substrate/vanchorPrivateTransaction.test.ts @@ -17,7 +17,7 @@ // This our basic Substrate VAnchor Transaction Relayer Tests. // These are for testing the basic relayer functionality. which is just to relay transactions for us. -import { assert } from 'chai'; +import { assert, expect } from 'chai'; import getPort, { portNumbers } from 'get-port'; import temp from 'temp'; import path from 'path'; @@ -29,11 +29,12 @@ import { Pallet, SubstrateVAnchorExtData, SubstrateVAnchorProofData, + SubstrateFeeInfo, } from '../../lib/webbRelayer.js'; -import { ethers } from 'ethers'; +import { BigNumber, ethers } from 'ethers'; import { ApiPromise } from '@polkadot/api'; -import { u8aToHex, hexToU8a } from '@polkadot/util'; +import { u8aToHex, hexToU8a, BN } from '@polkadot/util'; import { decodeAddress } from '@polkadot/util-crypto'; import { naclEncrypt, randomAsU8a } from '@polkadot/util-crypto'; @@ -51,8 +52,9 @@ import { generateVAnchorNote, } from '../../lib/utils.js'; import { LocalTangle } from '../../lib/localTangle.js'; +import { verify_js_proof } from '@webb-tools/wasm-utils/njs/wasm-utils-njs.js'; -describe.skip('Substrate VAnchor Private Transaction Relayer Tests', function () { +describe('Substrate VAnchor Private Transaction Relayer Tests', function () { const tmpDirPath = temp.mkdirSync(); let aliceNode: LocalTangle; let charlieNode: LocalTangle; @@ -90,6 +92,7 @@ describe.skip('Substrate VAnchor Private Transaction Relayer Tests', function () ports: 'auto', enableLogging: false, }); + // Wait until we are ready and connected const api = await aliceNode.api(); await api.isReady; @@ -136,12 +139,11 @@ describe.skip('Substrate VAnchor Private Transaction Relayer Tests', function () const data = await vanchorDeposit( typedSourceChainId.toString(), // source chain Id typedSourceChainId.toString(), // target chain Id - 10, // public amount + 1000000000, // public amount treeId, api, aliceNode ); - console.log('Deposit made'); // now we wait for all deposit to be saved in LeafStorageCache. await webbRelayer.waitForEvent({ kind: 'leaves_store', @@ -155,29 +157,60 @@ describe.skip('Substrate VAnchor Private Transaction Relayer Tests', function () // Bob's balance after withdrawal const bobBalanceBefore = await api.query.system.account(account.address); + const dummyVanchorData = await vanchorWithdraw( + typedSourceChainId.toString(), + typedSourceChainId.toString(), + account.address, + data.depositUtxos, + treeId, + BigInt(0), + // TODO: need to convert this once there is exchange rate between native + // token and wrapped token + BigInt(0), + api + ); + const token = new DataView(dummyVanchorData.extData.token.buffer, 0); + + const info = await api.tx.vAnchorBn254 + .transact(treeId, dummyVanchorData.proofData, dummyVanchorData.extData) + .paymentInfo(account); + const feeInfoResponse2 = await webbRelayer.getSubstrateFeeInfo( + substrateChainId, + info.partialFee.toBn() + ); + expect(feeInfoResponse2.status).equal(200); + const feeInfo2 = + await (feeInfoResponse2.json() as Promise); + const estimatedFee = BigInt(feeInfo2.estimatedFee); + + const refund = BigInt(0); + const feeTotal = estimatedFee + refund; const vanchorData = await vanchorWithdraw( typedSourceChainId.toString(), typedSourceChainId.toString(), account.address, data.depositUtxos, treeId, + feeTotal, + // TODO: need to convert this once there is exchange rate between native + // token and wrapped token + refund, api ); - // Now we construct payload for substrate private transaction. - // Convert [u8;4] to u32 asset Id - const token = new DataView(vanchorData.extData.token.buffer, 0); const substrateExtData: SubstrateVAnchorExtData = { recipient: vanchorData.extData.recipient, relayer: vanchorData.extData.relayer, - extAmount: Number(vanchorData.extData.extAmount), - fee: Number(vanchorData.extData.fee), + extAmount: BigNumber.from(vanchorData.extData.extAmount) + .toHexString() + .replace('0x', ''), + fee: BigNumber.from(feeTotal.toString()).toHexString(), encryptedOutput1: Array.from( hexToU8a(vanchorData.extData.encryptedOutput1) ), encryptedOutput2: Array.from( hexToU8a(vanchorData.extData.encryptedOutput2) ), - refund: Number(vanchorData.extData.refund), + refund: BigNumber.from(refund.toString()).toHexString(), token: token.getUint32(0, true), }; @@ -206,6 +239,7 @@ describe.skip('Substrate VAnchor Private Transaction Relayer Tests', function () ); // now we wait for relayer to execute private transaction. + await webbRelayer.waitForEvent({ kind: 'private_tx', event: { @@ -227,6 +261,7 @@ describe.skip('Substrate VAnchor Private Transaction Relayer Tests', function () after(async () => { await aliceNode?.stop(); + // await bobNode?.stop(); await charlieNode?.stop(); await webbRelayer?.stop(); }); @@ -240,6 +275,8 @@ async function vanchorWithdraw( recipient: string, depositUtxos: [Utxo, Utxo], treeId: number, + fee: bigint, + refund: bigint, api: ApiPromise ): Promise<{ extData: any; proofData: any }> { const secret = randomAsU8a(); @@ -261,6 +298,21 @@ async function vanchorWithdraw( ); const pk_hex = fs.readFileSync(pkPath).toString('hex'); const pk = hexToU8a(pk_hex); + + const vkPath = path.join( + // tests path + gitRoot, + 'tests', + 'substrate-fixtures', + 'vanchor', + 'bn254', + 'x5', + '2-2-2', + 'verifying_key_uncompressed.bin' + ); + const vk_hex = fs.readFileSync(vkPath).toString('hex'); + const vk = hexToU8a(vk_hex); + const leavesMap = {}; // get source chain (evm) leaves. const substrateLeaves = await api.derive.merkleTreeBn254.getLeavesForTree( @@ -297,14 +349,18 @@ async function vanchorWithdraw( const assetId = new Uint8Array([0, 0, 0, 0]); // WEBB native token asset Id. const address = recipient; - const fee = 0; - const refund = 0; const withdrawAmount = depositUtxos.reduce((acc, utxo) => { - return Number(utxo.amount) + acc; - }, 0); - const extAmount = -withdrawAmount; + return BigInt(utxo.amount) + acc; + }, BigInt(0)); const publicAmount = -withdrawAmount; + const extAmount = -(withdrawAmount - fee); + + console.log({ + fee: fee.toString(), + extAmount: extAmount.toString(), + publicAmount: publicAmount.toString(), + }); const tree = await api.query.merkleTreeBn254.trees(treeId); const root = tree.unwrap().root.toHex(); @@ -331,24 +387,34 @@ async function vanchorWithdraw( output: [output1, output2], encryptedCommitments: [comEnc1, comEnc2], provingKey: pk, - publicAmount: String(publicAmount), + publicAmount: publicAmount.toString(), roots: rootsSet, relayer: decodedAddress, recipient: decodedAddress, extAmount: extAmount.toString(), fee: fee.toString(), - refund: String(refund), + refund: refund.toString(), token: assetId, }; const data = await provingManager.prove('vanchor', setup); + + const isValidProof = verify_js_proof( + data.proof, + data.publicInputs, + u8aToHex(vk).replace('0x', ''), + 'Bn254' + ); + console.log('Is proof valid : ', isValidProof); + expect(isValidProof).to.be.true; + const extData = { relayer: address, recipient: address, - fee, - refund: String(refund), + fee: fee.toString(), + refund: refund.toString(), token: assetId, - extAmount: extAmount, + extAmount: extAmount.toString(), encryptedOutput1: u8aToHex(comEnc1), encryptedOutput2: u8aToHex(comEnc2), }; @@ -392,21 +458,6 @@ async function vanchorDeposit( ); const pk_hex = fs.readFileSync(pkPath).toString('hex'); const pk = hexToU8a(pk_hex); - - const vkPath = path.join( - // tests path - gitRoot, - 'tests', - 'substrate-fixtures', - 'vanchor', - 'bn254', - 'x5', - '2-2-2', - 'verifying_key_uncompressed.bin' - ); - const vk_hex = fs.readFileSync(vkPath).toString('hex'); - const vk = hexToU8a(vk_hex); - // dummy Deposit Note. Input note is directed toward source chain const depositNote = await generateVAnchorNote( 0, @@ -438,7 +489,7 @@ async function vanchorDeposit( const leavesMap = {}; const address = account.address; - const extAmount = currencyToUnitI128(10); + const extAmount = currencyToUnitI128(publicAmountUint); const fee = 0; const refund = 0; // Initially leaves will be empty @@ -485,7 +536,7 @@ async function vanchorDeposit( fee, refund: String(refund), token: assetId, - extAmount: extAmount.toNumber(), + extAmount: extAmount.toString(), encryptedOutput1: u8aToHex(comEnc1), encryptedOutput2: u8aToHex(comEnc2), }; diff --git a/tests/yarn.lock b/tests/yarn.lock index c9911410c..7d8d4609c 100644 --- a/tests/yarn.lock +++ b/tests/yarn.lock @@ -2134,6 +2134,27 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" +"@chainsafe/as-sha256@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.4.1.tgz#cfc0737e25f8c206767bdb6703e7943e5d44513e" + integrity sha512-IqeeGwQihK6Y2EYLFofqs2eY2ep1I2MvQXHzOAI+5iQN51OZlUkrLgyAugu2x86xZewDk5xas7lNczkzFzF62w== + +"@chainsafe/persistent-merkle-tree@^0.6.1": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.6.1.tgz#37bde25cf6cbe1660ad84311aa73157dc86ec7f2" + integrity sha512-gcENLemRR13+1MED2NeZBMA7FRS0xQPM7L2vhMqvKkjqtFT4YfjSVADq5U0iLuQLhFUJEMVuA8fbv5v+TN6O9A== + dependencies: + "@chainsafe/as-sha256" "^0.4.1" + "@noble/hashes" "^1.3.0" + +"@chainsafe/ssz@^0.11.1": + version "0.11.1" + resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.11.1.tgz#d4aec883af2ec5196ae67b96242c467da20b2476" + integrity sha512-cB8dBkgGN6ZoeOKuk+rIRHKN0L5i9JLGeC0Lui71QX0TuLcQKwgbfkUexpyJxnGFatWf8yeJxlOjozMn/OTP0g== + dependencies: + "@chainsafe/as-sha256" "^0.4.1" + "@chainsafe/persistent-merkle-tree" "^0.6.1" + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -2320,6 +2341,11 @@ crc-32 "^1.2.0" ethereumjs-util "^7.1.4" +"@ethereumjs/rlp@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" + integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== + "@ethereumjs/tx@^3.3.0", "@ethereumjs/tx@^3.3.2": version "3.5.1" resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.5.1.tgz#8d941b83a602b4a89949c879615f7ea9a90e6671" @@ -2328,6 +2354,16 @@ "@ethereumjs/common" "^2.6.3" ethereumjs-util "^7.1.4" +"@ethereumjs/util@^8.0.6": + version "8.0.6" + resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.0.6.tgz#f9716ed34235ea05eff8353bc5d483e5a6455989" + integrity sha512-zFLG/gXtF3QUC7iKFn4PT6HCr+DEnlCbwUGKGtXoqjA+64T+e0FuqMjlo4bQIY2ngRzk3EtudKdGYC4g31ehhg== + dependencies: + "@chainsafe/ssz" "^0.11.1" + "@ethereumjs/rlp" "^4.0.1" + ethereum-cryptography "^2.0.0" + micro-ftch "^0.3.1" + "@ethersproject/abi@5.0.0-beta.153": version "5.0.0-beta.153" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz#43a37172b33794e4562999f6e2d555b7599a8eee" @@ -3140,6 +3176,18 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== +"@metamask/eth-sig-util@^5.0.2": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-5.1.0.tgz#a47f62800ee1917fef976ba67544a0ccd7d1bd6b" + integrity sha512-mlgziIHYlA9pi/XZerChqg4NocdOgBPB9NmxgXWQO2U2hH8RGOJQrz6j/AIKkYxgCMIE2PY000+joOwXfzeTDQ== + dependencies: + "@ethereumjs/util" "^8.0.6" + bn.js "^4.12.0" + ethereum-cryptography "^2.0.0" + ethjs-util "^0.1.6" + tweetnacl "^1.0.3" + tweetnacl-util "^0.15.1" + "@metamask/safe-event-emitter@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-2.0.0.tgz#af577b477c683fad17c619a78208cede06f9605c" @@ -3150,7 +3198,14 @@ resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz#323d72dd25103d0c4fbdce89dadf574a787b1f9b" integrity sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ== -"@noble/hashes@1.3.0": +"@noble/curves@1.0.0", "@noble/curves@~1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.0.0.tgz#e40be8c7daf088aaf291887cbc73f43464a92932" + integrity sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw== + dependencies: + "@noble/hashes" "1.3.0" + +"@noble/hashes@1.3.0", "@noble/hashes@^1.3.0", "@noble/hashes@~1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== @@ -3852,11 +3907,28 @@ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728" integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== -"@scure/base@1.1.1": +"@scure/base@1.1.1", "@scure/base@~1.1.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== +"@scure/bip32@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.0.tgz#6c8d980ef3f290987736acd0ee2e0f0d50068d87" + integrity sha512-bcKpo1oj54hGholplGLpqPHRbIsnbixFtc06nwuNM5/dwSXOq/AAYoIBRsBmnZJSdfeNW5rnff7NTAz3ZCqR9Q== + dependencies: + "@noble/curves" "~1.0.0" + "@noble/hashes" "~1.3.0" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.0.tgz#a207e2ef96de354de7d0002292ba1503538fc77b" + integrity sha512-SX/uKq52cuxm4YFXWFaVByaSHJh2w3BnokVSeUJVCv6K7WulT9u2BuNRBhuFl8vAuYnzx9bEu9WgpcNYTrYieg== + dependencies: + "@noble/hashes" "~1.3.0" + "@scure/base" "~1.1.0" + "@sinclair/typebox@^0.25.16": version "0.25.24" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" @@ -4805,7 +4877,7 @@ "@webassemblyjs/ast" "1.11.5" "@xtuc/long" "4.2.2" -"@webb-tools/anchors@0.5.38", "@webb-tools/anchors@^0.5.13", "@webb-tools/anchors@^0.5.32", "@webb-tools/anchors@^0.5.38": +"@webb-tools/anchors@0.5.38", "@webb-tools/anchors@^0.5.13", "@webb-tools/anchors@^0.5.38": version "0.5.38" resolved "https://registry.yarnpkg.com/@webb-tools/anchors/-/anchors-0.5.38.tgz#aad77453e2621b79ab359bb34a19b12ebf48d368" integrity sha512-I7c0irJNwsMlhASoUmW0Y+onQx4Pm1bC6wnS63ufElIMe1CN2vDUCoBZpHqufYGHw6d1CLytNqIGPHB+WT23OA== @@ -4820,24 +4892,24 @@ ethers "5.7.0" jssha "^3.2.0" -"@webb-tools/api-derive@0.1.4-123": - version "0.1.4-123" - resolved "https://registry.yarnpkg.com/@webb-tools/api-derive/-/api-derive-0.1.4-123.tgz#5d50467cc85ea1da6b92fca78f749a1b89487915" - integrity sha512-oSTmq4D1xwgoE00YZXn9YbnCUfSGkVrNAeCH9VeseZsSQmVWQkeYDM2BbZoy4vuGg5IPNvh5njLTYsWBHGBXRA== +"@webb-tools/api-derive@0.1.4-125": + version "0.1.4-125" + resolved "https://registry.yarnpkg.com/@webb-tools/api-derive/-/api-derive-0.1.4-125.tgz#340bd597247f704ce7f53c57942d40c259fa0963" + integrity sha512-wguqcdczDD69M0z3K1O8sW6Qb9K+gV0iVy28EGwCF29h1gcEeqx8F7UbXal32o77UOnrsYuVqXj4u7LfqOKU2A== dependencies: "@polkadot/api" "10.3.2" "@webb-tools/protocol-substrate-types" "0.0.10" -"@webb-tools/api@0.1.4-123": - version "0.1.4-123" - resolved "https://registry.yarnpkg.com/@webb-tools/api/-/api-0.1.4-123.tgz#09be8a3f5d1aaf9edbe3fcab5c8d1d0956eeada2" - integrity sha512-xzhEgjkKXCR0ruZ0H9rKnrSgEGib0EbRQ//hrntLEiRUOIYuG13JDVH0AMQoek2rDG7i2l3an44nxIpJw7+B5g== +"@webb-tools/api@0.1.4-125": + version "0.1.4-125" + resolved "https://registry.yarnpkg.com/@webb-tools/api/-/api-0.1.4-125.tgz#4a90d7adfd4d9f3d9459b05f9122fa424e0c93d9" + integrity sha512-anKD8zmTEeQrfVrlD6L+NpipFSPBnPpo/TGlv9CXrvsQFOokkRrVIbU1NCYX1hMd2mth3rvIEQ0olV0x/GX9cw== dependencies: "@polkadot/api" "10.3.2" - "@webb-tools/api-derive" "0.1.4-123" + "@webb-tools/api-derive" "0.1.4-125" "@webb-tools/protocol-substrate-types" "0.0.10" -"@webb-tools/bridges@^0.5.32", "@webb-tools/bridges@^0.5.38": +"@webb-tools/bridges@^0.5.38": version "0.5.38" resolved "https://registry.yarnpkg.com/@webb-tools/bridges/-/bridges-0.5.38.tgz#ba0ee04d13a8cc1f61819d9d1e8b34ee647717e4" integrity sha512-7gQEFg6+/ZvSAbyyex4E8EB33h6OnqEpIJgOTb8cLj0xBQ0J3GvmyMTKjakOD0Ro82O3UgoAKA8VtWS7NxLh4A== @@ -4850,7 +4922,7 @@ "@webb-tools/utils" "^0.5.30" ethers "5.7.0" -"@webb-tools/contracts@^0.5.13", "@webb-tools/contracts@^0.5.32", "@webb-tools/contracts@^0.5.38": +"@webb-tools/contracts@^0.5.13", "@webb-tools/contracts@^0.5.38": version "0.5.38" resolved "https://registry.yarnpkg.com/@webb-tools/contracts/-/contracts-0.5.38.tgz#04504e4d1189d2663427798826728837c13ec135" integrity sha512-FeC8KWUpV4aUV8oZ9SpaKcSj9sEekT+ZU9U/vsjLD8CP1YH6Hf69bfCmW7CxOHTqFSiVfyfOTZmaaOHmHUw4oQ== @@ -4929,7 +5001,7 @@ minimatch "^7.4.2" mkdirp "^2.1.5" -"@webb-tools/evm-test-utils@0.5.38", "@webb-tools/evm-test-utils@^0.5.32", "@webb-tools/evm-test-utils@^0.5.38": +"@webb-tools/evm-test-utils@0.5.38", "@webb-tools/evm-test-utils@^0.5.38": version "0.5.38" resolved "https://registry.yarnpkg.com/@webb-tools/evm-test-utils/-/evm-test-utils-0.5.38.tgz#a881bd8ce18e6634927f5d3b0772e2e1267bd248" integrity sha512-nBZkPVwXpAHfsmRu9rX8qe2rylE/3AQCtrmEjvIdATVRPpsRUz+NUsfsF23vaPJfXBe6YPZ3mU5ullfezVdq1g== @@ -4943,7 +5015,7 @@ ganache "7.5.0" tiny-secp256k1 "^2.2.1" -"@webb-tools/interfaces@^0.5.32", "@webb-tools/interfaces@^0.5.38": +"@webb-tools/interfaces@^0.5.38": version "0.5.38" resolved "https://registry.yarnpkg.com/@webb-tools/interfaces/-/interfaces-0.5.38.tgz#b84dde2d47523392764dba4031971e81778d3aba" integrity sha512-mavaLiZEM0x/UFbDrnvUq6xOlJmwuo5HEuxYtGGV52d4NoS+ytLfL9rOKG4/KjpZ4zf7T9OtUG00upGnCAKOrg== @@ -4951,20 +5023,6 @@ "@webb-tools/contracts" "^0.5.38" "@webb-tools/sdk-core" "0.1.4-123" -"@webb-tools/protocol-solidity@0.5.32": - version "0.5.32" - resolved "https://registry.yarnpkg.com/@webb-tools/protocol-solidity/-/protocol-solidity-0.5.32.tgz#4edc7d3cc9662c419308ea5648cab6434486b226" - integrity sha512-8+ix1Chscs30cHNrZ0Ka1Me5O7AuV1trI1u9bhSOh93RX8OLmkCFHK8SUwbx5Wdc/hdogv3uJkeRDEEEkFxFyQ== - dependencies: - "@webb-tools/anchors" "^0.5.32" - "@webb-tools/bridges" "^0.5.32" - "@webb-tools/contracts" "^0.5.32" - "@webb-tools/evm-test-utils" "^0.5.32" - "@webb-tools/interfaces" "^0.5.32" - "@webb-tools/tokens" "^0.5.32" - "@webb-tools/utils" "^0.5.24" - "@webb-tools/vbridge" "^0.5.32" - "@webb-tools/protocol-solidity@0.5.38": version "0.5.38" resolved "https://registry.yarnpkg.com/@webb-tools/protocol-solidity/-/protocol-solidity-0.5.38.tgz#d336daa2b5ae2e60f3676ba05218e98a7915866a" @@ -5015,20 +5073,21 @@ minimatch "^7.4.2" mkdirp "^2.1.5" -"@webb-tools/sdk-core@0.1.4-105", "@webb-tools/sdk-core@0.1.4-108", "@webb-tools/sdk-core@0.1.4-119", "@webb-tools/sdk-core@0.1.4-123": - version "0.1.4-123" - resolved "https://registry.yarnpkg.com/@webb-tools/sdk-core/-/sdk-core-0.1.4-123.tgz#0ca9a867dd3cad1e6797f8cc57fb629fa3803344" - integrity sha512-yejvoXqmTYKqTV3hJlBeSuE0P5dS8w8r2QjCZCRMs7X7ec4YLCpw1LIv83+eRYhoffN93ZLjf3GvMObOzDCNnQ== +"@webb-tools/sdk-core@0.1.4-105", "@webb-tools/sdk-core@0.1.4-108", "@webb-tools/sdk-core@0.1.4-119", "@webb-tools/sdk-core@0.1.4-123", "@webb-tools/sdk-core@0.1.4-125": + version "0.1.4-125" + resolved "https://registry.yarnpkg.com/@webb-tools/sdk-core/-/sdk-core-0.1.4-125.tgz#709832397ea29dd6fbd87bf591c754524cfff2b2" + integrity sha512-Z5hC8M7Vj1UZGvwSr/vg+EjmWMOpHnvMAO0XzmcW1aw+V9/9QuCnZNrS4e+86KPkp08q6IvOkplkfO7xCUJPHQ== dependencies: + "@metamask/eth-sig-util" "^5.0.2" "@polkadot/util" "11.1.3" - "@webb-tools/wasm-utils" "0.1.4-123" + "@webb-tools/wasm-utils" "0.1.4-125" + big-integer "^1.6.51" bignumber.js "^9.0.0" - circomlibjs "0.0.8" + circomlibjs "^0.0.8" elliptic "6.5.4" - eth-sig-util "^3.0.1" ethers "5.7.0" - ffjavascript "0.2.55" - snarkjs "0.4.22" + ffjavascript "^0.2.57" + snarkjs "^0.6.10" "@webb-tools/semaphore-group@0.0.1-4": version "0.0.1-4" @@ -5131,22 +5190,18 @@ minimatch "^7.4.2" mkdirp "^2.1.5" -"@webb-tools/test-utils@0.1.4-108", "@webb-tools/test-utils@0.1.4-123": - version "0.1.4-123" - resolved "https://registry.yarnpkg.com/@webb-tools/test-utils/-/test-utils-0.1.4-123.tgz#f2c7692a00885854029c11afbedd8ed11b2144f8" - integrity sha512-h60SjygdHS5sC6JuwnkQYo2mFTO1sXEXe6n4/5wKBz24ANCPfj9c7KnFjN25La5JSW2iy5Y0jP1uPGYx6vkOeQ== +"@webb-tools/test-utils@0.1.4-108", "@webb-tools/test-utils@0.1.4-123", "@webb-tools/test-utils@0.1.4-125": + version "0.1.4-125" + resolved "https://registry.yarnpkg.com/@webb-tools/test-utils/-/test-utils-0.1.4-125.tgz#1718480e5167c18d328d84b416d5cfbbac7ee7c4" + integrity sha512-Jkon4ay4YzkYPWwUoG8oLXr4emF6XB7JSbT52xJFtY3QVWJm+BO70ANv/S5bpzed4YVOjqyefRNSm5vpXgLaCQ== dependencies: "@polkadot/api" "10.3.2" "@polkadot/keyring" "11.1.3" "@types/node" "16.11.7" - "@webb-tools/api" "0.1.4-123" + "@webb-tools/api" "0.1.4-125" "@webb-tools/dkg-substrate-types" "0.0.5" - "@webb-tools/protocol-solidity" "0.5.32" "@webb-tools/protocol-substrate-types" "0.0.10" - "@webb-tools/sdk-core" "0.1.4-123" - "@webb-tools/tokens" "0.5.32" - "@webb-tools/utils" "0.5.24" - "@webb-tools/vbridge" "0.5.32" + "@webb-tools/sdk-core" "0.1.4-125" ecpair "^2.0.1" ethers "5.7.0" ganache "7.5.0" @@ -5166,18 +5221,7 @@ "@webb-tools/utils" "^0.5.7" ethers "5.7.0" -"@webb-tools/tokens@0.5.32": - version "0.5.32" - resolved "https://registry.yarnpkg.com/@webb-tools/tokens/-/tokens-0.5.32.tgz#31a25d7e4b99806492b1d9d79ceda5f156a97c7a" - integrity sha512-24gs9jMUDZajPeHb6sb8T2vJpCmKRaSBMv1A0MigViJt+quafI+r25nPOZf14/uNsY4M3abGbF919bB/AMvnZg== - dependencies: - "@webb-tools/anchors" "^0.5.32" - "@webb-tools/contracts" "^0.5.32" - "@webb-tools/sdk-core" "0.1.4-119" - "@webb-tools/utils" "^0.5.24" - ethers "5.7.0" - -"@webb-tools/tokens@0.5.38", "@webb-tools/tokens@^0.5.32", "@webb-tools/tokens@^0.5.38": +"@webb-tools/tokens@0.5.38", "@webb-tools/tokens@^0.5.38": version "0.5.38" resolved "https://registry.yarnpkg.com/@webb-tools/tokens/-/tokens-0.5.38.tgz#87f3777654d07248c4029d0fe3ad939d918a6df6" integrity sha512-24JohBfeLdNyrpaEvl9IC69SIPGcKgKY2QRnAaHHdpKmitAhnUt1dIKZDauUKHKy6YE01dembGq2EncL8UNCNw== @@ -5189,15 +5233,7 @@ "@webb-tools/utils" "^0.5.30" ethers "5.7.0" -"@webb-tools/utils@0.5.24": - version "0.5.24" - resolved "https://registry.yarnpkg.com/@webb-tools/utils/-/utils-0.5.24.tgz#1fc58d68f9d3b4dcd8ded124eef58bcd1008ef17" - integrity sha512-Yo/E2pMnQOibSMvgkJ9idPGFSw7BMspF26sw1QLCixVEvBa9uwi6XTp954jlto2v6GPcBwb1ev226ReGQ/VVSg== - dependencies: - "@webb-tools/sdk-core" "0.1.4-119" - ethers "5.7.0" - -"@webb-tools/utils@0.5.30", "@webb-tools/utils@^0.5.24", "@webb-tools/utils@^0.5.30", "@webb-tools/utils@^0.5.7": +"@webb-tools/utils@0.5.30", "@webb-tools/utils@^0.5.30", "@webb-tools/utils@^0.5.7": version "0.5.30" resolved "https://registry.yarnpkg.com/@webb-tools/utils/-/utils-0.5.30.tgz#eb212b38fedfe9be20ba4895b3928c2989b0d94c" integrity sha512-8Fg4CFSMNhjmvJzGAiFwadtTUGu+TsKlgNa7sHBLI7RlvubbnaMd0SZAg92gcyrAi4H6e7YpxKl5MHlcqpFGvg== @@ -5213,21 +5249,7 @@ "@webb-tools/sdk-core" "0.1.4-105" ethers "5.7.0" -"@webb-tools/vbridge@0.5.32": - version "0.5.32" - resolved "https://registry.yarnpkg.com/@webb-tools/vbridge/-/vbridge-0.5.32.tgz#acbfcae7511ca272929ae5fd1a1247c7b8b60299" - integrity sha512-sweJdzq6pV2PxOdHysFN1jzkscRAaBpD9smaMgTa1f1hp4Ooww+ffAHs9Yr+RM68arNFHkdyVWA+PdMVjjWSIw== - dependencies: - "@webb-tools/anchors" "^0.5.32" - "@webb-tools/bridges" "^0.5.32" - "@webb-tools/contracts" "^0.5.32" - "@webb-tools/interfaces" "^0.5.32" - "@webb-tools/sdk-core" "0.1.4-119" - "@webb-tools/tokens" "^0.5.32" - "@webb-tools/utils" "^0.5.24" - ethers "5.7.0" - -"@webb-tools/vbridge@0.5.38", "@webb-tools/vbridge@^0.5.32", "@webb-tools/vbridge@^0.5.38": +"@webb-tools/vbridge@0.5.38", "@webb-tools/vbridge@^0.5.38": version "0.5.38" resolved "https://registry.yarnpkg.com/@webb-tools/vbridge/-/vbridge-0.5.38.tgz#5b84475796ba12cc34333c0041f570a575ebd1f3" integrity sha512-YCjU76HKahuUuWhkYtXutDyQZ9KlfwjYaYsQ0n0ex1/Rt++/SKhgCSHr9WMogKYWYLG0V5i629R8KlZZNViGEw== @@ -5241,10 +5263,10 @@ "@webb-tools/utils" "^0.5.30" ethers "5.7.0" -"@webb-tools/wasm-utils@0.1.4-123": - version "0.1.4-123" - resolved "https://registry.yarnpkg.com/@webb-tools/wasm-utils/-/wasm-utils-0.1.4-123.tgz#84b0908a4f14542027dfa44553f726fc7774619d" - integrity sha512-uk5nMPlydktPiqoD7Z6gdHSXhaRNS5iKEgvD4EQ4TJuQ0IYay5vFxttmK/RpZ+lEvx+Lw+/Xd+zFAzBFkT8hEQ== +"@webb-tools/wasm-utils@0.1.4-125": + version "0.1.4-125" + resolved "https://registry.yarnpkg.com/@webb-tools/wasm-utils/-/wasm-utils-0.1.4-125.tgz#f2942c1cdc05fac72ab80fdd5906e8de241a320e" + integrity sha512-wh2aDvNwjn7zq2cuP/Xo1V7RRaHsLfb6ssgjOK2zgTQfVWiNUxTNjsKHk0Gs0Hgv+llssee0lUL53sLQI66ipQ== "@webpack-cli/configtest@^2.0.1": version "2.0.1" @@ -6589,7 +6611,7 @@ big-integer@1.6.36: resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36" integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg== -big-integer@^1.6.42, big-integer@^1.6.48: +big-integer@^1.6.42, big-integer@^1.6.48, big-integer@^1.6.51: version "1.6.51" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== @@ -6679,7 +6701,7 @@ bn.js@4.11.6: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.8.0: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.12.0, bn.js@^4.8.0: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== @@ -7341,7 +7363,14 @@ circom_runtime@0.1.20: dependencies: ffjavascript "0.2.55" -circomlibjs@0.0.8: +circom_runtime@0.1.22: + version "0.1.22" + resolved "https://registry.yarnpkg.com/circom_runtime/-/circom_runtime-0.1.22.tgz#f957c47662cdd03cd3fb76979c434c719a366373" + integrity sha512-V/XYZWBhbZY8SotkaGH4FbiDYAZ8a1Md++MBiKPDOuWS/NIJB+Q+XIiTC8zKMgoDaa9cd2OiTvsC9J6te7twNg== + dependencies: + ffjavascript "0.2.57" + +circomlibjs@0.0.8, circomlibjs@^0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/circomlibjs/-/circomlibjs-0.0.8.tgz#c2d1130d2d99fbb22f3d40ac19f347d768eace76" integrity sha512-oZFYapLO0mfiA+i2GU/V7bRNEEPjVcwV4M444nU5lNsdSJpqLwD57m9zxTD5m/KeY7WQ3lEAC9NNKEPQHu7s1w== @@ -9468,6 +9497,16 @@ ethereum-cryptography@^0.1.3: secp256k1 "^4.0.1" setimmediate "^1.0.5" +ethereum-cryptography@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.0.0.tgz#e052b49fa81affae29402e977b8d3a31f88612b6" + integrity sha512-g25m4EtfQGjstWgVE1aIz7XYYjf3kH5kG17ULWVB5dH6uLahsoltOhACzSxyDV+fhn4gbR4xRrOXGe6r2uh4Bg== + dependencies: + "@noble/curves" "1.0.0" + "@noble/hashes" "1.3.0" + "@scure/bip32" "1.3.0" + "@scure/bip39" "1.2.0" + ethereum-protocol@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ethereum-protocol/-/ethereum-protocol-1.0.1.tgz#b7d68142f4105e0ae7b5e178cf42f8d4dc4b93cf" @@ -9846,7 +9885,7 @@ ethjs-unit@0.1.6: bn.js "4.11.6" number-to-bn "1.7.0" -ethjs-util@0.1.6, ethjs-util@^0.1.3: +ethjs-util@0.1.6, ethjs-util@^0.1.3, ethjs-util@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== @@ -9865,9 +9904,9 @@ eventemitter3@^4.0.0, eventemitter3@^4.0.7: integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== eventemitter3@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.0.tgz#084eb7f5b5388df1451e63f4c2aafd71b217ccb3" - integrity sha512-riuVbElZZNXLeLEoprfNYoDSwTBRR44X3mnhdI1YcnENpWTCsTTVZ2zFuqQcpoyqPQIUXdiPEU0ECAq0KQRaHg== + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== events@^3.0.0, events@^3.2.0: version "3.3.0" @@ -10170,6 +10209,15 @@ ffjavascript@0.2.55: wasmcurves "0.1.0" web-worker "^1.2.0" +ffjavascript@0.2.57, ffjavascript@^0.2.57: + version "0.2.57" + resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.2.57.tgz#ba1be96015b2688192e49f2f4de2cc5150fd8594" + integrity sha512-V+vxZ/zPNcthrWmqfe/1YGgqdkTamJeXiED0tsk7B84g40DKlrTdx47IqZuiygqAVG6zMw4qYuvXftIJWsmfKQ== + dependencies: + wasmbuilder "0.0.16" + wasmcurves "0.2.0" + web-worker "^1.2.0" + ffjavascript@^0.2.38: version "0.2.51" resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.2.51.tgz#5d714686e3a5bde96dc57be84babc61911283629" @@ -12261,9 +12309,9 @@ jsbn@~0.1.0: integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= jsdom@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-21.1.1.tgz#ab796361e3f6c01bcfaeda1fea3c06197ac9d8ae" - integrity sha512-Jjgdmw48RKcdAIQyUD1UdBh2ecH7VqwaXPN3ehoZN6MqgVbMn+lRm1aAT1AsdJRAJpwfa4IpwgzySn61h2qu3w== + version "21.1.2" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-21.1.2.tgz#6433f751b8718248d646af1cdf6662dc8a1ca7f9" + integrity sha512-sCpFmK2jv+1sjff4u7fzft+pUh2KSUbUrEHYHyfSIbGTIcmnjyp83qg6qLwdJ/I3LpTXx33ACxeRL7Lsyc6lGQ== dependencies: abab "^2.0.6" acorn "^8.8.2" @@ -12278,7 +12326,7 @@ jsdom@^21.1.1: http-proxy-agent "^5.0.0" https-proxy-agent "^5.0.1" is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.2" + nwsapi "^2.2.4" parse5 "^7.1.2" rrweb-cssom "^0.6.0" saxes "^6.0.0" @@ -13107,6 +13155,11 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= +micro-ftch@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" + integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== + micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -13695,10 +13748,10 @@ number-to-bn@1.7.0: bn.js "4.11.6" strip-hex-prefix "1.0.0" -nwsapi@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" - integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== +nwsapi@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.4.tgz#fd59d5e904e8e1f03c25a7d5a15cfa16c714a1e5" + integrity sha512-NHj4rzRo0tQdijE9ZqAx6kYDcoRwYwSYzCA8MY3JzfxlrvEU0jhnhJT9BhqhJs7I/dKcrDm6TyulaRqZPIhN5g== oauth-sign@~0.9.0: version "0.9.0" @@ -14765,6 +14818,16 @@ r1csfile@0.0.40: fastfile "0.0.20" ffjavascript "0.2.55" +r1csfile@0.0.45: + version "0.0.45" + resolved "https://registry.yarnpkg.com/r1csfile/-/r1csfile-0.0.45.tgz#59d59a33f8b5280017fc00ee691d003a3d705fe0" + integrity sha512-YKIp4D441aZ6OoI9y+bfAyb2j4Cl+OFq/iiX6pPWDrL4ZO968h0dq0w07i65edvrTt7/G43mTnl0qEuLXyp/Yw== + dependencies: + "@iden3/bigarray" "0.0.2" + "@iden3/binfileutils" "0.0.11" + fastfile "0.0.20" + ffjavascript "0.2.57" + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -15949,6 +16012,22 @@ snarkjs@^0.4.13: logplease "^1.2.15" r1csfile "0.0.40" +snarkjs@^0.6.10: + version "0.6.11" + resolved "https://registry.yarnpkg.com/snarkjs/-/snarkjs-0.6.11.tgz#577b0250c0d9bb93c0ee1d4a3d3075956d11775c" + integrity sha512-pYDcrSKmUMMJtYxSQTMNG/MtuGvUWPSk9gZzADeIiHp8vJmFdCscMFa/YtemPAkne4v6Awm5HAhqbfNPyoqjug== + dependencies: + "@iden3/binfileutils" "0.0.11" + bfj "^7.0.2" + blake2b-wasm "^2.4.0" + circom_runtime "0.1.22" + ejs "^3.1.6" + fastfile "0.0.20" + ffjavascript "0.2.57" + js-sha3 "^0.8.0" + logplease "^1.2.15" + r1csfile "0.0.45" + sockjs@^0.3.24: version "0.3.24" resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" @@ -16832,7 +16911,7 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tweetnacl-util@^0.15.0: +tweetnacl-util@^0.15.0, tweetnacl-util@^0.15.1: version "0.15.1" resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==